[releases/27.5] [Shopify] API 2026-01 uptake (#6244)#8366
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.5 as part of slice 621974.
Fixes AB#617321
Commits included
7b9c421Import unverified returns ([Shopify] Import unverified returns #4747) — prereq for the uptake (introduces the unverified-returns plumbing the uptake builds on)6495e43API 2026-01 uptake ([Shopify] API 2026-01 uptake #6244) — the main change: Shopify Admin API 2025-07 → 2026-01de89018Skip empty inventory API call when batch size is exact multiple of 250 ([Shopify] Skip empty inventory API call when batch size is exact multiple of 250 #7214) — fixes a boundary bug in the new 50K-batching code added by [Shopify] API 2026-01 uptake #62441726d4bFix wrong dictionary used for pagination cursor in ReturnsAPI ([Shopify] Fix wrong dictionary used for pagination cursor in ReturnsAPI #8309) — trivial 6-line fix in a file substantially rewritten by [Shopify] API 2026-01 uptake #62440892772Bump AppidRanges.toto 30460 — required to accommodate new codeunit 30457 added by [Shopify] API 2026-01 uptake #62442c9732aFix AL0570PayoutGidTxtduplicate translation ID — eliminated overloadedGetRandomPayoutLabel; surfaced under stricter validation on this branch66f6f92Align payout tests with main — reorders tests + addsInitialize()to fix shared-Any-state ordering issue that surfaced in CISame set of commits as the 27.x backport (#8360).