From 864f4d0a33201558e6a5cbb50ef5964f2c222e1b Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Tue, 16 Jun 2026 08:48:25 -0700 Subject: [PATCH] syncro: document Invoice Message (note field) + auto block-rate hint for non-block customers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The on-screen "Invoice Message" text block IS the invoice `note` field, editable via PUT /invoices/{id} {"note": "..."} (response {"invoice": {...}}). Verified on the ACG internal test account (#67741: set/verify/restore). Billing flow now sets a one-line upsell hint on the invoice note — "Interested in discounted labor? Ask us about block-rate pricing." — ONLY for customers with no prepaid block (prepay_hours == 0). Block customers (prepay_hours > 0) get no hint; never clobber a non-empty note. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/commands/syncro.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.claude/commands/syncro.md b/.claude/commands/syncro.md index 9d81ee8..c2eb646 100644 --- a/.claude/commands/syncro.md +++ b/.claude/commands/syncro.md @@ -719,6 +719,21 @@ curl -s -X DELETE "${BASE}/invoices/${INV_ID}?api_key=${API_KEY}" POST `/invoices` pulls all current line items from the ticket into the invoice automatically. The POST response includes `.invoice.id` and `.invoice.total` — if either is null, GET `/invoices?customer_id=${CUST_ID}&per_page=5` and find the invoice by `ticket_id` match before taking any other action. +**Invoice Message (the on-screen "Invoice Message" text block) = the invoice `note` field.** It is per-invoice, prints on the invoice, and is set/edited with `PUT /invoices/{id}` body `{"note": "..."}` (response `{"invoice": {...}}`). Blank by default. Verified 2026-06-16 on the ACG internal test account (invoice #67741 — set/verified/restored). + +**Block-rate upsell hint — non-block customers ONLY.** When you invoice a customer with **no prepaid block** (`customer.prepay_hours == 0`), set the invoice note to the one-line hint so it prints on their invoice. Customers who already have a block (`prepay_hours > 0`) must **not** get it. Add this right after the invoice is created (`$PREPAY` = `customer.prepay_hours`, already fetched in billing Step 1): + +```bash +# Block-rate hint on the invoice — only for customers with NO prepaid block. +if [ "$(awk "BEGIN{print ((${PREPAY:-0})+0>0)?1:0}")" = "0" ]; then + curl -s -X PUT "${BASE}/invoices/${INVOICE_ID}?api_key=${API_KEY}" \ + -H "Content-Type: application/json" \ + --data-binary '{"note": "Interested in discounted labor? Ask us about block-rate pricing."}' >/dev/null +fi +``` + +Keep it to that one line. If the invoice `note` is already non-empty (a real per-invoice message), do **not** clobber it — only set the hint when the note is blank. + #### Recurring Invoice Schedules Recurring invoice templates are at `/schedules` — **not** `/recurring_invoices` (404). Generated invoices carry a `schedule_id` field linking back to the template. The `recurring_invoice_id` field on invoices is always null; ignore it. @@ -1053,6 +1068,14 @@ INVOICE_ID=$(echo "$INV_RESP" | jq -r '.invoice.id') INVOICE_TOTAL=$(echo "$INV_RESP" | jq -r '.invoice.total') # If INVOICE_ID is null: GET /invoices?customer_id=${CUST_ID}&per_page=5, find by ticket_id +# 3b. Block-rate hint on the invoice note — ONLY for customers with NO prepaid block. +# ($PREPAY = customer.prepay_hours, fetched in Step 1. Block customers don't get the hint.) +if [ "$(awk "BEGIN{print ((${PREPAY:-0})+0>0)?1:0}")" = "0" ]; then + curl -s -X PUT "${BASE}/invoices/${INVOICE_ID}?api_key=${API_KEY}" \ + -H "Content-Type: application/json" \ + --data-binary '{"note": "Interested in discounted labor? Ask us about block-rate pricing."}' >/dev/null +fi + # 4. Mark Invoiced curl -s -X PUT "${BASE}/tickets/${ID}?api_key=${API_KEY}" \ -H "Content-Type: application/json" \