Tag products as in- or out-of-stock, by location ID, with Mechanic.

Mechanic is a development and ecommerce automation platform for Shopify. :)

Tag products as in- or out-of-stock, by location ID

Use this task to easily keep an eye on which products are in stock, or out of stock, as established by individual locations. Configure tag prefixes and suffixes to arrive at product tags resembling "location-123456890-instock" or "oos-123456890". Configure this task to run hourly or daily, to keep these tags in sync.

Runs Occurs when a user manually triggers the task and Occurs when a bulk operation is completed. Configuration includes tag prefix when in stock, tag suffix when in stock, tag prefix when out of stock, tag suffix when out of stock, run daily, and run hourly.

15-day free trial – unlimited tasks

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Shopifolks, everybody.

That’s why we make it easy to configure automation without code, why we make it easy to tweak the underlying code once tasks are installed, and why we publish it all here for everyone to learn from.

(By the way, have you seen our documentation? Have you joined the Slack community?)

Open source
View on GitHub to contribute to this task
Subscriptions
mechanic/user/trigger
mechanic/shopify/bulk_operation

{% if options.run_daily__boolean %}
  mechanic/scheduler/daily
{% elsif options.run_hourly__boolean %}
  mechanic/scheduler/hourly
{% endif %}
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
tag prefix when in stock, tag suffix when in stock, tag prefix when out of stock, tag suffix when out of stock, run daily (boolean), run hourly (boolean)
Code
{% assign tag_prefix_when_in_stock = options.tag_prefix_when_in_stock %}
{% assign tag_suffix_when_in_stock = options.tag_suffix_when_in_stock %}
{% assign tag_prefix_when_out_of_stock = options.tag_prefix_when_out_of_stock %}
{% assign tag_suffix_when_out_of_stock = options.tag_suffix_when_out_of_stock %}

{% if tag_prefix_when_in_stock == blank and tag_suffix_when_in_stock == blank %}
  {% error "Add either a prefix or suffix for the 'in stock' tag, to distinguish it from the 'out of stock' tag." %}
{% endif %}

{% if tag_prefix_when_out_of_stock == blank and tag_suffix_when_out_of_stock == blank %}
  {% error "Add either a prefix or suffix for the 'out of stock' tag, to distinguish it from the 'in stock' tag." %}
{% endif %}

{% if event.topic == "mechanic/user/trigger" or event.topic contains "mechanic/scheduler/" %}
  {% capture bulk_operation_query %}
    query {
      products {
        edges {
          node {
            __typename
            id
            tags
            variants {
              edges {
                node {
                  __typename
                  id
                  inventoryItem {
                    inventoryLevels {
                      edges {
                        node {
                          __typename
                          id
                          location {
                            legacyResourceId
                          }
                          quantities(names: "available") {
                            name
                            quantity
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  {% endcapture %}

  {% action "shopify" %}
    mutation {
      bulkOperationRunQuery(
        query: {{ bulk_operation_query | json }}
      ) {
        bulkOperation {
          id
          status
        }
        userErrors {
          field
          message
        }
      }
    }
  {% endaction %}

{% elsif event.topic == "mechanic/shopify/bulk_operation" %}
  {% if event.preview %}
    {% capture bulkOperation_objects_jsonl %}
      {"__typename":"Product","id":"gid:\/\/shopify\/Product\/1234567890"}
      {"__typename":"ProductVariant","id":"gid:\/\/shopify\/ProductVariant\/1234567890","__parentId":"gid:\/\/shopify\/Product\/1234567890"}
      {"__typename":"InventoryLevel","location":{"legacyResourceId":"1234567890"},"quantities":[{"name":"available","quantity":1}],"__parentId":"gid:\/\/shopify\/ProductVariant\/1234567890"}
    {% endcapture %}

    {% assign bulkOperation = hash %}
    {% assign bulkOperation["objects"] = bulkOperation_objects_jsonl | parse_jsonl %}
  {% endif %}

  {% assign bulk_products = bulkOperation.objects | where: "__typename", "Product" %}
  {% assign bulk_variants = bulkOperation.objects | where: "__typename", "ProductVariant" %}
  {% assign bulk_inventory_levels = bulkOperation.objects | where: "__typename", "InventoryLevel" %}

  {% for product in bulk_products %}
    {% assign tags_to_add = array %}
    {% assign tags_to_remove = array %}
    {% assign in_stock_by_location_id = hash %}

    {% assign variants = bulk_variants | where: "__parentId", product.id %}

    {% for variant in variants %}
      {% assign inventory_levels = bulk_inventory_levels | where: "__parentId", variant.id %}

      {% for inventory_level in inventory_levels %}
        {% assign location_id = inventory_level.location.legacyResourceId %}

        {% if inventory_level.quantities.first.quantity > 0 %}
          {% assign in_stock_by_location_id[location_id] = true %}

        {% elsif in_stock_by_location_id[location_id] == blank %}
          {% assign in_stock_by_location_id[location_id] = false %}
        {% endif %}
      {% endfor %}
    {% endfor %}

    {% for keyval in in_stock_by_location_id %}
      {% assign location_id = keyval[0] %}
      {% assign in_stock = keyval[1] %}      
      {% assign in_stock_tag = tag_prefix_when_in_stock | append: location_id | append: tag_suffix_when_in_stock %}
      {% assign out_of_stock_tag = tag_prefix_when_out_of_stock | append: location_id | append: tag_suffix_when_out_of_stock %}

      {% if in_stock %}
        {% unless product.tags contains in_stock_tag %}
          {% assign tags_to_add = tags_to_add | push: in_stock_tag %}
        {% endunless %}

        {% if product.tags contains out_of_stock_tag %}
          {% assign tags_to_remove = tags_to_remove | push: out_of_stock_tag %}
        {% endif %}

      {% else %}
        {% unless product.tags contains out_of_stock_tag %}
          {% assign tags_to_add = tags_to_add | push: out_of_stock_tag %}
        {% endunless %}

        {% if product.tags contains in_stock_tag %}
          {% assign tags_to_remove = tags_to_remove | push: in_stock_tag %}
        {% endif %}
      {% endif %}
    {% endfor %}

    {% if tags_to_add != blank or tags_to_remove != blank %}
      {% action "shopify" %}
        mutation {
          {% if tags_to_add != blank %}
            tagsAdd(
              id: {{ product.id | json }}
              tags: {{ tags_to_add | json }}
            ) {
              userErrors {
                field
                message
              }
            }
          {% endif %}
          {% if tags_to_remove != blank %}
            tagsRemove(
              id: {{ product.id | json }}
              tags: {{ tags_to_remove | json }}
            ) {
              userErrors {
                field
                message
              }
            }
          {% endif %}
        }
      {% endaction %}
    {% endif %}
  {% endfor %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Tag prefix when in stock
location-
Tag suffix when in stock
-instock
Tag prefix when out of stock
location-
Tag suffix when out of stock
-outofstock