@classytic/ledger 0.3.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.
Files changed (35) hide show
  1. package/README.md +82 -20
  2. package/dist/constants/index.d.mts +2 -2
  3. package/dist/constants/index.mjs +3 -3
  4. package/dist/{date-lock.plugin-eYAJ9h_u.mjs → date-lock.plugin-DL6pe24p.mjs} +2 -2
  5. package/dist/{engine-Cn-9yerQ.d.mts → engine-scgOvxHJ.d.mts} +30 -2
  6. package/dist/exports/index.d.mts +1 -1
  7. package/dist/exports/index.mjs +1 -1
  8. package/dist/{exports-I5Xkq-9_.mjs → exports-DoGQQtMQ.mjs} +96 -75
  9. package/dist/{fiscal-close-B6LhQ10f.mjs → fiscal-close-B2_7WMTe.mjs} +748 -751
  10. package/dist/{index-BPukb3L8.d.mts → index-J-XIbXH-.d.mts} +7 -7
  11. package/dist/index.d.mts +239 -87
  12. package/dist/index.mjs +149 -12
  13. package/dist/{fiscal-period.schema-BMnlI9H5.d.mts → journal-entry.schema-JqrfbvB4.d.mts} +12 -12
  14. package/dist/{journals-oH-FK3g8.mjs → journals-BfwnCFam.mjs} +27 -4
  15. package/dist/{currencies-4WAbFRlw.d.mts → journals-DTipb_rz.d.mts} +16 -7
  16. package/dist/money.mjs +2 -2
  17. package/dist/plugins/index.d.mts +1 -1
  18. package/dist/plugins/index.mjs +1 -1
  19. package/dist/{reconciliation.repository-CW4-8q90.d.mts → reconciliation.repository-D-D_ITL-.d.mts} +14 -14
  20. package/dist/{account.repository-BpkSd6q3.mjs → reconciliation.repository-fPwFKvrk.mjs} +255 -255
  21. package/dist/{reconciliation.schema-BuetvZTd.mjs → reconciliation.schema-BA1lPv4t.mjs} +174 -173
  22. package/dist/reports/index.d.mts +1 -1
  23. package/dist/reports/index.mjs +1 -1
  24. package/dist/repositories/index.d.mts +1 -1
  25. package/dist/repositories/index.mjs +1 -1
  26. package/dist/schemas/index.d.mts +6 -6
  27. package/dist/schemas/index.mjs +1 -1
  28. package/dist/{tenant-guard-Fm6AID_6.mjs → tenant-guard-r17Se3Bb.mjs} +1 -1
  29. package/dist/{revaluation-D9x0NE8w.d.mts → trial-balance-DcQ0xj_4.d.mts} +124 -124
  30. package/docs/schemas.md +2 -2
  31. package/package.json +14 -6
  32. /package/dist/{categories-CclX7Q94.mjs → categories-DWogBUgQ.mjs} +0 -0
  33. /package/dist/{errors-B7yC-Jfw.mjs → errors-B_dyYZc_.mjs} +0 -0
  34. /package/dist/{idempotency.plugin-B_CNsInz.d.mts → idempotency.plugin-zU-GKJ0-.d.mts} +0 -0
  35. /package/dist/{logger-CbHWZl7v.d.mts → logger-UbTdBb1x.d.mts} +0 -0
@@ -1,47 +1,50 @@
1
1
  import { c as DateRange } from "./core-8Xfnpn6g.mjs";
2
2
  import { t as CountryPack } from "./index-CxZqRaOU.mjs";
3
- import { t as Logger } from "./logger-CbHWZl7v.mjs";
3
+ import { t as Logger } from "./logger-UbTdBb1x.mjs";
4
4
  import { ClientSession, Model } from "mongoose";
5
5
 
6
- //#region src/reports/budget-vs-actual.d.ts
7
- interface BudgetVsActualOptions {
6
+ //#region src/reports/aged-balance.d.ts
7
+ interface AgedBucketConfig {
8
+ label: string;
9
+ minDays: number;
10
+ maxDays: number;
11
+ }
12
+ declare const DEFAULT_BUCKETS: AgedBucketConfig[];
13
+ interface AgedBalanceOptions {
8
14
  AccountModel: Model<unknown>;
9
15
  JournalEntryModel: Model<unknown>;
10
- BudgetModel: Model<unknown>;
11
16
  country: CountryPack;
12
17
  orgField?: string;
13
18
  }
14
- interface BudgetVsActualParams {
19
+ interface AgedBalanceParams {
15
20
  organizationId?: unknown;
16
- dateOption: 'month' | 'quarter' | 'year' | 'custom';
17
- dateValue: unknown;
21
+ asOfDate?: Date;
22
+ type: 'receivable' | 'payable';
18
23
  accountIds?: unknown[];
19
- filters?: Record<string, unknown>;
24
+ dueDateField?: string;
25
+ contactField?: string;
26
+ buckets?: AgedBucketConfig[];
20
27
  }
21
- interface BudgetVsActualRow {
28
+ interface AgedBalanceRow {
22
29
  accountId: unknown;
23
30
  accountName: string;
24
31
  accountCode: string;
25
- category: string;
26
- budgetAmount: number;
27
- actualAmount: number;
28
- variance: number;
29
- variancePercent: number;
32
+ contactId?: unknown;
33
+ total: number;
34
+ buckets: Record<string, number>;
30
35
  }
31
- interface BudgetVsActualReport {
36
+ interface AgedBalanceReport {
32
37
  metadata: {
33
38
  generatedAt: string;
34
- periodStart: string;
35
- periodEnd: string;
36
- };
37
- rows: BudgetVsActualRow[];
38
- summary: {
39
- totalBudget: number;
40
- totalActual: number;
41
- totalVariance: number;
39
+ asOfDate: string;
40
+ type: string;
42
41
  };
42
+ bucketLabels: string[];
43
+ rows: AgedBalanceRow[];
44
+ totals: Record<string, number>;
45
+ grandTotal: number;
43
46
  }
44
- declare function generateBudgetVsActual(opts: BudgetVsActualOptions, params: BudgetVsActualParams): Promise<BudgetVsActualReport>;
47
+ declare function generateAgedBalance(opts: AgedBalanceOptions, params: AgedBalanceParams): Promise<AgedBalanceReport>;
45
48
  //#endregion
46
49
  //#region src/types/report.d.ts
47
50
  interface ReportMetadata {
@@ -195,23 +198,6 @@ interface TaxReport {
195
198
  calculatedAt: string;
196
199
  }
197
200
  //#endregion
198
- //#region src/reports/trial-balance.d.ts
199
- interface TrialBalanceOptions {
200
- AccountModel: Model<unknown>;
201
- JournalEntryModel: Model<unknown>;
202
- country: CountryPack;
203
- orgField?: string;
204
- fiscalYearStartMonth?: number;
205
- }
206
- declare function generateTrialBalance(opts: TrialBalanceOptions, params: {
207
- organizationId?: unknown;
208
- dateOption: 'month' | 'quarter' | 'year' | 'custom';
209
- dateValue: unknown;
210
- accountId?: string;
211
- businessName?: string;
212
- filters?: Record<string, unknown>;
213
- }): Promise<TrialBalanceReport>;
214
- //#endregion
215
201
  //#region src/reports/balance-sheet.d.ts
216
202
  interface BalanceSheetOptions {
217
203
  AccountModel: Model<unknown>;
@@ -238,52 +224,100 @@ declare function generateBalanceSheet(opts: BalanceSheetOptions, params: {
238
224
  filters?: Record<string, unknown>;
239
225
  }): Promise<BalanceSheetReport>;
240
226
  //#endregion
241
- //#region src/reports/income-statement.d.ts
242
- interface IncomeStatementOptions {
227
+ //#region src/reports/budget-vs-actual.d.ts
228
+ interface BudgetVsActualOptions {
243
229
  AccountModel: Model<unknown>;
244
230
  JournalEntryModel: Model<unknown>;
231
+ BudgetModel: Model<unknown>;
245
232
  country: CountryPack;
246
233
  orgField?: string;
247
234
  }
248
- declare function generateIncomeStatement(opts: IncomeStatementOptions, params: {
235
+ interface BudgetVsActualParams {
249
236
  organizationId?: unknown;
250
237
  dateOption: 'month' | 'quarter' | 'year' | 'custom';
251
238
  dateValue: unknown;
252
- businessName?: string;
239
+ accountIds?: unknown[];
253
240
  filters?: Record<string, unknown>;
254
- }): Promise<IncomeStatementReport>;
241
+ }
242
+ interface BudgetVsActualRow {
243
+ accountId: unknown;
244
+ accountName: string;
245
+ accountCode: string;
246
+ category: string;
247
+ budgetAmount: number;
248
+ actualAmount: number;
249
+ variance: number;
250
+ variancePercent: number;
251
+ }
252
+ interface BudgetVsActualReport {
253
+ metadata: {
254
+ generatedAt: string;
255
+ periodStart: string;
256
+ periodEnd: string;
257
+ };
258
+ rows: BudgetVsActualRow[];
259
+ summary: {
260
+ totalBudget: number;
261
+ totalActual: number;
262
+ totalVariance: number;
263
+ };
264
+ }
265
+ declare function generateBudgetVsActual(opts: BudgetVsActualOptions, params: BudgetVsActualParams): Promise<BudgetVsActualReport>;
255
266
  //#endregion
256
- //#region src/reports/general-ledger.d.ts
257
- interface GeneralLedgerOptions {
267
+ //#region src/reports/cash-flow.d.ts
268
+ interface CashFlowOptions {
258
269
  AccountModel: Model<unknown>;
259
270
  JournalEntryModel: Model<unknown>;
260
271
  country: CountryPack;
261
272
  orgField?: string;
262
- fiscalYearStartMonth?: number;
263
273
  }
264
- declare function generateGeneralLedger(opts: GeneralLedgerOptions, params: {
274
+ declare function generateCashFlow(opts: CashFlowOptions, params: {
265
275
  organizationId?: unknown;
266
276
  dateOption: 'month' | 'quarter' | 'year' | 'custom';
267
277
  dateValue: unknown;
268
- accountId?: string;
269
278
  businessName?: string;
270
279
  filters?: Record<string, unknown>;
271
- }): Promise<GeneralLedgerReport>;
280
+ }): Promise<CashFlowReport>;
272
281
  //#endregion
273
- //#region src/reports/cash-flow.d.ts
274
- interface CashFlowOptions {
282
+ //#region src/reports/dimension-breakdown.d.ts
283
+ interface DimensionBreakdownOptions {
275
284
  AccountModel: Model<unknown>;
276
285
  JournalEntryModel: Model<unknown>;
277
286
  country: CountryPack;
278
287
  orgField?: string;
279
288
  }
280
- declare function generateCashFlow(opts: CashFlowOptions, params: {
289
+ interface DimensionBreakdownParams {
281
290
  organizationId?: unknown;
282
291
  dateOption: 'month' | 'quarter' | 'year' | 'custom';
283
292
  dateValue: unknown;
284
- businessName?: string;
293
+ /** Field on journalItems to group by, e.g. 'departmentId' */
294
+ dimension: string;
295
+ /** Filter accounts by category, e.g. 'Income Statement-Expense' */
296
+ accountCategory?: string;
297
+ /** Additional item-level filters */
285
298
  filters?: Record<string, unknown>;
286
- }): Promise<CashFlowReport>;
299
+ }
300
+ interface DimensionBreakdownRow {
301
+ dimensionValue: unknown;
302
+ accounts: Array<{
303
+ id: unknown;
304
+ name: string;
305
+ code: string;
306
+ balance: number;
307
+ }>;
308
+ total: number;
309
+ }
310
+ interface DimensionBreakdownReport {
311
+ metadata: {
312
+ generatedAt: string;
313
+ dimension: string;
314
+ periodStart: string;
315
+ periodEnd: string;
316
+ };
317
+ rows: DimensionBreakdownRow[];
318
+ grandTotal: number;
319
+ }
320
+ declare function generateDimensionBreakdown(opts: DimensionBreakdownOptions, params: DimensionBreakdownParams): Promise<DimensionBreakdownReport>;
287
321
  //#endregion
288
322
  //#region src/reports/fiscal-close.d.ts
289
323
  interface FiscalCloseOptions {
@@ -325,88 +359,37 @@ declare function reopenFiscalPeriod(opts: Pick<FiscalCloseOptions, 'JournalEntry
325
359
  session?: ClientSession;
326
360
  }): Promise<FiscalReopenResult>;
327
361
  //#endregion
328
- //#region src/reports/dimension-breakdown.d.ts
329
- interface DimensionBreakdownOptions {
362
+ //#region src/reports/general-ledger.d.ts
363
+ interface GeneralLedgerOptions {
330
364
  AccountModel: Model<unknown>;
331
365
  JournalEntryModel: Model<unknown>;
332
366
  country: CountryPack;
333
367
  orgField?: string;
368
+ fiscalYearStartMonth?: number;
334
369
  }
335
- interface DimensionBreakdownParams {
370
+ declare function generateGeneralLedger(opts: GeneralLedgerOptions, params: {
336
371
  organizationId?: unknown;
337
372
  dateOption: 'month' | 'quarter' | 'year' | 'custom';
338
373
  dateValue: unknown;
339
- /** Field on journalItems to group by, e.g. 'departmentId' */
340
- dimension: string;
341
- /** Filter accounts by category, e.g. 'Income Statement-Expense' */
342
- accountCategory?: string;
343
- /** Additional item-level filters */
374
+ accountId?: string;
375
+ businessName?: string;
344
376
  filters?: Record<string, unknown>;
345
- }
346
- interface DimensionBreakdownRow {
347
- dimensionValue: unknown;
348
- accounts: Array<{
349
- id: unknown;
350
- name: string;
351
- code: string;
352
- balance: number;
353
- }>;
354
- total: number;
355
- }
356
- interface DimensionBreakdownReport {
357
- metadata: {
358
- generatedAt: string;
359
- dimension: string;
360
- periodStart: string;
361
- periodEnd: string;
362
- };
363
- rows: DimensionBreakdownRow[];
364
- grandTotal: number;
365
- }
366
- declare function generateDimensionBreakdown(opts: DimensionBreakdownOptions, params: DimensionBreakdownParams): Promise<DimensionBreakdownReport>;
377
+ }): Promise<GeneralLedgerReport>;
367
378
  //#endregion
368
- //#region src/reports/aged-balance.d.ts
369
- interface AgedBucketConfig {
370
- label: string;
371
- minDays: number;
372
- maxDays: number;
373
- }
374
- declare const DEFAULT_BUCKETS: AgedBucketConfig[];
375
- interface AgedBalanceOptions {
379
+ //#region src/reports/income-statement.d.ts
380
+ interface IncomeStatementOptions {
376
381
  AccountModel: Model<unknown>;
377
382
  JournalEntryModel: Model<unknown>;
378
383
  country: CountryPack;
379
384
  orgField?: string;
380
385
  }
381
- interface AgedBalanceParams {
386
+ declare function generateIncomeStatement(opts: IncomeStatementOptions, params: {
382
387
  organizationId?: unknown;
383
- asOfDate?: Date;
384
- type: 'receivable' | 'payable';
385
- accountIds?: unknown[];
386
- dueDateField?: string;
387
- contactField?: string;
388
- buckets?: AgedBucketConfig[];
389
- }
390
- interface AgedBalanceRow {
391
- accountId: unknown;
392
- accountName: string;
393
- accountCode: string;
394
- contactId?: unknown;
395
- total: number;
396
- buckets: Record<string, number>;
397
- }
398
- interface AgedBalanceReport {
399
- metadata: {
400
- generatedAt: string;
401
- asOfDate: string;
402
- type: string;
403
- };
404
- bucketLabels: string[];
405
- rows: AgedBalanceRow[];
406
- totals: Record<string, number>;
407
- grandTotal: number;
408
- }
409
- declare function generateAgedBalance(opts: AgedBalanceOptions, params: AgedBalanceParams): Promise<AgedBalanceReport>;
388
+ dateOption: 'month' | 'quarter' | 'year' | 'custom';
389
+ dateValue: unknown;
390
+ businessName?: string;
391
+ filters?: Record<string, unknown>;
392
+ }): Promise<IncomeStatementReport>;
410
393
  //#endregion
411
394
  //#region src/utils/revaluation.d.ts
412
395
  /**
@@ -527,4 +510,21 @@ interface RevaluationReport {
527
510
  */
528
511
  declare function generateRevaluation(opts: RevaluationOptions, params: RevaluationParams): Promise<RevaluationReport>;
529
512
  //#endregion
530
- export { BudgetVsActualReport as $, generateGeneralLedger as A, GeneralLedgerAccount as B, FiscalCloseResult as C, CashFlowOptions as D, reopenFiscalPeriod as E, TrialBalanceOptions as F, ReportCategory as G, IncomeStatementReport as H, generateTrialBalance as I, TaxReturnSummary as J, ReportGroup as K, BalanceSheetReport as L, generateIncomeStatement as M, BalanceSheetOptions as N, generateCashFlow as O, generateBalanceSheet as P, BudgetVsActualParams as Q, CashFlowReport as R, FiscalCloseOptions as S, closeFiscalPeriod as T, LedgerEntry as U, GeneralLedgerReport as V, ReportAccount as W, TrialBalanceRow as X, TrialBalanceReport as Y, BudgetVsActualOptions as Z, DimensionBreakdownOptions as _, AccountForeignBalance as a, DimensionBreakdownRow as b, buildRevaluationEntry as c, AgedBalanceParams as d, BudgetVsActualRow as et, AgedBalanceReport as f, generateAgedBalance as g, DEFAULT_BUCKETS as h, generateRevaluation as i, IncomeStatementOptions as j, GeneralLedgerOptions as k, computeRevaluation as l, AgedBucketConfig as m, RevaluationParams as n, RevaluationRate as o, AgedBalanceRow as p, TaxReport as q, RevaluationReport as r, RevaluationResult as s, RevaluationOptions as t, generateBudgetVsActual as tt, AgedBalanceOptions as u, DimensionBreakdownParams as v, FiscalReopenResult as w, generateDimensionBreakdown as x, DimensionBreakdownReport as y, CashFlowSection as z };
513
+ //#region src/reports/trial-balance.d.ts
514
+ interface TrialBalanceOptions {
515
+ AccountModel: Model<unknown>;
516
+ JournalEntryModel: Model<unknown>;
517
+ country: CountryPack;
518
+ orgField?: string;
519
+ fiscalYearStartMonth?: number;
520
+ }
521
+ declare function generateTrialBalance(opts: TrialBalanceOptions, params: {
522
+ organizationId?: unknown;
523
+ dateOption: 'month' | 'quarter' | 'year' | 'custom';
524
+ dateValue: unknown;
525
+ accountId?: string;
526
+ businessName?: string;
527
+ filters?: Record<string, unknown>;
528
+ }): Promise<TrialBalanceReport>;
529
+ //#endregion
530
+ export { AgedBucketConfig as $, BudgetVsActualReport as A, IncomeStatementReport as B, DimensionBreakdownReport as C, generateCashFlow as D, CashFlowOptions as E, BalanceSheetReport as F, TaxReport as G, ReportAccount as H, CashFlowReport as I, TrialBalanceRow as J, TaxReturnSummary as K, CashFlowSection as L, generateBudgetVsActual as M, BalanceSheetOptions as N, BudgetVsActualOptions as O, generateBalanceSheet as P, AgedBalanceRow as Q, GeneralLedgerAccount as R, DimensionBreakdownParams as S, generateDimensionBreakdown as T, ReportCategory as U, LedgerEntry as V, ReportGroup as W, AgedBalanceParams as X, AgedBalanceOptions as Y, AgedBalanceReport as Z, FiscalCloseResult as _, RevaluationReport as a, reopenFiscalPeriod as b, RevaluationRate as c, computeRevaluation as d, DEFAULT_BUCKETS as et, IncomeStatementOptions as f, FiscalCloseOptions as g, generateGeneralLedger as h, RevaluationParams as i, BudgetVsActualRow as j, BudgetVsActualParams as k, RevaluationResult as l, GeneralLedgerOptions as m, generateTrialBalance as n, generateRevaluation as o, generateIncomeStatement as p, TrialBalanceReport as q, RevaluationOptions as r, AccountForeignBalance as s, TrialBalanceOptions as t, generateAgedBalance as tt, buildRevaluationEntry as u, FiscalReopenResult as v, DimensionBreakdownRow as w, DimensionBreakdownOptions as x, closeFiscalPeriod as y, GeneralLedgerReport as z };
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 | One of: `GENERAL`, `SALES`, `PURCHASE`, `CASH_RECEIPT`, `CASH_DISBURSEMENT`, `PAYROLL`, `ADJUSTMENT`, `YEAR_END`, `MISC` |
56
- | `referenceNumber` | String | Auto | Auto-generated (e.g. `GJ-0001`). Unique per org |
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/ledger",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Production-grade double-entry accounting engine for MongoDB — schemas, reports, tax, multi-tenant",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -88,8 +88,8 @@
88
88
  "url": "git+https://github.com/classytic/accounting.git"
89
89
  },
90
90
  "peerDependencies": {
91
- "@classytic/mongokit": ">=3.4.3",
92
- "mongoose": ">=9.0.0"
91
+ "@classytic/mongokit": ">=3.5.3",
92
+ "mongoose": ">=9.4.1"
93
93
  },
94
94
  "engines": {
95
95
  "node": ">=22"
@@ -101,14 +101,22 @@
101
101
  "test:watch": "vitest",
102
102
  "test:coverage": "vitest run --coverage",
103
103
  "typecheck": "tsc --noEmit",
104
- "prepublishOnly": "npm run build && npm run typecheck",
105
- "release": "npm run build && npm run typecheck && npm publish --access public"
104
+ "lint": "biome check src/",
105
+ "lint:fix": "biome check src/ --write",
106
+ "format": "biome format src/ --write",
107
+ "check": "biome ci src/ --diagnostic-level=error",
108
+ "knip": "knip",
109
+ "prepublishOnly": "npm run check && npm run build && npm run typecheck && npm test",
110
+ "release": "npm run check && npm run build && npm run typecheck && npm test && npm publish --access public"
106
111
  },
107
112
  "devDependencies": {
113
+ "@biomejs/biome": "^2.4.10",
114
+ "@classytic/mongokit": "^3.5.3",
108
115
  "@types/node": "^22.0.0",
109
116
  "@vitest/coverage-v8": "^3.2.4",
117
+ "knip": "^6.3.0",
110
118
  "mongodb-memory-server": "^10.2.3",
111
- "mongoose": "^9.3.1",
119
+ "mongoose": "^9.4.1",
112
120
  "tsdown": "^0.21.5",
113
121
  "typescript": "^5.7.0",
114
122
  "vitest": "^3.0.0"