Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new task: auto-approve retrun requests #363

Merged
merged 1 commit into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This directory is built automatically. Each task's documentation is generated fr
* [Auto-add phone numbers to unfulfilled orders, when the customer is updated](./auto-add-phone-numbers-to-unfulfilled-orders-when-the-customer-is-updated)
* [Auto-add products to a custom collection when tagged](./auto-add-products-to-a-custom-collection-when-tagged)
* [Auto-add the draft order to a new order's attributes](./auto-add-the-draft-order-id-to-an-orders-attributes)
* [Auto-approve return requests](./auto-approve-return-requests)
* [Auto-archive orders after fulfillment](./auto-archive-orders-after-fulfillment)
* [Auto-associate products with a delivery profile, by product tag](./auto-associate-products-with-a-delivery-profile-by-product-tag)
* [Auto-associate variants with a delivery profile, by metafield value](./auto-associate-variants-with-a-delivery-profile-by-metafield-value)
Expand Down Expand Up @@ -1507,6 +1508,7 @@ This directory is built automatically. Each task's documentation is generated fr

### Returns

* [Auto-approve return requests](./auto-approve-return-requests)
* [Send email notification when items are returned](./send-email-notification-when-items-are-returned)

### Reviews
Expand Down
55 changes: 55 additions & 0 deletions docs/auto-approve-return-requests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Auto-approve return requests

Tags: Returns

Use this task to auto-approve return requests, typically made by customers using self-serve from their account. Choose to limit the auto-approval to orders with any of a set of tags, products with any of a set of tags, or specific product categories or types. Optionally, configure email recipients to be notified when any auto-approval occurs.

* View in the task library: [tasks.mechanic.dev/auto-approve-return-requests](https://tasks.mechanic.dev/auto-approve-return-requests)
* Task JSON, for direct import: [task.json](../../tasks/auto-approve-return-requests.json)
* Preview task code: [script.liquid](./script.liquid)

## Default options

```json
{
"limit_to_orders_with_any_of_these_tags__array": null,
"limit_to_products_with_any_of_these_tags__array": null,
"limit_to_these_product_categories_or_types__array": null,
"notification_email_recipients__array": null
}
```

[Learn about task options in Mechanic](https://learn.mechanic.dev/core/tasks/options)

## Subscriptions

```liquid
shopify/returns/request
mechanic/actions/perform
```

[Learn about event subscriptions in Mechanic](https://learn.mechanic.dev/core/tasks/subscriptions)

## Documentation

Use this task to auto-approve return requests, typically made by customers using self-serve from their account. Choose to limit the auto-approval to orders with any of a set of tags, products with any of a set of tags, or specific product categories or types. Optionally, configure email recipients to be notified when any auto-approval occurs.

More info on Shopify self-serve returns [here](https://help.shopify.com/en/manual/orders/refunds-returns/self-serve-returns).

**Important:**
- Adding multiple limit conditions means the return request must meet ALL of the conditions in order to be auto-approved.
- More specifically, if any product conditions are configured, then ALL products on the return must meet those conditions.
- Return requests that are auto-approved **cannot** later be used to exchange items.
- Approval of return requests **cannot** be reverted; instead, the return request may be cancelled if needed.

## Installing this task

Find this task [in the library at tasks.mechanic.dev](https://tasks.mechanic.dev/auto-approve-return-requests), and use the "Try this task" button. Or, import [this task's JSON export](../../tasks/auto-approve-return-requests.json) – see [Importing and exporting tasks](https://learn.mechanic.dev/core/tasks/import-and-export) to learn how imports work.

## Contributions

Found a bug? Got an improvement to add? Start here: [../../CONTRIBUTING.md](../../CONTRIBUTING.md).

## Task requests

Submit your [task requests](https://mechanic.canny.io/task-requests) for consideration by the Mechanic community, and they may be chosen for development and inclusion in the [task library](https://tasks.mechanic.dev/)!
232 changes: 232 additions & 0 deletions docs/auto-approve-return-requests/script.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
{% assign limit_order_tags = options.limit_to_orders_with_any_of_these_tags__array %}
{% assign limit_product_tags = options.limit_to_products_with_any_of_these_tags__array %}
{% assign limit_product_categories_or_types = options.limit_to_these_product_categories_or_types__array %}
{% assign notification_email_recipients = options.notification_email_recipients__array %}

{% if event.topic == "shopify/returns/request" %}
{% comment %}
-- get additional return and product data not available in the webhook
{% endcomment %}

{% capture query %}
query {
return(id: {{ return.admin_graphql_api_id | json }}) {
id
name
status
order {
name
tags
}
returnLineItems(first: 100) {
nodes {
fulfillmentLineItem {
lineItem {
product {
category {
name
}
productType
tags
}
}
}
}
}
}
}
{% endcapture %}

{% assign result = query | shopify %}

{% if event.preview %}
{% capture result_json %}
{
"data": {
"return": {
"id": "gid://shopify/Return/1234567890",
"name": "#PREVIEW-R1",
"status": "REQUESTED",
"order": {
"name": "#PREVIEW",
"tags": {{ limit_order_tags.first | json }}
},
"returnLineItems": {
"nodes": [
{
"fulfillmentLineItem": {
"lineItem": {
"product": {
"category": {
"name": {{ limit_product_categories_or_types.first | json }}
},
"productType": {{ limit_product_categories_or_types.first | json }},
"tags": {{ limit_product_tags.first | json }}
}
}
}
}
]
}
}
}
}
{% endcapture %}

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

{% assign return = result.data.return %}
{% assign order = return.order %}
{% assign return_products
= return.returnLineItems.nodes
| map: "fulfillmentLineItem"
| map: "lineItem"
| map: "product"
%}

{% if return.status != "REQUESTED" %}
{% log "This return request does not have a status of 'REQUESTED' and likely has already been acted on; skipping." %}
{% break %}
{% endif %}

{% comment %}
-- assume the return request will be approved unless it doesn't meet any configured tag, category, or type limits
{% endcomment %}

{% assign return_qualifies = true %}

{% if limit_order_tags != blank %}
{% comment %}
-- make sure the order has one of the configured tags
{% endcomment %}

{% assign has_qualifying_order_tag = nil %}

{% for limit_order_tag in limit_order_tags %}
{% if order.tags contains limit_order_tag %}
{% assign has_qualifying_order_tag = true %}
{% break %}
{% endif %}
{% endfor %}

{% unless has_qualifying_order_tag %}
{% assign return_qualifies = false %}
{% endunless %}
{% endif %}

{% if limit_product_tags != blank %}
{% comment %}
-- make sure each returned product has one of the configured tags
{% endcomment %}

{% assign all_products_qualify = true %}

{% for product in return_products %}
{% assign product_qualifies = nil %}

{% for limit_product_tag in limit_product_tags %}
{% if product.tags contains limit_product_tag %}
{% assign product_qualifies = true %}
{% break %}
{% endif %}
{% endfor %}

{% unless product_qualifies %}
{% assign all_products_qualify = false %}
{% break %}
{% endunless %}
{% endfor %}

{% unless all_products_qualify %}
{% assign return_qualifies = false %}
{% endunless %}
{% endif %}

{% if limit_product_categories_or_types != blank %}
{% comment %}
-- make sure each returned product is one of the configured categories or types
{% endcomment %}

{% assign all_products_qualify = true %}

{% for product in return_products %}
{% assign product_qualifies = nil %}

{% for limit_product_category_or_type in limit_product_categories_or_types %}
{% if product.productType == limit_product_category_or_type or product.category.name == limit_product_category_or_type %}
{% assign product_qualifies = true %}
{% break %}
{% endif %}
{% endfor %}

{% unless product_qualifies %}
{% assign all_products_qualify = false %}
{% break %}
{% endunless %}
{% endfor %}

{% unless all_products_qualify %}
{% assign return_qualifies = false %}
{% endunless %}
{% endif %}

{% if return_qualifies %}
{% action "shopify" %}
mutation {
returnApproveRequest(input: {id: {{ return.id | json }}}) {
return {
id
name
status
order {
legacyResourceId
customer {
displayName
}
}
}
userErrors {
code
field
message
}
}
}
{% endaction %}
{% endif %}

{% elsif event.topic == "mechanic/actions/perform" %}
{% unless action.type == "shopify" and action.run.ok and notification_email_recipients != blank %}
{% break %}
{% endunless %}

{% comment %}
-- if any notification recipients are configured, send them an email when a return request is auto-approved
{% endcomment %}

{% assign return = action.run.result.data.returnApproveRequest.return %}

{%- capture email_subject -%}
Return request {{ return.name }} was auto-approved
{%- endcapture -%}

{%- capture email_body -%}
Return request {{ return.name }}, made by {{ return.order.customer.displayName }}, was auto-approved.

Review the return details and take further action on the <a href="{{ shop.admin_url }}orders/{{ return.order.legacyResourceId }}">order admin page</a>.

Thanks,
- Mechanic, for {{ shop.name }}
{%- endcapture -%}

{% action "email" %}
{
"to": {{ notification_email_recipients | json }},
"subject": {{ email_subject | json }},
"body": {{ email_body | newline_to_br | json }},
"reply_to": {{ shop.customer_email | json }},
"from_display_name": {{ shop.name | json }}
}
{% endaction %}
{% endif %}
Loading
Loading