Auto-reserve draft order items for X days, with Mechanic.

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

Auto-reserve draft order items for X days

Use this task to auto-reserve all of the line items for a set amount of time on qualifying new or updated draft orders. A common use case is when you have an app or service that is creating draft orders on your behalf and you want to make sure that the inventory for those orders is set aside if possible.

Runs Occurs whenever a draft order is created and Occurs whenever a draft order is updated, with a 10 second delay. Configuration includes amount of days to reserve, include draft orders with any of these tags, and exclude draft orders with any of these tags.

15-day free trial – unlimited tasks

Documentation

Use this task to auto-reserve all of the line items for a set amount of time on qualifying new or updated draft orders. A common use case is when you have an app or service that is creating draft orders on your behalf and you want to make sure that the inventory for those orders is set aside if possible.

Optionally, configure the task with one or more tags in the "Include draft orders with any of these tags" field, or configure the task with one or more tags in the "Exclude draft orders with any of these tags" field. Exclusion tags will be ignored if any inclusion tags are configured.

Important notes:

  • If no tags are configured, this task will attempt to reserve inventory on all new or updated draft orders
  • This task does not check the inventory of any line items before reserving them
  • Line items can only be reserved at the default location configured in Shopify, since draft orders do not support location assignment
  • The 10 second delay on the draft order update subscription should be left as configured to prevent interference with draft order completion events

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
shopify/draft_orders/create
shopify/draft_orders/update+10.seconds
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
amount of days to reserve (number, required), include draft orders with any of these tags (array), exclude draft orders with any of these tags (array)
Code
{% assign amount_of_days_to_reserve = options.amount_of_days_to_reserve__number_required | floor %}
{% assign inclusion_tags = options.include_draft_orders_with_any_of_these_tags__array %}
{% assign exclusion_tags = options.exclude_draft_orders_with_any_of_these_tags__array %}

{% if amount_of_days_to_reserve < 1 %}
  {% error "The amount of days to reserve must be a positive number." %}
{% endif %}

{% if inclusion_tags != blank and exclusion_tags != blank %}
  {% log "Exclusion tags will be ignored if any inclusion tags are configured." %}
{% endif %}

{% if event.topic == "shopify/draft_orders/create" or event.topic == "shopify/draft_orders/update" %}
  {% comment %}
    -- get draft order data
  {% endcomment %}

  {% capture query %}
    query {
      draftOrder(id: {{ draft_order.admin_graphql_api_id | json }}) {
        id
        reserveInventoryUntil
        status
        tags
      }
    }
  {% endcapture %}

  {% assign result = query | shopify %}

  {% if event.preview %}
    {% capture result_json %}
      {
        "data": {
          "draftOrder": {
            "id": "gid://shopify/DraftOrder/1234567890",
            "tags": {{ array | push: inclusion_tags.first | json }}
          }
        }
      }
    {% endcapture %}

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

  {% assign draft_order = result.data.draftOrder %}
  {% assign draft_order_tags_lowercase = draft_order.tags | json | downcase | parse_json %}

  {% log draft_order: draft_order %}

  {% if draft_order.status == "COMPLETED" %}
    {% log "This draft order has already been completed; skipping." %}
    {% break %}
  {% endif %}

  {% if draft_order.reserveInventoryUntil != blank %}
    {% log %}
      "Draft order already has a reservation date set ({{ draft_order.reserveInventoryUntil | date: "%FT%T" }}); skipping."
    {% endlog %}
    {% break %}
  {% endif %}

  {% comment %}
    -- first check if there are any inclusion tags configured, and if not then check for exclusion tags
  {% endcomment %}

  {% if inclusion_tags != blank %}
    {% assign draft_order_qualifies = false %}
    {% assign inclusion_tags_lowercase = inclusion_tags | json | downcase | parse_json %}

    {% for inclusion_tag_lowercase in inclusion_tags_lowercase %}
      {% if draft_order_tags_lowercase contains inclusion_tag_lowercase %}
        {% assign draft_order_qualifies = true %}
        {% break %}
      {% endif %}
    {% endfor %}

  {% elsif exclusion_tags != blank %}
    {% assign draft_order_qualifies = true %}
    {% assign exclusion_tags_lowercase = exclusion_tags | json | downcase | parse_json %}

    {% for exclusion_tag_lowercase in exclusion_tags_lowercase %}
      {% if draft_order_tags_lowercase contains exclusion_tag_lowercase %}
        {% assign draft_order_qualifies = false %}
        {% break %}
      {% endif %}
    {% endfor %}

  {% else %}
    {% log "No inclusion or exclusion tags are configured; all draft orders will attempt to reserve inventory." %}
    {% assign draft_order_qualifies = true %}
  {% endif %}

  {% unless draft_order_qualifies %}
    {% log "This draft order either does not have an inclusion tag, or it has an exclusion tag; skipping." %}
    {% break %}
  {% endunless %}

  {% comment %}
    -- calculate the reserve date to be 1 minute before midnight on the calculated reserve date (local shop time)
    -- this follows default convention used in Shopify admin
  {% endcomment %}

  {%- capture reserve_duration -%}
    +{{ amount_of_days_to_reserve | plus: 1 }} days
  {%- endcapture -%}

  {% assign reserve_date
    = "now"
    | date: "%F", advance: reserve_duration
    | date: "%FT%TZ", tz: "UTC", advance: "-1 minute"
  %}

  {% log %}
    "Reserve until (local shop time): {{ reserve_date | date: "%FT%T" }}"
  {% endlog %}

  {% comment %}
    -- update the draft order with the reserve date
  {% endcomment %}

  {% action "shopify" %}
    mutation {
      draftOrderUpdate(
        id: {{ draft_order.id | json }}
        input: {
          reserveInventoryUntil: {{ reserve_date | json }}
        }
      ) {
        userErrors {
          field
          message
        }
        draftOrder {
          name
          reserveInventoryUntil
        }
      }
    }
  {% endaction %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Include draft orders with any of these tags
["RESERVE"]