@classytic/ledger 0.6.0 → 0.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/README.md +221 -115
- package/dist/constants/index.d.mts +1 -1
- package/dist/country/index.d.mts +2 -2
- package/dist/country/index.mjs +0 -3
- package/dist/exports/index.d.mts +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/{fx-realization.plugin-CgQFDGv2.mjs → fx-realization.plugin-DDVK-oYO.mjs} +44 -37
- package/dist/{tax-hooks-BnVenul5.d.mts → index-BSsvrf3m.d.mts} +18 -67
- package/dist/index-RNZsX0Yo.d.mts +130 -0
- package/dist/index.d.mts +133 -68
- package/dist/index.mjs +166 -142
- package/dist/{journals-C50E9mpo.d.mts → journals-Dd4A9TN3.d.mts} +1 -1
- package/dist/opening-balance-DPXmAIzN.mjs +60 -0
- package/dist/plugins/index.d.mts +2 -16
- package/dist/plugins/index.mjs +2 -57
- package/dist/reports/index.d.mts +1 -1
- package/dist/sync/index.d.mts +313 -0
- package/dist/sync/index.mjs +527 -0
- package/dist/sync-CnuVf441.d.mts +152 -0
- package/dist/{trial-balance-s92GEvRR.d.mts → trial-balance-DTj-c21f.d.mts} +3 -34
- package/docs/country-packs.md +71 -47
- package/docs/engine.md +3 -2
- package/docs/subledger-integration.md +29 -8
- package/docs/sync.md +330 -0
- package/package.json +26 -14
- package/dist/index-BthGypsI.d.mts +0 -228
- /package/dist/{core-BkGjuVZj.d.mts → core-MpgjCqK0.d.mts} +0 -0
- /package/dist/{exports-BP-0Ni5W.mjs → exports-B3whucXe.mjs} +0 -0
- /package/dist/{index-D1ZjgVxn.d.mts → index-bCEeSzdO.d.mts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/ledger",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Production-grade double-entry accounting engine for MongoDB — schemas, reports, tax, multi-tenant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -42,6 +42,11 @@
|
|
|
42
42
|
"types": "./dist/exports/index.d.mts",
|
|
43
43
|
"import": "./dist/exports/index.mjs",
|
|
44
44
|
"default": "./dist/exports/index.mjs"
|
|
45
|
+
},
|
|
46
|
+
"./sync": {
|
|
47
|
+
"types": "./dist/sync/index.d.mts",
|
|
48
|
+
"import": "./dist/sync/index.mjs",
|
|
49
|
+
"default": "./dist/sync/index.mjs"
|
|
45
50
|
}
|
|
46
51
|
},
|
|
47
52
|
"files": [
|
|
@@ -78,9 +83,28 @@
|
|
|
78
83
|
"url": "git+https://github.com/classytic/accounting.git"
|
|
79
84
|
},
|
|
80
85
|
"peerDependencies": {
|
|
81
|
-
"@classytic/
|
|
86
|
+
"@classytic/fin-io": ">=0.1.0",
|
|
87
|
+
"@classytic/mongokit": ">=3.5.6",
|
|
82
88
|
"mongoose": ">=9.4.1"
|
|
83
89
|
},
|
|
90
|
+
"peerDependenciesMeta": {
|
|
91
|
+
"@classytic/fin-io": {
|
|
92
|
+
"optional": true
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"devDependencies": {
|
|
96
|
+
"@biomejs/biome": "^2.4.10",
|
|
97
|
+
"@classytic/fin-io": "file:../fin-io",
|
|
98
|
+
"@classytic/mongokit": "^3.5.6",
|
|
99
|
+
"@types/node": "^22.0.0",
|
|
100
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
101
|
+
"knip": "^6.3.0",
|
|
102
|
+
"mongodb-memory-server": "^10.2.3",
|
|
103
|
+
"mongoose": "^9.4.1",
|
|
104
|
+
"tsdown": "^0.21.5",
|
|
105
|
+
"typescript": "^5.7.0",
|
|
106
|
+
"vitest": "^3.0.0"
|
|
107
|
+
},
|
|
84
108
|
"engines": {
|
|
85
109
|
"node": ">=22"
|
|
86
110
|
},
|
|
@@ -99,17 +123,5 @@
|
|
|
99
123
|
"smoke": "node scripts/smoke.mjs",
|
|
100
124
|
"prepublishOnly": "npm run check && npm run build && npm run typecheck && npm test && npm run smoke",
|
|
101
125
|
"release": "npm run check && npm run build && npm run typecheck && npm test && npm run smoke && npm publish --access public"
|
|
102
|
-
},
|
|
103
|
-
"devDependencies": {
|
|
104
|
-
"@biomejs/biome": "^2.4.10",
|
|
105
|
-
"@classytic/mongokit": "^3.5.5",
|
|
106
|
-
"@types/node": "^22.0.0",
|
|
107
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
108
|
-
"knip": "^6.3.0",
|
|
109
|
-
"mongodb-memory-server": "^10.2.3",
|
|
110
|
-
"mongoose": "^9.4.1",
|
|
111
|
-
"tsdown": "^0.21.5",
|
|
112
|
-
"typescript": "^5.7.0",
|
|
113
|
-
"vitest": "^3.0.0"
|
|
114
126
|
}
|
|
115
127
|
}
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { t as AccountType } from "./core-BkGjuVZj.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/country/index.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* A single destination for a fraction of a tax amount. A `TaxCode` can declare
|
|
6
|
-
* multiple repartition lines so that one tax percentage produces multiple
|
|
7
|
-
* journal items (e.g. reverse-charge VAT books +100% to payable AND -100% to
|
|
8
|
-
* recoverable in the same entry). Factors sum across lines and the engine
|
|
9
|
-
* enforces balance inside the existing double-entry plugin.
|
|
10
|
-
*
|
|
11
|
-
* `accountRole` is a logical name looked up against the consumer's chart of
|
|
12
|
-
* accounts via the country pack's `resolveRepartitionAccount` helper — NOT a
|
|
13
|
-
* direct ObjectId, so the same country pack can drive any consumer's accounts.
|
|
14
|
-
* `gridCode` flows through to `taxDetails` for regulatory reporting (CRA
|
|
15
|
-
* schedule lines, HMRC VAT boxes, NBR Mushak grid, etc.).
|
|
16
|
-
*/
|
|
17
|
-
interface TaxRepartitionLine {
|
|
18
|
-
/**
|
|
19
|
-
* Signed multiplier applied to the base tax amount. Use `1` for the
|
|
20
|
-
* "normal" line, `-1` for a mirror (e.g. recoverable reverse-charge).
|
|
21
|
-
* Fractions (e.g. `0.5`) are allowed for split-destination taxes.
|
|
22
|
-
*/
|
|
23
|
-
readonly factor: number;
|
|
24
|
-
/**
|
|
25
|
-
* Logical role resolved against the country pack. Standard roles:
|
|
26
|
-
* - `'collected'` — tax collected from customer (liability)
|
|
27
|
-
* - `'recoverable'` — tax paid to supplier, recoverable (asset)
|
|
28
|
-
* - `'expense'` — tax paid, non-recoverable (expense)
|
|
29
|
-
* - `'transition'` — temporary holding account for cash-basis exigibility
|
|
30
|
-
* Consumers can define custom roles and wire them in their country pack.
|
|
31
|
-
*/
|
|
32
|
-
readonly accountRole: string;
|
|
33
|
-
/** Optional reporting grid code — propagated to `taxDetails` on the item. */
|
|
34
|
-
readonly gridCode?: string | number;
|
|
35
|
-
/** Optional human label surfaced in UI and audit trails. */
|
|
36
|
-
readonly label?: string;
|
|
37
|
-
/** Optional: only apply on these document types. Default: all. */
|
|
38
|
-
readonly documentTypes?: readonly ('invoice' | 'refund' | 'payment')[];
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* When a tax is realized into the books:
|
|
42
|
-
* - `'accrual'` (default) — books at entry time (what 0.5.x did for everything)
|
|
43
|
-
* - `'cash'` — books into a transition account at entry time, moves to the
|
|
44
|
-
* real tax account when the invoice is reconciled against a payment
|
|
45
|
-
*/
|
|
46
|
-
type TaxExigibility = 'accrual' | 'cash';
|
|
47
|
-
interface TaxCode {
|
|
48
|
-
readonly code: string;
|
|
49
|
-
readonly name: string;
|
|
50
|
-
readonly taxType: string;
|
|
51
|
-
readonly rate: number;
|
|
52
|
-
readonly direction: 'collected' | 'recoverable' | 'paid';
|
|
53
|
-
readonly province?: string;
|
|
54
|
-
readonly reportLines?: readonly number[];
|
|
55
|
-
readonly description: string;
|
|
56
|
-
readonly active: boolean;
|
|
57
|
-
/**
|
|
58
|
-
* Multi-line repartition — when present, `createRepartitionTaxGenerator`
|
|
59
|
-
* produces one journal item per line. When absent, the tax behaves as a
|
|
60
|
-
* single-line tax routed to the `direction`-implied account.
|
|
61
|
-
*/
|
|
62
|
-
readonly repartition?: readonly TaxRepartitionLine[];
|
|
63
|
-
/**
|
|
64
|
-
* Accrual (default) or cash-basis exigibility. When `'cash'`, requires
|
|
65
|
-
* a `transition` repartition role in `repartition` OR a country-pack
|
|
66
|
-
* default transition account.
|
|
67
|
-
*/
|
|
68
|
-
readonly exigibility?: TaxExigibility;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Declarative template that tells the engine which journals to seed for a
|
|
72
|
-
* new organization. Consumers call
|
|
73
|
-
* `engine.repositories.journals.seedDefaults(orgId)` which reads these from
|
|
74
|
-
* the country pack and creates one Journal document per template.
|
|
75
|
-
*
|
|
76
|
-
* Journals are *optional* — if a consumer never seeds journals, the legacy
|
|
77
|
-
* `journalType` enum on a journal entry still works. Consumers opting in
|
|
78
|
-
* get per-journal sequence prefixes, restricted payment methods, bank
|
|
79
|
-
* statement sources, etc.
|
|
80
|
-
*/
|
|
81
|
-
interface JournalTemplate {
|
|
82
|
-
/** Short stable identifier — e.g. `'SALES'`, `'PURCHASE'`, `'BANK'`. */
|
|
83
|
-
readonly code: string;
|
|
84
|
-
/** Display name. */
|
|
85
|
-
readonly name: string;
|
|
86
|
-
/**
|
|
87
|
-
* One of the registered `JOURNAL_TYPES` codes — connects this journal to
|
|
88
|
-
* the engine's reference-number generator and posting-contract system.
|
|
89
|
-
*/
|
|
90
|
-
readonly journalType: string;
|
|
91
|
-
/** Reference-number prefix — defaults to `code` when omitted. */
|
|
92
|
-
readonly sequencePrefix?: string;
|
|
93
|
-
/** First sequence number — defaults to `1`. */
|
|
94
|
-
readonly sequenceStartNum?: number;
|
|
95
|
-
/**
|
|
96
|
-
* Logical source — pure ledgering (`'general'`), sale-side docs (`'sale'`),
|
|
97
|
-
* purchase-side docs (`'purchase'`), cash/bank movement (`'bank'`, `'cash'`).
|
|
98
|
-
* Drives default locks (sale-lock, purchase-lock) when they're wired.
|
|
99
|
-
*/
|
|
100
|
-
readonly kind?: 'general' | 'sale' | 'purchase' | 'bank' | 'cash' | string;
|
|
101
|
-
/** Optional default debit/credit account roles for quick data entry. */
|
|
102
|
-
readonly defaultDebitAccountRole?: string;
|
|
103
|
-
readonly defaultCreditAccountRole?: string;
|
|
104
|
-
}
|
|
105
|
-
interface TaxCodesByRegion {
|
|
106
|
-
readonly [region: string]: readonly string[];
|
|
107
|
-
}
|
|
108
|
-
interface TaxReportLine {
|
|
109
|
-
readonly line: number | string;
|
|
110
|
-
readonly name: string;
|
|
111
|
-
readonly description: string;
|
|
112
|
-
readonly type: 'input' | 'calculated' | 'manual';
|
|
113
|
-
readonly calculate?: (data: Record<string | number, number>) => number;
|
|
114
|
-
readonly section: string;
|
|
115
|
-
}
|
|
116
|
-
interface TaxReportTemplate {
|
|
117
|
-
readonly name: string;
|
|
118
|
-
readonly lines: Readonly<Record<string | number, TaxReportLine>>;
|
|
119
|
-
calculate(inputData: Record<string | number, number>, manualData?: Record<string | number, number>): Record<string | number, number>;
|
|
120
|
-
summarize(calculated: Record<string | number, number>): Record<string, unknown>;
|
|
121
|
-
}
|
|
122
|
-
interface CountryPack {
|
|
123
|
-
/** ISO 3166-1 alpha-2 code (e.g., 'CA', 'US', 'GB') */
|
|
124
|
-
readonly code: string;
|
|
125
|
-
/** Country name */
|
|
126
|
-
readonly name: string;
|
|
127
|
-
/** Default currency code */
|
|
128
|
-
readonly defaultCurrency: string;
|
|
129
|
-
/**
|
|
130
|
-
* Full chart of accounts template — flat array of account type definitions.
|
|
131
|
-
* Includes both regular accounts and virtual tax sub-accounts.
|
|
132
|
-
*/
|
|
133
|
-
readonly accountTypes: readonly AccountType[];
|
|
134
|
-
/** Tax codes indexed by code string */
|
|
135
|
-
readonly taxCodes: Readonly<Record<string, TaxCode>>;
|
|
136
|
-
/** Tax codes grouped by region/province/state */
|
|
137
|
-
readonly taxCodesByRegion: TaxCodesByRegion;
|
|
138
|
-
/** Available regions (provinces/states) */
|
|
139
|
-
readonly regions: readonly string[];
|
|
140
|
-
/** Tax report template (e.g., CRA GST/HST return) */
|
|
141
|
-
readonly taxReport?: TaxReportTemplate;
|
|
142
|
-
/**
|
|
143
|
-
* Optional journal templates seeded per organization. When a consumer
|
|
144
|
-
* calls `engine.repositories.journals.seedDefaults(orgId)`, the engine
|
|
145
|
-
* creates one Journal document per template. See `JournalTemplate`.
|
|
146
|
-
*/
|
|
147
|
-
readonly journalTemplates?: readonly JournalTemplate[];
|
|
148
|
-
/**
|
|
149
|
-
* Map a logical `accountRole` string (e.g. `'collected'`, `'recoverable'`,
|
|
150
|
-
* `'transition'`) to the actual account-type code for this country. The
|
|
151
|
-
* repartition tax generator calls this for each repartition line so the
|
|
152
|
-
* same tax definition can resolve different account codes in BD vs CA.
|
|
153
|
-
*
|
|
154
|
-
* Default behavior when omitted: maps `'collected'` → account with
|
|
155
|
-
* direction='collected' in `taxCodes`, `'recoverable'` →
|
|
156
|
-
* direction='recoverable', etc. Consumers override for custom roles.
|
|
157
|
-
*/
|
|
158
|
-
readonly resolveTaxRepartitionAccountCode?: (role: string, taxCode: TaxCode) => string | undefined;
|
|
159
|
-
/**
|
|
160
|
-
* The retained earnings account code — the account that holds accumulated
|
|
161
|
-
* retained earnings (e.g. '3600' CA, '3310' BD).
|
|
162
|
-
*
|
|
163
|
-
* On the balance sheet, this account is excluded from normal equity grouping
|
|
164
|
-
* and its balance is folded into the computed "Retained Earnings" section
|
|
165
|
-
* (opening RE = RE account balance + prior-year unclosed P&L).
|
|
166
|
-
*
|
|
167
|
-
* Inspired by Odoo's `equity_unaffected` account type.
|
|
168
|
-
*/
|
|
169
|
-
readonly retainedEarningsAccountCode?: string;
|
|
170
|
-
/**
|
|
171
|
-
* Display code for the "Previous Years Retained Earnings" line on the
|
|
172
|
-
* balance sheet (e.g. '3660' for CA GIFI). Defaults to retainedEarningsAccountCode.
|
|
173
|
-
*/
|
|
174
|
-
readonly retainedEarningsDisplayCode?: string;
|
|
175
|
-
/** Display code for current year net income line (e.g. '3680' CA, '3311' BD) */
|
|
176
|
-
readonly currentYearEarningsCode?: string;
|
|
177
|
-
/** Group label code used to identify Cost of Sales in the income statement */
|
|
178
|
-
readonly cogsGroupCode?: string;
|
|
179
|
-
/** Override default English report section names */
|
|
180
|
-
readonly reportLabels?: {
|
|
181
|
-
readonly assets?: string;
|
|
182
|
-
readonly liabilities?: string;
|
|
183
|
-
readonly equity?: string;
|
|
184
|
-
readonly revenue?: string;
|
|
185
|
-
readonly expenses?: string;
|
|
186
|
-
};
|
|
187
|
-
/** Get all account types that can be posted to (not groups, not totals) */
|
|
188
|
-
getPostingAccountTypes(): readonly AccountType[];
|
|
189
|
-
/** Get account type by code */
|
|
190
|
-
getAccountType(code: string): AccountType | undefined;
|
|
191
|
-
/** Validate an account type code exists */
|
|
192
|
-
isValidAccountType(code: string): boolean;
|
|
193
|
-
/** Check if an account type can receive postings */
|
|
194
|
-
isPostingAccount(code: string): boolean;
|
|
195
|
-
/** Get tax codes for a specific region */
|
|
196
|
-
getTaxCodesForRegion(region: string): TaxCode[];
|
|
197
|
-
/** Flatten hierarchical accounts (if needed) */
|
|
198
|
-
flattenAccountTypes(): readonly AccountType[];
|
|
199
|
-
}
|
|
200
|
-
interface CountryPackInput {
|
|
201
|
-
code: string;
|
|
202
|
-
name: string;
|
|
203
|
-
defaultCurrency: string;
|
|
204
|
-
accountTypes: readonly AccountType[];
|
|
205
|
-
taxCodes: Readonly<Record<string, TaxCode>>;
|
|
206
|
-
taxCodesByRegion: TaxCodesByRegion;
|
|
207
|
-
regions: readonly string[];
|
|
208
|
-
taxReport?: TaxReportTemplate;
|
|
209
|
-
journalTemplates?: readonly JournalTemplate[];
|
|
210
|
-
resolveTaxRepartitionAccountCode?: (role: string, taxCode: TaxCode) => string | undefined;
|
|
211
|
-
retainedEarningsAccountCode?: string;
|
|
212
|
-
retainedEarningsDisplayCode?: string;
|
|
213
|
-
currentYearEarningsCode?: string;
|
|
214
|
-
cogsGroupCode?: string;
|
|
215
|
-
reportLabels?: {
|
|
216
|
-
readonly assets?: string;
|
|
217
|
-
readonly liabilities?: string;
|
|
218
|
-
readonly equity?: string;
|
|
219
|
-
readonly revenue?: string;
|
|
220
|
-
readonly expenses?: string;
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Factory to create a CountryPack with auto-generated helper methods.
|
|
225
|
-
*/
|
|
226
|
-
declare function defineCountryPack(input: CountryPackInput): CountryPack;
|
|
227
|
-
//#endregion
|
|
228
|
-
export { TaxCodesByRegion as a, TaxReportLine as c, TaxCode as i, TaxReportTemplate as l, CountryPackInput as n, TaxExigibility as o, JournalTemplate as r, TaxRepartitionLine as s, CountryPack as t, defineCountryPack as u };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|