I ended up creating a code unit that could be called after a order was created to update the VAT amount. I do not have a lot of experience writing AL code so it may not be the best, however, it has resolved the majority of our rounding issues to the point where this is no longer a significant issue for us. We also introduced rounding tolerances for our payment reconciliation that also helped.
codeunit 50107 "Sales Order VAT"
{
procedure UpdateVAT(orderNumber: Text; newVATAmount: Decimal) RetVal: Text;
var
salesHeader: Record "Sales Header";
salesLine: Record "Sales Line";
salesLineUpdate: Record "Sales Line";
vatAmountLine: Record "VAT Amount Line";
vatDifference: Decimal;
releaseSalesDocument: Codeunit "Release Sales Document";
salesCalcDiscountByType: Codeunit "Sales - Calc Discount By Type";
begin
// fetch sales header
salesHeader.SetCurrentKey("No.");
salesHeader.SetFilter("No.", orderNumber);
if salesHeader.FindFirst() then begin
// fetch first sales line
salesLine.SetRange("Document No.", salesHeader."No.");
salesLine.SetRange("Document Type", salesHeader."Document Type");
salesLine.SetFilter(Type, '>0');
salesLine.SetFilter(Quantity, '>0');
if salesLine.FindFirst() then begin
// calc VAT amount lines
salesLine.CalcVATAmountLines(0, salesHeader, salesLine, vatAmountLine);
// update VAT amount lines
vatDifference := newVATAmount - vatAmountLine."VAT Amount";
if vatDifference <> 0 then begin
vatAmountLine."VAT Amount" += vatDifference;
vatAmountLine."VAT Difference" := vatDifference;
if salesHeader."Prices Including VAT" then
vatAmountLine."VAT Base" := vatAmountLine."Amount Including VAT" - vatAmountLine."VAT Amount"
else
vatAmountLine."Amount Including VAT" := vatAmountLine."VAT Amount" + vatAmountLine."VAT Base";
vatAmountLine.Modify();
// update sales line
salesLine.Amount := vatAmountLine.GetTotalLineAmount(true, salesHeader."Currency Code");
salesLine."VAT Base Amount" := newVATAmount;
salesLine."VAT Difference" := vatDifference;
salesLine."Amount Including VAT" := vatAmountLine.GetTotalAmountInclVAT() + salesLine."Inv. Discount Amount";
if not salesHeader."Prices Including VAT" and (salesLine.Amount > 0) and (salesLine.Amount < salesLine."Prepmt. Line Amount") then
salesLine."Prepmt. Line Amount" := salesLine.Amount;
if salesHeader."Prices Including VAT" and (salesLine."Amount Including VAT" > 0) and (salesLine."Amount Including VAT" < salesLine."Prepmt. Line Amount") then
salesLine."Prepmt. Line Amount" := salesLine."Amount Including VAT";
salesLine.Modify();
// save changes
salesLineUpdate.UpdateVATOnLines(1, salesHeader, salesLine, vatAmountLine);
releaseSalesDocument.CalcAndUpdateVATOnLines(salesHeader, salesLine);
salesCalcDiscountByType.ResetRecalculateInvoiceDisc(salesHeader)
end;
RetVal := 'VAT updated successfully, VAT (To ' + Format(newVATAmount) + ', Diff ' + Format(vatDifference) + ')';
end;
end;
end;
}