@classytic/ledger 0.10.1 → 0.10.3
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/dist/index.d.mts +39 -6
- package/dist/index.mjs +39 -12
- package/dist/{partner-ledger-CR0geilx.mjs → partner-ledger-BIkmQsAc.mjs} +83 -1
- package/dist/reports/index.d.mts +2 -2
- package/dist/reports/index.mjs +2 -2
- package/dist/{trial-balance-DyNm5bFu.d.mts → trial-balance-DCG5lOoC.d.mts} +66 -1
- package/package.json +7 -4
package/dist/index.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ import { i as defineCountryPack, n as CountryPackInput, r as JournalTemplate, t
|
|
|
5
5
|
import { $ as ReconciliationUnmatchedPayload, A as LedgerEventDefinition, B as InProcessLedgerBusOptions, E as EntryUnposted, F as ReconciliationUnmatched, G as EntryArchivedPayload, H as createEvent, J as EntryPostedPayload, K as EntryCreatedPayload, L as ledgerEventDefinitions, M as LedgerEventSchema, N as ReconciliationMatched, O as JournalSeeded, Q as ReconciliationMatchedPayload, R as EventLogger, S as EntryPosted, U as AccountBulkCreatedPayload, V as EventContext, W as AccountSeededPayload, X as EntryUnpostedPayload, Y as EntryReversedPayload, Z as JournalSeededPayload, a as OutboxFailOptions, b as EntryDuplicated, c as OutboxFailurePolicy, d as OutboxWriteOptions, et as LEDGER_EVENTS, f as AccountBulkCreated, g as EntryArchived, i as OutboxErrorInfo, j as LedgerEventPayloadOf, l as OutboxOwnershipError, m as AccountSeeded, n as OutboxAcknowledgeOptions, o as OutboxFailureContext, q as EntryDuplicatedPayload, r as OutboxClaimOptions, s as OutboxFailureDecision, t as InvalidOutboxEventError, tt as LedgerEventName, u as OutboxStore, v as EntryCreated, w as EntryReversed, z as InProcessLedgerBus } from "./outbox-store-BcCiHMPw.mjs";
|
|
6
6
|
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";
|
|
7
7
|
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";
|
|
8
|
-
import { $ as AgedBalanceParams, A as generateDimensionBreakdown, B as BalanceSheetReport, D as DimensionBreakdownParams, E as DimensionBreakdownOptions, F as BudgetVsActualReport, G as IncomeStatementReport, H as CashFlowSection, I as BudgetVsActualRow, J as ReportCategory, K as LedgerEntry, L as generateBudgetVsActual, M as generateCashFlow, N as BudgetVsActualOptions, O as DimensionBreakdownReport, P as BudgetVsActualParams, Q as AgedBalanceOptions, T as reopenFiscalPeriod, U as GeneralLedgerAccount, V as CashFlowReport, W as GeneralLedgerReport, X as TrialBalanceReport, Y as ReportGroup, Z as TrialBalanceRow, a as RevaluationReport, at as Logger, b as generateGeneralLedger, c as RevaluationRate, d as computeRevaluation, et as AgedBalanceReport, f as PartnerLedgerLine, g as generatePartnerLedger, h as PartnerLedgerReport, i as RevaluationParams, it as generateAgedBalance, k as DimensionBreakdownRow, l as RevaluationResult, m as PartnerLedgerParams, n as generateTrialBalance, nt as AgedBucketConfig, o as generateRevaluation, ot as defaultLogger, p as PartnerLedgerOptions, q as ReportAccount, r as RevaluationOptions, rt as DEFAULT_BUCKETS, s as AccountForeignBalance, tt as AgedBalanceRow, u as buildRevaluationEntry, v as generateIncomeStatement, w as closeFiscalPeriod, z as generateBalanceSheet } from "./trial-balance-
|
|
8
|
+
import { $ as AgedBalanceParams, A as generateDimensionBreakdown, B as BalanceSheetReport, D as DimensionBreakdownParams, E as DimensionBreakdownOptions, F as BudgetVsActualReport, G as IncomeStatementReport, H as CashFlowSection, I as BudgetVsActualRow, J as ReportCategory, K as LedgerEntry, L as generateBudgetVsActual, M as generateCashFlow, N as BudgetVsActualOptions, O as DimensionBreakdownReport, P as BudgetVsActualParams, Q as AgedBalanceOptions, T as reopenFiscalPeriod, U as GeneralLedgerAccount, V as CashFlowReport, W as GeneralLedgerReport, X as TrialBalanceReport, Y as ReportGroup, Z as TrialBalanceRow, a as RevaluationReport, at as Logger, b as generateGeneralLedger, c as RevaluationRate, d as computeRevaluation, et as AgedBalanceReport, f as PartnerLedgerLine, g as generatePartnerLedger, h as PartnerLedgerReport, i as RevaluationParams, it as generateAgedBalance, k as DimensionBreakdownRow, l as RevaluationResult, lt as DaybookParams, m as PartnerLedgerParams, n as generateTrialBalance, nt as AgedBucketConfig, o as generateRevaluation, ot as defaultLogger, p as PartnerLedgerOptions, q as ReportAccount, r as RevaluationOptions, rt as DEFAULT_BUCKETS, s as AccountForeignBalance, tt as AgedBalanceRow, u as buildRevaluationEntry, ut as DaybookReport, v as generateIncomeStatement, w as closeFiscalPeriod, z as generateBalanceSheet } from "./trial-balance-DCG5lOoC.mjs";
|
|
9
9
|
import { A as OpenItem, C as AccountRepository, D as JournalItemRef, E as JournalEntryRepository, F as SeedOptions, I as SeedResult, M as ReconciliationRepository, N as ReverseOptions, O as JournalRepository, P as ReverseResult, S as creditLimitPlugin, T as BulkCreateResult, _ as FxRealizationPluginOptions, a as dailyLockPlugin, b as doubleEntryPlugin, c as periodResolver, d as LockAccountSelector, f as LockHit, g as idempotencyPlugin, i as FiscalLockPluginOptions, j as PostOptions, k as MatchInput, l as createLockPlugin, m as LockResolverContext, n as watermarkResolver, o as fiscalLockPlugin, p as LockResolver, r as DailyLockPluginOptions, s as PeriodResolverOptions, t as WatermarkResolverOptions, u as CreateLockPluginOptions, v as fxRealizationPlugin, w as BulkCreateInput, x as CreditLimitPluginOptions } from "./index-ClLwzNRF.mjs";
|
|
10
10
|
import { DomainEvent, EventHandler, EventTransport, EventTransport as EventTransport$1, PublishManyResult } from "@classytic/primitives/events";
|
|
11
11
|
import { PaginationConfig, PluginFunction, PluginType, QueryParser, QueryParserOptions, Repository } from "@classytic/mongokit";
|
|
@@ -280,6 +280,39 @@ interface AccountingEngineConfig {
|
|
|
280
280
|
currency: string;
|
|
281
281
|
/** Multi-tenant configuration. Omit for single-tenant apps. */
|
|
282
282
|
multiTenant?: MultiTenantConfig | undefined;
|
|
283
|
+
/**
|
|
284
|
+
* Field name used to stamp every journal entry with the originating
|
|
285
|
+
* organization / branch — *without* scoping the chart of accounts or any
|
|
286
|
+
* other collection. Use this for single-company-multi-branch deployments
|
|
287
|
+
* where Account / FiscalPeriod stay company-wide but each posting needs a
|
|
288
|
+
* branch attribution for partition-style reports (per-branch P&L, AR aging,
|
|
289
|
+
* partner ledger).
|
|
290
|
+
*
|
|
291
|
+
* When `multiTenant` is set, that takes precedence — `multiTenant.tenantField`
|
|
292
|
+
* already provides the same stamp and additionally scopes every repository.
|
|
293
|
+
*
|
|
294
|
+
* The host MUST declare the field on the JournalEntry schema via
|
|
295
|
+
* `schemaOptions.journalEntry.extraFields.<field>` (the engine doesn't add
|
|
296
|
+
* the schema path for you — keeps schema mutation explicit).
|
|
297
|
+
*
|
|
298
|
+
* Example:
|
|
299
|
+
*
|
|
300
|
+
* createAccountingEngine({
|
|
301
|
+
* // ...no multiTenant — accounts are company-wide
|
|
302
|
+
* journalEntryOrgField: 'organizationId',
|
|
303
|
+
* schemaOptions: {
|
|
304
|
+
* journalEntry: {
|
|
305
|
+
* extraFields: {
|
|
306
|
+
* organizationId: { type: ObjectId, ref: 'organization', default: null, index: true },
|
|
307
|
+
* },
|
|
308
|
+
* },
|
|
309
|
+
* },
|
|
310
|
+
* });
|
|
311
|
+
*
|
|
312
|
+
* await engine.record.sale(branchId, { ... });
|
|
313
|
+
* // → JE doc: { organizationId: branchId, ... }
|
|
314
|
+
*/
|
|
315
|
+
journalEntryOrgField?: string | undefined;
|
|
283
316
|
/** Multi-currency support. Omit for single-currency apps. */
|
|
284
317
|
multiCurrency?: MultiCurrencyConfig | undefined;
|
|
285
318
|
/** Fiscal year start month (1-12, default: 1 = January) */
|
|
@@ -322,14 +355,13 @@ interface AccountingEngineConfig {
|
|
|
322
355
|
/**
|
|
323
356
|
* Mongoose type for the multi-tenant field on all ledger schemas.
|
|
324
357
|
*
|
|
325
|
-
* - `'
|
|
326
|
-
* Accepts any external auth system (UUIDs, slugs, external identifiers).
|
|
327
|
-
* - `'objectId'`: stores tenant IDs as native MongoDB ObjectId with a
|
|
358
|
+
* - `'objectId'` (default): stores tenant IDs as native MongoDB ObjectId with a
|
|
328
359
|
* Mongoose ref to the organization collection. Enables `$lookup` and
|
|
329
360
|
* `.populate()` against Better Auth's `organization` collection.
|
|
361
|
+
* - `'string'`: stores tenant IDs as strings. Use this for UUID/slug-based
|
|
362
|
+
* auth systems.
|
|
330
363
|
*
|
|
331
|
-
*
|
|
332
|
-
* PACKAGE_RULES §9.1 and §9.2.
|
|
364
|
+
* See PACKAGE_RULES §9.1 and §9.2.
|
|
333
365
|
*
|
|
334
366
|
* Note: this field is plumbed into `multiTenantPlugin` when
|
|
335
367
|
* `multiTenant.plugin: true`. Schema-level type switching is applied
|
|
@@ -780,6 +812,7 @@ declare class AccountingEngine {
|
|
|
780
812
|
businessName?: string;
|
|
781
813
|
filters?: Record<string, unknown>;
|
|
782
814
|
}) => Promise<CashFlowReport>;
|
|
815
|
+
daybook: (params: DaybookParams) => Promise<DaybookReport>;
|
|
783
816
|
agedBalance: (params: {
|
|
784
817
|
organizationId?: unknown;
|
|
785
818
|
asOfDate?: Date;
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { _ as LEDGER_EVENTS, a as EntryArchived, c as EntryPosted, d as JournalS
|
|
|
2
2
|
import { a as IdempotencyConflictError, i as Errors, n as ConcurrencyError, o as ImmutableViolationError, r as DuplicateReferenceError, s as classifyDuplicateKey, t as AccountingError } from "./errors-vXd932rB.mjs";
|
|
3
3
|
import { a as JOURNAL_CODES, c as getCustomJournalTypes, d as isValidJournalType, f as registerJournalType, i as isValidCurrency, l as getJournalType, n as getCurrency, o as JOURNAL_TYPES, r as getMinorUnit, s as _freezeJournalTypes, t as CURRENCIES, u as getJournalTypeCodes } from "./currencies-Jo5oaM_4.mjs";
|
|
4
4
|
import { Money, add, allocate, format, formatPlain, fromDecimal, multiply, parseCents, percentage, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal } from "./money.mjs";
|
|
5
|
-
import { C as
|
|
5
|
+
import { C as computeEndingBalance, D as requireOrgScope, E as generateAgedBalance, S as calculateTotal, T as DEFAULT_BUCKETS, _ as generateBalanceSheet, a as finalizeSession, b as getFiscalYearStart, c as generateRevaluation, d as generateIncomeStatement, f as generateGeneralLedger, g as generateBudgetVsActual, h as generateCashFlow, i as acquireSession, l as buildRevaluationEntry, m as generateDaybook, n as closeFiscalPeriod, o as defaultLogger, p as generateDimensionBreakdown, r as reopenFiscalPeriod, s as generateTrialBalance, t as generatePartnerLedger, u as computeRevaluation, v as buildItemFilters, w as isVirtualTaxAccount, x as buildAccountTypeMap, y as getDateRange } from "./partner-ledger-BIkmQsAc.mjs";
|
|
6
6
|
import { c as getNormalBalance, d as isValidCategory, l as isBalanceSheet, n as CATEGORY_KEYS, t as CATEGORIES, u as isIncomeStatement } from "./categories-FJlrvzcl.mjs";
|
|
7
7
|
import { a as watermarkResolver, c as idempotencyPlugin, i as fiscalLockPlugin, l as doubleEntryPlugin, n as creditLimitPlugin, o as periodResolver, r as dailyLockPlugin, s as createLockPlugin, t as fxRealizationPlugin } from "./fx-realization.plugin-Dzqzi3u0.mjs";
|
|
8
8
|
import { t as buildOpeningBalanceEntry } from "./opening-balance-1cixYh6Y.mjs";
|
|
@@ -153,12 +153,10 @@ function createAccountSchema(config, options = {}) {
|
|
|
153
153
|
},
|
|
154
154
|
accountNumber: {
|
|
155
155
|
type: String,
|
|
156
|
-
required: true,
|
|
157
156
|
trim: true
|
|
158
157
|
},
|
|
159
158
|
name: {
|
|
160
159
|
type: String,
|
|
161
|
-
required: true,
|
|
162
160
|
trim: true
|
|
163
161
|
},
|
|
164
162
|
active: {
|
|
@@ -928,9 +926,28 @@ function isDuplicateKeyBulkError(err) {
|
|
|
928
926
|
function wireAccountMethods(repository, country, orgField, integrations = {}) {
|
|
929
927
|
const events = integrations.events;
|
|
930
928
|
const outboxStore = integrations.outboxStore;
|
|
931
|
-
|
|
929
|
+
const journalEntryModel = integrations.journalEntryModel;
|
|
930
|
+
repository.on("before:create", async (ctx) => {
|
|
932
931
|
const code = ctx.data?.accountTypeCode;
|
|
933
932
|
if (code && !country.isPostingAccount(code)) throw Errors.validation(`Cannot create account with type "${code}" — it is a structural group or calculated total, not a posting account.`);
|
|
933
|
+
const data = ctx.data;
|
|
934
|
+
if (!data) return;
|
|
935
|
+
const accountNumber = data.accountNumber ?? code;
|
|
936
|
+
if (!accountNumber) return;
|
|
937
|
+
const filter = { accountNumber };
|
|
938
|
+
if (orgField) {
|
|
939
|
+
const orgId = data[orgField] ?? ctx.organizationId;
|
|
940
|
+
if (orgId != null) filter[orgField] = orgId;
|
|
941
|
+
}
|
|
942
|
+
if (await repository.getByQuery(filter, {
|
|
943
|
+
throwOnNotFound: false,
|
|
944
|
+
lean: true
|
|
945
|
+
})) throw Errors.validation(`Account number "${accountNumber}" already exists. Provide a custom accountNumber (e.g. "${accountNumber}-NORTH") to create a sub-account.`);
|
|
946
|
+
});
|
|
947
|
+
if (journalEntryModel) repository.on("before:delete", async (ctx) => {
|
|
948
|
+
const id = ctx.id;
|
|
949
|
+
if (id == null) return;
|
|
950
|
+
if (await journalEntryModel.exists({ "journalItems.account": id })) throw Errors.validation(`Cannot delete account ${String(id)} — it is referenced by one or more journal entries. Set active: false to retire it instead.`);
|
|
934
951
|
});
|
|
935
952
|
/**
|
|
936
953
|
* Seed standard posting accounts for an organization.
|
|
@@ -1979,13 +1996,17 @@ function createRepositories(models, config, plugins = {}, pagination = {}, integ
|
|
|
1979
1996
|
const strictness = config.strictness;
|
|
1980
1997
|
const country = config.country;
|
|
1981
1998
|
const { events, bridges, outboxStore } = integrations;
|
|
1999
|
+
const tenantFieldType = config.tenantFieldType ?? "objectId";
|
|
1982
2000
|
const tenantPlugins = [];
|
|
1983
|
-
if (orgField && config.multiTenant?.plugin)
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
2001
|
+
if (orgField && config.multiTenant?.plugin) {
|
|
2002
|
+
const contextKey = config.multiTenant.contextKey ?? "organizationId";
|
|
2003
|
+
tenantPlugins.push(multiTenantPlugin({
|
|
2004
|
+
tenantField: orgField,
|
|
2005
|
+
contextKey,
|
|
2006
|
+
required: config.multiTenant.required ?? false,
|
|
2007
|
+
fieldType: tenantFieldType
|
|
2008
|
+
}));
|
|
2009
|
+
}
|
|
1989
2010
|
const accountPagination = pagination.account ?? {};
|
|
1990
2011
|
const jePagination = pagination.journalEntry ?? {};
|
|
1991
2012
|
const fpPagination = pagination.fiscalPeriod ?? {};
|
|
@@ -1994,7 +2015,8 @@ function createRepositories(models, config, plugins = {}, pagination = {}, integ
|
|
|
1994
2015
|
const accounts = wireAccountMethods(new Repository(models.Account, [...tenantPlugins, ...plugins.account ?? []], accountPagination), country, orgField, {
|
|
1995
2016
|
events,
|
|
1996
2017
|
bridges,
|
|
1997
|
-
outboxStore
|
|
2018
|
+
outboxStore,
|
|
2019
|
+
journalEntryModel: models.JournalEntry
|
|
1998
2020
|
});
|
|
1999
2021
|
const jePlugins = [
|
|
2000
2022
|
...tenantPlugins,
|
|
@@ -2372,6 +2394,7 @@ function buildIntrospectAPI({ models, country, config }) {
|
|
|
2372
2394
|
function buildRecordAPI({ models, repositories, config }) {
|
|
2373
2395
|
const AccountModel = models.Account;
|
|
2374
2396
|
const orgField = config.multiTenant?.tenantField;
|
|
2397
|
+
const journalTagField = orgField ?? config.journalEntryOrgField;
|
|
2375
2398
|
const resolveAccounts = async (organizationId, codes, path, session) => {
|
|
2376
2399
|
const unique = Array.from(new Set(codes));
|
|
2377
2400
|
const filter = { accountTypeCode: { $in: unique } };
|
|
@@ -2400,7 +2423,7 @@ function buildRecordAPI({ models, repositories, config }) {
|
|
|
2400
2423
|
}]);
|
|
2401
2424
|
};
|
|
2402
2425
|
const postEntry = async (organizationId, payload, options) => {
|
|
2403
|
-
if (
|
|
2426
|
+
if (journalTagField && organizationId != null) payload[journalTagField] = organizationId;
|
|
2404
2427
|
const actorId = options?.actorId ?? (options?.user ? options.user._id?.toString() ?? options.user.id?.toString() : void 0);
|
|
2405
2428
|
if (actorId) {
|
|
2406
2429
|
payload.createdBy = actorId;
|
|
@@ -2812,6 +2835,10 @@ var AccountingEngine = class {
|
|
|
2812
2835
|
country,
|
|
2813
2836
|
orgField
|
|
2814
2837
|
}, params),
|
|
2838
|
+
daybook: (params) => generateDaybook({
|
|
2839
|
+
JournalEntryModel,
|
|
2840
|
+
orgField
|
|
2841
|
+
}, params),
|
|
2815
2842
|
agedBalance: (params) => generateAgedBalance({
|
|
2816
2843
|
AccountModel,
|
|
2817
2844
|
JournalEntryModel,
|
|
@@ -723,6 +723,88 @@ async function generateCashFlow(opts, params) {
|
|
|
723
723
|
};
|
|
724
724
|
}
|
|
725
725
|
//#endregion
|
|
726
|
+
//#region src/reports/daybook.ts
|
|
727
|
+
const DEFAULT_LIMIT = 5e3;
|
|
728
|
+
const MAX_LIMIT = 5e4;
|
|
729
|
+
async function generateDaybook(opts, params) {
|
|
730
|
+
const { JournalEntryModel, orgField } = opts;
|
|
731
|
+
const { startDate, endDate, state = "posted", accountId, journalType, partnerId, partnerField = "partnerId" } = params;
|
|
732
|
+
requireOrgScope(orgField, params.organizationId);
|
|
733
|
+
const limit = Math.min(params.limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
734
|
+
const baseMatch = { date: {
|
|
735
|
+
$gte: startDate,
|
|
736
|
+
$lte: endDate
|
|
737
|
+
} };
|
|
738
|
+
if (state !== "all") baseMatch.state = state;
|
|
739
|
+
if (orgField && params.organizationId) baseMatch[orgField] = params.organizationId;
|
|
740
|
+
if (journalType) baseMatch.journalType = journalType;
|
|
741
|
+
const itemMatch = {};
|
|
742
|
+
if (accountId) itemMatch["journalItems.account"] = accountId;
|
|
743
|
+
if (partnerId !== void 0 && partnerId !== null) itemMatch[`journalItems.${partnerField}`] = partnerId;
|
|
744
|
+
const pipeline = [
|
|
745
|
+
{ $match: baseMatch },
|
|
746
|
+
{ $addFields: { journalItems: { $map: {
|
|
747
|
+
input: { $range: [0, { $size: "$journalItems" }] },
|
|
748
|
+
as: "idx",
|
|
749
|
+
in: { $mergeObjects: [{ $arrayElemAt: ["$journalItems", "$$idx"] }, { _itemIndex: "$$idx" }] }
|
|
750
|
+
} } } },
|
|
751
|
+
{ $unwind: "$journalItems" },
|
|
752
|
+
...Object.keys(itemMatch).length > 0 ? [{ $match: itemMatch }] : [],
|
|
753
|
+
{ $project: {
|
|
754
|
+
_id: 0,
|
|
755
|
+
entryId: "$_id",
|
|
756
|
+
itemIndex: "$journalItems._itemIndex",
|
|
757
|
+
date: { $ifNull: ["$journalItems.date", "$date"] },
|
|
758
|
+
referenceNumber: "$referenceNumber",
|
|
759
|
+
journalType: "$journalType",
|
|
760
|
+
entryLabel: "$label",
|
|
761
|
+
itemLabel: "$journalItems.label",
|
|
762
|
+
state: "$state",
|
|
763
|
+
accountId: "$journalItems.account",
|
|
764
|
+
debit: { $ifNull: ["$journalItems.debit", 0] },
|
|
765
|
+
credit: { $ifNull: ["$journalItems.credit", 0] },
|
|
766
|
+
partnerId: `$journalItems.${partnerField}`,
|
|
767
|
+
matchingNumber: "$journalItems.matchingNumber"
|
|
768
|
+
} },
|
|
769
|
+
{ $sort: {
|
|
770
|
+
date: 1,
|
|
771
|
+
entryId: 1,
|
|
772
|
+
itemIndex: 1
|
|
773
|
+
} },
|
|
774
|
+
{ $limit: limit + 1 }
|
|
775
|
+
];
|
|
776
|
+
const rows = await JournalEntryModel.aggregate(pipeline);
|
|
777
|
+
const truncated = rows.length > limit;
|
|
778
|
+
const lines = truncated ? rows.slice(0, limit) : rows;
|
|
779
|
+
let totalDebit = 0;
|
|
780
|
+
let totalCredit = 0;
|
|
781
|
+
for (const r of lines) {
|
|
782
|
+
totalDebit += r.debit ?? 0;
|
|
783
|
+
totalCredit += r.credit ?? 0;
|
|
784
|
+
}
|
|
785
|
+
return {
|
|
786
|
+
metadata: {
|
|
787
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
788
|
+
period: {
|
|
789
|
+
startDate: startDate.toISOString().split("T")[0],
|
|
790
|
+
endDate: endDate.toISOString().split("T")[0]
|
|
791
|
+
},
|
|
792
|
+
state,
|
|
793
|
+
filters: {
|
|
794
|
+
...accountId ? { accountId } : {},
|
|
795
|
+
...journalType ? { journalType } : {},
|
|
796
|
+
...partnerId !== void 0 && partnerId !== null ? { partnerId } : {}
|
|
797
|
+
},
|
|
798
|
+
truncated,
|
|
799
|
+
rowCount: lines.length
|
|
800
|
+
},
|
|
801
|
+
lines,
|
|
802
|
+
totalDebit,
|
|
803
|
+
totalCredit,
|
|
804
|
+
netDelta: totalDebit - totalCredit
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
//#endregion
|
|
726
808
|
//#region src/reports/dimension-breakdown.ts
|
|
727
809
|
async function generateDimensionBreakdown(opts, params) {
|
|
728
810
|
const { AccountModel, JournalEntryModel, country, orgField } = opts;
|
|
@@ -1797,4 +1879,4 @@ async function generatePartnerLedger(opts, params) {
|
|
|
1797
1879
|
};
|
|
1798
1880
|
}
|
|
1799
1881
|
//#endregion
|
|
1800
|
-
export {
|
|
1882
|
+
export { computeEndingBalance as C, requireOrgScope as D, generateAgedBalance as E, calculateTotal as S, DEFAULT_BUCKETS as T, generateBalanceSheet as _, finalizeSession as a, getFiscalYearStart as b, generateRevaluation as c, generateIncomeStatement as d, generateGeneralLedger as f, generateBudgetVsActual as g, generateCashFlow as h, acquireSession as i, buildRevaluationEntry as l, generateDaybook as m, closeFiscalPeriod as n, defaultLogger as o, generateDimensionBreakdown as p, reopenFiscalPeriod as r, generateTrialBalance as s, generatePartnerLedger as t, computeRevaluation as u, buildItemFilters as v, isVirtualTaxAccount as w, buildAccountTypeMap as x, getDateRange as y };
|
package/dist/reports/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as AgedBalanceParams, A as generateDimensionBreakdown, C as FiscalReopenResult, D as DimensionBreakdownParams, E as DimensionBreakdownOptions, F as BudgetVsActualReport, I as BudgetVsActualRow, L as generateBudgetVsActual, M as generateCashFlow, N as BudgetVsActualOptions, O as DimensionBreakdownReport, P as BudgetVsActualParams, Q as AgedBalanceOptions, R as BalanceSheetOptions, S as FiscalCloseResult, T as reopenFiscalPeriod, _ as IncomeStatementOptions, a as RevaluationReport, b as generateGeneralLedger, et as AgedBalanceReport, f as PartnerLedgerLine, g as generatePartnerLedger, h as PartnerLedgerReport, i as RevaluationParams, it as generateAgedBalance, j as CashFlowOptions, k as DimensionBreakdownRow, m as PartnerLedgerParams, n as generateTrialBalance, nt as AgedBucketConfig, o as generateRevaluation, p as PartnerLedgerOptions, r as RevaluationOptions, rt as DEFAULT_BUCKETS, t as TrialBalanceOptions, tt as AgedBalanceRow, v as generateIncomeStatement, w as closeFiscalPeriod, x as FiscalCloseOptions, y as GeneralLedgerOptions, z as generateBalanceSheet } from "../trial-balance-
|
|
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 PartnerLedgerLine, type PartnerLedgerOptions, type PartnerLedgerParams, type PartnerLedgerReport, type RevaluationOptions, type RevaluationParams, type RevaluationReport, type TrialBalanceOptions, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
|
1
|
+
import { $ as AgedBalanceParams, A as generateDimensionBreakdown, C as FiscalReopenResult, D as DimensionBreakdownParams, E as DimensionBreakdownOptions, F as BudgetVsActualReport, I as BudgetVsActualRow, L as generateBudgetVsActual, M as generateCashFlow, N as BudgetVsActualOptions, O as DimensionBreakdownReport, P as BudgetVsActualParams, Q as AgedBalanceOptions, R as BalanceSheetOptions, S as FiscalCloseResult, T as reopenFiscalPeriod, _ as IncomeStatementOptions, a as RevaluationReport, b as generateGeneralLedger, ct as DaybookOptions, dt as generateDaybook, et as AgedBalanceReport, f as PartnerLedgerLine, g as generatePartnerLedger, h as PartnerLedgerReport, i as RevaluationParams, it as generateAgedBalance, j as CashFlowOptions, k as DimensionBreakdownRow, lt as DaybookParams, m as PartnerLedgerParams, n as generateTrialBalance, nt as AgedBucketConfig, o as generateRevaluation, p as PartnerLedgerOptions, r as RevaluationOptions, rt as DEFAULT_BUCKETS, st as DaybookLine, t as TrialBalanceOptions, tt as AgedBalanceRow, ut as DaybookReport, v as generateIncomeStatement, w as closeFiscalPeriod, x as FiscalCloseOptions, y as GeneralLedgerOptions, z as generateBalanceSheet } from "../trial-balance-DCG5lOoC.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 DaybookLine, type DaybookOptions, type DaybookParams, type DaybookReport, type DimensionBreakdownOptions, type DimensionBreakdownParams, type DimensionBreakdownReport, type DimensionBreakdownRow, type FiscalCloseOptions, type FiscalCloseResult, type FiscalReopenResult, type GeneralLedgerOptions, type IncomeStatementOptions, type PartnerLedgerLine, type PartnerLedgerOptions, type PartnerLedgerParams, type PartnerLedgerReport, type RevaluationOptions, type RevaluationParams, type RevaluationReport, type TrialBalanceOptions, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDaybook, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
package/dist/reports/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { DEFAULT_BUCKETS, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
|
1
|
+
import { E as generateAgedBalance, T as DEFAULT_BUCKETS, _ as generateBalanceSheet, c as generateRevaluation, d as generateIncomeStatement, f as generateGeneralLedger, g as generateBudgetVsActual, h as generateCashFlow, m as generateDaybook, n as closeFiscalPeriod, p as generateDimensionBreakdown, r as reopenFiscalPeriod, s as generateTrialBalance, t as generatePartnerLedger } from "../partner-ledger-BIkmQsAc.mjs";
|
|
2
|
+
export { DEFAULT_BUCKETS, closeFiscalPeriod, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDaybook, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, reopenFiscalPeriod };
|
|
@@ -2,6 +2,71 @@ import { c as DateRange } from "./core-DwjkrRkJ.mjs";
|
|
|
2
2
|
import { t as CountryPack } from "./index-08IpHhrU.mjs";
|
|
3
3
|
import { ClientSession, Model } from "mongoose";
|
|
4
4
|
|
|
5
|
+
//#region src/reports/daybook.d.ts
|
|
6
|
+
interface DaybookOptions {
|
|
7
|
+
JournalEntryModel: Model<unknown>;
|
|
8
|
+
orgField?: string;
|
|
9
|
+
}
|
|
10
|
+
interface DaybookParams {
|
|
11
|
+
organizationId?: unknown;
|
|
12
|
+
startDate: Date;
|
|
13
|
+
endDate: Date;
|
|
14
|
+
/** Default `'posted'`. Pass `'draft'` or `'all'` to widen. */
|
|
15
|
+
state?: 'posted' | 'draft' | 'all';
|
|
16
|
+
/** Filter to one specific account (renders that account's daybook slice). */
|
|
17
|
+
accountId?: unknown;
|
|
18
|
+
/** Filter to one journal type (e.g. `'SALES'`, `'PURCHASES'`). */
|
|
19
|
+
journalType?: string;
|
|
20
|
+
/** Filter to one partner (item-level field). */
|
|
21
|
+
partnerId?: unknown;
|
|
22
|
+
/** Field name on each item that holds the partner reference. Default `partnerId`. */
|
|
23
|
+
partnerField?: string;
|
|
24
|
+
/** Hard cap on rows. Default 5000 — prevents accidental full-table dumps. */
|
|
25
|
+
limit?: number;
|
|
26
|
+
}
|
|
27
|
+
interface DaybookLine {
|
|
28
|
+
date: Date;
|
|
29
|
+
entryId: unknown;
|
|
30
|
+
itemIndex: number;
|
|
31
|
+
referenceNumber?: string;
|
|
32
|
+
journalType?: string;
|
|
33
|
+
entryLabel?: string;
|
|
34
|
+
itemLabel?: string;
|
|
35
|
+
state?: string;
|
|
36
|
+
accountId: unknown;
|
|
37
|
+
/** Item-level debit in minor units (paisa). */
|
|
38
|
+
debit: number;
|
|
39
|
+
/** Item-level credit in minor units (paisa). */
|
|
40
|
+
credit: number;
|
|
41
|
+
partnerId?: unknown;
|
|
42
|
+
matchingNumber?: string | null;
|
|
43
|
+
}
|
|
44
|
+
interface DaybookReport {
|
|
45
|
+
metadata: {
|
|
46
|
+
generatedAt: string;
|
|
47
|
+
period: {
|
|
48
|
+
startDate: string;
|
|
49
|
+
endDate: string;
|
|
50
|
+
};
|
|
51
|
+
state: string;
|
|
52
|
+
filters: {
|
|
53
|
+
accountId?: unknown;
|
|
54
|
+
journalType?: string;
|
|
55
|
+
partnerId?: unknown;
|
|
56
|
+
};
|
|
57
|
+
truncated: boolean;
|
|
58
|
+
rowCount: number;
|
|
59
|
+
};
|
|
60
|
+
lines: DaybookLine[];
|
|
61
|
+
/** Sum of debits across the returned slice (minor units). */
|
|
62
|
+
totalDebit: number;
|
|
63
|
+
/** Sum of credits across the returned slice (minor units). */
|
|
64
|
+
totalCredit: number;
|
|
65
|
+
/** Net = totalDebit − totalCredit. Posted-only slices should net to 0. */
|
|
66
|
+
netDelta: number;
|
|
67
|
+
}
|
|
68
|
+
declare function generateDaybook(opts: DaybookOptions, params: DaybookParams): Promise<DaybookReport>;
|
|
69
|
+
//#endregion
|
|
5
70
|
//#region src/utils/logger.d.ts
|
|
6
71
|
/**
|
|
7
72
|
* Minimal logger interface for the accounting package.
|
|
@@ -581,4 +646,4 @@ declare function generateTrialBalance(opts: TrialBalanceOptions, params: {
|
|
|
581
646
|
filters?: Record<string, unknown>;
|
|
582
647
|
}): Promise<TrialBalanceReport>;
|
|
583
648
|
//#endregion
|
|
584
|
-
export { AgedBalanceParams as $, generateDimensionBreakdown as A, BalanceSheetReport as B, FiscalReopenResult as C, DimensionBreakdownParams as D, DimensionBreakdownOptions as E, BudgetVsActualReport as F, IncomeStatementReport as G, CashFlowSection as H, BudgetVsActualRow as I, ReportCategory as J, LedgerEntry as K, generateBudgetVsActual as L, generateCashFlow as M, BudgetVsActualOptions as N, DimensionBreakdownReport as O, BudgetVsActualParams as P, AgedBalanceOptions as Q, BalanceSheetOptions as R, FiscalCloseResult as S, reopenFiscalPeriod as T, GeneralLedgerAccount as U, CashFlowReport as V, GeneralLedgerReport as W, TrialBalanceReport as X, ReportGroup as Y, TrialBalanceRow as Z, IncomeStatementOptions as _, RevaluationReport as a, Logger as at, generateGeneralLedger as b, RevaluationRate as c, computeRevaluation as d, AgedBalanceReport as et, PartnerLedgerLine as f, generatePartnerLedger as g, PartnerLedgerReport as h, RevaluationParams as i, generateAgedBalance as it, CashFlowOptions as j, DimensionBreakdownRow as k, RevaluationResult as l, PartnerLedgerParams as m, generateTrialBalance as n, AgedBucketConfig as nt, generateRevaluation as o, defaultLogger as ot, PartnerLedgerOptions as p, ReportAccount as q, RevaluationOptions as r, DEFAULT_BUCKETS as rt, AccountForeignBalance as s, TrialBalanceOptions as t, AgedBalanceRow as tt, buildRevaluationEntry as u, generateIncomeStatement as v, closeFiscalPeriod as w, FiscalCloseOptions as x, GeneralLedgerOptions as y, generateBalanceSheet as z };
|
|
649
|
+
export { AgedBalanceParams as $, generateDimensionBreakdown as A, BalanceSheetReport as B, FiscalReopenResult as C, DimensionBreakdownParams as D, DimensionBreakdownOptions as E, BudgetVsActualReport as F, IncomeStatementReport as G, CashFlowSection as H, BudgetVsActualRow as I, ReportCategory as J, LedgerEntry as K, generateBudgetVsActual as L, generateCashFlow as M, BudgetVsActualOptions as N, DimensionBreakdownReport as O, BudgetVsActualParams as P, AgedBalanceOptions as Q, BalanceSheetOptions as R, FiscalCloseResult as S, reopenFiscalPeriod as T, GeneralLedgerAccount as U, CashFlowReport as V, GeneralLedgerReport as W, TrialBalanceReport as X, ReportGroup as Y, TrialBalanceRow as Z, IncomeStatementOptions as _, RevaluationReport as a, Logger as at, generateGeneralLedger as b, RevaluationRate as c, DaybookOptions as ct, computeRevaluation as d, generateDaybook as dt, AgedBalanceReport as et, PartnerLedgerLine as f, generatePartnerLedger as g, PartnerLedgerReport as h, RevaluationParams as i, generateAgedBalance as it, CashFlowOptions as j, DimensionBreakdownRow as k, RevaluationResult as l, DaybookParams as lt, PartnerLedgerParams as m, generateTrialBalance as n, AgedBucketConfig as nt, generateRevaluation as o, defaultLogger as ot, PartnerLedgerOptions as p, ReportAccount as q, RevaluationOptions as r, DEFAULT_BUCKETS as rt, AccountForeignBalance as s, DaybookLine as st, TrialBalanceOptions as t, AgedBalanceRow as tt, buildRevaluationEntry as u, DaybookReport as ut, generateIncomeStatement as v, closeFiscalPeriod as w, FiscalCloseOptions as x, GeneralLedgerOptions as y, generateBalanceSheet as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/ledger",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "Production-grade double-entry accounting engine for MongoDB — schemas, reports, tax, multi-tenant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
},
|
|
95
95
|
"peerDependencies": {
|
|
96
96
|
"@classytic/fin-io": ">=0.1.0",
|
|
97
|
-
"@classytic/mongokit": ">=3.11.
|
|
97
|
+
"@classytic/mongokit": ">=3.11.1",
|
|
98
98
|
"@classytic/primitives": ">=0.1.0",
|
|
99
99
|
"@classytic/repo-core": ">=0.2.0",
|
|
100
100
|
"mongoose": ">=9.4.1",
|
|
@@ -107,8 +107,9 @@
|
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
109
|
"@biomejs/biome": "^2.4.12",
|
|
110
|
+
"@classytic/dev-tools": "^0.2.0",
|
|
110
111
|
"@classytic/fin-io": ">=0.1.0",
|
|
111
|
-
"@classytic/mongokit": "
|
|
112
|
+
"@classytic/mongokit": "^3.11.1",
|
|
112
113
|
"@classytic/primitives": ">=0.1.0",
|
|
113
114
|
"@classytic/repo-core": ">=0.2.0",
|
|
114
115
|
"@types/node": "^25.5.0",
|
|
@@ -139,8 +140,10 @@
|
|
|
139
140
|
"format": "biome format src/ --write",
|
|
140
141
|
"check": "biome ci src/ --diagnostic-level=error",
|
|
141
142
|
"knip": "knip",
|
|
143
|
+
"push": "classytic-push",
|
|
142
144
|
"smoke": "node scripts/smoke.mjs",
|
|
143
145
|
"prepublishOnly": "npm run check && npm run build && npm run typecheck && npm test && npm run smoke",
|
|
144
|
-
"release": "
|
|
146
|
+
"release:tag": "node -e \"require('child_process').execSync('npm run push -- v'+require('./package.json').version,{stdio:'inherit'})\"",
|
|
147
|
+
"release": "npm run push -- main && npm run release:tag && npm publish"
|
|
145
148
|
}
|
|
146
149
|
}
|