jaz-clio 5.4.32 → 5.4.34
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/assets/skills/api/SKILL.md +1 -1
- package/assets/skills/cli/SKILL.md +1 -1
- package/assets/skills/conversion/SKILL.md +1 -1
- package/assets/skills/jobs/SKILL.md +1 -1
- package/assets/skills/jobs/references/year-end-close.md +1 -1
- package/assets/skills/practice/SKILL.md +1 -1
- package/assets/skills/transaction-recipes/SKILL.md +1 -1
- package/assets/skills/transaction-recipes/references/bad-debt-provision.md +3 -3
- package/assets/skills/transaction-recipes/references/bank-loan.md +2 -2
- package/assets/skills/transaction-recipes/references/capital-wip.md +3 -3
- package/assets/skills/transaction-recipes/references/declining-balance.md +3 -3
- package/assets/skills/transaction-recipes/references/deferred-revenue.md +2 -2
- package/assets/skills/transaction-recipes/references/employee-accruals.md +3 -4
- package/assets/skills/transaction-recipes/references/fx-revaluation.md +2 -2
- package/assets/skills/transaction-recipes/references/hire-purchase.md +1 -1
- package/assets/skills/transaction-recipes/references/ifrs16-lease.md +3 -3
- package/assets/skills/transaction-recipes/references/intercompany.md +4 -4
- package/cli.mjs +4 -4
- package/package.json +1 -1
|
@@ -229,7 +229,7 @@ Invoke `audit-prep.md` job. Year-end-close output (TB final, all reports, all re
|
|
|
229
229
|
|
|
230
230
|
- **Run in January for prior FY.** Standalone mode includes all 4 quarter closes; allow 5-10 days for full FY catch-up if quarterly cadence has slipped.
|
|
231
231
|
- **External audit timeline:** auditor typically arrives 4-6 weeks after FY-end. Year-end-close + audit-prep should complete within 6 weeks of FY-end. Faster = cheaper audit.
|
|
232
|
-
- **Reclassification reversal:** the Y6 entries are FY-specific. Year 2's monthly-close.md step
|
|
232
|
+
- **Reclassification reversal:** the Y6 entries are FY-specific. Year 2's monthly-close.md step 1 (or a Y1 reverse step in next year's year-end-close) should reverse them before fresh classification.
|
|
233
233
|
- **Form C-S timing:** SG IRAS deadline is November 30 of the FOLLOWING year. ECI: within 3 months of FY-end. Plan year-end-close to feed audit-prep within 3 months for ECI compliance.
|
|
234
234
|
|
|
235
235
|
---
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
- **`apply_credit_to_invoice(...)` / `create_customer_credit_note(...)`** — step 6 specific write-off pattern: when individual invoices are deemed unrecoverable, write them off via credit note OR direct payment with `paymentMethod: 'DEBT_WRITE_OFF'` (per memory rule).
|
|
20
20
|
|
|
21
21
|
### Cross-references
|
|
22
|
-
- Within an engagement: invoked from `practice/references/annual-statutory.md` step 4d (Y4 in `year-end-close.md`) for FY-end ECL; from `practice/references/quarterly-gst.md` step
|
|
22
|
+
- Within an engagement: invoked from `practice/references/annual-statutory.md` step 4d (Y4 in `year-end-close.md`) for FY-end ECL; from `practice/references/quarterly-gst.md` step 8 if quarterly cadence is set; rarely from monthly-close (mental check during step 8 variance only).
|
|
23
23
|
- Sibling: `provisions.md` (engine `provision`) — IAS 37 provisions with PV unwinding pattern, more complex than this recipe.
|
|
24
24
|
- IFRS / accounting context: IFRS 9.5.5.15 (simplified approach mandatory for trade receivables); IFRS 9.B5.5.35 (provision matrix). For specific large customers in stage-3 (objective evidence of impairment): supplement this recipe with specific impairment via `create_customer_credit_note` per customer.
|
|
25
25
|
|
|
@@ -193,7 +193,7 @@ Write-offs reduce both the gross AR balance AND offset against the existing Allo
|
|
|
193
193
|
## Cross-references back to engagements
|
|
194
194
|
|
|
195
195
|
- `practice/references/annual-statutory.md` step 4d (Y4) — year-end ECL true-up. Practice playbook reads `CLIENT.ecl_loss_rate_matrix` for the bucket rates and `CLIENT.materiality_threshold` for skip-or-post decision.
|
|
196
|
-
- `practice/references/quarterly-gst.md` step
|
|
197
|
-
- `practice/references/monthly-close.md` step
|
|
196
|
+
- `practice/references/quarterly-gst.md` step 8 (where applicable) — quarterly ECL review for clients on quarterly cadence.
|
|
197
|
+
- `practice/references/monthly-close.md` step 8 — mental ECL cross-check during variance analysis only; formal recipe runs annually/quarterly.
|
|
198
198
|
- `audit-prep.md` step 8 — supporting schedule via the most recent `ECL Provision` capsule + the underlying `clio calc ecl` JSON. Auditor tests rate appropriateness against actual historical loss data.
|
|
199
199
|
- Sibling `provisions.md` (engine `provision`) — IAS 37 provisions with PV unwinding (more complex pattern).
|
|
@@ -143,12 +143,12 @@ After the FINAL period (60th repayment) is finalized:
|
|
|
143
143
|
- **Interest-only period:** Not supported by the loan calculator. Workaround: post N manual interest-only journals via `create_journal` (Dr Interest Expense / Cr Cash) for the interest-only window, then run `plan_recipe(recipe: 'loan', ...)` from the start of the amortizing window with the full outstanding principal.
|
|
144
144
|
- **Multi-currency loan (USD loan with SGD base):** Pass `currency: 'USD'`. Disbursement records via `currency: { sourceCurrency: 'USD' }` per `jaz-api/SKILL.md` rule 25. Monthly repayments stay in USD. Period-end FX revaluation against base currency is auto-handled by Jaz (Loan Payable is a monetary item per IAS 21.23 — Jaz auto-translates at closing rate). Verify via `practice/references/monthly-close.md` step 6 verification flow; do NOT invoke `execute_recipe(recipe: 'fx-reval', ...)`.
|
|
145
145
|
- **Loan origination fees:** Out of scope for this recipe (the engine's IFRS 9 effective-interest treatment doesn't currently amortize fees into the EIR). Post fees as a separate manual journal: Dr `Operating Expense > Loan Origination Fee` / Cr Cash. For IFRS 9 EIR-amortized fees, model the fee as `prepaid-expense` over the loan term.
|
|
146
|
-
- **Year-end current/non-current reclassification:** Out of scope for the engine — manual annual journal: Dr Loan Payable Non-Current / Cr Loan Payable Current for the next 12 months' principal portion.
|
|
146
|
+
- **Year-end current/non-current reclassification:** Out of scope for the engine — manual annual journal: Dr Loan Payable Non-Current / Cr Loan Payable Current for the next 12 months' principal portion. Job blueprint `jobs/references/year-end-close.md` Y6 covers this.
|
|
147
147
|
|
|
148
148
|
---
|
|
149
149
|
|
|
150
150
|
## Cross-references back to engagements
|
|
151
151
|
|
|
152
152
|
- `practice/references/monthly-close.md` step 4 — explicitly excludes loan interest from monthly accruals because the loan scheduler emits it automatically. Practitioner should never post a manual loan-interest accrual.
|
|
153
|
-
- `
|
|
153
|
+
- `jobs/references/year-end-close.md` Y6 — current/non-current reclassification of the next 12 months' principal portion (manual journal pattern, not engine-managed).
|
|
154
154
|
- `practice/references/onboarding.md` — when the prior firm carried a loan, the opening trial balance includes the outstanding balance. Conversion (`jaz-conversion/SKILL.md § Option 2`) loads it via the `Conversion Clearing > Loan` account; this recipe then runs from the migration date forward only (do NOT model historical periods retroactively).
|
|
@@ -22,7 +22,7 @@ CWIP costs accumulate as construction progresses — multiple bills from contrac
|
|
|
22
22
|
- **`generate_trial_balance(period_end: <date>)`** — step 5 verify CWIP balance is zero post-transfer; FA balance reflects new asset.
|
|
23
23
|
|
|
24
24
|
### Cross-references
|
|
25
|
-
- Within an engagement: invoked from `practice/references/monthly-close.md` step
|
|
25
|
+
- Within an engagement: invoked from `practice/references/monthly-close.md` step 7 (per active capital project per `CLIENT.capital_projects[]`); from `practice/references/annual-statutory.md` step 4h (year-end review of CWIP balances — IAS 16.20 capitalization criteria; flag any CWIP not capitalized for > 12 months as potential expense).
|
|
26
26
|
- Sibling: `bank-loan.md` (financing the construction often ties together — the loan funds the CWIP); `declining-balance.md` / `asset-disposal.md` for post-capitalization lifecycle.
|
|
27
27
|
- IFRS / accounting context: IAS 16.16-22 (cost components includable in PP&E during construction); IAS 16.23 (capitalization stops when asset is in location and condition for intended use); IAS 23 (borrowing costs eligible for capitalization on qualifying assets).
|
|
28
28
|
|
|
@@ -217,8 +217,8 @@ Close the project capsule (or keep ACTIVE for traceability — the FA still refe
|
|
|
217
217
|
|
|
218
218
|
## Cross-references back to engagements
|
|
219
219
|
|
|
220
|
-
- `practice/references/monthly-close.md` step
|
|
221
|
-
- `practice/references/annual-statutory.md` step
|
|
220
|
+
- `practice/references/monthly-close.md` step 7 — review active CWIP per project; flag any pending completion.
|
|
221
|
+
- `practice/references/annual-statutory.md` step 4h — year-end review: any CWIP balance > 12 months without completion should be questioned (auditor will). Either complete the transfer, or impair if abandoned.
|
|
222
222
|
- `audit-prep.md` step 8 — supporting schedule: per project capsule, all bills + transfer journal + FA registration. Auditor traces from individual bills → CWIP balance → FA cost.
|
|
223
223
|
- `bank-loan.md` — if construction is loan-financed, pair this recipe with the loan recipe; capitalize interest during construction per IAS 23.
|
|
224
224
|
- `asset-disposal.md` — when the eventual FA is later disposed (typically many years after construction).
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
- **`bulk_update_journals(items: [{resourceId: <id>, saveAsDraft: false}, ...])`** — step 5 monthly: finalize this period's pre-emitted DRAFT depreciation journal.
|
|
19
19
|
|
|
20
20
|
### Cross-references
|
|
21
|
-
- Within an engagement: invoked from `practice/references/monthly-close.md` step
|
|
21
|
+
- Within an engagement: invoked from `practice/references/monthly-close.md` step 5 (only when an asset uses non-SL method — Jaz native FA handles SL automatically). For SL: `create_fixed_asset` directly via `fixed-assets` tool family; do NOT use this recipe.
|
|
22
22
|
- Sibling: `asset-disposal.md` for end-of-life de-recognition; `ifrs16-lease.md` (lease engine) which uses SL depreciation via the FA register because ROU is always SL under IFRS 16.
|
|
23
23
|
- IFRS / accounting context: IAS 16.62 — depreciation method should reflect the pattern of consumption of the asset's economic benefits. DDB / 150DB are valid alternatives to SL when usage is front-loaded (vehicles, technology). NOT for buildings, land improvements (always SL).
|
|
24
24
|
|
|
@@ -136,8 +136,8 @@ After the FINAL period (month 60):
|
|
|
136
136
|
|
|
137
137
|
## Cross-references back to engagements
|
|
138
138
|
|
|
139
|
-
- `practice/references/monthly-close.md` step
|
|
140
|
-
- `practice/references/annual-statutory.md` step
|
|
139
|
+
- `practice/references/monthly-close.md` step 5 — invoked monthly only when an asset uses non-SL. SL depreciation runs through Jaz native FA register automatically (no recipe needed).
|
|
140
|
+
- `practice/references/annual-statutory.md` step 4a — full FY-end depreciation reconciliation: sum 12 monthly journals against `clio calc depreciation --frequency annual` cross-check; auditor will sample-test.
|
|
141
141
|
- `practice/references/onboarding.md` — opening accumulated depreciation loaded via conversion (Conversion Clearing > Accumulated Depreciation account); recipe runs forward from the migration date with `cost: <NBV at migration>` instead of original cost. Useful-life-years should be `remaining life`, not original.
|
|
142
142
|
- Sibling recipe `asset-disposal.md` — end-of-life de-recognition.
|
|
143
143
|
- `audit-prep.md` step 8 — supporting schedule via `search_capsules(filter: {capsuleType: {eq: 'Depreciation'}})` + per-capsule `clio calc depreciation` recompute.
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- **`bulk_update_journals(items: [{resourceId: <id>, saveAsDraft: false}, ...])`** — step 5 monthly: finalize this period's pre-emitted DRAFT recognition journal.
|
|
22
22
|
|
|
23
23
|
### Cross-references
|
|
24
|
-
- Within an engagement: invoked from `practice/references/monthly-close.md` step
|
|
24
|
+
- Within an engagement: invoked from `practice/references/monthly-close.md` step 7 (finalize this period's pre-emitted journal for existing capsules; create a new capsule for any new deferred arrangement starting this period).
|
|
25
25
|
- Sibling recipes: `prepaid-amortization.md` (mirror — same engine pattern, opposite direction).
|
|
26
26
|
- IFRS / accounting context: IFRS 15 — revenue recognition over time when control transfers gradually (subscriptions, retainers, multi-period service contracts). The recipe assumes ratable straight-line recognition; for stage-based / milestone billing, use a different pattern (see Variations).
|
|
27
27
|
|
|
@@ -140,7 +140,7 @@ If customer cancels mid-term: invoke ad-hoc adjustment — delete remaining DRAF
|
|
|
140
140
|
|
|
141
141
|
## Cross-references back to engagements
|
|
142
142
|
|
|
143
|
-
- `practice/references/monthly-close.md` step
|
|
143
|
+
- `practice/references/monthly-close.md` step 7 — invoked monthly to finalize this period's pre-emitted recognition journal per existing Deferred Revenue capsule, AND to plan/execute new capsules when a fresh deferred arrangement starts in the period.
|
|
144
144
|
- `practice/references/onboarding.md` — opening trial balance may include opening Deferred Revenue (subscriptions in flight at conversion date). Conversion (`jaz-conversion/SKILL.md § Option 2`) loads the opening balance via clearing account; this recipe then sets up forward recognition only (do NOT model historical periods retroactively).
|
|
145
145
|
- `practice/references/annual-statutory.md` step 1 — final monthly close before year-end-close handles the December recognition journal; year-end-close confirms Deferred Revenue is correctly classified as current vs non-current liability for BS presentation.
|
|
146
146
|
- Sibling recipe `prepaid-amortization.md` — same engine pattern from the buyer's perspective.
|
|
@@ -33,7 +33,7 @@ The two patterns share the same `Employee Benefits` capsule type but use differe
|
|
|
33
33
|
- For year-end true-up: see `year-end-close.md` Y2 — manual journal pattern with HR-supplied actuals.
|
|
34
34
|
|
|
35
35
|
### Cross-references
|
|
36
|
-
- Within an engagement: invoked from `practice/references/monthly-close.md` step
|
|
36
|
+
- Within an engagement: invoked from `practice/references/monthly-close.md` step 4 (monthly leave) and `practice/references/annual-statutory.md` step 4f (Y2 in `year-end-close.md` — bonus accrual true-up).
|
|
37
37
|
- Sibling: `accrued-expenses.md` (the engine that drives the bonus pattern); `dividend.md` (annual P&L distribution to shareholders, mirror to bonus).
|
|
38
38
|
- IFRS / accounting context: IAS 19.11 (short-term employee benefits — recognized as expense in the period the service is rendered); IAS 19.13 (accrual of leave entitlement); IAS 19.19 (recognition criteria for bonuses — present obligation + reliable estimate).
|
|
39
39
|
|
|
@@ -174,7 +174,6 @@ Per quarter-end-close (`quarter-end-close.md`):
|
|
|
174
174
|
|
|
175
175
|
## Cross-references back to engagements
|
|
176
176
|
|
|
177
|
-
- `practice/references/monthly-close.md` step
|
|
178
|
-
- `practice/references/
|
|
179
|
-
- `practice/references/annual-statutory.md` Y2 — both leave and bonus true-ups against actuals; transition from accrual to actual cash payment in early Q1 next FY.
|
|
177
|
+
- `practice/references/monthly-close.md` step 4 — monthly leave-accrual finalize per existing leave capsule.
|
|
178
|
+
- `practice/references/annual-statutory.md` step 4f (Y2 in `year-end-close.md`) — both leave and bonus true-ups against actuals; transition from accrual to actual cash payment in early Q1 next FY. (No quarterly bonus-accrual step exists in `quarterly-gst.md` — true-up runs annually only.)
|
|
180
179
|
- Sibling `accrued-expenses.md` — the engine that drives the bonus pattern; full error table + variations there.
|
|
@@ -139,7 +139,7 @@ If you genuinely need to know whether auto-FX is enabled for a specific org: che
|
|
|
139
139
|
|
|
140
140
|
## Cross-references back to engagements
|
|
141
141
|
|
|
142
|
-
- `practice/references/monthly-close.md` step 6 — VERIFICATION ONLY. Confirm Jaz's auto-posted FX gain/loss matches independent calc; surface variance only.
|
|
142
|
+
- `practice/references/monthly-close.md` step 6 — VERIFICATION ONLY. Confirm Jaz's auto-posted FX gain/loss matches independent calc; surface variance only.
|
|
143
143
|
- `practice/references/quarterly-gst.md` step 6 — same.
|
|
144
|
-
- `practice/references/annual-statutory.md` step
|
|
144
|
+
- `practice/references/annual-statutory.md` step 4c — FY-end FX verification feeds audit-prep step 8 supporting schedules; auditors want the independent recomputation alongside Jaz's auto-posted journals.
|
|
145
145
|
- `audit-prep.md` step 8 — receives the verification file as a supporting schedule.
|
|
@@ -110,6 +110,6 @@ Month 60: final depreciation post. NBV = 0. Decommission FA via `update_fixed_as
|
|
|
110
110
|
|
|
111
111
|
## Cross-references back to engagements
|
|
112
112
|
|
|
113
|
-
- See `ifrs16-lease.md` cross-references — same engagement contexts (monthly-close step 7,
|
|
113
|
+
- See `ifrs16-lease.md` cross-references — same engagement contexts (monthly-close step 7, `jobs/references/year-end-close.md` Y6 for current/non-current reclass).
|
|
114
114
|
- Sibling recipe `ifrs16-lease.md` — full step-by-step + error table + non-HP variations.
|
|
115
115
|
- `asset-disposal.md` — when HP'd asset is eventually sold/scrapped (typically after month 60 = end of useful life).
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- **`generate_fa_summary(period_end: <date>)`** — step 5 verify Jaz auto-posted ROU depreciation.
|
|
22
22
|
|
|
23
23
|
### Cross-references
|
|
24
|
-
- Within an engagement: invoked from `practice/references/monthly-close.md` step 7 (verify scheduler / pre-emitted unwinding journal + verify Jaz FA posted ROU depreciation), `
|
|
24
|
+
- Within an engagement: invoked from `practice/references/monthly-close.md` step 7 (verify scheduler / pre-emitted unwinding journal + verify Jaz FA posted ROU depreciation), `jobs/references/year-end-close.md` Y6 (current/non-current reclassification of the next 12 months' principal portion).
|
|
25
25
|
- Sibling recipes: `bank-loan.md` (similar amortization pattern but no FA dimension); `hire-purchase.md` (shares the lease engine but with different useful-life-months per asset).
|
|
26
26
|
- IFRS / accounting context: IFRS 16 paragraphs 22-25 (recognition), 36 (subsequent measurement), 47 (lease liability re-measurement).
|
|
27
27
|
|
|
@@ -164,14 +164,14 @@ After the FINAL period (month 36):
|
|
|
164
164
|
- **Variable rent** (CPI-linked, turnover-linked): NOT supported by initial recipe. Recompute PV at each reset event and re-measure manually.
|
|
165
165
|
- **Multi-currency lease** (USD payments from SGD bank): pass `currency: 'USD'`. ROU + Lease Liability denominate in USD; Jaz auto-translates BS balances at closing rate per IAS 21.23 (do NOT invoke `fx-reval` recipe).
|
|
166
166
|
- **Lease with prepayments** (initial payment at signing): post the prepayment as `create_cash_out_entry` against ROU Asset BEFORE invoking the recipe. The recipe's PV calculation should exclude the upfront payment portion.
|
|
167
|
-
- **Year-end current/non-current reclassification**: Out of scope for the engine. Manual annual journal: Dr Lease Liability (Non-Current) / Cr Lease Liability (Current) for the next 12 months' principal portion.
|
|
167
|
+
- **Year-end current/non-current reclassification**: Out of scope for the engine. Manual annual journal: Dr Lease Liability (Non-Current) / Cr Lease Liability (Current) for the next 12 months' principal portion. Job blueprint `jobs/references/year-end-close.md` Y6 covers this.
|
|
168
168
|
|
|
169
169
|
---
|
|
170
170
|
|
|
171
171
|
## Cross-references back to engagements
|
|
172
172
|
|
|
173
173
|
- `practice/references/monthly-close.md` step 7 — invoked monthly to finalize this period's pre-emitted unwinding DRAFT (5a) + verify Jaz auto-posted ROU depreciation (5b).
|
|
174
|
-
- `
|
|
174
|
+
- `jobs/references/year-end-close.md` Y6 — current/non-current reclassification (manual annual journal) + auditor sample-test of the lease schedule via `clio calc lease`.
|
|
175
175
|
- `practice/references/onboarding.md` — opening lease balances loaded via conversion (`jaz-conversion/SKILL.md § Option 2` with the Conversion Clearing > Lease account); recipe runs forward only from migration date.
|
|
176
176
|
- `audit-prep.md` step 8 — supporting schedule via `search_capsules(filter: {capsuleType: {eq: 'Lease'}})` + per-capsule `clio calc lease` recompute. Auditor reconciles to TB Lease Liability + ROU Asset NBV.
|
|
177
177
|
- Sibling recipe `hire-purchase.md` — same engine, different useful-life parameter.
|
|
@@ -28,7 +28,7 @@ Intercompany requires posting MIRRORED entries in TWO different Jaz orgs (Entity
|
|
|
28
28
|
- NEVER mix. Cross-org pollution corrupts both entities' books.
|
|
29
29
|
|
|
30
30
|
### Cross-references
|
|
31
|
-
- Within an engagement: invoked from `practice/references/monthly-close.md` step
|
|
31
|
+
- Within an engagement: invoked from `practice/references/monthly-close.md` step 7 (intercompany leg of monthly close, only for clients with active intercompany arrangements per `CLIENT.intercompany_arrangements[]`).
|
|
32
32
|
- Sibling: `dividend.md` (cross-entity equity distribution — also requires multi-org coordination).
|
|
33
33
|
- IFRS / accounting context: IAS 24 (related-party disclosure); intercompany balances ELIMINATE at consolidation per IFRS 10.B86 (consolidation procedures).
|
|
34
34
|
|
|
@@ -178,7 +178,7 @@ For consolidation (if the practitioner manages a group): the matched IC balances
|
|
|
178
178
|
| Cross-FX intercompany | Entity A in SGD, Entity B in USD — IC Receivable in A doesn't match USD-equivalent in B | Both sides should agree on the transaction-currency amount (e.g., USD 15,000). Translation to base currency happens at each entity's books separately. Reconciliation at the SOURCE currency level, not base. |
|
|
179
179
|
| Transfer-pricing dispute (IRAS audit) | (process — separate from posting) | IC charges must satisfy arm's-length principle (SG: ITA s34D / OECD TPG). Maintain a transfer-pricing study. Practice playbook should reference `CLIENT.transfer_pricing_documentation`. |
|
|
180
180
|
| Both entities forget to post | (audit risk) | Year-end audit-prep step — auditor reconciles IC balances. Build a quarterly review into the engagement playbook. |
|
|
181
|
-
| Settlement reference mismatch | Bank-recon doesn't match IC payment to bill payment | Use a consistent `IC-PAY-YYYY-MM-XX` reference convention. Document in `practice/references/monthly-close.md` step
|
|
181
|
+
| Settlement reference mismatch | Bank-recon doesn't match IC payment to bill payment | Use a consistent `IC-PAY-YYYY-MM-XX` reference convention. Document in `practice/references/monthly-close.md` step 7. |
|
|
182
182
|
|
|
183
183
|
---
|
|
184
184
|
|
|
@@ -194,8 +194,8 @@ For consolidation (if the practitioner manages a group): the matched IC balances
|
|
|
194
194
|
|
|
195
195
|
## Cross-references back to engagements
|
|
196
196
|
|
|
197
|
-
- `practice/references/monthly-close.md` step
|
|
198
|
-
- `practice/references/annual-statutory.md` step
|
|
197
|
+
- `practice/references/monthly-close.md` step 7 — invoked monthly per active IC arrangement in `CLIENT.intercompany_arrangements[]`. Practice playbook orchestrates multi-org context switching (load entity A → post → load entity B → post → reconcile).
|
|
198
|
+
- `practice/references/annual-statutory.md` step 4g — full FY IC reconciliation; auditor sample-tests.
|
|
199
199
|
- `audit-prep.md` step 8 — IC balances supporting schedule; auditor independently confirms with the counter-entity.
|
|
200
200
|
- Sibling `dividend.md` — cross-entity equity distribution; same multi-org coordination pattern.
|
|
201
201
|
- `practice/references/onboarding.md` — multi-org practitioner workflow setup; CLIENT.md per entity with `jaz_api_key_override` per client.
|
package/cli.mjs
CHANGED
|
@@ -699,14 +699,14 @@ Steps: 1) search_customer_credit_notes with status UNAPPLIED for the same contac
|
|
|
699
699
|
- Skips lock date validation (opening balances are special).
|
|
700
700
|
- Uses journalEntries (NOT lines \u2014 this is a journal type).`,params:{valueDate:{type:"string",description:"Opening balance date (YYYY-MM-DD)"},journalEntries:tc,currency:ec},required:["valueDate","journalEntries"],group:"journals",readOnly:!1,searchHint:"create transfer trial balance between periods",execute:async(e,t)=>W0(e.client,t)},{name:"delete_journal",description:"Delete a draft journal entry.",params:{resourceId:th},required:["resourceId"],group:"journals",readOnly:!1,searchHint:"permanently delete a draft journal entry",isDestructive:!0,execute:async(e,t)=>V0(e.client,t.resourceId)},{name:"generate_trial_balance",description:"Generate a trial balance report.",params:{endDate:{type:"string",description:"Snapshot date (YYYY-MM-DD)"},currencyCode:{type:"string",description:"Currency override"}},required:["endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate trial balance report for period",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>db(e.client,t)},{name:"generate_balance_sheet",description:"Generate a balance sheet report.",params:{snapshotDate:{type:"string",description:"Snapshot date (YYYY-MM-DD). Defaults to today if omitted."},currencyCode:MJ},required:[],group:"financial_reports",readOnly:!0,searchHint:"generate balance sheet report as at date",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t.snapshotDate??new Date().toISOString().slice(0,10);return pb(e.client,{primarySnapshotDate:r,currencyCode:t.currencyCode})}},{name:"generate_profit_and_loss",description:"Generate a profit & loss (income statement) report.",params:{startDate:{type:"string",description:"Period start (YYYY-MM-DD)"},endDate:{type:"string",description:"Period end (YYYY-MM-DD)"},currencyCode:MJ},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate profit and loss income statement report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>fb(e.client,t)},{name:"generate_cashflow",description:"Generate a cashflow report.",params:{startDate:SSe,endDate:p$},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate cashflow statement report for period",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>mb(e.client,t)},{name:"generate_aged_ar",description:"Generate aged accounts receivable summary.",params:{endDate:p$},required:["endDate"],group:"operational_reports",readOnly:!0,searchHint:"generate aged accounts receivable summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>hb(e.client,t)},{name:"generate_aged_ap",description:"Generate aged accounts payable summary.",params:{endDate:p$},required:["endDate"],group:"operational_reports",readOnly:!0,searchHint:"generate aged accounts payable summary report",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>gb(e.client,t)},{name:"generate_cash_balance",description:"Generate a cash balance report showing cash position at a specific date. PREFERRED for cash position questions \u2014 use this (NOT balance sheet) when asked about total cash, cash on hand, available cash, or cash position across all bank accounts.",params:{endDate:{type:"string",description:"Snapshot date (YYYY-MM-DD)"}},required:["endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate cash balance report across accounts",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>yb(e.client,t)},{name:"generate_general_ledger",description:"Generate a general ledger report.",params:{startDate:{type:"string",description:"Period start (YYYY-MM-DD)"},endDate:{type:"string",description:"Period end (YYYY-MM-DD)"},groupBy:{type:"string",description:"Group by: ACCOUNT (default), TRANSACTION, or CAPSULE"}},required:["startDate","endDate"],group:"financial_reports",readOnly:!0,searchHint:"generate general ledger report for account period",isConcurrencySafe:!0,maxResultSizeChars:1e5,execute:async(e,t)=>{let r=t;return Db(e.client,{...r,groupBy:r.groupBy??"ACCOUNT"})}},{name:"list_bank_accounts",description:"List bank accounts connected to the organization.",params:{},required:[],group:"bank",readOnly:!0,searchHint:"list bank and cash accounts with balances",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>zc(e.client)},gt("list_items","List items (products & services). Returns internalName, itemCode, appliesToSale/Purchase. Paginated \u2014 response includes totalElements. Use limit/offset to page.","items",(e,t,r)=>HD(e,{limit:r,offset:t}),"list products services items with pagination"),Rt({name:"search_items",description:"Search items. Use list_items to search by name (internalName is not a filter field).",group:"items",fields:Wp,defaults:Zp,fetcher:lu,searchHint:"find items products services by status category sale purchase type internalName via list_items"}),{name:"get_item",description:"Get full item details by resourceId.",params:{resourceId:{type:"string",description:"Item resourceId (UUID)"}},required:["resourceId"],group:"items",readOnly:!0,searchHint:"get item product service details by id",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>fp(e.client,t.resourceId)},{name:"create_item",description:`Create a new item. Auto-checks for duplicates by itemCode \u2014 returns existing item if found.
|
|
701
701
|
- saleItemName/purchaseItemName are auto-set from internalName if not provided.
|
|
702
|
-
- Set appliesToSale and/or appliesToPurchase to control where the item can be used.`,params:{itemCode:{type:"string",description:"Unique item code"},internalName:{type:"string",description:"Item name"},appliesToSale:{type:"boolean",description:"Can be used on invoices"},appliesToPurchase:{type:"boolean",description:"Can be used on bills"},salePrice:{type:"number",description:"Default sale price"},purchasePrice:{type:"number",description:"Default purchase price"},saleAccountResourceId:{type:"string",description:"Revenue account for sales"},purchaseAccountResourceId:{type:"string",description:"Expense account for purchases"},customFields:dn},required:["itemCode","internalName"],group:"items",readOnly:!1,searchHint:"create new product or service item for invoicing",execute:async(e,t)=>{let r=t.itemCode,n=await l0(e.client,r);if(n)return{_guard:"duplicate_skipped",message:`Item with code "${r}" already exists.`,existing:n};let{purchasePrice:o,...i}=t,s={...i,...o!==void 0&&{purchaseItemPrice:o}};return mp(e.client,s)}},{name:"update_item",description:"Update an existing item. Only send fields you want to change \u2014 required fields are auto-merged from current state.",params:{resourceId:{type:"string",description:"Item resourceId"},internalName:{type:"string",description:"New name"},itemCode:{type:"string",description:"New code"},salePrice:{type:"number"},purchasePrice:{type:"number"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Status (ACTIVE or INACTIVE)"},customFields:dn},required:["resourceId"],group:"items",readOnly:!1,searchHint:"update existing item name price account details",execute:async(e,t)=>{let{resourceId:r,purchasePrice:n,...o}=t,i={...o,...n!==void 0&&{purchaseItemPrice:n}};return WD(e.client,r,i)}},{name:"delete_item",description:"Delete an item.",params:{resourceId:{type:"string",description:"Item resourceId"}},required:["resourceId"],group:"items",readOnly:!1,searchHint:"permanently delete an item product service",isDestructive:!0,execute:async(e,t)=>ZD(e.client,t.resourceId)},{name:"bulk_upsert_items",description:"
|
|
702
|
+
- Set appliesToSale and/or appliesToPurchase to control where the item can be used.`,params:{itemCode:{type:"string",description:"Unique item code"},internalName:{type:"string",description:"Item name"},appliesToSale:{type:"boolean",description:"Can be used on invoices"},appliesToPurchase:{type:"boolean",description:"Can be used on bills"},salePrice:{type:"number",description:"Default sale price"},purchasePrice:{type:"number",description:"Default purchase price"},saleAccountResourceId:{type:"string",description:"Revenue account for sales"},purchaseAccountResourceId:{type:"string",description:"Expense account for purchases"},customFields:dn},required:["itemCode","internalName"],group:"items",readOnly:!1,searchHint:"create new product or service item for invoicing",execute:async(e,t)=>{let r=t.itemCode,n=await l0(e.client,r);if(n)return{_guard:"duplicate_skipped",message:`Item with code "${r}" already exists.`,existing:n};let{purchasePrice:o,...i}=t,s={...i,...o!==void 0&&{purchaseItemPrice:o}};return mp(e.client,s)}},{name:"update_item",description:"Update an existing item. Only send fields you want to change \u2014 required fields are auto-merged from current state.",params:{resourceId:{type:"string",description:"Item resourceId"},internalName:{type:"string",description:"New name"},itemCode:{type:"string",description:"New code"},salePrice:{type:"number"},purchasePrice:{type:"number"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Status (ACTIVE or INACTIVE)"},customFields:dn},required:["resourceId"],group:"items",readOnly:!1,searchHint:"update existing item name price account details",execute:async(e,t)=>{let{resourceId:r,purchasePrice:n,...o}=t,i={...o,...n!==void 0&&{purchaseItemPrice:n}};return WD(e.client,r,i)}},{name:"delete_item",description:"Delete an item.",params:{resourceId:{type:"string",description:"Item resourceId"}},required:["resourceId"],group:"items",readOnly:!1,searchHint:"permanently delete an item product service",isDestructive:!0,execute:async(e,t)=>ZD(e.client,t.resourceId)},{name:"bulk_upsert_items",description:"Max 500 items per call. Provide resourceId per item to update (partial \u2014 only changed fields needed, server preserves existing values). Omit resourceId to create (defaults: status=ACTIVE, itemCategory=NON_INVENTORY).",params:{items:{type:"array",description:"Array of items to create or update",items:{type:"object",properties:{resourceId:{type:"string",description:"Item resourceId (omit for create, provide for update)"},itemCode:{type:"string",description:"Unique item code (required for create)"},internalName:{type:"string",description:"Internal name (required for create)"},unit:{type:"string",description:"Unit of measure"},status:{type:"string",description:"Record status",enum:["ACTIVE","INACTIVE"]},appliesToSale:{type:"boolean",description:"Whether item applies to sales"},saleItemName:{type:"string",description:"Sale display name"},salePrice:{type:"number",description:"Sale price"},saleAccountResourceId:{type:"string",description:"Sale account resourceId"},saleTaxProfileResourceId:{type:"string",description:"Sale tax profile resourceId"},appliesToPurchase:{type:"boolean",description:"Whether item applies to purchases"},purchaseItemName:{type:"string",description:"Purchase display name"},purchasePrice:{type:"number",description:"Purchase price"},purchaseAccountResourceId:{type:"string",description:"Purchase account resourceId"},purchaseTaxProfileResourceId:{type:"string",description:"Purchase tax profile resourceId"},inventory:{type:"boolean",description:"Whether this is an inventory item"},cogsResourceId:{type:"string",description:"COGS account resourceId"},costingMethod:{type:"string",description:"Costing method",enum:["FIXED","WAC"]},itemCategory:{type:"string",description:"Item category",enum:["INVENTORY","NON_INVENTORY"]},blockInsufficientDeductions:{type:"boolean",description:"Block insufficient stock deductions"}}}}},required:["items"],group:"items",readOnly:!1,searchHint:"bulk create or update multiple items at once",execute:async(e,t)=>{let r=t.items.map(({purchasePrice:o,...i})=>({...i,...o!==void 0&&{purchaseItemPrice:o}}));return(await KD(e.client,r)).data}},gt("list_tags","List tags used for transaction categorization. Paginated \u2014 response includes totalElements. Use limit/offset to page.","tags",(e,t,r)=>hu(e,{limit:r,offset:t}),"list all tags for categorization tracking"),Rt({name:"search_tags",description:"Search tags.",group:"tags",fields:sf,defaults:af,fetcher:a0,searchHint:"find tags labels categorization by name"}),{name:"create_tag",description:"Create a new tag. Automatically reuses existing tag if one with the same name exists.",params:{name:{type:"string",description:"Tag name"}},required:["name"],group:"tags",readOnly:!1,searchHint:"create new tag for transaction categorization",execute:async(e,t)=>{let r=t.name,n=await f0(e.client,r);return n?{data:n,_note:`Tag "${r}" already exists \u2014 reusing.`}:yp(e.client,{name:r})}},Yn("get_tag","Get a tag by resourceId.","tags",(e,t)=>s0(e,t),"get tag details by resource id"),{name:"update_tag",description:"Rename a tag.",params:{resourceId:{type:"string",description:"Tag resourceId"},name:{type:"string",description:"New tag name"}},required:["resourceId","name"],group:"tags",readOnly:!1,searchHint:"update rename existing tag name",execute:async(e,t)=>c0(e.client,t.resourceId,{name:t.name})},{name:"delete_tag",description:"Delete a tag.",params:{resourceId:{type:"string",description:"Tag resourceId"}},required:["resourceId"],group:"tags",readOnly:!1,searchHint:"permanently delete a tag",isDestructive:!0,execute:async(e,t)=>u0(e.client,t.resourceId)},{name:"list_capsule_types",description:"List capsule types (e.g., PREPAID_EXPENSE, DEFERRED_REVENUE). Use to get capsuleTypeResourceId before creating capsules.",params:{},required:[],group:"capsules",readOnly:!0,searchHint:"list capsule types for transaction grouping",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>du(e.client)},gt("list_capsules","List capsules (transaction groupings for amortization, deferred revenue, etc.). Paginated \u2014 response includes totalElements. Use limit/offset to page.","capsules",(e,t,r)=>XD(e,{limit:r,offset:t}),"list capsules grouped transactions with pagination"),Rt({name:"search_capsules",description:"Search capsules.",group:"capsules",fields:lf,defaults:df,fetcher:pu,searchHint:"find capsules workflow groups by title status type capsuleType"}),{name:"get_capsule",description:"Get full capsule details by resourceId.",params:{resourceId:{type:"string",description:"Capsule resourceId (UUID)"}},required:["resourceId"],group:"capsules",readOnly:!0,searchHint:"get capsule details grouped transactions",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>gp(e.client,t.resourceId)},{name:"create_capsule",description:"Create a new capsule. List capsule types first to get the capsuleTypeResourceId.",params:{capsuleTypeResourceId:{type:"string",description:"Capsule type resourceId (from list_capsule_types)"},title:{type:"string",description:"Capsule title"},description:{type:"string",description:"Capsule description"}},required:["capsuleTypeResourceId","title"],group:"capsules",readOnly:!1,searchHint:"create new capsule to group related transactions",execute:async(e,t)=>{let r=t.title,n=await qz(e.client,r);return n?{_guard:"duplicate_skipped",message:`Capsule "${r}" already exists.`,existing:n}:Oa(e.client,{capsuleTypeResourceId:t.capsuleTypeResourceId,title:r,description:t.description})}},{name:"update_capsule",description:"Update a capsule title or description. Required fields are auto-merged from current state.",params:{resourceId:{type:"string",description:"Capsule resourceId"},title:{type:"string",description:"New title"},description:{type:"string",description:"New description"}},required:["resourceId"],group:"capsules",readOnly:!1,searchHint:"update capsule title description details",execute:async(e,t)=>{let{resourceId:r,...n}=t;return QD(e.client,r,n)}},{name:"delete_capsule",description:"Delete a capsule.",params:{resourceId:{type:"string",description:"Capsule resourceId"}},required:["resourceId"],group:"capsules",readOnly:!1,searchHint:"permanently delete a capsule group",isDestructive:!0,execute:async(e,t)=>e0(e.client,t.resourceId)},gt("list_customer_credit_notes","List customer credit notes (AR adjustments/refunds). Paginated \u2014 response includes totalElements. Use limit/offset to page.","customer_credit_notes",(e,t,r)=>Tb(e,{limit:r,offset:t}),"list customer credit notes with status pagination"),Rt({name:"search_customer_credit_notes",description:"Search customer credit notes. Status: DRAFT, UNAPPLIED, PARTIALLY_APPLIED, APPLIED, VOID.",group:"customer_credit_notes",fields:vs,defaults:Ou,fetcher:Tf,searchHint:"find customer credit notes refunds CN by reference status contact tag"}),{name:"get_customer_credit_note",description:"Get full customer credit note details including line items.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"}},required:["resourceId"],group:"customer_credit_notes",readOnly:!0,searchHint:"get customer credit note details line items",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Ro(e.client,t.resourceId)},{name:"create_customer_credit_note",description:`Create a customer credit note. Saves as draft by default.
|
|
703
703
|
- Status when finalized is UNAPPLIED (not APPROVED).
|
|
704
704
|
- Line items use "name" for item description.
|
|
705
705
|
- contactResourceId required \u2014 search contacts first.
|
|
706
706
|
- reference MUST be unique \u2014 generate one with a timestamp if user doesn't specify.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Customer contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:rc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:ec,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:Dr,tag:dl,customFields:dn},required:["valueDate","contactResourceId","lineItems"],group:"customer_credit_notes",readOnly:!1,searchHint:"create new customer credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`CCN-${Date.now()}`),Of(e.client,i)}},{name:"delete_customer_credit_note",description:"Delete a draft customer credit note.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"}},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"permanently delete draft customer credit note",isDestructive:!0,execute:async(e,t)=>$b(e.client,t.resourceId)},{name:"update_customer_credit_note",description:'Update a draft customer credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Customer credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr,tag:dl,customFields:dn},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"update customer credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return Ob(e.client,r,s)}},{name:"finalize_customer_credit_note",description:"Finalize a draft customer credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Customer credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr},required:["resourceId"],group:"customer_credit_notes",readOnly:!1,searchHint:"approve finalize customer credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await eh(e.client,"customer_credit_note",r,i);return $f(e.client,r,s)}},{name:"create_customer_credit_note_refund",description:"Record a refund payment against a customer credit note.",params:{creditNoteId:{type:"string",description:"Customer credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Qm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"customer_credit_notes",readOnly:!1,searchHint:"refund customer credit note to bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return Rf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_customer_credit_note_refunds",description:"List refund payments for a customer credit note.",params:{creditNoteId:{type:"string",description:"Customer credit note resourceId"}},required:["creditNoteId"],group:"customer_credit_notes",readOnly:!0,searchHint:"list refunds on a customer credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>Rb(e.client,t.creditNoteId)},gt("list_supplier_credit_notes","List supplier credit notes (AP adjustments/refunds). Paginated \u2014 response includes totalElements. Use limit/offset to page.","supplier_credit_notes",(e,t,r)=>Fb(e,{limit:r,offset:t}),"list supplier credit notes with status pagination"),Rt({name:"search_supplier_credit_notes",description:"Search supplier credit notes. Status: DRAFT, UNAPPLIED, PARTIALLY_APPLIED, APPLIED, VOID.",group:"supplier_credit_notes",fields:vs,defaults:Bp,fetcher:Nf,searchHint:"find supplier credit notes refunds CN by reference status contact tag"}),{name:"get_supplier_credit_note",description:"Get full supplier credit note details including line items.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"get supplier credit note details line items",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>No(e.client,t.resourceId)},{name:"create_supplier_credit_note",description:`Create a supplier credit note. Saves as draft by default.
|
|
707
707
|
- Status when finalized is UNAPPLIED (not APPROVED).
|
|
708
708
|
- Line items use "name" for item description.
|
|
709
|
-
- contactResourceId required \u2014 search contacts first.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Supplier contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:rc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:ec,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:Dr,tag:dl,customFields:dn},required:["valueDate","contactResourceId","lineItems"],group:"supplier_credit_notes",readOnly:!1,searchHint:"create new supplier credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`SCN-${Date.now()}`),kf(e.client,i)}},{name:"delete_supplier_credit_note",description:"Delete a draft supplier credit note.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"permanently delete draft supplier credit note",isDestructive:!0,execute:async(e,t)=>Lb(e.client,t.resourceId)},{name:"update_supplier_credit_note",description:'Update a draft supplier credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr,tag:dl,customFields:dn},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"update supplier credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return Pb(e.client,r,s)}},{name:"finalize_supplier_credit_note",description:"Finalize a draft supplier credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"approve finalize supplier credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await eh(e.client,"supplier_credit_note",r,i);return Ff(e.client,r,s)}},{name:"create_supplier_credit_note_refund",description:"Record a refund payment against a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Qm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"supplier_credit_notes",readOnly:!1,searchHint:"refund supplier credit note from bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return Pf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_supplier_credit_note_refunds",description:"List refund payments for a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"}},required:["creditNoteId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"list refunds on a supplier credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>jb(e.client,t.creditNoteId)},{name:"list_currencies",description:"List currencies enabled for the organization. Returns code, name, symbol, isBaseCurrency.",params:{},required:[],group:"currencies",readOnly:!0,searchHint:"list currencies enabled active organization base currency code symbol",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>Lf(e.client)},{name:"add_currency",description:"Enable one or more currencies for the organization.",params:{currencies:{type:"array",items:{type:"string"},description:'Currency codes to add (e.g., ["USD", "EUR"])'}},required:["currencies"],group:"currencies",readOnly:!1,searchHint:"add new currency to organization",execute:async(e,t)=>{let r=t.currencies,n=await Lf(e.client),o=new Set(n.data.map(c=>c.currencyCode.toUpperCase())),i=r.filter(c=>o.has(c.toUpperCase())),s=r.filter(c=>!o.has(c.toUpperCase()));if(s.length===0)return{_guard:"duplicate_skipped",message:`All currencies already enabled: ${r.join(", ")}.`,existing:i};let a=await Bb(e.client,s);return i.length>0?{...a,_note:`Skipped already-enabled: ${i.join(", ")}`}:a}},{name:"list_currency_rates",description:"List exchange rates for a specific currency. IMPORTANT: You MUST call list_currencies first to discover which currencies the org has enabled \u2014 never guess or assume currency codes.",params:{currencyCode:{type:"string",description:'Currency code (e.g., "USD")'},...h$},required:["currencyCode"],group:"currencies",readOnly:!0,searchHint:"list exchange rates for a currency pair",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>{let{limit:r,offset:n}=GJ(t),o=t.currencyCode;return Lp((i,s)=>Ub(e.client,o,{limit:s,offset:i}),r,n,100)}},{name:"add_currency_rate",description:'Add or set an exchange rate for a currency. ALWAYS use this tool even when the user says "update rate" \u2014 it handles both new and existing rates. Rate is relative to the base currency. Call list_currencies first to get valid currency codes.',params:{currencyCode:{type:"string",description:"Currency code"},rate:{type:"number",description:"Exchange rate (e.g., 1.35 for 1 USD = 1.35 SGD)"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"add new exchange rate for currency pair",execute:async(e,t)=>qb(e.client,t.currencyCode,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"update_currency_rate",description:'Update an EXISTING exchange rate record by its resourceId. Requires the rate resourceId from list_currency_rates. WARNING: If the user says "update the rate" or "set the rate", they almost always mean add_currency_rate (which creates/overwrites for a date). Only use this tool when explicitly modifying an existing rate record by ID.',params:{currencyCode:{type:"string",description:"Currency code"},resourceId:{type:"string",description:"Rate resourceId"},rate:{type:"number",description:"New exchange rate"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","resourceId","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"update existing exchange rate value",execute:async(e,t)=>zb(e.client,t.currencyCode,t.resourceId,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"start_currency_rates_import_job",description:"Start an async job to import currency rates from a CSV file URL.",params:{currencyCode:{type:"string",description:"Currency code"},csvUrl:{type:"string",description:"URL of the CSV file to import"}},required:["currencyCode","csvUrl"],group:"currencies",readOnly:!1,searchHint:"import exchange rates from external source",execute:async(e,t)=>Yb(e.client,t.currencyCode,t.csvUrl)},{name:"get_currency_rates_import_job_status",description:"Check the status of a currency rates import job.",params:{jobId:{type:"string",description:"Job ID from start_currency_rates_import_job"}},required:["jobId"],group:"currencies",readOnly:!0,searchHint:"check status of currency rates import job",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Jb(e.client,t.jobId)},{name:"bulk_upsert_currency_rates",description:"Create exchange rates in bulk (max 500 per call). Auto-enables currencies not yet enabled in the org \u2014 no need to call add_currency first. Requires rateDirection per rate. Response surfaces per-row failures: `failedRows[]` (each with rowIndex, columnName, columnValue, errorCode, errorMessage) + `failedCount` alongside `resourceIds[]` for successful inserts. Omitting `rateApplicableTo` defaults it to `rateApplicableFrom - 0.999ms` (no temporal gap).",params:{rates:{type:"array",description:"Array of exchange rates to create",items:{type:"object",properties:{sourceCurrencyCode:{type:"string",description:"Source currency code (ISO 4217, e.g. USD, EUR)"},rate:{type:"number",description:"Exchange rate value (must be > 0)"},rateDirection:{type:"string",description:"Rate direction",enum:["FUNCTIONAL_TO_SOURCE","SOURCE_TO_FUNCTIONAL"]},rateApplicableFrom:{type:"string",description:"Rate start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"Rate end date (YYYY-MM-DD, optional)"}},required:["sourceCurrencyCode","rate","rateDirection","rateApplicableFrom"]}}},required:["rates"],group:"currencies",readOnly:!1,searchHint:"bulk create or update multiple currency rates",execute:async(e,t)=>(await Gb(e.client,t.rates)).data},gt("list_tax_profiles","List tax profiles (GST, VAT, etc.). Returns name, rate, tax type.","tax_profiles",(e,t,r)=>fu(e,{limit:r,offset:t}),"list tax profiles GST VAT rates"),gt("list_tax_types","List available tax types. Use the tax type code when creating tax profiles.","tax_profiles",(e,t,r)=>t0(e,{limit:r,offset:t}),"list available tax types for profile creation"),{name:"create_tax_profile",description:"Create a new tax profile. List tax types first to get the taxTypeCode. Automatically checks for duplicates by name \u2014 returns existing profile if found.",params:{name:{type:"string",description:'Tax profile name (e.g., "GST 9%")'},taxRate:{type:"number",description:"Tax rate as percentage (e.g., 9 for 9%)"},taxTypeCode:{type:"string",description:"Tax type code (from list_tax_types)"}},required:["name","taxRate","taxTypeCode"],group:"tax_profiles",readOnly:!1,searchHint:"create new tax profile GST VAT rate",execute:async(e,t)=>{let r=t.name,n=await p0(e.client,r);return n?{_guard:"duplicate_skipped",message:`Tax profile "${r}" already exists.`,existing:n}:r0(e.client,{name:r,taxRate:t.taxRate,taxTypeCode:t.taxTypeCode})}},gt("list_cash_in","List cash-in entries (direct cash receipts). Paginated.","cash_entries",(e,t,r)=>Q0(e,{limit:r,offset:t}),"list cash in receipt entries with pagination"),{name:"create_cash_in",description:`Record money received INTO a bank account from an EXTERNAL source (customer payment, refund received, deposit). For inter-account moves use create_cash_transfer.
|
|
709
|
+
- contactResourceId required \u2014 search contacts first.`,params:{reference:{type:"string",description:"Credit note reference number"},valueDate:{type:"string",description:"Credit note date (YYYY-MM-DD)"},contactResourceId:{type:"string",description:"Supplier contact resourceId"},lineItems:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Line item description"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:rc},required:["name","quantity","unitPrice"]},description:"Credit note line items"},currency:ec,saveAsDraft:{type:"boolean",description:"Save as draft (default true)"},notes:Dr,tag:dl,customFields:dn},required:["valueDate","contactResourceId","lineItems"],group:"supplier_credit_notes",readOnly:!1,searchHint:"create new supplier credit note draft",execute:async(e,t)=>{let{notes:r,tag:n,...o}=t,i={...o,...r!==void 0&&{invoiceNotes:r},...n!==void 0&&{tags:[n]}};return i.reference||(i.reference=`SCN-${Date.now()}`),kf(e.client,i)}},{name:"delete_supplier_credit_note",description:"Delete a draft supplier credit note.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"}},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"permanently delete draft supplier credit note",isDestructive:!0,execute:async(e,t)=>Lb(e.client,t.resourceId)},{name:"update_supplier_credit_note",description:'Update a draft supplier credit note (change amount, line items, contact, date, notes). Use when the user says "update", "change", "fix", or "correct" a credit note.',params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr,tag:dl,customFields:dn},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"update supplier credit note lines reference",execute:async(e,t)=>{let{resourceId:r,notes:n,tag:o,...i}=t,s={...i,...n!==void 0&&{invoiceNotes:n},...o!==void 0&&{tags:[o]}};return Pb(e.client,r,s)}},{name:"finalize_supplier_credit_note",description:"Finalize a draft supplier credit note (set saveAsDraft=false). Status becomes UNAPPLIED.",params:{resourceId:{type:"string",description:"Supplier credit note resourceId"},reference:yo,valueDate:go,lineItems:fi,notes:Dr},required:["resourceId"],group:"supplier_credit_notes",readOnly:!1,searchHint:"approve finalize supplier credit note",isDestructive:!0,execute:async(e,t)=>{let{resourceId:r,notes:n,...o}=t,i={...o,...n!==void 0&&{invoiceNotes:n}},s=await eh(e.client,"supplier_credit_note",r,i);return Ff(e.client,r,s)}},{name:"create_supplier_credit_note_refund",description:"Record a refund payment against a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"},paymentAmount:{type:"number",description:"Refund amount"},transactionAmount:{type:"number",description:"Amount in credit note currency (defaults to paymentAmount for same-currency)"},accountResourceId:{type:"string",description:"Bank/cash account resourceId"},valueDate:{type:"string",description:"Payment date (YYYY-MM-DD)"},reference:{type:"string",description:"Payment reference"},paymentMethod:Qm},required:["creditNoteId","paymentAmount","accountResourceId","valueDate"],group:"supplier_credit_notes",readOnly:!1,searchHint:"refund supplier credit note from bank account",isDestructive:!0,execute:async(e,t)=>{let r=Number(t.paymentAmount);if(!Number.isFinite(r)||r<=0)throw new Error("paymentAmount must be a positive number");let n=Number(t.transactionAmount??r);if(!Number.isFinite(n)||n<=0)throw new Error("transactionAmount must be a positive number");return Pf(e.client,t.creditNoteId,{paymentAmount:r,transactionAmount:n,accountResourceId:t.accountResourceId,valueDate:t.valueDate,dueDate:t.valueDate,reference:t.reference??"",paymentMethod:t.paymentMethod??"BANK_TRANSFER",saveAsDraft:!1})}},{name:"list_supplier_credit_note_refunds",description:"List refund payments for a supplier credit note.",params:{creditNoteId:{type:"string",description:"Supplier credit note resourceId"}},required:["creditNoteId"],group:"supplier_credit_notes",readOnly:!0,searchHint:"list refunds on a supplier credit note",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>jb(e.client,t.creditNoteId)},{name:"list_currencies",description:"List currencies enabled for the organization. Returns code, name, symbol, isBaseCurrency.",params:{},required:[],group:"currencies",readOnly:!0,searchHint:"list currencies enabled active organization base currency code symbol",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async e=>Lf(e.client)},{name:"add_currency",description:"Enable one or more currencies for the organization.",params:{currencies:{type:"array",items:{type:"string"},description:'Currency codes to add (e.g., ["USD", "EUR"])'}},required:["currencies"],group:"currencies",readOnly:!1,searchHint:"add new currency to organization",execute:async(e,t)=>{let r=t.currencies,n=await Lf(e.client),o=new Set(n.data.map(c=>c.currencyCode.toUpperCase())),i=r.filter(c=>o.has(c.toUpperCase())),s=r.filter(c=>!o.has(c.toUpperCase()));if(s.length===0)return{_guard:"duplicate_skipped",message:`All currencies already enabled: ${r.join(", ")}.`,existing:i};let a=await Bb(e.client,s);return i.length>0?{...a,_note:`Skipped already-enabled: ${i.join(", ")}`}:a}},{name:"list_currency_rates",description:"List exchange rates for a specific currency. IMPORTANT: You MUST call list_currencies first to discover which currencies the org has enabled \u2014 never guess or assume currency codes.",params:{currencyCode:{type:"string",description:'Currency code (e.g., "USD")'},...h$},required:["currencyCode"],group:"currencies",readOnly:!0,searchHint:"list exchange rates for a currency pair",isConcurrencySafe:!0,maxResultSizeChars:5e4,execute:async(e,t)=>{let{limit:r,offset:n}=GJ(t),o=t.currencyCode;return Lp((i,s)=>Ub(e.client,o,{limit:s,offset:i}),r,n,100)}},{name:"add_currency_rate",description:'Add or set an exchange rate for a currency. ALWAYS use this tool even when the user says "update rate" \u2014 it handles both new and existing rates. Rate is relative to the base currency. Call list_currencies first to get valid currency codes.',params:{currencyCode:{type:"string",description:"Currency code"},rate:{type:"number",description:"Exchange rate (e.g., 1.35 for 1 USD = 1.35 SGD)"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"add new exchange rate for currency pair",execute:async(e,t)=>qb(e.client,t.currencyCode,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"update_currency_rate",description:'Update an EXISTING exchange rate record by its resourceId. Requires the rate resourceId from list_currency_rates. WARNING: If the user says "update the rate" or "set the rate", they almost always mean add_currency_rate (which creates/overwrites for a date). Only use this tool when explicitly modifying an existing rate record by ID.',params:{currencyCode:{type:"string",description:"Currency code"},resourceId:{type:"string",description:"Rate resourceId"},rate:{type:"number",description:"New exchange rate"},rateApplicableFrom:{type:"string",description:"Start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"End date (YYYY-MM-DD, optional)"}},required:["currencyCode","resourceId","rate","rateApplicableFrom"],group:"currencies",readOnly:!1,searchHint:"update existing exchange rate value",execute:async(e,t)=>zb(e.client,t.currencyCode,t.resourceId,{rate:t.rate,rateApplicableFrom:t.rateApplicableFrom,rateApplicableTo:t.rateApplicableTo})},{name:"start_currency_rates_import_job",description:"Start an async job to import currency rates from a CSV file URL.",params:{currencyCode:{type:"string",description:"Currency code"},csvUrl:{type:"string",description:"URL of the CSV file to import"}},required:["currencyCode","csvUrl"],group:"currencies",readOnly:!1,searchHint:"import exchange rates from external source",execute:async(e,t)=>Yb(e.client,t.currencyCode,t.csvUrl)},{name:"get_currency_rates_import_job_status",description:"Check the status of a currency rates import job.",params:{jobId:{type:"string",description:"Job ID from start_currency_rates_import_job"}},required:["jobId"],group:"currencies",readOnly:!0,searchHint:"check status of currency rates import job",isConcurrencySafe:!0,maxResultSizeChars:2e4,execute:async(e,t)=>Jb(e.client,t.jobId)},{name:"bulk_upsert_currency_rates",description:"Max 500 exchange rates per call. Auto-enables currencies not yet enabled in the org \u2014 no need to call add_currency first. Requires rateDirection per rate. Response surfaces per-row failures: `failedRows[]` (each with rowIndex, columnName, columnValue, errorCode, errorMessage) + `failedCount` alongside `resourceIds[]` for successful inserts. Omitting `rateApplicableTo` defaults it to `rateApplicableFrom - 0.999ms` (no temporal gap).",params:{rates:{type:"array",description:"Array of exchange rates to create",items:{type:"object",properties:{sourceCurrencyCode:{type:"string",description:"Source currency code (ISO 4217, e.g. USD, EUR)"},rate:{type:"number",description:"Exchange rate value (must be > 0)"},rateDirection:{type:"string",description:"Rate direction",enum:["FUNCTIONAL_TO_SOURCE","SOURCE_TO_FUNCTIONAL"]},rateApplicableFrom:{type:"string",description:"Rate start date (YYYY-MM-DD)"},rateApplicableTo:{type:"string",description:"Rate end date (YYYY-MM-DD, optional)"}},required:["sourceCurrencyCode","rate","rateDirection","rateApplicableFrom"]}}},required:["rates"],group:"currencies",readOnly:!1,searchHint:"bulk create or update multiple currency rates",execute:async(e,t)=>(await Gb(e.client,t.rates)).data},gt("list_tax_profiles","List tax profiles (GST, VAT, etc.). Returns name, rate, tax type.","tax_profiles",(e,t,r)=>fu(e,{limit:r,offset:t}),"list tax profiles GST VAT rates"),gt("list_tax_types","List available tax types. Use the tax type code when creating tax profiles.","tax_profiles",(e,t,r)=>t0(e,{limit:r,offset:t}),"list available tax types for profile creation"),{name:"create_tax_profile",description:"Create a new tax profile. List tax types first to get the taxTypeCode. Automatically checks for duplicates by name \u2014 returns existing profile if found.",params:{name:{type:"string",description:'Tax profile name (e.g., "GST 9%")'},taxRate:{type:"number",description:"Tax rate as percentage (e.g., 9 for 9%)"},taxTypeCode:{type:"string",description:"Tax type code (from list_tax_types)"}},required:["name","taxRate","taxTypeCode"],group:"tax_profiles",readOnly:!1,searchHint:"create new tax profile GST VAT rate",execute:async(e,t)=>{let r=t.name,n=await p0(e.client,r);return n?{_guard:"duplicate_skipped",message:`Tax profile "${r}" already exists.`,existing:n}:r0(e.client,{name:r,taxRate:t.taxRate,taxTypeCode:t.taxTypeCode})}},gt("list_cash_in","List cash-in entries (direct cash receipts). Paginated.","cash_entries",(e,t,r)=>Q0(e,{limit:r,offset:t}),"list cash in receipt entries with pagination"),{name:"create_cash_in",description:`Record money received INTO a bank account from an EXTERNAL source (customer payment, refund received, deposit). For inter-account moves use create_cash_transfer.
|
|
710
710
|
|
|
711
711
|
accountResourceId MUST be a Bank/Cash account (from list_bank_accounts) \u2014 any other type fails. Cannot appear in lines (API enforces separation).
|
|
712
712
|
|
|
@@ -807,11 +807,11 @@ Response: { updated, failed: [{resourceId, error, errorCode}] }. HTTP 207 = part
|
|
|
807
807
|
|
|
808
808
|
DO NOT use this for analytical / audit reports, financial statements, aging, summary reports, or statement-of-account \u2014 those go through download_export.`,params:{entityType:m$,query:BJ,filter:UJ,columns:qJ,sort:zJ},required:["entityType"],group:"export_records",readOnly:!0,isConcurrencySafe:!0,searchHint:"export records download xlsx file url",execute:async(e,t)=>E_(e.client,{entityType:t.entityType,outputFormat:"XLSX",query:t.query,filter:t.filter,columns:t.columns,sort:t.sort})},Rt({name:"search_background_jobs",description:"Search and poll background jobs. ANY operation that returns a jobId (bulk_upsert_contacts, bulk_upsert_items, bank statement import, magic file processing, etc.) can be tracked here. Filter by resourceId (the jobId value) to poll a specific job. Poll until status is SUCCESS, FAILED, or PARTIAL_SUCCESS. Use processedCount/failedCount/totalRecords for progress. IMPORTANT: filter by resourceId field, NOT jobId \u2014 they differ.",group:"background_jobs",fields:tf,defaults:rf,fetcher:Zm,searchHint:"poll background job status by jobId type status"}),{name:"bulk_upsert_contacts",description:`Bulk create/update contacts (max 500). resourceId per row \u2192 update (partial; omitted fields preserve existing). Omit resourceId \u2192 create. ${Bo} Per-row failures in errorDetails (NOT failedRows \u2014 that's the sync pattern). On PARTIAL_SUCCESS: succeeded rows are committed; re-submit only failed rowIndex entries.
|
|
809
809
|
|
|
810
|
-
Whole-batch 422 (validate before submit): (1) each contact must have at least one of customer:true OR supplier:true (after defaults + backfill); (2) emailList unique within a contact (case-insensitive after trim); (3) paymentTerms.value must be positive integer when paymentTerms.name != "CUSTOM"; (4) no duplicate names within batch (after whitespace+case normalize); (5) billingAddress / shippingAddress: addressLine1 required when address object provided.`,params:{contacts:{type:"array",description:"Array of contacts to create or update (max 500)",items:{type:"object",properties:{resourceId:{type:"string",description:"Contact resourceId (omit for create, provide UUID for update)"},billingName:{type:"string",description:"Billing name (required for create)"},name:{type:"string",description:"Display name (defaults to billingName)"},emails:{type:"array",items:{type:"string"},description:"Email addresses"},customer:{type:"boolean",description:"Mark as customer"},supplier:{type:"boolean",description:"Mark as supplier"},taxId:{type:"string",description:"Tax ID / GST registration number"},taxIdType:{type:"string",description:"Tax ID type (e.g., GST, VAT)"},registrationNumber:{type:"string",description:"Business registration number"},currencyCode:{type:"string",description:"Default currency code (e.g., SGD)"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Contact status"},paymentTerms:{type:"number",description:"Payment terms in days (e.g., 30 for Net 30)"},notes:{type:"string",description:"Internal notes"},billingAddress:{type:"object",description:"Billing address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}},shippingAddress:{type:"object",description:"Shipping address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}}}}}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create update contacts upsert",execute:async(e,t)=>(er(t.contacts,"contacts"),Ly(e.client,t.contacts))},{name:"bulk_upsert_invoices",description:`
|
|
810
|
+
Whole-batch 422 (validate before submit): (1) each contact must have at least one of customer:true OR supplier:true (after defaults + backfill); (2) emailList unique within a contact (case-insensitive after trim); (3) paymentTerms.value must be positive integer when paymentTerms.name != "CUSTOM"; (4) no duplicate names within batch (after whitespace+case normalize); (5) billingAddress / shippingAddress: addressLine1 required when address object provided.`,params:{contacts:{type:"array",description:"Array of contacts to create or update (max 500)",items:{type:"object",properties:{resourceId:{type:"string",description:"Contact resourceId (omit for create, provide UUID for update)"},billingName:{type:"string",description:"Billing name (required for create)"},name:{type:"string",description:"Display name (defaults to billingName)"},emails:{type:"array",items:{type:"string"},description:"Email addresses"},customer:{type:"boolean",description:"Mark as customer"},supplier:{type:"boolean",description:"Mark as supplier"},taxId:{type:"string",description:"Tax ID / GST registration number"},taxIdType:{type:"string",description:"Tax ID type (e.g., GST, VAT)"},registrationNumber:{type:"string",description:"Business registration number"},currencyCode:{type:"string",description:"Default currency code (e.g., SGD)"},status:{type:"string",enum:["ACTIVE","INACTIVE"],description:"Contact status"},paymentTerms:{type:"number",description:"Payment terms in days (e.g., 30 for Net 30)"},notes:{type:"string",description:"Internal notes"},billingAddress:{type:"object",description:"Billing address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}},shippingAddress:{type:"object",description:"Shipping address",properties:{address:{type:"string"},city:{type:"string"},state:{type:"string"},postalCode:{type:"string"},country:{type:"string"}}}}}}},required:["contacts"],group:"contacts",readOnly:!1,searchHint:"bulk create update contacts upsert",execute:async(e,t)=>(er(t.contacts,"contacts"),Ly(e.client,t.contacts))},{name:"bulk_upsert_invoices",description:`Max 500 invoices per call. FLAT shape \u2014 ONE line per invoice via itemDescription + totalAmount + invoiceAccountResourceId at row level. For multi-line, use bulk_upsert_invoice_line_items (nested lineItems[]).
|
|
811
811
|
|
|
812
812
|
Natural key: invoiceReference (rows sharing one within a batch are MERGED \u2014 last wins). resourceId per row \u2192 update by UUID; omit \u2192 upsert by invoiceReference.
|
|
813
813
|
|
|
814
|
-
ASYNC: returns jobId \u2192 poll search_background_jobs(filter:{resourceId:{eq:jobId}}); PARTIAL_SUCCESS \u2192 data[0].errorDetails. Dates ISO 8601 (YYYY-MM-DD); dateFormat field removed.`,params:{invoices:{type:"array",description:"Array of invoices to create or update (max 500). Each row needs at least: invoiceReference, contactResourceId, valueDate, totalAmount, invoiceAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string",description:"Optional caller-supplied row index for error reporting"},resourceId:{type:"string",description:"Invoice resourceId (UUID) \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key (e.g., INV-2025-001) \u2014 required"},contactResourceId:{type:"string",description:"Customer contact UUID \u2014 required"},valueDate:{type:"string",description:"Invoice date YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"Due date YYYY-MM-DD"},totalAmount:{type:"number",description:"Total amount (BigDecimal)"},currencyCode:{type:"string",description:"Currency (e.g., SGD)"},invoiceAccountResourceId:{type:"string",description:"Revenue account UUID"},itemDescription:{type:"string",description:"Single-line item description"},internalNotes:{type:"string",description:"Internal notes"},tags:{type:"array",items:{type:"string"},description:"Tag resourceIds"}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk create update invoices upsert import migrate",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),B0(e.client,r)}},{name:"bulk_upsert_invoice_line_items",description:`Create or update invoices with nested line items in bulk (max 500 invoices per call). Each row carries lineItems[] under its parent invoice (scoped by invoiceReference). ${Bo} Dates are ISO 8601 only.`,params:{invoices:{type:"array",description:"Array of invoices with line items (max 500). Each invoice row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string",description:"Invoice resourceId \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"YYYY-MM-DD"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",description:"Line items belonging to this invoice",items:{type:"object",properties:{itemDescription:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string",description:"Unit of measure (pcs, kg, etc.)"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Revenue account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk invoices line items multi-line upsert import",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),U0(e.client,r)}},{name:"bulk_upsert_bills",description:`Create or update bills in bulk (max 500 per call). FLAT shape: ONE line per bill via \`itemDescription\` + \`totalAmount\` + \`billAccountResourceId\` at row level. For multi-line bills use \`bulk_upsert_bill_line_items\` instead \u2014 that variant takes nested \`lineItems[]\`. Natural key: \`billReference\` (rows sharing one within a batch are MERGED \u2014 last wins). ${Bo} Dates are ISO 8601 only \u2014 dateFormat field was removed.`,params:{bills:{type:"array",description:"Array of bills to create or update (max 500). Each row needs at least: billReference, contactResourceId, valueDate, totalAmount, billAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},totalAmount:{type:"number"},currencyCode:{type:"string"},billAccountResourceId:{type:"string",description:"Expense account UUID"},itemDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk create update bills upsert import migrate",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),Ny(e.client,r)}},{name:"bulk_upsert_bill_line_items",description:`Create or update bills with nested line items in bulk (max 500 bills per call). Each row carries lineItems[] under its parent bill (scoped by billReference). ${Bo}`,params:{bills:{type:"array",description:"Array of bills with line items (max 500). Each bill row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Expense account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk bills line items multi-line upsert import",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),ky(e.client,r)}},{name:"bulk_upsert_customer_credit_notes",description:`Create or update customer credit notes in bulk (max 500 per call). Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{customerCreditNotes:{type:"array",description:"Array of customer credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["customerCreditNotes"],group:"customer_credit_notes",readOnly:!1,searchHint:"bulk customer credit notes refund upsert import",execute:async(e,t)=>{er(t.customerCreditNotes,"customerCreditNotes",500,"customer credit notes");let r=t.customerCreditNotes;return eo(r,["valueDate"]),kb(e.client,r)}},{name:"bulk_upsert_supplier_credit_notes",description:`Create or update supplier credit notes in bulk (max 500 per call). Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{supplierCreditNotes:{type:"array",description:"Array of supplier credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["supplierCreditNotes"],group:"supplier_credit_notes",readOnly:!1,searchHint:"bulk supplier credit notes refund upsert import",execute:async(e,t)=>{er(t.supplierCreditNotes,"supplierCreditNotes",500,"supplier credit notes");let r=t.supplierCreditNotes;return eo(r,["valueDate"]),Mb(e.client,r)}},{name:"bulk_upsert_journals",description:`Create or update manual journals in bulk (max 500 per call). NATURAL KEY: \`journalReference\` (NOT \`reference\` \u2014 every other bulk-upsert uses entityReference, this one is asymmetric). LEGS field: \`journalEntries[]\` (NOT \`entries[]\` \u2014 different from \`clio journals create\` which uses entries). Each leg has \`accountResourceId\` + \`debitAmount\` + \`creditAmount\` (debit + credit must balance per row). ${Bo} Dates are ISO 8601 (YYYY-MM-DD) only \u2014 dateFormat field was removed.`,params:{journals:{type:"array",description:"Array of journals to create or update (max 500). Each row has entries[] (debit/credit legs).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},journalReference:{type:"string",description:"Natural key \u2014 required (NOTE: field is `journalReference`, not `reference`)"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},journalEntries:{type:"array",description:"Journal legs (debit + credit amounts must balance) \u2014 field is `journalEntries`, NOT `entries`",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Required"},description:{type:"string"},debitAmount:{type:"number"},creditAmount:{type:"number"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["journals"],group:"journals",readOnly:!1,searchHint:"bulk manual journals upsert import migration",execute:async(e,t)=>{er(t.journals,"journals");let r=t.journals;return eo(r,["valueDate"]),H0(e.client,r)}},{name:"bulk_upsert_fixed_assets",description:`Bulk create/update fixed assets (max 500). Natural key: reference.
|
|
814
|
+
ASYNC: returns jobId \u2192 poll search_background_jobs(filter:{resourceId:{eq:jobId}}); PARTIAL_SUCCESS \u2192 data[0].errorDetails. Dates ISO 8601 (YYYY-MM-DD); dateFormat field removed.`,params:{invoices:{type:"array",description:"Array of invoices to create or update (max 500). Each row needs at least: invoiceReference, contactResourceId, valueDate, totalAmount, invoiceAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string",description:"Optional caller-supplied row index for error reporting"},resourceId:{type:"string",description:"Invoice resourceId (UUID) \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key (e.g., INV-2025-001) \u2014 required"},contactResourceId:{type:"string",description:"Customer contact UUID \u2014 required"},valueDate:{type:"string",description:"Invoice date YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"Due date YYYY-MM-DD"},totalAmount:{type:"number",description:"Total amount (BigDecimal)"},currencyCode:{type:"string",description:"Currency (e.g., SGD)"},invoiceAccountResourceId:{type:"string",description:"Revenue account UUID"},itemDescription:{type:"string",description:"Single-line item description"},internalNotes:{type:"string",description:"Internal notes"},tags:{type:"array",items:{type:"string"},description:"Tag resourceIds"}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk create update invoices upsert import migrate",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),B0(e.client,r)}},{name:"bulk_upsert_invoice_line_items",description:`Nested line items per invoice (max 500 invoices per call). Each row carries lineItems[] under its parent invoice (scoped by invoiceReference). ${Bo} Dates are ISO 8601 only.`,params:{invoices:{type:"array",description:"Array of invoices with line items (max 500). Each invoice row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string",description:"Invoice resourceId \u2014 provide to update by ID"},invoiceReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string",description:"YYYY-MM-DD"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",description:"Line items belonging to this invoice",items:{type:"object",properties:{itemDescription:{type:"string",description:"Line description \u2014 required"},quantity:{type:"number"},unit:{type:"string",description:"Unit of measure (pcs, kg, etc.)"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Revenue account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["invoices"],group:"invoices",readOnly:!1,searchHint:"bulk invoices line items multi-line upsert import",execute:async(e,t)=>{er(t.invoices,"invoices");let r=t.invoices;return eo(r,["valueDate","dueDate"]),U0(e.client,r)}},{name:"bulk_upsert_bills",description:`Max 500 bills per call. FLAT shape: ONE line per bill via \`itemDescription\` + \`totalAmount\` + \`billAccountResourceId\` at row level. For multi-line bills use \`bulk_upsert_bill_line_items\` instead \u2014 that variant takes nested \`lineItems[]\`. Natural key: \`billReference\` (rows sharing one within a batch are MERGED \u2014 last wins). ${Bo} Dates are ISO 8601 only \u2014 dateFormat field was removed.`,params:{bills:{type:"array",description:"Array of bills to create or update (max 500). Each row needs at least: billReference, contactResourceId, valueDate, totalAmount, billAccountResourceId.",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},totalAmount:{type:"number"},currencyCode:{type:"string"},billAccountResourceId:{type:"string",description:"Expense account UUID"},itemDescription:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk create update bills upsert import migrate",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),Ny(e.client,r)}},{name:"bulk_upsert_bill_line_items",description:`Nested line items per bill (max 500 bills per call). Each row carries lineItems[] under its parent bill (scoped by billReference). ${Bo}`,params:{bills:{type:"array",description:"Array of bills with line items (max 500). Each bill row has lineItems[].",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},billReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},dueDate:{type:"string"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unit:{type:"string"},unitPrice:{type:"number"},accountResourceId:{type:"string",description:"Expense account UUID"},taxProfileResourceId:{type:"string"}}}}}}}},required:["bills"],group:"bills",readOnly:!1,searchHint:"bulk bills line items multi-line upsert import",execute:async(e,t)=>{er(t.bills,"bills");let r=t.bills;return eo(r,["valueDate","dueDate"]),ky(e.client,r)}},{name:"bulk_upsert_customer_credit_notes",description:`Max 500 customer credit notes per call. Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{customerCreditNotes:{type:"array",description:"Array of customer credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Customer UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["customerCreditNotes"],group:"customer_credit_notes",readOnly:!1,searchHint:"bulk customer credit notes refund upsert import",execute:async(e,t)=>{er(t.customerCreditNotes,"customerCreditNotes",500,"customer credit notes");let r=t.customerCreditNotes;return eo(r,["valueDate"]),kb(e.client,r)}},{name:"bulk_upsert_supplier_credit_notes",description:`Max 500 supplier credit notes per call. Natural key: creditNoteReference. ${Bo} Dates are ISO 8601 only.`,params:{supplierCreditNotes:{type:"array",description:"Array of supplier credit notes (max 500).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},creditNoteReference:{type:"string",description:"Natural key \u2014 required"},contactResourceId:{type:"string",description:"Supplier UUID \u2014 required"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},lineItems:{type:"array",items:{type:"object",properties:{itemDescription:{type:"string",description:"Required"},quantity:{type:"number"},unitPrice:{type:"number"},accountResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["supplierCreditNotes"],group:"supplier_credit_notes",readOnly:!1,searchHint:"bulk supplier credit notes refund upsert import",execute:async(e,t)=>{er(t.supplierCreditNotes,"supplierCreditNotes",500,"supplier credit notes");let r=t.supplierCreditNotes;return eo(r,["valueDate"]),Mb(e.client,r)}},{name:"bulk_upsert_journals",description:`Max 500 manual journals per call. NATURAL KEY: \`journalReference\` (NOT \`reference\` \u2014 every other bulk-upsert uses entityReference, this one is asymmetric). LEGS field: \`journalEntries[]\` (NOT \`entries[]\` \u2014 different from \`clio journals create\` which uses entries). Each leg has \`accountResourceId\` + \`debitAmount\` + \`creditAmount\` (debit + credit must balance per row). ${Bo} Dates are ISO 8601 (YYYY-MM-DD) only \u2014 dateFormat field was removed.`,params:{journals:{type:"array",description:"Array of journals to create or update (max 500). Each row has entries[] (debit/credit legs).",items:{type:"object",properties:{rowIndex:{type:"string"},resourceId:{type:"string"},journalReference:{type:"string",description:"Natural key \u2014 required (NOTE: field is `journalReference`, not `reference`)"},valueDate:{type:"string",description:"YYYY-MM-DD \u2014 required"},currencyCode:{type:"string"},internalNotes:{type:"string"},tags:{type:"array",items:{type:"string"}},journalEntries:{type:"array",description:"Journal legs (debit + credit amounts must balance) \u2014 field is `journalEntries`, NOT `entries`",items:{type:"object",properties:{accountResourceId:{type:"string",description:"Required"},description:{type:"string"},debitAmount:{type:"number"},creditAmount:{type:"number"},contactResourceId:{type:"string"},taxProfileResourceId:{type:"string"}}}}}}}},required:["journals"],group:"journals",readOnly:!1,searchHint:"bulk manual journals upsert import migration",execute:async(e,t)=>{er(t.journals,"journals");let r=t.journals;return eo(r,["valueDate"]),H0(e.client,r)}},{name:"bulk_upsert_fixed_assets",description:`Bulk create/update fixed assets (max 500). Natural key: reference.
|
|
815
815
|
|
|
816
816
|
\u26A0\uFE0F DATE FIELD MISMATCH: REQUEST uses valueDate (NOT purchaseDate); GET response uses purchaseDate. Sending purchaseDate \u2192 cryptic 400 "Invalid request body".
|
|
817
817
|
|