Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Exclusive offer: get 50% off this eBook here
WCF 4.0 Multi-tier Services Development with LINQ to Entities

WCF 4.0 Multi-tier Services Development with LINQ to Entities — Save 50%

Build SOA applications on the Microsoft platform with this hands-on WCF 4.0 book and eBook guide updated for VS2010

$29.99    $15.00
by Mark Brummel | June 2010 | Enterprise Articles Microsoft

Microsoft Dynamics NAV 2009 is a very complete ERP package, but unlike other ERP packages it has a design capable of providing an open structure and a development platform. The idea is to provide 80% of the solution out of the box and allow the other 20% to be designed by qualified business application developers.

In the first part of the three part article series we have learned how to apply reverse engineering to customize our application

In this article, by Mark Brummel, author of Microsoft Dynamics NAV 2009 Application Design we will learn:

  • how Journals and Ledger entries work throughout the system
  • how to create your own Journal application.

(Further on Microsoft Dynamics NAV:here.)

Designing a journal

Now it is time to start on the product part of the Squash Application. In this part we will no longer reverse engineer in detail. We will learn how to search in the standard functionality and reuse parts in our own software.

For this part we will look at resources in Microsoft Dynamics NAV. Resources are similar to use products as Items but far less complex making it easier to look and learn.

Squash Court master data

Our company has 12 courts that we want to register in Microsoft Dynamics NAV. This master data is comparable to resources so we'll go ahead and copy this functionality. Resources are not attached to umbrella data like the vendor/squash player tables. We need the number series again so we'll add a new number series to our squash setup table.

The Squash Court table should look like this after creation:

Microsoft Dynamics NAV 2009: Apply reverse engineering to customize our application

Chapter objects

With this chapter some objects are required. A description of how to import these objects can be found in the Appendix.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

After the import process is completed make sure that your current database is the default database for the role tailored client and run Page 123456701, Squash Setup.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

From this page select the Action Initialise Squash Application. This will execute the C/AL code in the InitSquashApp function of this page, which will prepare demo data for us to play with. The objects are prepared and tested in a Microsoft Dynamics NAV 2009 SP1 W1 database.

Reservations

When running a squash court we want to be able to keep track of reservations.Looking at standard Dynamics NAV functionality it might be a good idea to create Squash player Journal. The Journal can create entries for reservations that can be invoiced.

A journal needs the object structure. The journal is prepared in the objects delivered with this article. Creating a new journal from scratch is a lot of work and can easily lead to making mistakes. It is easier and safer to copy an existing Journal structure from the standard application that is similar to the journal we need for our design.

In our example we have copied the Resource Journals.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

You can export these objects to text format, and then rename and renumber the objects to be reused easily. The squash journal objects are renumbered and renamed from the resource journal.

all journals have the same structure. The template, batch and register tables are almost always the same, whereas the journal line and ledger entry table contain function specific fields. Let's have a look at all of them one by one.

Journal Template

The Journal Template has several fields as shown in the following screenshot:

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Lets discuss these fields in more detail:

  • Name: This is the unique name. It is possible to define as many Templates as required but usually one Template per Form ID and one for Recurring will do. If you want journals with different source codes you need to have more templates.
  • Description: A readable and understandable description of its purpose.
  • Test Report ID: All Templates have a test report that allows the user to check for posting errors.
  • Form ID: For some journals, more UI objects are required. For example, the General Journals have a special form for bank and cash.
  • Posting Report ID: This report is printed when a user selects Post and Print.
  • Force Posting Report: Use this option when a posting report is mandatory.
  • Source Code: Here you can enter a Trail Code for all the postings done via this Journal.
  • Reason Code: This functionality is similar to source sodes.
  • Recurring: Whenever you post lines from a recurring journal, new lines are automatically created with a posting date defined in the recurring date formula.
  • No. Series: When you use this feature the Document No. in the Journal Line is automatically populated with a new number from this Number Series.
  • Posting No. Series: Use this feature for recurring journals.

Journal Batch

Journal Batch has various fields as shown in the following screenshot:

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Lets discuss these fields in more detail:

  • Journal Template Name: The name of the Journal Template this batch refers to
  • Name : Each batch should have a unique code
  • Description: A readable and explaining description for this batch
  • Reason Code: When populated, this Reason Code will overrule the Reason Code from the Journal Template
  • No. Series: When populated this No. Series will overrule the No. Series from the Journal Template
  • Posting No. Series: When populated this Posting No. Series will overrule the Posting No. Series from the Journal Template

Register

The Register table has various fields as shown in the following screenshot:

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Lets discuss these fields in more detail:

  • No.: This field is automatically and incrementally populated for each transaction with this journal. There are no gaps between the numbers.
  • From Entry No.: A reference to the first Ledger Entry created is with this transaction.
  • To Entry No.: A reference to the last Ledger Entry is created with this transaction.
  • Creation Date: Always populated with the real date when the transaction was posted.
  • User ID: The ID of the end user who has posted the transaction.

The Journal

The journal line has a number of mandatory fields that are required for all journals and some fields that are required for its designed functionality.

In our case the journal should create a reservation which then can be invoiced. This requires some information to be populated in the lines.

Reservation

The reservation process is a logistical process that requires us to know the number of the Squash Court, the date and the time of the reservation. We also need to know how long the players want to play. To check the reservation it might also be useful to store the number of the Squash Player.

Invoicing

For the invoicing part we need to know the price we need to invoice. It might also be useful to store the cost to see our profit. For the system to figure out the proper G/L Account for the turnover we also need to define a General Product Posting Group.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

  • Journal Template Name: This is a reference to the current journal template.
  • Line No. : Each journal has a virtually unlimited number of lines; this number is automatically incremented by 10000 allowing lines to be created in between.
  • Entry Type: Reservation or invoice.
  • Document No.: This number can be used to give to the squash player as a reservation number. When the entry type is invoice, it is the invoice number.
  • Posting Date: Posting date is usually the reservation date but when the entry type is invoice it might be the date of the invoice which might differ from the posting date in the general ledger.
  • Squash Player No.: A reference to the squash player who has made the reservation.
  • Squash Court No.: A reference to the squash court.
  • Description: This is automatically updated with the number of the squash court, reservation date and times, but can be changed by the user.
  • Reservation Date: The actual date of the reservation.
  • From Time: The starting time of the reservation. We allow only whole or half hours.
  • To Time: The ending time of the reservation. We only allow whole and half hours. This is automatically populated when people enter a quantity.
  • Quantity: The number of hours playing time. We only allow units of 0.5 to be entered here. This is automatically calculated when the times are populated.
  • Unit Cost: The cost to run a Squash Court for one hour.
  • Total Cost: The cost for this reservation.
  • Unit Price: The invoice price for this reservation per hour. This depends on whether or not the squash player is a member or not.
  • Total Price: The total invoice price for this reservation.
  • Shortcut Dimension Code 1 & 2: A reference to the dimensions used for this transaction.
  • Applies-to Entry No.: When a reservation is invoiced, this is the reference to the squash entry no. of the reservation.
  • Source Code: Inherited from the journal batch or template and used when posting the transaction.
  • Chargeable: When this option is used, there will not be an invoice for the reservation.
  • Journal Batch Name: A reference to the journal batch that is used for this transaction.
  • Reason Code: Inherited from the journal batch or template, and used when posting the transaction.
  • Recurring Method: When the journal is a recurring journal you can use this field to determine whether the amount field is blanked after posting the lines.
  • Recurring Frequency: This field determines the new posting date after the recurring lines are posted.
  • Gen. Bus. Posting Group: The combination of general business and product posting group determines the G/L cccount for turnover when we invoice the reservation. The Gen. Bus. Posting Group is inherited from the bill-to customer.
  • Gen. Prod. Posting Group: This will be inherited from the squash player.
  • External Document No.: When a squash player wants us to note a reference number we can store it here.
  • Posting No. Series: When the journal template has a posting no. series it is populated here to be used when posting.
  • Bill-to Customer No.: This determines who is paying for the reservation. We will inherit this from the squash player.

So now we have a place to enter reservations but we have something to do before we can start doing this.

Some fields were determined to be inherited and calculated:

  • The time field needs calculation to avoid people entering wrong values
  • The Unit Price should be calculated
  • The Unit Cost, Posting groups and Bill-to Customer No. need to be inherited
  • As final cherry on top, we will look at implementing dimensions
WCF 4.0 Multi-tier Services Development with LINQ to Entities Build SOA applications on the Microsoft platform with this hands-on WCF 4.0 book and eBook guide updated for VS2010
Published: June 2010
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

(Further on Microsoft Dynamics NAV:here.)

Time calculation

As it comes to the times we want only to allow specific start and end times. Our Squash Court can be used in blocks of half an hour. The quantity field should be calculated based on the entered times and vice versa.

To have the most flexible solution possible we will create a new table with allowed starting and ending times. This table will have two fields; Reservation Time and Duration as shown in the following screenshot:

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Duration will be a decimal field that we will promote to a Sum Index Field. This will enable us to use SIFT to calculate the Quantity.

When populated the table will look like this:

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

The time fields in the squash journal table will now get a table relation with this table. This prevents a user from entering values that are not in the table thus only valid starting and ending times. This is all done without any C/AL code and flexible when times change later.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Now we need some code that calculates the quantity based on the user's input:

From Time - OnValidate()
CalcQty;

To Time - OnValidate()
CalcQty;

CalcQty()
IF ("From Time" <> 0T) AND ("To Time" <> 0T) THEN BEGIN
IF "To Time" <= "From Time" THEN
FIELDERROR("To Time");
ResTime.SETRANGE("Reservation Time", "From Time",
"To Time");
ResTime.FIND('+');
ResTime.NEXT(-1);
ResTime.SETRANGE("Reservation Time", "From Time",
ResTime."Reservation Time");
ResTime.CALCSUMS(Duration);
VALIDATE(Quantity, ResTime.Duration);
END;

When a user enters a value in the From Time or To Time the function CalcQty is executed. This checks if both fields have a value and then checks whether To Time is larger than From Time.

Then we place a filter on the Reservation Time table. When a user now makes a reservation from 8:00 to 9:00 there are three records in the filter making the result of the CALCSUMS (Total of all records) of duration 1, 5. Therefore we find the previous reservation time and use that.

This example shows how easy it is to use built in Microsoft Dynamics NAV functionality like table relations and CALCSUMS instead of complex time calculations which we could have also used.

Price calculation

Microsoft Dynamics NAV has a special technique to determine prices. Prices are stored in a table with all possible parameters as fields and by filtering down on these fields the best price is determined. If required with extra logic to find the lowest (or highest) price if more prices are found.

To look, learn, and love this part of the standard application we have used table Sales Price (7002) and Sales Price Calc. Mgt. (7000) even though we only need a small part of this functionality. This mechanism of price calculation is used throughout the application and offers a normalized way of calculating sales prices. A similar construction is used for purchase prices with table purchase price (7012) and Purch.Price calc. Mgt. (7010).

Squash prices

In our case we have already determined that we have a special rate for members, but let's say we have also a special rate for daytime and evening in winter and summer.

This could make our table look like this:

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

We can make special prices for members on dates for winter and summer and make a price only valid until a certain time. We can also make a special price for a court.

This table could be creatively expanded with all kinds of codes until we end up with table sales price (7002) in the standard product which was the template for our example.

Price calc mgt. codeunit

To calculate the price we need a codeunit similar to the standard product. This codeunit is called with a squash journal line record and stores all valid prices in a buffer table and then finds the lowest price if there is an overlap:

FindSquashPrice()
WITH FromSquashPrice DO BEGIN
SETFILTER("Ending Date",'%1|>=%2',0D,StartingDate);
SETRANGE("Starting Date",0D,StartingDate);

ToSquashPrice.RESET;
ToSquashPrice.DELETEALL;

SETRANGE(Member, IsMember);

SETRANGE("Ending Time", 0T);
SETRANGE("Squash Court No.", '');
CopySquashPriceToSquashPrice(FromSquashPrice,ToSquashPrice);

SETRANGE("Ending Time", 0T);
SETRANGE("Squash Court No.", CourtNo);
CopySquashPriceToSquashPrice(FromSquashPrice,ToSquashPrice);

SETRANGE("Squash Court No.", '');
IF StartingTime <> 0T THEN BEGIN
SETFILTER("Ending Time",'%1|>=%2',000001T,StartingTime);
CopySquashPriceToSquashPrice(FromSquashPrice,
ToSquashPrice);
END;

SETRANGE("Squash Court No.", CourtNo);
IF StartingTime <> 0T THEN BEGIN
SETFILTER("Ending Time",'%1|>=%2',000001T,StartingTime);
CopySquashPriceToSquashPrice(FromSquashPrice,
ToSquashPrice);
END;
END;

If there is no price in the filter it uses the unit price from the Squash Court.

CalcBestUnitPrice()
WITH SquashPrice DO BEGIN
FoundSquashPrice := FINDSET;
IF FoundSquashPrice THEN BEGIN
BestSquashPrice := SquashPrice;
REPEAT
IF SquashPrice."Unit Price" <
BestSquashPrice."Unit Price"
THEN
BestSquashPrice := SquashPrice;
UNTIL NEXT = 0;
END;
END;
// No price found in agreement
IF BestSquashPrice."Unit Price" = 0 THEN
BestSquashPrice."Unit Price" := SquashCourt."Unit Price";
SquashPrice := BestSquashPrice

Inherited data

To use the journal for the product part of the application we want to inherit some of the fields from the master data tables. In order to make that possible we need to copy and paste these fields from other tables to our master data table and populate it.

In our example we can copy and paste the fields from the Resource table (156). We also need to add code to the OnValidate triggers in the Journal Line table.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

The Squash Court table for example is expanded with the fields Unit Code, Unit Price, Gen. Prod. Posting Group, and VAT Prod. Posting Group (as shown in the previous screenshot)

We can now add code to the OnValidate of the Squash Court No. field in the journal line table:

Squash Court No. - OnValidate()
IF SquashCourt.GET("Squash Court No.") THEN BEGIN
Description := SquashCourt.Description;
"Unit Cost" := SquashCourt."Unit Cost";
"Gen. Prod. Posting Group" := SquashCourt."Gen. Prod. Posting
Group";
FindSquashPlayerPrice;
END;

Please note that unit price is used in the squash price calc. mgt. codeunit that is executed from the function FindSquashPlayerPrice.

Dimensions

In Microsoft Dynamics NAV, dimensions are defined in master data and posted to the ledger entries to be used in analysis view entries.

In between that journey they move around a lot in different tables:

  • Table 348 | Dimension: Here the main dimension codes are defined.
  • Table 349 | Dimension Value: Here each dimension can have an unlimited number of values.
  • Table 350 | Dimension Combination: In this table we can block certain combinations of dimension codes.
  • Table 351 | Dimension Value Combination: In this table we can block certain combinations of dimension values. If this table is populated, the value limited is populated in the dimension combination table for these dimensions.
  • Table 352 | Default Dimension: This table is populated for all master data that has dimensions defined.
  • Table 354 | Default Dimension Priority: When more than one master-data record in one transaction have the same dimensions, it is possible here to set priorities.
  • Table 355 | Ledger Entry Dimension: This is the history table for posted dimensions in ledger entries.
  • Table 356 | Journal Line Dimension: This is a buffer table for dimensions in unposted journal lines.
  • Table 357 | Document Dimension: This is a buffer table for dimensions in unposted documents.
  • Table 358 | Production Document Dimension: This is table saves dimensions especially for production orders.
  • Table 359 | Posted Document Dimension: This is the history table for posted dimensions in posted documents.
  • Codeunit 408 | DimensionManagement: This codeunit is the single point in the application where all dimension movement is done.

In our application dimensions are moved from the squash player, squash court, and customer table via the squash journal line to the squash ledger entries. When we create an invoice we move the dimensions from the ledger entries to the sales line table.

Master data

To connect dimensions to master data we first need to allow this changing codeunit 408 dimension management.

SetupObjectNoList()
TableIDArray[1] := DATABASE::"Salesperson/Purchaser";
TableIDArray[2] := DATABASE::"G/L Account";
TableIDArray[3] := DATABASE::Customer;
...
TableIDArray[22] := DATABASE::"Service Item Group";
TableIDArray[23] := DATABASE::"Service Item";


//* Squash Application
TableIDArray[49] := DATABASE::"Squash Player";
TableIDArray[50] := DATABASE::"Squash Court";
//* Squash Application


Object.SETRANGE(Type,Object.Type::Table);


FOR Index := 1 TO ARRAYLEN(TableIDArray) DO BEGIN
...

The variable TableIDArray has a default number of 23 dimensions. We have changed this to 50.

By leaving gaps we allow Microsoft to add master data tables in the future without us having to change our code

Without this change, the system would return an error message when we tried to use dimensions.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

Next change is to add the Global Dimension fields to the master data tables. They can be copied and pasted from other master data tables (as shown in the following screenshot):

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

When these fields are validated the function ValidateShortcutDimCode is executed.

ValidateShortcutDimCode()
DimMgt.ValidateDimValueCode(FieldNumber,ShortcutDimCode);
DimMgt.SaveDefaultDim(DATABASE::"Squash Player","No.",
FieldNumber,ShortcutDimCode);
MODIFY;

Journal

When we use the master data records in the Journal table, the dimensions are copied from the default dimension table to the journal line dimension table. This is done using this piece of code that is called from the OnValidate of each master data reference field:

CreateDim()
TableID[1] := Type1;
No[1] := No1;
TableID[2] := Type2;
No[2] := No2;
TableID[3] := Type3;
No[3] := No3;
"Shortcut Dimension 1 Code" := '';
"Shortcut Dimension 2 Code" := '';
DimMgt.GetDefaultDim(
TableID,No,"Source Code",
"Shortcut Dimension 1 Code","Shortcut Dimension 2 Code");
IF "Line No." <> 0 THEN
DimMgt.UpdateJnlLineDefaultDim(
DATABASE::"Squash Journal Line","Journal Template Name",
"Journal Batch Name","Line No.",0,
"Shortcut Dimension 1 Code","Shortcut Dimension 2 Code");

To decide which dimensions to inherit we should first analyze which master data is used in our journal that is using default dimensions.

Squash Court No. - OnValidate()
CreateDim(
DATABASE::"Squash Court","Squash Court No.",
DATABASE::"Squash Player","Squash Player No.",
DATABASE::Customer,"Bill-to Customer No.");

In our case Table[1] is Squash Player, Table[2] is Squash Court, and Table[3] is Customer. The dimension management codeunit makes sure everything is copied. We can use standard Microsoft Dynamics NAV functions.

Posting

When we post a journal using codeunit squash jnl.-post line (123456703) the dimensions are first copied into a posting buffer table.

RunWithCheck()
SquashJnlLine.COPY(SquashJnlLine2);
TempJnlLineDim.RESET;
TempJnlLineDim.DELETEALL;
DimMgt.CopyJnlLineDimToJnlLineDim(TempJnlLineDim2,
TempJnlLineDim);
Code;
SquashJnlLine2 := SquashJnlLine;

Then after we have created the ledger entry and know the number, the ledger entry dimensions are created. Again we use standard Microsoft Dynamics NAV functions without changing them.

Code()

...

SquashLedgEntry.INSERT;

DimMgt.MoveJnlLineDimToLedgEntryDim(
TempJnlLineDim,DATABASE::"Squash Ledger Entry",
SquashLedgEntry."Entry No.");

NextEntryNo := NextEntryNo + 1;

Document

For moving ledger entry dimensions to document dimensions, Microsoft Dynamics NAV does not have a standard function, so we have copied the function CopyLedgEntryDimToJnlLnDim to CopyLedgEntryDimToDocDim.

CopyLedgEntryDimToDocDim()
WITH FromLedgEntryDim DO
IF FINDSET THEN
REPEAT
ToDocDim."Dimension Code" := "Dimension Code";
ToDocDim."Dimension Value Code" :=
"Dimension Value Code";
ToDocDim.INSERT;
UNTIL NEXT = 0;

This function we can then call from our combine invoicing report, which we will create later in the other article in the invoicing section.

CreateLn()
...

DocDim."Table ID" := DATABASE::"Sales Line";
DocDim."Document Type" := SalesLn."Document Type";
DocDim."Document No." := SalesLn."Document No.";
DocDim."Line No." := SalesLn."Line No.";

LedgEntryDim.SETRANGE("Table ID",
DATABASE::"Squash Ledger Entry");
LedgEntryDim.SETRANGE("Entry No.", "Entry No.");
DimMgt.CopyLedgEntryDimToDocDim(LedgEntryDim, DocDim);

The posting process

Our journal is now ready to be posted. We've implemented all business logic, except the posting code.

Microsoft Dynamics NAV 2009: Using the journals and entries in a custom application

The posting process of a journal in Microsoft Dynamics NAV has several codeunits for the structure:

  • Jnl.-Check Line: This codeunit checks if the journal line is valid for posting
  • Jnl.-Post Line: This codeunit does the actual creation of the ledger entry and register tables, and calls other jnl.-post line codeunits if necessary to provide the transaction structure in Chapter 1.
  • Jnl.-Post Batch: This codeunit loops through all journal lines in a journal batch and posts all the lines. There is a dialog.
  • Jnl.-Post: This is the codeunit that is called from the page. It calls the codeunit jnl.-post batch and takes care of some user messaging.
  • Jnl.-Post+Print: This is the codeunit that is called when you push post + print. It does the same as the jnl.-post codeunit but with the additional printing of a report defined in the journal template.
  • Jnl.-B.Post: Posts all the journal lines that have no errors and marks the ones that have errors.
  • Jnl.-B.Post+Print: Does the same as Jnl.-B.Post but with the additional printing of a report defined in the journal template.

Check line

Let's have a look at the check line codeunit. When it comes to testing, Microsoft Dynamics NAV has a simple rule:

Test near, Test far, Do-it, Clean up

First we need to test the field in the journal line table, then read external data tables to check if all is good, then post the lines and delete the data from the journal table.

It does not make sense to read the G/L setup table from the database if the document no. in our own table is blank, or to start the posting process and error out because the Posting Date is outside of a valid range. This would cause a lot of unnecessary I/O from the database to the client.

RunCheck()
WITH SquashJnlLine DO BEGIN
IF EmptyLine THEN
EXIT;
TESTFIELD("Squash Player No.");
TESTFIELD("Squash Court No.");
TESTFIELD("Posting Date");
TESTFIELD("Gen. Prod. Posting Group");
TESTFIELD("From Time");
TESTFIELD("To Time");
TESTFIELD("Reservation Date");
TESTFIELD("Bill-to Customer No.");

IF "Entry Type" = "Entry Type"::Invoice THEN
TESTFIELD("Applies-to Entry No.");
IF "Applies-to Entry No." <> 0 THEN
TESTFIELD("Entry Type", "Entry Type"::Invoice);
IF "Posting Date" <> NORMALDATE("Posting Date") THEN
FIELDERROR("Posting Date",Text000);
IF (AllowPostingFrom = 0D) AND (AllowPostingTo = 0D) THEN
...
END;
...
IF NOT DimMgt.CheckJnlLineDimComb(JnlLineDim) THEN
...
TableID[1] := DATABASE::"Squash Player";
No[1] := "Squash Player No.";
...
IF NOT DimMgt.CheckJnlLineDimValuePosting(JnlLineDim,
TableID,No)
THEN
IF "Line No." <> 0 THEN
...

Here we can clearly see that fields in our table are checked first, then the date validation, and lastly the dimension checking.

Post line

The actual posting code turns out to be quite simple. The values are checked and then a Register is created or updated.

Code()

WITH SquashJnlLine DO BEGIN
IF EmptyLine THEN
EXIT;

SquashJnlCheckLine.RunCheck(SquashJnlLine,TempJnlLineDim);

IF NextEntryNo = 0 THEN BEGIN
SquashLedgEntry.LOCKTABLE;
IF SquashLedgEntry.FIND('+') THEN
NextEntryNo := SquashLedgEntry."Entry No.";
NextEntryNo := NextEntryNo + 1;
END;

IF SquashReg."No." = 0 THEN BEGIN
SquashReg.LOCKTABLE;
IF (NOT SquashReg.FIND('+')) OR ... THEN BEGIN
SquashReg.INIT;
SquashReg."No." := SquashReg."No." + 1;
...
SquashReg.INSERT;
END;
END;
SquashReg."To Entry No." := NextEntryNo;
SquashReg.MODIFY;

SquashPlayer.GET("Squash Player No.");
SquashPlayer.TESTFIELD(Blocked,FALSE);

IF (GenPostingSetup."Gen. Bus. Posting Group" <>
"Gen. Bus. Posting Group") OR
(GenPostingSetup."Gen. Prod. Posting Group" <>
"Gen. Prod. Posting Group")
THEN
GenPostingSetup.GET("Gen. Bus. Posting Group",
"Gen. Prod. Posting Group");
SquashLedgEntry.INIT;
SquashLedgEntry."Entry Type" := "Entry Type";
SquashLedgEntry."Document No." := "Document No.";
...
SquashLedgEntry."No. Series" := "Posting No. Series";
SquashLedgEntry.INSERT;

All the fields are simply moved to the ledger entry table.

This is what makes Microsoft Dynamics NAV simple and powerful.

Here we can clearly see how easy it is to add a field to a posting process. Just add the fields to the journal line, the ledger entry, and add one line of code to the posting process.

Summary

In this article we have learned:

  • how Journals and Ledger entries work throughout the system
  • how to create your own Journal application.

Further resources on this subject:

WCF 4.0 Multi-tier Services Development with LINQ to Entities Build SOA applications on the Microsoft platform with this hands-on WCF 4.0 book and eBook guide updated for VS2010
Published: June 2010
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

About the Author :


Mark Brummel

Mark Brummel is an all-round Microsoft Dynamics NAV specialist. He started in 1997 as an end user but quickly moved to the other side of the table. For ten years he has worked for resellers, specializing in designing and maintaining add-on systems. Some of these add-on systems exceed the standard product in size and complexity. Also coaching colleagues and troubleshooting 'impossible' problems are a passion and part of his day-to-day work. Mark has trained most of the experienced NAV developers for the NAV 2009 product in The Netherlands and Belgium and he has been hired by almost every NAV reseller in the Benelux.

Mark works as a freelancer. His main focus area is helping out end users in implementations all over the world.
Mark was the first worldwide to use the NAV 2009 (CTP3) product in a production system, feeding back valuable information to Microsoft. Today he is still involved in projects to provide input for future versions and test new CTP releases.

A special project has been performance tuning of the Dynamics NAV product on SQL Server. From 2007 to 2009 he was involved in the development of the 'SQL Perform Tools' as business partner of SQL Perform Benelux. As a unique specialist he has done break-through research in improving the performance of Dynamics NAV on SQL Server.

When time is left, Mark maintains his blog on www.brummelds.com. This blog contains a wide range of articles about both the Microsoft Dynamics NAV and SQL Server products. He is also a frequent speaker at Microsoft events and writer for independent Dynamics NAV websites and user groups. In 2006 Mark was rewarded by Microsoft with the Most Valuable Professional award for his contribution to the online and offline communities. In 2007 and 2009 he reviewed Programming Microsoft Dynamics NAV and Programming Microsoft Dynamics NAV 2009.

Books From Packt


Joomla! 1.5: Beginner's Guide
Joomla! 1.5: Beginner's Guide

Refactoring with Microsoft Visual Studio 2010
Refactoring with Microsoft Visual Studio 2010

Microsoft Silverlight 4 Data and Services Cookbook
Microsoft Silverlight 4 Data and Services Cookbook

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide
Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

Programming Microsoft Dynamics NAV 2009
Programming Microsoft Dynamics NAV 2009

Microsoft Dynamics AX 2009 Programming: Getting Started
Microsoft Dynamics AX 2009 Programming: Getting Started

Oracle JRockit: The Definitive Guide
Oracle JRockit: The Definitive Guide

Microsoft Dynamics AX 2009 Development Cookbook
Microsoft Dynamics AX 2009 Development Cookbook


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software