@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.
- package/README.md +161 -64
- package/dist/{account.repository-kDKwDt0I.mjs → account.repository-BpkSd6q3.mjs} +189 -38
- package/dist/categories-CclX7Q94.mjs +0 -2
- package/dist/core-8Xfnpn6g.d.mts +1 -2
- package/dist/country/index.d.mts +1 -1
- package/dist/country/index.mjs +0 -2
- package/dist/currencies-4WAbFRlw.d.mts +1 -2
- package/dist/currencies-W8kQAkm0.mjs +0 -2
- package/dist/{idempotency.plugin-v9NQ_ta-.mjs → date-lock.plugin-eYAJ9h_u.mjs} +49 -9
- package/dist/{engine-BzBMpWuy.d.mts → engine-Cn-9yerQ.d.mts} +11 -7
- package/dist/errors-B7yC-Jfw.mjs +0 -2
- package/dist/exports-I5Xkq-9_.mjs +0 -2
- package/dist/{fiscal-close-L631E3De.mjs → fiscal-close-B6LhQ10f.mjs} +737 -20
- package/dist/fiscal-period.schema-BMnlI9H5.d.mts +103 -0
- package/dist/{idempotency.plugin-CPxPt4vX.d.mts → idempotency.plugin-B_CNsInz.d.mts} +19 -17
- package/dist/index-BPukb3L8.d.mts +1 -2
- package/dist/{index-ZnSiqHYV.d.mts → index-CxZqRaOU.d.mts} +20 -6
- package/dist/index.d.mts +248 -26
- package/dist/index.mjs +119 -21
- package/dist/journals-oH-FK3g8.mjs +0 -2
- package/dist/{logger-UbTdBb1x.d.mts → logger-CbHWZl7v.d.mts} +1 -2
- package/dist/money.d.mts +1 -2
- package/dist/money.mjs +3 -3
- package/dist/plugins/index.d.mts +38 -2
- package/dist/plugins/index.mjs +57 -2
- package/dist/reconciliation.repository-CW4-8q90.d.mts +135 -0
- package/dist/{fiscal-period.schema-BQ5wsAq3.mjs → reconciliation.schema-BuetvZTd.mjs} +168 -24
- package/dist/reports/index.d.mts +2 -2
- package/dist/reports/index.mjs +2 -2
- package/dist/repositories/index.d.mts +2 -2
- package/dist/repositories/index.mjs +2 -2
- package/dist/revaluation-D9x0NE8w.d.mts +530 -0
- package/dist/schemas/index.d.mts +71 -2
- package/dist/schemas/index.mjs +2 -2
- package/dist/tenant-guard-Fm6AID_6.mjs +13 -0
- package/docs/reports.md +1 -1
- package/package.json +2 -2
- package/dist/account.repository-C7gwFLfM.d.mts +0 -29
- package/dist/account.repository-C7gwFLfM.d.mts.map +0 -1
- package/dist/account.repository-kDKwDt0I.mjs.map +0 -1
- package/dist/categories-CclX7Q94.mjs.map +0 -1
- package/dist/core-8Xfnpn6g.d.mts.map +0 -1
- package/dist/country/index.mjs.map +0 -1
- package/dist/currencies-4WAbFRlw.d.mts.map +0 -1
- package/dist/currencies-W8kQAkm0.mjs.map +0 -1
- package/dist/engine-BzBMpWuy.d.mts.map +0 -1
- package/dist/errors-B7yC-Jfw.mjs.map +0 -1
- package/dist/exports-I5Xkq-9_.mjs.map +0 -1
- package/dist/fiscal-close-L631E3De.mjs.map +0 -1
- package/dist/fiscal-close-dNlzB37y.d.mts +0 -270
- package/dist/fiscal-close-dNlzB37y.d.mts.map +0 -1
- package/dist/fiscal-period.schema-BQ5wsAq3.mjs.map +0 -1
- package/dist/fiscal-period.schema-BRdKAjrr.d.mts +0 -38
- package/dist/fiscal-period.schema-BRdKAjrr.d.mts.map +0 -1
- package/dist/idempotency.plugin-CPxPt4vX.d.mts.map +0 -1
- package/dist/idempotency.plugin-v9NQ_ta-.mjs.map +0 -1
- package/dist/index-BPukb3L8.d.mts.map +0 -1
- package/dist/index-ZnSiqHYV.d.mts.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/journals-oH-FK3g8.mjs.map +0 -1
- package/dist/logger-UbTdBb1x.d.mts.map +0 -1
- package/dist/money.d.mts.map +0 -1
- package/dist/money.mjs.map +0 -1
- package/dist/session-Ba8E3Ufa.mjs +0 -84
- package/dist/session-Ba8E3Ufa.mjs.map +0 -1
|
@@ -70,9 +70,8 @@ function createAccountSchema(config, options = {}) {
|
|
|
70
70
|
};
|
|
71
71
|
const schema = new mongoose.Schema(fields, { timestamps: true });
|
|
72
72
|
schema.pre("validate", function() {
|
|
73
|
-
|
|
74
|
-
if (!
|
|
75
|
-
if (!doc.name && doc.accountTypeCode) doc.name = country.getAccountType(doc.accountTypeCode)?.name ?? doc.accountTypeCode;
|
|
73
|
+
if (!this.accountNumber && this.accountTypeCode) this.accountNumber = this.accountTypeCode;
|
|
74
|
+
if (!this.name && this.accountTypeCode) this.name = country.getAccountType(this.accountTypeCode)?.name ?? this.accountTypeCode;
|
|
76
75
|
});
|
|
77
76
|
if (indexes) if (multiTenant) {
|
|
78
77
|
const org = multiTenant.orgField;
|
|
@@ -275,22 +274,21 @@ function createJournalEntrySchema(config, accountModelName, options = {}) {
|
|
|
275
274
|
};
|
|
276
275
|
const schema = new mongoose.Schema(fields, { timestamps: true });
|
|
277
276
|
schema.pre("validate", function() {
|
|
278
|
-
const
|
|
279
|
-
for (
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
const c = doc.journalItems[i].credit || 0;
|
|
277
|
+
for (const item of this.journalItems) if (!item.date) item.date = this.date;
|
|
278
|
+
for (let i = 0; i < this.journalItems.length; i++) {
|
|
279
|
+
const d = this.journalItems[i].debit ?? 0;
|
|
280
|
+
const c = this.journalItems[i].credit ?? 0;
|
|
283
281
|
if (d > 0 && c > 0) throw new Error(`Journal item at index ${i}: cannot have both debit (${d}) and credit (${c}) greater than zero`);
|
|
284
|
-
if (
|
|
282
|
+
if (this.state === "posted" && d === 0 && c === 0) throw new Error(`Journal item at index ${i}: posted entries cannot have zero-value lines (both debit and credit are 0)`);
|
|
285
283
|
}
|
|
286
|
-
const totalDebit =
|
|
287
|
-
const totalCredit =
|
|
288
|
-
if (
|
|
289
|
-
if (
|
|
284
|
+
const totalDebit = this.journalItems.reduce((s, item) => s + (item.debit ?? 0), 0);
|
|
285
|
+
const totalCredit = this.journalItems.reduce((s, item) => s + (item.credit ?? 0), 0);
|
|
286
|
+
if (this.state === "posted") {
|
|
287
|
+
if (this.journalItems.length < 2) throw new Error("Posted entries must have at least 2 journal items");
|
|
290
288
|
if (totalDebit !== totalCredit) throw new Error("Total debit must equal total credit for posted entries");
|
|
291
289
|
}
|
|
292
|
-
|
|
293
|
-
|
|
290
|
+
this.totalDebit = totalDebit;
|
|
291
|
+
this.totalCredit = totalCredit;
|
|
294
292
|
});
|
|
295
293
|
if (autoReference) {
|
|
296
294
|
const generateReferenceNumber = async (doc, Model, session) => {
|
|
@@ -312,12 +310,11 @@ function createJournalEntrySchema(config, accountModelName, options = {}) {
|
|
|
312
310
|
return `${prefix}${String(seq).padStart(4, "0")}`;
|
|
313
311
|
};
|
|
314
312
|
schema.pre("save", async function() {
|
|
315
|
-
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
doc.referenceNumber = await generateReferenceNumber(doc, Model, session);
|
|
313
|
+
if (this.isModified("journalType")) this.referenceNumber = void 0;
|
|
314
|
+
if (!this.referenceNumber) {
|
|
315
|
+
const session = this.$session?.() ?? null;
|
|
316
|
+
const Model = this.constructor;
|
|
317
|
+
this.referenceNumber = await generateReferenceNumber(this, Model, session);
|
|
321
318
|
}
|
|
322
319
|
});
|
|
323
320
|
const MAX_REF_RETRIES = 3;
|
|
@@ -516,6 +513,153 @@ function createFiscalPeriodSchema(config, options = {}) {
|
|
|
516
513
|
return schema;
|
|
517
514
|
}
|
|
518
515
|
//#endregion
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
516
|
+
//#region src/schemas/budget.schema.ts
|
|
517
|
+
/**
|
|
518
|
+
* Budget Schema Factory
|
|
519
|
+
*
|
|
520
|
+
* Creates a Mongoose schema for budget records.
|
|
521
|
+
* Each record represents a budgeted amount for an account over a specific period.
|
|
522
|
+
* All monetary amounts are in integer cents.
|
|
523
|
+
*/
|
|
524
|
+
function createBudgetSchema(config, options = {}) {
|
|
525
|
+
const { multiTenant } = config;
|
|
526
|
+
const { indexes = true, extraFields = {}, extraIndexes = [] } = options;
|
|
527
|
+
const fields = {
|
|
528
|
+
account: {
|
|
529
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
530
|
+
ref: "Account",
|
|
531
|
+
required: true
|
|
532
|
+
},
|
|
533
|
+
periodStart: {
|
|
534
|
+
type: Date,
|
|
535
|
+
required: true
|
|
536
|
+
},
|
|
537
|
+
periodEnd: {
|
|
538
|
+
type: Date,
|
|
539
|
+
required: true
|
|
540
|
+
},
|
|
541
|
+
amount: {
|
|
542
|
+
type: Number,
|
|
543
|
+
required: true,
|
|
544
|
+
validate: {
|
|
545
|
+
validator: (v) => Number.isInteger(v),
|
|
546
|
+
message: "amount must be an integer (cents)."
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
label: {
|
|
550
|
+
type: String,
|
|
551
|
+
default: null
|
|
552
|
+
},
|
|
553
|
+
...extraFields
|
|
554
|
+
};
|
|
555
|
+
if (multiTenant) fields[multiTenant.orgField] = {
|
|
556
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
557
|
+
ref: multiTenant.orgRef,
|
|
558
|
+
required: true
|
|
559
|
+
};
|
|
560
|
+
const schema = new mongoose.Schema(fields, { timestamps: true });
|
|
561
|
+
schema.pre("validate", function() {
|
|
562
|
+
const doc = this;
|
|
563
|
+
if (doc.periodStart && doc.periodEnd && doc.periodEnd <= doc.periodStart) doc.invalidate("periodEnd", "periodEnd must be after periodStart.", doc.periodEnd, "periodEnd");
|
|
564
|
+
});
|
|
565
|
+
if (indexes) if (multiTenant) {
|
|
566
|
+
const org = multiTenant.orgField;
|
|
567
|
+
schema.index({
|
|
568
|
+
[org]: 1,
|
|
569
|
+
account: 1,
|
|
570
|
+
periodStart: 1,
|
|
571
|
+
periodEnd: 1
|
|
572
|
+
}, { unique: true });
|
|
573
|
+
schema.index({
|
|
574
|
+
[org]: 1,
|
|
575
|
+
periodStart: 1,
|
|
576
|
+
periodEnd: 1
|
|
577
|
+
});
|
|
578
|
+
} else {
|
|
579
|
+
schema.index({
|
|
580
|
+
account: 1,
|
|
581
|
+
periodStart: 1,
|
|
582
|
+
periodEnd: 1
|
|
583
|
+
}, { unique: true });
|
|
584
|
+
schema.index({
|
|
585
|
+
periodStart: 1,
|
|
586
|
+
periodEnd: 1
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
for (const idx of extraIndexes) schema.index(idx.fields, idx.options);
|
|
590
|
+
return schema;
|
|
591
|
+
}
|
|
592
|
+
//#endregion
|
|
593
|
+
//#region src/schemas/reconciliation.schema.ts
|
|
594
|
+
/**
|
|
595
|
+
* Reconciliation Schema Factory
|
|
596
|
+
*
|
|
597
|
+
* Creates a Mongoose schema for reconciliation records that link matched
|
|
598
|
+
* debit/credit journal items. Used to track which journal entries have been
|
|
599
|
+
* reconciled against each other for a given account.
|
|
600
|
+
*/
|
|
601
|
+
function createReconciliationSchema(config, accountModelName, journalEntryModelName, options = {}) {
|
|
602
|
+
const { multiTenant } = config;
|
|
603
|
+
const { indexes = true, extraFields = {}, extraIndexes = [] } = options;
|
|
604
|
+
const fields = {
|
|
605
|
+
account: {
|
|
606
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
607
|
+
ref: accountModelName,
|
|
608
|
+
required: true
|
|
609
|
+
},
|
|
610
|
+
journalEntryIds: {
|
|
611
|
+
type: [{
|
|
612
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
613
|
+
ref: journalEntryModelName
|
|
614
|
+
}],
|
|
615
|
+
required: true,
|
|
616
|
+
validate: {
|
|
617
|
+
validator: (v) => Array.isArray(v) && v.length > 0,
|
|
618
|
+
message: "journalEntryIds must contain at least one entry."
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
debitTotal: {
|
|
622
|
+
type: Number,
|
|
623
|
+
required: true
|
|
624
|
+
},
|
|
625
|
+
creditTotal: {
|
|
626
|
+
type: Number,
|
|
627
|
+
required: true
|
|
628
|
+
},
|
|
629
|
+
difference: {
|
|
630
|
+
type: Number,
|
|
631
|
+
default: 0
|
|
632
|
+
},
|
|
633
|
+
note: { type: String },
|
|
634
|
+
reconciledBy: { type: String },
|
|
635
|
+
reconciledAt: {
|
|
636
|
+
type: Date,
|
|
637
|
+
default: Date.now
|
|
638
|
+
},
|
|
639
|
+
...extraFields
|
|
640
|
+
};
|
|
641
|
+
if (multiTenant) fields[multiTenant.orgField] = {
|
|
642
|
+
type: mongoose.Schema.Types.ObjectId,
|
|
643
|
+
ref: multiTenant.orgRef,
|
|
644
|
+
required: true
|
|
645
|
+
};
|
|
646
|
+
const schema = new mongoose.Schema(fields, { timestamps: true });
|
|
647
|
+
if (indexes) {
|
|
648
|
+
if (multiTenant) {
|
|
649
|
+
const org = multiTenant.orgField;
|
|
650
|
+
schema.index({
|
|
651
|
+
[org]: 1,
|
|
652
|
+
account: 1,
|
|
653
|
+
reconciledAt: 1
|
|
654
|
+
});
|
|
655
|
+
} else schema.index({
|
|
656
|
+
account: 1,
|
|
657
|
+
reconciledAt: 1
|
|
658
|
+
});
|
|
659
|
+
schema.index({ journalEntryIds: 1 });
|
|
660
|
+
}
|
|
661
|
+
for (const idx of extraIndexes) schema.index(idx.fields, idx.options);
|
|
662
|
+
return schema;
|
|
663
|
+
}
|
|
664
|
+
//#endregion
|
|
665
|
+
export { createAccountSchema as a, createJournalEntrySchema as i, createBudgetSchema as n, createFiscalPeriodSchema as r, createReconciliationSchema as t };
|
package/dist/reports/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { type BalanceSheetOptions, type CashFlowOptions, type FiscalCloseOptions, type FiscalCloseResult, type FiscalReopenResult, type GeneralLedgerOptions, type IncomeStatementOptions, type TrialBalanceOptions, closeFiscalPeriod, generateBalanceSheet, generateCashFlow, generateGeneralLedger, generateIncomeStatement, generateTrialBalance, reopenFiscalPeriod };
|
|
1
|
+
import { $ as BudgetVsActualReport, A as generateGeneralLedger, C as FiscalCloseResult, D as CashFlowOptions, E as reopenFiscalPeriod, F as TrialBalanceOptions, I as generateTrialBalance, M as generateIncomeStatement, N as BalanceSheetOptions, O as generateCashFlow, P as generateBalanceSheet, Q as BudgetVsActualParams, S as FiscalCloseOptions, T as closeFiscalPeriod, Z as BudgetVsActualOptions, _ as DimensionBreakdownOptions, b as DimensionBreakdownRow, d as AgedBalanceParams, et as BudgetVsActualRow, f as AgedBalanceReport, g as generateAgedBalance, h as DEFAULT_BUCKETS, i as generateRevaluation, j as IncomeStatementOptions, k as GeneralLedgerOptions, m as AgedBucketConfig, n as RevaluationParams, p as AgedBalanceRow, r as RevaluationReport, t as RevaluationOptions, tt as generateBudgetVsActual, u as AgedBalanceOptions, v as DimensionBreakdownParams, w as FiscalReopenResult, x as generateDimensionBreakdown, y as DimensionBreakdownReport } from "../revaluation-D9x0NE8w.mjs";
|
|
2
|
+
export { type AgedBalanceOptions, type AgedBalanceParams, type AgedBalanceReport, type AgedBalanceRow, type AgedBucketConfig, type BalanceSheetOptions, type BudgetVsActualOptions, type BudgetVsActualParams, type BudgetVsActualReport, type BudgetVsActualRow, type CashFlowOptions, DEFAULT_BUCKETS, type DimensionBreakdownOptions, type DimensionBreakdownParams, type DimensionBreakdownReport, type DimensionBreakdownRow, type FiscalCloseOptions, type FiscalCloseResult, type FiscalReopenResult, type GeneralLedgerOptions, type IncomeStatementOptions, type RevaluationOptions, type RevaluationParams, type RevaluationReport, type TrialBalanceOptions, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
package/dist/reports/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { closeFiscalPeriod, generateBalanceSheet, generateCashFlow, generateGeneralLedger, generateIncomeStatement, generateTrialBalance, reopenFiscalPeriod };
|
|
1
|
+
import { d as DEFAULT_BUCKETS, f as generateAgedBalance, g as generateBalanceSheet, h as generateIncomeStatement, l as generateBudgetVsActual, m as generateGeneralLedger, n as reopenFiscalPeriod, o as generateRevaluation, p as generateCashFlow, t as closeFiscalPeriod, u as generateDimensionBreakdown, x as generateTrialBalance } from "../fiscal-close-B6LhQ10f.mjs";
|
|
2
|
+
export { DEFAULT_BUCKETS, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as wireJournalEntryMethods, t as
|
|
2
|
-
export { wireAccountMethods, wireJournalEntryMethods };
|
|
1
|
+
import { n as wireAccountMethods, r as wireJournalEntryMethods, t as wireReconciliationMethods } from "../reconciliation.repository-CW4-8q90.mjs";
|
|
2
|
+
export { wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as wireJournalEntryMethods, t as wireAccountMethods } from "../account.repository-
|
|
2
|
-
export { wireAccountMethods, wireJournalEntryMethods };
|
|
1
|
+
import { n as wireJournalEntryMethods, r as wireReconciliationMethods, t as wireAccountMethods } from "../account.repository-BpkSd6q3.mjs";
|
|
2
|
+
export { wireAccountMethods, wireJournalEntryMethods, wireReconciliationMethods };
|