@classytic/ledger 0.4.0 → 0.4.1
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 +82 -20
- package/dist/constants/index.mjs +2 -2
- package/dist/{date-lock.plugin-C8kqPBjh.mjs → date-lock.plugin-DL6pe24p.mjs} +1 -1
- package/dist/{engine-DF-MtsEr.d.mts → engine-scgOvxHJ.d.mts} +29 -1
- package/dist/{fiscal-close-DmPV82e4.mjs → fiscal-close-B2_7WMTe.mjs} +3 -3
- package/dist/index.d.mts +158 -6
- package/dist/index.mjs +148 -11
- package/dist/{journal-entry.schema-B1CzLwC3.d.mts → journal-entry.schema-JqrfbvB4.d.mts} +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/{reconciliation.repository-DEybU_Ok.d.mts → reconciliation.repository-D-D_ITL-.d.mts} +1 -1
- package/dist/{reconciliation.repository-DgJEDVS-.mjs → reconciliation.repository-fPwFKvrk.mjs} +2 -2
- package/dist/{reconciliation.schema-KScbsXbY.mjs → reconciliation.schema-BA1lPv4t.mjs} +1 -1
- package/dist/reports/index.mjs +1 -1
- package/dist/repositories/index.d.mts +1 -1
- package/dist/repositories/index.mjs +1 -1
- package/dist/schemas/index.d.mts +2 -2
- package/dist/schemas/index.mjs +1 -1
- package/dist/{tenant-guard-CAxXoWuS.mjs → tenant-guard-r17Se3Bb.mjs} +1 -1
- package/docs/schemas.md +2 -2
- package/package.json +1 -1
- /package/dist/{categories-FJlrvzcl.mjs → categories-DWogBUgQ.mjs} +0 -0
- /package/dist/{errors-BoGUSUYL.mjs → errors-B_dyYZc_.mjs} +0 -0
- /package/dist/{journals-BcMn71Cq.mjs → journals-BfwnCFam.mjs} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @classytic/ledger
|
|
2
2
|
|
|
3
|
-
Embeddable double-entry accounting engine for MongoDB. Integer-cents arithmetic, plugin-based, country-agnostic.
|
|
3
|
+
Embeddable double-entry accounting engine for MongoDB. Integer-cents arithmetic, plugin-based, country-agnostic. Extensible journal types, multi-tenant isolation at every layer.
|
|
4
4
|
|
|
5
5
|
Build QuickBooks, Xero, or TaxCycle-grade apps — the engine handles the accounting, you handle the UX.
|
|
6
6
|
|
|
@@ -15,23 +15,49 @@ npm install @classytic/ledger-bd # Bangladesh (BFRS, VAT/TDS, Mushak)
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
+
import mongoose from 'mongoose';
|
|
18
19
|
import { createAccountingEngine } from '@classytic/ledger';
|
|
19
20
|
import { canadaPack } from '@classytic/ledger-ca';
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
// The engine owns the models — matches flow/promo pattern
|
|
23
|
+
const engine = createAccountingEngine({
|
|
24
|
+
mongoose: mongoose.connection,
|
|
22
25
|
country: canadaPack,
|
|
23
26
|
currency: 'CAD',
|
|
24
|
-
multiTenant: { orgField: '
|
|
27
|
+
multiTenant: { orgField: 'organizationId', orgRef: 'Organization' },
|
|
25
28
|
});
|
|
26
29
|
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
30
|
+
// Models, repositories, and reports are auto-created
|
|
31
|
+
await engine.repositories.accounts.seedAccounts(orgId);
|
|
32
|
+
const entry = await engine.repositories.journalEntries.post(entryId, orgId);
|
|
33
|
+
const bs = await engine.reports.balanceSheet({ organizationId: orgId, dateOption: 'year', dateValue: 2025 });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Engine-owned models (recommended)
|
|
37
|
+
|
|
38
|
+
Pass `mongoose: connection` in config and the engine creates and wires everything:
|
|
39
|
+
|
|
40
|
+
| Property | What it gives you |
|
|
41
|
+
|----------|-------------------|
|
|
42
|
+
| `engine.models.Account` / `JournalEntry` / `FiscalPeriod` / `Budget` / `Reconciliation` | Mongoose models, ready to query |
|
|
43
|
+
| `engine.repositories.accounts.seedAccounts()` / `bulkCreate()` | Account repo with domain methods |
|
|
44
|
+
| `engine.repositories.journalEntries.post()` / `reverse()` / `unpost()` / `duplicate()` | JE repo with plugins pre-wired (double-entry, fiscal-lock, idempotency) |
|
|
45
|
+
| `engine.repositories.fiscalPeriods` / `budgets` | Plain CRUD repos |
|
|
46
|
+
| `engine.repositories.reconciliations.reconcile()` / `unreconcile()` / `getUnreconciled()` | Reconciliation repo with domain methods |
|
|
47
|
+
| `engine.reports.trialBalance()` / `balanceSheet()` / etc. | All 10 reports, bound to the owned models |
|
|
48
|
+
|
|
49
|
+
This pattern unblocks framework auto-discovery (Arc `loadResources`, Fastify plugins, etc.) because resources can be defined at module top-level without factory wrappers.
|
|
50
|
+
|
|
51
|
+
### Low-level (manual schema/model setup)
|
|
31
52
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
53
|
+
If you need custom naming or don't want the engine to own models, omit `mongoose` from config:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const engine = createAccountingEngine({ country: canadaPack, currency: 'CAD' });
|
|
57
|
+
const Account = mongoose.model('GLAccount', engine.createAccountSchema());
|
|
58
|
+
const JournalEntry = mongoose.model('GLEntry', engine.createJournalEntrySchema('GLAccount'));
|
|
59
|
+
const accountRepo = engine.wireAccountRepository(new Repository(Account), Account);
|
|
60
|
+
const reports = engine.createReports({ Account, JournalEntry });
|
|
35
61
|
```
|
|
36
62
|
|
|
37
63
|
## Core Features
|
|
@@ -41,8 +67,9 @@ const bs = await reports.balanceSheet({ organizationId, dateOption: 'year', date
|
|
|
41
67
|
- Integer-cents storage — zero floating-point drift
|
|
42
68
|
- Draft → Posted → Reversed state machine
|
|
43
69
|
- Configurable immutability (corrections only via reversal)
|
|
44
|
-
- Multi-tenant isolation at every layer
|
|
70
|
+
- Multi-tenant isolation at every layer (reports, schemas, repositories)
|
|
45
71
|
- Country packs for localized charts of accounts and tax codes
|
|
72
|
+
- Extensible journal type registry — add domain-specific types (POS, E-Commerce, Payroll) at startup
|
|
46
73
|
|
|
47
74
|
**10 Reports**
|
|
48
75
|
- Trial Balance (3-column: initial + period + ending)
|
|
@@ -155,7 +182,36 @@ taxHookPlugin({
|
|
|
155
182
|
| `@classytic/ledger/repositories` | Repository wiring |
|
|
156
183
|
| `@classytic/ledger/exports` | CSV export + QuickBooks field maps |
|
|
157
184
|
| `@classytic/ledger/country` | `defineCountryPack`, `CountryPack` interface |
|
|
158
|
-
| `@classytic/ledger/constants` | Categories, journal types, currencies |
|
|
185
|
+
| `@classytic/ledger/constants` | Categories, journal types (+ registry), currencies |
|
|
186
|
+
|
|
187
|
+
## Extensible Journal Types
|
|
188
|
+
|
|
189
|
+
The 15 built-in journal types (SALES, PURCHASES, GENERAL, PAYROLL, etc.) cover standard accounting. For domain-specific needs, register custom types **before** schema creation:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { registerJournalType, getJournalTypeCodes, isValidJournalType } from '@classytic/ledger';
|
|
193
|
+
|
|
194
|
+
// Register at startup, before createJournalEntrySchema()
|
|
195
|
+
registerJournalType('POS_SALES', {
|
|
196
|
+
code: 'POS_SALES',
|
|
197
|
+
name: 'POS Sales Journal',
|
|
198
|
+
description: 'Daily aggregated point-of-sale transactions',
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
registerJournalType('ECOM_SALES', {
|
|
202
|
+
code: 'ECOM_SALES',
|
|
203
|
+
name: 'E-Commerce Sales Journal',
|
|
204
|
+
description: 'Per-order online transactions',
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Custom types pass Mongoose enum validation, appear in all lookups
|
|
208
|
+
isValidJournalType('POS_SALES'); // true
|
|
209
|
+
getJournalTypeCodes(); // [...15 built-in, 'POS_SALES', 'ECOM_SALES']
|
|
210
|
+
|
|
211
|
+
// Reference numbers use the custom type prefix: POS_SALES/2025/03/0001
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
The registry freezes when `createJournalEntrySchema()` is called. Late registration throws. Built-in types cannot be overridden.
|
|
159
215
|
|
|
160
216
|
## Country Packs
|
|
161
217
|
|
|
@@ -180,25 +236,31 @@ Available packs: `@classytic/ledger-ca` (Canada), `@classytic/ledger-bd` (Bangla
|
|
|
180
236
|
|
|
181
237
|
## Testing
|
|
182
238
|
|
|
183
|
-
949 tests covering unit, integration, and end-to-end scenarios:
|
|
184
|
-
|
|
185
239
|
```bash
|
|
186
|
-
npm test
|
|
187
|
-
npx vitest run tests/e2e/
|
|
240
|
+
npm test # run all
|
|
241
|
+
npx vitest run tests/e2e/ # e2e scenarios only
|
|
242
|
+
npx vitest run tests/scenarios/ # integration scenarios
|
|
243
|
+
npx vitest run tests/hardening/ # edge cases & invariants
|
|
188
244
|
```
|
|
189
245
|
|
|
190
|
-
|
|
246
|
+
Test suites cover:
|
|
191
247
|
- Canadian small business full-year lifecycle
|
|
192
248
|
- Multi-currency trading with FX revaluation
|
|
193
|
-
-
|
|
249
|
+
- Multi-tenant report isolation (org A cannot see org B)
|
|
250
|
+
- Posting pipeline → Trial Balance → Income Statement → Balance Sheet
|
|
251
|
+
- Reversal & correction workflows with audit trail
|
|
252
|
+
- Custom journal type registry → schema → posting pipeline
|
|
253
|
+
- Double-entry conservation law (debit = credit across all entries)
|
|
254
|
+
- Money arithmetic hardening (overflow, penny-leak, float traps)
|
|
255
|
+
- Public API surface & subpath export verification
|
|
194
256
|
- O-Level / A-Level / university textbook accounting problems
|
|
195
257
|
|
|
196
258
|
## Requirements
|
|
197
259
|
|
|
198
260
|
- Node.js >= 22
|
|
199
261
|
- MongoDB (replica set recommended for transactions)
|
|
200
|
-
- Mongoose >= 9
|
|
201
|
-
- @classytic/mongokit >= 3
|
|
262
|
+
- Mongoose >= 9.4.1
|
|
263
|
+
- @classytic/mongokit >= 3.5.3
|
|
202
264
|
|
|
203
265
|
## License
|
|
204
266
|
|
package/dist/constants/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import { a as
|
|
1
|
+
import { a as getJournalType, c as registerJournalType, i as getCustomJournalTypes, n as JOURNAL_TYPES, o as getJournalTypeCodes, s as isValidJournalType, t as JOURNAL_CODES } from "../journals-BfwnCFam.mjs";
|
|
2
|
+
import { a as extractStatementType, c as getNormalBalance, d as isValidCategory, i as extractMainType, l as isBalanceSheet, n as CATEGORY_KEYS, o as getCategoryMainType, r as categoryKey, s as getCategoryStatementType, t as CATEGORIES, u as isIncomeStatement } from "../categories-DWogBUgQ.mjs";
|
|
3
3
|
import { i as isValidCurrency, n as getCurrency, r as getMinorUnit, t as CURRENCIES } from "../currencies-W8kQAkm0.mjs";
|
|
4
4
|
export { CATEGORIES, CATEGORY_KEYS, CURRENCIES, JOURNAL_CODES, JOURNAL_TYPES, categoryKey, extractMainType, extractStatementType, getCategoryMainType, getCategoryStatementType, getCurrency, getCustomJournalTypes, getJournalType, getJournalTypeCodes, getMinorUnit, getNormalBalance, isBalanceSheet, isIncomeStatement, isValidCategory, isValidCurrency, isValidJournalType, registerJournalType };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as Errors } from "./errors-
|
|
1
|
+
import { n as Errors } from "./errors-B_dyYZc_.mjs";
|
|
2
2
|
//#region src/plugins/double-entry.plugin.ts
|
|
3
3
|
function doubleEntryPlugin(options = {}) {
|
|
4
4
|
const { onlyOnPost = true, JournalEntryModel, AccountModel, orgField } = options;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { t as CountryPack } from "./index-CxZqRaOU.mjs";
|
|
2
2
|
import { t as Logger } from "./logger-UbTdBb1x.mjs";
|
|
3
|
+
import { Connection } from "mongoose";
|
|
3
4
|
|
|
4
5
|
//#region src/types/engine.d.ts
|
|
5
6
|
/** Multi-tenant configuration */
|
|
@@ -68,8 +69,35 @@ interface MultiCurrencyConfig {
|
|
|
68
69
|
/** Allowed foreign currency codes. If omitted, any ISO 4217 code is accepted. */
|
|
69
70
|
currencies?: readonly string[];
|
|
70
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Override default model names. Useful when you want to avoid collisions
|
|
74
|
+
* with existing models or use custom naming conventions.
|
|
75
|
+
*/
|
|
76
|
+
interface ModelNames {
|
|
77
|
+
account?: string;
|
|
78
|
+
journalEntry?: string;
|
|
79
|
+
fiscalPeriod?: string;
|
|
80
|
+
budget?: string;
|
|
81
|
+
reconciliation?: string;
|
|
82
|
+
}
|
|
71
83
|
/** Main engine configuration */
|
|
72
84
|
interface AccountingEngineConfig {
|
|
85
|
+
/**
|
|
86
|
+
* Mongoose connection. Required for `engine.models` and `engine.repositories`
|
|
87
|
+
* to be auto-populated. If omitted, you must use the low-level schema
|
|
88
|
+
* factories (`engine.createAccountSchema()`) and register models yourself.
|
|
89
|
+
*/
|
|
90
|
+
mongoose?: Connection;
|
|
91
|
+
/** Override default model names (e.g. 'Account' → 'GLAccount') */
|
|
92
|
+
modelNames?: ModelNames;
|
|
93
|
+
/** Extra fields / indexes per model */
|
|
94
|
+
schemaOptions?: {
|
|
95
|
+
account?: SchemaOptions;
|
|
96
|
+
journalEntry?: JournalSchemaOptions;
|
|
97
|
+
fiscalPeriod?: SchemaOptions;
|
|
98
|
+
budget?: SchemaOptions;
|
|
99
|
+
reconciliation?: SchemaOptions;
|
|
100
|
+
};
|
|
73
101
|
/** Country pack providing account types, tax codes, and templates */
|
|
74
102
|
country: CountryPack;
|
|
75
103
|
/** Default ISO 4217 currency code — the functional/base currency (e.g., 'CAD', 'BDT') */
|
|
@@ -99,4 +127,4 @@ interface AccountingEngineConfig {
|
|
|
99
127
|
strictness?: StrictnessConfig;
|
|
100
128
|
}
|
|
101
129
|
//#endregion
|
|
102
|
-
export {
|
|
130
|
+
export { MultiCurrencyConfig as a, StrictnessConfig as c, ModelNames as i, AuditConfig as n, MultiTenantConfig as o, JournalSchemaOptions as r, SchemaOptions as s, AccountingEngineConfig as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as Errors } from "./errors-
|
|
2
|
-
import { t as requireOrgScope } from "./tenant-guard-
|
|
3
|
-
import { i as extractMainType } from "./categories-
|
|
1
|
+
import { n as Errors } from "./errors-B_dyYZc_.mjs";
|
|
2
|
+
import { t as requireOrgScope } from "./tenant-guard-r17Se3Bb.mjs";
|
|
3
|
+
import { i as extractMainType } from "./categories-DWogBUgQ.mjs";
|
|
4
4
|
import mongoose from "mongoose";
|
|
5
5
|
//#region src/reports/aged-balance.ts
|
|
6
6
|
const DEFAULT_BUCKETS = [
|
package/dist/index.d.mts
CHANGED
|
@@ -4,15 +4,66 @@ import { a as TaxReportLine, i as TaxCodesByRegion, n as CountryPackInput, o as
|
|
|
4
4
|
import { _ as PopulatedJournalEntry, a as exportToCsv, h as FlatJournalRow, i as quickbooksFieldMap, m as ExportFieldMap, p as ExportField, r as universalFieldMap, t as flattenJournalEntries } from "./index-J-XIbXH-.mjs";
|
|
5
5
|
import { Money, abs, add, allocate, equals, format, formatPlain, fromDecimal, isNegative, isPositive, isValid, isZero, max, min, multiply, negate, parseCents, percentage, round, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal } from "./money.mjs";
|
|
6
6
|
import { n as defaultLogger, t as Logger } from "./logger-UbTdBb1x.mjs";
|
|
7
|
-
import { a as
|
|
8
|
-
import { a as BulkCreateInput, c as PostOptions, d as ReverseOptions, f as ReverseResult, i as AccountRepository, l as ReconcileParams, m as SeedResult, n as wireJournalEntryMethods, o as BulkCreateResult, p as SeedOptions, r as wireAccountMethods, s as JournalEntryRepository, t as wireReconciliationMethods, u as ReconciliationRepository } from "./reconciliation.repository-
|
|
9
|
-
import { n as createFiscalPeriodSchema, r as createAccountSchema, t as createJournalEntrySchema } from "./journal-entry.schema-
|
|
7
|
+
import { a as MultiCurrencyConfig, c as StrictnessConfig, i as ModelNames, n as AuditConfig, o as MultiTenantConfig, r as JournalSchemaOptions, s as SchemaOptions, t as AccountingEngineConfig } from "./engine-scgOvxHJ.mjs";
|
|
8
|
+
import { a as BulkCreateInput, c as PostOptions, d as ReverseOptions, f as ReverseResult, i as AccountRepository, l as ReconcileParams, m as SeedResult, n as wireJournalEntryMethods, o as BulkCreateResult, p as SeedOptions, r as wireAccountMethods, s as JournalEntryRepository, t as wireReconciliationMethods, u as ReconciliationRepository } from "./reconciliation.repository-D-D_ITL-.mjs";
|
|
9
|
+
import { n as createFiscalPeriodSchema, r as createAccountSchema, t as createJournalEntrySchema } from "./journal-entry.schema-JqrfbvB4.mjs";
|
|
10
10
|
import { c as dateLockPlugin, i as fiscalLockPlugin, n as idempotencyPlugin, o as doubleEntryPlugin } from "./idempotency.plugin-zU-GKJ0-.mjs";
|
|
11
11
|
import { $ as AgedBucketConfig, A as BudgetVsActualReport, B as IncomeStatementReport, C as DimensionBreakdownReport, D as generateCashFlow, F as BalanceSheetReport, G as TaxReport, H as ReportAccount, I as CashFlowReport, J as TrialBalanceRow, K as TaxReturnSummary, L as CashFlowSection, M as generateBudgetVsActual, O as BudgetVsActualOptions, P as generateBalanceSheet, Q as AgedBalanceRow, R as GeneralLedgerAccount, S as DimensionBreakdownParams, T as generateDimensionBreakdown, U as ReportCategory, V as LedgerEntry, W as ReportGroup, X as AgedBalanceParams, Y as AgedBalanceOptions, Z as AgedBalanceReport, a as RevaluationReport, b as reopenFiscalPeriod, c as RevaluationRate, d as computeRevaluation, et as DEFAULT_BUCKETS, h as generateGeneralLedger, i as RevaluationParams, j as BudgetVsActualRow, k as BudgetVsActualParams, l as RevaluationResult, n as generateTrialBalance, o as generateRevaluation, p as generateIncomeStatement, q as TrialBalanceReport, r as RevaluationOptions, s as AccountForeignBalance, tt as generateAgedBalance, u as buildRevaluationEntry, w as DimensionBreakdownRow, x as DimensionBreakdownOptions, y as closeFiscalPeriod, z as GeneralLedgerReport } from "./trial-balance-DcQ0xj_4.mjs";
|
|
12
12
|
import * as mongoose$1 from "mongoose";
|
|
13
13
|
import { ClientSession, Connection, Model } from "mongoose";
|
|
14
14
|
import { PluginType, Repository } from "@classytic/mongokit";
|
|
15
15
|
|
|
16
|
+
//#region src/models/factory.d.ts
|
|
17
|
+
interface LedgerModels {
|
|
18
|
+
Account: Model<unknown>;
|
|
19
|
+
JournalEntry: Model<unknown>;
|
|
20
|
+
FiscalPeriod: Model<unknown>;
|
|
21
|
+
Budget: Model<unknown>;
|
|
22
|
+
Reconciliation: Model<unknown>;
|
|
23
|
+
}
|
|
24
|
+
interface ResolvedModelNames {
|
|
25
|
+
account: string;
|
|
26
|
+
journalEntry: string;
|
|
27
|
+
fiscalPeriod: string;
|
|
28
|
+
budget: string;
|
|
29
|
+
reconciliation: string;
|
|
30
|
+
}
|
|
31
|
+
declare function resolveModelNames(overrides?: ModelNames): ResolvedModelNames;
|
|
32
|
+
/**
|
|
33
|
+
* Create (or reuse) all ledger models on the given connection.
|
|
34
|
+
*
|
|
35
|
+
* If a model with the same name is already registered on the connection,
|
|
36
|
+
* the existing model is reused — this allows multiple engine instances
|
|
37
|
+
* to share models and prevents "OverwriteModelError".
|
|
38
|
+
*/
|
|
39
|
+
declare function createModels(connection: Connection, config: AccountingEngineConfig): LedgerModels;
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/repositories/factory.d.ts
|
|
42
|
+
interface LedgerRepositoryPlugins {
|
|
43
|
+
account?: PluginType[];
|
|
44
|
+
journalEntry?: PluginType[];
|
|
45
|
+
fiscalPeriod?: PluginType[];
|
|
46
|
+
budget?: PluginType[];
|
|
47
|
+
reconciliation?: PluginType[];
|
|
48
|
+
}
|
|
49
|
+
interface LedgerRepositories {
|
|
50
|
+
accounts: AccountRepository<unknown>;
|
|
51
|
+
journalEntries: JournalEntryRepository<unknown>;
|
|
52
|
+
fiscalPeriods: Repository<unknown>;
|
|
53
|
+
budgets: Repository<unknown>;
|
|
54
|
+
reconciliations: ReconciliationRepository<unknown>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build all ledger repositories with plugins + domain methods pre-wired.
|
|
58
|
+
*
|
|
59
|
+
* - `accounts` — has seedAccounts(), bulkCreate()
|
|
60
|
+
* - `journalEntries` — has post(), unpost(), reverse(), duplicate() + double-entry + fiscal-lock (+ idempotency if enabled)
|
|
61
|
+
* - `fiscalPeriods` — plain CRUD
|
|
62
|
+
* - `budgets` — plain CRUD
|
|
63
|
+
* - `reconciliations` — has reconcile(), unreconcile(), getUnreconciled()
|
|
64
|
+
*/
|
|
65
|
+
declare function createRepositories(models: LedgerModels, config: AccountingEngineConfig, plugins?: LedgerRepositoryPlugins): LedgerRepositories;
|
|
66
|
+
//#endregion
|
|
16
67
|
//#region src/engine.d.ts
|
|
17
68
|
declare class AccountingEngine {
|
|
18
69
|
readonly config: AccountingEngineConfig;
|
|
@@ -42,7 +93,102 @@ declare class AccountingEngine {
|
|
|
42
93
|
readonly isValid: typeof isValid;
|
|
43
94
|
readonly parseCents: typeof parseCents;
|
|
44
95
|
};
|
|
45
|
-
|
|
96
|
+
private _models?;
|
|
97
|
+
private _repositories?;
|
|
98
|
+
private _reports?;
|
|
99
|
+
constructor(config: AccountingEngineConfig, plugins?: LedgerRepositoryPlugins);
|
|
100
|
+
/**
|
|
101
|
+
* Auto-created Mongoose models. Requires `mongoose` in config.
|
|
102
|
+
*
|
|
103
|
+
* @throws if `mongoose` was not provided in config
|
|
104
|
+
*/
|
|
105
|
+
get models(): LedgerModels;
|
|
106
|
+
/**
|
|
107
|
+
* Auto-wired repositories with plugins + domain methods (post, reverse, etc.).
|
|
108
|
+
* Requires `mongoose` in config.
|
|
109
|
+
*
|
|
110
|
+
* @throws if `mongoose` was not provided in config
|
|
111
|
+
*/
|
|
112
|
+
get repositories(): LedgerRepositories;
|
|
113
|
+
/**
|
|
114
|
+
* Pre-built reports bound to auto-created models. Requires `mongoose` in config.
|
|
115
|
+
* For custom models, use `engine.createReports({ Account, JournalEntry, Budget })`.
|
|
116
|
+
*/
|
|
117
|
+
get reports(): {
|
|
118
|
+
trialBalance: (params: {
|
|
119
|
+
organizationId?: unknown;
|
|
120
|
+
dateOption: "month" | "quarter" | "year" | "custom";
|
|
121
|
+
dateValue: unknown;
|
|
122
|
+
accountId?: string;
|
|
123
|
+
filters?: Record<string, unknown>;
|
|
124
|
+
}) => Promise<TrialBalanceReport>;
|
|
125
|
+
balanceSheet: (params: {
|
|
126
|
+
organizationId?: unknown;
|
|
127
|
+
dateOption: "month" | "quarter" | "year" | "custom";
|
|
128
|
+
dateValue: unknown;
|
|
129
|
+
businessName?: string;
|
|
130
|
+
filters?: Record<string, unknown>;
|
|
131
|
+
}) => Promise<BalanceSheetReport>;
|
|
132
|
+
incomeStatement: (params: {
|
|
133
|
+
organizationId?: unknown;
|
|
134
|
+
dateOption: "month" | "quarter" | "year" | "custom";
|
|
135
|
+
dateValue: unknown;
|
|
136
|
+
businessName?: string;
|
|
137
|
+
filters?: Record<string, unknown>;
|
|
138
|
+
}) => Promise<IncomeStatementReport>;
|
|
139
|
+
generalLedger: (params: {
|
|
140
|
+
organizationId?: unknown;
|
|
141
|
+
dateOption: "month" | "quarter" | "year" | "custom";
|
|
142
|
+
dateValue: unknown;
|
|
143
|
+
accountId?: string;
|
|
144
|
+
filters?: Record<string, unknown>;
|
|
145
|
+
}) => Promise<GeneralLedgerReport>;
|
|
146
|
+
cashFlow: (params: {
|
|
147
|
+
organizationId?: unknown;
|
|
148
|
+
dateOption: "month" | "quarter" | "year" | "custom";
|
|
149
|
+
dateValue: unknown;
|
|
150
|
+
businessName?: string;
|
|
151
|
+
filters?: Record<string, unknown>;
|
|
152
|
+
}) => Promise<CashFlowReport>;
|
|
153
|
+
agedBalance: (params: {
|
|
154
|
+
organizationId?: unknown;
|
|
155
|
+
asOfDate?: Date;
|
|
156
|
+
type: "receivable" | "payable";
|
|
157
|
+
accountIds?: unknown[];
|
|
158
|
+
dueDateField?: string;
|
|
159
|
+
contactField?: string;
|
|
160
|
+
buckets?: {
|
|
161
|
+
label: string;
|
|
162
|
+
minDays: number;
|
|
163
|
+
maxDays: number;
|
|
164
|
+
}[] | undefined;
|
|
165
|
+
}) => Promise<AgedBalanceReport>;
|
|
166
|
+
dimensionBreakdown: (params: {
|
|
167
|
+
organizationId?: unknown;
|
|
168
|
+
dateOption: "month" | "quarter" | "year" | "custom";
|
|
169
|
+
dateValue: unknown;
|
|
170
|
+
dimension: string;
|
|
171
|
+
accountCategory?: string;
|
|
172
|
+
filters?: Record<string, unknown>;
|
|
173
|
+
}) => Promise<DimensionBreakdownReport>;
|
|
174
|
+
budgetVsActual: (params: {
|
|
175
|
+
organizationId?: unknown;
|
|
176
|
+
dateOption: "month" | "quarter" | "year" | "custom";
|
|
177
|
+
dateValue: unknown;
|
|
178
|
+
accountIds?: unknown[];
|
|
179
|
+
filters?: Record<string, unknown>;
|
|
180
|
+
}) => Promise<BudgetVsActualReport>;
|
|
181
|
+
revaluation: (params: {
|
|
182
|
+
organizationId?: unknown;
|
|
183
|
+
asOfDate: Date;
|
|
184
|
+
rates: {
|
|
185
|
+
currency: string;
|
|
186
|
+
rate: number;
|
|
187
|
+
}[];
|
|
188
|
+
unrealizedGainLossAccountId: unknown;
|
|
189
|
+
generateEntry?: boolean;
|
|
190
|
+
}) => Promise<RevaluationReport>;
|
|
191
|
+
};
|
|
46
192
|
createAccountSchema(options?: SchemaOptions): mongoose$1.Schema<any, Model<any, any, any, any, any, any, any>, {}, {}, {}, {}, {
|
|
47
193
|
timestamps: true;
|
|
48
194
|
}, {
|
|
@@ -198,6 +344,11 @@ declare class AccountingEngine {
|
|
|
198
344
|
} & {
|
|
199
345
|
__v: number;
|
|
200
346
|
}>;
|
|
347
|
+
/**
|
|
348
|
+
* Build a reports object bound to the given models. Use this when you
|
|
349
|
+
* need custom/external models. Prefer `engine.reports` when the engine
|
|
350
|
+
* owns the models (via `mongoose` in config).
|
|
351
|
+
*/
|
|
201
352
|
createReports(models: {
|
|
202
353
|
Account: Model<unknown>;
|
|
203
354
|
JournalEntry: Model<unknown>;
|
|
@@ -277,6 +428,7 @@ declare class AccountingEngine {
|
|
|
277
428
|
generateEntry?: boolean;
|
|
278
429
|
}) => Promise<RevaluationReport>;
|
|
279
430
|
};
|
|
431
|
+
private _buildReports;
|
|
280
432
|
/** Get all posting account types (accounts you can post transactions to) */
|
|
281
433
|
getPostingAccountTypes(): readonly AccountType[];
|
|
282
434
|
/** Validate an account type code */
|
|
@@ -335,7 +487,7 @@ declare class AccountingEngine {
|
|
|
335
487
|
*/
|
|
336
488
|
wireReconciliationRepository<TDoc = unknown>(repository: Repository<TDoc>, ReconciliationModel: Model<unknown>, JournalEntryModel: Model<unknown>): ReconciliationRepository<TDoc>;
|
|
337
489
|
}
|
|
338
|
-
declare function createAccountingEngine(config: AccountingEngineConfig): AccountingEngine;
|
|
490
|
+
declare function createAccountingEngine(config: AccountingEngineConfig, plugins?: LedgerRepositoryPlugins): AccountingEngine;
|
|
339
491
|
//#endregion
|
|
340
492
|
//#region src/utils/account-helpers.d.ts
|
|
341
493
|
/**
|
|
@@ -527,4 +679,4 @@ interface PostingResult {
|
|
|
527
679
|
idempotencyKeys?: string[];
|
|
528
680
|
}
|
|
529
681
|
//#endregion
|
|
530
|
-
export { type AccountForeignBalance, type AccountRepository, type AccountType, AccountingEngine, type AccountingEngineConfig, AccountingError, type AgedBalanceOptions, type AgedBalanceParams, type AgedBalanceReport, type AgedBalanceRow, type AgedBucketConfig, type AuditConfig, type BalanceSheetReport, type BudgetVsActualOptions, type BudgetVsActualParams, type BudgetVsActualReport, type BudgetVsActualRow, type BulkCreateInput, type BulkCreateResult, CATEGORIES, CATEGORY_KEYS, CURRENCIES, type CashFlowCategory, type CashFlowReport, type CashFlowSection, type CategoryKey, type Cents, type CountryPack, type CountryPackInput, type Currency, DEFAULT_BUCKETS, type DateOption, type DateRange, type DimensionBreakdownOptions, type DimensionBreakdownParams, type DimensionBreakdownReport, type DimensionBreakdownRow, type DimensionDefinition, type EntryState, Errors, type ExportField, type ExportFieldMap, type FlatJournalRow, type GeneralLedgerAccount, type GeneralLedgerReport, type IncomeStatementReport, JOURNAL_CODES, JOURNAL_TYPES, type JournalEntryRepository, type JournalItem, type JournalSchemaOptions, type JournalType, type LedgerEntry, type Logger, type MainType, Money, type MultiCurrencyConfig, type MultiTenantConfig, type NormalBalance, type PopulatedJournalEntry, type PostOptions, type PostingContract, type PostingResult, type ReconcileParams, type ReconciliationRepository, type ReportAccount, type ReportCategory, type ReportGroup, type RevaluationOptions, type RevaluationParams, type RevaluationRate, type RevaluationReport, type RevaluationResult, type ReverseOptions, type ReverseResult, type SchemaOptions, type SeedOptions, type SeedResult, type SessionResult, type StatementType, type StrictnessConfig, type SubledgerJournalItem, type SubledgerPostingInput, type TaxCode, type TaxCodesByRegion, type TaxDetail, type TaxMetadata, type TaxReport, type TaxReportLine, type TaxReportTemplate, type TaxReturnSummary, type TotalAccountOp, type TrialBalanceReport, type TrialBalanceRow, acquireSession, add, allocate, buildAccountTypeMap, buildDimensionFields, buildDimensionIndexes, buildItemFilters, buildRevaluationEntry, calculateTotal, closeFiscalPeriod, computeEndingBalance, computeRevaluation, createAccountSchema, createAccountingEngine, createFiscalPeriodSchema, createJournalEntrySchema, dateLockPlugin, defaultLogger, defineCountryPack, doubleEntryPlugin, exportToCsv, finalizeSession, fiscalLockPlugin, flattenJournalEntries, format, formatPlain, fromDecimal, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generateRevaluation, generateTrialBalance, getCurrency, getCustomJournalTypes, getDateRange, getFiscalYearStart, getJournalType, getJournalTypeCodes, getMinorUnit, getNormalBalance, idempotencyPlugin, isBalanceSheet, isIncomeStatement, isValidCategory, isValidCurrency, isValidJournalType, isVirtualTaxAccount, multiply, parseCents, percentage, quickbooksFieldMap, registerJournalType, reopenFiscalPeriod, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal, universalFieldMap, wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|
|
682
|
+
export { type AccountForeignBalance, type AccountRepository, type AccountType, AccountingEngine, type AccountingEngineConfig, AccountingError, type AgedBalanceOptions, type AgedBalanceParams, type AgedBalanceReport, type AgedBalanceRow, type AgedBucketConfig, type AuditConfig, type BalanceSheetReport, type BudgetVsActualOptions, type BudgetVsActualParams, type BudgetVsActualReport, type BudgetVsActualRow, type BulkCreateInput, type BulkCreateResult, CATEGORIES, CATEGORY_KEYS, CURRENCIES, type CashFlowCategory, type CashFlowReport, type CashFlowSection, type CategoryKey, type Cents, type CountryPack, type CountryPackInput, type Currency, DEFAULT_BUCKETS, type DateOption, type DateRange, type DimensionBreakdownOptions, type DimensionBreakdownParams, type DimensionBreakdownReport, type DimensionBreakdownRow, type DimensionDefinition, type EntryState, Errors, type ExportField, type ExportFieldMap, type FlatJournalRow, type GeneralLedgerAccount, type GeneralLedgerReport, type IncomeStatementReport, JOURNAL_CODES, JOURNAL_TYPES, type JournalEntryRepository, type JournalItem, type JournalSchemaOptions, type JournalType, type LedgerEntry, type LedgerModels, type LedgerRepositories, type LedgerRepositoryPlugins, type Logger, type MainType, type ModelNames, Money, type MultiCurrencyConfig, type MultiTenantConfig, type NormalBalance, type PopulatedJournalEntry, type PostOptions, type PostingContract, type PostingResult, type ReconcileParams, type ReconciliationRepository, type ReportAccount, type ReportCategory, type ReportGroup, type ResolvedModelNames, type RevaluationOptions, type RevaluationParams, type RevaluationRate, type RevaluationReport, type RevaluationResult, type ReverseOptions, type ReverseResult, type SchemaOptions, type SeedOptions, type SeedResult, type SessionResult, type StatementType, type StrictnessConfig, type SubledgerJournalItem, type SubledgerPostingInput, type TaxCode, type TaxCodesByRegion, type TaxDetail, type TaxMetadata, type TaxReport, type TaxReportLine, type TaxReportTemplate, type TaxReturnSummary, type TotalAccountOp, type TrialBalanceReport, type TrialBalanceRow, acquireSession, add, allocate, buildAccountTypeMap, buildDimensionFields, buildDimensionIndexes, buildItemFilters, buildRevaluationEntry, calculateTotal, closeFiscalPeriod, computeEndingBalance, computeRevaluation, createAccountSchema, createAccountingEngine, createFiscalPeriodSchema, createJournalEntrySchema, createModels, createRepositories, dateLockPlugin, defaultLogger, defineCountryPack, doubleEntryPlugin, exportToCsv, finalizeSession, fiscalLockPlugin, flattenJournalEntries, format, formatPlain, fromDecimal, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generateRevaluation, generateTrialBalance, getCurrency, getCustomJournalTypes, getDateRange, getFiscalYearStart, getJournalType, getJournalTypeCodes, getMinorUnit, getNormalBalance, idempotencyPlugin, isBalanceSheet, isIncomeStatement, isValidCategory, isValidCurrency, isValidJournalType, isVirtualTaxAccount, multiply, parseCents, percentage, quickbooksFieldMap, registerJournalType, reopenFiscalPeriod, resolveModelNames, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal, universalFieldMap, wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|
package/dist/index.mjs
CHANGED
|
@@ -1,25 +1,154 @@
|
|
|
1
|
+
import { a as createAccountSchema, i as createBudgetSchema, n as createJournalEntrySchema, r as createFiscalPeriodSchema, t as createReconciliationSchema } from "./reconciliation.schema-BA1lPv4t.mjs";
|
|
2
|
+
import { a as getJournalType, c as registerJournalType, i as getCustomJournalTypes, n as JOURNAL_TYPES, o as getJournalTypeCodes, s as isValidJournalType, t as JOURNAL_CODES } from "./journals-BfwnCFam.mjs";
|
|
1
3
|
import { Money, add, allocate, format, formatPlain, fromDecimal, multiply, parseCents, percentage, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal } from "./money.mjs";
|
|
2
|
-
import { n as Errors, t as AccountingError } from "./errors-
|
|
3
|
-
import { i as doubleEntryPlugin, n as idempotencyPlugin, r as fiscalLockPlugin, t as dateLockPlugin } from "./date-lock.plugin-
|
|
4
|
-
import { C as DEFAULT_BUCKETS, S as isVirtualTaxAccount, _ as getDateRange, a as defaultLogger, b as calculateTotal, c as buildRevaluationEntry, d as generateGeneralLedger, f as generateDimensionBreakdown, g as buildItemFilters, h as generateBalanceSheet, i as finalizeSession, l as computeRevaluation, m as generateBudgetVsActual, n as reopenFiscalPeriod, o as generateTrialBalance, p as generateCashFlow, r as acquireSession, s as generateRevaluation, t as closeFiscalPeriod, u as generateIncomeStatement, v as getFiscalYearStart, w as generateAgedBalance, x as computeEndingBalance, y as buildAccountTypeMap } from "./fiscal-close-
|
|
5
|
-
import { c as getNormalBalance, d as isValidCategory, l as isBalanceSheet, n as CATEGORY_KEYS, t as CATEGORIES, u as isIncomeStatement } from "./categories-
|
|
6
|
-
import { n as wireJournalEntryMethods, r as wireAccountMethods, t as wireReconciliationMethods } from "./reconciliation.repository-
|
|
7
|
-
import { a as createAccountSchema, i as createBudgetSchema, n as createJournalEntrySchema, r as createFiscalPeriodSchema, t as createReconciliationSchema } from "./reconciliation.schema-KScbsXbY.mjs";
|
|
8
|
-
import { a as getJournalType, c as registerJournalType, i as getCustomJournalTypes, n as JOURNAL_TYPES, o as getJournalTypeCodes, s as isValidJournalType, t as JOURNAL_CODES } from "./journals-BcMn71Cq.mjs";
|
|
4
|
+
import { n as Errors, t as AccountingError } from "./errors-B_dyYZc_.mjs";
|
|
5
|
+
import { i as doubleEntryPlugin, n as idempotencyPlugin, r as fiscalLockPlugin, t as dateLockPlugin } from "./date-lock.plugin-DL6pe24p.mjs";
|
|
6
|
+
import { C as DEFAULT_BUCKETS, S as isVirtualTaxAccount, _ as getDateRange, a as defaultLogger, b as calculateTotal, c as buildRevaluationEntry, d as generateGeneralLedger, f as generateDimensionBreakdown, g as buildItemFilters, h as generateBalanceSheet, i as finalizeSession, l as computeRevaluation, m as generateBudgetVsActual, n as reopenFiscalPeriod, o as generateTrialBalance, p as generateCashFlow, r as acquireSession, s as generateRevaluation, t as closeFiscalPeriod, u as generateIncomeStatement, v as getFiscalYearStart, w as generateAgedBalance, x as computeEndingBalance, y as buildAccountTypeMap } from "./fiscal-close-B2_7WMTe.mjs";
|
|
7
|
+
import { c as getNormalBalance, d as isValidCategory, l as isBalanceSheet, n as CATEGORY_KEYS, t as CATEGORIES, u as isIncomeStatement } from "./categories-DWogBUgQ.mjs";
|
|
8
|
+
import { n as wireJournalEntryMethods, r as wireAccountMethods, t as wireReconciliationMethods } from "./reconciliation.repository-fPwFKvrk.mjs";
|
|
9
9
|
import { i as isValidCurrency, n as getCurrency, r as getMinorUnit, t as CURRENCIES } from "./currencies-W8kQAkm0.mjs";
|
|
10
10
|
import { defineCountryPack } from "./country/index.mjs";
|
|
11
11
|
import { a as exportToCsv, i as quickbooksFieldMap, r as universalFieldMap, t as flattenJournalEntries } from "./exports-DoGQQtMQ.mjs";
|
|
12
12
|
import { Schema } from "mongoose";
|
|
13
|
+
import { Repository } from "@classytic/mongokit";
|
|
14
|
+
//#region src/models/factory.ts
|
|
15
|
+
function resolveModelNames(overrides) {
|
|
16
|
+
return {
|
|
17
|
+
account: overrides?.account ?? "Account",
|
|
18
|
+
journalEntry: overrides?.journalEntry ?? "JournalEntry",
|
|
19
|
+
fiscalPeriod: overrides?.fiscalPeriod ?? "FiscalPeriod",
|
|
20
|
+
budget: overrides?.budget ?? "Budget",
|
|
21
|
+
reconciliation: overrides?.reconciliation ?? "Reconciliation"
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create (or reuse) all ledger models on the given connection.
|
|
26
|
+
*
|
|
27
|
+
* If a model with the same name is already registered on the connection,
|
|
28
|
+
* the existing model is reused — this allows multiple engine instances
|
|
29
|
+
* to share models and prevents "OverwriteModelError".
|
|
30
|
+
*/
|
|
31
|
+
function createModels(connection, config) {
|
|
32
|
+
const names = resolveModelNames(config.modelNames);
|
|
33
|
+
const so = config.schemaOptions ?? {};
|
|
34
|
+
const existing = connection.models;
|
|
35
|
+
if (existing[names.account] && existing[names.journalEntry] && existing[names.fiscalPeriod] && existing[names.budget] && existing[names.reconciliation]) return {
|
|
36
|
+
Account: existing[names.account],
|
|
37
|
+
JournalEntry: existing[names.journalEntry],
|
|
38
|
+
FiscalPeriod: existing[names.fiscalPeriod],
|
|
39
|
+
Budget: existing[names.budget],
|
|
40
|
+
Reconciliation: existing[names.reconciliation]
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
Account: existing[names.account] ?? connection.model(names.account, createAccountSchema(config, so.account)),
|
|
44
|
+
JournalEntry: existing[names.journalEntry] ?? connection.model(names.journalEntry, createJournalEntrySchema(config, names.account, so.journalEntry)),
|
|
45
|
+
FiscalPeriod: existing[names.fiscalPeriod] ?? connection.model(names.fiscalPeriod, createFiscalPeriodSchema(config, so.fiscalPeriod)),
|
|
46
|
+
Budget: existing[names.budget] ?? connection.model(names.budget, createBudgetSchema(config, so.budget)),
|
|
47
|
+
Reconciliation: existing[names.reconciliation] ?? connection.model(names.reconciliation, createReconciliationSchema(config, names.account, names.journalEntry, so.reconciliation))
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/repositories/factory.ts
|
|
52
|
+
/**
|
|
53
|
+
* Repositories Factory — wires fully-configured repositories.
|
|
54
|
+
*
|
|
55
|
+
* Matches the flow/promo pattern: engine owns the repositories with all
|
|
56
|
+
* plugins (double-entry, fiscal-lock, idempotency) pre-wired.
|
|
57
|
+
*
|
|
58
|
+
* Consumer never constructs Repository, never calls wireXxx methods.
|
|
59
|
+
* Just uses `engine.repositories.accounts.seedAccounts(orgId)`.
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Build all ledger repositories with plugins + domain methods pre-wired.
|
|
63
|
+
*
|
|
64
|
+
* - `accounts` — has seedAccounts(), bulkCreate()
|
|
65
|
+
* - `journalEntries` — has post(), unpost(), reverse(), duplicate() + double-entry + fiscal-lock (+ idempotency if enabled)
|
|
66
|
+
* - `fiscalPeriods` — plain CRUD
|
|
67
|
+
* - `budgets` — plain CRUD
|
|
68
|
+
* - `reconciliations` — has reconcile(), unreconcile(), getUnreconciled()
|
|
69
|
+
*/
|
|
70
|
+
function createRepositories(models, config, plugins = {}) {
|
|
71
|
+
const orgField = config.multiTenant?.orgField;
|
|
72
|
+
const strictness = config.strictness;
|
|
73
|
+
const country = config.country;
|
|
74
|
+
const accounts = wireAccountMethods(new Repository(models.Account, plugins.account ?? []), models.Account, country, orgField);
|
|
75
|
+
const jePlugins = [
|
|
76
|
+
...plugins.journalEntry ?? [],
|
|
77
|
+
doubleEntryPlugin({
|
|
78
|
+
JournalEntryModel: models.JournalEntry,
|
|
79
|
+
AccountModel: models.Account,
|
|
80
|
+
orgField
|
|
81
|
+
}),
|
|
82
|
+
fiscalLockPlugin({
|
|
83
|
+
FiscalPeriodModel: models.FiscalPeriod,
|
|
84
|
+
JournalEntryModel: models.JournalEntry,
|
|
85
|
+
orgField
|
|
86
|
+
})
|
|
87
|
+
];
|
|
88
|
+
if (config.idempotency) jePlugins.push(idempotencyPlugin({
|
|
89
|
+
JournalEntryModel: models.JournalEntry,
|
|
90
|
+
orgField
|
|
91
|
+
}));
|
|
92
|
+
return {
|
|
93
|
+
accounts,
|
|
94
|
+
journalEntries: wireJournalEntryMethods(new Repository(models.JournalEntry, jePlugins), models.JournalEntry, orgField, strictness),
|
|
95
|
+
fiscalPeriods: new Repository(models.FiscalPeriod, plugins.fiscalPeriod ?? []),
|
|
96
|
+
budgets: new Repository(models.Budget, plugins.budget ?? []),
|
|
97
|
+
reconciliations: wireReconciliationMethods(new Repository(models.Reconciliation, plugins.reconciliation ?? []), models.Reconciliation, models.JournalEntry, orgField)
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
13
101
|
//#region src/engine.ts
|
|
14
102
|
var AccountingEngine = class {
|
|
15
103
|
config;
|
|
16
104
|
country;
|
|
17
105
|
currency;
|
|
18
106
|
money = Money;
|
|
19
|
-
|
|
107
|
+
_models;
|
|
108
|
+
_repositories;
|
|
109
|
+
_reports;
|
|
110
|
+
constructor(config, plugins = {}) {
|
|
20
111
|
this.config = config;
|
|
21
112
|
this.country = config.country;
|
|
22
113
|
this.currency = config.currency;
|
|
114
|
+
if (config.mongoose) {
|
|
115
|
+
this._models = createModels(config.mongoose, config);
|
|
116
|
+
this._repositories = createRepositories(this._models, config, plugins);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Auto-created Mongoose models. Requires `mongoose` in config.
|
|
121
|
+
*
|
|
122
|
+
* @throws if `mongoose` was not provided in config
|
|
123
|
+
*/
|
|
124
|
+
get models() {
|
|
125
|
+
if (!this._models) throw new Error("engine.models requires a Mongoose connection. Pass `mongoose: connection` in createAccountingEngine config.");
|
|
126
|
+
return this._models;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Auto-wired repositories with plugins + domain methods (post, reverse, etc.).
|
|
130
|
+
* Requires `mongoose` in config.
|
|
131
|
+
*
|
|
132
|
+
* @throws if `mongoose` was not provided in config
|
|
133
|
+
*/
|
|
134
|
+
get repositories() {
|
|
135
|
+
if (!this._repositories) throw new Error("engine.repositories requires a Mongoose connection. Pass `mongoose: connection` in createAccountingEngine config.");
|
|
136
|
+
return this._repositories;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Pre-built reports bound to auto-created models. Requires `mongoose` in config.
|
|
140
|
+
* For custom models, use `engine.createReports({ Account, JournalEntry, Budget })`.
|
|
141
|
+
*/
|
|
142
|
+
get reports() {
|
|
143
|
+
if (!this._reports) {
|
|
144
|
+
if (!this._models) throw new Error("engine.reports requires a Mongoose connection. Pass `mongoose: connection` in createAccountingEngine config, or use engine.createReports({ Account, JournalEntry }) for manual models.");
|
|
145
|
+
this._reports = this._buildReports({
|
|
146
|
+
Account: this._models.Account,
|
|
147
|
+
JournalEntry: this._models.JournalEntry,
|
|
148
|
+
Budget: this._models.Budget
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return this._reports;
|
|
23
152
|
}
|
|
24
153
|
createAccountSchema(options) {
|
|
25
154
|
return createAccountSchema(this.config, options);
|
|
@@ -36,7 +165,15 @@ var AccountingEngine = class {
|
|
|
36
165
|
createReconciliationSchema(accountModelName, journalEntryModelName, options) {
|
|
37
166
|
return createReconciliationSchema(this.config, accountModelName, journalEntryModelName, options);
|
|
38
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Build a reports object bound to the given models. Use this when you
|
|
170
|
+
* need custom/external models. Prefer `engine.reports` when the engine
|
|
171
|
+
* owns the models (via `mongoose` in config).
|
|
172
|
+
*/
|
|
39
173
|
createReports(models) {
|
|
174
|
+
return this._buildReports(models);
|
|
175
|
+
}
|
|
176
|
+
_buildReports(models) {
|
|
40
177
|
const { Account: AccountModel, JournalEntry: JournalEntryModel, Budget: BudgetModel } = models;
|
|
41
178
|
const { country, config } = this;
|
|
42
179
|
const orgField = config.multiTenant?.orgField;
|
|
@@ -202,8 +339,8 @@ var AccountingEngine = class {
|
|
|
202
339
|
return wireReconciliationMethods(repository, ReconciliationModel, JournalEntryModel, orgField);
|
|
203
340
|
}
|
|
204
341
|
};
|
|
205
|
-
function createAccountingEngine(config) {
|
|
206
|
-
return new AccountingEngine(config);
|
|
342
|
+
function createAccountingEngine(config, plugins = {}) {
|
|
343
|
+
return new AccountingEngine(config, plugins);
|
|
207
344
|
}
|
|
208
345
|
//#endregion
|
|
209
346
|
//#region src/utils/dimensions.ts
|
|
@@ -265,4 +402,4 @@ function buildDimensionIndexes(dimensions, orgField) {
|
|
|
265
402
|
});
|
|
266
403
|
}
|
|
267
404
|
//#endregion
|
|
268
|
-
export { AccountingEngine, AccountingError, CATEGORIES, CATEGORY_KEYS, CURRENCIES, DEFAULT_BUCKETS, Errors, JOURNAL_CODES, JOURNAL_TYPES, Money, acquireSession, add, allocate, buildAccountTypeMap, buildDimensionFields, buildDimensionIndexes, buildItemFilters, buildRevaluationEntry, calculateTotal, closeFiscalPeriod, computeEndingBalance, computeRevaluation, createAccountSchema, createAccountingEngine, createFiscalPeriodSchema, createJournalEntrySchema, dateLockPlugin, defaultLogger, defineCountryPack, doubleEntryPlugin, exportToCsv, finalizeSession, fiscalLockPlugin, flattenJournalEntries, format, formatPlain, fromDecimal, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generateRevaluation, generateTrialBalance, getCurrency, getCustomJournalTypes, getDateRange, getFiscalYearStart, getJournalType, getJournalTypeCodes, getMinorUnit, getNormalBalance, idempotencyPlugin, isBalanceSheet, isIncomeStatement, isValidCategory, isValidCurrency, isValidJournalType, isVirtualTaxAccount, multiply, parseCents, percentage, quickbooksFieldMap, registerJournalType, reopenFiscalPeriod, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal, universalFieldMap, wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|
|
405
|
+
export { AccountingEngine, AccountingError, CATEGORIES, CATEGORY_KEYS, CURRENCIES, DEFAULT_BUCKETS, Errors, JOURNAL_CODES, JOURNAL_TYPES, Money, acquireSession, add, allocate, buildAccountTypeMap, buildDimensionFields, buildDimensionIndexes, buildItemFilters, buildRevaluationEntry, calculateTotal, closeFiscalPeriod, computeEndingBalance, computeRevaluation, createAccountSchema, createAccountingEngine, createFiscalPeriodSchema, createJournalEntrySchema, createModels, createRepositories, dateLockPlugin, defaultLogger, defineCountryPack, doubleEntryPlugin, exportToCsv, finalizeSession, fiscalLockPlugin, flattenJournalEntries, format, formatPlain, fromDecimal, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generateRevaluation, generateTrialBalance, getCurrency, getCustomJournalTypes, getDateRange, getFiscalYearStart, getJournalType, getJournalTypeCodes, getMinorUnit, getNormalBalance, idempotencyPlugin, isBalanceSheet, isIncomeStatement, isValidCategory, isValidCurrency, isValidJournalType, isVirtualTaxAccount, multiply, parseCents, percentage, quickbooksFieldMap, registerJournalType, reopenFiscalPeriod, resolveModelNames, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal, universalFieldMap, wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as JournalSchemaOptions, s as SchemaOptions, t as AccountingEngineConfig } from "./engine-scgOvxHJ.mjs";
|
|
2
2
|
import mongoose from "mongoose";
|
|
3
3
|
|
|
4
4
|
//#region src/schemas/account.schema.d.ts
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as doubleEntryPlugin, n as idempotencyPlugin, r as fiscalLockPlugin, t as dateLockPlugin } from "../date-lock.plugin-
|
|
1
|
+
import { i as doubleEntryPlugin, n as idempotencyPlugin, r as fiscalLockPlugin, t as dateLockPlugin } from "../date-lock.plugin-DL6pe24p.mjs";
|
|
2
2
|
//#region src/utils/tax-hooks.ts
|
|
3
3
|
/**
|
|
4
4
|
* Apply a tax hook to journal items.
|
package/dist/{reconciliation.repository-DEybU_Ok.d.mts → reconciliation.repository-D-D_ITL-.d.mts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as CountryPack } from "./index-CxZqRaOU.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { c as StrictnessConfig } from "./engine-scgOvxHJ.mjs";
|
|
3
3
|
import { ClientSession, Model } from "mongoose";
|
|
4
4
|
import { Repository } from "@classytic/mongokit";
|
|
5
5
|
|
package/dist/{reconciliation.repository-DgJEDVS-.mjs → reconciliation.repository-fPwFKvrk.mjs}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as Errors } from "./errors-
|
|
2
|
-
import { t as requireOrgScope } from "./tenant-guard-
|
|
1
|
+
import { n as Errors } from "./errors-B_dyYZc_.mjs";
|
|
2
|
+
import { t as requireOrgScope } from "./tenant-guard-r17Se3Bb.mjs";
|
|
3
3
|
//#region src/repositories/account.repository.ts
|
|
4
4
|
/**
|
|
5
5
|
* Wire seedAccounts, bulkCreate and posting-account validation
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as getJournalTypeCodes, r as _freezeJournalTypes, t as JOURNAL_CODES } from "./journals-
|
|
1
|
+
import { o as getJournalTypeCodes, r as _freezeJournalTypes, t as JOURNAL_CODES } from "./journals-BfwnCFam.mjs";
|
|
2
2
|
import mongoose from "mongoose";
|
|
3
3
|
//#region src/schemas/currency-field.ts
|
|
4
4
|
/**
|
package/dist/reports/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as DEFAULT_BUCKETS, d as generateGeneralLedger, f as generateDimensionBreakdown, h as generateBalanceSheet, m as generateBudgetVsActual, n as reopenFiscalPeriod, o as generateTrialBalance, p as generateCashFlow, s as generateRevaluation, t as closeFiscalPeriod, u as generateIncomeStatement, w as generateAgedBalance } from "../fiscal-close-
|
|
1
|
+
import { C as DEFAULT_BUCKETS, d as generateGeneralLedger, f as generateDimensionBreakdown, h as generateBalanceSheet, m as generateBudgetVsActual, n as reopenFiscalPeriod, o as generateTrialBalance, p as generateCashFlow, s as generateRevaluation, t as closeFiscalPeriod, u as generateIncomeStatement, w as generateAgedBalance } from "../fiscal-close-B2_7WMTe.mjs";
|
|
2
2
|
export { DEFAULT_BUCKETS, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as wireJournalEntryMethods, r as wireAccountMethods, t as wireReconciliationMethods } from "../reconciliation.repository-
|
|
1
|
+
import { n as wireJournalEntryMethods, r as wireAccountMethods, t as wireReconciliationMethods } from "../reconciliation.repository-D-D_ITL-.mjs";
|
|
2
2
|
export { wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as wireJournalEntryMethods, r as wireAccountMethods, t as wireReconciliationMethods } from "../reconciliation.repository-
|
|
1
|
+
import { n as wireJournalEntryMethods, r as wireAccountMethods, t as wireReconciliationMethods } from "../reconciliation.repository-fPwFKvrk.mjs";
|
|
2
2
|
export { wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|
package/dist/schemas/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as createFiscalPeriodSchema, r as createAccountSchema, t as createJournalEntrySchema } from "../journal-entry.schema-
|
|
1
|
+
import { s as SchemaOptions, t as AccountingEngineConfig } from "../engine-scgOvxHJ.mjs";
|
|
2
|
+
import { n as createFiscalPeriodSchema, r as createAccountSchema, t as createJournalEntrySchema } from "../journal-entry.schema-JqrfbvB4.mjs";
|
|
3
3
|
import mongoose from "mongoose";
|
|
4
4
|
|
|
5
5
|
//#region src/schemas/budget.schema.d.ts
|
package/dist/schemas/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createAccountSchema, i as createBudgetSchema, n as createJournalEntrySchema, r as createFiscalPeriodSchema, t as createReconciliationSchema } from "../reconciliation.schema-
|
|
1
|
+
import { a as createAccountSchema, i as createBudgetSchema, n as createJournalEntrySchema, r as createFiscalPeriodSchema, t as createReconciliationSchema } from "../reconciliation.schema-BA1lPv4t.mjs";
|
|
2
2
|
export { createAccountSchema, createBudgetSchema, createFiscalPeriodSchema, createJournalEntrySchema, createReconciliationSchema };
|
package/docs/schemas.md
CHANGED
|
@@ -52,8 +52,8 @@ const JournalEntry = mongoose.model('JournalEntry', JournalEntrySchema);
|
|
|
52
52
|
|
|
53
53
|
| Field | Type | Required | Description |
|
|
54
54
|
|---|---|---|---|
|
|
55
|
-
| `journalType` | String | Yes |
|
|
56
|
-
| `referenceNumber` | String | Auto | Auto-generated (e.g. `
|
|
55
|
+
| `journalType` | String | Yes | Built-in: `SALES`, `PURCHASES`, `CASH_RECEIPTS`, `CASH_PAYMENTS`, `PAYROLL`, `GENERAL`, `INVENTORY`, `FIXED_ASSETS`, `BANK_RECONCILIATION`, `DEPRECIATION`, `YEAR_END`, `ACCOUNTS_RECEIVABLE`, `ACCOUNTS_PAYABLE`, `TAX`, `MISC`. Extensible via `registerJournalType()` before schema creation. |
|
|
56
|
+
| `referenceNumber` | String | Auto | Auto-generated as `{JOURNAL_TYPE}/{YYYY}/{MM}/{NNNN}` (e.g. `SALES/2025/03/0001`). Unique per org. Sequence increments per journal type per month. |
|
|
57
57
|
| `label` | String | No | Description/memo |
|
|
58
58
|
| `date` | Date | No | Defaults to `new Date()` |
|
|
59
59
|
| `state` | String | No | `draft` (default), `posted`, or `archived` |
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|