[Shopify] Fix missing shop currency mapping on order transactions#8679
[Shopify] Fix missing shop currency mapping on order transactions#8679nikolakukrika wants to merge 9 commits into
Conversation
The amountSet.shopMoney.currencyCode was no longer mapped to the Currency field on order transactions after the code was moved from NAV to BCApps and presentment currency fields were added. This caused the Currency column on the Shopify Order Transactions page to be empty or retain stale values from the old REST API era. Fixes ICM 51000001074581 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
f7c810f to
7c64468
Compare
Currency lookup calls Count() twice on same setThe new currency resolution logic calls Recommendation:
Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why |
4e2ea1b to
5075bd8
Compare
- Early exit for empty input to avoid accidental ISO Code lookup - Try Currency.Get(code) first before falling back to ISO Code search - Add telemetry warning when multiple currencies share the same ISO Code Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5075bd8 to
d25c0b2
Compare
- Add ExtractShopifyOrderTransactionFromMock for testability
- Create ShpfyTransactionsTest codeunit with scenario tests:
- Import transaction sets Currency from shopMoney.currencyCode
- Import transaction with LCY currency returns empty
- Import transaction sets Presentment Currency correctly
- Import transaction amounts match shopMoney/presentmentMoney
- TranslateCurrencyCode unit tests for ISO match, empty input,
Code fallback, and not-found scenarios
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove mock entry point from ShpfyTransactions.Codeunit.al and rewrite tests to use [HttpClientHandler] pattern with Library - Variable Storage for dynamic JSON responses. Tests now exercise the full transaction import flow through the real HTTP pipeline. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add DKK currency setup in Initialize to support the existing resource file (OrderTransactionResult.txt uses DKK). Add new test that validates transaction Currency and Presentment Currency are correctly populated from shopMoney/presentmentMoney in the JSON response during order import. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Local procedure broadened to internal for testability
Recommendation:
Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why |
Edge case:
|
| Old logic | New logic | |
|---|---|---|
| Resolve ISO→Code | DKK → DAN |
DKK → DAN |
| LCY check | DAN = DAN → '' ✓ |
raw DKK ≠ DAN → returns DAN ✗ |
So a transaction that is actually in local currency gets stamped with a non-blank currency code instead of blank — a currency mismatch versus the LCY document.
Note the old logic had the mirror gap (when LCY Code is ISO-style but the currency record's Code differs, the raw check catches it but the resolved-code check does not). Neither approach alone is robust to Code ≠ ISO Code.
Suggested fix — keep the early exit as a fast path for the common ISO-convention case, and also re-check the resolved code against LCY Code at the end (union of old + new behavior). While here, cache Currency.Count() to address the redundant round-trips flagged elsewhere:
internal procedure TranslateCurrencyCode(ShopifyCurrencyCode: Text): Code[10]
var
Currency: Record Currency;
GeneralLedgerSetup: Record "General Ledger Setup";
CurrencyCode: Code[10];
CurrencyCount: Integer;
begin
if ShopifyCurrencyCode = '' then
exit('');
GeneralLedgerSetup.Get();
if CopyStr(ShopifyCurrencyCode, 1, MaxStrLen(GeneralLedgerSetup."LCY Code")) = GeneralLedgerSetup."LCY Code" then
exit('');
Currency.SetLoadFields(Code);
Currency.SetRange("ISO Code", CopyStr(ShopifyCurrencyCode, 1, 3));
CurrencyCount := Currency.Count();
if CurrencyCount = 1 then begin
Currency.FindFirst();
CurrencyCode := Currency.Code;
end else
if CurrencyCount > 1 then begin
Session.LogMessage('0000S1A', StrSubstNo(DuplicateISOCodeTelemetryLbl, ShopifyCurrencyCode, CurrencyCount), Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
Currency.FindFirst();
CurrencyCode := Currency.Code;
end else
if Currency.Get(CopyStr(ShopifyCurrencyCode, 1, MaxStrLen(Currency.Code))) then
CurrencyCode := Currency.Code
else
Session.LogMessage('0000S1B', StrSubstNo(CurrencyNotFoundTelemetryLbl, ShopifyCurrencyCode), Verbosity::Warning, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', CategoryTok);
// Edge case: LCY Code is configured as a non-ISO currency code, so the fast path
// above did not catch it. Treat the resolved code as LCY as well.
if CurrencyCode = GeneralLedgerSetup."LCY Code" then
exit('');
exit(CurrencyCode);
end;I'll also add a test where Currency.Code ≠ "ISO Code" and the shop currency equals LCY-by-ISO, asserting the result is blank — this currently isn't exercised (the existing tests set ISO = Code).
…ncyCode The early LCY exit compared the raw Shopify ISO code to G/L Setup "LCY Code". When a currency's Code differs from its ISO Code and "LCY Code" follows the Code, a local-currency transaction was stamped with a non-blank currency code instead of blank. Re-check the resolved BC currency code against "LCY Code" at the end so both configurations are handled. Also cache Currency.Count() to avoid redundant round-trips, and fix the new test codeunit ID (139700 was outside the app idRanges) to 139697. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pushed a commit ( Applied
Considered, not changed
Validated: App project builds clean (0 errors); both modified test files compile with 0 errors. |
Copilot PR ReviewIteration 5 · Outcome: completed
Knowledge source: https://github.com/microsoft/BCQuality@822cae1b2771ac25f665f73369f69093bd4fd630 Orchestrator pre-filter (13 file(s) excluded)
Findings produced by the Copilot CLI agent against BCQuality at |
The new transaction tests failed in CI for two reasons: 1) 'Transaction should be created': the full order-import path fires several GraphQL queries (fulfillment, shipping, transactions) through a single queue-based HTTP mock. GraphQL read queries bypass the Allow Outgoing Requests gate, so the fulfillment query consumed the enqueued transaction data before the transactions query ran, leaving no transaction. Import transactions in isolation via Transactions.UpdateTransactionInfos so exactly one GraphQL call hits the mock. 2) 'Should find currency by Code when ISO Code does not match': the tests committed currencies whose ISO Code was set to the 3-char prefix of a generated code (all 'GU0'), so the ISO lookup matched multiple rows across tests. Use distinct 3-char ISO codes and drop Commit() so per-test currency data is rolled back and cannot pollute later tests. Also remove the misplaced, fragile UnitTestTransactionCurrencyIsSetFromOrderImport from ShpfyShippingChargesTest (a transaction-currency test in a shipping codeunit); the same coverage now lives, robustly, in ShpfyTransactionsTest. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pushed 1. "Transaction should be created" (5 tests) — the tests imported a full order via 2. Also: removed Both edited test files compile clean (0 errors / 0 warnings) locally against the full v29 symbol set; CI will confirm the run. |
CI showed ImportTransactionAmountMatchesShopMoney and ImportTransactionWithLCYCurrencyReturnsEmpty failing with 'The record in table Shopify Order Header already exists' for fixed ids (691767, 323801). Any.IntegerInRange is deterministic, so the generated order/transaction ids collided with records committed by other Shopify test codeunits in the shared UncategorizedTests database. Generate the Shopify Order Id and Shopify Transaction Id as FindLast + 1 so they are always above any existing record, and pick ISO codes not already in use. Two of these tests already passed in CI, confirming the transaction-import and currency-mapping logic is correct. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
The re-run got past the infra outage and surfaced the real failure: two of the new tests hit Notably, Fixed in |
Add Comment parameters naming the %1/%2 placeholders on DuplicateISOCodeTelemetryLbl and CurrencyNotFoundTelemetryLbl, matching the label-comment convention used consistently across the Shopify app. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Problem
The
amountSet.shopMoney.currencyCodewas no longer mapped to theCurrencyfield onShpfy Order Transactionrecords. This regression was introduced in commit acd8280 (presentment currency support) where the existingshopMoney.currencyCodemapping was accidentally replaced by the newpresentmentMoneylines instead of being kept alongside them.This causes the Currency column on the Shopify Order Transactions page to show stale/incorrect values from prior sync runs or remain empty for new transactions - while
TranslateCurrencyCode(OrderTransaction.Currency)is called expecting the field to be populated.Root Cause
In commit acd8280, the shopMoney.currencyCode line was replaced by presentmentMoney lines instead of being kept alongside them.
Fix
Re-add the missing
amountSet.shopMoney.currencyCodetoCurrencymapping, restoring parity with howamountRoundingSetcorrectly handles both shopMoney and presentmentMoney currency codes in the same block.Verification
shopMoney { amount currencyCode }- the data was available but not being read.TranslateCurrencyCodecall on line 121 correctly handles the raw Shopify currency code once populated.amountRoundingSetblock (lines 99-102) was already correct (both shopMoney and presentmentMoney mapped).Fixes AB#641570
Ref: ICM 51000001074581