(Further on Microsoft Dynamics NAV:here.)
The last issue on our to-do list is the invoicing process. For this we use a part of the standard application.
invoicing is done using a document structure with a header and a line table. This has a posting routine that will start the journal transactions.
For our application we need to create the invoice document and make sure that when posted, it updates our sub administration.
The sales invoice documents in Microsoft Dynamics NAV are stored in the sales header (36) and sales line (37) tables. We will create a report that will combine the outstanding reservation entries into invoices allowing the user to filter on a specific entry or any other field value in the squash ledger entry table.
Reports in Microsoft Dynamics NAV are not just for printing documents, we can also use its dataset capabilities to start batch jobs.
To enable this, our batch job needs to have a special property, ProcessingOnly (as shown in the following screenshot), so let’s start a blank report and do this.
The report will browse through the squash ledger entries filtered on entry type reservation and open (yes). The sorting is Open, Entry Type, Bill-to Customer No. and Reservation Date (as shown in the following screenshot):
Because bill-to customer no. is the first non filtered value in the sorting we can assume that if this value changes we need a new sales header.
For every Squash Ledger Entry we will generate a sales line.
Squash Ledger Entry - OnAfterGetRecord()
IF "Bill-to Customer No." <> SalesHdr."Bill-to Customer No."
The code to create a sales header looks like this:
SalesHdr."Document Type" := SalesHdr."Document Type"::Invoice;
SalesHdr."Document Date" := WORKDATE;
SalesHdr."Posting Date" := WORKDATE;
SalesHdr.VALIDATE("Sell-to Customer No.",
"Squash Ledger Entry"."Bill-to Customer No.");
NextLineNo := 10000;
CounterOK := CounterOK + 1;
The function SetHideValidationDialog makes sure that we don’t get pop-up messages while validating values. This is a standard function in Microsoft Dynamics NAV which is designed for this purpose.
To create a sales line we need a minimum of this code. Please note that we added the field Applies-to Squash Entry No. to the sales line table.
WITH "Squash Ledger Entry" DO BEGIN
GenPstSetup.GET("Gen. Bus. Posting Group",
"Gen. Prod. Posting Group");
SalesLn."Document Type" := SalesHdr."Document Type";
SalesLn."Document No." := SalesHdr."No.";
SalesLn."Line No." := NextLineNo;
SalesLn."System-Created Entry" := TRUE;
SalesLn.Type := SalesLn.Type::"G/L Account";
SalesLn.VALIDATE("No.", GenPstSetup."Sales Account");
SalesLn.Description := Description;
SalesLn.VALIDATE("Unit Price", "Unit Price");
SalesLn.VALIDATE("Unit Cost (LCY)", "Unit Cost");
SalesLn."Applies-to Squash Entry No." := "Entry No.";
NextLineNo := NextLineNo + 10000;
When you add fields to the sales and purchase document tables, make sure to also add these to the posted equivalents of these tables with the same number. This way you make sure that the information is copied to the historic data. This is done using the TRANSFERFIELDS command.
If the combined invoicing takes some time it might be good to show the user a process bar. For this Microsoft Dynamics NAV has a standard structure.
The window shows the bill-to customer no. it is currently processing and a bar going from 1 percent to 100 percent. This is calculated by keeping a counter.
At the end of the process we show a message telling the user how many invoices were created out of the number of squash ledger entries.
Squash Ledger Entry - OnPreDataItem()
CounterTotal := COUNT;
Squash Ledger Entry - OnAfterGetRecord()
Counter := Counter + 1;
Window.UPDATE(1,"Bill-to Customer No.");
Window.UPDATE(2,ROUND(Counter / CounterTotal * 10000,1));
Squash Ledger Entry - OnPostDataItem()
To do this we need some variables. The Window variable is of type Dialog whilst Counter, CounterTotal and CounterOK are integers (as shown in the following screenshot):
The constant Text000 has a special values #1########## and @2@@@@@@@@@@@@@ (as shown in the following screenshot). The first allows us to show and update the text; the latter is to create the process bar:
The result is this:
We see the following window when invoice creation process completes:
bars in combination with the impact on performance at http://www.mibuso.com/howtoinfo.asp?FileID=17
Now, our sales invoice is ready so we can start making the necessary changes to the posting process. Posting a sales document is done using a single posting codeunit and some helper objects:
- Report 297: This report can be used to post more than one document at the same time with a filter.
- Codeunit 80: This is the actual posting routine we are going to change.
- Codeunit 81: This codeunit is called from the user interface and has a dialog whether the user wants to ship, invoice or both if the document is an order, and a yes/no if the document is an invoice or credit memo.
- Codeunit 82: When the user chooses post and print this codeunit is executed which does the same as codeunit 81 plus printing a report.
So we will make a change to codeunit 80. This codeunit has a specific structure that we need to understand before we go in and make the change.