web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

Community site session details

Community site session details

Session Id :

Automating Prepayment Handling in Business Central – Part 2

CloudFronts.Blogs Profile Picture CloudFronts.Blogs

In Part 1, we explored the core logic of handling prepayment invoices in Business Central using AL. In this part, we will dive deeper into the practical implementation, focusing on how prepayments are applied, invoices are generated, and item charges are assigned. This blog will break down the logic in a simplified, yet complete way. Why Automate Prepayments? In real-world business scenarios, companies often pay vendors before the invoice is fully posted. Handling these prepayments manually is tedious and error-prone: Our AL code automates this process: it creates purchase invoices, handles prepayment lines, applies payments, and ensures that item charges are correctly assigned. 1. Event Subscriber: Trigger After Posting Purchase Document The automation starts with an event subscriber that triggers after a purchase document is posted: [EventSubscriber(ObjectType::Codeunit, Codeunit::”Purch.-Post”, ‘OnAfterPostPurchaseDoc’, ”, false, false)]procedure OnAfterPostPurchaseDocHandler(var PurchaseHeader: Record “Purchase Header”)var    Rec_PreppaymentLines: Record PrepaymentLinesandPayment;    PurchInvoiceHeader: Record “Purchase Header”;    VendorInvoiceMap: Dictionary of [Code[20], Code[20]];    VendorNo: Code[20];begin    // Collect unique vendors    Rec_PreppaymentLines.SetRange(“Purchase Order No.”, PurchaseHeader.”No.”);    Clear(VendorList);    if Rec_PreppaymentLines.FindSet() then        repeat            if not VendorList.Contains(Rec_PreppaymentLines.”Vendor No.”) then                VendorList.Add(Rec_PreppaymentLines.”Vendor No.”);        until Rec_PreppaymentLines.Next() = 0; // Process each vendor    foreach VendorNo in VendorList do begin        // Create or reuse invoice        if VendorInvoiceMap.ContainsKey(VendorNo) then            PurchInvoiceHeader.Get(PurchInvoiceHeader.”Document Type”::Invoice, VendorInvoiceMap.Get(VendorNo))        else begin            PurchInvoiceHeader := CreatePurchaseInvoiceHeader(VendorNo);            VendorInvoiceMap.Add(VendorNo, PurchInvoiceHeader.”No.”);        end; // Handle prepayment lines        Rec_PreppaymentLines.SetRange(“Purchase Order No.”, PurchaseHeader.”No.”);        Rec_PreppaymentLines.SetRange(“Vendor No.”, VendorNo);        if Rec_PreppaymentLines.FindSet() then            repeat                HandlePrepaymentLine(Rec_PreppaymentLines, PurchInvoiceHeader);            until Rec_PreppaymentLines.Next() = 0;    end;end; Key Takeaways: 2. Handling Prepayment Lines The HandlePrepaymentLine procedure ensures each prepayment is processed correctly: procedure HandlePrepaymentLine(var PrepaymentLine: Record PrepaymentLinesandPayment; var PurchHeader: Record “Purchase Header”)var    PaymentEntryNo: Integer;begin    // Unapply previous payments if any    PaymentEntryNo := UnapplyPaymentFromPrepayInvoice(PrepaymentLine.”Prepayment Invoice”);    if PaymentEntryNo = 0 then        Error(‘Failed to unapply Vendor Ledger Entry for Document No. %1’, PrepaymentLine.”Prepayment Invoice”); // Create credit memo and invoice line    CreateCreditMemoLine(PrepaymentLine, PrepaymentLine.”Prepayment Invoice”);    CreatePurchaseInvoiceLine(PurchHeader, PrepaymentLine); // Assign item charges and post    AssignItemChargeToReceiptAndPost(PrepaymentLine, PurchHeader.”No.”, PrepaymentLine.”Purchase Order No.”);end; Highlights: 3. Applying Payments to Invoice The ApplyPaymentToInvoice procedure ensures the invoice is linked with the correct prepayment: procedure ApplyPaymentToInvoice(InvoiceNo: Code[20]; PaymentEntryNo: Integer)var    InvoiceEntry, VendLedEntry: Record “Vendor Ledger Entry”;    ApplyPostedEntries: Codeunit “VendEntry-Apply Posted Entries”;    ApplyUnapplyParameters: Record “Apply Unapply Parameters”;begin    InvoiceEntry.SetRange(“Document No.”, InvoiceNo);    InvoiceEntry.SetRange(Open, true);    if InvoiceEntry.FindFirst() then begin        VendLedEntry.SetRange(“Entry No.”, PaymentEntryNo);        if VendLedEntry.FindFirst() then begin            InvoiceEntry.Validate(“Amount to Apply”, InvoiceEntry.”Remaining Amount”);            VendLedEntry.Validate(“Amount to Apply”, -InvoiceEntry.”Remaining Amount”); ApplyUnapplyParameters.”Document No.” := VendLedEntry.”Document No.”;            ApplyPostedEntries.Apply(InvoiceEntry, ApplyUnapplyParameters);        end;    end;end; Benefits: 4. Assigning Item Charges Item charges from receipts are automatically assigned to invoices: procedure AssignItemChargeToReceiptAndPost(var PrepaymentLine: Record PrepaymentLinesandPayment; PurchInvoiceNo: Code[20]; PurchaseOrderNo: Code[20])var    PurchRcptLine: Record “Purch. Rcpt. Line”;    ItemChargeAssign: Record “Item Charge Assignment (Purch)”;begin    PurchRcptLine.SetRange(“Order No.”, PrepaymentLine.”Purchase Order No.”);    PurchRcptLine.SetFilter(Quantity, ‘>0’);    PurchRcptLine.SetRange(“No.”, PrepaymentLine.”Item No.”); if PurchRcptLine.FindSet() then        repeat            ItemChargeAssign.Init();            ItemChargeAssign.”Document No.” := PurchInvoiceNo;            ItemChargeAssign.”Applies-to Doc. No.” := PurchRcptLine.”Document No.”;            ItemChargeAssign.”Item Charge No.” := PrepaymentLine.”Item Charge”;            ItemChargeAssign.”Qty. to Assign” := 1;            ItemChargeAssign.”Amount to Assign” := PrepaymentLine.Amount;            ItemChargeAssign.Insert(true);        until PurchRcptLine.Next() = 0;end; Outcome: To conclude, by implementing this automation: This code can save significant time for finance teams while keeping processes accurate and transparent. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

The post Automating Prepayment Handling in Business Central – Part 2 appeared first on .


This was originally posted here.

Comments

*This post is locked for comments