Beruflich Dokumente
Kultur Dokumente
A practical approach
Presentation
Flemming Mortensen. Navision since 1991. Partner in Logos Consult A/S, a Danish midsized Microsoft Partner specializing in Business Solution. Participated in development of parts of the standard application. Taught development in Navision 97 04.
Presentation
Logos Staff
4 programmers 4 consultants 2 salespersons 1 admin
Presentation
Typical project 50 to 500 hours 1, at most 2, programmers 1 consultant
Purpose
Show the practical use of Navision as development environment for administrative solutions. Argue its virtues Simple Safe
Scope
Classic Navision Native database Basic field and variable types Classic objects: Tabel Form Report Dataport Codeunit
Facts
Navison is a Client / Server based administrative solution. Small and exact pieces of data with a long life expectancy. The business logic is all made in C/Side, a development environment build for this purpose.
Design
Enforces few restrictions on work flow. Copies data freely to allow both use of defaults, e.g. a Unit Price and exceptions, e.g. a special Unit Price. Or to save copies of data with higher longevity than the original. Divided in Functional Areas of identical structure.
Functional Area
The Navision application consists of a number of Functional Areas. A Functional Area is a set of related business functionality.
Examples
Examples of Functional Areas: General Ledger Sales & Receivables Purchase & Payables Fixed Asset Inventory Resources Jobs
Uniformity
All Functional Areas are build with the same few, welldefined components. The application is not made up of a random subset of all possible uses of C/Side.
Posting Function
e.g. Codeunit 22 Item Jnl.-Post Line
Posting Function
Reuse
The design of a functional area, specifically the Journal Line Posting Function Ledger Entry setup allows for a very high degree of reuse of code, and at a very high level.
Master Table
Posting Function
Inventory
Item Item Journal Line Codeunit 80
Codeunit 22
Posting
In Navision the term posting can have several more or less precise meanings: 1. Posting a journal or journal line. 2. Posting a document such as an sales order. 3. Activating some function to store data in an non editable format and in the process testing that the data is consistent. Below we first discuss posting journals and then documents in some detail.
Posting 1
Only codeunit 13 knows the entire journal. Both 11 and 12 are called with single journal line record variables. 13 11 12
Posting 2
13 passes each line to 11 for test. 13 passes each line to 12 for posting. 13 then deletes all lines.
13
11
12
Posting 3
13 is only one of many functions, that calls 12 to post a journal line. It is consequently not allowed to let 13 influence the posting by letting it mark one line with information from other lines or in any other way use its knowledge of the context. Thus its 12, which is responsible for creating the Register for each posting transaction even at the price of a performance penalty. This is contrary to what actually happens with Bill-to/Payto No. which is anyway a piece of crap.
Ledger Entries 1
All ledger entry tables have a field called Entry No., which is the sole field in the primary key. The Entry No. is assigned consecutively by the posting function. 1, 2, 3 The only exception are the customer and vendor ledger entries. They share the entry number series with the general ledger entries.
Ledger Entries 2
Sharing numbers:
Registers
All ledger entries from 1 posting transaction are grouped together by a register entry, holding the first and the last of the entry numbers.
Registers 2
Integration 1
Any module that creates a ledger entry must, ultimately, do it by creating a journal line variable and then post it with the corresponding 12-function. But this allows us to reuse all the functionality in the 12 function and often the trigger code on the journal line.
Integration 2
An important consequence of the posting design is that to post a journal line, the journal line record needs not to be written to the database. This makes the integration, from a technical point of view, very easy and robust.
Integration 3
Another, perhaps more high level, way to integrate a module with the standard application is to create a not posted document, e.g. an sales invoice, and then to post it with the corresponding document posting function, e.g. codeunit 80. Because documents consists of a header and several lines they must be written to the database before they can be posted. This makes it a bit more fragile and complicated than posting lines from within the code.
Posting Documents 1
But it is still facilitated by the detailed design of the document posting function.
81
80
Posting Documents 2
1. 81 is responsible for the dialog Do you want to post the invoice?. 2. 80 is responsible for the actual posting. 3. You can substitute 81 with 82 to get post and print. 4. There is also a post batch for documents report 297, which calls 80 for each document.
Posting Documents 3
1. It is the same set of tables, 36 / 37, which is used for the different types of not posted documents: Quote, Order, Invoice, Credit Memo, Blanket Order and Return Order. 2. The primary key of Table 36 is Document Type and Document No. Document Type is the field that makes the document to a quote, order, invoice etc. 3. It is always codeunit 80 which is used to post a document, whether its an invoice, an order, a credit memo or a return order.
Posting Documents 4
1. Contrary to the not posted documents, the posted documents are stored in different tables depending on type. 2. Posted Shipment Table 110 / 111 3. Posted Invoice Table 112 / 113 4. Posted Credit Memo Table 114 / 115
Posting Documents 5
1. When codeunit 80 posts an invoice, it creates a posted invoice header (Table 112) and a set of posted invoice lines (Table 113). And, depending on set up, a posted shipment header (Table 110) and a set of posted shipment lines (Table 111).
Posting Documents 6
36 / 37 Document Type = Invoice Depending on set up
Codeunit 80
Posting Documents 7
2. When codeunit 80 posts an order, it creates a posted invoice header (Table 112), a set of posted invoice lines (Table 113), a posted shipment header (Table 110) and a set of posted shipment lines (Table 111). The unique power of orders is their ability to be partially posted.
Posting Documents 8
36 / 37 Document Type = Order
Codeunit 80
Posting Documents 9
3. When codeunit 80 posts a credit memo, it creates a posted credit memo (Table 114) and set of posted credit memo lines (Table 115).
Posting Documents 10
36 / 37 Document Type = Cr. Memo
Codeunit 80
Codeunit 80
Dimensions 1
The purpose of dimensions is to link ledgers entries to, for example, a project or a department. To that end each ledger entry has 2 fields: Department Code and Project Code that can link each ledger entry to a department or a project. Just like the account number links it to an account. This is exactly how it was up to and including version 2.70.
Dimensions 2
An important feature in version 3.0 was the introduction of an infinite number of dimensions.
Dimensions 3
As we cannot have an infinite number of fields in a table, the new feature is implemented by the Ledger Entry Dimension table Table 355.
Dimensions 4
Ledger Entry Dimensions are of cause created by the posting function 12, based on the journal line dimensions. The journal line dimensions are much like the ledger entry dimensions, just for journal lines. Again its the same table, Table 356, which is used for all types of journals, g/l, item, resource etc.
Dimensions 5
Journal line dimensions can be entered by the user. They are also automatically created, when the number of a master table (e.g. G/L acc. No., Customer No., Item No.) is entered on the journal line. This happens because Navision then copies the Default Dimension of the master table record.
Dimensions 6
The old Department Code and Project Code have been kept as Global Dimension 1 and 2 on the ledger entry itself. And of cause as entry dimensions. Which of the many dimensions that are selected as global dimensions, is decided in G/L Setup.
Dimensions 7
The 8 Shortcut Dimensions are much as Global Dimensions, but for journals. The 2 first shortcut dimensions must be the same as the global dimensions. The last 6 shortcut dimensions are not stored as fields on the journal line tables. It only looks like it.
Dimensions 8
One reason for having the global dimensions is of cause backwards compatibility and general ease of use. But beyond that, note that there is a significant difference in the power of a global and a not global dimension. It is easy to find ledger entries with a specific global dim value, you just apply the filter It is difficult to find ledger entries with a specific non global dimension, you cannot just apply a filter. To overcome this we have Analysis View, but only for general ledger and inventory.
What is C/Side
C/Side Client / Server Integrated Development Environment. The development system for the business logic in Navision. Including the C/AL Client Application Language programming language
C/Side
C/Side is not a general purpose development environment. It is accessible to others than full time programmers. It is powerful enough to allow professional programmers to structure larger programs correctly.
C/Side
It is simple and easy to learn Few and simple concepts. Few uniform object types. Simple database interface. It is safe Version principle aka read consistency. Write Transactions.
Versions
A process works on a consistent snapshot of the database.
Transactions
A Write Transactions starts automatically when a process writes to the database. A write transaction is either completed successfully or aborted. A write transaction automatically ends, when the process ends and gives control back to the user. A write transaction can be ended inside code. Either with COMIT Or by encapsulating it inside a call to the default function of a codeunit. Write transactions do not nest.
C/Side
C/Side consists offers a few basic types of objects: Table Form Report Dataport Codeunit (XMLporte) (MenuSuite)
Tables
Table
Fields
Properties Triggers
Keys
Properties
Forms
Form
Controls
Properties Triggers
Reports
Report
Dataitem
Properties Triggers
Sections
Controls Triggers Properties
Dataports
Dataport
Dataitem
Properties Triggers
Dataport fields
Controls Triggers Properties
Codeunits
Codeunit
Default function
Limited parameters and return value Special semantic of return value
C/AL
Basic control structure from Pascal IF THEN ELSE REPEAT UNTIL WHILE DO FOR TO WITH DO BEGIN END CASE OF := ; as statement separator
C/AL
Strongly typed. Variables are either Of a simple type or Of type some objects Functions Do not nest Have call by value and call by reference parameters Have simple return values Object variables must be passed as call by ref. to preserve their properties other than field values in records.
Variables
In C/AL there are Local and Global variables. Local and global variables are different in two ways: Scope and Lifetime.
Cust
Cust
Scope of Variables
The scope of a local variable is the trigger or the function in which is has been declared.
Cust
F Cust
G Cust
Temporary Tables
C/AL doesnt have pointers. The need for dynamically created variables is covered by temporary tables. Temporary tables are ordinary record variables with the property Temporay set to yes. This create a private table for this specific instance of the record variable. But with all the ordinary features of the table, including access by the well know database functions. Writing to a temporary table doesnt trigger a write transaction.
Signature Examples 0
A signature example from c
while(*t++ = *s++);
Making Changes
A good modification is: Generally Navision Like. Supporting and using standard functionality. Easy to upgrade.
Handling Objects
Development Versions Documentation
Handling Objects
For each customer we have A common development database on M: A common folder with all object files P:\CustName\Objects An object log in our Navision. Customer, Object Log
Handling Objects
Example
Development Database
The common development database contains The current versions of the objects at the customer. Data that enables us to test special features. As a rule not the customers real data. It is named as <CustName_C/SideVersion>.fdb
Development base
1. Copy database
Local database
2. Export objects
Development
Versioning
Versioning is the process of changing the fields Modified, Versionlist, Date and Time in the Object Designer. Versioning has 2 purposes: To make it easy to identify modified objects. To make it easy and safe for the customer to import the changed objects. Versioning expresses only chronology. There must never be a checkmark in Modified in a completed, versioned object.
Versioning
The customer must be able to import his objects with a dialog like this:
Versioning
Filter on Modified all objects that have been changed.
Versioning
Locate the customer in Navision. Open the Object Log. Find the next version no.
Versioning
For each object add the new version no. Apply uniform date and time. Remove checkmark in Modified
Versioning
Filter on all changed objects (*LC01.22) and export them to LC0122.FOB in the object folder Insert a line in the object log. Import the object file in the development database Send the object file to the customer
Versioning
Versioning is the fist step in documentation.
Documentation
Changes in a object, fields, keys, code, controls etc. are documented in the Documentation trigger of the object with the following syntax:
No. Version no. Initials Date - Description 01 LC01.22 FM 05.11.02 Field 50000 .. 50005 02 LC01.27 FM 27.04.05 New key: Country Code,Post Code
Documentation
Changes in code is also documented in the code:
// >> No.Initials Code // <<
DtldCVLedgEntryBuf."Initial Document Type" := "Document Type"; // >> 07.FM DtldCVLedgEntryBuf."Document Date" := "Document Date"; DtldCVLedgEntryBuf."Job No." := "Job No."; // << TransferCustLedgEntry(CVLedgEntryBuf,CustLedgEntry,TRUE);
Documentation
Variables are added at the bottom of the form, starting with a dummy variable >> LC Parameters are described in comments at the top of the function.
Documentation
Functions are added at the bottom of the form, starting with a dummy function >> LC F
Documentation
Text Constants are added at the bottom of the form, starting with a dummy constant >> LC C In so far that we are using the default naming conventions, we start with Text50000.
Upgrade
Respecting the above, we can offer our customers to upgrade their solution once a year for 10% of the original cost + minor fee per client. And make a business out of it.
Modifications
A modification is very customer specific, with a low degree of reusability. Customers, even in the same line of business, are not very similar. The standard application contains by definition the functionality which can be widely used. The partners ability to make changes allows the standard application to remain just that.
Table Triggers
All table triggers are on before triggers.
Trigger OnInsert OnDelete OnModify OnRename Databasefunction r.insert(true) r.delete(true) r.deleteall(true) r.modify(true) r.modifyall(..,true) r.rename(..)
Field Triggers
Trigger
OnValidate OnLookUp