Buchungsdatum oder Buchungsbeschreibung in Navision oder Business Central ändern

Nav123: Navision, Showare, OrderApp

Einleitung/Erklärung/Disclaimer: Es gibt sehr gute Gründe, das in Navision und Business Central und den meisten Buchhaltungsprogrammen wie z.B. Datev und Diamand und HS Buchungen nachträglich nicht mehr veränderbar sind. Der Wichtigste ist z.B. die GoB, Grundsätze ordnungsgemäßer Buchführung. Diese sind auch gesetzlich fixiert. Diese Lösung hier für das nachträgliche korrigieren eines Buchungsdatums betrifft z.B. § 146 Abs. 4 AO und § 239 Abs. 3. Nach diesen Verordnungen muss bei der Änderung von Aufzeichnungen der ursprüngliche Inhalt der Aufzeichnung feststellbar ist. Falls Änderungen vorgenommen werden müssen, muss die Kenntlichmachung dieser sichergestellt werden, sodass klar ersichtlich ist, dass die ursprüngliche Aufzeichnung geändert wurde.
Dies stellt diese Funktion für Navision oder Business Central -in einem gewissen Rahmen- dadurch sicher, das
-Die Buchungsjournale nicht verändert werden, d.H. aus dem Navision Fibu Buchungsjournal und dem Artikeljournal kann weiter herausgelesen werden, wann die Ursprungsbuchung erzeugt wurde.
-Der Vorgang selbst („Buchungsdatum geändert“) in die Rechnungsbemerkung eingetragen wird.

§146 Abs. 1 AO und § 239 Abs. 2 HGB verlangen den Grundsatz der geordneten und zeitgerechten Buchung. Nach beiden Paragraphen müssen Aufzeichnungen vollständig, richtig, zeitgerecht und geordnet vorgenommen werden. Und genau hier setzt meine Korrekturfunktion für Navision oder Business Central ein. Denn Sie dient natürlich nicht dazu, beliebig Umsätze hin und her zu schieben. Dies verbietet bereits die eingebaute Sicherheit, dass das neue Buchungsdatum im erlaubten Buchungsbereich liegen muss, so dass Sie z.B. keine Rechnung in einen bereits per UVA gemeldeten Buchungszeitraum rückdatieren können. Sie dient dazu, eine versehentlich auf ein falsches Datum gebuchte Rechnung nachträglich auf das korrekte Datum zu buchen.

Um auf Nummer Sicher zu gehen, sollten Sie dieses Vorgehen mit ihrem Wirtschaftsprüfer absprechen, bevor Sie diese Funktion in Ihr Navision / Business Central einbauen.

Wenn Sie auch noch die Buchungsbeschreibung ändern möchten, können Sie die Codeunit einfach dafür erweitern. Oder mich ansprechen.

Diese Navision / Business Central Funktion ist in dieser Form unverändert aus einer konkreten Kundenanforderung aus einem Navision 2009r2 (ein logisches Navision 4.03) entstanden, und daher schon etwas individuell, z.B. mit dem Buchungsdatum in den Verkauf Rechungszeilen. Dafür ist sie, so wie sie hier steht, auch 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.
  }
}

Außerdem ist durch die eigene Codeunit sichergestellt, das Sie die ganze Funktion nur an verantwortlich arbeitende Mitarbeiter delegieren können („Zugriffsrechte“)