Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patch Keep variant inventory in sync across locations #274

Merged
merged 1 commit into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
{% endif %}

{% assign inventory_item = result.data.inventoryLevel.item %}
{% assign variant = inventory_item.variant %}
{% assign product = inventory_item.variant.product %}
{% assign inventory_levels = inventory_item.inventoryLevels.nodes %}

Expand Down
2 changes: 1 addition & 1 deletion tasks/keep-variant-inventory-in-sync-across-locations.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
}
}
],
"script": "{% assign filter_by_these_product_types = options.filter_by_these_product_types__array %}\n\n{% comment %}\n -- query for \"available\" quantites at all locations where this inventory item / variant is stocked\n{% endcomment %}\n\n{% capture query %}\n query {\n inventoryLevel(id: {{ inventory_level.admin_graphql_api_id | json }}) {\n item {\n id\n variant {\n legacyResourceId\n product {\n productType\n }\n }\n inventoryLevels(first: 100) {\n nodes {\n id\n location {\n id\n }\n quantities(names: \"available\") {\n quantity\n }\n }\n }\n }\n }\n }\n{% endcapture %}\n\n{% assign result = query | shopify %}\n\n{% if event.preview %}\n {% capture result_json %}\n {\n \"data\": {\n \"inventoryLevel\": {\n \"item\": {\n \"id\": \"gid://shopify/InventoryItem/1234567890\",\n \"variant\": {\n \"legacyResourceId\": \"1234567890\",\n \"product\": {\n \"productType\": {{ filter_by_these_product_types.first | json }}\n }\n },\n \"inventoryLevels\": {\n \"nodes\": [\n {\n \"id\": \"gid://shopify/InventoryLevel/1234567890?inventory_item_id=1234567890\",\n \"location\": {\n \"id\": \"gid://shopify/Location/1234567890\"\n },\n \"quantities\": [\n {\n \"quantity\": 1\n }\n ]\n },\n {\n \"id\": \"gid://shopify/InventoryLevel/2345678901?inventory_item_id=1234567890\",\n \"location\": {\n \"id\": \"gid://shopify/Location/2345678901\"\n },\n \"quantities\": [\n {\n \"quantity\": 0\n }\n ]\n }\n ]\n }\n }\n }\n }\n }\n {% endcapture %}\n\n {% assign result = result_json | parse_json %}\n{% endif %}\n\n{% assign inventory_item = result.data.inventoryLevel.item %}\n{% assign product = inventory_item.variant.product %}\n{% assign inventory_levels = inventory_item.inventoryLevels.nodes %}\n\n{% comment %}\n -- if product types are configured in the task, make sure this inventory level update belongs to a product with one of the configured types\n{% endcomment %}\n\n{% if filter_by_these_product_types != blank %}\n {% unless filter_by_these_product_types contains product.productType %}\n {% log\n message: \"Product type is not in the configured product types; skipping.\",\n variant: variant,\n filter_by_these_product_types: filter_by_these_product_types\n %}\n {% break %}\n {% endunless %}\n{% endif %}\n\n{% if inventory_levels.size < 2 %}\n {% log\n message: \"This variant is only stocked at a single location; no inventory sync needed.\",\n variant: variant\n %}\n {% break %}\n{% endif %}\n\n{% comment %}\n -- get the \"available\" quantity for the inventory level that caused the update event\n{% endcomment %}\n\n{% assign source_inventory_level\n = inventory_levels\n | where: \"id\", inventory_level.admin_graphql_api_id\n | first\n%}\n\n{% assign source_quantity = source_inventory_level.quantities.first.quantity %}\n\n{% comment %}\n -- check to see if a cached value exists, and set this inventory level to that value if they are not the same\n{% endcomment %}\n\n{% assign cache_key = \"variant-inventory-level-\" | append: inventory_item.variant.legacyResourceId %}\n{% assign cached_value = cache[cache_key] %}\n\n{% if cached_value != blank %}\n {% log\n message: \"Cached variant inventory level value already exists, which means an update was made in the last minute. Revert this inventory level if mismatched.\",\n cached_value: cached_value,\n source_quantity: source_quantity\n %}\n\n {% if cached_value != source_quantity %}\n {% action \"shopify\" %}\n mutation {\n inventoryAdjustQuantities(\n input: {\n name: \"available\"\n reason: \"correction\"\n changes: [\n {\n inventoryItemId: {{ inventory_item.id | json }}\n locationId: {{ source_inventory_level.location.id | json }}\n delta: {{ cached_value | minus: source_quantity }}\n }\n ]\n }\n ) {\n userErrors {\n code\n field\n message\n }\n }\n }\n {% endaction %}\n {% endif %}\n\n {% break %}\n{% endif %}\n\n{% comment %}\n -- no cached value exists, so set it and then adjust \"available\" quantities across locations, using the source quantity to determine deltas\n{% endcomment %}\n\n{% action \"cache\", \"setex\", cache_key, 60, source_quantity %}\n\n{% assign adjustments = array %}\n\n{% for inventory_level in inventory_levels %}\n {% assign delta = source_quantity | minus: inventory_level.quantities.first.quantity %}\n\n {% if delta != 0 %}\n {% assign adjustment = hash %}\n {% assign adjustment[\"inventoryItemId\"] = inventory_item.id %}\n {% assign adjustment[\"locationId\"] = inventory_level.location.id %}\n {% assign adjustment[\"delta\"] = delta %}\n {% assign adjustments = adjustments | push: adjustment %}\n {% endif %}\n{% endfor %}\n\n{% if adjustments != blank %}\n {% action \"shopify\" %}\n mutation {\n inventoryAdjustQuantities(\n input: {\n name: \"available\"\n reason: \"correction\"\n changes: {{ adjustments | graphql_arguments }}\n }\n ) {\n userErrors {\n code\n field\n message\n }\n }\n }\n {% endaction %}\n{% endif %}\n",
"script": "{% assign filter_by_these_product_types = options.filter_by_these_product_types__array %}\n\n{% comment %}\n -- query for \"available\" quantites at all locations where this inventory item / variant is stocked\n{% endcomment %}\n\n{% capture query %}\n query {\n inventoryLevel(id: {{ inventory_level.admin_graphql_api_id | json }}) {\n item {\n id\n variant {\n legacyResourceId\n product {\n productType\n }\n }\n inventoryLevels(first: 100) {\n nodes {\n id\n location {\n id\n }\n quantities(names: \"available\") {\n quantity\n }\n }\n }\n }\n }\n }\n{% endcapture %}\n\n{% assign result = query | shopify %}\n\n{% if event.preview %}\n {% capture result_json %}\n {\n \"data\": {\n \"inventoryLevel\": {\n \"item\": {\n \"id\": \"gid://shopify/InventoryItem/1234567890\",\n \"variant\": {\n \"legacyResourceId\": \"1234567890\",\n \"product\": {\n \"productType\": {{ filter_by_these_product_types.first | json }}\n }\n },\n \"inventoryLevels\": {\n \"nodes\": [\n {\n \"id\": \"gid://shopify/InventoryLevel/1234567890?inventory_item_id=1234567890\",\n \"location\": {\n \"id\": \"gid://shopify/Location/1234567890\"\n },\n \"quantities\": [\n {\n \"quantity\": 1\n }\n ]\n },\n {\n \"id\": \"gid://shopify/InventoryLevel/2345678901?inventory_item_id=1234567890\",\n \"location\": {\n \"id\": \"gid://shopify/Location/2345678901\"\n },\n \"quantities\": [\n {\n \"quantity\": 0\n }\n ]\n }\n ]\n }\n }\n }\n }\n }\n {% endcapture %}\n\n {% assign result = result_json | parse_json %}\n{% endif %}\n\n{% assign inventory_item = result.data.inventoryLevel.item %}\n{% assign variant = inventory_item.variant %}\n{% assign product = inventory_item.variant.product %}\n{% assign inventory_levels = inventory_item.inventoryLevels.nodes %}\n\n{% comment %}\n -- if product types are configured in the task, make sure this inventory level update belongs to a product with one of the configured types\n{% endcomment %}\n\n{% if filter_by_these_product_types != blank %}\n {% unless filter_by_these_product_types contains product.productType %}\n {% log\n message: \"Product type is not in the configured product types; skipping.\",\n variant: variant,\n filter_by_these_product_types: filter_by_these_product_types\n %}\n {% break %}\n {% endunless %}\n{% endif %}\n\n{% if inventory_levels.size < 2 %}\n {% log\n message: \"This variant is only stocked at a single location; no inventory sync needed.\",\n variant: variant\n %}\n {% break %}\n{% endif %}\n\n{% comment %}\n -- get the \"available\" quantity for the inventory level that caused the update event\n{% endcomment %}\n\n{% assign source_inventory_level\n = inventory_levels\n | where: \"id\", inventory_level.admin_graphql_api_id\n | first\n%}\n\n{% assign source_quantity = source_inventory_level.quantities.first.quantity %}\n\n{% comment %}\n -- check to see if a cached value exists, and set this inventory level to that value if they are not the same\n{% endcomment %}\n\n{% assign cache_key = \"variant-inventory-level-\" | append: inventory_item.variant.legacyResourceId %}\n{% assign cached_value = cache[cache_key] %}\n\n{% if cached_value != blank %}\n {% log\n message: \"Cached variant inventory level value already exists, which means an update was made in the last minute. Revert this inventory level if mismatched.\",\n cached_value: cached_value,\n source_quantity: source_quantity\n %}\n\n {% if cached_value != source_quantity %}\n {% action \"shopify\" %}\n mutation {\n inventoryAdjustQuantities(\n input: {\n name: \"available\"\n reason: \"correction\"\n changes: [\n {\n inventoryItemId: {{ inventory_item.id | json }}\n locationId: {{ source_inventory_level.location.id | json }}\n delta: {{ cached_value | minus: source_quantity }}\n }\n ]\n }\n ) {\n userErrors {\n code\n field\n message\n }\n }\n }\n {% endaction %}\n {% endif %}\n\n {% break %}\n{% endif %}\n\n{% comment %}\n -- no cached value exists, so set it and then adjust \"available\" quantities across locations, using the source quantity to determine deltas\n{% endcomment %}\n\n{% action \"cache\", \"setex\", cache_key, 60, source_quantity %}\n\n{% assign adjustments = array %}\n\n{% for inventory_level in inventory_levels %}\n {% assign delta = source_quantity | minus: inventory_level.quantities.first.quantity %}\n\n {% if delta != 0 %}\n {% assign adjustment = hash %}\n {% assign adjustment[\"inventoryItemId\"] = inventory_item.id %}\n {% assign adjustment[\"locationId\"] = inventory_level.location.id %}\n {% assign adjustment[\"delta\"] = delta %}\n {% assign adjustments = adjustments | push: adjustment %}\n {% endif %}\n{% endfor %}\n\n{% if adjustments != blank %}\n {% action \"shopify\" %}\n mutation {\n inventoryAdjustQuantities(\n input: {\n name: \"available\"\n reason: \"correction\"\n changes: {{ adjustments | graphql_arguments }}\n }\n ) {\n userErrors {\n code\n field\n message\n }\n }\n }\n {% endaction %}\n{% endif %}\n",
"subscriptions": ["shopify/inventory_levels/update"],
"subscriptions_template": "shopify/inventory_levels/update",
"tags": ["Inventory", "Location", "Sync", "Variants"]
Expand Down