Skip to content

[APAC] Keep vendor ACY on purchase invoice payables entry - #10168

Open
Jose Antonio Garcia Garcia (Jose-agg) wants to merge 5 commits into
mainfrom
bugs/641827-apac-vendor-acy-balancing-entry
Open

[APAC] Keep vendor ACY on purchase invoice payables entry#10168
Jose Antonio Garcia Garcia (Jose-agg) wants to merge 5 commits into
mainfrom
bugs/641827-apac-vendor-acy-balancing-entry

Conversation

@Jose-agg

@Jose-agg Jose Antonio Garcia Garcia (Jose-agg) commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What & why

I reproduced this issue in AU with an Additional Reporting Currency enabled, Enable Vendor GST Amount (ACY) turned on, a blank purchase invoice currency, and a nonzero Vendor Exchange Rate (ACY).

The same scenario does not reproduce in W1 because W1 keeps the detailed CV buffer amount as the document/source amount and calculates ACY independently from LCY. APAC uses that buffer differently: it stores the vendor-calculated ACY so the vendor exchange rate is preserved.

The source-currency change from PR 241506 applied the W1 initialization pattern to APAC as well. In this APAC path, that passed zero as the balancing entry's ACY and reused the actual ACY as Source Currency Amount. The posting therefore left the full ACY amount unbalanced and created a separate residual entry.

This change keeps the already-calculated vendor ACY in Additional-Currency Amount and calculates Source Currency Amount independently from LCY. It does not restore the global TotalSrcCurrAmount state removed by PR 241506.

Linked work

Fixes AB#641827

How I validated this

  • I read the full diff and it contains only changes I intended.
  • I built the affected app(s) locally with no new analyzer warnings.
  • I ran the change in Business Central and confirmed it behaves as expected.
  • I added or updated tests for the new behavior.

What I tested and the outcome

  • Built the AU Base Application and Tests-Local with static analysis.
  • Added and ran PurchaseInvoiceWithVendorACYPostsACYOnPayablesEntry; the test passes.
  • Ran the existing PurchaseVendorExchangeRateIsUsedForAdditionalCurrencyAmountCalculation; the test passes.
  • Repeated the original AU preview-posting scenario with LCY 1,477.00 and vendor ACY rate 1.2726.
    • Purchase entry: LCY/source 1,477.00, ACY 1,879.63.
    • Payables entry: LCY/source -1,477.00, ACY -1,879.63.
    • No Residual caused by rounding entry was created.

Risk & compatibility

The change is limited to the APAC layer and does not change W1 behavior, table schemas, or stored data.

The existing branch where Source Currency Code equals ACY remains unchanged. For other APAC entries, source currency and ACY are now calculated independently rather than using the same amount for both fields.

@github-actions github-actions Bot added the Finance GitHub request for Finance area label Aug 12, 2026
@github-actions github-actions Bot added this to the Version 29.0 milestone Aug 12, 2026
Comment thread src/Layers/APAC/Tests/Local/ERMMiscellaneousAPAC.Codeunit.al
@dcenic
dcenic enabled auto-merge August 12, 2026 10:00
dcenic
dcenic previously approved these changes Aug 12, 2026
ventselartur
ventselartur previously approved these changes Aug 12, 2026
mynjj
Joshua (mynjj) previously approved these changes Aug 12, 2026
@alexei-dobriansky

Copy link
Copy Markdown
Contributor

Agentic PR Review - Round 1

Recommendation: Accept

What this PR does

This PR fixes the APAC purchase invoice path when Additional Reporting Currency and Vendor GST Amount (ACY) are enabled. It keeps the vendor-rate ACY on the payables G/L entry when the purchase invoice is in LCY, and it calculates Source Currency Amount from LCY instead of reusing ACY.

The change is in HandleDtldAdjustment, before the payables G/L entry is initialized. In the vendor path, UseVendExchRate makes GLCalcAddCurrency keep the supplied TotalAmountAddCurr, so the detailed vendor buffer ACY now reaches the balancing entry instead of being posted as a residual entry. The source-currency-equals-ACY branch is unchanged, and the new test checks the expense ACY, payables ACY, source currency amount, total balances, and absence of residual G/L entries.

Suggestions

None.

Risk assessment and necessity

Risk: This is a financial posting path, so the main risk is wrong G/L amounts for APAC purchase documents with additional reporting currency. The code change is narrow: one InitGLEntry call now passes the already calculated vendor ACY and an independently calculated source currency amount. There are no schema, public API, or event signature changes.

Necessity: The linked bug and PR evidence describe a real live-site case where the payables ACY was left at zero and a residual gains/losses entry was created. The fix targets that root cause without restoring the removed global source-currency state, and the added test covers the reported posting result.


[AI-PR-REVIEW] version=1 promptVersion=2 system=github pr=10168 round=1 by=alexei-dobriansky at=2026-08-12T15:06:01.2077318Z lastSha=03c1023b74e0265e9235a6dacb8bfbd3810db3db reviewKey=50c81551ec18bee0ac3fa628eae49eee37b4369b73f517d0f4ca71a5ac71a9b7 suggestions=none

@dcenic
dcenic dismissed stale reviews from Joshua (mynjj), ventselartur, and themself via 3f72dc7 August 13, 2026 08:45
Comment thread src/Layers/APAC/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostLine.Codeunit.al Outdated
Comment thread src/Layers/APAC/Tests/Local/ERMMiscellaneousAPAC.Codeunit.al
Comment thread src/Layers/APAC/Tests/Local/ERMMiscellaneousAPAC.Codeunit.al
Comment thread src/Layers/APAC/Tests/Local/ERMMiscellaneousAPAC.Codeunit.al
end;
end;

local procedure VendorACYExchangeRateApplies(): Boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Agent}$

VendorACYExchangeRateApplies() (GenJnlPostLine.Codeunit.al, new local procedure) is documented as mirroring GLCalcAddCurrency's vendor-ACY branch, but it omits one of that branch's guard conditions. GLCalcAddCurrency only takes the vendor-ACY path when (AddCurrencyCode <> '') and (GenJnlLine."Additional-Currency Posting" = GenJnlLine."Additional-Currency Posting"::None) AND PurchSetup."Enable Vendor GST Amount (ACY)" and UseVendExchRate; otherwise it falls through to UseVendExchRate := false; exit(OldAddCurrAmount). VendorACYExchangeRateApplies() only checks AddCurrencyCode <> '', UseVendExchRate, and the setup flag — it never checks GenJnlLine."Additional-Currency Posting". When a gen. journal line has "Additional-Currency Posting" <> None (e.g. set to "Amount Only"/"Additional-Currency Amount Only") together with AddCurrencyCode <> '', UseVendExchRate = true and the setup flag enabled, GLCalcAddCurrency would skip the vendor-ACY branch entirely (falling through to the OldAddCurrAmount exit), while the new HandleDtldAdjustment call site will still believe VendorACYExchangeRateApplies() = true and derive the balancing entry's Source Currency Amount via CalcAmountSrcCurr(GenJnlLine, TotalAmountLCY). This diverges from the actual value GLCalcAddCurrency produced for the entry's Additional-Currency Amount, unbalancing the posted document for that posting-rule combination. Add the same "Additional-Currency Posting" = ::None guard to VendorACYExchangeRateApplies() so it truly mirrors GLCalcAddCurrency's condition.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.32.4

exit(GetVendGSTAmountACYEnabled());
end;

local procedure GetVendGSTAmountACYEnabled(): Boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Agent}$

GetVendGSTAmountACYEnabled() caches "Purchases & Payables Setup"."Enable Vendor GST Amount (ACY)" in the new instance-level fields VendGSTAmountACYEnabled/VendGSTAmountACYRead for the lifetime of the codeunit 12 instance, and nothing in the diff ever resets VendGSTAmountACYRead back to false. Codeunit 12 is reused across multiple gen. journal lines/documents within one posting run (this is exactly why UseVendExchRate is defensively reset to false in three separate places in this same codeunit, including one added by this PR). If the setup flag is toggled between documents processed by the same running instance (e.g. an admin change mid-batch, or reuse in a long-running batch/test session), the cached value silently continues driving VendorACYExchangeRateApplies() instead of reflecting the current setup, unlike GLCalcAddCurrency's own PurchSetup.Get() which re-reads on every call. Reset VendGSTAmountACYRead alongside UseVendExchRate at the existing reset points, or drop the cache and read the setup field fresh (as GLCalcAddCurrency already does) since this is a single boolean field.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.32.4

Comment on lines +841 to +844
PurchasesPayablesSetup.Get();
OriginalVendorGSTAmountACY := PurchasesPayablesSetup."Enable Vendor GST Amount (ACY)";
PurchasesPayablesSetup."Enable Vendor GST Amount (ACY)" := true;
PurchasesPayablesSetup.Modify();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟡\ Medium\ Severity\ —\ Testing}$

This test changes "Purchases & Payables Setup"."Enable Vendor GST Amount (ACY)" without first calling LibrarySetupStorage.Save for that table. If any assertion above fails, the manual restore at the end never runs and later tests inherit the modified setup. Save the setup before the modification so Initialize()/LibrarySetupStorage.Restore() cleans it up even on failure.

Suggested change
PurchasesPayablesSetup.Get();
OriginalVendorGSTAmountACY := PurchasesPayablesSetup."Enable Vendor GST Amount (ACY)";
PurchasesPayablesSetup."Enable Vendor GST Amount (ACY)" := true;
PurchasesPayablesSetup.Modify();
PurchasesPayablesSetup.Get();
LibrarySetupStorage.Save(DATABASE::"Purchases & Payables Setup");
OriginalVendorGSTAmountACY := PurchasesPayablesSetup."Enable Vendor GST Amount (ACY)";
PurchasesPayablesSetup."Enable Vendor GST Amount (ACY)" := true;
PurchasesPayablesSetup.Modify();

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.32.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Finance GitHub request for Finance area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants