@classytic/ledger 0.2.0 → 0.3.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.
Files changed (66) hide show
  1. package/README.md +161 -64
  2. package/dist/{account.repository-kDKwDt0I.mjs → account.repository-BpkSd6q3.mjs} +189 -38
  3. package/dist/categories-CclX7Q94.mjs +0 -2
  4. package/dist/core-8Xfnpn6g.d.mts +1 -2
  5. package/dist/country/index.d.mts +1 -1
  6. package/dist/country/index.mjs +0 -2
  7. package/dist/currencies-4WAbFRlw.d.mts +1 -2
  8. package/dist/currencies-W8kQAkm0.mjs +0 -2
  9. package/dist/{idempotency.plugin-v9NQ_ta-.mjs → date-lock.plugin-eYAJ9h_u.mjs} +49 -9
  10. package/dist/{engine-BzBMpWuy.d.mts → engine-Cn-9yerQ.d.mts} +11 -7
  11. package/dist/errors-B7yC-Jfw.mjs +0 -2
  12. package/dist/exports-I5Xkq-9_.mjs +0 -2
  13. package/dist/{fiscal-close-L631E3De.mjs → fiscal-close-B6LhQ10f.mjs} +737 -20
  14. package/dist/fiscal-period.schema-BMnlI9H5.d.mts +103 -0
  15. package/dist/{idempotency.plugin-CPxPt4vX.d.mts → idempotency.plugin-B_CNsInz.d.mts} +19 -17
  16. package/dist/index-BPukb3L8.d.mts +1 -2
  17. package/dist/{index-ZnSiqHYV.d.mts → index-CxZqRaOU.d.mts} +20 -6
  18. package/dist/index.d.mts +248 -26
  19. package/dist/index.mjs +119 -21
  20. package/dist/journals-oH-FK3g8.mjs +0 -2
  21. package/dist/{logger-UbTdBb1x.d.mts → logger-CbHWZl7v.d.mts} +1 -2
  22. package/dist/money.d.mts +1 -2
  23. package/dist/money.mjs +3 -3
  24. package/dist/plugins/index.d.mts +38 -2
  25. package/dist/plugins/index.mjs +57 -2
  26. package/dist/reconciliation.repository-CW4-8q90.d.mts +135 -0
  27. package/dist/{fiscal-period.schema-BQ5wsAq3.mjs → reconciliation.schema-BuetvZTd.mjs} +168 -24
  28. package/dist/reports/index.d.mts +2 -2
  29. package/dist/reports/index.mjs +2 -2
  30. package/dist/repositories/index.d.mts +2 -2
  31. package/dist/repositories/index.mjs +2 -2
  32. package/dist/revaluation-D9x0NE8w.d.mts +530 -0
  33. package/dist/schemas/index.d.mts +71 -2
  34. package/dist/schemas/index.mjs +2 -2
  35. package/dist/tenant-guard-Fm6AID_6.mjs +13 -0
  36. package/docs/reports.md +1 -1
  37. package/package.json +2 -2
  38. package/dist/account.repository-C7gwFLfM.d.mts +0 -29
  39. package/dist/account.repository-C7gwFLfM.d.mts.map +0 -1
  40. package/dist/account.repository-kDKwDt0I.mjs.map +0 -1
  41. package/dist/categories-CclX7Q94.mjs.map +0 -1
  42. package/dist/core-8Xfnpn6g.d.mts.map +0 -1
  43. package/dist/country/index.mjs.map +0 -1
  44. package/dist/currencies-4WAbFRlw.d.mts.map +0 -1
  45. package/dist/currencies-W8kQAkm0.mjs.map +0 -1
  46. package/dist/engine-BzBMpWuy.d.mts.map +0 -1
  47. package/dist/errors-B7yC-Jfw.mjs.map +0 -1
  48. package/dist/exports-I5Xkq-9_.mjs.map +0 -1
  49. package/dist/fiscal-close-L631E3De.mjs.map +0 -1
  50. package/dist/fiscal-close-dNlzB37y.d.mts +0 -270
  51. package/dist/fiscal-close-dNlzB37y.d.mts.map +0 -1
  52. package/dist/fiscal-period.schema-BQ5wsAq3.mjs.map +0 -1
  53. package/dist/fiscal-period.schema-BRdKAjrr.d.mts +0 -38
  54. package/dist/fiscal-period.schema-BRdKAjrr.d.mts.map +0 -1
  55. package/dist/idempotency.plugin-CPxPt4vX.d.mts.map +0 -1
  56. package/dist/idempotency.plugin-v9NQ_ta-.mjs.map +0 -1
  57. package/dist/index-BPukb3L8.d.mts.map +0 -1
  58. package/dist/index-ZnSiqHYV.d.mts.map +0 -1
  59. package/dist/index.d.mts.map +0 -1
  60. package/dist/index.mjs.map +0 -1
  61. package/dist/journals-oH-FK3g8.mjs.map +0 -1
  62. package/dist/logger-UbTdBb1x.d.mts.map +0 -1
  63. package/dist/money.d.mts.map +0 -1
  64. package/dist/money.mjs.map +0 -1
  65. package/dist/session-Ba8E3Ufa.mjs +0 -84
  66. package/dist/session-Ba8E3Ufa.mjs.map +0 -1
@@ -80,8 +80,8 @@ function doubleEntryPlugin(options = {}) {
80
80
  ...existing
81
81
  }, context);
82
82
  };
83
- repo.on("before:create", (payload) => validate(payload));
84
- repo.on("before:update", (payload) => validateUpdate(payload));
83
+ repo.on("before:create", validate);
84
+ repo.on("before:update", validateUpdate);
85
85
  }
86
86
  };
87
87
  }
@@ -132,8 +132,8 @@ function fiscalLockPlugin(options) {
132
132
  throw Errors.fiscal(`Cannot post entry dated ${entryDate.toISOString().split("T")[0]}: fiscal period "${period.name}" is closed.`);
133
133
  }
134
134
  };
135
- repo.on("before:create", (payload) => checkPeriod(payload, false));
136
- repo.on("before:update", (payload) => checkPeriod(payload, true));
135
+ repo.on("before:create", (ctx) => checkPeriod(ctx, false));
136
+ repo.on("before:update", (ctx) => checkPeriod(ctx, true));
137
137
  }
138
138
  };
139
139
  }
@@ -144,8 +144,7 @@ function idempotencyPlugin(options) {
144
144
  return {
145
145
  name: "accounting:idempotency",
146
146
  apply(repo) {
147
- repo.on("before:create", async (raw) => {
148
- const context = raw;
147
+ repo.on("before:create", async (context) => {
149
148
  const data = context.data;
150
149
  if (!data?.idempotencyKey) return;
151
150
  const query = { idempotencyKey: data.idempotencyKey };
@@ -157,6 +156,47 @@ function idempotencyPlugin(options) {
157
156
  };
158
157
  }
159
158
  //#endregion
160
- export { fiscalLockPlugin as n, doubleEntryPlugin as r, idempotencyPlugin as t };
161
-
162
- //# sourceMappingURL=idempotency.plugin-v9NQ_ta-.mjs.map
159
+ //#region src/plugins/date-lock.plugin.ts
160
+ function dateLockPlugin(options) {
161
+ const { getLockDate, JournalEntryModel, orgField } = options;
162
+ return {
163
+ name: "accounting:date-lock",
164
+ apply(repo) {
165
+ const checkLock = async (context, isUpdate) => {
166
+ const data = context.data;
167
+ if (!data) return;
168
+ if (data.state !== "posted") return;
169
+ const session = context.session ?? null;
170
+ let entryDate;
171
+ let persistedDoc = null;
172
+ if (data.date) entryDate = new Date(data.date);
173
+ else if (!isUpdate) entryDate = /* @__PURE__ */ new Date();
174
+ else {
175
+ if (!context.id) throw new Error("dateLockPlugin: update context is missing \"id\". Cannot validate date lock without document ID.");
176
+ const selectFields = orgField ? `date ${orgField}` : "date";
177
+ persistedDoc = await JournalEntryModel.findById(context.id).select(selectFields).session(session).lean();
178
+ if (persistedDoc?.date) entryDate = new Date(persistedDoc.date);
179
+ }
180
+ if (!entryDate) return;
181
+ let orgValue;
182
+ if (orgField) {
183
+ orgValue = data[orgField] ?? context[orgField];
184
+ if (!orgValue && isUpdate) {
185
+ if (persistedDoc) orgValue = persistedDoc[orgField];
186
+ else if (context.id) {
187
+ const persisted = await JournalEntryModel.findById(context.id).select(orgField).session(session).lean();
188
+ if (persisted) orgValue = persisted[orgField];
189
+ }
190
+ }
191
+ }
192
+ const lockDate = await getLockDate(orgValue, session ?? void 0);
193
+ if (!lockDate) return;
194
+ if (entryDate < lockDate) throw Errors.fiscal(`Cannot post entry dated ${entryDate.toISOString().split("T")[0]}: date is before lock date ${lockDate.toISOString().split("T")[0]}.`);
195
+ };
196
+ repo.on("before:create", (ctx) => checkLock(ctx, false));
197
+ repo.on("before:update", (ctx) => checkLock(ctx, true));
198
+ }
199
+ };
200
+ }
201
+ //#endregion
202
+ export { doubleEntryPlugin as i, idempotencyPlugin as n, fiscalLockPlugin as r, dateLockPlugin as t };
@@ -1,5 +1,5 @@
1
- import { t as CountryPack } from "./index-ZnSiqHYV.mjs";
2
- import { t as Logger } from "./logger-UbTdBb1x.mjs";
1
+ import { t as CountryPack } from "./index-CxZqRaOU.mjs";
2
+ import { t as Logger } from "./logger-CbHWZl7v.mjs";
3
3
 
4
4
  //#region src/types/engine.d.ts
5
5
  /** Multi-tenant configuration */
@@ -80,9 +80,14 @@ interface AccountingEngineConfig {
80
80
  multiCurrency?: MultiCurrencyConfig;
81
81
  /** Fiscal year start month (1-12, default: 1 = January) */
82
82
  fiscalYearStartMonth?: number;
83
- /** Display code for prior retained earnings on balance sheet (default: '3660') */
84
- retainedEarningsCode?: string;
85
- /** Display code for current year net income on balance sheet (default: '3680') */
83
+ /**
84
+ * The retained earnings account code (e.g. '3600' CA, '3310' BD).
85
+ * Overrides the country pack value. See CountryPack.retainedEarningsAccountCode.
86
+ */
87
+ retainedEarningsAccountCode?: string;
88
+ /** Display code for the "Previous Years Retained Earnings" line. Overrides country pack. */
89
+ retainedEarningsDisplayCode?: string;
90
+ /** Display code for current year net income line. Overrides country pack. */
86
91
  currentYearEarningsCode?: string;
87
92
  /** Logger instance. Defaults to console-based logger. */
88
93
  logger?: Logger;
@@ -94,5 +99,4 @@ interface AccountingEngineConfig {
94
99
  strictness?: StrictnessConfig;
95
100
  }
96
101
  //#endregion
97
- export { MultiTenantConfig as a, MultiCurrencyConfig as i, AuditConfig as n, SchemaOptions as o, JournalSchemaOptions as r, StrictnessConfig as s, AccountingEngineConfig as t };
98
- //# sourceMappingURL=engine-BzBMpWuy.d.mts.map
102
+ export { MultiTenantConfig as a, MultiCurrencyConfig as i, AuditConfig as n, SchemaOptions as o, JournalSchemaOptions as r, StrictnessConfig as s, AccountingEngineConfig as t };
@@ -24,5 +24,3 @@ const Errors = {
24
24
  };
25
25
  //#endregion
26
26
  export { Errors as n, AccountingError as t };
27
-
28
- //# sourceMappingURL=errors-B7yC-Jfw.mjs.map
@@ -248,5 +248,3 @@ const universalFieldMap = {
248
248
  };
249
249
  //#endregion
250
250
  export { exportToCsv as a, getHeaders as c, serializeCsv as d, flattenJournalEntry as i, buildCsv as l, quickbooksFieldMap as n, extractAllRows as o, flattenJournalEntries as r, extractRow as s, universalFieldMap as t, escapeCell as u };
251
-
252
- //# sourceMappingURL=exports-I5Xkq-9_.mjs.map