Skip to content

Commit 58e712e

Browse files
committed
separate gift card fulfilments
1 parent 1a898de commit 58e712e

File tree

3 files changed

+140
-52
lines changed

3 files changed

+140
-52
lines changed

docs/auto-fulfill-items-that-dont-require-shipping/README.md

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Tags: Fulfillment, Orders
44

5-
Useful for digital products, memberships, or anything else that needs to be fulfilled instantly. This task watches for paid (or new) orders, and auto-fulfills all line items that don't require shipping.
5+
Useful for digital products, shipping insurance, gift cards, or anything else that needs to be fulfilled instantly. This task watches for new orders, and auto-fulfills all line items that don't require shipping.
66

77
* View in the task library: [tasks.mechanic.dev/auto-fulfill-items-that-dont-require-shipping](https://tasks.mechanic.dev/auto-fulfill-items-that-dont-require-shipping)
88
* Task JSON, for direct import: [task.json](../../tasks/auto-fulfill-items-that-dont-require-shipping.json)
@@ -15,7 +15,8 @@ Useful for digital products, memberships, or anything else that needs to be fulf
1515
"include_products_with_any_of_these_tags__array": null,
1616
"exclude_products_with_any_of_these_tags__array": null,
1717
"only_process_paid_orders__boolean": true,
18-
"wait_until_any_other_shippable_items_are_fulfilled__boolean": false
18+
"wait_until_any_other_shippable_items_are_fulfilled__boolean": false,
19+
"fulfill_gift_cards__boolean": true
1920
}
2021
```
2122

@@ -33,13 +34,21 @@ mechanic/user/trigger
3334

3435
## Documentation
3536

36-
Useful for digital products, memberships, or anything else that needs to be fulfilled instantly. This task watches for paid (or new) orders, and auto-fulfills all line items that don't require shipping.
37+
Useful for digital products, shipping insurance, gift cards, or anything else that needs to be fulfilled instantly. This task watches for new orders, and auto-fulfills all line items that don't require shipping.
3738

38-
Optionally, choose to only process paid orders (default), to wait until other shippable items are fulfilled, and whether to include or exclude products by tag.
39+
Optionally, choose whether to:
40+
- Only process paid orders
41+
- Wait until other shippable items are fulfilled
42+
- Fulfill gift cards
43+
- Include or exclude products by tag
44+
45+
This task may also be run manually to process existing open, unfulfilled orders.
46+
47+
**Important:**
48+
- Exclusion tags on a product will take priority over inclusion tags
49+
- Shopify has an optional admin setting to auto-fulfill gift cards when orders are paid. Depending on how this task is configured, that setting may need to be turned off to avoid fulfillment conflicts.
3950

40-
**Note:** exclusion tags on a product will take priority over inclusion tags.
4151

42-
This task may also be run manually to process existing open, unfulfilled orders (checking for paid status or other shippable items as configured).
4352

4453
## Installing this task
4554

docs/auto-fulfill-items-that-dont-require-shipping/script.liquid

Lines changed: 121 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
{% assign exclusion_tags = options.exclude_products_with_any_of_these_tags__array %}
33
{% assign only_process_paid_orders = options.only_process_paid_orders__boolean %}
44
{% assign wait_until_any_other_shippable_items_are_fulfilled = options.wait_until_any_other_shippable_items_are_fulfilled__boolean %}
5+
{% assign fulfill_gift_cards = options.fulfill_gift_cards__boolean %}
56

67
{% if event.topic contains "shopify/orders/" %}
78
{% comment %}
8-
-- get all open or in progress fulfillment orders
9+
-- get all open or in progress fulfillment orders for this order
910
{% endcomment %}
1011

1112
{% capture query %}
@@ -32,7 +33,11 @@
3233
remainingQuantity
3334
requiresShipping
3435
variant {
36+
id
37+
displayName
3538
product {
39+
id
40+
isGiftCard
3641
tags
3742
}
3843
}
@@ -76,6 +81,7 @@
7681
}
7782
nodes {
7883
id
84+
name
7985
displayFinancialStatus
8086
displayFulfillmentStatus
8187
fulfillmentOrders(
@@ -95,7 +101,11 @@
95101
remainingQuantity
96102
requiresShipping
97103
variant {
104+
id
105+
displayName
98106
product {
107+
id
108+
isGiftCard
99109
tags
100110
}
101111
}
@@ -152,6 +162,16 @@
152162
"tags": {{ inclusion_tags.first | json }}
153163
}
154164
}
165+
},
166+
{
167+
"id": "gid://shopify/FulfillmentOrderLineItem/2345678901",
168+
"remainingQuantity": 1,
169+
"requiresShipping": false,
170+
"variant": {
171+
"product": {
172+
"isGiftCard": true
173+
}
174+
}
155175
}
156176
]
157177
}
@@ -186,6 +206,7 @@
186206

187207
{% comment %}
188208
-- fulfillments can only be created for one location at a time, so need to group fulfillment orders by location
209+
-- Shopify will also throw an error if gift cards are fulfilled with any other item types
189210
{% endcomment %}
190211

191212
{% assign fulfillment_orders_by_location = hash %}
@@ -197,7 +218,7 @@
197218

198219
{% for fulfillment_order_line_item in fulfillment_order.lineItems.nodes %}
199220
{% comment %}
200-
-- skip items that do not require shipping, but set flag if any are unfulfilled
221+
-- skip items that require shipping, but set flag if any are unfulfilled in case the option to wait on them is enabled
201222
{% endcomment %}
202223

203224
{% if fulfillment_order_line_item.requiresShipping %}
@@ -255,23 +276,34 @@
255276
{% endif %}
256277

257278
{% comment %}
258-
-- save unfulfilled line items that do not require shipping
279+
-- save unfulfilled line items that do not require shipping; gift cards must be grouped separately
259280
{% endcomment %}
260281

261282
{% if fulfillment_order_line_item.remainingQuantity > 0 %}
262-
{% assign fulfillment_order_data["unfulfilled_line_items"]
263-
= fulfillment_order_data["unfulfilled_line_items"]
264-
| default: array
265-
| push: fulfillment_order_line_item
266-
%}
283+
{% if fulfillment_order_line_item.variant.product.isGiftCard %}
284+
{% if fulfill_gift_cards %}
285+
{% assign fulfillment_order_data["gift_cards_to_fulfill"]
286+
= fulfillment_order_data["gift_cards_to_fulfill"]
287+
| default: array
288+
| push: fulfillment_order_line_item
289+
%}
290+
{% endif %}
291+
292+
{% else %}
293+
{% assign fulfillment_order_data["line_items_to_fulfill"]
294+
= fulfillment_order_data["line_items_to_fulfill"]
295+
| default: array
296+
| push: fulfillment_order_line_item
297+
%}
298+
{% endif %}
267299
{% endif %}
268300
{% endfor %}
269301

270302
{% comment %}
271-
-- group unfulfilled line items by location for fulfillment
303+
-- group fulfillment orders by location
272304
{% endcomment %}
273305

274-
{% if fulfillment_order_data.unfulfilled_line_items != blank %}
306+
{% if fulfillment_order_data.line_items_to_fulfill != blank or fulfillment_order_data.gift_cards_to_fulfill != blank %}
275307
{% assign fulfillment_orders_by_location[fulfillment_order.assignedLocation.location.id]
276308
= fulfillment_orders_by_location[fulfillment_order.assignedLocation.location.id]
277309
| default: array
@@ -280,7 +312,10 @@
280312
{% endif %}
281313
{% endfor %}
282314

283-
{% if wait_until_any_other_shippable_items_are_fulfilled and has_unfulfilled_shippable_items and fulfillment_orders_by_location != blank %}
315+
{% if wait_until_any_other_shippable_items_are_fulfilled
316+
and has_unfulfilled_shippable_items
317+
and fulfillment_orders_by_location != blank
318+
%}
284319
{% log
285320
message: "Unfulfilled shippable items exist on this order and the 'Wait until any other shippable items are fulfilled' option is checked; no auto fulfillments will be made in this task run.",
286321
order: order
@@ -289,42 +324,85 @@
289324
{% endif %}
290325

291326
{% comment %}
292-
-- fulfill the items that don't require shipping
327+
-- fulfill the line items that don't require shipping; fulfill any gift cards separately
293328
{% endcomment %}
294329

330+
{% unless event.preview %}
331+
{% log
332+
order_name: order.name,
333+
fulfillment_orders_by_location: fulfillment_orders_by_location
334+
%}
335+
{% endunless %}
336+
295337
{% for keyval in fulfillment_orders_by_location %}
296-
{% action "shopify" %}
297-
mutation {
298-
fulfillmentCreate(
299-
fulfillment: {
300-
lineItemsByFulfillmentOrder: [
301-
{% for fulfillment_order_data in keyval[1] %}
302-
{
303-
fulfillmentOrderId: {{ fulfillment_order_data.fulfillment_order_id | json }}
304-
fulfillmentOrderLineItems: [
305-
{% for unfulfilled_line_item in fulfillment_order_data.unfulfilled_line_items %}
306-
{
307-
id: {{ unfulfilled_line_item.id | json }}
308-
quantity: {{ unfulfilled_line_item.remainingQuantity }}
309-
}
310-
{% endfor %}
311-
]
312-
}
313-
{% endfor %}
314-
]
315-
notifyCustomer: false
316-
}
317-
) {
318-
fulfillment {
319-
id
320-
status
338+
{% for fulfillment_order_data in keyval[1] %}
339+
{% if fulfillment_order_data.gift_cards_to_fulfill != blank %}
340+
{% action "shopify" %}
341+
mutation {
342+
fulfillmentCreate(
343+
fulfillment: {
344+
lineItemsByFulfillmentOrder: [
345+
{
346+
fulfillmentOrderId: {{ fulfillment_order_data.fulfillment_order_id | json }}
347+
fulfillmentOrderLineItems: [
348+
{% for line_item in fulfillment_order_data.gift_cards_to_fulfill %}
349+
{
350+
id: {{ line_item.id | json }}
351+
quantity: {{ line_item.remainingQuantity }}
352+
}
353+
{% endfor %}
354+
]
355+
}
356+
]
357+
notifyCustomer: false
358+
}
359+
) {
360+
fulfillment {
361+
id
362+
status
363+
}
364+
userErrors {
365+
field
366+
message
367+
}
368+
}
321369
}
322-
userErrors {
323-
field
324-
message
370+
{% endaction %}
371+
{% endif %}
372+
373+
{% if fulfillment_order_data.line_items_to_fulfill != blank %}
374+
{% action "shopify" %}
375+
mutation {
376+
fulfillmentCreate(
377+
fulfillment: {
378+
lineItemsByFulfillmentOrder: [
379+
{
380+
fulfillmentOrderId: {{ fulfillment_order_data.fulfillment_order_id | json }}
381+
fulfillmentOrderLineItems: [
382+
{% for line_item in fulfillment_order_data.line_items_to_fulfill %}
383+
{
384+
id: {{ line_item.id | json }}
385+
quantity: {{ line_item.remainingQuantity }}
386+
}
387+
{% endfor %}
388+
]
389+
}
390+
]
391+
notifyCustomer: false
392+
}
393+
) {
394+
fulfillment {
395+
id
396+
status
397+
}
398+
userErrors {
399+
field
400+
message
401+
}
402+
}
325403
}
326-
}
327-
}
328-
{% endaction %}
404+
{% endaction %}
405+
{% endif %}
406+
{% endfor %}
329407
{% endfor %}
330408
{% endfor %}

0 commit comments

Comments
 (0)