@classytic/ledger 0.10.2 → 0.11.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 (31) hide show
  1. package/dist/bridges/index.d.mts +1 -1
  2. package/dist/constants/index.d.mts +1 -1
  3. package/dist/constants/index.mjs +2 -2
  4. package/dist/{core-DwjkrRkJ.d.mts → core-B7uVjqGS.d.mts} +25 -0
  5. package/dist/country/index.d.mts +1 -1
  6. package/dist/events/index.d.mts +1 -1
  7. package/dist/exports/index.d.mts +1 -1
  8. package/dist/exports/index.mjs +1 -1
  9. package/dist/{fx-realization.plugin-Dzqzi3u0.mjs → fx-realization.plugin-DY3pPxIi.mjs} +70 -1
  10. package/dist/{index-ClLwzNRF.d.mts → index-BFPFihTF.d.mts} +8 -0
  11. package/dist/{index-08IpHhrU.d.mts → index-Dd7HknPP.d.mts} +1 -1
  12. package/dist/index.d.mts +120 -24
  13. package/dist/index.mjs +375 -165
  14. package/dist/{journals-DUpWwFt1.d.mts → journals-CTrAuzdk.d.mts} +1 -1
  15. package/dist/{partner-ledger-CR0geilx.mjs → partner-ledger-B0eym6Ss.mjs} +951 -213
  16. package/dist/plugins/index.d.mts +1 -1
  17. package/dist/plugins/index.mjs +1 -1
  18. package/dist/reports/index.d.mts +2 -2
  19. package/dist/reports/index.mjs +2 -2
  20. package/dist/{trial-balance-DyNm5bFu.d.mts → trial-balance-UXV2PN6x.d.mts} +280 -75
  21. package/package.json +8 -20
  22. package/dist/opening-balance-1cixYh6Y.mjs +0 -60
  23. package/dist/sync/index.d.mts +0 -324
  24. package/dist/sync/index.mjs +0 -530
  25. package/dist/sync-JvchM3FO.d.mts +0 -152
  26. /package/dist/{categories-FJlrvzcl.mjs → categories-CclX7Q94.mjs} +0 -0
  27. /package/dist/{currencies-Jo5oaM_4.mjs → currencies-OuPHPyS2.mjs} +0 -0
  28. /package/dist/{exports-C30yRapf.mjs → exports-B3whucXe.mjs} +0 -0
  29. /package/dist/{index-Bl0gP9lD.d.mts → index-DygMrab0.d.mts} +0 -0
  30. /package/dist/{index-J-XIbXH-.d.mts → index-pRW5cZhF.d.mts} +0 -0
  31. /package/dist/{outbox-store-BcCiHMPw.d.mts → outbox-store-CPLeocPg.d.mts} +0 -0
@@ -1,324 +0,0 @@
1
- import { a as ImportMapper, c as JournalItemInput, i as ImportError, l as WireExportArgs, n as ExportSink, o as ImportReport, r as ImportContext, s as JournalEntryInput, t as ExportReport, u as WireImportArgs } from "../sync-JvchM3FO.mjs";
2
- import { CanonicalInvoice, CanonicalJournalEntry, CanonicalTransaction } from "@classytic/fin-io";
3
-
4
- //#region src/sync/builders/opening-balance.d.ts
5
- interface OpeningBalanceInput {
6
- /** Cutover date — typically the start of fiscal year.
7
- * The opening balance entry is dated on this day. */
8
- cutoverDate: Date;
9
- /**
10
- * Account balances in integer cents (minor units), signed:
11
- * - Positive = normal debit balance (assets, expenses)
12
- * - Negative = normal credit balance (liabilities, equity, revenue)
13
- *
14
- * Callers should include balance sheet accounts only (assets, liabilities,
15
- * equity). P&L cumulative effect belongs in retained earnings (the equity
16
- * contra account) — this matches the Odoo and Beancount convention.
17
- *
18
- * The `accountCode` is opaque at this layer — it can be a GIFI code, a
19
- * custom account number, or an ObjectId string. The consumer resolves it.
20
- */
21
- balances: ReadonlyArray<{
22
- accountCode: string; /** Signed balance in integer cents. */
23
- balance: number;
24
- }>;
25
- /**
26
- * The equity account that absorbs the difference. Typically:
27
- * - CA: '3600' (Retained Earnings)
28
- * - BD: '3310' (Retained Earnings)
29
- * - Generic: 'Opening Balance Equity'
30
- *
31
- * This follows Odoo's pattern (unaffected earnings) rather than ERPNext's
32
- * temporary account, because the retained earnings approach is
33
- * audit-clean and doesn't require a zeroing-out step.
34
- */
35
- equityAccountCode: string;
36
- /** Optional label. Defaults to 'Opening Balance — Cutover YYYY-MM-DD'. */
37
- label?: string;
38
- }
39
- interface OpeningBalanceResult {
40
- /** The journal entry input, ready for `journalEntries.create()`. */
41
- entry: JournalEntryInput;
42
- /** The net residual posted to the equity account.
43
- * Should be zero for a balanced trial balance.
44
- * Non-zero means the TB was unbalanced — the equity account absorbs it. */
45
- residual: number;
46
- /** Number of account lines (excluding the equity contra line). */
47
- lineCount: number;
48
- }
49
- declare function buildOpeningBalanceEntry(input: OpeningBalanceInput): OpeningBalanceResult;
50
- //#endregion
51
- //#region src/sync/ledger-bridge.d.ts
52
- /**
53
- * createLedgerBridge — adapter between @classytic/invoice's LedgerBridge
54
- * contract and @classytic/ledger's Record API.
55
- *
56
- * This is the glue layer that lets the invoice engine post journal entries,
57
- * record payments, and reverse entries through the ledger engine without
58
- * either package depending on the other.
59
- *
60
- * @example
61
- * ```typescript
62
- * import { createAccountingEngine } from '@classytic/ledger';
63
- * import { createLedgerBridge } from '@classytic/ledger/sync';
64
- * import { createInvoiceEngine } from '@classytic/invoice';
65
- *
66
- * const accounting = createAccountingEngine({ ... });
67
- *
68
- * const invoicing = createInvoiceEngine({
69
- * ledger: createLedgerBridge(accounting, {
70
- * accounts: {
71
- * receivable: '1200', // Accounts Receivable
72
- * payable: '2000', // Accounts Payable
73
- * revenue: '4000', // Revenue
74
- * expense: '5000', // Cost of Goods / Expenses
75
- * taxPayable: '2100', // Tax Payable (sales tax collected)
76
- * taxReceivable: '1150', // Tax Receivable (purchase tax paid)
77
- * cash: '1000', // Cash / Bank
78
- * },
79
- * }),
80
- * });
81
- * ```
82
- *
83
- * The bridge maps each invoice moveType to the correct accounting entries:
84
- *
85
- * out_invoice → DR Receivable, CR Revenue per line, CR Tax Payable
86
- * in_invoice → DR Expense per line, DR Tax Receivable, CR Payable
87
- * out_refund → CR Receivable, DR Revenue per line, DR Tax Payable
88
- * in_refund → DR Payable, CR Expense per line, CR Tax Receivable
89
- * receipt → DR Cash/Receivable, CR Revenue per line, CR Tax Payable
90
- *
91
- * All amounts are integer cents. The bridge uses `record.adjustment()` for
92
- * multi-line entries (invoices with tax) and `record.payment()` for payment
93
- * recording.
94
- */
95
- /** Account code mapping — tells the bridge which ledger accounts to use. */
96
- interface LedgerBridgeAccounts {
97
- /** Accounts Receivable (e.g. '1200'). Used for customer invoices + receipts. */
98
- receivable: string;
99
- /** Accounts Payable (e.g. '2000'). Used for vendor bills. */
100
- payable: string;
101
- /** Default revenue account (e.g. '4000'). Used for sales line items. */
102
- revenue: string;
103
- /** Default expense account (e.g. '5000'). Used for purchase line items. */
104
- expense: string;
105
- /** Tax payable / tax liability (e.g. '2100'). Sales tax collected. */
106
- taxPayable: string;
107
- /** Tax receivable / input tax (e.g. '1150'). Purchase tax paid. */
108
- taxReceivable: string;
109
- /** Cash / bank account (e.g. '1000'). Used for payments. */
110
- cash: string;
111
- }
112
- interface LedgerBridgeConfig {
113
- /** Account code mapping. */
114
- accounts: LedgerBridgeAccounts;
115
- /**
116
- * Override the debit account for receipts (POS).
117
- * Defaults to `accounts.receivable`. Set to `accounts.cash` if receipts
118
- * are immediately paid (no AR).
119
- */
120
- receiptAccount?: string;
121
- /**
122
- * Custom resolver for payment accounts. When provided, the bridge calls
123
- * this instead of using the default receivable/cash mapping.
124
- *
125
- * Use this when the invoice engine doesn't track moveType on payments
126
- * and you need to determine AR vs AP based on context.
127
- */
128
- resolvePaymentAccounts?: (input: LedgerPaymentInput) => {
129
- receivableOrPayable: string;
130
- cash: string;
131
- };
132
- }
133
- type MoveType = 'out_invoice' | 'in_invoice' | 'out_refund' | 'in_refund' | 'receipt';
134
- interface LedgerPostInput {
135
- organizationId?: string;
136
- invoiceId: string;
137
- moveType: MoveType;
138
- partnerId: string;
139
- date: Date;
140
- currency: string;
141
- lines: LedgerPostLine[];
142
- totalAmount: number;
143
- taxAmount: number;
144
- notes?: string;
145
- idempotencyKey?: string;
146
- }
147
- interface LedgerPostLine {
148
- description: string;
149
- amount: number;
150
- taxAmount: number;
151
- taxCode?: string;
152
- productId?: string;
153
- }
154
- interface LedgerPaymentInput {
155
- organizationId?: string;
156
- invoiceId: string;
157
- paymentId: string;
158
- amount: number;
159
- currency: string;
160
- date: Date;
161
- method: string;
162
- }
163
- /**
164
- * The LedgerBridge interface that @classytic/invoice expects.
165
- * This is the contract — createLedgerBridge() returns an implementation.
166
- */
167
- interface LedgerBridge {
168
- createJournalEntry(input: LedgerPostInput): Promise<string>;
169
- reverseJournalEntry(journalEntryId: string, reason: string, ctx: LedgerReverseContext): Promise<string>;
170
- recordPayment(input: LedgerPaymentInput): Promise<string>;
171
- }
172
- /**
173
- * Context threaded from the invoice engine into the ledger reversal call.
174
- * Required so the ledger can stamp `reversedByUser` and satisfy strict-mode
175
- * `requireActor` / multi-tenant guards.
176
- */
177
- interface LedgerReverseContext {
178
- organizationId?: string;
179
- actorId?: string;
180
- session?: unknown;
181
- }
182
- interface AdjustmentLine {
183
- account: string;
184
- debit?: number;
185
- credit?: number;
186
- label?: string;
187
- }
188
- interface RecordAPILike {
189
- adjustment(organizationId: unknown, input: {
190
- date: Date;
191
- lines: AdjustmentLine[];
192
- label?: string;
193
- journalType?: string;
194
- }, options?: {
195
- idempotencyKey?: string;
196
- [key: string]: unknown;
197
- }): Promise<unknown>;
198
- payment(organizationId: unknown, input: {
199
- date: Date;
200
- amount: number;
201
- fromReceivableAccount: string;
202
- toCashAccount: string;
203
- label?: string;
204
- }, options?: {
205
- idempotencyKey?: string;
206
- [key: string]: unknown;
207
- }): Promise<unknown>;
208
- }
209
- interface JournalEntryRepoLike {
210
- reverse(id: unknown, orgId?: unknown, options?: {
211
- actorId?: string;
212
- session?: unknown;
213
- reversalDate?: Date;
214
- }): Promise<{
215
- original: {
216
- _id: unknown;
217
- };
218
- reversal: {
219
- _id: unknown;
220
- };
221
- }>;
222
- }
223
- interface EngineLike {
224
- record: RecordAPILike;
225
- repositories: {
226
- journalEntries: JournalEntryRepoLike;
227
- };
228
- }
229
- /**
230
- * Create a LedgerBridge implementation backed by a @classytic/ledger engine.
231
- *
232
- * @param engine - The accounting engine (or any object matching the minimal
233
- * shape: `{ record: { adjustment, payment }, repositories: { journalEntries: { reverse } } }`)
234
- * @param config - Account mapping configuration
235
- * @returns A LedgerBridge that the invoice engine can use
236
- */
237
- declare function createLedgerBridge(engine: EngineLike, config: LedgerBridgeConfig): LedgerBridge;
238
- //#endregion
239
- //#region src/sync/mappers/bank-statement.d.ts
240
- interface BankStatementMapperConfig {
241
- /** ObjectId of the bank/cash account (debit side for inflows, credit side for outflows). */
242
- bankAccountId: unknown;
243
- /** ObjectId of the suspense/unclassified account (the other side). */
244
- suspenseAccountId: unknown;
245
- /**
246
- * Optional categorization callback. Given a CanonicalTransaction, return
247
- * the ObjectId of a more specific counter-account (e.g. rent, utilities,
248
- * payroll). If returns undefined, suspenseAccountId is used.
249
- *
250
- * This is where AI categorization or a rules engine plugs in.
251
- */
252
- categorize?: (txn: CanonicalTransaction) => unknown | undefined;
253
- /** Label prefix for imported entries. Default: 'Import'. */
254
- labelPrefix?: string;
255
- }
256
- declare function bankStatementMapper(config: BankStatementMapperConfig): ImportMapper<CanonicalTransaction>;
257
- //#endregion
258
- //#region src/sync/mappers/invoice.d.ts
259
- interface InvoiceMapperConfig {
260
- /** ObjectId for Accounts Receivable (sales) or Accounts Payable (purchase). */
261
- receivablesAccountId: unknown;
262
- payablesAccountId: unknown;
263
- /** Default revenue account (used when invoice line has no accountCode). */
264
- defaultRevenueAccountId: unknown;
265
- /** Default expense account. */
266
- defaultExpenseAccountId: unknown;
267
- /** Tax liability account (for sales tax collected). */
268
- taxLiabilityAccountId?: unknown;
269
- /** Tax receivable account (for purchase tax paid). */
270
- taxReceivableAccountId?: unknown;
271
- /** Map accountCode from the source to a ledger Account ObjectId. */
272
- resolveAccountCode?: (code: string) => unknown | undefined;
273
- }
274
- declare function invoiceMapper(config: InvoiceMapperConfig): ImportMapper<CanonicalInvoice>;
275
- //#endregion
276
- //#region src/sync/mappers/journal-entry.d.ts
277
- interface JournalEntryMapperConfig {
278
- /** Map accountCode from the source to a ledger Account ObjectId. */
279
- resolveAccountCode: (code: string) => unknown;
280
- }
281
- declare function journalEntryMapper(config: JournalEntryMapperConfig): ImportMapper<CanonicalJournalEntry>;
282
- //#endregion
283
- //#region src/sync/mappers/opening-balance.d.ts
284
- /** Minimal trial balance shape — matches CanonicalTrialBalance from fin-io
285
- * but defined locally to avoid a hard dependency on fin-io. Any object
286
- * matching this shape works. */
287
- interface TrialBalanceInput {
288
- asOfDate: Date;
289
- currency: string;
290
- lines: ReadonlyArray<{
291
- accountCode: string;
292
- accountName: string;
293
- debit?: {
294
- amount: bigint;
295
- currency: string;
296
- };
297
- credit?: {
298
- amount: bigint;
299
- currency: string;
300
- };
301
- }>;
302
- }
303
- interface OpeningBalanceMapperConfig {
304
- /** Resolve an account type code to a ledger Account ObjectId (or any ID).
305
- * Return `undefined` to skip an account line. */
306
- resolveAccountCode: (code: string) => unknown | undefined;
307
- /** The ObjectId of the equity/retained earnings account. */
308
- equityAccountId: unknown;
309
- /** Cutover date for the opening balance entry. */
310
- cutoverDate: Date;
311
- }
312
- declare function openingBalanceMapper(config: OpeningBalanceMapperConfig): ImportMapper<TrialBalanceInput>;
313
- //#endregion
314
- //#region src/sync/wire-export.d.ts
315
- declare function wireExport<TOut>(args: WireExportArgs<TOut>): {
316
- run(): Promise<ExportReport>;
317
- };
318
- //#endregion
319
- //#region src/sync/wire-import.d.ts
320
- declare function wireImport<TRaw>(args: WireImportArgs<TRaw>): {
321
- run(): Promise<ImportReport>;
322
- };
323
- //#endregion
324
- export { type BankStatementMapperConfig, type ExportReport, type ExportSink, type ImportContext, type ImportError, type ImportMapper, type ImportReport, type InvoiceMapperConfig, type JournalEntryInput, type JournalEntryMapperConfig, type JournalItemInput, type LedgerBridge, type LedgerBridgeAccounts, type LedgerBridgeConfig, type LedgerPaymentInput, type LedgerPostInput, type LedgerPostLine, type LedgerReverseContext, type OpeningBalanceInput, type OpeningBalanceMapperConfig, type OpeningBalanceResult, type TrialBalanceInput, type WireExportArgs, type WireImportArgs, bankStatementMapper, buildOpeningBalanceEntry, createLedgerBridge, invoiceMapper, journalEntryMapper, openingBalanceMapper, wireExport, wireImport };