[releases/27.x] [Shopify] API 2026-01 uptake (#6244)#8360
Open
onbuyuka wants to merge 7 commits into
Open
Conversation
<!-- Thank you for submitting a Pull Request. If you're new to contributing to BCApps please read our pull request guideline below * https://github.com/microsoft/BCApps/Contributing.md --> #### Summary <!-- Provide a general summary of your changes --> Complicated process... https://help.shopify.com/en/manual/sell-in-person/shopify-pos/order-management/unverified-returns So far we are only going to import them and that's it. We may think about creating ledger entries to balance the inventory, customer account etc. but not now #### Work Item(s) <!-- Add the issue number here after the #. The issue needs to be open and approved. Submitting PRs with no linked issues or unapproved issues is highly discouraged. --> Fixes [AB#601701](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/601701)
This PR upgrades the Shopify Connector to API version 2026-01,
addressing deprecations, new features, and breaking changes announced in
the Shopify changelog.
- **Mutation upgrade**: Replaced deprecated
`inventorySetOnHandQuantities` with `inventorySetQuantities` using
`name: "on_hand"` and `reason: "correction"`
- **Idempotency support**: Added `@idempotent(key: "...")` directive to
inventory mutations for safe retries
- **Concurrency handling**: Added `changeFromQuantity: null` to opt-out
of compare-and-swap (BC is the authoritative source)
- **Retry logic**: Auto-retry once on `IDEMPOTENCY_CONCURRENT_REQUEST`
or `CHANGE_FROM_QUANTITY_STALE` errors, then log to skipped records
- Added batching logic in `AddProductVariants` to respect the new limit
of 50,000 inventory quantities per mutation
- `GetMaxVariantsPerBatch()` calculates max variants based on `50000 div
LocationCount`
- Made `GetDefaultLocationCount()` and `GetMaxVariantsPerBatch()`
internal for testability
- Removed deprecated `currentBulkOperation` query (now uses
`GetBulkRequest` by ID)
- Deleted `ShpfyGQLBulkOperations.Codeunit.al` and removed
`GetCurrentBulkOperation` enum value
- Replaced deprecated `returnReason` enum with `returnReasonDefinition {
name handle }`
- Added `Return Reason Name` and `Return Reason Handle` fields to `Shpfy
Return Line` table
- Marked old `Return Reason` enum field as obsolete
- Added `externalTraceId` field to payout queries and `Shpfy Payout`
table
- Made `ImportPayout()` internal for testability
- Removed deprecated `taxCode` field from variant queries and mutations
- Marked `Tax Code` field as obsolete on `Shpfy Variant` table and page
- Added `article_reference` metafield type with
`ShpfyMtfldTypeArticleRef.Codeunit.al`
- **New**: ShpfyInventoryExportTest.Codeunit.al - Tests for idempotency,
retry logic, and skipped record logging
- **New**: ShpfyInventorySubscriber.Codeunit.al - Mock subscriber with
configurable retry scenarios
- **New**: ShpfyInventoryRetryScenario.Enum.al - Enum for test scenarios
(Success, FailOnceThenSucceed, AlwaysFail)
- **New**: ShpfyVariantBatchingTest.Codeunit.al - Tests for 50K limit
batch calculations
- **Updated**: ShpfyOrderRefundsHelper.Codeunit.al - Uses new return
reason fields
- **Updated**: ShpfyPaymentsTest.Codeunit.al - Added `externalTraceId`
test
- **Updated**: ShpfyBulkOpSubscriber.Codeunit.al - Removed obsolete
`currentBulkOperation` handler
- **Deleted**: CurrentBulkOperationCompletedResult.txt,
CurrentBulkOperationRunningResult.txt
- `inventorySetOnHandQuantities` mutation replaced - no action required
for users
- `returnReason` field deprecated - users should reference `Return
Reason Name` instead
- `taxCode` field deprecated - users relying on this field should
migrate away
- [Shopify API 2026-01
Changelog](https://shopify.dev/changelog?filter=api&api_version=2026-01&api_type=admin-graphql)
- [Shopify API 2025-10
Changelog](https://shopify.dev/changelog?filter=api&api_version=2025-10&api_type=admin-graphql)
Fixes
[AB#617321](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/617321)
…iple of 250 (#7214) - Guard the final `ExecuteInventoryGraphQL` call in `ExportStock` with `if InputSize > 0` to avoid sending an unnecessary empty request when the number of inventory items is an exact multiple of the 250-item batch size Fixes [AB#625960](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/625960) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…PI (#8309) ## What this changes In Shpfy Returns API (codeunit 30250), procedures GetReturnLocations (lines 107–130) and GetReturnLocationsFromReturnFulfillOrder (lines 132–155) both declare a local `LineParameters: Dictionary of [text, Text]` and pass that dictionary to `CommunicationMgt.ExecuteGraphQL` — but they were writing the `After` cursor into the **module-level** `Parameters` dictionary instead. As a result the `{{After}}` placeholder in `GetNextReverseFulfillmentOrders.graphql` and `GetNextReverseFulfillmentOrderLines.graphql` (both substituted from `LineParameters`) was never populated, breaking pagination beyond the first 10 reverse-fulfillment-orders for a return, or the first 10 line items of a reverse fulfillment order. The user-visible symptom is **Shpfy Return Lines with missing Location IDs**, and credit memos that consequently lose the restock-to-location information for the affected lines. The intermittence depends on whether a return reaches the >10 reverse-fulfillment-orders or >10 lines-per-RFO thresholds. This PR replaces the three `Parameters` references in each procedure with `LineParameters` — the dictionary that is actually passed to `ExecuteGraphQL`. Six lines changed total. ## Why no test There is no existing unit-test coverage for `GetReturnLocations` / `GetReturnLocationsFromReturnFulfillOrder` in `src/Apps/W1/Shopify/Test`. A pagination test would need new mock-GraphQL fixtures that simulate the `pageInfo.hasNextPage` contract for the `reverseFulfillmentOrders` connection and a multi-page disposition response. That harness work is out of scope for this surgical fix; a follow-up to add coverage is welcome. Fixes [AB#636657](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/636657) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On main, the backfill test added by PR #7633 reuses the 2-arg GetRandomPayout(Id, ExternalTraceId) helper introduced by the API 2026-01 uptake (PR #6244), passing a throwaway value for the externalTraceId. On releases/27.x #7633 was backported before the uptake, so the cherry-pick produced two overloaded GetRandomPayout procedures, each with a local 'PayoutGidTxt' Label. AL's translation ID derivation collapses overloads, triggering AL0570. Mirror main: drop the 1-arg overload and have UnitTestImportPayoutBackfillsShopCode call the 2-arg helper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ring Reorder so UnitTestImportPayoutWithExternalTraceId runs before UnitTestImportPayoutBackfillsShopCode and add Initialize()/SetShop(Shop) plus Shop Code assertion to ExternalTraceId test. Matches the structure on main (post #7633), avoiding cross-test 'Any' codeunit and DB state leakage that caused the External Trace Id assertion to fail on 27.x. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #6244 to
releases/27.xas part of slice 621974.Fixes AB#617321
Commits included
29fe94dImport unverified returns. The API 2026-01 uptake builds on top of this.25f5fa324b1fa3be6ef87ShpfyReturnsAPI. The file was substantially rewritten by the uptake.7820cf1App/app.jsonidRanges.tofrom 30450 → 30460 to accommodate new codeunit30457from #6244.Scope rationale
The 17 commits that touch any file modified by #6244 since it merged were triaged. Only #7214 and #8309 are direct API-2026-01 follow-ups (fix bugs in code introduced or substantially rewritten by the uptake). All other overlap commits are independent features, refactors, version bumps, already-backported fixes, or coincidental file overlaps — explicitly excluded to keep this backport low-risk.
Notably excluded: PR #7204 (
IsTestInProgress→HttpClientHandlertest-infra migration) and PR #6396 (Inventory Sync Controls feature) — both are out-of-scope and not API-version-related.Conflict resolution
The uptake cherry-pick had 5 conflicts caused by PR #7633 (multi-store payout fix) already being backported to
releases/27.xas commit18ad26aae. All conflict hunks were resolved by preferring the uptake's content where it modifies the same lines, while preserving the multi-store fix elsewhere.PR #7214 cherry-pick dropped two
ForceExport-dependent test assertions that require PR #6396 (excluded from this backport).