Automating Prepayment Handling in Business Central – Part 2
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.

Like
Report
*This post is locked for comments