Dynamics 365 Business Central: Can we insert/modify/delete posted data (Posted Documents & Posted Entries) via AL???

Dynamics 365 Business Central

Hi, Readers.
Today I would like to briefly discuss a question that I always get asked, can we insert/modify/delete posted data (Posted Documents & Posted Entries) via AL???
As you might know, in addition to the setup data, there are two main types of data in Business Central, one is pre-posting data such as master data (Customers, Items…), and transactions data (Sales Orders, General Journals…), and the other is posted data such as Posted Sales Invoices, Customer Ledger Entries, etc. In general, we can modify and delete the pre-posting data but we can’t edit and delete the posted data.

First of all, for these posted tables, we cannot insert, modify, or delete them through the Configuration Package. For example, G/L Entry (17)

Sorry, the current permissions prevented the action. (TableData 17 G/L Entry Insert: Base Application)

A similar error is prompted when we try to modify it in the AL code. For example, clear the Document Type of the selected line.

Sorry, the current permissions prevented the action. (TableData 17 G/L Entry Modify: Test Extension)

PS: There are special features to edit posted documents.
1. Edit Posted Documents

More details: Dynamics 365 Business Central: How to extend the Posted Document Update page (A solution for editing Posted Document)

2. Change descriptions on G/L entries

Business Central short video: Change descriptions on G/L entries (Standard Feature)

3. Dynamics 365 Business Central: Can we delete Posted Documents (Posted invoices and credit memos)???

4. Business Central 2021 release wave 1 (BC18): Dimension corrections (for G/L Entries)

Note:
The features for correcting dimensions are intended only to help make financial reporting accurate. Dimension corrections apply only to the G/L entries. They do not change the dimensions assigned to the entries in other ledgers for the same transaction. There will be a mismatch between the dimensions assigned in the general ledger and the sub-ledgers.

So, is it true that we can’t edit posted data via AL code? No, actually we can, there is a step missing. If you look at the standard code for codeunit 80 “Sales-Post” or codeunit 12 “Gen. Jnl.-Post Line”, you’ll find that there are many settings for Permissions Property, including posted tables.
codeunit 80 “Sales-Post”:

codeunit 12 “Gen. Jnl.-Post Line”:

Let’s see more details.
Permissions Property: Sets whether an object has additional permission required to perform some operations on one or more tables. The operations can be to read, insert, modify, and delete data.

Applies to:

  • Codeunit
  • Table
  • Request Page
  • Page
  • Xml Port
  • Report
  • Query
  • Permission Set
  • Permission Set Extension

Note:
After you set the Permissions property of an object, only users with direct permission to perform all the extra operations that the object has been given can modify this object.
Do not use the Permissions property to give extra permissions to an object that you would like your users to be able to modify. These users might not have direct permission to perform these operations. This is why you should be careful when you use the Permissions property for tables and pages.

Since this property cannot be customized, it is usually set in Codeunit or Report.

The property ‘Permissions’ cannot be customized. ALAL0246

Let’s go back to the example above, clear the Document Type of the selected line. We can edit G/L Entry (17) by simply doing the following. (In addition to the Modify permission, I also granted Read, Insert, and Delete permissions)

Let’s try again.

Document Type has been cleared.

Similarly, we can also insert and delete posted data.

For example,

Test video:

Okay, I think you have learned how to edit posted data. But I want to say, please never do this. This will cause many problems, not just data inconsistency. For example, if you change any one of the Posting Date, G/L Account or Amount, the financial data will be inaccurate. And since this is changed via AL code, it is difficult to find the cause. So I want to mention it again, please never do it.

Test code:

pageextension 50223 GeneralLedgerEntriesExt extends "General Ledger Entries"
{
    actions
    {
        addfirst(processing)
        {
            action(UpdateSelectedLine)
            {
                ApplicationArea = All;
                Caption = 'Update Selected Line';
                Promoted = true;
                PromotedCategory = Process;
                Image = UpdateUnitCost;

                trigger OnAction()
                var
                    GLEntry: Record "G/L Entry";
                    EditGLEntry: Codeunit EditGLEntry;
                begin
                    GLEntry.Reset();
                    CurrPage.SetSelectionFilter(GLEntry);
                    EditGLEntry.ClearDocumentTypeForSelectedLine(GLEntry);
                end;
            }
            action(InsertEntry)
            {
                ApplicationArea = All;
                Caption = 'Insert Entry';
                Promoted = true;
                PromotedCategory = Process;
                Image = Insert;

                trigger OnAction()
                var
                    EditGLEntry: Codeunit EditGLEntry;
                begin
                    EditGLEntry.InsertEntry();
                end;
            }
            action(DeleteEntry)
            {
                ApplicationArea = All;
                Caption = 'Delete Entry';
                Promoted = true;
                PromotedCategory = Process;
                Image = Delete;

                trigger OnAction()
                var
                    EditGLEntry: Codeunit EditGLEntry;
                begin
                    EditGLEntry.DeleteEntry();
                end;
            }
        }
    }
}

codeunit 50222 EditGLEntry
{
    Permissions = TableData "G/L Entry" = rimd;

    procedure ClearDocumentTypeForSelectedLine(var GLEntry: Record "G/L Entry")
    begin
        if GLEntry.FindFirst() then begin
            GLEntry."Document Type" := GLEntry."Document Type"::" ";
            GLEntry."Document No." := 'Updated';
            GLEntry.Amount := 999;
            GLEntry.Modify(true);
        end;
    end;

    procedure InsertEntry()
    var
        GLEntry: Record "G/L Entry";
    begin
        GLEntry.Init();
        GLEntry."Entry No." := 999999999;
        GLEntry."Document Type" := GLEntry."Document Type"::Invoice;
        GLEntry."Document No." := 'xxxxxxxx';
        GLEntry."Posting Date" := WorkDate();
        GLEntry.Amount := 100;
        GLEntry.Insert();
    end;

    procedure DeleteEntry()
    var
        GLEntry: Record "G/L Entry";
    begin
        if GLEntry.Get(999999999) then
            GLEntry.Delete(true);
    end;
}

END

Hope this will help.

Thanks for reading.

ZHU

コメント

Copied title and URL