[Shopify] Fix missing shop currency mapping on order transactions#8679
[Shopify] Fix missing shop currency mapping on order transactions#8679nikolakukrika wants to merge 5 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>
|
Could not find a linked ADO work item. Please link one by using the pattern 'AB#' followed by the relevant work item number. You may use the 'Fixes' keyword to automatically resolve the work item when the pull request is merged. E.g. 'Fixes AB#1234' |
f7c810f to
7c64468
Compare
| GeneralLedgerSetup: Record "General Ledger Setup"; | ||
| CurrencyCode: Code[10]; | ||
| begin | ||
| if ShopifyCurrencyCode = '' then |
There was a problem hiding this comment.
Currency filter excludes empty ISO code incorrectly
The filter Currency.SetFilter("ISO Code", '<>%1&%2', '', CopyStr(ShopifyCurrencyCode, 1, 3)) uses & (AND) between the two conditions, which will never match any record because no ISO Code can simultaneously be both not-empty AND match the given currency code. The intended logic is likely OR, or a separate SetRange call.
Recommendation:
- Use two separate filter calls or the correct operator. To find currencies matching the ISO code that are not blank:
Currency.SetRange("ISO Code", CopyStr(ShopifyCurrencyCode, 1, 3));
| if ShopifyCurrencyCode = '' then | |
| Currency.SetRange("ISO Code", CopyStr(ShopifyCurrencyCode, 1, 3)); |
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
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>
| Currency.SetLoadFields(Code); | ||
| Currency.SetRange("ISO Code", CopyStr(ShopifyCurrencyCode, 1, 3)); | ||
| if Currency.FindFirst() then | ||
| if Currency.Count() = 1 then begin |
There was a problem hiding this comment.
Currency.Count() called three times in one path
Currency.Count() is invoked on lines 666, 670, and again inside StrSubstNo on line 671 — each is a separate database round-trip. This function is called for every order imported from Shopify, so the redundant queries compound at scale.
Recommendation:
- Cache the result of
Currency.Count()in a localCurrencyCount: Integervariable before the if-else block, then reference the variable in all three places.
| if Currency.Count() = 1 then begin | |
| CurrencyCount := Currency.Count(); | |
| if CurrencyCount = 1 then begin | |
| Currency.FindFirst(); | |
| CurrencyCode := Currency.Code; | |
| end else begin | |
| 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); | |
| end; |
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
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 |
| Currency.Get(CurrencyCode); | ||
| Currency."ISO Code" := CopyStr(CurrencyCode, 1, MaxStrLen(Currency."ISO Code")); | ||
| Currency.Modify(); | ||
|
|
There was a problem hiding this comment.
Test currency ISO code equals Currency.Code; translation not exercised
In ImportTransactionSetsShopCurrencyFromJson and similar tests, the mocked Shopify currency code is set equal to the BC Currency.Code. Because TranslateCurrencyCode returns the same value in this case, the test does not verify the translation path (ISO Code → BC Code) when they differ, leaving the core mapping logic untested.
Recommendation:
- Set the currency's
ISO Codeto a value that differs fromCurrency.Code(e.g., setCurrency.Code := 'EURC'andCurrency."ISO Code" := 'EUR'), then enqueue'EUR'as the Shopify currency and assertOrderTransaction.Currency = 'EURC'. This exercises the actual ISO-to-BC-code translation.
| CurrencyCode := LibraryERM.CreateCurrencyWithRounding(); | |
| Currency.Get(CurrencyCode); | |
| Currency."ISO Code" := 'ZYX'; // ISO code deliberately different from Currency.Code | |
| Currency.Modify(); | |
| TransactionData.Enqueue('ZYX'); // shopMoney.currencyCode (ISO) | |
| // ... rest of test ... | |
| LibraryAssert.AreEqual(CurrencyCode, OrderTransaction.Currency, 'Currency should be translated from ISO code to BC currency code'); |
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
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 ICM 51000001074581