jaz-cli 2.7.0 → 2.8.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/assets/skills/api/SKILL.md +1 -1
- package/assets/skills/conversion/SKILL.md +1 -1
- package/assets/skills/jobs/SKILL.md +104 -0
- package/assets/skills/jobs/references/audit-prep.md +319 -0
- package/assets/skills/jobs/references/bank-recon.md +234 -0
- package/assets/skills/jobs/references/building-blocks.md +135 -0
- package/assets/skills/jobs/references/credit-control.md +273 -0
- package/assets/skills/jobs/references/fa-review.md +267 -0
- package/assets/skills/jobs/references/gst-vat-filing.md +250 -0
- package/assets/skills/jobs/references/month-end-close.md +308 -0
- package/assets/skills/jobs/references/payment-run.md +246 -0
- package/assets/skills/jobs/references/quarter-end-close.md +268 -0
- package/assets/skills/jobs/references/supplier-recon.md +330 -0
- package/assets/skills/jobs/references/year-end-close.md +341 -0
- package/assets/skills/transaction-recipes/SKILL.md +1 -1
- package/dist/__tests__/jobs-audit-prep.test.js +125 -0
- package/dist/__tests__/jobs-bank-recon.test.js +108 -0
- package/dist/__tests__/jobs-credit-control.test.js +98 -0
- package/dist/__tests__/jobs-fa-review.test.js +104 -0
- package/dist/__tests__/jobs-gst-vat.test.js +113 -0
- package/dist/__tests__/jobs-month-end.test.js +162 -0
- package/dist/__tests__/jobs-payment-run.test.js +106 -0
- package/dist/__tests__/jobs-quarter-end.test.js +155 -0
- package/dist/__tests__/jobs-supplier-recon.test.js +115 -0
- package/dist/__tests__/jobs-validate.test.js +181 -0
- package/dist/__tests__/jobs-year-end.test.js +149 -0
- package/dist/commands/jobs.js +184 -0
- package/dist/index.js +2 -0
- package/dist/jobs/audit-prep.js +211 -0
- package/dist/jobs/bank-recon.js +163 -0
- package/dist/jobs/credit-control.js +126 -0
- package/dist/jobs/fa-review.js +121 -0
- package/dist/jobs/format.js +102 -0
- package/dist/jobs/gst-vat.js +187 -0
- package/dist/jobs/month-end.js +232 -0
- package/dist/jobs/payment-run.js +199 -0
- package/dist/jobs/quarter-end.js +135 -0
- package/dist/jobs/supplier-recon.js +132 -0
- package/dist/jobs/types.js +36 -0
- package/dist/jobs/validate.js +115 -0
- package/dist/jobs/year-end.js +153 -0
- package/dist/types/index.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Building Blocks for Accounting Jobs
|
|
2
|
+
|
|
3
|
+
Shared concepts that all jobs rely on. Read this first.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Accounting Periods
|
|
8
|
+
|
|
9
|
+
Jaz uses a **financial year** (FY) that may not match the calendar year. The org's FY start date determines period boundaries.
|
|
10
|
+
|
|
11
|
+
**Period formats used in jobs:**
|
|
12
|
+
- Month: `YYYY-MM` (e.g., `2025-01` = January 2025)
|
|
13
|
+
- Quarter: `YYYY-QN` (e.g., `2025-Q1` = Jan–Mar 2025 for calendar-year orgs)
|
|
14
|
+
- Year: `YYYY` (e.g., `2025` = full FY 2025)
|
|
15
|
+
|
|
16
|
+
**Period boundaries matter for:**
|
|
17
|
+
- Search filters (`valueDate between`) — determines which transactions are "in period"
|
|
18
|
+
- Report snapshots (`startDate`, `endDate`, `primarySnapshotDate`) — determines what the reports cover
|
|
19
|
+
- Lock dates — determines what can no longer be edited
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Lock Dates
|
|
24
|
+
|
|
25
|
+
Lock dates prevent backdated entries. Two levels:
|
|
26
|
+
|
|
27
|
+
| Level | What it locks | When to set |
|
|
28
|
+
|-------|--------------|-------------|
|
|
29
|
+
| **Org-wide** | All transactions before this date | After month/quarter/year-end close |
|
|
30
|
+
| **Per-account** | Specific CoA account locked before date | For bank accounts after recon, or controlled accounts |
|
|
31
|
+
|
|
32
|
+
**Setting lock dates via API:**
|
|
33
|
+
- Org lock date: managed through organization settings
|
|
34
|
+
- Per-account lock date: `lockDate` field on CoA account
|
|
35
|
+
|
|
36
|
+
**Best practice for SMBs:**
|
|
37
|
+
- Set org lock date after completing each month-end close
|
|
38
|
+
- Move it forward each month: Jan close → lock to 2025-01-31, Feb close → lock to 2025-02-28
|
|
39
|
+
- Only move lock date forward, never backward (unless correcting errors — requires admin)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Period Verification Pattern
|
|
44
|
+
|
|
45
|
+
Every job ends with a verification phase. The universal pattern:
|
|
46
|
+
|
|
47
|
+
### 1. Trial Balance Check
|
|
48
|
+
```
|
|
49
|
+
POST /generate-reports/trial-balance
|
|
50
|
+
{ "startDate": "YYYY-MM-01", "endDate": "YYYY-MM-DD" }
|
|
51
|
+
```
|
|
52
|
+
- Total debits MUST equal total credits
|
|
53
|
+
- No unexpected account balances (e.g., negative cash, negative inventory)
|
|
54
|
+
- Compare to prior period — flag significant variances
|
|
55
|
+
|
|
56
|
+
### 2. P&L Review
|
|
57
|
+
```
|
|
58
|
+
POST /generate-reports/profit-and-loss
|
|
59
|
+
{ "primarySnapshotDate": "YYYY-MM-DD", "secondarySnapshotDate": "YYYY-MM-01" }
|
|
60
|
+
```
|
|
61
|
+
- Revenue and expense trends should make sense
|
|
62
|
+
- One-off entries (accruals, adjustments) should be explainable
|
|
63
|
+
|
|
64
|
+
### 3. Balance Sheet Review
|
|
65
|
+
```
|
|
66
|
+
POST /generate-reports/balance-sheet
|
|
67
|
+
{ "primarySnapshotDate": "YYYY-MM-DD" }
|
|
68
|
+
```
|
|
69
|
+
- Assets = Liabilities + Equity (always, by definition)
|
|
70
|
+
- Bank balances match bank statements
|
|
71
|
+
- AR/AP aging ties to balance sheet control accounts
|
|
72
|
+
|
|
73
|
+
### 4. Bank Balance Reconciliation
|
|
74
|
+
```
|
|
75
|
+
POST /generate-reports/bank-balance-summary
|
|
76
|
+
{ "primarySnapshotDate": "YYYY-MM-DD" }
|
|
77
|
+
```
|
|
78
|
+
- Book balance per Jaz should match bank statement closing balance
|
|
79
|
+
- Differences = timing items (outstanding cheques, deposits in transit)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Scheduler Verification
|
|
84
|
+
|
|
85
|
+
Many month-end steps are automated via schedulers. Before closing, verify:
|
|
86
|
+
|
|
87
|
+
1. **Schedulers fired** — Check that recurring journals were created for the period
|
|
88
|
+
- `POST /journals/search` with capsule filter + valueDate in period
|
|
89
|
+
2. **Amounts correct** — Fixed schedulers should produce consistent amounts
|
|
90
|
+
3. **No duplicates** — If you manually posted a journal AND the scheduler fired, you'll double-count
|
|
91
|
+
|
|
92
|
+
**Common issue for SMBs:** Scheduler was set up mid-period or end date already passed. Always check before assuming automation handled it.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## Capsule Conventions for Jobs
|
|
97
|
+
|
|
98
|
+
Jobs reference capsules from transaction recipes. Standard capsule types:
|
|
99
|
+
|
|
100
|
+
| Capsule Type | Used By |
|
|
101
|
+
|-------------|---------|
|
|
102
|
+
| Prepaid Expenses | Prepaid amortization steps |
|
|
103
|
+
| Deferred Revenue | Revenue recognition steps |
|
|
104
|
+
| Accrued Expenses | Accrued expense steps |
|
|
105
|
+
| Loan Repayment | Loan interest accrual steps |
|
|
106
|
+
| Lease Accounting | IFRS 16 lease steps |
|
|
107
|
+
| Depreciation | Non-standard depreciation steps |
|
|
108
|
+
| FX Revaluation | Period-end FX revaluation |
|
|
109
|
+
| ECL Provision | Bad debt provision steps |
|
|
110
|
+
| Employee Benefits | Leave and bonus accrual steps |
|
|
111
|
+
|
|
112
|
+
**Verification shortcut:** Group the General Ledger by capsule to see the complete lifecycle of each multi-step workflow in one view.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Report API Quick Reference
|
|
117
|
+
|
|
118
|
+
Jobs frequently generate reports. The key endpoints and their required fields:
|
|
119
|
+
|
|
120
|
+
| Report | Endpoint | Required Fields |
|
|
121
|
+
|--------|----------|----------------|
|
|
122
|
+
| Trial Balance | `POST /generate-reports/trial-balance` | `startDate`, `endDate` |
|
|
123
|
+
| P&L | `POST /generate-reports/profit-and-loss` | `primarySnapshotDate`, `secondarySnapshotDate` |
|
|
124
|
+
| Balance Sheet | `POST /generate-reports/balance-sheet` | `primarySnapshotDate` |
|
|
125
|
+
| General Ledger | `POST /generate-reports/general-ledger` | `startDate`, `endDate`, `groupBy: "ACCOUNT"` |
|
|
126
|
+
| AR Aging | `POST /generate-reports/ar-report` | `endDate` |
|
|
127
|
+
| AP Aging | `POST /generate-reports/ap-report` | `endDate` |
|
|
128
|
+
| Cash Balance | `POST /generate-reports/cash-balance` | `reportDate` |
|
|
129
|
+
| Cashflow | `POST /generate-reports/cashflow` | `primaryStartDate`, `primaryEndDate` |
|
|
130
|
+
| Bank Balance | `POST /generate-reports/bank-balance-summary` | `primarySnapshotDate` |
|
|
131
|
+
| Tax Ledger | `POST /generate-reports/vat-ledger` | `startDate`, `endDate` |
|
|
132
|
+
| FA Register | `POST /generate-reports/fixed-assets-summary` | (check endpoint) |
|
|
133
|
+
| Equity Movement | `POST /generate-reports/equity-movement` | `primarySnapshotStartDate`, `primarySnapshotEndDate` |
|
|
134
|
+
|
|
135
|
+
**Data exports** (Excel/CSV) use `/data-exports/` with the same report names but simpler field names (e.g., P&L export uses `startDate`/`endDate` instead of snapshot dates).
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Credit Control / AR Chase
|
|
2
|
+
|
|
3
|
+
Systematically chase overdue customer invoices, assess collection risk, and manage bad debt exposure. This is not just "send reminders" — it's a structured process to protect your cash flow and recognize when receivables are impaired.
|
|
4
|
+
|
|
5
|
+
**CLI:** `jaz jobs credit-control [--overdue-days 30] [--json]`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Phase 1: Generate the AR Aging
|
|
10
|
+
|
|
11
|
+
The aging report is your starting point. Everything flows from this.
|
|
12
|
+
|
|
13
|
+
### Step 1: Generate AR aging report
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
POST /api/v1/generate-reports/ar-report
|
|
17
|
+
{ "endDate": "2025-02-28" }
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**What you get:** All outstanding customer invoices grouped by aging bucket (current, 1-30 days, 31-60 days, 61-90 days, 91-120 days, 120+ days), with totals per customer and grand totals.
|
|
21
|
+
|
|
22
|
+
### Step 2: Export for working paper (optional)
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
POST /api/v1/data-exports/ar-report
|
|
26
|
+
{ "endDate": "2025-02-28" }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Phase 2: Prioritize
|
|
32
|
+
|
|
33
|
+
### Step 3: Filter by overdue threshold
|
|
34
|
+
|
|
35
|
+
If `--overdue-days` is specified (e.g., 30), focus on invoices overdue by at least that many days. Otherwise, review all overdue items.
|
|
36
|
+
|
|
37
|
+
**Priority classification:**
|
|
38
|
+
|
|
39
|
+
| Priority | Overdue | Action |
|
|
40
|
+
|----------|---------|--------|
|
|
41
|
+
| **Critical** | 90+ days | Escalate to management, consider legal, assess bad debt |
|
|
42
|
+
| **High** | 60-90 days | Direct phone call, formal demand letter |
|
|
43
|
+
| **Medium** | 30-60 days | Follow-up email with statement of account |
|
|
44
|
+
| **Low** | 1-30 days | Gentle reminder, may be processing delay |
|
|
45
|
+
| **Current** | Not yet due | No action needed — monitor only |
|
|
46
|
+
|
|
47
|
+
### Step 4: Group by customer, sort by largest balance
|
|
48
|
+
|
|
49
|
+
From the AR aging data, rank customers by total overdue amount (descending). The 80/20 rule applies — a handful of customers typically account for most of your overdue AR.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Phase 3: Detailed Customer Review
|
|
54
|
+
|
|
55
|
+
For each overdue customer (starting with the largest balances), pull the full picture.
|
|
56
|
+
|
|
57
|
+
### Step 5: List outstanding invoices for a customer
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
POST /api/v1/invoices/search
|
|
61
|
+
{
|
|
62
|
+
"filter": {
|
|
63
|
+
"contactResourceId": { "eq": "<customer-uuid>" },
|
|
64
|
+
"status": { "eq": "POSTED" },
|
|
65
|
+
"balanceAmount": { "gt": 0 }
|
|
66
|
+
},
|
|
67
|
+
"sort": { "sortBy": ["dueDate"], "order": "ASC" },
|
|
68
|
+
"limit": 100
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**What to check per invoice:**
|
|
73
|
+
- `dueDate` — How overdue is it?
|
|
74
|
+
- `balanceAmount` — How much is still owed? (Could be partially paid)
|
|
75
|
+
- `reference` — The invoice number for follow-up correspondence
|
|
76
|
+
- `totalAmount` vs `balanceAmount` — Has the customer been making partial payments?
|
|
77
|
+
|
|
78
|
+
### Step 6: Check for unapplied credit notes
|
|
79
|
+
|
|
80
|
+
Before chasing, verify there are no unapplied customer credit notes that should reduce the balance:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
POST /api/v1/customer-credit-notes/search
|
|
84
|
+
{
|
|
85
|
+
"filter": {
|
|
86
|
+
"contactResourceId": { "eq": "<customer-uuid>" },
|
|
87
|
+
"status": { "eq": "POSTED" }
|
|
88
|
+
},
|
|
89
|
+
"sort": { "sortBy": ["valueDate"], "order": "DESC" },
|
|
90
|
+
"limit": 50
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If there are unapplied credit notes, apply them before chasing:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
POST /api/v1/invoices/{invoiceResourceId}/credits
|
|
98
|
+
{
|
|
99
|
+
"credits": [
|
|
100
|
+
{ "creditNoteResourceId": "<credit-note-uuid>", "amountApplied": 500.00 }
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Step 7: Generate statement of account
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
POST /api/v1/statement-of-account-export
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The statement of account is what you send to the customer — it shows all invoices, payments, and the running balance. Attach this to follow-up communications.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Phase 4: Follow-Up Priority List
|
|
116
|
+
|
|
117
|
+
### Step 8: Build the chase list
|
|
118
|
+
|
|
119
|
+
For each overdue customer, document:
|
|
120
|
+
|
|
121
|
+
| Customer | Total Overdue | Oldest Invoice | Days Overdue | Priority | Action |
|
|
122
|
+
|----------|--------------|----------------|--------------|----------|--------|
|
|
123
|
+
| Acme Corp | $45,000 | INV-1023 | 95 | Critical | Phone + demand letter |
|
|
124
|
+
| Beta Ltd | $12,500 | INV-1089 | 62 | High | Phone call |
|
|
125
|
+
| Gamma Inc | $3,200 | INV-1134 | 35 | Medium | Email reminder |
|
|
126
|
+
|
|
127
|
+
**Escalation process (typical SMB):**
|
|
128
|
+
|
|
129
|
+
1. **Day 1-7 overdue:** Automated or gentle email reminder with invoice attached
|
|
130
|
+
2. **Day 14 overdue:** Second reminder, direct email to AP contact
|
|
131
|
+
3. **Day 30 overdue:** Phone call to AP contact, request payment commitment date
|
|
132
|
+
4. **Day 45 overdue:** Escalate to customer's management, send statement of account
|
|
133
|
+
5. **Day 60 overdue:** Formal demand letter, consider suspending future sales on credit
|
|
134
|
+
6. **Day 90 overdue:** Final demand, engage collections agency or legal counsel
|
|
135
|
+
7. **Day 120+ overdue:** Write off if uncollectable (see Phase 5)
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Phase 5: Bad Debt Assessment
|
|
140
|
+
|
|
141
|
+
**Conditional:** Only if there are material amounts in the 90+ day aging bucket.
|
|
142
|
+
|
|
143
|
+
### Step 9: Assess bad debt risk
|
|
144
|
+
|
|
145
|
+
For invoices that appear uncollectable, evaluate using the ECL (Expected Credit Loss) model:
|
|
146
|
+
|
|
147
|
+
**Calculator:** `jaz calc ecl`
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
jaz calc ecl --current 100000 --30d 50000 --60d 20000 --90d 10000 --120d 5000 --rates 0.5,2,5,10,50
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
This produces the provision matrix — the estimated total bad debt exposure based on aging buckets and historical loss rates.
|
|
154
|
+
|
|
155
|
+
**Recipe:** `bad-debt-provision` — see `transaction-recipes/references/bad-debt-provision.md` for the full ECL provision pattern.
|
|
156
|
+
|
|
157
|
+
### Step 10: Record bad debt write-off (if uncollectable)
|
|
158
|
+
|
|
159
|
+
When a specific invoice is confirmed uncollectable (customer bankrupt, dissolved, or dispute resolution failed), write it off:
|
|
160
|
+
|
|
161
|
+
**Option A: Customer credit note + write-off journal**
|
|
162
|
+
|
|
163
|
+
Create a customer credit note to clear the invoice balance:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
POST /api/v1/customer-credit-notes
|
|
167
|
+
{
|
|
168
|
+
"contactResourceId": "<customer-uuid>",
|
|
169
|
+
"saveAsDraft": false,
|
|
170
|
+
"reference": "CN-BADDEBT-001",
|
|
171
|
+
"valueDate": "2025-02-28",
|
|
172
|
+
"lineItems": [{
|
|
173
|
+
"name": "Bad debt write-off — INV-1023",
|
|
174
|
+
"unitPrice": 45000.00,
|
|
175
|
+
"quantity": 1,
|
|
176
|
+
"accountResourceId": "<bad-debt-expense-uuid>"
|
|
177
|
+
}]
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Then apply the credit note to the invoice:
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
POST /api/v1/invoices/{invoiceResourceId}/credits
|
|
185
|
+
{
|
|
186
|
+
"credits": [
|
|
187
|
+
{ "creditNoteResourceId": "<credit-note-uuid>", "amountApplied": 45000.00 }
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Option B: Use DEBT_WRITE_OFF payment method**
|
|
193
|
+
|
|
194
|
+
Record as a payment using the special write-off method:
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
POST /api/v1/invoices/{invoiceResourceId}/payments
|
|
198
|
+
{
|
|
199
|
+
"payments": [{
|
|
200
|
+
"paymentAmount": 45000.00,
|
|
201
|
+
"transactionAmount": 45000.00,
|
|
202
|
+
"accountResourceId": "<bad-debt-expense-uuid>",
|
|
203
|
+
"paymentMethod": "DEBT_WRITE_OFF",
|
|
204
|
+
"reference": "WRITEOFF-INV-1023",
|
|
205
|
+
"valueDate": "2025-02-28"
|
|
206
|
+
}]
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Accounting effect:** DR Bad Debt Expense, CR Accounts Receivable — removes the receivable from the books and recognizes the expense.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Phase 6: Verification
|
|
215
|
+
|
|
216
|
+
### Step 11: Re-run AR aging after actions
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
POST /api/v1/generate-reports/ar-report
|
|
220
|
+
{ "endDate": "2025-02-28" }
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**What to check:**
|
|
224
|
+
- Credit notes have reduced the correct invoice balances
|
|
225
|
+
- Written-off invoices no longer appear in the aging
|
|
226
|
+
- Total AR ties to the Accounts Receivable balance on the trial balance
|
|
227
|
+
|
|
228
|
+
### Step 12: Review trial balance impact
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
POST /api/v1/generate-reports/trial-balance
|
|
232
|
+
{ "startDate": "2025-02-01", "endDate": "2025-02-28" }
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**What to check:**
|
|
236
|
+
- Accounts Receivable balance reflects all collections, credit notes, and write-offs
|
|
237
|
+
- Bad Debt Expense (if write-offs were made) shows the correct amount
|
|
238
|
+
- Allowance for Doubtful Debts (if using provision method) reflects the ECL calculation
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Credit Control Checklist (Quick Reference)
|
|
243
|
+
|
|
244
|
+
| # | Step | Phase | Conditional |
|
|
245
|
+
|---|------|-------|-------------|
|
|
246
|
+
| 1 | Generate AR aging | Assess | Always |
|
|
247
|
+
| 2 | Export working paper | Assess | Optional |
|
|
248
|
+
| 3 | Filter by overdue threshold | Prioritize | If --overdue-days specified |
|
|
249
|
+
| 4 | Group by customer | Prioritize | Always |
|
|
250
|
+
| 5 | List outstanding invoices | Review | Always |
|
|
251
|
+
| 6 | Check unapplied credit notes | Review | Always |
|
|
252
|
+
| 7 | Generate statement of account | Review | Always |
|
|
253
|
+
| 8 | Build chase list | Follow-up | Always |
|
|
254
|
+
| 9 | Assess bad debt (ECL) | Bad debt | If material 90d+ balances |
|
|
255
|
+
| 10 | Record write-off | Bad debt | If confirmed uncollectable |
|
|
256
|
+
| 11 | Re-run AR aging | Verify | Always |
|
|
257
|
+
| 12 | Review trial balance | Verify | Always |
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Tips for SMBs
|
|
262
|
+
|
|
263
|
+
**Typical credit terms:** Net 30 is standard in Singapore. Some industries use Net 60 or Net 14. Whatever your terms, enforce them consistently — if you let one customer pay at 60 when terms are 30, everyone will.
|
|
264
|
+
|
|
265
|
+
**Prevention is cheaper than collection.** Before extending credit to a new customer, do a basic credit check (ACRA business profile for SG companies, $5.50). Set a credit limit and stick to it.
|
|
266
|
+
|
|
267
|
+
**The phone is more effective than email.** After 30 days, email follow-ups have diminishing returns. A 5-minute phone call to the AP department resolves more overdue invoices than 10 emails.
|
|
268
|
+
|
|
269
|
+
**Document everything.** Keep records of all follow-up attempts (dates, who you spoke to, commitments made). If it goes to legal, you need an evidence trail.
|
|
270
|
+
|
|
271
|
+
**When to involve legal:** If the amount exceeds $20,000 and the customer is unresponsive after 90 days, consider a letter of demand from a lawyer ($300-500). For amounts under $10,000, the Small Claims Tribunal (SG) is a cost-effective option.
|
|
272
|
+
|
|
273
|
+
**Bad debt tax deduction (SG):** Bad debts written off are deductible for income tax purposes if you can prove the debt is genuinely irrecoverable and reasonable steps were taken to collect. Keep documentation.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Fixed Asset Review
|
|
2
|
+
|
|
3
|
+
Review the fixed asset register for accuracy, identify assets requiring disposal or write-off, process disposals, and reconcile the register to the trial balance. This is a housekeeping job — ensuring the FA register reflects reality.
|
|
4
|
+
|
|
5
|
+
**CLI:** `jaz jobs fa-review [--json]`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## When to Do This
|
|
10
|
+
|
|
11
|
+
- **Annually (minimum):** As part of year-end close or audit preparation
|
|
12
|
+
- **Quarterly:** For growing businesses that acquire assets frequently
|
|
13
|
+
- **Ad-hoc:** After a major event (office move, equipment upgrade, insurance claim)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Phase 1: Take Stock
|
|
18
|
+
|
|
19
|
+
### Step 1: List all fixed assets
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
POST /api/v1/fixed-assets/search
|
|
23
|
+
{
|
|
24
|
+
"filter": { "status": { "eq": "ACTIVE" } },
|
|
25
|
+
"sort": { "sortBy": ["purchaseDate"], "order": "ASC" },
|
|
26
|
+
"limit": 1000
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**What you get:** Every active fixed asset with `name`, `purchaseDate`, `purchaseAmount`, `bookValueAmount`, `depreciationMethod`, `typeName`, and `status`.
|
|
31
|
+
|
|
32
|
+
### Step 2: List fixed asset types
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
POST /api/v1/fixed-assets-types/search
|
|
36
|
+
{
|
|
37
|
+
"filter": {},
|
|
38
|
+
"sort": { "sortBy": ["typeName"], "order": "ASC" },
|
|
39
|
+
"limit": 100
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Asset types define the default depreciation method and useful life. Common types for SMBs:
|
|
44
|
+
|
|
45
|
+
| Type | Typical Useful Life | Depreciation | Examples |
|
|
46
|
+
|------|-------------------|--------------|----------|
|
|
47
|
+
| **Office Equipment** | 5-7 years | Straight-line | Desks, chairs, shelving |
|
|
48
|
+
| **Computer Equipment** | 3-5 years | Straight-line or DDB | Laptops, servers, monitors |
|
|
49
|
+
| **Motor Vehicles** | 5-8 years | Straight-line | Delivery vans, company cars |
|
|
50
|
+
| **Furniture & Fittings** | 7-10 years | Straight-line | Reception area, meeting rooms |
|
|
51
|
+
| **Leasehold Improvements** | Lease term | Straight-line | Renovation, fit-out |
|
|
52
|
+
| **Plant & Machinery** | 5-15 years | Straight-line or DDB | Production equipment |
|
|
53
|
+
| **Software** | 3-5 years | Straight-line | Licensed software, ERP |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Phase 2: Review
|
|
58
|
+
|
|
59
|
+
Work through the asset list and classify each asset.
|
|
60
|
+
|
|
61
|
+
### Step 3: Identify fully depreciated assets still in use
|
|
62
|
+
|
|
63
|
+
Search for assets where book value equals zero (or equals salvage value):
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
POST /api/v1/fixed-assets/search
|
|
67
|
+
{
|
|
68
|
+
"filter": {
|
|
69
|
+
"status": { "eq": "ACTIVE" },
|
|
70
|
+
"bookValueAmount": { "eq": 0 }
|
|
71
|
+
},
|
|
72
|
+
"sort": { "sortBy": ["purchaseDate"], "order": "ASC" },
|
|
73
|
+
"limit": 1000
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**What to do:**
|
|
78
|
+
- If the asset is still in use → no action required. It stays on the register at zero NBV. No further depreciation is posted.
|
|
79
|
+
- If the asset is no longer in use → dispose (Phase 3)
|
|
80
|
+
|
|
81
|
+
**Note:** Fully depreciated assets still in use should be reviewed for impairment reversal under IAS 36 if their recoverable amount is significantly higher than carrying amount (zero). In practice, most SMBs don't reverse — the asset just sits at zero until disposal.
|
|
82
|
+
|
|
83
|
+
### Step 4: Identify assets no longer in use
|
|
84
|
+
|
|
85
|
+
This is a physical verification step — walk through the office/warehouse and compare the register to reality. Common findings:
|
|
86
|
+
|
|
87
|
+
- **Thrown away but not written off:** Old laptops, broken equipment disposed of without updating the register
|
|
88
|
+
- **Lost or stolen:** Equipment that can't be located
|
|
89
|
+
- **Returned under warranty:** Asset was replaced but the old entry wasn't removed
|
|
90
|
+
- **Sold informally:** Asset was sold (e.g., to an employee) but the sale wasn't recorded
|
|
91
|
+
|
|
92
|
+
**Flag these for disposal in Phase 3.**
|
|
93
|
+
|
|
94
|
+
### Step 5: Review depreciation methods
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
POST /api/v1/fixed-assets/search
|
|
98
|
+
{
|
|
99
|
+
"filter": { "status": { "eq": "ACTIVE" } },
|
|
100
|
+
"sort": { "sortBy": ["typeName"], "order": "ASC" },
|
|
101
|
+
"limit": 1000
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Group by asset type and verify:
|
|
106
|
+
- All assets of the same type use the same depreciation method (consistency principle)
|
|
107
|
+
- Useful lives are reasonable for the asset type
|
|
108
|
+
- No assets have an obviously wrong method (e.g., a building on 3-year straight-line)
|
|
109
|
+
|
|
110
|
+
**Conditional:** Only act on this if you find inconsistencies. Changing depreciation method mid-life is a change in accounting estimate (IAS 8) — apply prospectively, not retrospectively.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Phase 3: Disposals
|
|
115
|
+
|
|
116
|
+
### Step 6: Sale disposals
|
|
117
|
+
|
|
118
|
+
When an asset is sold, record the disposal. The calculator computes accumulated depreciation to disposal date, net book value, and gain/loss.
|
|
119
|
+
|
|
120
|
+
**Calculator:** `jaz calc asset-disposal`
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
jaz calc asset-disposal --cost 50000 --salvage 5000 --life 5 --acquired 2022-01-01 --disposed 2025-06-15 --proceeds 12000
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Recipe:** `asset-disposal` — see `transaction-recipes/references/asset-disposal.md` for the full journal pattern.
|
|
127
|
+
|
|
128
|
+
Record the disposal journal:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
POST /api/v1/journals
|
|
132
|
+
{
|
|
133
|
+
"saveAsDraft": false,
|
|
134
|
+
"reference": "FA-DISP-001",
|
|
135
|
+
"valueDate": "2025-06-15",
|
|
136
|
+
"journalEntries": [
|
|
137
|
+
{ "accountResourceId": "<bank-account-uuid>", "amount": 12000.00, "type": "DEBIT", "name": "Proceeds from sale of Delivery Van VH-1234" },
|
|
138
|
+
{ "accountResourceId": "<accumulated-depreciation-uuid>", "amount": 31500.00, "type": "DEBIT", "name": "Clear accumulated depreciation — Delivery Van VH-1234" },
|
|
139
|
+
{ "accountResourceId": "<loss-on-disposal-uuid>", "amount": 6500.00, "type": "DEBIT", "name": "Loss on disposal — Delivery Van VH-1234" },
|
|
140
|
+
{ "accountResourceId": "<fixed-asset-cost-uuid>", "amount": 50000.00, "type": "CREDIT", "name": "Remove cost — Delivery Van VH-1234" }
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then mark the asset as sold in the FA register:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
POST /api/v1/mark-as-sold/fixed-assets
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Step 7: Scrap / write-off disposals
|
|
152
|
+
|
|
153
|
+
When an asset is scrapped (no sale proceeds), the full NBV becomes a loss.
|
|
154
|
+
|
|
155
|
+
**Calculator:**
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
jaz calc asset-disposal --cost 50000 --salvage 5000 --life 5 --acquired 2022-01-01 --disposed 2025-06-15 --proceeds 0
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Record the write-off journal:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
POST /api/v1/journals
|
|
165
|
+
{
|
|
166
|
+
"saveAsDraft": false,
|
|
167
|
+
"reference": "FA-WRITEOFF-001",
|
|
168
|
+
"valueDate": "2025-06-15",
|
|
169
|
+
"journalEntries": [
|
|
170
|
+
{ "accountResourceId": "<accumulated-depreciation-uuid>", "amount": 31500.00, "type": "DEBIT", "name": "Clear accumulated depreciation — Old Server Rack" },
|
|
171
|
+
{ "accountResourceId": "<loss-on-disposal-uuid>", "amount": 18500.00, "type": "DEBIT", "name": "Write-off loss — Old Server Rack" },
|
|
172
|
+
{ "accountResourceId": "<fixed-asset-cost-uuid>", "amount": 50000.00, "type": "CREDIT", "name": "Remove cost — Old Server Rack" }
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Then mark the asset as discarded:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
POST /api/v1/discard-fixed-assets/{assetResourceId}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Phase 4: Verification
|
|
186
|
+
|
|
187
|
+
### Step 8: FA register reconciliation
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
POST /api/v1/generate-reports/fixed-assets-summary
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
POST /api/v1/generate-reports/fixed-assets-recon-summary
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The reconciliation report shows:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
Opening NBV (start of period)
|
|
201
|
+
+ Additions (new assets acquired)
|
|
202
|
+
- Disposals (sold or scrapped)
|
|
203
|
+
- Depreciation (period charge)
|
|
204
|
+
= Closing NBV (end of period)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Step 9: Reconcile to trial balance
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
POST /api/v1/generate-reports/trial-balance
|
|
211
|
+
{ "startDate": "2025-01-01", "endDate": "2025-12-31" }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**What must tie:**
|
|
215
|
+
|
|
216
|
+
| FA Register | Trial Balance Account |
|
|
217
|
+
|------------|----------------------|
|
|
218
|
+
| Total cost (all active assets) | Fixed Assets (at cost) — total of all FA cost accounts |
|
|
219
|
+
| Total accumulated depreciation | Accumulated Depreciation — total of all accum. dep. accounts |
|
|
220
|
+
| Closing NBV | Cost minus Accumulated Depreciation = Net Book Value |
|
|
221
|
+
| Period depreciation charge | Depreciation Expense on P&L |
|
|
222
|
+
| Gain/Loss on disposal | Other Income / Other Expense on P&L |
|
|
223
|
+
|
|
224
|
+
If the register and trial balance don't tie, investigate:
|
|
225
|
+
- Manual journal entries to FA accounts that bypassed the register
|
|
226
|
+
- FA register entries that didn't generate journals (system issue)
|
|
227
|
+
- Disposed assets not yet removed from the register
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## FA Review Checklist (Quick Reference)
|
|
232
|
+
|
|
233
|
+
| # | Step | Phase | What |
|
|
234
|
+
|---|------|-------|------|
|
|
235
|
+
| 1 | List all fixed assets | Take stock | Search active assets |
|
|
236
|
+
| 2 | List asset types | Take stock | Review type definitions |
|
|
237
|
+
| 3 | Fully depreciated assets | Review | Identify NBV = 0 assets |
|
|
238
|
+
| 4 | Assets no longer in use | Review | Physical verification |
|
|
239
|
+
| 5 | Depreciation methods | Review | Consistency check |
|
|
240
|
+
| 6 | Sale disposals | Dispose | Calculator + journal + mark as sold |
|
|
241
|
+
| 7 | Scrap / write-off | Dispose | Calculator + journal + discard |
|
|
242
|
+
| 8 | FA register report | Verify | Reconciliation summary |
|
|
243
|
+
| 9 | Reconcile to trial balance | Verify | FA register = TB accounts |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Tips for SMBs
|
|
248
|
+
|
|
249
|
+
**Keep a low-value asset threshold.** Items under $1,000 (or your chosen threshold) should be expensed immediately, not capitalized as fixed assets. This reduces register clutter and depreciation complexity. Common SG practice is $1,000-$5,000 depending on company size.
|
|
250
|
+
|
|
251
|
+
**Tag your assets.** Use physical asset tags (numbered stickers) and record the tag number as the asset reference in Jaz. This makes physical verification much faster.
|
|
252
|
+
|
|
253
|
+
**Review useful lives annually.** If your "3-year laptop" is still going strong at year 5, the useful life estimate was wrong. Adjust prospectively (IAS 8) — extend the remaining life and recalculate monthly depreciation.
|
|
254
|
+
|
|
255
|
+
**Depreciation for tax (SG-specific):**
|
|
256
|
+
- IRAS allows 1-year write-off for assets costing <= S$5,000 (Section 19A(10A))
|
|
257
|
+
- IRAS allows 3-year accelerated write-off for all other assets (Section 19A)
|
|
258
|
+
- Book depreciation (straight-line over useful life) and tax depreciation (accelerated) can differ — track the deferred tax difference
|
|
259
|
+
|
|
260
|
+
**Insurance coverage check.** While reviewing assets, verify that your business insurance covers the replacement cost of active assets. Fully depreciated assets may still have significant replacement value — a 5-year-old server at $0 NBV still costs $15,000 to replace.
|
|
261
|
+
|
|
262
|
+
**Common FA accounts in Jaz:**
|
|
263
|
+
- Fixed Assets (at cost) — typically one sub-account per asset type
|
|
264
|
+
- Accumulated Depreciation — mirror sub-accounts for each asset type
|
|
265
|
+
- Depreciation Expense — on P&L, may be split by asset type for reporting
|
|
266
|
+
- Gain on Disposal — Other Income
|
|
267
|
+
- Loss on Disposal — Other Expense
|