[Bug]: Blocked item variants remain purchasable in Shopify — variant-level Blocked/Sales Blocked only skips export
Nobody has claimed this yet.
- Dominant language
- AL
- Stars
- 683
- Forks
- 459
- Avg merge
- 3d 26m
- Merged PRs (30d)
- 633
Description
Describe the issue
When an Item Variant is marked Blocked or Sales Blocked in Business Central, the Shopify connector only skips the variant during product export. If the variant already exists in Shopify, it simply stops receiving updates — and stays fully purchasable in the online store. Business users expect that blocking a variant in BC stops selling it on Shopify, the same way blocking an item does (via "Action for Removed Products").
Details (verified in src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyProductExport.Codeunit.al, both in 28.3 and current main):
CreateProductVariantcorrectly skips blocked variants (they are never created in Shopify), but the update path (UpdateProductVariant→FillInProductVariantData) still syncs a blocked variant as a normal sellable variant — only the price recalculation is skipped."Available For Sales"onShpfy Variantis computed from item-level flags only —(not Item.Blocked) and (not Item."Sales Blocked")— the variant-level flags are ignored. Moreover the field maps toavailableForSale, which is a read-only computed field in the Shopify Admin API, so it is never sent to Shopify either way.Shop."Action for Removed Products"(StatusToDraft/StatusToArchived/DoNothing) exists only at product level and only reacts toItem.Blocked. There is no variant-level counterpart, andItem."Sales Blocked"alone is not handled at all.- The situation is worse for shops selling on non-availability (inventory policy
CONTINUE, the native Shopify way of offering made-to-order goods): even zero inventory does not stop sales of a blocked variant there.
The only trace is a Skipped Records entry ("Item variant is blocked or sales blocked."), which does not change anything on the Shopify side.
Expected behavior
Blocking a variant in BC makes it unpurchasable in Shopify on the next sync — a variant-level analogue of "Action for Removed Products", e.g. options to:
- remove/delete the Shopify variant, or
- force
inventoryPolicy: DENYand zero the available quantity for that variant.
At minimum, the variant-level Blocked/Sales Blocked flags should be handled consistently with the item-level behavior.
Steps to reproduce
- Sync an item with multiple variants to Shopify (product becomes ACTIVE with all variants purchasable).
- In BC, set
Blockedand/orSales Blockedon one of the variants. - Run the product sync and the inventory sync.
- Check the product in Shopify: the blocked variant is still active and purchasable (with its last-known price and inventory). Only a Skipped Record entry is written in BC.
Additional context
- Reproduced on 28.3; the relevant logic on current
mainis identical. - Real-world scenario: a color variant (e.g. an anniversary edition) is discontinued by purchasing while the other variants of the product keep selling. The purchasing department blocks the variant in BC and expects the e-shop to stop offering it, without having to touch the Shopify admin.
- Workaround we currently ship as a PTE: subscribers on
OnAfterCalculationStock(force zero stock for blocked variants) andOnAfterFillInProductVariantData(forceDENYinventory policy so the variant cannot sell on non-availability). It works, but every customer has to rediscover and rebuild this. - Happy to align on the preferred design (variant-level removed-action enum vs. simply respecting the variant flags in the update path) before opening the PR.
I will provide a fix for a bug
- I will provide a fix for a bug
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/Apps/W1/Shopify/App/src/Products/Codeunits/ShpfyProductExport.Codeunit.al and trace CreateProductVariant, UpdateProductVariant, and FillInProductVariantData, then compare the existing item-level Action for Removed Products behavior. Review the inventory path and the OnAfterCalculationStock and OnAfterFillInProductVariantData extension points. Done means a blocked or sales-blocked variant is no longer purchasable in Shopify after product and inventory sync, while other variants continue selling.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100