-
Notifications
You must be signed in to change notification settings - Fork 35
/
copy-draft-order-metafields-to-orders.json
26 lines (26 loc) · 8.4 KB
/
copy-draft-order-metafields-to-orders.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"docs": "This task will watch for orders created from draft, copying over any metafields to the order that match the ones configured in this task. If the \"Copy all metafields\" option is checked, then it will skip the matching and instead just copy any metafields that exist on the draft order.\n\nWhen configuring metafields to copy, they should be entered as **namespace.key** (e.g. \"custom.estimated_ship_date\").\n\nOrders may also be sent individually to this task from an admin link. Caution when using this feature though, as this task does not check if the metafields already exist on the order nor if the values are different; it will just overwrite them.",
"halt_action_run_sequence_on_error": false,
"name": "Copy draft order metafields to orders",
"online_store_javascript": null,
"options": {
"metafields_to_copy__array": [
"sample.change_me"
],
"copy_all_metafields__boolean": false
},
"order_status_javascript": null,
"perform_action_runs_in_sequence": false,
"preview_event_definitions": [],
"script": "{% assign metafields_to_copy = options.metafields_to_copy__array %}\n{% assign copy_all_metafields = options.copy_all_metafields__boolean %}\n\n{% comment %}\n -- check that task has been configured with at least one option, and that any metafields entered have the proper format (using match fitler, i.e. regex)\n{% endcomment %}\n\n{% unless copy_all_metafields %}\n {% if metafields_to_copy == blank %}\n {% error \"Choose either to 'Copy all metafields' or enter at least one metafield to copy.\" %}\n\n {% else %}\n {% for metafield_to_copy in metafields_to_copy %}\n {% assign metafield_check = metafield_to_copy | match: \"^([\\w-]{3,})\\.([\\w-]{3,})$\" %}\n\n {% unless metafield_check %}\n {% log invalid_metafield_format: metafield_to_copy %}\n\n {% error \"All configured metafields should be entered as namespace.key using only alphanumeric characters, underscores, and dashes.\" %}\n\n {% break %}\n {% endunless %}\n {% endfor %}\n {% endif %}\n{% endunless %}\n\n{% if event.topic == \"shopify/orders/create\" or event.topic == \"mechanic/user/order\" %}\n {% if event.preview %}\n {% capture order_json %}\n {\n \"admin_graphql_api_id\": \"gid://shopify/Order/1234567890\",\n \"source_name\": \"shopify_draft_order\"\n }\n {% endcapture %}\n \n {% assign order = order_json | parse_json %}\n {% endif %}\n \n {% if order.source_name != \"shopify_draft_order\" %}\n {% log \"Order was not generated from a draft; skipping\" %}\n {% break %}\n {% endif %}\n\n {% comment %}\n -- Shopify does not have any data in the REST or GraphQL order resources linking back to the completed draft order\n -- Query recent completed draft orders to find the link to this order\n -- As this task allows orders to be sent via the admin link, it will need to paginate the draft orders\n {% endcomment %}\n\n {% assign cursor = nil %}\n {% assign draft_order_id = nil %}\n\n {% for n in (1..10) %}\n {% capture query %}\n query {\n draftOrders(\n first: 250\n after: {{ cursor | json }}\n reverse: true\n query: \"status:completed\"\n ) {\n pageInfo {\n hasNextPage\n endCursor\n }\n nodes {\n id\n order {\n id\n }\n }\n }\n }\n {% endcapture %}\n\n {% assign result = query | shopify %}\n\n {% if event.preview %}\n {% capture result_json %}\n {\n \"data\": {\n \"draftOrders\": {\n \"nodes\": [\n {\n \"id\": \"gid://shopify/DraftOrder/1234567890\",\n \"order\": {\n \"id\": \"gid://shopify/Order/1234567890\"\n }\n }\n ]\n }\n }\n }\n {% endcapture %}\n\n {% assign result = result_json | parse_json %}\n {% endif %}\n\n {% comment %}\n -- search for order ID in this batch before querying another page of results\n {% endcomment %}\n\n {% for draft_order in result.data.draftOrders.nodes %}\n {% if draft_order.order.id == order.admin_graphql_api_id %}\n {% assign draft_order_id = draft_order.id %}\n {% break %}\n {% endif %}\n {% endfor %}\n\n {% if draft_order_id == blank and result.data.draftOrders.pageInfo.hasNextPage %}\n {% assign cursor = result.data.draftOrders.pageInfo.endCursor %}\n {% else %}\n {% break %}\n {% endif %}\n {% endfor %}\n\n {% if draft_order_id == blank %}\n {% log \"Source draft order for this order was not found in most recent 2500 completed draft orders\" %}\n {% break %}\n {% endif %}\n\n {% comment %}\n -- get metafields from draft order\n -- Shopify supports up to 200 metafields per resource (as of June 2023)\n {% endcomment %}\n\n {% capture query %}\n query {\n draftOrder(id: {{ draft_order_id | json }}) {\n metafields(first: 200) {\n nodes {\n namespace\n key\n type\n value\n }\n }\n }\n }\n {% endcapture %}\n\n {% assign result = query | shopify %}\n\n {% comment %}\n -- preview block uses the first configured metafield (if there is one) so that the logic below will find a \"match\"\n {% endcomment %}\n\n {% if event.preview %}\n {% capture result_json %}\n {\n \"data\": {\n \"draftOrder\": {\n \"metafields\": {\n \"nodes\": [\n {\n \"namespace\": {{ metafields_to_copy.first | split: \".\" | first | default: \"custom\" | json }},\n \"key\": {{ metafields_to_copy.first | split: \".\" | last | default: \"preview\" | json }},\n \"type\": \"single_line_text_field\",\n \"value\": \"alpha\"\n }\n ]\n }\n }\n }\n }\n {% endcapture %}\n\n {% assign result = result_json | parse_json %}\n {% endif %}\n\n {% assign draft_order_metafields = result.data.draftOrder.metafields.nodes %}\n\n {% assign matched_metafields = array %}\n\n {% if copy_all_metafields %}\n {% assign matched_metafields = draft_order_metafields %}\n\n {% else %}\n {% for metafield_to_copy in metafields_to_copy %}\n {% assign metafield_namespace = metafield_to_copy | split: \".\" | first %}\n {% assign metafield_key = metafield_to_copy | split: \".\" | last %}\n {% assign matched_metafield\n = draft_order_metafields\n | where: \"namespace\", metafield_namespace\n | where: \"key\", metafield_key\n | first\n %}\n\n {% if matched_metafield %}\n {% assign matched_metafields = matched_metafields | push: matched_metafield %}\n {% endif %}\n {% endfor %}\n {% endif %}\n\n {% comment %}\n -- add order ID as the owner on each matched metafield\n {% endcomment %}\n\n {% assign metafields_to_set = array %}\n\n {% for matched_metafield in matched_metafields %}\n {% assign metafield_to_set = matched_metafield %}\n {% assign metafield_to_set[\"ownerId\"] = order.admin_graphql_api_id %}\n {% assign metafields_to_set = metafields_to_set | push: metafield_to_set %}\n\n {% else %}\n {% log \"The source draft order either has no metafields or none of the ones configured in this task.\" %}\n {% break %}\n {% endfor %}\n\n {% comment %}\n -- set the matched metafields on the order\n -- metafieldsSet mutation only allows 25 metafields to be set at a time (as of June 2023)\n {% endcomment %}\n\n {% assign groups_of_metafields_to_set = metafields_to_set | in_groups_of: 25, fill_with: false %}\n\n {% for group_of_metafields_to_set in groups_of_metafields_to_set %}\n {% action \"shopify\" %}\n mutation {\n metafieldsSet(\n metafields: {{ group_of_metafields_to_set | graphql_arguments }}\n ) {\n metafields {\n namespace\n key\n type\n value\n }\n userErrors {\n code\n field\n message\n }\n }\n }\n {% endaction %}\n {% endfor %}\n{% endif %}",
"subscriptions": [
"shopify/orders/create",
"mechanic/user/order"
],
"subscriptions_template": "shopify/orders/create\nmechanic/user/order",
"tags": [
"Draft Orders",
"Metafields",
"Orders"
]
}