jaz-cli 2.6.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 +12 -2
- package/assets/skills/api/references/dependencies.md +3 -2
- package/assets/skills/api/references/endpoints.md +78 -0
- package/assets/skills/api/references/feature-glossary.md +4 -4
- package/assets/skills/api/references/field-map.md +17 -0
- package/assets/skills/api/references/full-api-surface.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__/amortization.test.js +101 -0
- package/dist/__tests__/asset-disposal.test.js +249 -0
- package/dist/__tests__/blueprint.test.js +72 -0
- package/dist/__tests__/depreciation.test.js +125 -0
- package/dist/__tests__/ecl.test.js +134 -0
- package/dist/__tests__/fixed-deposit.test.js +214 -0
- package/dist/__tests__/fx-reval.test.js +115 -0
- 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/__tests__/lease.test.js +96 -0
- package/dist/__tests__/loan.test.js +80 -0
- package/dist/__tests__/provision.test.js +141 -0
- package/dist/__tests__/validate.test.js +81 -0
- package/dist/calc/asset-disposal.js +17 -13
- package/dist/calc/fixed-deposit.js +26 -17
- package/dist/calc/lease.js +7 -3
- 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 +5 -2
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# Year-End Close
|
|
2
|
+
|
|
3
|
+
The annual close builds on the quarterly close. It is quarter-end close repeated four times, plus a set of year-end-specific adjustments — true-ups, dividends, retained earnings rollover, final GST reconciliation, and audit preparation. For most SMBs, the annual extras add 2-5 days of work depending on complexity and whether an external audit is required.
|
|
4
|
+
|
|
5
|
+
**CLI:** `jaz jobs year-end --period 2025 [--currency SGD] [--json]`
|
|
6
|
+
|
|
7
|
+
**Standalone vs Incremental:**
|
|
8
|
+
- **Standalone (default):** Generates the full plan — all quarterly close steps for each of the four quarters, followed by the annual extras. Use this when quarters haven't been closed yet.
|
|
9
|
+
- **Incremental (`--incremental`):** Generates only the annual extras below. Use this when all four quarters are already closed and locked.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Phase 1–7: Quarterly Close (x4)
|
|
14
|
+
|
|
15
|
+
Complete the full quarter-end close for each quarter in the year. Each quarter follows the monthly close (x3) plus quarterly extras pattern.
|
|
16
|
+
|
|
17
|
+
**Reference:** `references/quarter-end-close.md`
|
|
18
|
+
|
|
19
|
+
| FY | Q1 | Q2 | Q3 | Q4 |
|
|
20
|
+
|----|----|----|----|----|
|
|
21
|
+
| Calendar year | Jan–Mar | Apr–Jun | Jul–Sep | Oct–Dec |
|
|
22
|
+
|
|
23
|
+
**Important:** Close quarters in order. Q1 must be locked before starting Q2, and so on. The annual extras run after Q4 is closed. By the time you reach this phase, all 12 months are individually closed, all four quarterly GST returns are filed, and all quarterly provisions are up to date.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Phase 8: Annual Extras
|
|
28
|
+
|
|
29
|
+
These steps run once per year, after all four quarters are closed. They address items that are inherently annual — full-year depreciation reconciliation, true-ups against actuals, dividends, retained earnings rollover, and audit preparation.
|
|
30
|
+
|
|
31
|
+
### Step Y1: Final depreciation run
|
|
32
|
+
|
|
33
|
+
Verify the full year's depreciation is correctly recorded and reconciles to the fixed asset register.
|
|
34
|
+
|
|
35
|
+
**Recipe:** `declining-balance` | **Calculator:** `jaz calc depreciation`
|
|
36
|
+
|
|
37
|
+
**Step-by-step:**
|
|
38
|
+
|
|
39
|
+
1. Pull the fixed asset register as at year-end:
|
|
40
|
+
```
|
|
41
|
+
POST /generate-reports/fixed-assets-summary
|
|
42
|
+
{}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. For each asset class, verify that 12 months of depreciation have been recorded. If using Jaz native FA depreciation (straight-line), this should be automatic. If using manual journals for non-standard methods (DDB, 150DB), verify all 12 monthly entries exist.
|
|
46
|
+
|
|
47
|
+
3. Run the calculator for each non-standard asset to confirm the full-year charge:
|
|
48
|
+
```bash
|
|
49
|
+
jaz calc depreciation --cost 50000 --salvage 5000 --life 5 --method ddb --frequency monthly --json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
4. Reconcile accumulated depreciation per the FA register to accumulated depreciation per the trial balance:
|
|
53
|
+
```
|
|
54
|
+
POST /generate-reports/trial-balance
|
|
55
|
+
{ "startDate": "2025-01-01", "endDate": "2025-12-31" }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**What to check:**
|
|
59
|
+
- Depreciation expense on P&L = sum of all 12 monthly depreciation charges
|
|
60
|
+
- Accumulated depreciation on balance sheet = prior year balance + current year depreciation - accumulated depreciation on disposed assets
|
|
61
|
+
- FA register NBV (net book value) per asset ties to the balance sheet total
|
|
62
|
+
- No asset has been depreciated below its salvage value
|
|
63
|
+
|
|
64
|
+
**Conditional:** Always, if fixed assets exist. Even if depreciation runs automatically, verify it at year-end. Auditors will test this.
|
|
65
|
+
|
|
66
|
+
### Step Y2: Year-end true-ups
|
|
67
|
+
|
|
68
|
+
Reconcile accruals to actuals and post adjustments. Three components:
|
|
69
|
+
|
|
70
|
+
#### a) Leave balance true-up
|
|
71
|
+
|
|
72
|
+
Monthly closes accrued a fixed amount for leave liability. At year-end, reconcile to actual leave balances.
|
|
73
|
+
|
|
74
|
+
**Recipe:** `employee-accruals`
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
POST /journals
|
|
78
|
+
{
|
|
79
|
+
"valueDate": "2025-12-31",
|
|
80
|
+
"reference": "YE-LEAVE-TRUEUP-FY25",
|
|
81
|
+
"journalEntries": [
|
|
82
|
+
{ "accountResourceId": "<leave-expense>", "amount": 3200.00, "type": "DEBIT", "name": "Leave accrual true-up — FY2025 (actual vs accrued)" },
|
|
83
|
+
{ "accountResourceId": "<leave-liability>", "amount": 3200.00, "type": "CREDIT", "name": "Leave accrual true-up — FY2025 (actual vs accrued)" }
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**What to check:** Leave liability on balance sheet should equal (unused leave days x daily rate) for each employee. If accrual > actual, reverse the excess (DR Leave Liability, CR Leave Expense).
|
|
89
|
+
|
|
90
|
+
**Conditional:** Only if you track leave balances in the books. Most SMBs with 5+ employees should.
|
|
91
|
+
|
|
92
|
+
#### b) Bonus true-up
|
|
93
|
+
|
|
94
|
+
Quarterly closes maintained the bonus accrual estimate. At year-end, true up to actual bonus amounts declared.
|
|
95
|
+
|
|
96
|
+
**Recipe:** `employee-accruals` (bonus component)
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
POST /journals
|
|
100
|
+
{
|
|
101
|
+
"valueDate": "2025-12-31",
|
|
102
|
+
"reference": "YE-BONUS-TRUEUP-FY25",
|
|
103
|
+
"journalEntries": [
|
|
104
|
+
{ "accountResourceId": "<bonus-expense>", "amount": 5000.00, "type": "DEBIT", "name": "Bonus true-up — FY2025 (actual declared vs accrued)" },
|
|
105
|
+
{ "accountResourceId": "<bonus-liability>", "amount": 5000.00, "type": "CREDIT", "name": "Bonus true-up — FY2025 (actual declared vs accrued)" }
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**What to check:** Bonus liability on balance sheet = actual bonuses declared but not yet paid. If over-accrued, reverse the excess.
|
|
111
|
+
|
|
112
|
+
**Conditional:** Only if the business has bonus schemes.
|
|
113
|
+
|
|
114
|
+
#### c) Provision reassessment (IAS 37)
|
|
115
|
+
|
|
116
|
+
At year-end, reassess all provisions — not just unwind the discount, but review whether the provision amount itself is still the best estimate.
|
|
117
|
+
|
|
118
|
+
**Recipe:** `provisions`
|
|
119
|
+
|
|
120
|
+
**What to check for each provision:**
|
|
121
|
+
- Is the obligating event still valid? (If resolved, release the provision.)
|
|
122
|
+
- Has the best estimate changed? (Adjust up or down.)
|
|
123
|
+
- Has the discount rate changed? (Re-measure at current rate, post the difference.)
|
|
124
|
+
- Has the expected settlement date changed? (Adjust the unwinding schedule.)
|
|
125
|
+
|
|
126
|
+
Post adjustment journals for any changes. Document the reasoning — auditors will review provision assessments.
|
|
127
|
+
|
|
128
|
+
**Conditional:** Only if IAS 37 provisions exist. Most simple SMBs can skip this.
|
|
129
|
+
|
|
130
|
+
### Step Y3: Dividend declaration and payment
|
|
131
|
+
|
|
132
|
+
If the business is declaring dividends for the fiscal year, post two journals — one for declaration and one for payment. These are distinct accounting events.
|
|
133
|
+
|
|
134
|
+
**Recipe:** `dividend`
|
|
135
|
+
|
|
136
|
+
#### Declaration (board resolution date):
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
POST /journals
|
|
140
|
+
{
|
|
141
|
+
"valueDate": "2025-12-31",
|
|
142
|
+
"reference": "YE-DIV-DECLARE-FY25",
|
|
143
|
+
"journalEntries": [
|
|
144
|
+
{ "accountResourceId": "<retained-earnings>", "amount": 50000.00, "type": "DEBIT", "name": "Dividend declared — FY2025" },
|
|
145
|
+
{ "accountResourceId": "<dividends-payable>", "amount": 50000.00, "type": "CREDIT", "name": "Dividend declared — FY2025" }
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Payment (actual payment date):
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
POST /journals
|
|
154
|
+
{
|
|
155
|
+
"valueDate": "2026-01-15",
|
|
156
|
+
"reference": "YE-DIV-PAY-FY25",
|
|
157
|
+
"journalEntries": [
|
|
158
|
+
{ "accountResourceId": "<dividends-payable>", "amount": 50000.00, "type": "DEBIT", "name": "Dividend paid — FY2025" },
|
|
159
|
+
{ "accountResourceId": "<bank-account>", "amount": 50000.00, "type": "CREDIT", "name": "Dividend paid — FY2025" }
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Note:** Declaration often falls in the current FY (e.g., Dec 31), but payment may fall in the next FY (e.g., Jan 15). The declaration journal reduces retained earnings in the current year. The payment journal just clears the liability — no P&L impact.
|
|
165
|
+
|
|
166
|
+
**For Singapore:** Dividends are tax-exempt in the hands of the shareholder (one-tier system). No withholding tax. No additional tax journal needed.
|
|
167
|
+
|
|
168
|
+
**For Philippines:** Dividends to resident individuals are subject to 10% final withholding tax. Post the withholding tax separately (DR Dividends Payable, CR Withholding Tax Payable) and remit to BIR.
|
|
169
|
+
|
|
170
|
+
**Conditional:** Only if the business is declaring dividends. Many SMBs retain all earnings. Skip if no dividend resolution.
|
|
171
|
+
|
|
172
|
+
### Step Y4: Retained earnings rollover (Current Year Earnings)
|
|
173
|
+
|
|
174
|
+
Jaz auto-manages the annual rollover of Current Year Earnings (CYE) into Retained Earnings at the start of each new fiscal year. The net P&L for the year is accumulated in CYE during the year, then rolled forward.
|
|
175
|
+
|
|
176
|
+
**What to verify:**
|
|
177
|
+
|
|
178
|
+
1. Pull the equity movement report:
|
|
179
|
+
```
|
|
180
|
+
POST /generate-reports/equity-movement
|
|
181
|
+
{ "primarySnapshotStartDate": "2025-01-01", "primarySnapshotEndDate": "2025-12-31" }
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
2. Confirm:
|
|
185
|
+
- CYE balance at year-end = Net profit (or loss) for the year per P&L
|
|
186
|
+
- Retained Earnings opening balance = prior year closing Retained Earnings
|
|
187
|
+
- After rollover (in the new year): CYE resets to zero, Retained Earnings increases by last year's net profit (less any dividends declared)
|
|
188
|
+
|
|
189
|
+
**Tip:** If CYE doesn't match the P&L bottom line, there's a posting error somewhere — most likely a journal posted directly to an equity account that shouldn't have been.
|
|
190
|
+
|
|
191
|
+
**No journal needed** — this is a platform-managed rollover. Your job is to verify it happened correctly.
|
|
192
|
+
|
|
193
|
+
### Step Y5: Final GST/VAT reconciliation
|
|
194
|
+
|
|
195
|
+
Reconcile the full year's GST/VAT against all four quarterly returns (or twelve monthly returns for PH).
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
POST /generate-reports/vat-ledger
|
|
199
|
+
{ "startDate": "2025-01-01", "endDate": "2025-12-31" }
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**What to check:**
|
|
203
|
+
|
|
204
|
+
1. Annual output tax per tax ledger = sum of output tax across all four quarterly returns
|
|
205
|
+
2. Annual input tax per tax ledger = sum of input tax across all four quarterly returns
|
|
206
|
+
3. Net GST paid/refunded during the year = sum of all quarterly GST payments/refunds
|
|
207
|
+
4. GST control account on trial balance = net GST payable/receivable for Q4 (if Q1–Q3 already settled)
|
|
208
|
+
5. No orphan transactions — every taxable invoice and bill is accounted for in the tax ledger
|
|
209
|
+
|
|
210
|
+
**For Singapore:** IRAS may request the Annual GST Return (GST F8) for certain businesses. The annual reconciliation feeds directly into this.
|
|
211
|
+
|
|
212
|
+
**For Philippines:** Cross-check annual totals against the Summary List of Sales (SLS) and Summary List of Purchases (SLP) required by BIR.
|
|
213
|
+
|
|
214
|
+
**Tip:** If the annual tax ledger total doesn't match the sum of quarterly returns, the most common causes are: (a) transactions entered after the quarterly filing with a backdated date, (b) credit notes or amendments posted in a later quarter, (c) reclassification of tax codes mid-year.
|
|
215
|
+
|
|
216
|
+
### Step Y6: Audit preparation
|
|
217
|
+
|
|
218
|
+
Compile all reports, reconciliation schedules, and supporting documentation for the external auditor or tax preparer.
|
|
219
|
+
|
|
220
|
+
**Reference:** `references/audit-prep.md` for the full audit preparation job.
|
|
221
|
+
|
|
222
|
+
At minimum, generate and export:
|
|
223
|
+
|
|
224
|
+
| Report | API Call |
|
|
225
|
+
|--------|----------|
|
|
226
|
+
| Trial Balance (full year) | `POST /generate-reports/trial-balance { "startDate": "2025-01-01", "endDate": "2025-12-31" }` |
|
|
227
|
+
| Balance Sheet (year-end) | `POST /generate-reports/balance-sheet { "primarySnapshotDate": "2025-12-31" }` |
|
|
228
|
+
| P&L (full year) | `POST /generate-reports/profit-and-loss { "primarySnapshotDate": "2025-12-31", "secondarySnapshotDate": "2025-01-01" }` |
|
|
229
|
+
| General Ledger (full year) | `POST /generate-reports/general-ledger { "startDate": "2025-01-01", "endDate": "2025-12-31", "groupBy": "ACCOUNT" }` |
|
|
230
|
+
| Cashflow Statement | `POST /generate-reports/cashflow { "primaryStartDate": "2025-01-01", "primaryEndDate": "2025-12-31" }` |
|
|
231
|
+
| AR Aging (year-end) | `POST /generate-reports/ar-report { "endDate": "2025-12-31" }` |
|
|
232
|
+
| AP Aging (year-end) | `POST /generate-reports/ap-report { "endDate": "2025-12-31" }` |
|
|
233
|
+
| FA Register | `POST /generate-reports/fixed-assets-summary {}` |
|
|
234
|
+
| Tax Ledger (full year) | `POST /generate-reports/vat-ledger { "startDate": "2025-01-01", "endDate": "2025-12-31" }` |
|
|
235
|
+
| Equity Movement | `POST /generate-reports/equity-movement { "primarySnapshotStartDate": "2025-01-01", "primarySnapshotEndDate": "2025-12-31" }` |
|
|
236
|
+
|
|
237
|
+
**Supporting schedules to prepare:**
|
|
238
|
+
- Bank reconciliation statements for each bank account at year-end
|
|
239
|
+
- ECL provision calculation workpaper (from Q4 Step Q2)
|
|
240
|
+
- Fixed asset movement schedule (additions, disposals, depreciation, NBV)
|
|
241
|
+
- Intercompany balance confirmation letters (if multi-entity)
|
|
242
|
+
- Loan amortization schedules with principal/interest split
|
|
243
|
+
- Provision schedules with movement analysis
|
|
244
|
+
|
|
245
|
+
**Conditional:** Always for audited entities. For non-audited SMBs, at minimum prepare TB + BS + P&L for tax filing purposes.
|
|
246
|
+
|
|
247
|
+
### Step Y7: Final lock date
|
|
248
|
+
|
|
249
|
+
Lock the entire fiscal year. This prevents any accidental or unauthorized entries into the closed year.
|
|
250
|
+
|
|
251
|
+
**Best practice:** Set the org lock date to the last day of the fiscal year (e.g., `2025-12-31`).
|
|
252
|
+
|
|
253
|
+
**Important considerations:**
|
|
254
|
+
- Confirm with the auditor that they have no remaining adjustments before locking. Many auditors request a "soft close" first, with the hard lock applied after audit adjustments are posted.
|
|
255
|
+
- If using an audit adjustments period (e.g., January 1–15 of the new year for audit entries), set the lock date after those entries are complete.
|
|
256
|
+
- Once locked, reopening requires admin action and should be documented.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Phase 9: Annual Verification
|
|
261
|
+
|
|
262
|
+
Run the standard period verification (see `references/building-blocks.md` — Period Verification Pattern) for the full year, plus these annual-specific checks.
|
|
263
|
+
|
|
264
|
+
### Standard verification (full year)
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
POST /generate-reports/trial-balance
|
|
268
|
+
{ "startDate": "2025-01-01", "endDate": "2025-12-31" }
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
POST /generate-reports/profit-and-loss
|
|
273
|
+
{ "primarySnapshotDate": "2025-12-31", "secondarySnapshotDate": "2025-01-01" }
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
POST /generate-reports/balance-sheet
|
|
278
|
+
{ "primarySnapshotDate": "2025-12-31" }
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Annual-specific checks
|
|
282
|
+
|
|
283
|
+
**CYE rollover check:**
|
|
284
|
+
- Current Year Earnings at year-end = Net profit per the annual P&L
|
|
285
|
+
- After the new FY opens: CYE resets to zero, Retained Earnings increases by the prior year's net profit (less dividends)
|
|
286
|
+
- Total equity movement = Net profit - Dividends declared + Other equity movements (capital injection, etc.)
|
|
287
|
+
|
|
288
|
+
**Annual P&L vs monthly P&Ls sum:**
|
|
289
|
+
- Generate P&L for each of the 12 months individually
|
|
290
|
+
- Sum all 12 monthly net profit figures
|
|
291
|
+
- This sum MUST equal the annual P&L net profit
|
|
292
|
+
- If it doesn't, there's a timing/posting error — most commonly a journal posted to a month that was supposed to be locked
|
|
293
|
+
|
|
294
|
+
**FA register reconciliation:**
|
|
295
|
+
- NBV per FA register = Cost less accumulated depreciation per balance sheet
|
|
296
|
+
- Depreciation expense per FA register = Depreciation expense per P&L
|
|
297
|
+
- Asset count per FA register = physical count (if performed)
|
|
298
|
+
- Any fully depreciated assets still in use should be noted but not removed from register
|
|
299
|
+
|
|
300
|
+
**Provision balances:**
|
|
301
|
+
- Each provision on the balance sheet has documented support (IAS 37 criteria met)
|
|
302
|
+
- Provision movement = Opening + New provisions + Unwinding - Utilizations - Releases
|
|
303
|
+
- Unwinding total for the year = sum of four quarterly unwinding entries
|
|
304
|
+
|
|
305
|
+
**Intercompany elimination (if consolidating):**
|
|
306
|
+
- All intercompany balances net to zero across the group
|
|
307
|
+
- Intercompany revenue/expense eliminated on consolidation
|
|
308
|
+
- No intercompany profit in inventory or fixed assets (if applicable)
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Year-End Close Checklist (Quick Reference)
|
|
313
|
+
|
|
314
|
+
| # | Step | Phase | Conditional | Recipe/Calc |
|
|
315
|
+
|---|------|-------|-------------|-------------|
|
|
316
|
+
| 1–18 | Q1 Month 1 close | Monthly | Always | See month-end-close.md |
|
|
317
|
+
| 1–18 | Q1 Month 2 close | Monthly | Always | See month-end-close.md |
|
|
318
|
+
| 1–18 | Q1 Month 3 close | Monthly | Always | See month-end-close.md |
|
|
319
|
+
| Q1–Q5 | Q1 quarterly extras | Quarterly | See quarter-end-close.md | See quarter-end-close.md |
|
|
320
|
+
| 1–18 | Q2 Month 1 close | Monthly | Always | See month-end-close.md |
|
|
321
|
+
| 1–18 | Q2 Month 2 close | Monthly | Always | See month-end-close.md |
|
|
322
|
+
| 1–18 | Q2 Month 3 close | Monthly | Always | See month-end-close.md |
|
|
323
|
+
| Q1–Q5 | Q2 quarterly extras | Quarterly | See quarter-end-close.md | See quarter-end-close.md |
|
|
324
|
+
| 1–18 | Q3 Month 1 close | Monthly | Always | See month-end-close.md |
|
|
325
|
+
| 1–18 | Q3 Month 2 close | Monthly | Always | See month-end-close.md |
|
|
326
|
+
| 1–18 | Q3 Month 3 close | Monthly | Always | See month-end-close.md |
|
|
327
|
+
| Q1–Q5 | Q3 quarterly extras | Quarterly | See quarter-end-close.md | See quarter-end-close.md |
|
|
328
|
+
| 1–18 | Q4 Month 1 close | Monthly | Always | See month-end-close.md |
|
|
329
|
+
| 1–18 | Q4 Month 2 close | Monthly | Always | See month-end-close.md |
|
|
330
|
+
| 1–18 | Q4 Month 3 close | Monthly | Always | See month-end-close.md |
|
|
331
|
+
| Q1–Q5 | Q4 quarterly extras | Quarterly | See quarter-end-close.md | See quarter-end-close.md |
|
|
332
|
+
| Y1 | Final depreciation run | Annual | If fixed assets exist | declining-balance / `jaz calc depreciation` |
|
|
333
|
+
| Y2a | Leave balance true-up | Annual | If tracking leave | employee-accruals |
|
|
334
|
+
| Y2b | Bonus true-up | Annual | If bonus schemes exist | employee-accruals |
|
|
335
|
+
| Y2c | Provision reassessment | Annual | If IAS 37 provisions exist | provisions |
|
|
336
|
+
| Y3 | Dividend declaration & payment | Annual | If declaring dividends | dividend |
|
|
337
|
+
| Y4 | Retained earnings rollover (CYE) | Annual | Always (verify only) | — |
|
|
338
|
+
| Y5 | Final GST/VAT reconciliation | Annual | Always (if GST-registered) | gst-vat-filing job |
|
|
339
|
+
| Y6 | Audit preparation | Annual | Always (scope varies) | audit-prep job |
|
|
340
|
+
| Y7 | Final lock date | Annual | Always | — |
|
|
341
|
+
| V | Annual verification | Verification | Always | — |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: transaction-recipes
|
|
3
|
-
version: 2.
|
|
3
|
+
version: 2.8.0
|
|
4
4
|
description: 16 IFRS-compliant recipes for complex multi-step accounting in Jaz — prepaid amortization, deferred revenue, loan schedules, IFRS 16 leases, hire purchase, fixed deposits, asset disposal, FX revaluation, ECL provisioning, IAS 37 provisions, dividends, intercompany, and capital WIP. Each recipe includes journal entries, capsule structure, and verification steps. Paired with 10 financial calculators that produce execution-ready blueprints with workings.
|
|
5
5
|
license: MIT
|
|
6
6
|
compatibility: Works with Claude Code, Claude Cowork, Claude.ai, and any agent that reads markdown. For API payloads, load the jaz-api skill alongside this one.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { calculatePrepaidExpense, calculateDeferredRevenue } from '../calc/amortization.js';
|
|
3
|
+
import { CalcValidationError } from '../calc/validate.js';
|
|
4
|
+
describe('calculatePrepaidExpense', () => {
|
|
5
|
+
const base = { amount: 12000, periods: 12 };
|
|
6
|
+
it('per period = amount / periods', () => {
|
|
7
|
+
const r = calculatePrepaidExpense(base);
|
|
8
|
+
expect(r.perPeriodAmount).toBe(1000);
|
|
9
|
+
});
|
|
10
|
+
it('schedule has correct length', () => {
|
|
11
|
+
const r = calculatePrepaidExpense(base);
|
|
12
|
+
expect(r.schedule).toHaveLength(12);
|
|
13
|
+
});
|
|
14
|
+
it('total amortized = original amount', () => {
|
|
15
|
+
const r = calculatePrepaidExpense(base);
|
|
16
|
+
const total = r.schedule.reduce((s, row) => s + row.amortized, 0);
|
|
17
|
+
expect(Math.round(total * 100) / 100).toBe(12000);
|
|
18
|
+
});
|
|
19
|
+
it('remaining balance reaches zero at final period', () => {
|
|
20
|
+
const r = calculatePrepaidExpense(base);
|
|
21
|
+
expect(r.schedule[r.schedule.length - 1].remainingBalance).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
it('handles rounding — 10000 / 3 periods', () => {
|
|
24
|
+
const r = calculatePrepaidExpense({ amount: 10000, periods: 3 });
|
|
25
|
+
expect(r.perPeriodAmount).toBe(3333.33);
|
|
26
|
+
const total = r.schedule.reduce((s, row) => s + row.amortized, 0);
|
|
27
|
+
expect(Math.round(total * 100) / 100).toBe(10000);
|
|
28
|
+
// Final period absorbs rounding
|
|
29
|
+
expect(r.schedule[2].amortized).toBe(3333.34);
|
|
30
|
+
});
|
|
31
|
+
it('every journal entry balanced', () => {
|
|
32
|
+
const r = calculatePrepaidExpense(base);
|
|
33
|
+
for (const row of r.schedule) {
|
|
34
|
+
const debits = row.journal.lines.reduce((s, l) => s + l.debit, 0);
|
|
35
|
+
const credits = row.journal.lines.reduce((s, l) => s + l.credit, 0);
|
|
36
|
+
expect(debits).toBe(credits);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
it('journal entries use Expense / Prepaid Asset accounts', () => {
|
|
40
|
+
const r = calculatePrepaidExpense(base);
|
|
41
|
+
expect(r.schedule[0].journal.lines[0].account).toBe('Expense');
|
|
42
|
+
expect(r.schedule[0].journal.lines[1].account).toBe('Prepaid Asset');
|
|
43
|
+
});
|
|
44
|
+
// Blueprint
|
|
45
|
+
it('blueprint step 1 = bill', () => {
|
|
46
|
+
const r = calculatePrepaidExpense({ ...base, startDate: '2025-01-01' });
|
|
47
|
+
expect(r.blueprint.steps[0].action).toBe('bill');
|
|
48
|
+
});
|
|
49
|
+
it('blueprint step count = 1 + periods', () => {
|
|
50
|
+
const r = calculatePrepaidExpense({ ...base, startDate: '2025-01-01' });
|
|
51
|
+
expect(r.blueprint.steps).toHaveLength(13);
|
|
52
|
+
});
|
|
53
|
+
it('blueprint null without startDate', () => {
|
|
54
|
+
const r = calculatePrepaidExpense(base);
|
|
55
|
+
expect(r.blueprint).toBeNull();
|
|
56
|
+
});
|
|
57
|
+
// Quarterly
|
|
58
|
+
it('quarterly frequency works', () => {
|
|
59
|
+
const r = calculatePrepaidExpense({ amount: 12000, periods: 4, frequency: 'quarterly', startDate: '2025-01-01' });
|
|
60
|
+
expect(r.schedule).toHaveLength(4);
|
|
61
|
+
// Date present and properly formatted (exact value depends on TZ)
|
|
62
|
+
expect(r.schedule[0].date).toMatch(/^\d{4}-\d{2}-\d{2}$/);
|
|
63
|
+
});
|
|
64
|
+
// Validation
|
|
65
|
+
it('rejects zero amount', () => {
|
|
66
|
+
expect(() => calculatePrepaidExpense({ amount: 0, periods: 12 })).toThrow(CalcValidationError);
|
|
67
|
+
});
|
|
68
|
+
it('rejects zero periods', () => {
|
|
69
|
+
expect(() => calculatePrepaidExpense({ amount: 12000, periods: 0 })).toThrow(CalcValidationError);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('calculateDeferredRevenue', () => {
|
|
73
|
+
const base = { amount: 36000, periods: 12 };
|
|
74
|
+
it('per period = amount / periods', () => {
|
|
75
|
+
const r = calculateDeferredRevenue(base);
|
|
76
|
+
expect(r.perPeriodAmount).toBe(3000);
|
|
77
|
+
});
|
|
78
|
+
it('total recognized = original amount', () => {
|
|
79
|
+
const r = calculateDeferredRevenue(base);
|
|
80
|
+
const total = r.schedule.reduce((s, row) => s + row.amortized, 0);
|
|
81
|
+
expect(Math.round(total * 100) / 100).toBe(36000);
|
|
82
|
+
});
|
|
83
|
+
it('journal entries use Deferred Revenue / Revenue accounts', () => {
|
|
84
|
+
const r = calculateDeferredRevenue(base);
|
|
85
|
+
expect(r.schedule[0].journal.lines[0].account).toBe('Deferred Revenue');
|
|
86
|
+
expect(r.schedule[0].journal.lines[1].account).toBe('Revenue');
|
|
87
|
+
});
|
|
88
|
+
// Blueprint
|
|
89
|
+
it('blueprint step 1 = invoice', () => {
|
|
90
|
+
const r = calculateDeferredRevenue({ ...base, startDate: '2025-01-01' });
|
|
91
|
+
expect(r.blueprint.steps[0].action).toBe('invoice');
|
|
92
|
+
});
|
|
93
|
+
it('capsuleType is Deferred Revenue', () => {
|
|
94
|
+
const r = calculateDeferredRevenue({ ...base, startDate: '2025-01-01' });
|
|
95
|
+
expect(r.blueprint.capsuleType).toBe('Deferred Revenue');
|
|
96
|
+
});
|
|
97
|
+
it('capsuleDescription present', () => {
|
|
98
|
+
const r = calculateDeferredRevenue({ ...base, startDate: '2025-01-01' });
|
|
99
|
+
expect(r.blueprint.capsuleDescription).toBeTruthy();
|
|
100
|
+
});
|
|
101
|
+
});
|