sync: auto-sync from GURU-BEAST-ROG at 2026-05-22 13:13:08
Author: Mike Swanson Machine: GURU-BEAST-ROG Timestamp: 2026-05-22 13:13:08
This commit is contained in:
@@ -584,14 +584,21 @@ POST `/invoices` pulls all current line items from the ticket into the invoice a
|
||||
|
||||
#### Estimates
|
||||
|
||||
Estimates (quotes) are standalone or ticket-linked. Verified 2026-05-22 against ACG internal account.
|
||||
Estimates (quotes) always get an associated ticket with a private note containing links. This is a hard workflow requirement — never create an estimate without the ticket and private note.
|
||||
|
||||
**Required fields for POST /estimates:** `customer_id`, `date` (ISO date string `"YYYY-MM-DD"`)
|
||||
**Optional:** `name` (estimate title), `ticket_id` (link to ticket), `location_id`
|
||||
**Statuses:** `Fresh` (default), `Approved`, `Declined`
|
||||
|
||||
**MANDATORY estimate workflow (4 steps, always in this order):**
|
||||
|
||||
1. Create estimate
|
||||
2. Add line items (with price fix — see below)
|
||||
3. Create ticket (`do_not_email: true`, `hidden: true` note) with private note containing estimate link + product/source links
|
||||
4. Link estimate to ticket via PUT, then post a single bot alert with both links
|
||||
|
||||
```bash
|
||||
# Create estimate
|
||||
# Step 1 — Create estimate
|
||||
EST_RESP=$(curl -s -X POST "${BASE}/estimates?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
@@ -605,8 +612,9 @@ JSON
|
||||
ESTIMATE_ID=$(echo "$EST_RESP" | jq -r '.estimate.id')
|
||||
ESTIMATE_NUM=$(echo "$EST_RESP" | jq -r '.estimate.number')
|
||||
|
||||
# Add line item — endpoint is /line_items NOT /add_line_item (that 404s)
|
||||
# Response: {"estimate": {...}, "line_item": {"id": N, "item": name, "price": rate, ...}}
|
||||
# Step 2 — Add line item, then fix price via PUT
|
||||
# NOTE: POST /line_items ignores price_retail for hardware (product 32252) — price stays $0.
|
||||
# Always follow up with PUT /line_items/{id} to set the price. Verified 2026-05-22.
|
||||
LI_RESP=$(curl -s -X POST "${BASE}/estimates/${ESTIMATE_ID}/line_items?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
@@ -616,13 +624,57 @@ LI_RESP=$(curl -s -X POST "${BASE}/estimates/${ESTIMATE_ID}/line_items?api_key=$
|
||||
"description": "<one-line description>",
|
||||
"quantity": ${QTY},
|
||||
"price_retail": ${RATE},
|
||||
"taxable": false
|
||||
"taxable": true
|
||||
}
|
||||
JSON
|
||||
)
|
||||
LI_ID=$(echo "$LI_RESP" | jq -r '.line_item.id')
|
||||
|
||||
# GET estimate (verify)
|
||||
# Fix price via PUT (required — POST does not apply price_retail for hardware)
|
||||
curl -s -X PUT "${BASE}/estimates/${ESTIMATE_ID}/line_items/${LI_ID}?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
{"price": ${RATE}, "price_retail": ${RATE}}
|
||||
JSON
|
||||
|
||||
# Step 3 — Create ticket + private note
|
||||
TICKET_RESP=$(curl -s -X POST "${BASE}/tickets?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
{
|
||||
"customer_id": ${CUST_ID},
|
||||
"subject": "<subject matching estimate name>",
|
||||
"problem_type": "Hardware",
|
||||
"status": "New",
|
||||
"priority": "2 Normal",
|
||||
"user_id": ${TECH_ID},
|
||||
"do_not_email": true
|
||||
}
|
||||
JSON
|
||||
)
|
||||
TICKET_ID=$(echo "$TICKET_RESP" | jq -r '.ticket.id')
|
||||
TICKET_NUM=$(echo "$TICKET_RESP" | jq -r '.ticket.number')
|
||||
|
||||
# Private note — hidden, with estimate link + product/source links
|
||||
curl -s -X POST "${BASE}/tickets/${TICKET_ID}/comment?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
{
|
||||
"subject": "Estimate Links",
|
||||
"body": "Estimate #${ESTIMATE_NUM}: https://computerguru.syncromsp.com/estimates/${ESTIMATE_ID}<br><source link description>: <URL><br><cost breakdown>",
|
||||
"hidden": true,
|
||||
"do_not_email": true
|
||||
}
|
||||
JSON
|
||||
|
||||
# Step 4 — Link estimate to ticket + touch to recalculate total
|
||||
curl -s -X PUT "${BASE}/estimates/${ESTIMATE_ID}?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
{"ticket_id": ${TICKET_ID}}
|
||||
JSON
|
||||
|
||||
# GET estimate (verify total recalculated)
|
||||
curl -s "${BASE}/estimates/${ESTIMATE_ID}?api_key=${API_KEY}" | \
|
||||
jq '{id: .estimate.id, number: .estimate.number, total: .estimate.total,
|
||||
lines: [.estimate.line_items[]? | {id, item, name, quantity, price}]}'
|
||||
@@ -636,11 +688,15 @@ curl -s -X DELETE "${BASE}/estimates/${ESTIMATE_ID}?api_key=${API_KEY}"
|
||||
|
||||
**GET /estimates line_items vs POST response:** GET returns `line_items` as an array on `.estimate.line_items[]`. POST `/line_items` returns the line item under `.line_item` (singular, not nested under estimate).
|
||||
|
||||
**Estimate total recalculation:** The `total` field on GET /estimates does not update automatically after line item changes. Always do a PUT on the estimate (even a no-op name update) to trigger recalculation, then re-fetch to verify.
|
||||
|
||||
**Hardware on estimates:** All hardware line items use a single generic product — `product_id: 32252` ("Hardware", `price_retail: 0.0`). The specific item name and price are set per-line-item via the `name` and `price_retail` fields on each line. Never look up a separate product ID for hardware items on estimates — always use `32252` and vary the description and price per item.
|
||||
|
||||
**Hardware line item price bug (verified 2026-05-22):** POST `/estimates/{id}/line_items` ignores `price_retail` for product 32252 — the line item is created at $0. Always follow POST with a PUT to `/estimates/{id}/line_items/{li_id}` passing both `price` and `price_retail`. The PUT succeeds and sets the price correctly.
|
||||
|
||||
```bash
|
||||
# Example hardware line item on an estimate
|
||||
curl -s -X POST "${BASE}/estimates/${ESTIMATE_ID}/line_items?api_key=${API_KEY}" \
|
||||
# Example hardware line item on an estimate (POST + required price fix PUT)
|
||||
LI_RESP=$(curl -s -X POST "${BASE}/estimates/${ESTIMATE_ID}/line_items?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
{
|
||||
@@ -652,6 +708,15 @@ curl -s -X POST "${BASE}/estimates/${ESTIMATE_ID}/line_items?api_key=${API_KEY}"
|
||||
"taxable": true
|
||||
}
|
||||
JSON
|
||||
)
|
||||
LI_ID=$(echo "$LI_RESP" | jq -r '.line_item.id')
|
||||
|
||||
# Required: fix price via PUT
|
||||
curl -s -X PUT "${BASE}/estimates/${ESTIMATE_ID}/line_items/${LI_ID}?api_key=${API_KEY}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- <<JSON
|
||||
{"price": 649.00, "price_retail": 649.00}
|
||||
JSON
|
||||
```
|
||||
|
||||
### Display formatting
|
||||
@@ -803,6 +868,9 @@ echo "$ALERT_OUT"
|
||||
|---|---|
|
||||
| Ticket (create / update / close / comment / bill) | `https://computerguru.syncromsp.com/tickets/<ticket.id>` |
|
||||
| Customer (create) | `https://computerguru.syncromsp.com/customers/<customer.id>` |
|
||||
| Estimate (create) | `https://computerguru.syncromsp.com/estimates/<estimate.id>` |
|
||||
|
||||
**Estimate alert — single post with both links:** When creating an estimate, send ONE alert after all four steps complete (estimate + line items + ticket + link). Include both the ticket link and estimate link in a single message.
|
||||
|
||||
**Examples:**
|
||||
|
||||
@@ -812,6 +880,10 @@ bash "$CLAUDETOOLS_ROOT/.claude/scripts/post-bot-alert.sh" \
|
||||
"[SYNCRO] Howard created #32301 (Desert Auto Tech) - Server won't boot -> https://computerguru.syncromsp.com/tickets/110736645"
|
||||
# Success output: [OK] post-bot-alert: posted to #bot-alerts (message_id=1507055781780918404)
|
||||
|
||||
# Estimate created (single alert, both links)
|
||||
bash "$CLAUDETOOLS_ROOT/.claude/scripts/post-bot-alert.sh" \
|
||||
"[SYNCRO] Mike created estimate #7188 (Arizona Computer Guru) - ASUS V500 i7 Workstation \$849.99 | ticket #32316 -> https://computerguru.syncromsp.com/tickets/110843061 | https://computerguru.syncromsp.com/estimates/23967407"
|
||||
|
||||
# Billed + invoiced
|
||||
bash "$CLAUDETOOLS_ROOT/.claude/scripts/post-bot-alert.sh" \
|
||||
"[SYNCRO] Mike billed #32164 (Jerry Burger) - 1.0h remote, \$150.00 -> https://computerguru.syncromsp.com/tickets/110169036"
|
||||
|
||||
Reference in New Issue
Block a user