Skip to content

[Shopify] Store tax lines linked to order shipping charges#9537

Open
onbuyuka wants to merge 3 commits into
mainfrom
bugs/642379-shopify-shipping-tax-lines
Open

[Shopify] Store tax lines linked to order shipping charges#9537
onbuyuka wants to merge 3 commits into
mainfrom
bugs/642379-shopify-shipping-tax-lines

Conversation

@onbuyuka

@onbuyuka onbuyuka commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

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 Line table, linked to the shipping charge via Parent 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

  • ShpfyShippingCharges.Codeunit – parse and persist each shipping line's tax lines (title, rate, rate %, shop amount, presentment amount, Channel Liable), using delete-then-recreate so reimport produces no duplicates or stale rows.
  • ShpfyOrderShippingCharges.TableOnDelete now removes the linked tax lines (cleanup when a shipping line is removed on reimport).
  • ShpfyOrderTaxLine.Table – currency-code AutoFormat lookups resolve via the shipping charge as well as order line/header.
  • ShpfyOrderShippingCharges.Page – new Tax Lines action (opens the existing tax-lines page filtered to the selected shipping charge); migrated the page to the modern area(Promoted) model.
  • ShpfyOrderTaxLines.Page – presentment-currency column visibility resolves via the shipping charge.

The GraphQL query files already retrieved taxLines, so no query change was needed.

Test plan

Added tests in ShpfyShippingChargesTest covering:

  • channelLiable = true, false, null, and missing (defaults to false)
  • all field values preserved (title, rate, rate %, shop/presentment amounts)
  • multiple shipping lines keep their tax lines separated
  • reimport replaces tax lines without duplicates or stale rows
  • removing a shipping line on reimport deletes its shipping charge and tax lines

Fixes AB#642379

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
@onbuyuka onbuyuka requested a review from a team July 16, 2026 12:46
@github-actions github-actions Bot added the AL: Apps (W1) Add-on apps for W1 label Jul 16, 2026
@onbuyuka onbuyuka enabled auto-merge July 16, 2026 12:47
@github-actions github-actions Bot added this to the Version 29.0 milestone Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

$\textbf{🟡\ Medium\ Severity\ —\ Agent} \quad \color{gray}{\texttt{\small Iteration\ 1}}$

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 (if not OrderHeader.Get(Rec."Parent Id") then exit) for exactly this case, so the page correctly decides Presentment Amount visibility for order-level rows while the table's own currency-code resolution used to format that same field does not.

Recommendation:

  • add the same third fallback (OrderHeader.Get("Parent Id")) to both OrderCurrencyCode() and OrderPresentmentCurrencyCode() so order-level tax lines get correctly formatted amounts, consistent with the page trigger.

Line mapping was unavailable, so this was posted as an issue comment.

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Copilot PR Review

Iteration 3 · Outcome: completed

Knowledge source: https://github.com/microsoft/BCQuality@186d8a131465475c79244d994acb872cd5c0d4bf

Findings by domain

Findings split into Knowledge-backed (cite a BCQuality article) and Agent (the agent's own judgement, no matching BCQuality rule).

Domain Findings Knowledge-backed Agent Inline Fallback
Agent 1 0 1 1 0
Performance 1 1 0 1 0
Testing 1 1 0 1 0

Totals: 2 knowledge-backed · 1 agent findings.

Orchestrator pre-filter (2 file(s) excluded)

  • layer-disabled (knowledge) : 2 file(s)

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
@onbuyuka

Copy link
Copy Markdown
Contributor Author

Good catch — applied in c6fee21. OrderCurrencyCode() and OrderPresentmentCurrencyCode() now have the same third fallback (OrderHeader.Get("Parent Id")) as the page's SetShowPresentmentCurrencyVisibility(), so order-level tax lines (Parent Id = Shopify Order Id) get correctly formatted Amount / Presentment Amount.

@JesperSchulz JesperSchulz added the Integration GitHub request for Integration area label Jul 16, 2026
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)

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} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

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();

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\ —\ Performance} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

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.

Suggested change
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")

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} \quad \color{gray}{\texttt{\small Iteration\ 3}}$

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

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

Labels

AL: Apps (W1) Add-on apps for W1 Integration GitHub request for Integration area

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants