[Shopify] Store tax lines linked to order shipping charges#9537
[Shopify] Store tax lines linked to order shipping charges#9537onbuyuka wants to merge 3 commits into
Conversation
Shopify shipping GraphQL queries already retrieve shippingLines.taxLines (channelLiable, title, rate, ratePercentage, priceSet), but the shipping import did not persist them, so shipping tax details and Channel Liable status were only available in raw Retrieved Shopify Data. Shipping-line tax lines are now imported into the existing "Shpfy Order Tax Line" table, linked to the shipping charge via Parent Id = shipping line Id, and can be opened from the Shipping Costs page via a new Tax Lines action. - ShpfyShippingCharges: parse and persist each shipping line's tax lines (delete-then-recreate for clean reimport, no duplicates or stale rows). - ShpfyOrderShippingCharges.Table: OnDelete removes linked tax lines. - ShpfyOrderTaxLine.Table: currency-code AutoFormat resolves via shipping charges. - ShpfyOrderShippingCharges.Page: new promoted Tax Lines action (modern area(Promoted)). - ShpfyOrderTaxLines.Page: presentment-currency visibility resolves via shipping charges. - Tests cover channelLiable true/false/null/missing, multiple shipping lines, reimport dedupe, and removal cleanup. Fixes AB#642379 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c81e7b74-3793-4602-82ae-e74c7ceab730
OrderCurrencyCode() and OrderPresentmentCurrencyCode() on "Shpfy Order Tax Line" (used as the AutoFormatExpression for the Amount and Presentment Amount fields) were extended in this PR with an else-branch that resolves the order via "Shpfy Order Shipping Charges" when "Parent Id" is not an order line id, but they stop there.Order-level tax lines (added via AddTaxLines(OrderHeader."Shopify Order Id", ...) in ShpfyImportOrder.Codeunit.al, where "Parent Id" equals the Shopify Order Id directly) still fall through both branches and return a blank currency code, so Amount/Presentment Amount render without currency formatting for those rows. The sibling logic this PR also touched, ShpfyOrderTaxLines.Page.al's SetShowPresentmentCurrencyVisibility(), was given a third fallback ( Recommendation:
Line mapping was unavailable, so this was posted as an issue comment. 👍 useful · ❤️ especially valuable · 👎 wrong - reply with why |
Copilot PR ReviewIteration 3 · Outcome: completed Knowledge source: https://github.com/microsoft/BCQuality@186d8a131465475c79244d994acb872cd5c0d4bf Findings by domainFindings split into Knowledge-backed (cite a BCQuality article) and Agent (the agent's own judgement, no matching BCQuality rule).
Totals: 2 knowledge-backed · 1 agent findings. Orchestrator pre-filter (2 file(s) excluded)
Findings produced by the AL review agent v1.7.3. Reply 👎 on any inline comment to flag false positives. |
OrderCurrencyCode/OrderPresentmentCurrencyCode now fall back to
OrderHeader.Get("Parent Id") for order-level tax lines (Parent Id =
Shopify Order Id), consistent with the Shpfy Order Tax Lines page
presentment-visibility trigger. Without this, order-level tax line
amounts rendered without currency formatting.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c81e7b74-3793-4602-82ae-e74c7ceab730
|
Good catch — applied in c6fee21. |
The new tests generated the Shopify Order Id via LibraryRandom.RandIntInRange, which is deterministic, so every test produced the same id (774600). Under the CI codeunit-level test isolation, records are not rolled back between methods within a codeunit, so the second test onward failed inserting a duplicate Order Header. Route all order-id and shipping-line-id generation through a persistent GetUniqueId() counter so each test uses globally unique ids within the run. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c81e7b74-3793-4602-82ae-e74c7ceab730
| Result += JsonHelper.GetValueAsDecimal(JAllocationAmountSet, StrSubstNo(amountLbl, MoneyType)); | ||
| end; | ||
|
|
||
| local procedure AddTaxLines(ParentId: BigInteger; JTaxLines: JsonArray) |
There was a problem hiding this comment.
The new local procedure AddTaxLines in ShpfyShippingCharges.Codeunit.al (parse tax-line JSON via RecordRef into 'Shpfy Order Tax Line', delete-then-reinsert) is a byte-for-byte duplicate of the pre-existing AddTaxLines in ShpfyImportOrder.Codeunit.al.
Two independent copies of the same mapping logic will drift the next time a tax-line field is added or a mapping bug is fixed in only one of them.
Recommendation:
- extract the shared logic into one internal procedure (e.g. on the 'Shpfy Order Tax Line' table or a shared helper codeunit) and have both call sites use it.
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| begin | ||
| OrderTaxLine.SetRange("Parent Id", ParentId); | ||
| if not OrderTaxLine.IsEmpty() then | ||
| OrderTaxLine.DeleteAll(); |
There was a problem hiding this comment.
AddTaxLines deletes prior tax lines with a plain DeleteAll() (RunTrigger = true) while the sibling cleanup in ShpfyOrderShippingCharges.Table.al OnDelete uses DeleteAll(false) for the identical table with no OnDelete trigger to preserve.
Since 'Shpfy Order Tax Line' has no OnDelete trigger, the true form pays per-row trigger-dispatch cost for no behavioral benefit. Use DeleteAll(false) here too for consistency with the established pattern in this same PR.
| OrderTaxLine.DeleteAll(); | |
| OrderTaxLine.DeleteAll(false); |
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
| OrderShippingCharges.Insert(true); | ||
| end; | ||
|
|
||
| local procedure CreateOrderHeaderForShop(var OrderHeader: Record "Shpfy Order Header") |
There was a problem hiding this comment.
The new tests build their Shopify Order Header fixture with a hand-rolled CreateOrderHeaderForShop (Clear/assign two fields/Insert) and a hand-rolled GetUniqueId counter, instead of the ImportShopifyOrder helper and LibraryRandom-based id generation already used by every other test in this codeunit.
The direct Insert bypasses Validate on 'Shop Code' and any mandatory-field/TableRelation logic the platform enforces in production, so the fixture can silently drift out of sync as the Shpfy Order Header schema evolves, and it diverges from the file's own established fixture convention.
Knowledge:
👍 useful · ❤️ especially valuable · 👎 wrong - reply with why
Summary
Shopify shipping GraphQL queries already retrieve
shippingLines.taxLines(channelLiable, title, rate, ratePercentage, priceSet), but the shipping import did not persist them. Shipping tax details and Channel Liable status were therefore only available in the raw Retrieved Shopify Data, not as structured records, and could not be viewed from the Shipping Costs page.This change imports each shipping line's tax lines into the existing
Shpfy Order Tax Linetable, linked to the shipping charge viaParent Id = Shopify Shipping Line Id(consistent with how header and product-line tax lines are stored), and exposes them from the Shipping Costs page.Changes
OnDeletenow removes the linked tax lines (cleanup when a shipping line is removed on reimport).area(Promoted)model.The GraphQL query files already retrieved
taxLines, so no query change was needed.Test plan
Added tests in
ShpfyShippingChargesTestcovering:channelLiable= true, false, null, and missing (defaults to false)Fixes AB#642379