@go-labs-sg/bb 2.41.0 → 2.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/command-manifest.json +132 -2
- package/command-reference.md +138 -2
- package/dist/index.js +637 -228
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,39 @@ The shared API rechecks existing records at submission. Canonical matches reuse
|
|
|
22
22
|
|
|
23
23
|
`bb company use` and `bb company create` are state-changing, potentially external-writing commands. In non-interactive mode their existing permission gates require `--allow-state-change --allow-external-write`. Deploy the backend before publishing this CLI change. See [company discovery details](../api/docs/company-discovery.md) for limits and retry behaviour.
|
|
24
24
|
|
|
25
|
+
## Record a payment made outside Budget Builder
|
|
26
|
+
|
|
27
|
+
Admins can record an already-made payment on an APPROVED bill or claim without transferring money or emailing the supplier/claimant:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bb bill payment accounts
|
|
31
|
+
bb bill payment record-external <billId> \
|
|
32
|
+
--paymentReference 2343190532 \
|
|
33
|
+
--paymentDate 2026-09-01 \
|
|
34
|
+
--paymentAccount <quickbooks-account-id> \
|
|
35
|
+
--paymentProof receipt.pdf
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Choose the bank or card account actually used (including `Events Requisitions`); no account or date is defaulted. Omit `--paymentProof` if a payment-proof PDF is already attached. In non-interactive use, add `--allow-state-change --allow-external-write --allow-financial-write`; no `--allow-email` is needed. The UI offers the same **Record external payment** action next to ordinary **Mark paid**.
|
|
39
|
+
|
|
40
|
+
BB marks the bill PAID immediately and queues durable QuickBooks reconciliation. A settled zero-balance QBO bill reuses its existing BillPayment IDs. Otherwise reconciliation creates a payment with the specified date/account and a stable provider request ID. Partially settled or inconsistent QBO bills require manual reconciliation; BB never guesses. Inspect failed/pending work in Integration Queue and **do not pay the bill again**. Exact retries with the same reference/date/account return the recorded settlement; changed details conflict. Ordinary Mark paid keeps its existing payment-advice workflow.
|
|
41
|
+
|
|
42
|
+
`bb update-bill --payload '{"id":"<billId>","comment":"Already paid; do not pay again"}'` now accepts a partial payload. Omitted fields are preserved; comment-only updates do not change financial data or sync QBO, and are allowed on approved/paid bills for the creator or an admin. Financial edits retain their draft/rejected restrictions.
|
|
43
|
+
|
|
44
|
+
Deployment prerequisite: apply the Budget Builder Prisma schema additions (`Bill.externalPayment` JSON and `EXTERNAL_PAYMENT` operation enum) before deploying the API/web/workers; deploy the backend before publishing the CLI. This feature does not modify existing paid bills or repair historical QBO entries automatically.
|
|
45
|
+
|
|
46
|
+
## Payload help and uncertain writes
|
|
47
|
+
|
|
48
|
+
Run `bb <command> --help` (for example, `bb create-item --help`) to see required and optional `--payload` fields and an example JSON object. Item creation and updates accept a finite numeric `cost` and convert it to the API's decimal-string input. Validation errors identify the affected field; unsupported QuickBooks name characters are listed explicitly.
|
|
49
|
+
|
|
50
|
+
If `create-budget` reports an uncertain outcome (including Prisma P2028 or a network interruption), **do not retry immediately**. Run `bb list-budgets --projectId <project-id>` and check for the budget name first; the write may have committed even though the CLI did not receive a successful response. This check is not an idempotency guarantee when another budget has the same name.
|
|
51
|
+
|
|
52
|
+
A failed `create-supplier` request may likewise have committed. Inspect `bb list-suppliers --name <name>` and matching supplier details before retrying; names alone do not identify one attempt. If supplier creation succeeded but its separate approval request failed or returned no approval IDs, inspect that supplier's approvals by ID and retry only the approval step if needed. Do not create the supplier again. The CLI confirms the combined supplier-and-approval workflow before the first write.
|
|
53
|
+
|
|
54
|
+
`create-budget-approval` and `create-estimate` accept `--companyPayload`, `--contactPayload`, and `--eventPayload` as JSON objects. The CLI rejects non-object JSON; the API validates required fields.
|
|
55
|
+
|
|
56
|
+
`create-project` requires an existing Asana Deals lead task. In non-interactive runs pass `--asanaTaskId`; interactive runs can select a match with `--asanaSearch`. The Slack channel is resolved from the task unless all Slack channel flags are provided. For a new direct client, create the lead task in the website form first.
|
|
57
|
+
|
|
25
58
|
## Shared catalogue editing
|
|
26
59
|
|
|
27
60
|
All active authenticated users can edit suppliers, inventory items and item categories. Normal-user supplier updates submit a revision for approval in the shared API; item/category edits apply immediately. Lead/Admin supplier edits bypass human review. `bb supplier update` returns the server-owned approval/synchronization result without issuing another approval request. New supplier usage stays on hold during review and linked QuickBooks synchronization; existing usage continues with the last approved details until the edit is approved. Creator identity and delete/archive permissions are unchanged.
|
package/command-manifest.json
CHANGED
|
@@ -790,6 +790,18 @@
|
|
|
790
790
|
{
|
|
791
791
|
"name": "--allow-financial-write",
|
|
792
792
|
"description": "Allow financial-record changes in non-interactive use."
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
"name": "--companyPayload <json>",
|
|
796
|
+
"description": "Company update JSON object with id, name, and website fields."
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
"name": "--contactPayload <json>",
|
|
800
|
+
"description": "Contact update JSON object with companyId, title, firstName, lastName, email, and mobile fields."
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"name": "--eventPayload <json>",
|
|
804
|
+
"description": "Event timing JSON object with date, startTime, and endTime fields."
|
|
793
805
|
}
|
|
794
806
|
],
|
|
795
807
|
"argumentMode": "legacy-passthrough",
|
|
@@ -840,6 +852,18 @@
|
|
|
840
852
|
{
|
|
841
853
|
"name": "--allow-financial-write",
|
|
842
854
|
"description": "Allow financial-record changes in non-interactive use."
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
"name": "--companyPayload <json>",
|
|
858
|
+
"description": "Company update JSON object with id, name, and website fields."
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
"name": "--contactPayload <json>",
|
|
862
|
+
"description": "Contact update JSON object with companyId, title, firstName, lastName, email, and mobile fields."
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
"name": "--eventPayload <json>",
|
|
866
|
+
"description": "Event timing JSON object with date, startTime, and endTime fields."
|
|
843
867
|
}
|
|
844
868
|
],
|
|
845
869
|
"argumentMode": "legacy-passthrough",
|
|
@@ -2237,7 +2261,7 @@
|
|
|
2237
2261
|
{
|
|
2238
2262
|
"path": ["bill", "update"],
|
|
2239
2263
|
"legacyAliases": ["update-bill", "update_bill"],
|
|
2240
|
-
"summary": "Update a bill or claim
|
|
2264
|
+
"summary": "Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.",
|
|
2241
2265
|
"globalOptions": [
|
|
2242
2266
|
{
|
|
2243
2267
|
"name": "--help",
|
|
@@ -2437,6 +2461,112 @@
|
|
|
2437
2461
|
"effects": ["state-change", "email", "financial-write"],
|
|
2438
2462
|
"legacyTarget": "update-bill-status"
|
|
2439
2463
|
},
|
|
2464
|
+
{
|
|
2465
|
+
"path": ["bill", "payment", "record-external"],
|
|
2466
|
+
"legacyAliases": [
|
|
2467
|
+
"record-external-bill-payment",
|
|
2468
|
+
"record_external_bill_payment"
|
|
2469
|
+
],
|
|
2470
|
+
"summary": "Record an already-made payment on an APPROVED bill or claim, with no email and no money transfer. Requires <billId> --paymentReference --paymentDate YYYY-MM-DD --paymentAccount <QBO account ID> [--paymentProof receipt.pdf]. Reuses settled QBO payment links or queues one dated payment from the selected account. Exact retries are safe; do not pay again while reconciliation is pending.",
|
|
2471
|
+
"globalOptions": [
|
|
2472
|
+
{
|
|
2473
|
+
"name": "--help",
|
|
2474
|
+
"description": "Show help for this command."
|
|
2475
|
+
},
|
|
2476
|
+
{
|
|
2477
|
+
"name": "--quiet",
|
|
2478
|
+
"description": "Suppress non-error diagnostics."
|
|
2479
|
+
},
|
|
2480
|
+
{
|
|
2481
|
+
"name": "--debug",
|
|
2482
|
+
"description": "Emit sanitized diagnostic traces."
|
|
2483
|
+
},
|
|
2484
|
+
{
|
|
2485
|
+
"name": "--api-url",
|
|
2486
|
+
"description": "Override the Budget Builder API base URL."
|
|
2487
|
+
},
|
|
2488
|
+
{
|
|
2489
|
+
"name": "--no-browser",
|
|
2490
|
+
"description": "Print the authorization URL without opening a browser."
|
|
2491
|
+
},
|
|
2492
|
+
{
|
|
2493
|
+
"name": "--allow-state-change",
|
|
2494
|
+
"description": "Allow a Budget Builder state change in non-interactive use."
|
|
2495
|
+
},
|
|
2496
|
+
{
|
|
2497
|
+
"name": "--allow-email",
|
|
2498
|
+
"description": "Allow sending email in non-interactive use."
|
|
2499
|
+
},
|
|
2500
|
+
{
|
|
2501
|
+
"name": "--allow-external-write",
|
|
2502
|
+
"description": "Allow writes to external systems in non-interactive use."
|
|
2503
|
+
},
|
|
2504
|
+
{
|
|
2505
|
+
"name": "--allow-delete",
|
|
2506
|
+
"description": "Allow deleting data in non-interactive use."
|
|
2507
|
+
},
|
|
2508
|
+
{
|
|
2509
|
+
"name": "--allow-financial-write",
|
|
2510
|
+
"description": "Allow financial-record changes in non-interactive use."
|
|
2511
|
+
}
|
|
2512
|
+
],
|
|
2513
|
+
"argumentMode": "legacy-passthrough",
|
|
2514
|
+
"effects": ["state-change", "external-write", "financial-write"],
|
|
2515
|
+
"legacyTarget": "record-external-bill-payment"
|
|
2516
|
+
},
|
|
2517
|
+
{
|
|
2518
|
+
"path": ["bill", "payment", "accounts"],
|
|
2519
|
+
"legacyAliases": [
|
|
2520
|
+
"list-external-payment-accounts",
|
|
2521
|
+
"list_external_payment_accounts"
|
|
2522
|
+
],
|
|
2523
|
+
"summary": "List active QuickBooks bank and credit-card account IDs for recording external payments (admin only).",
|
|
2524
|
+
"globalOptions": [
|
|
2525
|
+
{
|
|
2526
|
+
"name": "--help",
|
|
2527
|
+
"description": "Show help for this command."
|
|
2528
|
+
},
|
|
2529
|
+
{
|
|
2530
|
+
"name": "--quiet",
|
|
2531
|
+
"description": "Suppress non-error diagnostics."
|
|
2532
|
+
},
|
|
2533
|
+
{
|
|
2534
|
+
"name": "--debug",
|
|
2535
|
+
"description": "Emit sanitized diagnostic traces."
|
|
2536
|
+
},
|
|
2537
|
+
{
|
|
2538
|
+
"name": "--api-url",
|
|
2539
|
+
"description": "Override the Budget Builder API base URL."
|
|
2540
|
+
},
|
|
2541
|
+
{
|
|
2542
|
+
"name": "--no-browser",
|
|
2543
|
+
"description": "Print the authorization URL without opening a browser."
|
|
2544
|
+
},
|
|
2545
|
+
{
|
|
2546
|
+
"name": "--allow-state-change",
|
|
2547
|
+
"description": "Allow a Budget Builder state change in non-interactive use."
|
|
2548
|
+
},
|
|
2549
|
+
{
|
|
2550
|
+
"name": "--allow-email",
|
|
2551
|
+
"description": "Allow sending email in non-interactive use."
|
|
2552
|
+
},
|
|
2553
|
+
{
|
|
2554
|
+
"name": "--allow-external-write",
|
|
2555
|
+
"description": "Allow writes to external systems in non-interactive use."
|
|
2556
|
+
},
|
|
2557
|
+
{
|
|
2558
|
+
"name": "--allow-delete",
|
|
2559
|
+
"description": "Allow deleting data in non-interactive use."
|
|
2560
|
+
},
|
|
2561
|
+
{
|
|
2562
|
+
"name": "--allow-financial-write",
|
|
2563
|
+
"description": "Allow financial-record changes in non-interactive use."
|
|
2564
|
+
}
|
|
2565
|
+
],
|
|
2566
|
+
"argumentMode": "legacy-passthrough",
|
|
2567
|
+
"effects": [],
|
|
2568
|
+
"legacyTarget": "list-external-payment-accounts"
|
|
2569
|
+
},
|
|
2440
2570
|
{
|
|
2441
2571
|
"path": ["bill", "payment", "patch"],
|
|
2442
2572
|
"legacyAliases": ["patch-bill-payment", "patch_bill_payment"],
|
|
@@ -5504,7 +5634,7 @@
|
|
|
5504
5634
|
{
|
|
5505
5635
|
"path": ["project", "create"],
|
|
5506
5636
|
"legacyAliases": ["create-project", "create_project"],
|
|
5507
|
-
"summary": "Create
|
|
5637
|
+
"summary": "Create a project linked to an existing Asana Deals lead task. Supply --asanaTaskId in non-interactive use; interactive use searches for and selects a lead task (optionally --asanaSearch). The Slack channel is resolved from the selected Asana task unless all three Slack channel flags are supplied. For a new direct client, create the lead task using the website form first.",
|
|
5508
5638
|
"globalOptions": [
|
|
5509
5639
|
{
|
|
5510
5640
|
"name": "--help",
|
package/command-reference.md
CHANGED
|
@@ -161,6 +161,11 @@ Legacy aliases: `send-estimate-to-contact-person`, `send_estimate_to_contact_per
|
|
|
161
161
|
|
|
162
162
|
Effects: state-change, email.
|
|
163
163
|
|
|
164
|
+
Payload fields (--payload JSON)
|
|
165
|
+
Required: estimateId: string; budgetId: string; to: email; cc: email[]; replyTo: email; subject: string; content: HTML string; signature: HTML string
|
|
166
|
+
Optional: estimateDocNumber: string
|
|
167
|
+
Example: bb send-estimate-to-contact-person --payload '{"estimateId":"<estimate-id>","budgetId":"<budget-id>","to":"client@example.com","cc":[],"replyTo":"team@example.com","subject":"Estimate","content":"<p>Attached estimate</p>","signature":"<p>Team</p>"}'
|
|
168
|
+
|
|
164
169
|
## `bb budget create`
|
|
165
170
|
|
|
166
171
|
Create Budget.
|
|
@@ -169,6 +174,11 @@ Legacy aliases: `create-budget`, `create_budget`.
|
|
|
169
174
|
|
|
170
175
|
Effects: state-change.
|
|
171
176
|
|
|
177
|
+
Payload fields (--payload JSON)
|
|
178
|
+
Required: name: string; budget: decimal string; paymentTerm: string; categoryId: string; projectId: string
|
|
179
|
+
Optional: sourceBudgetId: string; unavailableItemReviewAcknowledged: boolean (only after review); pipedriveDealId: string
|
|
180
|
+
Example: bb create-budget --payload '{"name":"Event budget","budget":"1500","paymentTerm":"Net 30","categoryId":"<category-id>","projectId":"<project-id>"}'
|
|
181
|
+
|
|
172
182
|
## `bb budget update`
|
|
173
183
|
|
|
174
184
|
Update Budget.
|
|
@@ -177,6 +187,11 @@ Legacy aliases: `update-budget`, `update_budget`.
|
|
|
177
187
|
|
|
178
188
|
Effects: state-change.
|
|
179
189
|
|
|
190
|
+
Payload fields (--payload JSON)
|
|
191
|
+
Required: id: string; name: string; budget: decimal string; paymentTerm: string; categoryId: string; projectId: string
|
|
192
|
+
Optional: sourceBudgetId: string; pipedriveDealId: string
|
|
193
|
+
Example: bb update-budget --payload '{"id":"<budget-id>","name":"Event budget","budget":"1500","paymentTerm":"Net 30","categoryId":"<category-id>","projectId":"<project-id>"}'
|
|
194
|
+
|
|
180
195
|
## `bb budget delete`
|
|
181
196
|
|
|
182
197
|
Delete Budget.
|
|
@@ -273,6 +288,11 @@ Legacy aliases: `update-budget-commission`, `update_budget_commission`.
|
|
|
273
288
|
|
|
274
289
|
Effects: state-change, financial-write.
|
|
275
290
|
|
|
291
|
+
Payload fields (--payload JSON)
|
|
292
|
+
Required: budgetId: string; name: string; percentage: decimal string; totalSellingAfterDiscount: number
|
|
293
|
+
Optional: none
|
|
294
|
+
Example: bb update-budget-commission --payload '{"budgetId":"<budget-id>","name":"Sales commission","percentage":"10","totalSellingAfterDiscount":1500}'
|
|
295
|
+
|
|
276
296
|
## `bb budget discount update`
|
|
277
297
|
|
|
278
298
|
Update Budget Discount.
|
|
@@ -281,6 +301,11 @@ Legacy aliases: `update-budget-discount`, `update_budget_discount`.
|
|
|
281
301
|
|
|
282
302
|
Effects: state-change, financial-write.
|
|
283
303
|
|
|
304
|
+
Payload fields (--payload JSON)
|
|
305
|
+
Required: budgetId: string; name: string; type: percentage|amount; value: decimal string; totalSellingBeforeDiscount: number
|
|
306
|
+
Optional: none
|
|
307
|
+
Example: bb update-budget-discount --payload '{"budgetId":"<budget-id>","name":"Discount","type":"amount","value":"100","totalSellingBeforeDiscount":1500}'
|
|
308
|
+
|
|
284
309
|
## `bb budget commission delete`
|
|
285
310
|
|
|
286
311
|
Delete Budget Commission.
|
|
@@ -353,6 +378,11 @@ Legacy aliases: `create-bill`, `create_bill`.
|
|
|
353
378
|
|
|
354
379
|
Effects: state-change, email, external-write, financial-write.
|
|
355
380
|
|
|
381
|
+
Payload fields (--payload JSON)
|
|
382
|
+
Required: budgetId: string; projectId: string; supplierId: string; amount: number (ex-GST); budgetItemIds: string[]; isClaimable: boolean; supplier bills: quotationIds: string[] or quotationAllocations: {budgetItemId, quotationId, amount}[] (unless --quotation-exempt)
|
|
383
|
+
Optional: lineAmounts: {budgetItemId, amount}[] (required with quotationAllocations); attachments: {id,name,key,size}[]; invoiceNumber: string; invoiceDate: ISO date; draftOnly: boolean; alreadyPaid: boolean; extractedAmount: number
|
|
384
|
+
Example: bb create-bill --payload '{"budgetId":"<budget-id>","projectId":"<project-id>","supplierId":"<supplier-id>","amount":1800,"budgetItemIds":["<budget-item-id>"],"isClaimable":false,"quotationIds":["<quotation-id>"],"attachments":[]}'
|
|
385
|
+
|
|
356
386
|
## `bb bill selection validate`
|
|
357
387
|
|
|
358
388
|
Validate the approved supplier and selected bill line items.
|
|
@@ -361,6 +391,11 @@ Legacy aliases: `validate-bill-selection`, `validate_bill_selection`.
|
|
|
361
391
|
|
|
362
392
|
Effects: none.
|
|
363
393
|
|
|
394
|
+
Payload fields (--payload JSON)
|
|
395
|
+
Required: projectId: string; supplierId: string; budgetItemIds: string[]
|
|
396
|
+
Optional: quotationIds: string[] for supplier bills; isClaimable: boolean; amount: number; lineAmounts: {budgetItemId, amount}[]; quotationAllocations: {budgetItemId, quotationId, amount}[] (requires amount and lineAmounts)
|
|
397
|
+
Example: bb validate-bill-selection --payload '{"projectId":"<project-id>","supplierId":"<supplier-id>","budgetItemIds":["<budget-item-id>"],"quotationIds":["<quotation-id>"]}'
|
|
398
|
+
|
|
364
399
|
## `bb bill quotation link`
|
|
365
400
|
|
|
366
401
|
Link Bill Quotations.
|
|
@@ -369,14 +404,24 @@ Legacy aliases: `link-bill-quotations`, `link_bill_quotations`, `billId`.
|
|
|
369
404
|
|
|
370
405
|
Effects: state-change, financial-write.
|
|
371
406
|
|
|
407
|
+
Payload fields (--payload JSON)
|
|
408
|
+
Required: positional <billId>; quotationIds: string[] or quotationAllocations: {budgetItemId, quotationId, amount}[]
|
|
409
|
+
Optional: none (legacy quotationId is not supported)
|
|
410
|
+
Example: bb link-bill-quotations <billId> --payload '{"quotationIds":["<quotation-id>"]}'
|
|
411
|
+
|
|
372
412
|
## `bb bill update`
|
|
373
413
|
|
|
374
|
-
Update a bill or claim
|
|
414
|
+
Update a bill or claim with a partial payload including id; omitted fields are preserved. Comment-only updates are allowed on approved/paid bills without altering financial data or QuickBooks. All amount fields exclude GST: amount is the portion billed; extractedAmount is the full invoice subtotal; lineAmounts and quotationAllocations also exclude GST. Example: 1800 + 162 GST = 1962 total requires amount=1800 and extractedAmount=1800 for a full bill. The CLI does not strip GST from input. Re-read and verify both amount fields and allocations after correcting a gross/net mistake.
|
|
375
415
|
|
|
376
416
|
Legacy aliases: `update-bill`, `update_bill`.
|
|
377
417
|
|
|
378
418
|
Effects: state-change, external-write, financial-write.
|
|
379
419
|
|
|
420
|
+
Payload fields (--payload JSON)
|
|
421
|
+
Required: id: string; budgetId: string; projectId: string; supplierId: string; amount: number (ex-GST); budgetItemIds: string[]; isClaimable: boolean
|
|
422
|
+
Optional: quotationIds: string[]; quotationAllocations: {budgetItemId, quotationId, amount}[]; lineAmounts: {budgetItemId, amount}[]; attachments: {id,name,key,size}[]; invoiceNumber: string; invoiceDate: ISO date
|
|
423
|
+
Example: bb update-bill --payload '{"id":"<bill-id>","budgetId":"<budget-id>","projectId":"<project-id>","supplierId":"<supplier-id>","amount":1800,"budgetItemIds":["<budget-item-id>"],"isClaimable":false,"quotationIds":["<quotation-id>"],"attachments":[]}'
|
|
424
|
+
|
|
380
425
|
## `bb bill payment-evidence update`
|
|
381
426
|
|
|
382
427
|
Update Bill Payment Evidence.
|
|
@@ -385,6 +430,11 @@ Legacy aliases: `update-bill-payment-evidence`, `update_bill_payment_evidence`.
|
|
|
385
430
|
|
|
386
431
|
Effects: state-change, financial-write.
|
|
387
432
|
|
|
433
|
+
Payload fields (--payload JSON)
|
|
434
|
+
Required: id: string; paymentReference: string; paymentProofAttachments: {id,name (PDF),key,size}[] (at least one)
|
|
435
|
+
Optional: none
|
|
436
|
+
Example: bb update-bill-payment-evidence --payload '{"id":"<bill-id>","paymentReference":"TRANSFER-123","paymentProofAttachments":[{"id":"<attachment-id>","name":"receipt.pdf","key":"<staged-key>","size":1000}]}'
|
|
437
|
+
|
|
388
438
|
## `bb bill delete`
|
|
389
439
|
|
|
390
440
|
Delete Bill.
|
|
@@ -401,6 +451,22 @@ Legacy aliases: `update-bill-status`, `update_bill_status`.
|
|
|
401
451
|
|
|
402
452
|
Effects: state-change, email, financial-write.
|
|
403
453
|
|
|
454
|
+
## `bb bill payment record-external`
|
|
455
|
+
|
|
456
|
+
Record an already-made payment on an APPROVED bill or claim, with no email and no money transfer. Requires <billId> --paymentReference --paymentDate YYYY-MM-DD --paymentAccount <QBO account ID> [--paymentProof receipt.pdf]. Reuses settled QBO payment links or queues one dated payment from the selected account. Exact retries are safe; do not pay again while reconciliation is pending.
|
|
457
|
+
|
|
458
|
+
Legacy aliases: `record-external-bill-payment`, `record_external_bill_payment`.
|
|
459
|
+
|
|
460
|
+
Effects: state-change, external-write, financial-write.
|
|
461
|
+
|
|
462
|
+
## `bb bill payment accounts`
|
|
463
|
+
|
|
464
|
+
List active QuickBooks bank and credit-card account IDs for recording external payments (admin only).
|
|
465
|
+
|
|
466
|
+
Legacy aliases: `list-external-payment-accounts`, `list_external_payment_accounts`.
|
|
467
|
+
|
|
468
|
+
Effects: none.
|
|
469
|
+
|
|
404
470
|
## `bb bill payment patch`
|
|
405
471
|
|
|
406
472
|
Patch Bill Payment.
|
|
@@ -513,6 +579,11 @@ Legacy aliases: `create-quotation`, `create_quotation`.
|
|
|
513
579
|
|
|
514
580
|
Effects: state-change.
|
|
515
581
|
|
|
582
|
+
Payload fields (--payload JSON)
|
|
583
|
+
Required: projectId: string; budgetId: string; supplierId: string; budgetItemIds: string[]; amountWithoutGst: number; gstAmount: number; attachments: array (uploaded attachment)
|
|
584
|
+
Optional: lineAmounts: {budgetItemId, amount}[] (required for multiple budget items)
|
|
585
|
+
Example: bb create-quotation --payload '{"projectId":"<project-id>","budgetId":"<budget-id>","supplierId":"<supplier-id>","budgetItemIds":["<budget-item-id>"],"amountWithoutGst":1200,"gstAmount":0,"attachments":[{"id":"<attachment-id>","name":"quote.pdf","key":"<staged-key>","size":1000}]}'
|
|
586
|
+
|
|
516
587
|
## `bb quotation update`
|
|
517
588
|
|
|
518
589
|
Update a DRAFT or REJECTED quotation using --payload JSON with id and the complete creation payload. Multiple budget items require lineAmounts: [{"budgetItemId":"<first-id>","amount":750},{"budgetItemId":"<second-id>","amount":450}], covering every budgetItemIds entry exactly once and summing to amountWithoutGst. Amounts exclude GST; use gstAmount: 0 for no GST.
|
|
@@ -521,6 +592,11 @@ Legacy aliases: `update-quotation`, `update_quotation`.
|
|
|
521
592
|
|
|
522
593
|
Effects: state-change.
|
|
523
594
|
|
|
595
|
+
Payload fields (--payload JSON)
|
|
596
|
+
Required: id: string; projectId: string; budgetId: string; supplierId: string; budgetItemIds: string[]; amountWithoutGst: number; gstAmount: number; attachments: array
|
|
597
|
+
Optional: lineAmounts: {budgetItemId, amount}[] (required for multiple budget items)
|
|
598
|
+
Example: bb update-quotation --payload '{"id":"<quotation-id>","projectId":"<project-id>","budgetId":"<budget-id>","supplierId":"<supplier-id>","budgetItemIds":["<budget-item-id>"],"amountWithoutGst":1200,"gstAmount":0,"attachments":[{"id":"<attachment-id>","name":"quote.pdf","key":"<staged-key>","size":1000}]}'
|
|
599
|
+
|
|
524
600
|
## `bb quotation delete`
|
|
525
601
|
|
|
526
602
|
Delete Quotation.
|
|
@@ -641,6 +717,11 @@ Legacy aliases: `create-customer-invoice`, `create_customer_invoice`.
|
|
|
641
717
|
|
|
642
718
|
Effects: state-change, email, external-write, financial-write.
|
|
643
719
|
|
|
720
|
+
Payload fields (--payload JSON)
|
|
721
|
+
Required: budgetId: string; splits: [{label: string, percentage: number, dueDate: ISO date}] (exactly one)
|
|
722
|
+
Optional: requestId: UUID string (recommended); invoiceDate: ISO date; details: {billingAddress: string, customerMemo: string}; isCustomPercentage: boolean
|
|
723
|
+
Example: bb create-customer-invoice --payload '{"budgetId":"<budget-id>","splits":[{"label":"Deposit","percentage":50,"dueDate":"2026-10-15"}],"details":{"billingAddress":"1 Example St","customerMemo":"Thanks"}}'
|
|
724
|
+
|
|
644
725
|
## `bb customer-invoice discard`
|
|
645
726
|
|
|
646
727
|
Discard Customer Invoice.
|
|
@@ -689,6 +770,11 @@ Legacy aliases: `send-customer-invoice-to-contact-person`, `send_customer_invoic
|
|
|
689
770
|
|
|
690
771
|
Effects: state-change, email.
|
|
691
772
|
|
|
773
|
+
Payload fields (--payload JSON)
|
|
774
|
+
Required: invoiceId: string; to: email; cc: email[]; replyTo: email; subject: string; content: HTML string; signature: HTML string
|
|
775
|
+
Optional: none
|
|
776
|
+
Example: bb send-customer-invoice-to-contact-person --payload '{"invoiceId":"<invoice-id>","to":"client@example.com","cc":[],"replyTo":"team@example.com","subject":"Invoice","content":"<p>Attached invoice</p>","signature":"<p>Team</p>"}'
|
|
777
|
+
|
|
692
778
|
## `bb customer-invoice pdf download`
|
|
693
779
|
|
|
694
780
|
Download a customer invoice PDF when permitted.
|
|
@@ -817,6 +903,11 @@ Legacy aliases: `update-company`, `update_company`.
|
|
|
817
903
|
|
|
818
904
|
Effects: state-change, external-write.
|
|
819
905
|
|
|
906
|
+
Payload fields (--payload JSON)
|
|
907
|
+
Required: id: string; name: string; website: URL string
|
|
908
|
+
Optional: confirmDistinct: boolean
|
|
909
|
+
Example: bb update-company --payload '{"id":"<company-id>","name":"Example Co","website":"https://example.com"}'
|
|
910
|
+
|
|
820
911
|
## `bb company delete`
|
|
821
912
|
|
|
822
913
|
Delete Company.
|
|
@@ -875,7 +966,7 @@ Effects: state-change, external-write.
|
|
|
875
966
|
|
|
876
967
|
## `bb project create`
|
|
877
968
|
|
|
878
|
-
Create
|
|
969
|
+
Create a project linked to an existing Asana Deals lead task. Supply --asanaTaskId in non-interactive use; interactive use searches for and selects a lead task (optionally --asanaSearch). The Slack channel is resolved from the selected Asana task unless all three Slack channel flags are supplied. For a new direct client, create the lead task using the website form first.
|
|
879
970
|
|
|
880
971
|
Legacy aliases: `create-project`, `create_project`.
|
|
881
972
|
|
|
@@ -889,6 +980,11 @@ Legacy aliases: `update-project`, `update_project`.
|
|
|
889
980
|
|
|
890
981
|
Effects: state-change, external-write.
|
|
891
982
|
|
|
983
|
+
Payload fields (--payload JSON)
|
|
984
|
+
Required: id: string; name: string; companyId: string; contactPersonId: string; asanaTaskId: string; insideSalesId: string; businessDevelopmentId: string; venue: string; dateRange: {from: ISO date}
|
|
985
|
+
Optional: dateRange.to: ISO date; projectManagerId: string; pax: string; description: string; slackChannelId/slackChannelUrl/slackChannelName: strings (supply all three); requestQboAccountantNotification: boolean; confirmEstimateInvalidation: boolean
|
|
986
|
+
Example: bb update-project --payload '{"id":"<project-id>","name":"Launch","companyId":"<company-id>","contactPersonId":"<contact-id>","asanaTaskId":"<asana-task-id>","insideSalesId":"<user-id>","businessDevelopmentId":"<user-id>","venue":"Hall","dateRange":{"from":"2026-10-01T09:00:00Z"}}'
|
|
987
|
+
|
|
892
988
|
## `bb project delete`
|
|
893
989
|
|
|
894
990
|
Delete Project.
|
|
@@ -953,6 +1049,11 @@ Legacy aliases: `create-contact-person`, `create_contact_person`.
|
|
|
953
1049
|
|
|
954
1050
|
Effects: state-change.
|
|
955
1051
|
|
|
1052
|
+
Payload fields (--payload JSON)
|
|
1053
|
+
Required: companyId: string; title: MR|MRS|MS|DR; firstName: string; lastName: string|null; email: string; mobile: string
|
|
1054
|
+
Optional: address: {streetAddress1?, city?, state?, postalCode?, country?}
|
|
1055
|
+
Example: bb create-contact-person --payload '{"companyId":"<company-id>","title":"MS","firstName":"Jane","lastName":"Tan","email":"jane@example.com","mobile":"+65 9123 4567"}'
|
|
1056
|
+
|
|
956
1057
|
## `bb contact update`
|
|
957
1058
|
|
|
958
1059
|
Update Contact Person.
|
|
@@ -961,6 +1062,11 @@ Legacy aliases: `update-contact-person`, `update_contact_person`.
|
|
|
961
1062
|
|
|
962
1063
|
Effects: state-change.
|
|
963
1064
|
|
|
1065
|
+
Payload fields (--payload JSON)
|
|
1066
|
+
Required: id: string; companyId: string; title: MR|MRS|MS|DR; firstName: string; lastName: string|null; email: string; mobile: string
|
|
1067
|
+
Optional: address: object
|
|
1068
|
+
Example: bb update-contact-person --payload '{"id":"<contact-id>","companyId":"<company-id>","title":"MS","firstName":"Jane","lastName":"Tan","email":"jane@example.com","mobile":"+65 9123 4567"}'
|
|
1069
|
+
|
|
964
1070
|
## `bb supplier list`
|
|
965
1071
|
|
|
966
1072
|
List suppliers.
|
|
@@ -977,6 +1083,11 @@ Legacy aliases: `create-supplier`, `create_supplier`.
|
|
|
977
1083
|
|
|
978
1084
|
Effects: state-change, email, external-write.
|
|
979
1085
|
|
|
1086
|
+
Payload fields (--payload JSON)
|
|
1087
|
+
Required: name: string; primaryContactPerson: string; email: string; phone: string; paymentMethodId: string; paymentTerm: string; roleId: string
|
|
1088
|
+
Optional: gstRegistered: boolean; tags: string[]; website: URL string; address: object; attachments: array; bank and PayNow fields
|
|
1089
|
+
Example: bb create-supplier --payload '{"name":"Example Supplier","primaryContactPerson":"Jane Tan","email":"jane@example.com","phone":"91234567","paymentMethodId":"<method-id>","paymentTerm":"Net 30","roleId":"<role-id>"}'
|
|
1090
|
+
|
|
980
1091
|
## `bb supplier update`
|
|
981
1092
|
|
|
982
1093
|
Update Supplier.
|
|
@@ -985,6 +1096,11 @@ Legacy aliases: `update-supplier`, `update_supplier`.
|
|
|
985
1096
|
|
|
986
1097
|
Effects: state-change, email, external-write.
|
|
987
1098
|
|
|
1099
|
+
Payload fields (--payload JSON)
|
|
1100
|
+
Required: id: string; name: string; primaryContactPerson: string; email: string; phone: string; paymentMethodId: string; paymentTerm: string; roleId: string
|
|
1101
|
+
Optional: gstRegistered: boolean; tags: string[]; website: URL string; address: object; attachments: array; bank and PayNow fields
|
|
1102
|
+
Example: bb update-supplier --payload '{"id":"<supplier-id>","name":"Example Supplier","primaryContactPerson":"Jane Tan","email":"jane@example.com","phone":"91234567","paymentMethodId":"<method-id>","paymentTerm":"Net 30","roleId":"<role-id>"}'
|
|
1103
|
+
|
|
988
1104
|
## `bb supplier delete`
|
|
989
1105
|
|
|
990
1106
|
Delete Suppliers.
|
|
@@ -1065,6 +1181,11 @@ Legacy aliases: `create-item`, `create_item`.
|
|
|
1065
1181
|
|
|
1066
1182
|
Effects: state-change, external-write.
|
|
1067
1183
|
|
|
1184
|
+
Payload fields (--payload JSON)
|
|
1185
|
+
Required: name: string (QuickBooks-safe characters); categoryId: string; supplierId: string; cost: decimal string or number
|
|
1186
|
+
Optional: description: string; gstInclusive: boolean; gstOutOfScope: boolean; goLabsProduct: boolean; attachments: array
|
|
1187
|
+
Example: bb create-item --payload '{"name":"Event Crew per hour","categoryId":"<category-id>","supplierId":"<supplier-id>","cost":19}'
|
|
1188
|
+
|
|
1068
1189
|
## `bb item update`
|
|
1069
1190
|
|
|
1070
1191
|
Update Item.
|
|
@@ -1073,6 +1194,11 @@ Legacy aliases: `update-item`, `update_item`.
|
|
|
1073
1194
|
|
|
1074
1195
|
Effects: state-change, external-write.
|
|
1075
1196
|
|
|
1197
|
+
Payload fields (--payload JSON)
|
|
1198
|
+
Required: id: string; name: string; categoryId: string; supplierId: string; cost: decimal string or number
|
|
1199
|
+
Optional: description: string; gstInclusive: boolean; gstOutOfScope: boolean; goLabsProduct: boolean; attachments: array
|
|
1200
|
+
Example: bb update-item --payload '{"id":"<item-id>","name":"Event Crew per hour","categoryId":"<category-id>","supplierId":"<supplier-id>","cost":"19"}'
|
|
1201
|
+
|
|
1076
1202
|
## `bb item archive`
|
|
1077
1203
|
|
|
1078
1204
|
Archive Items.
|
|
@@ -1297,6 +1423,11 @@ Legacy aliases: `save-inbound-mapping`, `save_inbound_mapping`.
|
|
|
1297
1423
|
|
|
1298
1424
|
Effects: state-change.
|
|
1299
1425
|
|
|
1426
|
+
Payload fields (--payload JSON)
|
|
1427
|
+
Required: positional <sourceId>; payload: [{canonicalField: enum, typeformFieldId: string, required?: boolean, typeformFieldRef?: string|null}] (1-50 entries)
|
|
1428
|
+
Optional: required defaults false; typeformFieldRef may be omitted
|
|
1429
|
+
Example: bb save-inbound-mapping <sourceId> --payload '[{"canonicalField":"CONTACT_FIRST_NAME","typeformFieldId":"<typeform-field-id>"}]'
|
|
1430
|
+
|
|
1300
1431
|
## `bb inbound automation save`
|
|
1301
1432
|
|
|
1302
1433
|
Save Inbound Automation Config.
|
|
@@ -1305,6 +1436,11 @@ Legacy aliases: `save-inbound-automation-config`, `save_inbound_automation_confi
|
|
|
1305
1436
|
|
|
1306
1437
|
Effects: state-change.
|
|
1307
1438
|
|
|
1439
|
+
Payload fields (--payload JSON)
|
|
1440
|
+
Required: positional <sourceId>; asanaCustomFields: object; asanaDefaultAssigneeId: string|null; asanaDefaultAssigneeName: string|null; asanaFollowerIds: string[]; asanaProjectId: string; asanaSectionId: string; asanaWonSectionId: string; asanaLostSectionId: string; googleCalendarId: string; googleCalendarTimeZone: string; goshBriefBaseUrl: URL; slackDefaultAssigneeId: string|null; slackInboundChannelId: string; slackInviteUserIds: string[]; slackPitchChannelPrefix: string
|
|
1441
|
+
Optional: asanaDiscussionSectionId, asanaFirstContactSectionId, asanaFirstProposalSentSectionId, asanaProposalWipSectionId: string|null; asanaCustomFields.*: mapped IDs
|
|
1442
|
+
Example: bb save-inbound-automation-config <sourceId> --payload '{"asanaCustomFields":{},"asanaDefaultAssigneeId":null,"asanaDefaultAssigneeName":null,"asanaFollowerIds":[],"asanaProjectId":"<asana-project-id>","asanaSectionId":"<asana-section-id>","asanaWonSectionId":"<asana-won-id>","asanaLostSectionId":"<asana-lost-id>","googleCalendarId":"team@example.com","googleCalendarTimeZone":"Asia/Singapore","goshBriefBaseUrl":"https://example.com/brief","slackDefaultAssigneeId":null,"slackInboundChannelId":"<slack-channel-id>","slackInviteUserIds":[],"slackPitchChannelPrefix":"pitch"}'
|
|
1443
|
+
|
|
1308
1444
|
## `bb inbound processing update`
|
|
1309
1445
|
|
|
1310
1446
|
Update Inbound Processing.
|