Mechanic is a development and ecommerce automation platform for Shopify. :)
Based on an out-of-stock threshold you define, this task sends you an email summary (with CSV attachment) of all variants that are out of stock in any location. Run this task manually to receive the report on demand.
Runs Occurs when a user manually triggers the task and Occurs every day at midnight (in local time). Configuration includes out of stock quantity, report recipient email, and report subject.
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?)
mechanic/user/trigger mechanic/scheduler/daily
{% assign out_of_stock_list_items = array %} {% assign report_csv = array %} {% assign report_csv[0] = array %} {% assign report_csv[0][0] = "Display name" %} {% assign report_csv[0][1] = "Product ID" %} {% assign report_csv[0][2] = "Variant ID" %} {% assign report_csv[0][3] = "Location ID" %} {% assign cursor = nil %} {% for n in (0..30000) %} {% capture query %} query { productVariants( first: 3 after: {{ cursor | json }} sortKey: FULL_TITLE ) { pageInfo { hasNextPage endCursor } nodes { displayName legacyResourceId product { legacyResourceId } inventoryItem { tracked inventoryLevels(first: 100) { nodes { location { name legacyResourceId } quantities(names: "available") { name quantity } } } } } } } {% endcapture %} {% assign result = query | shopify %} {% if event.preview %} {% capture result_json %} { "data": { "productVariants": { "nodes": [ { "displayName": "Short Sleeve T-Shirt - M, Red", "inventoryItem": { "tracked": true, "inventoryLevels": { "nodes": [ { "location": { "name": "Warehouse" }, "quantities": [ { "name": "available", "quantity": 0 } ] } ] } } }, { "displayName": "Short Sleeve T-Shirt - S, Blue", "inventoryItem": { "tracked": true, "inventoryLevels": { "nodes": [ { "location": { "name": "Warehouse" }, "quantities": [ { "name": "available", "quantity": -1 } ] } ] } } }, { "displayName": "Short Sleeve T-Shirt - XL, Green", "inventoryItem": { "tracked": true, "inventoryLevels": { "nodes": [ { "location": { "name": "Storefront" }, "quantities": [ { "name": "available", "quantity": -5 } ] } ] } } } ] } } } {% endcapture %} {% assign result = result_json | parse_json %} {% endif %} {% for variant in result.data.productVariants.nodes %} {% if variant.inventoryItem.tracked == false %} {% continue %} {% endif %} {% for inventory_level in variant.inventoryItem.inventoryLevels.nodes %} {% if inventory_level.quantities.first.quantity <= options.out_of_stock_quantity__number_required %} {% capture list_item %} <li> {% if event.preview %} <a>{{ variant.displayName }}</a> {% else %} <a href="https://{{ shop.domain }}/admin/products/{{ variant.product.legacyResourceId }}/variants/{{ variant.legacyResourceId }}">{{ variant.displayName }}</a> {% endif %} ({{ inventory_level.quantities.first.quantity }} in {{ inventory_level.location.name }}) </li> {% endcapture %} {% assign out_of_stock_list_items[out_of_stock_list_items.size] = list_item %} {% assign report_csv_row = array %} {% assign report_csv_row[0] = variant.displayName %} {% assign report_csv_row[1] = variant.product.legacyResourceId %} {% assign report_csv_row[2] = variant.legacyResourceId %} {% assign report_csv_row[3] = inventory_level.location.legacyResourceId %} {% assign report_csv[report_csv.size] = report_csv_row %} {% endif %} {% endfor %} {% endfor %} {% if result.data.productVariants.pageInfo.hasNextPage %} {% assign cursor = result.data.productVariants.pageInfo.endCursor %} {% else %} {% break %} {% endif %} {% endfor %} {% if out_of_stock_list_items != empty %} {% action "email" %} { "to": {{ options.report_recipient_email__email_required | json }}, "subject": {{ options.report_subject__required | json }}, "body": {{ out_of_stock_list_items | join: newline | prepend: "<p>Hello,</p><p>The following variants are out of stock, in the named locations:</p><ul>" | append: "</ul><p>Thanks,<br>Mechanic, for " | append: shop.name | append: "</p>" | json }}, "attachments": { {{ "now" | date: "%Y%m%d" | prepend: "out-of-stock-" | append: ".csv" | json }}: {{ report_csv | csv | json }} } } {% endaction %} {% endif %}
0
Out of stock report ({{ "now" | date: "%Y-%m-%d" }})