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

Mechanic is an automation development platform for Shopify. :)

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

by Isaac Bowen (team@usemechanic.com)

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 when a user triggers the task and when a bulk operation finishes. 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, Gurus, 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.

Events
when a user triggers the task (mechanic/user/trigger)
when a bulk operation finishes (mechanic/shopify/bulk_operation)
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)
Script
{% if options.tag_prefix_when_in_stock == blank and options.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 options.tag_prefix_when_out_of_stock == blank and options.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" %}
  {% capture bulk_operation_query %}
    query {
      products {
        edges {
          node {
            __typename
            id
            tags
            variants {
              edges {
                node {
                  __typename
                  id
                  inventoryItem {
                    inventoryLevels {
                      edges {
                        node {
                          __typename
                          id
                          location {
                            id
                          }
                          available
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  {% 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 %}
    {% assign bulkOperation = hash %}
    {% assign bulkOperation["objects"] = array %}

    {% assign product = hash %}
    {% assign product["__typename"] = "Product" %}
    {% assign product["id"] = "gid://shopify/Product/1234567890" %}
    {% assign product["tags"] = "" %}

    {% assign variant = hash %}
    {% assign variant["__typename"] = "Variant" %}
    {% assign variant["__parent"] = product %}

    {% assign inventory_level = hash %}
    {% assign inventory_level["__typename"] = "InventoryLevel" %}
    {% assign inventory_level["__parent"] = variant %}
    {% assign inventory_level["available"] = 1 %}
    {% assign inventory_level["location"] = hash %}
    {% assign inventory_level["location"]["id"] = "gid://shopify/Location/1234567890" %}

    {% assign bulkOperation["objects"][0] = product %}
    {% assign bulkOperation["objects"][1] = variant %}
    {% assign bulkOperation["objects"][2] = inventory_level %}
  {% endif %}

  {% assign in_stock_by_product_id_and_location_id = hash %}

  {% assign inventory_levels = bulkOperation.objects | where: "__typename", "InventoryLevel" %}
  {% assign products = bulkOperation.objects | where: "__typename", "Product" %}

  {% for inventory_level in inventory_levels %}
    {% assign variant = inventory_level.__parent %}
    {% assign product = variant.__parent %}
    {% assign location = inventory_level.location %}

    {% if in_stock_by_product_id_and_location_id[product.id] == nil %}
      {% assign in_stock_by_product_id_and_location_id[product.id] = hash %}
    {% endif %}

    {% if inventory_level.available > 0 %}
      {% assign in_stock_by_product_id_and_location_id[product.id][location.id] = true %}
    {% elsif in_stock_by_product_id_and_location_id[product.id][location.id] == nil %}
      {% assign in_stock_by_product_id_and_location_id[product.id][location.id] = false %}
    {% endif %}
  {% endfor %}

  {% for product in products %}
    {% for keyval in in_stock_by_product_id_and_location_id[product.id] %}
      {% assign location_id = keyval[0] %}
      {% assign in_stock = keyval[1] %}

      {% assign location_id_integer = location_id | split: "/" | last %}

      {% assign in_stock_tag = options.tag_prefix_when_in_stock | append: location_id_integer | append: options.tag_suffix_when_in_stock %}
      {% assign out_of_stock_tag = options.tag_prefix_when_out_of_stock | append: location_id_integer | append: options.tag_suffix_when_out_of_stock %}

      {% if in_stock %}
        {% assign tag_to_add = in_stock_tag %}
        {% assign tag_to_remove = out_of_stock_tag %}
      {% else %}
        {% assign tag_to_remove = in_stock_tag %}
        {% assign tag_to_add = out_of_stock_tag %}
      {% endif %}

      {% if product.tags contains tag_to_add %}
        {% assign tag_to_add = nil %}
      {% endif %}

      {% unless product.tags contains tag_to_remove %}
        {% assign tag_to_remove = nil %}
      {% endunless %}

      {% if tag_to_add or tag_to_remove %}
        {% action "shopify" %}
          mutation {
            {% if tag_to_add %}
              tagsAdd(
                id: {{ product.id | json }}
                tags: {{ tag_to_add | json }}
              ) {
                userErrors {
                  field
                  message
                }
              }
            {% endif %}
            {% if tag_to_remove %}
              tagsRemove(
                id: {{ product.id | json }}
                tags: {{ tag_to_remove | json }}
              ) {
                userErrors {
                  field
                  message
                }
              }
            {% endif %}
          }
        {% endaction %}
      {% endif %}
    {% endfor %}
  {% endfor %}
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.
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