jaz-clio 5.74.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/assets/skills/api/SKILL.md +3 -36
- package/assets/skills/cli/SKILL.md +18 -28
- package/assets/skills/cli/references/agent-gotchas.md +2 -2
- package/assets/skills/cli/references/command-catalog.md +15 -31
- package/assets/skills/cli/references/common-workflows.md +19 -28
- package/assets/skills/conversion/SKILL.md +1 -1
- package/assets/skills/jaz-kit/SKILL.md +1 -1
- package/assets/skills/jaz-kit/references/flows.md +2 -2
- package/assets/skills/jaz-pseudo-sql/SKILL.md +1 -1
- package/assets/skills/jobs/SKILL.md +42 -42
- package/assets/skills/jobs/references/audit-prep.md +8 -8
- package/assets/skills/jobs/references/bank-match.md +1 -1
- package/assets/skills/jobs/references/bank-recon.md +6 -6
- package/assets/skills/jobs/references/building-blocks.md +49 -30
- package/assets/skills/jobs/references/credit-control.md +13 -12
- package/assets/skills/jobs/references/document-collection.md +6 -6
- package/assets/skills/jobs/references/fa-review.md +28 -29
- package/assets/skills/jobs/references/gst-vat-filing.md +3 -3
- package/assets/skills/jobs/references/month-end-close.md +37 -33
- package/assets/skills/jobs/references/payment-run.md +3 -4
- package/assets/skills/jobs/references/quarter-end-close.md +20 -18
- package/assets/skills/jobs/references/supplier-recon.md +5 -5
- package/assets/skills/jobs/references/year-end-close.md +31 -21
- package/assets/skills/transaction-recipes/SKILL.md +54 -117
- package/assets/skills/transaction-recipes/references/accrued-expenses.md +86 -61
- package/assets/skills/transaction-recipes/references/asset-disposal.md +135 -93
- package/assets/skills/transaction-recipes/references/bad-debt-provision.md +87 -65
- package/assets/skills/transaction-recipes/references/bank-loan.md +104 -70
- package/assets/skills/transaction-recipes/references/building-blocks.md +168 -72
- package/assets/skills/transaction-recipes/references/capital-wip.md +9 -8
- package/assets/skills/transaction-recipes/references/declining-balance.md +91 -64
- package/assets/skills/transaction-recipes/references/deferred-revenue.md +105 -68
- package/assets/skills/transaction-recipes/references/dividend.md +100 -64
- package/assets/skills/transaction-recipes/references/employee-accruals.md +111 -73
- package/assets/skills/transaction-recipes/references/fixed-deposit.md +116 -63
- package/assets/skills/transaction-recipes/references/fx-revaluation.md +28 -19
- package/assets/skills/transaction-recipes/references/hire-purchase.md +45 -44
- package/assets/skills/transaction-recipes/references/ifrs16-lease.md +108 -73
- package/assets/skills/transaction-recipes/references/intercompany.md +8 -6
- package/assets/skills/transaction-recipes/references/prepaid-amortization.md +104 -65
- package/assets/skills/transaction-recipes/references/provisions.md +116 -64
- package/assets/templates/platform-rules/jaz-agent-rules.md +10 -9
- package/cli.mjs +529 -607
- package/package.json +1 -1
|
@@ -1,57 +1,47 @@
|
|
|
1
|
-
# Recipe: Accrued Expenses (
|
|
1
|
+
# Recipe: Accrued Expenses (calculator type: `accrued-expense`)
|
|
2
2
|
|
|
3
|
-
> Canonical recipe for month-end expense accruals (utilities, professional fees, cleaning, employee bonuses), incurred but not yet billed.
|
|
3
|
+
> Canonical recipe for month-end expense accruals (utilities, professional fees, cleaning, employee bonuses), incurred but not yet billed. Each period is a pair of journals: the accrual at period-end and its reversal in the next period, all in one capsule. You calculate, create the capsule and post each journal yourself (see `building-blocks.md` § The three-step flow).
|
|
4
4
|
|
|
5
|
-
## Tools
|
|
5
|
+
## Tools and calculator this recipe uses
|
|
6
6
|
|
|
7
|
-
###
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
### Calculator (offline, posts nothing)
|
|
8
|
+
- **MCP: `calculate(type: 'accrued-expense', amount, periods, frequency, startDate, currency)`** (step 1).
|
|
9
|
+
- **CLI: `clio calc accrued-expense --amount <per-period> --periods <n> --start-date <YYYY-MM-DD> --currency <code> --json`** (step 1): the same result.
|
|
10
10
|
|
|
11
|
-
###
|
|
12
|
-
- **`
|
|
11
|
+
### Posting tools
|
|
12
|
+
- **`list_capsule_types` / `create_capsule_type(displayName: 'Accrued Expenses')` / `create_capsule(...)`** (step 3).
|
|
13
|
+
- **`create_journal(...)`** (step 4): one per accrual and one per reversal, each with `capsuleResourceId`.
|
|
13
14
|
|
|
14
|
-
###
|
|
15
|
-
- **`search_journals(filter: {tags: {eq: <accrual
|
|
16
|
-
- **`
|
|
17
|
-
- **`
|
|
18
|
-
- **`
|
|
19
|
-
- **`
|
|
20
|
-
- **`bulk_update_journals(items: [{resourceId: <id>, saveAsDraft: false}, ...])`**, step 5: finalize this period's accrual + reversal pair.
|
|
21
|
-
- **`generate_trial_balance(endDate: <date>)`**, step 5 verification: confirm Accrued Expenses balance and net P&L impact.
|
|
15
|
+
### Lookup and verification tools
|
|
16
|
+
- **`search_journals(filter: {tags: {eq: <accrual tag>}, valueDate: {between: [<-3 months>, <today>]}})`** (step 1 estimation): pull the posted accrual amounts for the prior month or the trailing three months.
|
|
17
|
+
- **`search_contacts(filter: {name: {eq: <vendor>}})`** (step 2): resolve the accrual's vendor for the journal narrative.
|
|
18
|
+
- **`search_accounts(filter: {name: {in: ['<expense GL>', '<accrued liability GL>']}})`** (step 2): confirm both sides of the journal exist in the CoA.
|
|
19
|
+
- **`update_journal(resourceId: <id>, saveAsDraft: false)`** (step 5): finalize a draft accrual or reversal.
|
|
20
|
+
- **`generate_trial_balance(endDate: <date>)`** (step 5 verification): confirm the Accrued Expenses balance and net P&L impact.
|
|
22
21
|
|
|
23
22
|
### Cross-references
|
|
24
23
|
- Operational context: invoked during month-end close, once per recurring accrual whose last-posted period precedes the current period end. The close loop supplies the estimation method, GL account, vendor, and fixed/budget amount for each accrual.
|
|
25
|
-
- Sibling recipes: `prepaid-amortization.md` (mirror: paid upfront, recognized over time vs incurred over time, billed later); `employee-accruals.md` (
|
|
24
|
+
- Sibling recipes: `prepaid-amortization.md` (mirror: paid upfront, recognized over time vs incurred over time, billed later); `employee-accruals.md` (bonus accruals use this same calculator; leave uses `leave-accrual`, monthly-only with no reversal, since leave accumulates).
|
|
26
25
|
- IFRS / accounting context: matching principle (IFRS Conceptual Framework). The reversal pattern eliminates double-counting when the actual bill arrives.
|
|
27
26
|
|
|
28
27
|
---
|
|
29
28
|
|
|
30
29
|
## Step-by-step
|
|
31
30
|
|
|
32
|
-
### Step 1: Compute the per-period amount
|
|
31
|
+
### Step 1: Compute the per-period amount and calculate
|
|
33
32
|
|
|
34
33
|
Per the accrual's estimation method:
|
|
35
34
|
|
|
36
|
-
- **`prior_month`**: pull last period's posted amount via `search_journals
|
|
35
|
+
- **`prior_month`**: pull last period's posted amount via `search_journals` on the accrual's tag and the prior period's dates. Use that amount.
|
|
37
36
|
- **`trailing_3m_avg`**: pull last 3 months' posted amounts and average.
|
|
38
37
|
- **`budget`**: use the accrual's budget amount.
|
|
39
38
|
- **`fixed_amount`**: use the accrual's fixed amount directly.
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
Then run the calculator:
|
|
42
41
|
|
|
43
42
|
```
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Returns `{ totalAccrued: 3000, schedule: [{accrualDate: '2025-01-31', reversalDate: '2025-02-01', accrualJournal: {...}, reversalJournal: {...}}] }`. For a single-period accrual, `periods: 1`. For a multi-period rolling accrual (e.g. quarterly bill arriving in month 3), use `periods: 3`.
|
|
48
|
-
|
|
49
|
-
### Step 2: Plan the recipe
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
plan_recipe(
|
|
53
|
-
// Accounts, capsule and counterparty are not plan_recipe params: execute_recipe resolves accounts from the CoA and takes bankAccountName / contactName.
|
|
54
|
-
recipe: 'accrued-expense',
|
|
43
|
+
calculate(
|
|
44
|
+
type: 'accrued-expense',
|
|
55
45
|
amount: 3000,
|
|
56
46
|
periods: 1,
|
|
57
47
|
startDate: '2025-01-31',
|
|
@@ -59,62 +49,97 @@ plan_recipe(
|
|
|
59
49
|
)
|
|
60
50
|
```
|
|
61
51
|
|
|
62
|
-
|
|
52
|
+
```
|
|
53
|
+
clio calc accrued-expense --amount 3000 --periods 1 --start-date 2025-01-31 --currency SGD --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Returns `{ totalAccruals: 3000, schedule: [{ period, accrualDate: '2025-01-31', reversalDate: '2025-02-28', amount: 3000, accrualJournal, reversalJournal }], blueprint }`. For a single-period accrual, `periods: 1`. For a multi-period rolling accrual (e.g. quarterly bill arriving in month 3), use `periods: 3`.
|
|
57
|
+
|
|
58
|
+
`blueprint.steps` (2 journals for `periods: 1`; 6 for `periods: 3`):
|
|
59
|
+
- Step 1, `journal`, dated `2025-01-31`: Dr Expense Account 3,000 / Cr Accrued Liability 3,000.
|
|
60
|
+
- Step 2, `journal`, dated `2025-02-28`: Dr Accrued Liability 3,000 / Cr Expense Account 3,000.
|
|
63
61
|
|
|
64
|
-
|
|
62
|
+
The calculator dates each reversal one period after its accrual. If the entity reverses on day 1 of the next period (the usual convention), post the reversal with `valueDate: '2025-02-01'` instead: both dates fall in the next period, so the monthly P&L is the same.
|
|
65
63
|
|
|
66
|
-
### Step
|
|
64
|
+
### Step 2: Resolve accounts
|
|
67
65
|
|
|
68
|
-
|
|
69
|
-
- `search_accounts(filter: {name: {
|
|
66
|
+
The blueprint's `Expense Account` and `Accrued Liability` are labels. Map each to the real account:
|
|
67
|
+
- `search_accounts(filter: {name: {in: ['<expense GL>', 'Accrued Expenses']}})`. If one is missing: halt and surface "Accrual needs GL account `<accountName>`, which is not in the Jaz CoA. Create via `create_account` (suggested classifications: expense → `Operating Expense`; accrued liability → `Current Liability`) or remap the account."
|
|
70
68
|
|
|
71
|
-
Vendor: confirm via `search_contacts(filter: {name: {eq: <vendor>}})` for
|
|
69
|
+
Vendor: confirm via `search_contacts(filter: {name: {eq: <vendor>}})` for the journal narrative. The accrual itself needs no contact (no AR/AP document).
|
|
72
70
|
|
|
73
|
-
### Step
|
|
71
|
+
### Step 3: Create the capsule
|
|
74
72
|
|
|
75
73
|
```
|
|
76
|
-
|
|
74
|
+
list_capsule_types()
|
|
75
|
+
create_capsule(
|
|
76
|
+
capsuleTypeResourceId: <id of 'Accrued Expenses'>,
|
|
77
|
+
title: 'Utilities Accrual, PowerCo, FY2025',
|
|
78
|
+
description: <blueprint.capsuleDescription>
|
|
79
|
+
)
|
|
77
80
|
```
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
If `Accrued Expenses` is not in the list: `create_capsule_type(displayName: 'Accrued Expenses')` first. A recurring accrual keeps ONE capsule: later periods post into the same one.
|
|
83
|
+
|
|
84
|
+
### Step 4: Post the journals
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
create_journal(
|
|
88
|
+
valueDate: '2025-01-31',
|
|
89
|
+
reference: 'ACCR-POWERCO-2025-01',
|
|
90
|
+
journalEntries: [
|
|
91
|
+
{ accountResourceId: <expense GL>, type: 'DEBIT', amount: 3000, description: 'Accrued utilities: Jan 2025' },
|
|
92
|
+
{ accountResourceId: <Accrued Expenses>, type: 'CREDIT', amount: 3000, description: 'Accrued utilities: Jan 2025' }
|
|
93
|
+
],
|
|
94
|
+
saveAsDraft: false,
|
|
95
|
+
capsuleResourceId: <capsule id>
|
|
96
|
+
)
|
|
97
|
+
create_journal(
|
|
98
|
+
valueDate: '2025-02-01',
|
|
99
|
+
reference: 'ACCR-POWERCO-2025-01-REV',
|
|
100
|
+
journalEntries: [
|
|
101
|
+
{ accountResourceId: <Accrued Expenses>, type: 'DEBIT', amount: 3000, description: 'Reverse accrued utilities: Jan 2025' },
|
|
102
|
+
{ accountResourceId: <expense GL>, type: 'CREDIT', amount: 3000, description: 'Reverse accrued utilities: Jan 2025' }
|
|
103
|
+
],
|
|
104
|
+
saveAsDraft: true,
|
|
105
|
+
capsuleResourceId: <capsule id>
|
|
106
|
+
)
|
|
107
|
+
```
|
|
80
108
|
|
|
81
|
-
|
|
82
|
-
- Step 1 (date `2025-01-31`): Dr `<expense GL>` 3000 / Cr Accrued Expenses 3000. DRAFT.
|
|
83
|
-
- Step 2 (date `2025-02-01`): Dr Accrued Expenses 3000 / Cr `<expense GL>` 3000. DRAFT; reverses step 1 in February.
|
|
109
|
+
The reversal stays a DRAFT until February's close.
|
|
84
110
|
|
|
85
|
-
### Step 5: Monthly action
|
|
111
|
+
### Step 5: Monthly action
|
|
86
112
|
|
|
87
|
-
|
|
113
|
+
January close: the accrual is posted (step 4). February close: find the reversal by its reference and finalize it, then post February's accrual if the bill still has not arrived (run step 1 again for February's amount and post the new pair into the same capsule).
|
|
88
114
|
|
|
89
115
|
```
|
|
90
|
-
|
|
91
|
-
update_journal(resourceId: <
|
|
116
|
+
search_journals(filter: {reference: {eq: 'ACCR-POWERCO-2025-01-REV'}})
|
|
117
|
+
update_journal(resourceId: <reversal journal id>, saveAsDraft: false)
|
|
92
118
|
```
|
|
93
119
|
|
|
94
|
-
|
|
120
|
+
**Do NOT finalize an accrual and its reversal in the same period**; that defeats the period-matching purpose. Journals cannot be filtered by capsule, and a date-plus-status search returns every matching DRAFT in the org: never feed one into `bulk_update_journals` or `delete_journal`.
|
|
95
121
|
|
|
96
|
-
Verify after January
|
|
122
|
+
Verify after January:
|
|
97
123
|
- `generate_trial_balance(endDate: '2025-01-31')`.
|
|
98
124
|
- Assert: `balance['Accrued Expenses']` increased by 3000.
|
|
99
125
|
- Assert: `balance['<expense GL>']` (period MTD) increased by 3000.
|
|
100
126
|
- Net P&L impact for January: $3,000 expense.
|
|
101
127
|
|
|
102
|
-
After February
|
|
128
|
+
After February (with reversal + new Feb accrual posted):
|
|
103
129
|
- `balance['Accrued Expenses']` reflects only the Feb accrual (Jan's reversed cleanly).
|
|
104
130
|
|
|
105
131
|
When the actual quarterly bill arrives (typically Mar 31, $9,000 total): post a normal `create_bill(...)` for the full $9,000 against `<expense GL>`. The capsule may or may not include this bill; practitioner's call. The accrual capsule's net P&L impact is zero across the rolling window once all reversals post.
|
|
106
132
|
|
|
107
133
|
---
|
|
108
134
|
|
|
109
|
-
## Common
|
|
135
|
+
## Common problems and recovery
|
|
110
136
|
|
|
111
|
-
|
|
|
137
|
+
| Where | Problem | Recovery |
|
|
112
138
|
|--------|-------|----------|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
| `
|
|
116
|
-
|
|
|
117
|
-
| Verification | Net P&L impact stuck after reversal posts | Likely the reversal hasn't been finalized yet. Find it (journals cannot be filtered by capsule: check each candidate with `get_journal` (its `capsule.resourceId`) and confirm the set with the practitioner); if it is still DRAFT, finalize it. |
|
|
139
|
+
| Calculator | "Amount must be a positive number" | The computed amount is zero or negative: `prior_month` may have returned a credit balance. Switch the estimation method to `fixed_amount` for this row this period, OR investigate the credit. |
|
|
140
|
+
| Step 2 | An account is missing | `search_accounts`; create via `create_account` if the practitioner confirms classification. |
|
|
141
|
+
| `create_journal` | "Unbalanced journal" | The lines were retyped incorrectly. Take both amounts from the calculator's step; debits must equal credits. |
|
|
142
|
+
| Verification | Net P&L impact stuck after the reversal should have posted | The reversal is likely still a DRAFT. Find it by its reference (journals cannot be filtered by capsule) and finalize it. |
|
|
118
143
|
| Verification | Accrued Expenses balance nonzero after the actual bill posts AND all reversals run | Either the bill amount diverged from the accrual estimate (post a true-up journal: Dr/Cr `<expense GL>` for the difference) OR a reversal was missed. Audit via `generate_general_ledger(accountResourceIds: [<Accrued Expenses id>], startDate: <accrual date>, endDate: <today>)`. |
|
|
119
144
|
| Actual bill posted against `Accrued Expenses` instead of `<expense GL>` | (process error) | The reversal AND the bill both touch `Accrued Expenses`: net to zero on liability, but expense gets double-recognized. Reverse the bill, re-post against `<expense GL>`. Note the risk in your working notes. |
|
|
120
145
|
|
|
@@ -122,11 +147,11 @@ When the actual quarterly bill arrives (typically Mar 31, $9,000 total): post a
|
|
|
122
147
|
|
|
123
148
|
## Variations
|
|
124
149
|
|
|
125
|
-
- **Multi-period rolling accrual** (quarterly bill, monthly accrual): `periods: 3` with `frequency: 'monthly'`.
|
|
126
|
-
- **One-shot accrual** (year-end true-up where you don't know the per-period split): `periods: 1`, `startDate: <FY-end>`.
|
|
150
|
+
- **Multi-period rolling accrual** (quarterly bill, monthly accrual): `periods: 3` with `frequency: 'monthly'`. The calculator returns 3 accrual + 3 reversal pairs. Each month's close posts that month's pair.
|
|
151
|
+
- **One-shot accrual** (year-end true-up where you don't know the per-period split): `periods: 1`, `startDate: <FY-end>`. Post the reversal on FY-end+1 day. The practitioner posts the actual bill in the next FY when it arrives.
|
|
127
152
|
- **Quarterly cadence**: `frequency: 'quarterly', periods: 4` for an annual rolling accrual (rare for SMBs).
|
|
128
|
-
- **Different
|
|
129
|
-
- **Vendor unknown** (estimating an accrual but supplier not yet identified):
|
|
153
|
+
- **Different estimate per period**: the calculator assumes a constant per-period amount. For variable amounts, run it once per period with that period's amount.
|
|
154
|
+
- **Vendor unknown** (estimating an accrual but supplier not yet identified): leave the vendor out of the narrative. The journal still posts; update the narrative later via `update_journal`.
|
|
130
155
|
|
|
131
156
|
---
|
|
132
157
|
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
# Recipe: Asset Disposal (
|
|
1
|
+
# Recipe: Asset Disposal (calculator type: `asset-disposal`)
|
|
2
2
|
|
|
3
|
-
> One-shot recipe for fixed-asset disposal under IAS 16.67-72 (sale, scrap, write-off).
|
|
3
|
+
> One-shot recipe for fixed-asset disposal under IAS 16.67-72 (sale, scrap, write-off). One disposal journal, plus the fixed-asset register update that stops depreciation. The calculator returns the accumulated depreciation, net book value, gain or loss and the journal lines; you post the journal and update the register yourself (see `building-blocks.md` § The three-step flow).
|
|
4
4
|
|
|
5
|
-
## Tools
|
|
5
|
+
## Tools and calculator this recipe uses
|
|
6
6
|
|
|
7
|
-
###
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
### Calculator (offline, posts nothing)
|
|
8
|
+
- **MCP: `calculate(type: 'asset-disposal', cost, salvageValue, usefulLifeYears, acquisitionDate, disposalDate, proceeds, method, currency)`** (step 1). `method` is `sl` (the default), `ddb` or `150db`.
|
|
9
|
+
- **CLI: `clio calc asset-disposal --cost <c> --salvage <s> --life <years> --acquired <YYYY-MM-DD> --disposed <YYYY-MM-DD> --proceeds <p> --method <sl|ddb|150db> --currency <code> --json`** (step 1): the same result.
|
|
10
10
|
|
|
11
|
-
###
|
|
12
|
-
- **`
|
|
11
|
+
### Posting tools
|
|
12
|
+
- **`list_capsule_types` / `create_capsule_type(displayName: 'Asset Disposal')` / `create_capsule(...)`** (step 3).
|
|
13
|
+
- **`create_journal(...)`** (step 4): the disposal journal.
|
|
14
|
+
- **`mark_fixed_asset_sold(...)`** for a sale (it links the sale transaction and records gain/loss) or **`discard_fixed_asset(...)`** for a write-off (step 5). A disposal is its own operation, never a `status` change via `update_fixed_asset`.
|
|
13
15
|
|
|
14
|
-
###
|
|
15
|
-
- **`get_fixed_asset(resourceId: <id>)`** (step 1):
|
|
16
|
-
- **`generate_fa_summary(primarySnapshotStartDate: <FY-start>, primarySnapshotEndDate: <disposalDate>, groupBy: 'CATEGORY')`** (step 1 alt):
|
|
17
|
-
- **`search_capsules(filter: {title: {eq: <capsule
|
|
18
|
-
- **`search_accounts(filter: {name: {in: ['Vehicles', 'Accumulated Depreciation (Vehicles)', 'Gain on Disposal', 'Loss on Disposal']}})`**: step
|
|
19
|
-
- **`mark_fixed_asset_sold(...)` for a sale (it links the sale transaction and records gain/loss) or `discard_fixed_asset(...)` for a write-off; a disposal is its own operation, never a `status` mutation via update_fixed_asset** OR **`POST /api/v1/mark-as-sold/fixed-assets`** OR **`POST /api/v1/discard-fixed-assets/{id}`**: step 5 manual FA-register update (the engine-skipped note step).
|
|
16
|
+
### Lookup and verification tools
|
|
17
|
+
- **`get_fixed_asset(resourceId: <id>)`** (step 1): the asset's registered cost, purchase date and net book value. Use the live FA-register values; the auditor wants those, not a cached estimate.
|
|
18
|
+
- **`generate_fa_summary(primarySnapshotStartDate: <FY-start>, primarySnapshotEndDate: <disposalDate>, groupBy: 'CATEGORY')`** (step 1 alt): NBV from Jaz's running FA register. If this matches your independent calculation, use it as the authoritative NBV. If they diverge: investigate (likely a missing depreciation journal).
|
|
19
|
+
- **`search_capsules(filter: {title: {eq: <capsule title>}})`**: step 0 idempotency check. Each disposal is unique; duplicate disposal journals would corrupt the FA register reconciliation.
|
|
20
|
+
- **`search_accounts(filter: {name: {in: ['Vehicles', 'Accumulated Depreciation (Vehicles)', 'Gain on Disposal', 'Loss on Disposal']}})`**: step 2.
|
|
20
21
|
- **`generate_trial_balance(endDate: <disposalDate>)`** (step 6): verify cost + accumulated depreciation cleared; gain/loss in P&L.
|
|
21
22
|
|
|
22
23
|
### Cross-references
|
|
23
24
|
- Operational context: invoked during year-end close (FA disposals discovered during the year-end review) or ad-hoc during month-end close if a disposal happens mid-period.
|
|
24
|
-
- Sibling: `declining-balance.md` (depreciation up to the disposal date;
|
|
25
|
+
- Sibling: `declining-balance.md` (depreciation up to the disposal date; the disposal calculator recomputes it from the same inputs); `capital-wip.md` (the inverse: adding to FA, not disposing).
|
|
25
26
|
- IFRS / accounting context: IAS 16.67-72 (derecognition); IAS 16.71 (gain on disposal classified as Other Income, NOT revenue); IAS 16.68 (gain/loss = net proceeds − carrying amount).
|
|
26
27
|
|
|
27
28
|
---
|
|
@@ -31,37 +32,22 @@
|
|
|
31
32
|
### Step 0: Idempotency check
|
|
32
33
|
|
|
33
34
|
```
|
|
34
|
-
search_capsules(filter: {title: {eq: 'Disposal
|
|
35
|
+
search_capsules(filter: {title: {eq: 'Disposal, Delivery Vehicle (Truck-001), 2026-03-15'}})
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
If a result returns: halt. Disposal capsules are unique per asset+date; duplicates would double-book the disposal.
|
|
38
39
|
|
|
39
|
-
### Step 1: Pull asset details
|
|
40
|
+
### Step 1: Pull asset details and calculate
|
|
40
41
|
|
|
41
42
|
```
|
|
42
43
|
get_fixed_asset(resourceId: <FA UUID>)
|
|
43
44
|
```
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
Read the registered values off the record: `purchaseAmount` (cost), `purchaseDate` (epoch milliseconds: convert to a date), `netBookValueAmount`, `status`, and the asset's depreciation settings (life, method, residual value) as registered. Use these as the authoritative inputs to the calculator (don't accept user-provided values blindly; auditor will tie back to the FA register).
|
|
46
47
|
|
|
47
48
|
```
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
Returns: `{ accumulatedDepreciation: 28500, netBookValue: 21500, proceeds: 18000, gainOrLoss: -3500, classification: 'loss' }`. (`(50000 - 5000) / 60 months × 38 months elapsed = 28,500` accumulated; NBV = 50,000 − 28,500 = 21,500; loss = 18,000 − 21,500 = −3,500).
|
|
52
|
-
|
|
53
|
-
Cross-check with Jaz FA register:
|
|
54
|
-
```
|
|
55
|
-
get_fixed_asset(resourceId: <FA UUID>)
|
|
56
|
-
```
|
|
57
|
-
Should report `accumulatedDepreciation: 28500, netBookValue: 21500` matching the independent calc within 1 cent. Variance investigation: missing monthly depreciation journals (journals cannot be filtered by capsule: check each candidate with `get_journal` (its `capsule.resourceId`) and confirm the set with the practitioner); finalize them BEFORE disposal recipe.
|
|
58
|
-
|
|
59
|
-
### Step 2: Plan the recipe
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
plan_recipe(
|
|
63
|
-
// Accounts, capsule and counterparty are not plan_recipe params: execute_recipe resolves accounts from the CoA and takes bankAccountName / contactName.
|
|
64
|
-
recipe: 'asset-disposal',
|
|
49
|
+
calculate(
|
|
50
|
+
type: 'asset-disposal',
|
|
65
51
|
cost: 50000,
|
|
66
52
|
salvageValue: 5000,
|
|
67
53
|
usefulLifeYears: 5,
|
|
@@ -73,67 +59,119 @@ plan_recipe(
|
|
|
73
59
|
)
|
|
74
60
|
```
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
-
|
|
62
|
+
```
|
|
63
|
+
clio calc asset-disposal --cost 50000 --salvage 5000 --life 5 --acquired 2023-01-01 --disposed 2026-03-15 --proceeds 18000 --method sl --currency SGD --json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Returns `{ monthsHeld: 39, accumulatedDepreciation: 29250, netBookValue: 20750, gainOrLoss: -2750, isGain: false, disposalJournal, blueprint }`. The calculator counts a part month as a full month, so 2023-01-01 to 2026-03-15 is 39 months: `(50000 - 5000) / 60 months × 39 months = 29,250` accumulated; NBV = 50,000 − 29,250 = 20,750; loss = 18,000 − 20,750 = −2,750.
|
|
67
|
+
|
|
68
|
+
`blueprint.steps`:
|
|
69
|
+
- Step 1, `journal`, dated `2026-03-15`, multi-line:
|
|
78
70
|
- Dr Cash / Bank Account 18,000 (proceeds received)
|
|
79
|
-
- Dr Accumulated Depreciation
|
|
80
|
-
- Dr Loss on Disposal
|
|
81
|
-
- Cr
|
|
82
|
-
- Step 2
|
|
71
|
+
- Dr Accumulated Depreciation 29,250 (clear contra-asset)
|
|
72
|
+
- Dr Loss on Disposal 2,750 (P&L impact)
|
|
73
|
+
- Cr Fixed Asset (at cost) 50,000 (clear original cost)
|
|
74
|
+
- Step 2, `note`: an instruction to update the FA register. For a registered asset the register books the disposal itself, so step 1 is a cross-check, not an entry to post (step 4 below).
|
|
83
75
|
|
|
84
|
-
For scrap (no proceeds): `proceeds: 0` → `gainOrLoss: -netBookValue` → all loss.
|
|
85
|
-
For gain (proceeds > NBV):
|
|
76
|
+
For scrap (no proceeds): `proceeds: 0` → `gainOrLoss: -netBookValue` → all loss, and the journal has no cash line.
|
|
77
|
+
For a gain (proceeds > NBV): the journal debits Cash, debits Accumulated Depreciation, credits Fixed Asset (at cost), AND credits Gain on Disposal for the difference.
|
|
86
78
|
|
|
87
|
-
|
|
79
|
+
Cross-check with the Jaz FA register: `netBookValueAmount` from `get_fixed_asset` should match the calculator's `netBookValue` within 1 cent. The register depreciates to the posting date it has reached, so a difference of the current month's charge is timing, not error. A larger variance means depreciation is missing or was posted outside the register: resolve it BEFORE posting the disposal.
|
|
88
80
|
|
|
89
|
-
|
|
90
|
-
- `search_accounts(filter: {name: {eq: <accountName>}})`. Suggested classifications: asset → `Non-current Asset`; accum dep → `Non-current Asset` contra; **`Gain on Disposal` → `Other Revenue`** (NOT Operating Revenue per IAS 16.71); `Loss on Disposal` → `Other Expense` (or `Operating Expense`, jurisdiction-specific).
|
|
81
|
+
### Step 2: Resolve accounts and the bank account
|
|
91
82
|
|
|
92
|
-
|
|
83
|
+
The blueprint's account names are labels. Map each to the real account:
|
|
84
|
+
- `search_accounts(filter: {name: {in: ['Vehicles', 'Accumulated Depreciation (Vehicles)', 'Gain on Disposal', 'Loss on Disposal']}})`. Suggested classifications: asset → `Non-current Asset`; accum dep → `Non-current Asset` contra; **`Gain on Disposal` → `Other Revenue`** (NOT Operating Revenue per IAS 16.71); `Loss on Disposal` → `Other Expense` (or `Operating Expense`, jurisdiction-specific).
|
|
93
85
|
|
|
94
|
-
|
|
86
|
+
Bank account: `list_bank_accounts()` for the account the proceeds arrive in. For scrap (no proceeds) none is needed, unless there is a disposal cost (e.g., scrap fee paid to a disposal vendor), which is its own `create_cash_out`.
|
|
87
|
+
|
|
88
|
+
### Step 3: Create the capsule
|
|
95
89
|
|
|
96
90
|
```
|
|
97
|
-
|
|
91
|
+
list_capsule_types()
|
|
92
|
+
create_capsule(
|
|
93
|
+
capsuleTypeResourceId: <id of 'Asset Disposal'>,
|
|
94
|
+
title: 'Disposal, Delivery Vehicle (Truck-001), 2026-03-15',
|
|
95
|
+
description: <blueprint.capsuleDescription>
|
|
96
|
+
)
|
|
98
97
|
```
|
|
99
98
|
|
|
100
|
-
|
|
99
|
+
If `Asset Disposal` is not in the list: `create_capsule_type(displayName: 'Asset Disposal')` first.
|
|
101
100
|
|
|
102
|
-
|
|
101
|
+
### Step 4: Book the disposal
|
|
103
102
|
|
|
104
|
-
|
|
103
|
+
Which entries you post depends on whether the asset is in the Jaz fixed-asset register. **Never do both**: the register books a disposal itself, so posting the calculator's full disposal journal and then running a register tool books the disposal twice.
|
|
105
104
|
|
|
106
|
-
The
|
|
105
|
+
**A. The asset is in the register (the usual case).** Do NOT post the calculator's disposal journal. Its figures are your cross-check.
|
|
107
106
|
|
|
108
|
-
|
|
107
|
+
*Sale (proceeds received).* Jaz requires a sale entry to exist before an asset can be marked sold: an invoice line on the asset's account, or a journal whose CREDIT line is on the asset's fixed-asset account. Post the proceeds as that entry, then mark the asset sold against the credit line:
|
|
109
108
|
|
|
110
|
-
**Sale (proceeds received):**
|
|
111
109
|
```
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
110
|
+
create_journal(
|
|
111
|
+
valueDate: '2026-03-15',
|
|
112
|
+
reference: 'DISP-TRUCK-001',
|
|
113
|
+
journalEntries: [
|
|
114
|
+
{ accountResourceId: <bank account>, type: 'DEBIT', amount: 18000, description: 'Proceeds, Truck-001' },
|
|
115
|
+
{ accountResourceId: <Vehicles>, type: 'CREDIT', amount: 18000, description: 'Sale of Truck-001' }
|
|
116
|
+
],
|
|
117
|
+
saveAsDraft: true,
|
|
118
|
+
capsuleResourceId: <capsule id>
|
|
119
|
+
)
|
|
119
120
|
```
|
|
120
|
-
OR the MCP tool: `mark_fixed_asset_sold(resourceId: <id>, depreciationEndDate: '2026-03-15', assetDisposalGainLossAccountResourceId: <Gain/Loss on Disposal>, saleBusinessTransactionType: 'SALE', saleItemResourceId: <sale line item id>)` for a sale, or `discard_fixed_asset(resourceId: <id>, disposalDate: '2026-03-15', depreciationEndDate: '2026-03-15')` for a write-off.
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
Finalize when the practitioner confirms (`update_journal(resourceId: <journal id>, saveAsDraft: false)`), read the credit line's id with `get_journal`, then:
|
|
123
|
+
|
|
123
124
|
```
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
mark_fixed_asset_sold(
|
|
126
|
+
resourceId: <FA UUID>,
|
|
127
|
+
depreciationEndDate: '2026-03-15',
|
|
128
|
+
assetDisposalGainLossAccountResourceId: <Gain / Loss on Disposal>,
|
|
129
|
+
saleBusinessTransactionType: 'JOURNAL_MANUAL',
|
|
130
|
+
saleItemResourceId: <the journal's credit line id>
|
|
131
|
+
)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`saleBusinessTransactionType` is the kind of document that recorded the sale (`JOURNAL_MANUAL` here; `SALE` for an invoice line; `PURCHASE` for a trade-in) and `saleItemResourceId` is the LINE on that document, not the document's id. A sale entry can be linked to one asset sale only.
|
|
135
|
+
|
|
136
|
+
*Scrap / write-off (no proceeds).* No journal at all:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
discard_fixed_asset(resourceId: <FA UUID>, disposalDate: '2026-03-15', depreciationEndDate: '2026-03-15')
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Either tool records the final depreciation up to `depreciationEndDate` and the disposal entry (cost and accumulated depreciation cleared, gain or loss to the account you passed).
|
|
143
|
+
|
|
144
|
+
CLI equivalents:
|
|
145
|
+
```bash
|
|
146
|
+
clio fixed-assets sell --id <FA UUID> --depreciation-end-date 2026-03-15 --gain-loss-account <account id> --sale-type JOURNAL_MANUAL --sale-item <journal credit line id> --json
|
|
147
|
+
clio fixed-assets discard <FA UUID> --disposal-date 2026-03-15 --depreciation-end-date 2026-03-15 --json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
After it: `get_fixed_asset(resourceId: <id>)` should return `status: 'DISPOSED'`. A disposal made in error is reversed with `undo_fixed_asset_disposal`.
|
|
151
|
+
|
|
152
|
+
**B. The asset was never in the register** (for example one depreciated by declining-balance journals, see `declining-balance.md`). There is no register to update, so the calculator's journal is the whole disposal:
|
|
153
|
+
|
|
129
154
|
```
|
|
130
|
-
|
|
155
|
+
create_journal(
|
|
156
|
+
valueDate: '2026-03-15',
|
|
157
|
+
reference: 'DISP-TRUCK-001',
|
|
158
|
+
journalEntries: [
|
|
159
|
+
{ accountResourceId: <bank account>, type: 'DEBIT', amount: 18000, description: 'Proceeds, Truck-001' },
|
|
160
|
+
{ accountResourceId: <Accumulated Depreciation (Vehicles)>, type: 'DEBIT', amount: 29250, description: 'Clear accumulated depreciation' },
|
|
161
|
+
{ accountResourceId: <Loss on Disposal>, type: 'DEBIT', amount: 2750, description: 'Loss on disposal' },
|
|
162
|
+
{ accountResourceId: <Vehicles>, type: 'CREDIT', amount: 50000, description: 'Clear cost' }
|
|
163
|
+
],
|
|
164
|
+
saveAsDraft: true,
|
|
165
|
+
capsuleResourceId: <capsule id>
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
It is a DRAFT; finalize when the practitioner confirms.
|
|
131
170
|
|
|
132
|
-
|
|
133
|
-
1. First: invoke this recipe with `proceeds: <fair value of trade-in credit>` for the disposal of the old asset.
|
|
134
|
-
2. Then: `create_fixed_asset(...)` for the new asset with cost = cash paid + trade-in credit (the trade-in is part-payment).
|
|
171
|
+
### Step 5: Trade-in (proceeds + replacement asset)
|
|
135
172
|
|
|
136
|
-
|
|
173
|
+
1. Dispose of the old asset as in step 4, with `proceeds: <fair value of the trade-in credit>`.
|
|
174
|
+
2. `create_fixed_asset(...)` for the new asset with cost = cash paid + trade-in credit (the trade-in is part-payment).
|
|
137
175
|
|
|
138
176
|
### Step 6: Verify
|
|
139
177
|
|
|
@@ -142,15 +180,19 @@ generate_trial_balance(endDate: '2026-03-15')
|
|
|
142
180
|
```
|
|
143
181
|
|
|
144
182
|
Assert:
|
|
145
|
-
- `balance['Vehicles']` reduced by 50,000 (cost cleared).
|
|
146
|
-
- `balance['Accumulated Depreciation (Vehicles)']` reduced by
|
|
183
|
+
- `balance['Vehicles']` reduced by 50,000 (cost cleared), once.
|
|
184
|
+
- `balance['Accumulated Depreciation (Vehicles)']` reduced by 29,250 (contra-asset cleared), once.
|
|
147
185
|
- `balance['Cash / Bank Account']` increased by 18,000.
|
|
148
|
-
- `balance['Loss on Disposal'] (period MTD) ==
|
|
186
|
+
- `balance['Loss on Disposal'] (period MTD) == 2,750` (or Gain on Disposal of `gainOrLoss` if positive).
|
|
187
|
+
|
|
188
|
+
**Compare with the calculator.** For a registered asset the gain or loss the register booked should match the calculator's `gainOrLoss`; a difference of one month's depreciation is the month convention (the calculator counts a part month as a full month), anything larger needs explaining before the period closes.
|
|
189
|
+
|
|
190
|
+
**Check for a double count.** If the cost, accumulated depreciation or gain/loss moved by twice the expected amount, a full manual disposal journal was posted for an asset the register also disposed of: pull `generate_general_ledger(accountResourceIds: [<Vehicles>], startDate: <disposalDate>, endDate: <disposalDate>)`, show the practitioner both entries, and remove the manual one.
|
|
149
191
|
|
|
150
192
|
```
|
|
151
193
|
get_fixed_asset(resourceId: <FA UUID>)
|
|
152
194
|
```
|
|
153
|
-
Should now show `status: 'DISPOSED'`,
|
|
195
|
+
Should now show `status: 'DISPOSED'`, and no further depreciation auto-posting.
|
|
154
196
|
|
|
155
197
|
```
|
|
156
198
|
generate_fa_recon_summary(primarySnapshotStartDate: <FY-start>, primarySnapshotEndDate: <FY-end>)
|
|
@@ -159,28 +201,28 @@ Should reflect the disposal in the year's movement: `openingNbv − depreciation
|
|
|
159
201
|
|
|
160
202
|
---
|
|
161
203
|
|
|
162
|
-
## Common
|
|
204
|
+
## Common problems and recovery
|
|
163
205
|
|
|
164
|
-
|
|
|
206
|
+
| Where | Problem | Recovery |
|
|
165
207
|
|--------|-------|----------|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
168
|
-
|
|
|
169
|
-
| Step 5
|
|
170
|
-
| `mark_fixed_asset_sold` / `discard_fixed_asset` |
|
|
171
|
-
| Cross-check | Calculator NBV ≠ FA register NBV | Investigate missing depreciation journals
|
|
172
|
-
|
|
|
208
|
+
| Calculator | "Disposal date must be after acquisition date." | Inputs swapped. Verify and re-run. |
|
|
209
|
+
| Calculator | Disposal date later than the period being closed | The disposal belongs to the next period; halt and confirm with the practitioner. |
|
|
210
|
+
| Step 2 | `Gain on Disposal` / `Loss on Disposal` is missing | Create via `create_account(accountType: 'Other Revenue' / 'Other Expense', ...)`. |
|
|
211
|
+
| Step 5 register update missed | (process error: Jaz FA continues auto-depreciating) | Surface to practitioner: "Asset `<name>` (resourceId `<id>`) is still ACTIVE in FA register but disposal journal posted. Auto-depreciation will continue. Run `mark_fixed_asset_sold` (sale) or `discard_fixed_asset` (write-off) immediately." |
|
|
212
|
+
| `mark_fixed_asset_sold` / `discard_fixed_asset` | Refused because depreciation is pending after the disposal date | DRAFT depreciation journals exist for periods after the disposal date. Identify them by their references (journals cannot be filtered by capsule) and confirm the set with the practitioner, then `delete_journal` per confirmed journal. |
|
|
213
|
+
| Cross-check | Calculator NBV ≠ FA register NBV | Investigate missing depreciation (period journals posted as DRAFT that were never finalized). Finalize all up to the disposal date BEFORE this recipe. |
|
|
214
|
+
| Calculator NBV ≠ TB Vehicles − TB Accum Dep | (audit failure) | Likely a manual journal touched Vehicles or Accum Dep outside the depreciation schedule. Audit `generate_general_ledger(accountResourceIds: [<Vehicles>], startDate: <acquisition date>, endDate: <today>)`. |
|
|
173
215
|
|
|
174
216
|
---
|
|
175
217
|
|
|
176
218
|
## Variations
|
|
177
219
|
|
|
178
|
-
- **Scrap (no proceeds)**: `proceeds: 0`. Resulting `gainOrLoss = -netBookValue` (full NBV is loss). Step 5 uses `
|
|
220
|
+
- **Scrap (no proceeds)**: `proceeds: 0`. Resulting `gainOrLoss = -netBookValue` (full NBV is loss). Step 5 uses `discard_fixed_asset`, not `mark_fixed_asset_sold`.
|
|
179
221
|
- **Donation**: `proceeds: 0`, but classify the loss as `Charitable Donation` (not `Loss on Disposal`) per practitioner judgment. May have tax implications (deductible donation); flag to practitioner for SG IRAS / PH BIR treatment.
|
|
180
222
|
- **Insurance write-off after damage**: `proceeds: <insurance payout>`. The payout is taxable income; the loss may be deductible. Document the insurance reference in the journal narrative.
|
|
181
|
-
- **Trade-in**:
|
|
182
|
-
- **Partial disposal** (e.g., dismantling part of a building): NOT supported by
|
|
183
|
-
- **Disposal of a fully depreciated asset (NBV = 0)**: `proceeds > 0` → all gain. `proceeds == 0` → no entries needed in P&L; just clear the contra-asset against the cost (Dr Accum Dep / Cr Vehicles, both at full cost).
|
|
223
|
+
- **Trade-in**: this recipe for the old asset, plus `create_fixed_asset` for the new one, plus a manual reconciliation of the trade-in credit.
|
|
224
|
+
- **Partial disposal** (e.g., dismantling part of a building): NOT supported by the calculator. Manual journal: pro-rate cost + accum dep based on the disposed portion.
|
|
225
|
+
- **Disposal of a fully depreciated asset (NBV = 0)**: `proceeds > 0` → all gain. `proceeds == 0` → no entries needed in P&L; just clear the contra-asset against the cost (Dr Accum Dep / Cr Vehicles, both at full cost). The calculator still works; gain/loss = proceeds.
|
|
184
226
|
- **Foreign-currency proceeds**: pass `currency: 'USD'`. Per `jaz-api/SKILL.md` rule 25, journal records via `currency: { sourceCurrency: 'USD' }`. FX gain/loss between disposal-date rate and book rate is auto-handled by Jaz on the cash side.
|
|
185
227
|
|
|
186
228
|
---
|
|
@@ -190,5 +232,5 @@ Should reflect the disposal in the year's movement: `openingNbv − depreciation
|
|
|
190
232
|
- Year-end close: FA disposals discovered during the year-end review trigger this recipe per asset.
|
|
191
233
|
- Month-end close: ad-hoc invocation when a disposal happens mid-period.
|
|
192
234
|
- `audit-prep.md` step 8: supporting schedule via `search_capsules(filter: {status: {eq: 'ACTIVE'}})` then narrow by date on the rows (**do not filter capsules by date**: `startDate`/`endDate` are declared on `CapsuleFilter` and pass validation, but every form of them answers `500 Internal Server Error` (measured 2026-09-07: `{gte}`, `{between}`, and `{gte}`+`{lte}` all 500)) plus per-capsule recompute via `clio calc asset-disposal`. Auditor tests proceeds against bank statements, NBV against FA register.
|
|
193
|
-
- `fa-review.md` job: annual FA register review identifies candidates for disposal (assets fully depreciated, assets no longer in use, assets damaged) →
|
|
194
|
-
- Sibling recipe `declining-balance.md`: depreciation up to the disposal date;
|
|
235
|
+
- `fa-review.md` job: annual FA register review identifies candidates for disposal (assets fully depreciated, assets no longer in use, assets damaged) → follow this recipe per identified disposal.
|
|
236
|
+
- Sibling recipe `declining-balance.md`: depreciation up to the disposal date; finalize all DRAFT depreciation journals BEFORE this recipe so NBV is correct.
|