Fix /syncro: time is added via comment fields, not timer_entry

Discovered from GUI page source: comment[product_id] + comment[minutes_spent]
+ comment[bill_time_now] are fields on POST /tickets/{id}/comment. This is
how the GUI adds time — as part of the comment, not via separate timer_entry.
Updated billing workflow + added --time/--labor flags to comment command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 11:17:40 -07:00
parent 392c42710c
commit ac4ceb65c0

View File

@@ -64,17 +64,23 @@ API_KEY=$(sops -d D:/vault/msp-tools/syncro.sops.yaml | python -c "import sys,ya
- `contact_id` (customer contact)
- `ticket_type_id` (ticket category)
#### Comments
#### Comments (with optional time entry)
| Operation | Method | Endpoint | Body |
|---|---|---|---|
| Add comment | POST | `/tickets/<id>/comment` | `{"subject": "Update", "body": "...", "hidden": false, "do_not_email": false}` |
| Add comment + time | POST | `/tickets/<id>/comment` | Same as above, PLUS: `"product_id": N, "minutes_spent": 60, "bill_time_now": false` |
**Comment fields:**
- `subject` — comment header (e.g., "Update", "Resolution", "Internal Note")
- `body` — comment text (HTML supported)
- `hidden` — if true, internal-only (customer can't see)
- `do_not_email` — if true, don't email customer about this comment
- `product_id` — labor product ID (see labor products table below). Adds billable time to the ticket.
- `minutes_spent` — integer, minutes of work (60 = 1hr minimum in most cases)
- `bill_time_now` — if true, immediately creates a charge (equivalent to "Charge now" checkbox in GUI)
**This is the primary way to log time.** Comment + time in one call mirrors the GUI workflow exactly. Timer entries (`/tickets/{id}/timer_entry`) exist but are rarely used.
#### Customers
@@ -139,16 +145,17 @@ When showing ticket detail, include:
### Billing workflow
When `/syncro bill <number>` is called:
1. Get ticket details + existing time entries
2. If no timer entries exist, ask: "Add time? How many hours + labor type?"
3. Add timer entry via `POST /tickets/{id}/timer_entry` with correct labor product_id
4. Show summary: total billable time, labor product, estimated total
5. Ask for confirmation: "Create invoice? [yes/no]"
6. On yes: `POST /invoices` with `{"ticket_id": N, "customer_id": N, "category": "Standard"}`
7. Update ticket status to "Invoiced"
1. Get ticket details
2. Ask: "How many minutes + labor type?" (default: 60 min, Labor - Remote Business)
3. Add comment with time: `POST /tickets/{id}/comment` with `product_id`, `minutes_spent`, `bill_time_now: false`, and work notes as body
4. Then create invoice: `POST /invoices` with `{"ticket_id": N, "customer_id": N, "category": "Standard"}`
5. Update ticket status to "Invoiced"
**The flow is: timer entries → Make Invoice → Syncro auto-creates line items from timers.**
Do NOT create line items manually unless adding non-labor charges (parts, products, etc.).
**The flow mirrors the GUI: add comment with time attached → Make Invoice.**
When `/syncro comment <number> <text> --time 60 --labor remote` is called:
- Post the comment with time in one API call
- `--labor` maps to product IDs: `remote` → 1190473, `onsite` → 26118, `emergency` → 26184, `project` → 9269129, `internal` → 9269124, `travel` → 26117, `website` → 68055
### Error handling