@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 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-DyNm5bFu.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, 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
- * - `'string'` (default, back-compat): stores tenant IDs as strings.
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
- * New hosts wiring Better Auth should pass `'objectId'`. See
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 isVirtualTaxAccount, E as requireOrgScope, S as computeEndingBalance, T as generateAgedBalance, _ as buildItemFilters, a as finalizeSession, b as buildAccountTypeMap, c as generateRevaluation, d as generateIncomeStatement, f as generateGeneralLedger, g as generateBalanceSheet, h as generateBudgetVsActual, i as acquireSession, l as buildRevaluationEntry, m as generateCashFlow, n as closeFiscalPeriod, o as defaultLogger, p as generateDimensionBreakdown, r as reopenFiscalPeriod, s as generateTrialBalance, t as generatePartnerLedger, u as computeRevaluation, v as getDateRange, w as DEFAULT_BUCKETS, x as calculateTotal, y as getFiscalYearStart } from "./partner-ledger-CR0geilx.mjs";
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
- repository.on("before:create", (ctx) => {
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) tenantPlugins.push(multiTenantPlugin({
1984
- tenantField: orgField,
1985
- contextKey: "organizationId",
1986
- required: config.multiTenant.required ?? false,
1987
- fieldType: config.tenantFieldType ?? "string"
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 (orgField && organizationId != null) payload[orgField] = organizationId;
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 { isVirtualTaxAccount as C, requireOrgScope as E, computeEndingBalance as S, generateAgedBalance as T, buildItemFilters as _, finalizeSession as a, buildAccountTypeMap as b, generateRevaluation as c, generateIncomeStatement as d, generateGeneralLedger as f, generateBalanceSheet as g, generateBudgetVsActual as h, acquireSession as i, buildRevaluationEntry as l, generateCashFlow as m, closeFiscalPeriod as n, defaultLogger as o, generateDimensionBreakdown as p, reopenFiscalPeriod as r, generateTrialBalance as s, generatePartnerLedger as t, computeRevaluation as u, getDateRange as v, DEFAULT_BUCKETS as w, calculateTotal as x, getFiscalYearStart as y };
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 };
@@ -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-DyNm5bFu.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 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 };
@@ -1,2 +1,2 @@
1
- import { T as generateAgedBalance, c as generateRevaluation, d as generateIncomeStatement, f as generateGeneralLedger, g as generateBalanceSheet, h as generateBudgetVsActual, m as generateCashFlow, n as closeFiscalPeriod, p as generateDimensionBreakdown, r as reopenFiscalPeriod, s as generateTrialBalance, t as generatePartnerLedger, w as DEFAULT_BUCKETS } from "../partner-ledger-CR0geilx.mjs";
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.1",
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.0",
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": ">=3.11.0",
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": "npm run check && npm run build && npm run typecheck && npm test && npm run smoke && npm publish --access public"
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
  }