Introduction/Explanation/Disclaimer: There are very good reasons that in Navision, Business Central and most accounting programs such as Datev and Diamand and HS bookings can not be changed afterwards. The most important is e.g. the GoB, principles of proper accounting. These are also fixed by law. This solution here for the subsequent correction of a booking date relates to e.g. § 146 paragraph 4 AO and § 239 paragraph 3. According to these regulations, when records are changed, the original content of the record must be ascertainable. If changes have to be made, it must be ensured that they are clearly indicated so that it is evident that the original record has been changed.
This function ensures this for Navision or Business Central -within a certain framework- in which
-The posting journals cannot be changed, i.e. from the Navision Fibu posting journal and the article journal it's possible to see when the original posting was created.
-The transaction itself ("posting date changed") is entered in the invoice note.
§Section 146 (1) of the German Tax Code (AO) and Section 239 (2) of the German Commercial Code (HGB) require the principle of orderly and timely accounting. According to both paragraphs, records must be complete, correct, timely and orderly And this is where my correction function for Navision or Business Central comes in. Because it is of course not used to arbitrarily move sales back and forth. This is already prohibited by the built-in security which ensures that the new posting date must be within the permitted posting range, so you can't, for example, backdate an invoice to a posting period already reported by UVA. It is used to retroactively post an invoice that was accidentally posted to an incorrect date to the correct date.
To be on the safe side, you should discuss this procedure with your auditor, before you add this function to your Navision / Business Central.
If you also want to change the booking description, you can simply extend the code unit for this purpose. Or contact me.
This Navision / Business Central function was developed in this form, unchanged, from a specific customer requirement from a Navision 2009r2 (a logical Navision 4.03), and is therefore somewhat customized, e.g. with the posting date in the sales invoice lines. That's why it is, as it stands here, also Kolo 🙂.
OBJECT Codeunit 50003 Change Posting Date { OBJECT-PROPERTIES { Date=02.04.22; Time=07:51:44; Modified=Yes; Version List=; } PROPERTIES { Permissions=TableData 17=m, TableData 21=m, TableData 32=m, TableData 112=m, TableData 113=m, TableData 169=m, TableData 203=m, TableData 254=m, TableData 379=m, TableData 5802=m; OnRun=BEGIN END; } CODE { VAR GLentry@1119455019 : Record 17; GLentry2@1119455018 : Record 17; VATentry@1119455017 : Record 254; VATentry2@1119455016 : Record 254; CustLedgEntry@1119455015 : Record 21; CustLedgEntry2@1119455014 : Record 21; DetCustLedgEntry@1119455013 : Record 379; DetCustLedgEntry2@1119455012 : Record 379; ItemLedgEntry@1119455011 : Record 32; ItemLedgEntry2@1119455010 : Record 32; ValueEntry@1119455009 : Record 5802; ValueEntry2@1119455008 : Record 5802; ResLedgEntry@1119455007 : Record 203; ResLedgEntry2@1119455006 : Record 203; JobLedgEntry@1119455005 : Record 169; JobLedgEntry2@1119455004 : Record 169; GenJrnCheckLine@1119455000 : Codeunit 11; Window@1119455020 : Dialog; NewPostingDate@1119455021 : Date; PROCEDURE GetNewPostDate@1119455002(pInitPostingDate@1119455000 : Date) : Date; BEGIN Window.OPEN('Neues Buchungsdatum: #1##########'); Window.INPUT(1,pInitPostingDate); Window.CLOSE; EXIT(pInitPostingDate); END; PROCEDURE ChangeInvoicePostingDate@1119455000(pSalesInvHeader@1119455000 : Record 112); VAR SalesInvoiceLine@1119455001 : Record 113; PaymentTerms@1119455002 : Record 3; SalesCommentLines@1119455003 : Record 44; BEGIN NewPostingDate := GetNewPostDate(pSalesInvHeader."Posting Date"); IF NewPostingDate = pSalesInvHeader."Posting Date" THEN EXIT; IF GenJrnCheckLine.DateNotAllowed(NewPostingDate) THEN; SalesCommentLines."Document Type" := SalesCommentLines."Document Type"::"Posted Invoice"; SalesCommentLines."No." := pSalesInvHeader."No."; SalesCommentLines."Line No." := 1; //Ganz oben in der Bemerkung SalesCommentLines.Date := TODAY; SalesCommentLines.Comment := STRSUBSTNO('Buchungsdatum ge„ndert! %1 -> %2',pSalesInvHeader."Posting Date",NewPostingDate); WHILE NOT SalesCommentLines.INSERT(TRUE) DO SalesCommentLines."Line No." += 1; WITH pSalesInvHeader DO BEGIN IF "Document Date" = "Posting Date" THEN "Document Date" := NewPostingDate; "Posting Date" := NewPostingDate; IF ("Payment Terms Code" <> '') AND ("Document Date" = "Posting Date") THEN BEGIN PaymentTerms.GET("Payment Terms Code"); "Due Date" := CALCDATE(PaymentTerms."Due Date Calculation","Document Date"); "Pmt. Discount Date" := CALCDATE(PaymentTerms."Discount Date Calculation","Document Date"); END; END; WITH GLentry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT GLentry2 := GLentry; GLentry2."Posting Date" := NewPostingDate; GLentry2.MODIFY; UNTIL NEXT = 0; END; WITH VATentry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT VATentry2 := VATentry; VATentry2."Posting Date" := NewPostingDate; VATentry2.MODIFY; UNTIL NEXT = 0; END; WITH CustLedgEntry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT CustLedgEntry2 := CustLedgEntry; CustLedgEntry2."Posting Date" := NewPostingDate; CustLedgEntry2."Document Date" := pSalesInvHeader."Document Date"; CustLedgEntry2."Due Date" := pSalesInvHeader."Due Date"; CustLedgEntry2."Pmt. Discount Date" := pSalesInvHeader."Pmt. Discount Date"; CustLedgEntry2.MODIFY; UNTIL NEXT = 0; END; WITH DetCustLedgEntry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT DetCustLedgEntry2 := DetCustLedgEntry; DetCustLedgEntry2."Posting Date" := NewPostingDate; DetCustLedgEntry2.MODIFY; UNTIL NEXT = 0; END; WITH ItemLedgEntry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT ItemLedgEntry2 := ItemLedgEntry; ItemLedgEntry2."Posting Date" := NewPostingDate; ItemLedgEntry2.MODIFY; UNTIL NEXT = 0; END; WITH ValueEntry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT ValueEntry2 := ValueEntry; ValueEntry2."Posting Date" := NewPostingDate; ValueEntry2.MODIFY; UNTIL NEXT = 0; END; WITH ResLedgEntry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT ResLedgEntry2 := ResLedgEntry; ResLedgEntry2."Posting Date" := NewPostingDate; ResLedgEntry2.MODIFY; UNTIL NEXT = 0; END; WITH JobLedgEntry DO BEGIN SETCURRENTKEY("Document No."); SETRANGE("Document No.",pSalesInvHeader."No."); SETRANGE("Posting Date",pSalesInvHeader."Posting Date"); IF FINDSET THEN REPEAT JobLedgEntry2 := JobLedgEntry; JobLedgEntry2."Posting Date" := NewPostingDate; JobLedgEntry2.MODIFY; UNTIL NEXT = 0; END; pSalesInvHeader.MODIFY; SalesInvoiceLine.SETRANGE("Document No.",pSalesInvHeader."No."); SalesInvoiceLine.MODIFYALL("Posting Date",pSalesInvHeader."Posting Date"); END; BEGIN { } END. } }
In addition, the separate code unit ensures that you can delegate the entire function only to employees who work responsibly ("Access Rights"))