syncro: document Invoice Message (note field) + auto block-rate hint for non-block customers
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
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 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.
|
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')
|
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
|
# 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
|
# 4. Mark Invoiced
|
||||||
curl -s -X PUT "${BASE}/tickets/${ID}?api_key=${API_KEY}" \
|
curl -s -X PUT "${BASE}/tickets/${ID}?api_key=${API_KEY}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
|
|||||||
Reference in New Issue
Block a user