From 7ab016d85a12e06bb294978a90fc001f6024793c Mon Sep 17 00:00:00 2001 From: Brad Hover Date: Mon, 2 Oct 2023 20:56:11 -0700 Subject: [PATCH 1/3] new task: send tax receipts for donations --- docs/README.md | 2 + .../send-tax-receipts-for-donations/README.md | 50 +++++++++++++++++ .../script.liquid | 53 +++++++++++++++++++ tasks/send-tax-receipts-for-donations.json | 21 ++++++++ 4 files changed, 126 insertions(+) create mode 100644 docs/send-tax-receipts-for-donations/README.md create mode 100644 docs/send-tax-receipts-for-donations/script.liquid create mode 100644 tasks/send-tax-receipts-for-donations.json diff --git a/docs/README.md b/docs/README.md index 02a40ed7..7e62b4f1 100644 --- a/docs/README.md +++ b/docs/README.md @@ -302,6 +302,7 @@ This directory is built automatically. Each task's documentation is generated fr * [Send follow-up emails after sending a draft order invoice](./send-follow-up-emails-after-sending-a-draft-order-invoice) * [Send new customer signups to IFTTT](./send-new-customer-signups-to-ifttt) * [Send recurring reminders about unpaid orders](./unpaid-order-reminders) +* [Send tax receipts for donations](./send-tax-receipts-for-donations) * [Send your customers reorder reminders](./send-your-customers-reorder-reminders) * [Set a default tracking number for new fulfillments](./set-a-default-tracking-number-for-new-fulfillments) * [Set product or variant metafields values in bulk](./set-product-or-variant-metafields-in-bulk) @@ -1680,6 +1681,7 @@ This directory is built automatically. Each task's documentation is generated fr ### Uncategorized * [Mechanic tour task](./mechanic-tour-task) +* [Send tax receipts for donations](./send-tax-receipts-for-donations) ### Unpaid diff --git a/docs/send-tax-receipts-for-donations/README.md b/docs/send-tax-receipts-for-donations/README.md new file mode 100644 index 00000000..e81154a1 --- /dev/null +++ b/docs/send-tax-receipts-for-donations/README.md @@ -0,0 +1,50 @@ +# Send tax receipts for donations + +Tags: (not tagged!) + +[to be updated] + +* View in the task library: [tasks.mechanic.dev/send-tax-receipts-for-donations](https://tasks.mechanic.dev/send-tax-receipts-for-donations) +* Task JSON, for direct import: [task.json](../../tasks/send-tax-receipts-for-donations.json) +* Preview task code: [script.liquid](./script.liquid) + +## Default options + +```json +{ + "tax_id__required": "123-ABC", + "only_include_orders_with_any_of_these_tags__array": null, + "send_cc_email_to_shop__boolean": true, + "email_subject__required": "Receipt {{ order.name }} for donation to {{ shop.name }}", + "email_body__multiline_required": "Thank you for your recent donation!\n\nAttached you will find your official donation receipt.", + "donation_receipt_filename__required": "{{ shop.name | handleize }}-donation-receipt-{{ order.name }}.pdf", + "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law
\n
\n Thank you\n

\n
\n
\n\n" +} +``` + +[Learn about task options in Mechanic](https://learn.mechanic.dev/core/tasks/options) + +## Subscriptions + +```liquid +shopify/orders/paid +mechanic/user/order +``` + +[Learn about event subscriptions in Mechanic](https://learn.mechanic.dev/core/tasks/subscriptions) + +## Documentation + +[to be updated] + +## Installing this task + +Find this task [in the library at tasks.mechanic.dev](https://tasks.mechanic.dev/send-tax-receipts-for-donations), and use the "Try this task" button. Or, import [this task's JSON export](../../tasks/send-tax-receipts-for-donations.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/)! diff --git a/docs/send-tax-receipts-for-donations/script.liquid b/docs/send-tax-receipts-for-donations/script.liquid new file mode 100644 index 00000000..67c0253d --- /dev/null +++ b/docs/send-tax-receipts-for-donations/script.liquid @@ -0,0 +1,53 @@ +{% assign tax_id = options.tax_id__required %} +{% assign order_inclusion_tags = options.only_include_orders_with_any_of_these_tags__array %} +{% assign cc_shop = options.send_cc_email_to_shop__boolean %} +{% assign email_subject = options.email_subject__required %} +{% assign email_body = options.email_body__multiline_required %} +{% assign donation_receipt_filename = options.donation_receipt_filename__required %} +{% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %} + +{% if event.topic == "shopify/orders/paid" or event.topic == "mechanic/user/order" %} + {% comment %} + -- NOTE: if this order was sent directly via an admin link, then neither the "paid" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends) + {% endcomment %} + + {% if order.email == blank %} + {% log "This order does not have an email associated with it." %} + {% break %} + {% endif %} + + {% if order_inclusion_tags != blank %} + {% assign has_inclusion_tag = nil %} + {% assign order_tags = order.tags | split: ", " %} + + {% for order_tag in order_tags %} + {% if order_inclusion_tags contains order_tag %} + {% assign has_inclusion_tag = true %} + {% break %} + {% endif %} + {% endfor %} + + {% unless has_inclusion_tag or event.preview %} + {% break %} + {% endunless %} + {% endif %} + + {% action "email" %} + { + "to": {{ order.email | json }}, + "subject": {{ email_subject | json }}, + "body": {{ email_body | newline_to_br | json }}, + {% if cc_shop %}"cc": {{ shop.customer_email | json }},{% endif %} + "reply_to": {{ shop.customer_email | json }}, + "from_display_name": {{ shop.name | json }}, + "attachments": { + {{ donation_receipt_filename | remove: "#" | json }}: { + "pdf": { + "html": {{ donation_reciept_html_template | replace: "[TAX_ID]", tax_id | json }}, + "__force_pdfcrowd": true + } + } + } + } + {% endaction %} +{% endif %} diff --git a/tasks/send-tax-receipts-for-donations.json b/tasks/send-tax-receipts-for-donations.json new file mode 100644 index 00000000..ae71e234 --- /dev/null +++ b/tasks/send-tax-receipts-for-donations.json @@ -0,0 +1,21 @@ +{ + "docs": "[to be updated]", + "halt_action_run_sequence_on_error": false, + "name": "Send tax receipts for donations", + "online_store_javascript": null, + "options": { + "tax_id__required": "123-ABC", + "only_include_orders_with_any_of_these_tags__array": null, + "send_cc_email_to_shop__boolean": true, + "email_subject__required": "Receipt {{ order.name }} for donation to {{ shop.name }}", + "email_body__multiline_required": "Thank you for your recent donation!\n\nAttached you will find your official donation receipt.", + "donation_receipt_filename__required": "{{ shop.name | handleize }}-donation-receipt-{{ order.name }}.pdf", + "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law
\n
\n Thank you\n

\n
\n
\n\n" + }, + "order_status_javascript": null, + "perform_action_runs_in_sequence": false, + "preview_event_definitions": [], + "script": "{% assign tax_id = options.tax_id__required %}\n{% assign order_inclusion_tags = options.only_include_orders_with_any_of_these_tags__array %}\n{% assign cc_shop = options.send_cc_email_to_shop__boolean %}\n{% assign email_subject = options.email_subject__required %}\n{% assign email_body = options.email_body__multiline_required %}\n{% assign donation_receipt_filename = options.donation_receipt_filename__required %}\n{% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %}\n\n{% if event.topic == \"shopify/orders/paid\" or event.topic == \"mechanic/user/order\" %}\n {% comment %}\n -- NOTE: if this order was sent directly via an admin link, then neither the \"paid\" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends)\n {% endcomment %}\n\n {% if order.email == blank %}\n {% log \"This order does not have an email associated with it.\" %}\n {% break %}\n {% endif %}\n\n {% if order_inclusion_tags != blank %}\n {% assign has_inclusion_tag = nil %}\n {% assign order_tags = order.tags | split: \", \" %}\n\n {% for order_tag in order_tags %}\n {% if order_inclusion_tags contains order_tag %}\n {% assign has_inclusion_tag = true %}\n {% break %}\n {% endif %}\n {% endfor %}\n\n {% unless has_inclusion_tag or event.preview %}\n {% break %}\n {% endunless %}\n {% endif %}\n\n {% action \"email\" %}\n {\n \"to\": {{ order.email | json }},\n \"subject\": {{ email_subject | json }},\n \"body\": {{ email_body | newline_to_br | json }},\n {% if cc_shop %}\"cc\": {{ shop.customer_email | json }},{% endif %}\n \"reply_to\": {{ shop.customer_email | json }},\n \"from_display_name\": {{ shop.name | json }},\n \"attachments\": {\n {{ donation_receipt_filename | remove: \"#\" | json }}: {\n \"pdf\": {\n \"html\": {{ donation_reciept_html_template | replace: \"[TAX_ID]\", tax_id | json }},\n \"__force_pdfcrowd\": true\n }\n }\n }\n }\n {% endaction %}\n{% endif %}", + "subscriptions": ["shopify/orders/paid", "mechanic/user/order"], + "subscriptions_template": "shopify/orders/paid\nmechanic/user/order" +} From 0e820bc1b60dec1424c8c0d40e4f7ccd81a876ec Mon Sep 17 00:00:00 2001 From: Brad Hover Date: Tue, 3 Oct 2023 10:31:44 -0700 Subject: [PATCH 2/3] add docs and tags --- docs/README.md | 8 +++++++- docs/send-tax-receipts-for-donations/README.md | 16 ++++++++++------ .../script.liquid | 14 +++++++++----- lib/task_schema.json | 1 + tasks/send-tax-receipts-for-donations.json | 13 +++++++------ 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/docs/README.md b/docs/README.md index 7e62b4f1..f1ab466d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1221,6 +1221,7 @@ This directory is built automatically. Each task's documentation is generated fr * [Send email when an order comes in](./send-email-when-an-order-comes-in) * [Send email when an order is tagged](./send-email-when-an-order-is-tagged) * [Send recurring reminders about unpaid orders](./unpaid-order-reminders) +* [Send tax receipts for donations](./send-tax-receipts-for-donations) * [Sync an inverse order tag](./sync-an-inverse-order-tag) * [Sync order timeline comments to the customer note](./sync-order-timeline-comments-to-the-customer-note) * [Tag online orders by ?ls= Locksmith secret link used](./tag-orders-by-locksmith-secret-link) @@ -1251,6 +1252,7 @@ This directory is built automatically. Each task's documentation is generated fr * [Report Toaster: Deliver report PDF via email or Slack](./report-toaster-deliver-report-pdf-via-email-or-slack) * [Send a PDF invoice when an order is created](./send-a-pdf-invoice-when-an-order-is-created) * [Send a PDF when an order is sent to Mechanic](./send-a-pdf-when-an-order-is-sent-to-mechanic) +* [Send tax receipts for donations](./send-tax-receipts-for-donations) ### Payment @@ -1392,6 +1394,10 @@ This directory is built automatically. Each task's documentation is generated fr * [Publish back-in-stock products](./publish-back-in-stock-products) * [Scheduled theme publishing](./scheduled-theme-publishing) +### Receipts + +* [Send tax receipts for donations](./send-tax-receipts-for-donations) + ### Recurring * [Auto-recurring draft orders](./auto-recurring-draft-orders) @@ -1644,6 +1650,7 @@ This directory is built automatically. Each task's documentation is generated fr ### Tax +* [Send tax receipts for donations](./send-tax-receipts-for-donations) * [Temporarily enable tax-exempt status when a customer is tagged](./temporarily-enable-tax-exempt-status-when-a-customer-is-tagged) ### Template @@ -1681,7 +1688,6 @@ This directory is built automatically. Each task's documentation is generated fr ### Uncategorized * [Mechanic tour task](./mechanic-tour-task) -* [Send tax receipts for donations](./send-tax-receipts-for-donations) ### Unpaid diff --git a/docs/send-tax-receipts-for-donations/README.md b/docs/send-tax-receipts-for-donations/README.md index e81154a1..e3cb4a7a 100644 --- a/docs/send-tax-receipts-for-donations/README.md +++ b/docs/send-tax-receipts-for-donations/README.md @@ -1,8 +1,8 @@ # Send tax receipts for donations -Tags: (not tagged!) +Tags: Orders, PDF, Receipts, Tax -[to be updated] +Use this task to send donation receipts to customers (i.e. donors) as PDF attachments on new, paid orders (i.e. donations). If desired, orders may be filtered by tag to support non-donation orders in the same shop. Optionally, the task can cc the donation receipt to the configured shop email. * View in the task library: [tasks.mechanic.dev/send-tax-receipts-for-donations](https://tasks.mechanic.dev/send-tax-receipts-for-donations) * Task JSON, for direct import: [task.json](../../tasks/send-tax-receipts-for-donations.json) @@ -12,13 +12,13 @@ Tags: (not tagged!) ```json { - "tax_id__required": "123-ABC", + "tax_id__required": null, "only_include_orders_with_any_of_these_tags__array": null, - "send_cc_email_to_shop__boolean": true, + "send_cc_email_to_shop__boolean": false, "email_subject__required": "Receipt {{ order.name }} for donation to {{ shop.name }}", "email_body__multiline_required": "Thank you for your recent donation!\n\nAttached you will find your official donation receipt.", "donation_receipt_filename__required": "{{ shop.name | handleize }}-donation-receipt-{{ order.name }}.pdf", - "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law
\n
\n Thank you\n

\n
\n
\n\n" + "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law.
\n
\n Thank you\n

\n
\n
\n\n" } ``` @@ -35,7 +35,11 @@ mechanic/user/order ## Documentation -[to be updated] +Use this task to send donation receipts to customers (i.e. donors) as PDF attachments on new, paid orders (i.e. donations). If desired, orders may be filtered by tag to support non-donation orders in the same shop. Optionally, the task can cc the donation receipt to the configured shop email. + +This task can also receive orders sent directly via [admin action links](https://learn.mechanic.dev/core/shopify/admin-action-links#link-usage). When doing so, the task will **not** check that the order is paid or has any of the inclusion tags. This is to allow flexibility when sending donation receipts manually. + +The task comes with a sample email subject, email body, donation receipt filename, and donation receipt HTML template. The HTML template is used by the PDF file generator, so care must be taken to provide valid HTML if this field is customized. ## Installing this task diff --git a/docs/send-tax-receipts-for-donations/script.liquid b/docs/send-tax-receipts-for-donations/script.liquid index 67c0253d..df54d2fb 100644 --- a/docs/send-tax-receipts-for-donations/script.liquid +++ b/docs/send-tax-receipts-for-donations/script.liquid @@ -7,16 +7,16 @@ {% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %} {% if event.topic == "shopify/orders/paid" or event.topic == "mechanic/user/order" %} - {% comment %} - -- NOTE: if this order was sent directly via an admin link, then neither the "paid" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends) - {% endcomment %} - {% if order.email == blank %} {% log "This order does not have an email associated with it." %} {% break %} {% endif %} - {% if order_inclusion_tags != blank %} + {% comment %} + -- NOTE: if this order was sent directly via an admin link, then neither the "paid" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends) + {% endcomment %} + + {% if event.topic == "shopify/orders/paid" and order_inclusion_tags != blank %} {% assign has_inclusion_tag = nil %} {% assign order_tags = order.tags | split: ", " %} @@ -32,6 +32,10 @@ {% endunless %} {% endif %} + {% comment %} + -- generate tax receipt as a PDF and attach to email to donor; optionally cc the shop email address + {% endcomment %} + {% action "email" %} { "to": {{ order.email | json }}, diff --git a/lib/task_schema.json b/lib/task_schema.json index c30ede3a..b6b9e155 100644 --- a/lib/task_schema.json +++ b/lib/task_schema.json @@ -88,6 +88,7 @@ "Price", "Products", "Publish", + "Receipts", "Recurring", "Redirects", "Referral", diff --git a/tasks/send-tax-receipts-for-donations.json b/tasks/send-tax-receipts-for-donations.json index ae71e234..64a76d44 100644 --- a/tasks/send-tax-receipts-for-donations.json +++ b/tasks/send-tax-receipts-for-donations.json @@ -1,21 +1,22 @@ { - "docs": "[to be updated]", + "docs": "Use this task to send donation receipts to customers (i.e. donors) as PDF attachments on new, paid orders (i.e. donations). If desired, orders may be filtered by tag to support non-donation orders in the same shop. Optionally, the task can cc the donation receipt to the configured shop email.\n\nThis task can also receive orders sent directly via [admin action links](https://learn.mechanic.dev/core/shopify/admin-action-links#link-usage). When doing so, the task will **not** check that the order is paid or has any of the inclusion tags. This is to allow flexibility when sending donation receipts manually.\n\nThe task comes with a sample email subject, email body, donation receipt filename, and donation receipt HTML template. The HTML template is used by the PDF file generator, so care must be taken to provide valid HTML if this field is customized.", "halt_action_run_sequence_on_error": false, "name": "Send tax receipts for donations", "online_store_javascript": null, "options": { - "tax_id__required": "123-ABC", + "tax_id__required": null, "only_include_orders_with_any_of_these_tags__array": null, - "send_cc_email_to_shop__boolean": true, + "send_cc_email_to_shop__boolean": false, "email_subject__required": "Receipt {{ order.name }} for donation to {{ shop.name }}", "email_body__multiline_required": "Thank you for your recent donation!\n\nAttached you will find your official donation receipt.", "donation_receipt_filename__required": "{{ shop.name | handleize }}-donation-receipt-{{ order.name }}.pdf", - "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law
\n
\n Thank you\n

\n
\n
\n\n" + "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law.
\n
\n Thank you\n

\n
\n
\n\n" }, "order_status_javascript": null, "perform_action_runs_in_sequence": false, "preview_event_definitions": [], - "script": "{% assign tax_id = options.tax_id__required %}\n{% assign order_inclusion_tags = options.only_include_orders_with_any_of_these_tags__array %}\n{% assign cc_shop = options.send_cc_email_to_shop__boolean %}\n{% assign email_subject = options.email_subject__required %}\n{% assign email_body = options.email_body__multiline_required %}\n{% assign donation_receipt_filename = options.donation_receipt_filename__required %}\n{% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %}\n\n{% if event.topic == \"shopify/orders/paid\" or event.topic == \"mechanic/user/order\" %}\n {% comment %}\n -- NOTE: if this order was sent directly via an admin link, then neither the \"paid\" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends)\n {% endcomment %}\n\n {% if order.email == blank %}\n {% log \"This order does not have an email associated with it.\" %}\n {% break %}\n {% endif %}\n\n {% if order_inclusion_tags != blank %}\n {% assign has_inclusion_tag = nil %}\n {% assign order_tags = order.tags | split: \", \" %}\n\n {% for order_tag in order_tags %}\n {% if order_inclusion_tags contains order_tag %}\n {% assign has_inclusion_tag = true %}\n {% break %}\n {% endif %}\n {% endfor %}\n\n {% unless has_inclusion_tag or event.preview %}\n {% break %}\n {% endunless %}\n {% endif %}\n\n {% action \"email\" %}\n {\n \"to\": {{ order.email | json }},\n \"subject\": {{ email_subject | json }},\n \"body\": {{ email_body | newline_to_br | json }},\n {% if cc_shop %}\"cc\": {{ shop.customer_email | json }},{% endif %}\n \"reply_to\": {{ shop.customer_email | json }},\n \"from_display_name\": {{ shop.name | json }},\n \"attachments\": {\n {{ donation_receipt_filename | remove: \"#\" | json }}: {\n \"pdf\": {\n \"html\": {{ donation_reciept_html_template | replace: \"[TAX_ID]\", tax_id | json }},\n \"__force_pdfcrowd\": true\n }\n }\n }\n }\n {% endaction %}\n{% endif %}", + "script": "{% assign tax_id = options.tax_id__required %}\n{% assign order_inclusion_tags = options.only_include_orders_with_any_of_these_tags__array %}\n{% assign cc_shop = options.send_cc_email_to_shop__boolean %}\n{% assign email_subject = options.email_subject__required %}\n{% assign email_body = options.email_body__multiline_required %}\n{% assign donation_receipt_filename = options.donation_receipt_filename__required %}\n{% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %}\n\n{% if event.topic == \"shopify/orders/paid\" or event.topic == \"mechanic/user/order\" %}\n {% if order.email == blank %}\n {% log \"This order does not have an email associated with it.\" %}\n {% break %}\n {% endif %}\n\n {% comment %}\n -- NOTE: if this order was sent directly via an admin link, then neither the \"paid\" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends)\n {% endcomment %}\n\n {% if event.topic == \"shopify/orders/paid\" and order_inclusion_tags != blank %}\n {% assign has_inclusion_tag = nil %}\n {% assign order_tags = order.tags | split: \", \" %}\n\n {% for order_tag in order_tags %}\n {% if order_inclusion_tags contains order_tag %}\n {% assign has_inclusion_tag = true %}\n {% break %}\n {% endif %}\n {% endfor %}\n\n {% unless has_inclusion_tag or event.preview %}\n {% break %}\n {% endunless %}\n {% endif %}\n\n {% comment %}\n -- generate tax receipt as a PDF and attach to email to donor; optionally cc the shop email address\n {% endcomment %}\n\n {% action \"email\" %}\n {\n \"to\": {{ order.email | json }},\n \"subject\": {{ email_subject | json }},\n \"body\": {{ email_body | newline_to_br | json }},\n {% if cc_shop %}\"cc\": {{ shop.customer_email | json }},{% endif %}\n \"reply_to\": {{ shop.customer_email | json }},\n \"from_display_name\": {{ shop.name | json }},\n \"attachments\": {\n {{ donation_receipt_filename | remove: \"#\" | json }}: {\n \"pdf\": {\n \"html\": {{ donation_reciept_html_template | replace: \"[TAX_ID]\", tax_id | json }},\n \"__force_pdfcrowd\": true\n }\n }\n }\n }\n {% endaction %}\n{% endif %}\n", "subscriptions": ["shopify/orders/paid", "mechanic/user/order"], - "subscriptions_template": "shopify/orders/paid\nmechanic/user/order" + "subscriptions_template": "shopify/orders/paid\nmechanic/user/order", + "tags": ["Orders", "PDF", "Receipts", "Tax"] } From f2b39fd2bbc2e2e7ba7580929248d6584016fb77 Mon Sep 17 00:00:00 2001 From: Brad Hover Date: Tue, 10 Oct 2023 12:44:24 -0700 Subject: [PATCH 3/3] switch to product tags and GraphQL order query --- .../send-tax-receipts-for-donations/README.md | 20 ++-- .../script.liquid | 101 +++++++++++++++--- tasks/send-tax-receipts-for-donations.json | 12 ++- 3 files changed, 106 insertions(+), 27 deletions(-) diff --git a/docs/send-tax-receipts-for-donations/README.md b/docs/send-tax-receipts-for-donations/README.md index e3cb4a7a..dd6d3c68 100644 --- a/docs/send-tax-receipts-for-donations/README.md +++ b/docs/send-tax-receipts-for-donations/README.md @@ -2,7 +2,7 @@ Tags: Orders, PDF, Receipts, Tax -Use this task to send donation receipts to customers (i.e. donors) as PDF attachments on new, paid orders (i.e. donations). If desired, orders may be filtered by tag to support non-donation orders in the same shop. Optionally, the task can cc the donation receipt to the configured shop email. +Use this task to email donation receipts to donors as PDF attachments, with an option to cc the shop email. It runs on new, paid orders, and it will sum the donation amount from all line items that have a configured product donation tag. * View in the task library: [tasks.mechanic.dev/send-tax-receipts-for-donations](https://tasks.mechanic.dev/send-tax-receipts-for-donations) * Task JSON, for direct import: [task.json](../../tasks/send-tax-receipts-for-donations.json) @@ -13,12 +13,14 @@ Use this task to send donation receipts to customers (i.e. donors) as PDF attach ```json { "tax_id__required": null, - "only_include_orders_with_any_of_these_tags__array": null, - "send_cc_email_to_shop__boolean": false, + "identify_donation_products_with_any_of_these_tags__array_required": [ + "donation" + ], + "send_cc_to_shop_email__boolean": false, "email_subject__required": "Receipt {{ order.name }} for donation to {{ shop.name }}", "email_body__multiline_required": "Thank you for your recent donation!\n\nAttached you will find your official donation receipt.", "donation_receipt_filename__required": "{{ shop.name | handleize }}-donation-receipt-{{ order.name }}.pdf", - "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law.
\n
\n Thank you\n

\n
\n
\n\n" + "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: [DONATION_AMOUNT]
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law.
\n
\n Thank you\n

\n
\n
\n\n" } ``` @@ -35,11 +37,15 @@ mechanic/user/order ## Documentation -Use this task to send donation receipts to customers (i.e. donors) as PDF attachments on new, paid orders (i.e. donations). If desired, orders may be filtered by tag to support non-donation orders in the same shop. Optionally, the task can cc the donation receipt to the configured shop email. +Use this task to email donation receipts to donors as PDF attachments, with an option to cc the shop email. It runs on new, paid orders, and it will sum the donation amount from all line items that have a configured product donation tag. -This task can also receive orders sent directly via [admin action links](https://learn.mechanic.dev/core/shopify/admin-action-links#link-usage). When doing so, the task will **not** check that the order is paid or has any of the inclusion tags. This is to allow flexibility when sending donation receipts manually. +This task can also receive orders sent directly via [admin action links](https://learn.mechanic.dev/core/shopify/admin-action-links#link-usage). When doing so, the task will **not** check that the order is paid to allow for flexibility when sending donation receipts manually. -The task comes with a sample email subject, email body, donation receipt filename, and donation receipt HTML template. The HTML template is used by the PDF file generator, so care must be taken to provide valid HTML if this field is customized. +**Notes:** + +- The task comes with a sample donation tag, email subject, email body, donation receipt filename, and donation receipt HTML template. The HTML template is used by the PDF file generator, so care must be taken to provide valid HTML if this field is customized. +- The *[TAX_ID]* and *[DONATION_AMOUNT]* variables need to be present in the HTML template in order for those values to be included in the PDF donation receipt. +- Orders with no donation products will be ignored. ## Installing this task diff --git a/docs/send-tax-receipts-for-donations/script.liquid b/docs/send-tax-receipts-for-donations/script.liquid index df54d2fb..35185425 100644 --- a/docs/send-tax-receipts-for-donations/script.liquid +++ b/docs/send-tax-receipts-for-donations/script.liquid @@ -1,36 +1,107 @@ {% assign tax_id = options.tax_id__required %} -{% assign order_inclusion_tags = options.only_include_orders_with_any_of_these_tags__array %} -{% assign cc_shop = options.send_cc_email_to_shop__boolean %} +{% assign donation_product_tags = options.identify_donation_products_with_any_of_these_tags__array_required %} +{% assign send_cc_to_shop_email = options.send_cc_to_shop_email__boolean %} {% assign email_subject = options.email_subject__required %} {% assign email_body = options.email_body__multiline_required %} {% assign donation_receipt_filename = options.donation_receipt_filename__required %} {% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %} {% if event.topic == "shopify/orders/paid" or event.topic == "mechanic/user/order" %} + {% comment %} + -- NOTE: if this order was sent directly via an admin link, then the "paid" financial status will not be checked to allow for flexibility on manual sends + {% endcomment %} + {% if order.email == blank %} {% log "This order does not have an email associated with it." %} {% break %} {% endif %} {% comment %} - -- NOTE: if this order was sent directly via an admin link, then neither the "paid" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends) + -- get the order data to see if there are any donation products on this order, by product tag {% endcomment %} - {% if event.topic == "shopify/orders/paid" and order_inclusion_tags != blank %} - {% assign has_inclusion_tag = nil %} - {% assign order_tags = order.tags | split: ", " %} + {% capture query %} + query { + order(id: {{ order.admin_graphql_api_id | json }}) { + id + presentmentCurrencyCode + lineItems(first: 100) { + nodes { + product { + tags + } + originalTotalSet { + presentmentMoney { + amount + } + } + } + } + } + } + {% endcapture %} - {% for order_tag in order_tags %} - {% if order_inclusion_tags contains order_tag %} - {% assign has_inclusion_tag = true %} + {% assign result = query | shopify %} + + {% if event.preview %} + {% capture result_json %} + { + "data": { + "order": { + "presentmentCurrencyCode": "USD", + "lineItems": { + "nodes": [ + { + "product": { + "tags": {{ donation_product_tags.first | json }} + }, + "originalTotalSet": { + "presentmentMoney": { + "amount": "100.0" + } + } + } + ] + } + } + } + } + {% endcapture %} + + {% assign result = result_json | parse_json %} + {% endif %} + + {% comment %} + -- for any donation products, add the non-discounted total for that line item to the runnning donation amount + {% endcomment %} + + {% assign donation_amount = 0 %} + + {% for line_item in result.data.order.lineItems.nodes %} + {% for donation_product_tag in donation_product_tags %} + {% if line_item.product.tags contains donation_product_tag %} + {% assign donation_amount = donation_amount | plus: line_item.originalTotalSet.presentmentMoney.amount %} {% break %} {% endif %} {% endfor %} + {% endfor %} - {% unless has_inclusion_tag or event.preview %} - {% break %} - {% endunless %} - {% endif %} + {% unless donation_amount > 0 %} + {% log "This order has no donation products on it; skipping" %} + {% break %} + {% endunless %} + + {% assign donation_with_currency = donation_amount | currency: result.data.order.presentmentCurrencyCode %} + + {% comment %} + -- replace variables in the HTML template for the configured tax ID and the calculated donation amount + {% endcomment %} + + {% assign donation_html + = donation_reciept_html_template + | replace: "[TAX_ID]", tax_id + | replace: "[DONATION_AMOUNT]", donation_with_currency + %} {% comment %} -- generate tax receipt as a PDF and attach to email to donor; optionally cc the shop email address @@ -41,13 +112,13 @@ "to": {{ order.email | json }}, "subject": {{ email_subject | json }}, "body": {{ email_body | newline_to_br | json }}, - {% if cc_shop %}"cc": {{ shop.customer_email | json }},{% endif %} + {% if send_cc_to_shop_email %}"cc": {{ shop.customer_email | json }},{% endif %} "reply_to": {{ shop.customer_email | json }}, "from_display_name": {{ shop.name | json }}, "attachments": { {{ donation_receipt_filename | remove: "#" | json }}: { "pdf": { - "html": {{ donation_reciept_html_template | replace: "[TAX_ID]", tax_id | json }}, + "html": {{ donation_html | json }}, "__force_pdfcrowd": true } } diff --git a/tasks/send-tax-receipts-for-donations.json b/tasks/send-tax-receipts-for-donations.json index 64a76d44..b3cafe04 100644 --- a/tasks/send-tax-receipts-for-donations.json +++ b/tasks/send-tax-receipts-for-donations.json @@ -1,21 +1,23 @@ { - "docs": "Use this task to send donation receipts to customers (i.e. donors) as PDF attachments on new, paid orders (i.e. donations). If desired, orders may be filtered by tag to support non-donation orders in the same shop. Optionally, the task can cc the donation receipt to the configured shop email.\n\nThis task can also receive orders sent directly via [admin action links](https://learn.mechanic.dev/core/shopify/admin-action-links#link-usage). When doing so, the task will **not** check that the order is paid or has any of the inclusion tags. This is to allow flexibility when sending donation receipts manually.\n\nThe task comes with a sample email subject, email body, donation receipt filename, and donation receipt HTML template. The HTML template is used by the PDF file generator, so care must be taken to provide valid HTML if this field is customized.", + "docs": "Use this task to email donation receipts to donors as PDF attachments, with an option to cc the shop email. It runs on new, paid orders, and it will sum the donation amount from all line items that have a configured product donation tag.\n\nThis task can also receive orders sent directly via [admin action links](https://learn.mechanic.dev/core/shopify/admin-action-links#link-usage). When doing so, the task will **not** check that the order is paid to allow for flexibility when sending donation receipts manually.\n\n**Notes:**\n\n- The task comes with a sample donation tag, email subject, email body, donation receipt filename, and donation receipt HTML template. The HTML template is used by the PDF file generator, so care must be taken to provide valid HTML if this field is customized.\n- The *[TAX_ID]* and *[DONATION_AMOUNT]* variables need to be present in the HTML template in order for those values to be included in the PDF donation receipt.\n- Orders with no donation products will be ignored.", "halt_action_run_sequence_on_error": false, "name": "Send tax receipts for donations", "online_store_javascript": null, "options": { "tax_id__required": null, - "only_include_orders_with_any_of_these_tags__array": null, - "send_cc_email_to_shop__boolean": false, + "identify_donation_products_with_any_of_these_tags__array_required": [ + "donation" + ], + "send_cc_to_shop_email__boolean": false, "email_subject__required": "Receipt {{ order.name }} for donation to {{ shop.name }}", "email_body__multiline_required": "Thank you for your recent donation!\n\nAttached you will find your official donation receipt.", "donation_receipt_filename__required": "{{ shop.name | handleize }}-donation-receipt-{{ order.name }}.pdf", - "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: {{ order.total_price | currency }}
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law.
\n
\n Thank you\n

\n
\n
\n\n" + "donation_reciept_html_template__code_multiline_required": "\n\n\n \n \n\n\n
\n
\n

\n {{ shop.name }}
\n {{ shop.address1 }}
{% if shop.address2 != blank -%}{{ shop.address2 }}
{%- endif %}\n {{ shop.city }}, {{ shop.province }} {{ shop.zip }}
\n {{ order.billing_address.country }}\n

\n

\n OFFICIAL DONATION RECEIPT
\n TAX ID #[TAX_ID]
\n

\n
\n
\n

\n Donor:
\n {{ order.billing_address.first_name }} {{ billing_address.last_name }}
\n {{ order.billing_address.address1 }}
{% if order.billing_address.address2 != blank -%}{{ order.billing_address.address2 }}
{%- endif %}\n {{ order.billing_address.city }}, {{ order.billing_address.province }} {{ order.billing_address.zip }}
\n {{ order.billing_address.country }}\n

\n

\n Donation Details:
\n Order Number: {{ order.name }}
\n Donation Received: {{ order.created_at | date: \"%F\" }}
\n Amount: [DONATION_AMOUNT]
\n Date Issued: {{ \"now\" | date: \"%F\" }}
\n Place Issued: {{ shop.province }}, {{ shop.country_name }}
\n
\n Donations are tax deductible to the extent permitted by law.
\n
\n Thank you\n

\n
\n
\n\n" }, "order_status_javascript": null, "perform_action_runs_in_sequence": false, "preview_event_definitions": [], - "script": "{% assign tax_id = options.tax_id__required %}\n{% assign order_inclusion_tags = options.only_include_orders_with_any_of_these_tags__array %}\n{% assign cc_shop = options.send_cc_email_to_shop__boolean %}\n{% assign email_subject = options.email_subject__required %}\n{% assign email_body = options.email_body__multiline_required %}\n{% assign donation_receipt_filename = options.donation_receipt_filename__required %}\n{% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %}\n\n{% if event.topic == \"shopify/orders/paid\" or event.topic == \"mechanic/user/order\" %}\n {% if order.email == blank %}\n {% log \"This order does not have an email associated with it.\" %}\n {% break %}\n {% endif %}\n\n {% comment %}\n -- NOTE: if this order was sent directly via an admin link, then neither the \"paid\" financial status nor any configured inclusion tags will be checked (on purpose, to allow for merchant flexibility on manual sends)\n {% endcomment %}\n\n {% if event.topic == \"shopify/orders/paid\" and order_inclusion_tags != blank %}\n {% assign has_inclusion_tag = nil %}\n {% assign order_tags = order.tags | split: \", \" %}\n\n {% for order_tag in order_tags %}\n {% if order_inclusion_tags contains order_tag %}\n {% assign has_inclusion_tag = true %}\n {% break %}\n {% endif %}\n {% endfor %}\n\n {% unless has_inclusion_tag or event.preview %}\n {% break %}\n {% endunless %}\n {% endif %}\n\n {% comment %}\n -- generate tax receipt as a PDF and attach to email to donor; optionally cc the shop email address\n {% endcomment %}\n\n {% action \"email\" %}\n {\n \"to\": {{ order.email | json }},\n \"subject\": {{ email_subject | json }},\n \"body\": {{ email_body | newline_to_br | json }},\n {% if cc_shop %}\"cc\": {{ shop.customer_email | json }},{% endif %}\n \"reply_to\": {{ shop.customer_email | json }},\n \"from_display_name\": {{ shop.name | json }},\n \"attachments\": {\n {{ donation_receipt_filename | remove: \"#\" | json }}: {\n \"pdf\": {\n \"html\": {{ donation_reciept_html_template | replace: \"[TAX_ID]\", tax_id | json }},\n \"__force_pdfcrowd\": true\n }\n }\n }\n }\n {% endaction %}\n{% endif %}\n", + "script": "{% assign tax_id = options.tax_id__required %}\n{% assign donation_product_tags = options.identify_donation_products_with_any_of_these_tags__array_required %}\n{% assign send_cc_to_shop_email = options.send_cc_to_shop_email__boolean %}\n{% assign email_subject = options.email_subject__required %}\n{% assign email_body = options.email_body__multiline_required %}\n{% assign donation_receipt_filename = options.donation_receipt_filename__required %}\n{% assign donation_reciept_html_template = options.donation_reciept_html_template__code_multiline_required %}\n\n{% if event.topic == \"shopify/orders/paid\" or event.topic == \"mechanic/user/order\" %}\n {% comment %}\n -- NOTE: if this order was sent directly via an admin link, then the \"paid\" financial status will not be checked to allow for flexibility on manual sends\n {% endcomment %}\n\n {% if order.email == blank %}\n {% log \"This order does not have an email associated with it.\" %}\n {% break %}\n {% endif %}\n\n {% comment %}\n -- get the order data to see if there are any donation products on this order, by product tag\n {% endcomment %}\n\n {% capture query %}\n query {\n order(id: {{ order.admin_graphql_api_id | json }}) {\n id\n presentmentCurrencyCode\n lineItems(first: 100) {\n nodes {\n product {\n tags\n }\n originalTotalSet {\n presentmentMoney {\n amount\n }\n }\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 \"order\": {\n \"presentmentCurrencyCode\": \"USD\",\n \"lineItems\": {\n \"nodes\": [\n {\n \"product\": {\n \"tags\": {{ donation_product_tags.first | json }}\n },\n \"originalTotalSet\": {\n \"presentmentMoney\": {\n \"amount\": \"100.0\"\n }\n }\n }\n ]\n }\n }\n }\n }\n {% endcapture %}\n\n {% assign result = result_json | parse_json %}\n {% endif %}\n\n {% comment %}\n -- for any donation products, add the non-discounted total for that line item to the runnning donation amount\n {% endcomment %}\n\n {% assign donation_amount = 0 %}\n\n {% for line_item in result.data.order.lineItems.nodes %}\n {% for donation_product_tag in donation_product_tags %}\n {% if line_item.product.tags contains donation_product_tag %}\n {% assign donation_amount = donation_amount | plus: line_item.originalTotalSet.presentmentMoney.amount %}\n {% break %}\n {% endif %}\n {% endfor %}\n {% endfor %}\n\n {% unless donation_amount > 0 %}\n {% log \"This order has no donation products on it; skipping\" %}\n {% break %}\n {% endunless %}\n\n {% assign donation_with_currency = donation_amount | currency: result.data.order.presentmentCurrencyCode %}\n\n {% comment %}\n -- replace variables in the HTML template for the configured tax ID and the calculated donation amount\n {% endcomment %}\n\n {% assign donation_html\n = donation_reciept_html_template\n | replace: \"[TAX_ID]\", tax_id\n | replace: \"[DONATION_AMOUNT]\", donation_with_currency\n %}\n\n {% comment %}\n -- generate tax receipt as a PDF and attach to email to donor; optionally cc the shop email address\n {% endcomment %}\n\n {% action \"email\" %}\n {\n \"to\": {{ order.email | json }},\n \"subject\": {{ email_subject | json }},\n \"body\": {{ email_body | newline_to_br | json }},\n {% if send_cc_to_shop_email %}\"cc\": {{ shop.customer_email | json }},{% endif %}\n \"reply_to\": {{ shop.customer_email | json }},\n \"from_display_name\": {{ shop.name | json }},\n \"attachments\": {\n {{ donation_receipt_filename | remove: \"#\" | json }}: {\n \"pdf\": {\n \"html\": {{ donation_html | json }},\n \"__force_pdfcrowd\": true\n }\n }\n }\n }\n {% endaction %}\n{% endif %}\n", "subscriptions": ["shopify/orders/paid", "mechanic/user/order"], "subscriptions_template": "shopify/orders/paid\nmechanic/user/order", "tags": ["Orders", "PDF", "Receipts", "Tax"]