Reset inventory levels daily, with Mechanic.

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

Reset inventory levels daily

This task resets your inventory levels at the default location in your shop, every night, for all products within a given collection (configured by ID).

Runs Occurs every day at midnight (in local time). Configuration includes inventory level to apply and collection id.

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/scheduler/daily
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
inventory level to apply (number, required), collection id (number, required)
Code
{% assign inventory_level_to_apply = options.inventory_level_to_apply__number_required %}
{% assign collection_id = options.collection_id__number_required %}

{% assign location_id = shop.primary_location_id | prepend: "gid://shopify/Location/" %}

{% comment %}
  -- get all product IDs from the configured collection
{% endcomment %}

{% assign cursor = nil %}
{% assign product_ids = array %}

{% for n in (1..100) %}
  {% capture query %}
    query {
      collection(id: {{ collection_id | prepend: "gid://shopify/Collection/" | json }}) {
        products(
          first: 250
          after: {{ cursor | json }}
        ) {
          pageInfo {
            hasNextPage
            endCursor
          }
          nodes {
            id
          }
        }
      }
    }
  {% endcapture %}

  {% assign result = query | shopify %}

  {% if event.preview %}
    {% capture result_json %}
      {
        "data": {
          "collection": {
            "products": {
              "nodes": [
                {
                  "id": "gid://shopify/Product/1234567890"
                }
              ]
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = result_json | parse_json %}
  {% endif %}

  {% assign collection = result.data.collection %}
  {% assign product_ids
    = collection.products.nodes
    | map: "id"
    | concat: product_ids
    %}

  {% if result.data.collection.products.pageInfo.hasNextPage %}
    {% assign cursor = result.data.collection.products.pageInfo.endCursor %}
  {% else %}
    {% break %}
  {% endif %}
{% endfor %}

{% comment %}
  -- make sure collection exists and has products
{% endcomment %}

{% if collection == blank %}
  {% log "Collection not found by ID." %}
  {% break %}

{% elsif product_ids == blank %}
  {% log "No products found in the collection." %}
  {% break %}
{% endif %}

{% comment %}
  -- determine which inventory levels need to be set on this task run
{% endcomment %}

{% assign inventory_inputs = array %}

{% for product_id in product_ids %}
  {% comment %}
    -- get all variants for this product (up to 2K), and their inventory items and inventory levels at the default location
  {% endcomment %}

  {% assign cursor = nil %}
  {% assign variants = array %}

  {% for n in (1..8) %}
    {% capture query %}
      query {
        product(id: {{ product_id | json }}) {
          id
          handle
          variants(
            first: 250
            after: {{ cursor | json }}
          ) {
            pageInfo {
              hasNextPage
              endCursor
            }
            nodes {
              inventoryItem {
                id
                tracked
                inventoryLevel(locationId: {{ location_id | json }}) {
                  quantities(names: "available") {
                    quantity
                  }
                }
              }
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = query | shopify %}

    {% if event.preview %}
      {% capture result_json %}
        {
          "data": {
            "product": {
              "variants": {
                "nodes": [
                  {
                    "inventoryItem": {
                      "id": "gid://shopify/InventoryItem/1234567890",
                      "tracked": "true",
                      "inventoryLevel": {
                        "quantities": {
                          "quantity": {{ inventory_level_to_apply | minus: 1 }}
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      {% endcapture %}

      {% assign result = result_json | parse_json %}
    {% endif %}

    {% comment %}
      -- if a variant's inventory is tracked (i.e. managed by Shopify) and the available quantity at the default location differs from the configured level, then add it to input array
    {% endcomment %}

    {% for variant in result.data.product.variants.nodes %}
      {% if variant.inventoryItem.tracked and variant.inventoryItem.inventoryLevel.quantities.first.quantity != inventory_level_to_apply %}
        {% assign inventory_input = hash %}
        {% assign inventory_input["inventoryItemId"] = variant.inventoryItem.id %}
        {% assign inventory_input["locationId"] = location_id %}
        {% assign inventory_input["quantity"] = inventory_level_to_apply %}
        {% assign inventory_inputs = inventory_inputs | push: inventory_input %}
      {% endif %}
    {% endfor %}

    {% if result.data.product.variants.pageInfo.hasNextPage %}
      {% assign cursor = result.data.product.variants.pageInfo.endCursor %}
    {% else %}
      {% break %}
    {% endif %}
  {% endfor %}
{% endfor %}

{% if inventory_inputs != blank %}
  {% assign groups_of_inventory_inputs = inventory_inputs | in_groups_of: 250, fill_with: false %}

  {% for group_of_inventory_inputs in groups_of_inventory_inputs %}
    {% action "shopify" %}
      mutation {
        inventorySetQuantities(
          input: {
            name: "available"
            reason: "correction"
            ignoreCompareQuantity: true
            quantities: {{ group_of_inventory_inputs | graphql_arguments }}
          }
        ) {
          userErrors {
            code
            field
            message
          }
        }
      }
    {% endaction %}
  {% endfor %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more