@classytic/ledger 0.7.0 → 0.8.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/dist/index.d.mts CHANGED
@@ -1,12 +1,12 @@
1
- import { _ as TaxMetadata, a as Cents, c as DateRange, d as JournalType, f as MainType, g as TaxDetail, h as StatementType, i as CategoryKey, l as EntryState, m as ObjectId, n as CashFlowCategory, o as Currency, p as NormalBalance, s as DateOption, t as AccountType, u as JournalItem, v as TotalAccountOp } from "./core-BkGjuVZj.mjs";
2
- import { S as isValidCategory, a as getJournalTypeCodes, b as isBalanceSheet, c as CURRENCIES, d as isValidCurrency, f as CATEGORIES, i as getJournalType, l as getCurrency, n as JOURNAL_TYPES, o as isValidJournalType, p as CATEGORY_KEYS, r as getCustomJournalTypes, s as registerJournalType, t as JOURNAL_CODES, u as getMinorUnit, x as isIncomeStatement, y as getNormalBalance } from "./journals-C50E9mpo.mjs";
3
- import { i as defineCountryPack, n as CountryPackInput, r as JournalTemplate, t as CountryPack } from "./index-BX8miYdu.mjs";
4
- 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-D1ZjgVxn.mjs";
1
+ import { _ as TaxMetadata, a as Cents, c as DateRange, d as JournalType, f as MainType, g as TaxDetail, h as StatementType, i as CategoryKey, l as EntryState, m as ObjectId, n as CashFlowCategory, o as Currency, p as NormalBalance, s as DateOption, t as AccountType, u as JournalItem, v as TotalAccountOp } from "./core-MpgjCqK0.mjs";
2
+ import { S as isValidCategory, a as getJournalTypeCodes, b as isBalanceSheet, c as CURRENCIES, d as isValidCurrency, f as CATEGORIES, i as getJournalType, l as getCurrency, n as JOURNAL_TYPES, o as isValidJournalType, p as CATEGORY_KEYS, r as getCustomJournalTypes, s as registerJournalType, t as JOURNAL_CODES, u as getMinorUnit, x as isIncomeStatement, y as getNormalBalance } from "./journals-Dd4A9TN3.mjs";
3
+ import { i as defineCountryPack, n as CountryPackInput, r as JournalTemplate, t as CountryPack } from "./index-RNZsX0Yo.mjs";
4
+ 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-bCEeSzdO.mjs";
5
5
  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";
6
- 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-DTc8kzTD.mjs";
7
- 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-Bl0_ak5w.mjs";
6
+ 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-DTj-c21f.mjs";
7
+ 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-BSsvrf3m.mjs";
8
+ import { PaginationConfig, PluginType, QueryParser, QueryParserOptions, Repository } from "@classytic/mongokit";
8
9
  import { ClientSession, Connection, Model } from "mongoose";
9
- import { PaginationConfig, PluginType, Repository } from "@classytic/mongokit";
10
10
 
11
11
  //#region src/types/engine.d.ts
12
12
  /** Mongokit plugins to install per repository (composes with engine built-ins). */
@@ -381,6 +381,28 @@ interface RecordAdjustmentInput {
381
381
  readonly dimensions?: Record<string, unknown>;
382
382
  readonly journalType?: string;
383
383
  }
384
+ interface RecordOpeningBalanceInput {
385
+ /** Cutover date — typically start of fiscal year. */
386
+ readonly cutoverDate: Date;
387
+ /**
388
+ * Account balances in integer cents, signed:
389
+ * - Positive = normal debit balance (assets)
390
+ * - Negative = normal credit balance (liabilities, equity)
391
+ *
392
+ * Should only contain balance sheet accounts. P&L cumulative effect
393
+ * belongs in retained earnings (the equity account).
394
+ */
395
+ readonly balances: ReadonlyArray<{
396
+ readonly account: AccountCode;
397
+ readonly balance: Cents$1;
398
+ }>;
399
+ /**
400
+ * Equity contra account code. Defaults to the country pack's
401
+ * `retainedEarningsAccountCode` (e.g. '3600' for CA, '3310' for BD).
402
+ */
403
+ readonly equityAccount?: AccountCode;
404
+ readonly label?: string;
405
+ }
384
406
  interface RecordAPI {
385
407
  /**
386
408
  * Record a sale. Debits cash/AR, credits revenue. Tax lines — if needed —
@@ -418,6 +440,31 @@ interface RecordAPI {
418
440
  * the other verbs. Amounts must balance (debits = credits).
419
441
  */
420
442
  adjustment(organizationId: unknown, input: RecordAdjustmentInput, options?: RecordOptions): Promise<unknown>;
443
+ /**
444
+ * Record opening balances for a cutover migration. Creates a single
445
+ * multi-line journal entry with each account's balance, contra'd against
446
+ * an equity account (retained earnings by default).
447
+ *
448
+ * Follows the Odoo convention: regular JE, not a special type. Only
449
+ * balance sheet accounts should be passed — P&L cumulative effect belongs
450
+ * in the equity contra account.
451
+ *
452
+ * Idempotent: uses `_externalId: 'opening-balance:{date}'` so re-calling
453
+ * with the same cutover date fails cleanly (duplicate key error).
454
+ *
455
+ * @example
456
+ * ```typescript
457
+ * await engine.record.openingBalance(orgId, {
458
+ * cutoverDate: new Date('2025-01-01'),
459
+ * balances: [
460
+ * { account: '1000', balance: 5000000 }, // $50k cash
461
+ * { account: '2620', balance: -1875000 }, // $18.75k AP
462
+ * { account: '3600', balance: -3125000 }, // $31.25k RE
463
+ * ],
464
+ * });
465
+ * ```
466
+ */
467
+ openingBalance(organizationId: unknown, input: RecordOpeningBalanceInput, options?: RecordOptions): Promise<unknown>;
421
468
  }
422
469
  //#endregion
423
470
  //#region src/engine.d.ts
@@ -540,10 +587,80 @@ declare class AccountingEngine {
540
587
  isValidAccountType(code: string): boolean;
541
588
  /** Get account type definition by code */
542
589
  getAccountType(code: string): AccountType | undefined;
590
+ /**
591
+ * Create a pre-configured QueryParser for URL-driven queries against
592
+ * ledger repositories. Returns a mongokit QueryParser with the correct
593
+ * schema and pagination limits for the specified model.
594
+ *
595
+ * @param model - Which ledger model to parse queries for
596
+ * @param overrides - Additional QueryParserOptions to merge
597
+ *
598
+ * @example
599
+ * ```typescript
600
+ * const parser = engine.createQueryParser('journalEntry');
601
+ * const parsed = parser.parse(req.query);
602
+ * const result = await engine.repositories.journalEntries.getAll({
603
+ * ...parsed,
604
+ * filters: { ...parsed.filters, organizationId },
605
+ * });
606
+ * ```
607
+ */
608
+ createQueryParser(model: 'account' | 'journalEntry' | 'fiscalPeriod' | 'budget' | 'reconciliation' | 'journal', overrides?: Partial<QueryParserOptions>): QueryParser;
543
609
  private _buildReports;
544
610
  }
545
611
  declare function createAccountingEngine(config: AccountingEngineConfig): AccountingEngine;
546
612
  //#endregion
613
+ //#region src/repositories/reconciliation.repository.d.ts
614
+ interface MatchHookItem {
615
+ entry: unknown;
616
+ itemIndex: number;
617
+ debit: number;
618
+ credit: number;
619
+ amountCurrency: number | null;
620
+ exchangeRate: number | null;
621
+ }
622
+ /**
623
+ * Context passed to `before:match` and `after:match` hooks.
624
+ *
625
+ * - `before:match`: fired after validation but before the matchingNumber is
626
+ * stamped and the reconciliation doc is created. Throw to abort.
627
+ * - `after:match`: fired after the reconciliation doc is persisted. Used by
628
+ * fxRealizationPlugin, and can be used by invoice packages to update
629
+ * payment state.
630
+ */
631
+ interface MatchHookContext {
632
+ /** The input that was passed to match(). */
633
+ input: MatchInput;
634
+ /** Validated + enriched item snapshots with debit/credit/currency info. */
635
+ items: MatchHookItem[];
636
+ /** Shared currency across all items, or null if mixed. */
637
+ sharedCurrency: string | null;
638
+ /** The matching number (auto-generated or caller-provided). */
639
+ matchingNumber: string;
640
+ /** Totals for the matched set. */
641
+ debitTotal: number;
642
+ creditTotal: number;
643
+ isFullReconcile: boolean;
644
+ /** The created reconciliation document (only in after:match). */
645
+ reconciliation?: unknown;
646
+ session: ClientSession | null;
647
+ }
648
+ /**
649
+ * Context passed to `before:unmatch` and `after:unmatch` hooks.
650
+ */
651
+ interface UnmatchHookContext {
652
+ matchingNumber: string;
653
+ /** The reconciliation document being removed. */
654
+ reconciliation: Record<string, unknown>;
655
+ /** The items that will be / were unmatched. */
656
+ items: Array<{
657
+ entry: unknown;
658
+ itemIndex: number;
659
+ }>;
660
+ organizationId?: unknown;
661
+ session: ClientSession | null;
662
+ }
663
+ //#endregion
547
664
  //#region src/utils/account-helpers.d.ts
548
665
  /**
549
666
  * Check if an account type is a virtual tax sub-account.
@@ -764,4 +881,4 @@ interface PostingResult {
764
881
  idempotencyKeys?: string[];
765
882
  }
766
883
  //#endregion
767
- export { type AccountCode, type AccountForeignBalance, type AccountRepository, type AccountSummary, type AccountType, AccountingEngine, type AccountingEngineConfig, AccountingError, type ActorContext, type AgedBalanceOptions, type AgedBalanceParams, type AgedBalanceReport, type AgedBalanceRow, type AgedBucketConfig, type AuditConfig, type BalanceSheetReport, type BudgetVsActualOptions, type BudgetVsActualParams, type BudgetVsActualReport, type BudgetVsActualRow, type BulkCreateInput, type BulkCreateResult, CATEGORIES, CATEGORY_KEYS, CURRENCIES, type CashFlowCategory, type CashFlowReport, type CashFlowSection, type CategoryKey, type Cents, type CountryPack, type CountryPackInput, type CreateLockPluginOptions, type CreditLimitPluginOptions, type Currency, DEFAULT_BUCKETS, type DailyLockPluginOptions, type DateOption, type DateRange, type DimensionBreakdownOptions, type DimensionBreakdownParams, type DimensionBreakdownReport, type DimensionBreakdownRow, type DimensionDefinition, type EntryState, Errors, type ExportField, type ExportFieldMap, type FieldError, type FiscalLockPluginOptions, type FiscalPeriodSummary, type FlatJournalRow, type FxRealizationPluginOptions, type GeneralLedgerAccount, type GeneralLedgerReport, type IncomeStatementReport, type IntrospectAPI, JOURNAL_CODES, JOURNAL_TYPES, type JournalEntryRepository, type JournalItem, type JournalItemRef, type JournalRepository, type JournalSchemaOptions, type JournalTemplate, type JournalType, type LedgerEntry, type LedgerModels, type LedgerPaginationConfig, type LedgerRepositories, type LedgerRepositoryPlugins, type LockAccountSelector, type LockHit, type LockResolver, type LockResolverContext, type Logger, type MainType, type MatchInput, type ModelNames, Money, type MultiCurrencyConfig, type MultiTenantConfig, type NormalBalance, type OpenItem, type PartnerLedgerLine, type PartnerLedgerOptions, type PartnerLedgerParams, type PartnerLedgerReport, type PeriodResolverOptions, type PopulatedJournalEntry, type PostOptions, type PostingContract, type PostingResult, type ReconciliationRepository, type RecordAPI, type RecordAdjustmentInput, type RecordAdjustmentLine, type RecordExpenseInput, type RecordOptions, type RecordPaymentInput, type RecordSaleInput, type RecordTransferInput, type ReportAccount, type ReportCategory, type ReportDescriptor, type ReportGroup, type ResolvedModelNames, type RevaluationOptions, type RevaluationParams, type RevaluationRate, type RevaluationReport, type RevaluationResult, type ReverseOptions, type ReverseResult, type SchemaOptions, type SeedOptions, type SeedResult, type Cents$1 as SemanticCents, type SessionResult, type StatementType, type StrictnessConfig, type SubledgerJournalItem, type SubledgerPostingInput, type TaxDetail, type TaxMetadata, type TotalAccountOp, type TrialBalanceReport, type TrialBalanceRow, type WatermarkResolverOptions, acquireSession, add, allocate, buildAccountTypeMap, buildDimensionFields, buildDimensionIndexes, buildItemFilters, buildRevaluationEntry, calculateTotal, closeFiscalPeriod, computeEndingBalance, computeRevaluation, createAccountingEngine, createLockPlugin, createModels, createRepositories, creditLimitPlugin, dailyLockPlugin, defaultLogger, defineCountryPack, doubleEntryPlugin, exportToCsv, finalizeSession, fiscalLockPlugin, flattenJournalEntries, format, formatPlain, fromDecimal, fxRealizationPlugin, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, getCurrency, getCustomJournalTypes, getDateRange, getFiscalYearStart, getJournalType, getJournalTypeCodes, getMinorUnit, getNormalBalance, idempotencyPlugin, isBalanceSheet, isIncomeStatement, isValidCategory, isValidCurrency, isValidJournalType, isVirtualTaxAccount, multiply, parseCents, percentage, periodResolver, quickbooksFieldMap, registerJournalType, reopenFiscalPeriod, resolveModelNames, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal, universalFieldMap, watermarkResolver };
884
+ export { type AccountCode, type AccountForeignBalance, type AccountRepository, type AccountSummary, type AccountType, AccountingEngine, type AccountingEngineConfig, AccountingError, type ActorContext, type AgedBalanceOptions, type AgedBalanceParams, type AgedBalanceReport, type AgedBalanceRow, type AgedBucketConfig, type AuditConfig, type BalanceSheetReport, type BudgetVsActualOptions, type BudgetVsActualParams, type BudgetVsActualReport, type BudgetVsActualRow, type BulkCreateInput, type BulkCreateResult, CATEGORIES, CATEGORY_KEYS, CURRENCIES, type CashFlowCategory, type CashFlowReport, type CashFlowSection, type CategoryKey, type Cents, type CountryPack, type CountryPackInput, type CreateLockPluginOptions, type CreditLimitPluginOptions, type Currency, DEFAULT_BUCKETS, type DailyLockPluginOptions, type DateOption, type DateRange, type DimensionBreakdownOptions, type DimensionBreakdownParams, type DimensionBreakdownReport, type DimensionBreakdownRow, type DimensionDefinition, type EntryState, Errors, type ExportField, type ExportFieldMap, type FieldError, type FiscalLockPluginOptions, type FiscalPeriodSummary, type FlatJournalRow, type FxRealizationPluginOptions, type GeneralLedgerAccount, type GeneralLedgerReport, type IncomeStatementReport, type IntrospectAPI, JOURNAL_CODES, JOURNAL_TYPES, type JournalEntryRepository, type JournalItem, type JournalItemRef, type JournalRepository, type JournalSchemaOptions, type JournalTemplate, type JournalType, type LedgerEntry, type LedgerModels, type LedgerPaginationConfig, type LedgerRepositories, type LedgerRepositoryPlugins, type LockAccountSelector, type LockHit, type LockResolver, type LockResolverContext, type Logger, type MainType, type MatchHookContext, type MatchHookItem, type MatchInput, type ModelNames, Money, type MultiCurrencyConfig, type MultiTenantConfig, type NormalBalance, type OpenItem, type PartnerLedgerLine, type PartnerLedgerOptions, type PartnerLedgerParams, type PartnerLedgerReport, type PeriodResolverOptions, type PopulatedJournalEntry, type PostOptions, type PostingContract, type PostingResult, type ReconciliationRepository, type RecordAPI, type RecordAdjustmentInput, type RecordAdjustmentLine, type RecordExpenseInput, type RecordOptions, type RecordPaymentInput, type RecordSaleInput, type RecordTransferInput, type ReportAccount, type ReportCategory, type ReportDescriptor, type ReportGroup, type ResolvedModelNames, type RevaluationOptions, type RevaluationParams, type RevaluationRate, type RevaluationReport, type RevaluationResult, type ReverseOptions, type ReverseResult, type SchemaOptions, type SeedOptions, type SeedResult, type Cents$1 as SemanticCents, type SessionResult, type StatementType, type StrictnessConfig, type SubledgerJournalItem, type SubledgerPostingInput, type TaxDetail, type TaxMetadata, type TotalAccountOp, type TrialBalanceReport, type TrialBalanceRow, type UnmatchHookContext, type WatermarkResolverOptions, acquireSession, add, allocate, buildAccountTypeMap, buildDimensionFields, buildDimensionIndexes, buildItemFilters, buildRevaluationEntry, calculateTotal, closeFiscalPeriod, computeEndingBalance, computeRevaluation, createAccountingEngine, createLockPlugin, createModels, createRepositories, creditLimitPlugin, dailyLockPlugin, defaultLogger, defineCountryPack, doubleEntryPlugin, exportToCsv, finalizeSession, fiscalLockPlugin, flattenJournalEntries, format, formatPlain, fromDecimal, fxRealizationPlugin, generateAgedBalance, generateBalanceSheet, generateBudgetVsActual, generateCashFlow, generateDimensionBreakdown, generateGeneralLedger, generateIncomeStatement, generatePartnerLedger, generateRevaluation, generateTrialBalance, getCurrency, getCustomJournalTypes, getDateRange, getFiscalYearStart, getJournalType, getJournalTypeCodes, getMinorUnit, getNormalBalance, idempotencyPlugin, isBalanceSheet, isIncomeStatement, isValidCategory, isValidCurrency, isValidJournalType, isVirtualTaxAccount, multiply, parseCents, percentage, periodResolver, quickbooksFieldMap, registerJournalType, reopenFiscalPeriod, resolveModelNames, splitTaxExclusive, splitTaxInclusive, subtract, toDecimal, universalFieldMap, watermarkResolver };
package/dist/index.mjs CHANGED
@@ -3,11 +3,12 @@ import { Money, add, allocate, format, formatPlain, fromDecimal, multiply, parse
3
3
  import { n as Errors, t as AccountingError } from "./errors-CSDQPNyt.mjs";
4
4
  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-D9H5hegI.mjs";
5
5
  import { c as getNormalBalance, d as isValidCategory, l as isBalanceSheet, n as CATEGORY_KEYS, t as CATEGORIES, u as isIncomeStatement } from "./categories-BkKdv16V.mjs";
6
- 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-CfYy1tB6.mjs";
6
+ 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-DDVK-oYO.mjs";
7
+ import { t as buildOpeningBalanceEntry } from "./opening-balance-DPXmAIzN.mjs";
7
8
  import { defineCountryPack } from "./country/index.mjs";
8
- import { a as exportToCsv, i as quickbooksFieldMap, r as universalFieldMap, t as flattenJournalEntries } from "./exports-BP-0Ni5W.mjs";
9
+ import { a as exportToCsv, i as quickbooksFieldMap, r as universalFieldMap, t as flattenJournalEntries } from "./exports-B3whucXe.mjs";
10
+ import { QueryParser, Repository } from "@classytic/mongokit";
9
11
  import mongoose, { Schema } from "mongoose";
10
- import { Repository } from "@classytic/mongokit";
11
12
  //#region src/schemas/currency-field.ts
12
13
  /**
13
14
  * Build the Mongoose currency field definition.
@@ -919,11 +920,10 @@ function createModels(connection, config) {
919
920
  * onto an existing mongokit Repository.
920
921
  *
921
922
  * @param repository - A mongokit Repository instance (already created)
922
- * @param AccountModel - The Mongoose model for accounts
923
923
  * @param country - The CountryPack for account type lookups
924
924
  * @param orgField - The multi-tenant field name (e.g. 'business')
925
925
  */
926
- function wireAccountMethods(repository, AccountModel, country, orgField) {
926
+ function wireAccountMethods(repository, country, orgField) {
927
927
  repository.on("before:create", (ctx) => {
928
928
  const code = ctx.data?.accountTypeCode;
929
929
  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.`);
@@ -936,7 +936,10 @@ function wireAccountMethods(repository, AccountModel, country, orgField) {
936
936
  const postingTypes = country.getPostingAccountTypes();
937
937
  const filter = {};
938
938
  if (orgField && orgId != null) filter[orgField] = orgId;
939
- const existing = await AccountModel.find(filter).select("accountNumber").lean();
939
+ const existing = await repository.findAll(filter, {
940
+ select: { accountNumber: 1 },
941
+ lean: true
942
+ });
940
943
  const existingNumbers = new Set(existing.map((a) => a.accountNumber));
941
944
  const toCreate = postingTypes.filter((at) => !existingNumbers.has(at.code)).map((at) => {
942
945
  const doc = {
@@ -953,7 +956,7 @@ function wireAccountMethods(repository, AccountModel, country, orgField) {
953
956
  };
954
957
  try {
955
958
  return {
956
- created: (await AccountModel.insertMany(toCreate, {
959
+ created: (await repository.createMany(toCreate, {
957
960
  session: options.session ?? void 0,
958
961
  ordered: false
959
962
  })).length,
@@ -1034,7 +1037,10 @@ function wireAccountMethods(repository, AccountModel, country, orgField) {
1034
1037
  };
1035
1038
  const existsFilter = { accountNumber: { $in: validAccounts.map((a) => a.accountNumber) } };
1036
1039
  if (orgField && orgId != null) existsFilter[orgField] = orgId;
1037
- const existingDocs = await AccountModel.find(existsFilter).select("accountNumber").lean();
1040
+ const existingDocs = await repository.findAll(existsFilter, {
1041
+ select: { accountNumber: 1 },
1042
+ lean: true
1043
+ });
1038
1044
  const existingNumbers = new Set(existingDocs.map((d) => d.accountNumber));
1039
1045
  const toCreate = [];
1040
1046
  for (const item of validAccounts) if (existingNumbers.has(item.accountNumber)) results.skipped.push({
@@ -1056,7 +1062,7 @@ function wireAccountMethods(repository, AccountModel, country, orgField) {
1056
1062
  return doc;
1057
1063
  });
1058
1064
  try {
1059
- const inserted = await AccountModel.insertMany(docs, { ordered: false });
1065
+ const inserted = await repository.createMany(docs, { ordered: false });
1060
1066
  results.created = toCreate.map((item, idx) => ({
1061
1067
  accountTypeCode: item.accountTypeCode,
1062
1068
  active: item.active,
@@ -1541,6 +1547,7 @@ function wireReconciliationMethods(repository, ReconciliationModel, JournalEntry
1541
1547
  const create = repository.create.bind(repository);
1542
1548
  const deleteById = repository.delete.bind(repository);
1543
1549
  const repoInstance = repository;
1550
+ const emitHook = repoInstance.emitAsync.bind(repoInstance);
1544
1551
  repository.match = async (input) => {
1545
1552
  const { account, items, note, reconciledBy, organizationId, session = null } = input;
1546
1553
  let { matchingNumber } = input;
@@ -1585,6 +1592,17 @@ function wireReconciliationMethods(repository, ReconciliationModel, JournalEntry
1585
1592
  const isFullReconcile = difference === 0;
1586
1593
  const sharedCurrency = currencies.size === 1 ? Array.from(currencies)[0] : null;
1587
1594
  if (!matchingNumber) matchingNumber = await nextMatchingNumber(ReconciliationModel, orgField, organizationId, session);
1595
+ const hookCtx = {
1596
+ input,
1597
+ items: itemSnapshots,
1598
+ sharedCurrency,
1599
+ matchingNumber,
1600
+ debitTotal,
1601
+ creditTotal,
1602
+ isFullReconcile,
1603
+ session
1604
+ };
1605
+ await emitHook("before:match", hookCtx);
1588
1606
  const bulkOps = itemSnapshots.map((snap) => ({ updateOne: {
1589
1607
  filter: { _id: snap.entry },
1590
1608
  update: { $set: { [`journalItems.${snap.itemIndex}.matchingNumber`]: matchingNumber } }
@@ -1612,12 +1630,9 @@ function wireReconciliationMethods(repository, ReconciliationModel, JournalEntry
1612
1630
  };
1613
1631
  if (orgField && organizationId != null) reconciliationData[orgField] = organizationId;
1614
1632
  const record = await create(reconciliationData);
1615
- const emit = repoInstance._emitHook;
1616
- if (emit) await emit.call(repoInstance, "after:match", {
1617
- reconciliation: record,
1618
- items: itemSnapshots,
1619
- sharedCurrency,
1620
- session
1633
+ await emitHook("after:match", {
1634
+ ...hookCtx,
1635
+ reconciliation: record
1621
1636
  });
1622
1637
  return record;
1623
1638
  };
@@ -1628,13 +1643,23 @@ function wireReconciliationMethods(repository, ReconciliationModel, JournalEntry
1628
1643
  if (orgField && organizationId != null) query[orgField] = organizationId;
1629
1644
  const existing = await ReconciliationModel.findOne(query).session(session).lean();
1630
1645
  if (!existing) throw Errors.notFound(`Reconciliation ${matchingNumber} not found`);
1631
- const bulkOps = (existing.items ?? []).map((it) => ({ updateOne: {
1646
+ const items = existing.items ?? [];
1647
+ const unmatchCtx = {
1648
+ matchingNumber,
1649
+ reconciliation: existing,
1650
+ items,
1651
+ organizationId,
1652
+ session
1653
+ };
1654
+ await emitHook("before:unmatch", unmatchCtx);
1655
+ const bulkOps = items.map((it) => ({ updateOne: {
1632
1656
  filter: { _id: it.entry },
1633
1657
  update: { $set: { [`journalItems.${it.itemIndex}.matchingNumber`]: null } }
1634
1658
  } }));
1635
1659
  if (bulkOps.length > 0) await JournalEntryModel.bulkWrite(bulkOps, { session: session ?? void 0 });
1636
1660
  const result = await deleteById(String(existing._id));
1637
1661
  if (!result.success) throw Errors.notFound("Failed to delete reconciliation record");
1662
+ await emitHook("after:unmatch", unmatchCtx);
1638
1663
  return result;
1639
1664
  };
1640
1665
  repository.getOpenItems = async (params) => {
@@ -1727,7 +1752,7 @@ function createRepositories(models, config, plugins = {}, pagination = {}) {
1727
1752
  const fpPagination = pagination.fiscalPeriod ?? {};
1728
1753
  const budgetPagination = pagination.budget ?? {};
1729
1754
  const reconPagination = pagination.reconciliation ?? {};
1730
- const accounts = wireAccountMethods(new Repository(models.Account, plugins.account ?? [], accountPagination), models.Account, country, orgField);
1755
+ const accounts = wireAccountMethods(new Repository(models.Account, plugins.account ?? [], accountPagination), country, orgField);
1731
1756
  const jePlugins = [
1732
1757
  ...plugins.journalEntry ?? [],
1733
1758
  doubleEntryPlugin({
@@ -2255,16 +2280,80 @@ function buildRecordAPI({ models, repositories, config }) {
2255
2280
  journalItems: items
2256
2281
  }, options);
2257
2282
  };
2283
+ const openingBalance = async (organizationId, input, options) => {
2284
+ if (!input.balances || input.balances.length === 0) throw Errors.validation("Opening balance requires at least one account balance.", [{
2285
+ path: "balances",
2286
+ issue: "must contain at least 1 entry",
2287
+ value: 0
2288
+ }]);
2289
+ const equityCode = input.equityAccount ?? config.country?.retainedEarningsAccountCode;
2290
+ if (!equityCode) throw Errors.validation("Equity contra account code is required. Pass equityAccount or configure retainedEarningsAccountCode in the country pack.", [{
2291
+ path: "equityAccount",
2292
+ issue: "required",
2293
+ value: void 0
2294
+ }]);
2295
+ const result = buildOpeningBalanceEntry({
2296
+ cutoverDate: input.cutoverDate,
2297
+ balances: input.balances.map((b) => ({
2298
+ accountCode: b.account,
2299
+ balance: b.balance
2300
+ })),
2301
+ equityAccountCode: equityCode,
2302
+ label: input.label
2303
+ });
2304
+ const acctMap = await resolveAccounts(organizationId, result.entry.journalItems.map((item) => item.account), "balances", options?.session ?? null);
2305
+ const items = result.entry.journalItems.map((item) => buildItem(acctMap.get(item.account), item.debit, item.credit, item.label));
2306
+ return postEntry(organizationId, {
2307
+ journalType: result.entry.journalType ?? "GENERAL",
2308
+ date: result.entry.date,
2309
+ label: result.entry.label,
2310
+ journalItems: items,
2311
+ ...result.entry.extra
2312
+ }, options);
2313
+ };
2258
2314
  return {
2259
2315
  sale,
2260
2316
  expense,
2261
2317
  transfer,
2262
2318
  payment,
2263
- adjustment
2319
+ adjustment,
2320
+ openingBalance
2264
2321
  };
2265
2322
  }
2266
2323
  //#endregion
2267
2324
  //#region src/engine.ts
2325
+ /**
2326
+ * AccountingEngine — The main entry point for @classytic/ledger.
2327
+ *
2328
+ * The engine owns all models, repositories, and reports. Matches the
2329
+ * @classytic/flow and @classytic/promo pattern: pass a mongoose connection
2330
+ * in config, and everything is auto-wired.
2331
+ *
2332
+ * @example
2333
+ * ```typescript
2334
+ * import mongoose from 'mongoose';
2335
+ * import { createAccountingEngine } from '@classytic/ledger';
2336
+ * import { canadaPack } from '@classytic/ledger-ca';
2337
+ *
2338
+ * const engine = createAccountingEngine({
2339
+ * mongoose: mongoose.connection,
2340
+ * country: canadaPack,
2341
+ * currency: 'CAD',
2342
+ * multiTenant: { orgField: 'organizationId', orgRef: 'Organization' },
2343
+ * });
2344
+ *
2345
+ * // Models — auto-created Mongoose models
2346
+ * engine.models.Account
2347
+ * engine.models.JournalEntry
2348
+ *
2349
+ * // Repositories — plugins + domain methods pre-wired
2350
+ * await engine.repositories.accounts.seedAccounts(orgId);
2351
+ * await engine.repositories.journalEntries.post(entryId, orgId);
2352
+ *
2353
+ * // Reports — bound to owned models
2354
+ * const bs = await engine.reports.balanceSheet({ organizationId: orgId, dateOption: 'year', dateValue: 2025 });
2355
+ * ```
2356
+ */
2268
2357
  var AccountingEngine = class {
2269
2358
  config;
2270
2359
  country;
@@ -2313,6 +2402,60 @@ var AccountingEngine = class {
2313
2402
  getAccountType(code) {
2314
2403
  return this.country.getAccountType(code);
2315
2404
  }
2405
+ /**
2406
+ * Create a pre-configured QueryParser for URL-driven queries against
2407
+ * ledger repositories. Returns a mongokit QueryParser with the correct
2408
+ * schema and pagination limits for the specified model.
2409
+ *
2410
+ * @param model - Which ledger model to parse queries for
2411
+ * @param overrides - Additional QueryParserOptions to merge
2412
+ *
2413
+ * @example
2414
+ * ```typescript
2415
+ * const parser = engine.createQueryParser('journalEntry');
2416
+ * const parsed = parser.parse(req.query);
2417
+ * const result = await engine.repositories.journalEntries.getAll({
2418
+ * ...parsed,
2419
+ * filters: { ...parsed.filters, organizationId },
2420
+ * });
2421
+ * ```
2422
+ */
2423
+ createQueryParser(model, overrides) {
2424
+ const paginationConfig = this.config.pagination ?? {};
2425
+ const entry = {
2426
+ account: {
2427
+ model: this.models.Account,
2428
+ pagination: paginationConfig.account
2429
+ },
2430
+ journalEntry: {
2431
+ model: this.models.JournalEntry,
2432
+ pagination: paginationConfig.journalEntry
2433
+ },
2434
+ fiscalPeriod: {
2435
+ model: this.models.FiscalPeriod,
2436
+ pagination: paginationConfig.fiscalPeriod
2437
+ },
2438
+ budget: {
2439
+ model: this.models.Budget,
2440
+ pagination: paginationConfig.budget
2441
+ },
2442
+ reconciliation: {
2443
+ model: this.models.Reconciliation,
2444
+ pagination: paginationConfig.reconciliation
2445
+ },
2446
+ journal: {
2447
+ model: this.models.Journal,
2448
+ pagination: paginationConfig.journal
2449
+ }
2450
+ }[model];
2451
+ if (!entry) throw new Error(`createQueryParser: unknown model "${model}"`);
2452
+ return new QueryParser({
2453
+ schema: entry.model.schema,
2454
+ maxLimit: entry.pagination?.maxLimit ?? 100,
2455
+ searchMode: "regex",
2456
+ ...overrides
2457
+ });
2458
+ }
2316
2459
  _buildReports() {
2317
2460
  const AccountModel = this.models.Account;
2318
2461
  const JournalEntryModel = this.models.JournalEntry;
@@ -1,4 +1,4 @@
1
- import { d as JournalType, f as MainType, h as StatementType, i as CategoryKey, o as Currency, r as Category } from "./core-BkGjuVZj.mjs";
1
+ import { d as JournalType, f as MainType, h as StatementType, i as CategoryKey, o as Currency, r as Category } from "./core-MpgjCqK0.mjs";
2
2
 
3
3
  //#region src/constants/categories.d.ts
4
4
  /** All valid categories */
@@ -0,0 +1,60 @@
1
+ //#region src/sync/builders/opening-balance.ts
2
+ function buildOpeningBalanceEntry(input) {
3
+ const { cutoverDate, balances, equityAccountCode } = input;
4
+ const dateStr = cutoverDate.toISOString().split("T")[0];
5
+ const label = input.label ?? `Opening Balance — Cutover ${dateStr}`;
6
+ const items = [];
7
+ let totalDebit = 0;
8
+ let totalCredit = 0;
9
+ for (const { accountCode, balance } of balances) {
10
+ if (balance === 0) continue;
11
+ if (balance > 0) {
12
+ items.push({
13
+ account: accountCode,
14
+ debit: balance,
15
+ credit: 0,
16
+ label: "Opening balance"
17
+ });
18
+ totalDebit += balance;
19
+ } else {
20
+ const absBalance = Math.abs(balance);
21
+ items.push({
22
+ account: accountCode,
23
+ debit: 0,
24
+ credit: absBalance,
25
+ label: "Opening balance"
26
+ });
27
+ totalCredit += absBalance;
28
+ }
29
+ }
30
+ const residual = totalDebit - totalCredit;
31
+ const lineCount = items.length;
32
+ if (residual > 0) items.push({
33
+ account: equityAccountCode,
34
+ debit: 0,
35
+ credit: residual,
36
+ label: "Opening balance equity (contra)"
37
+ });
38
+ else if (residual < 0) items.push({
39
+ account: equityAccountCode,
40
+ debit: Math.abs(residual),
41
+ credit: 0,
42
+ label: "Opening balance equity (contra)"
43
+ });
44
+ return {
45
+ entry: {
46
+ date: cutoverDate,
47
+ label,
48
+ journalType: "GENERAL",
49
+ journalItems: items,
50
+ extra: {
51
+ _externalId: `opening-balance:${dateStr}`,
52
+ _importSource: "opening-balance"
53
+ }
54
+ },
55
+ residual,
56
+ lineCount
57
+ };
58
+ }
59
+ //#endregion
60
+ export { buildOpeningBalanceEntry as t };
@@ -1,2 +1,2 @@
1
- import { S as creditLimitPlugin, _ as FxRealizationPluginOptions, a as dailyLockPlugin, b as doubleEntryPlugin, c as periodResolver, d as LockAccountSelector, f as LockHit, g as idempotencyPlugin, h as IdempotencyPluginOptions, i as FiscalLockPluginOptions, 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, x as CreditLimitPluginOptions, y as DoubleEntryPluginOptions } from "../index-Bl0_ak5w.mjs";
1
+ import { S as creditLimitPlugin, _ as FxRealizationPluginOptions, a as dailyLockPlugin, b as doubleEntryPlugin, c as periodResolver, d as LockAccountSelector, f as LockHit, g as idempotencyPlugin, h as IdempotencyPluginOptions, i as FiscalLockPluginOptions, 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, x as CreditLimitPluginOptions, y as DoubleEntryPluginOptions } from "../index-BSsvrf3m.mjs";
2
2
  export { type CreateLockPluginOptions, type CreditLimitPluginOptions, type DailyLockPluginOptions, type DoubleEntryPluginOptions, type FiscalLockPluginOptions, type FxRealizationPluginOptions, type IdempotencyPluginOptions, type LockAccountSelector, type LockHit, type LockResolver, type LockResolverContext, type PeriodResolverOptions, type WatermarkResolverOptions, createLockPlugin, creditLimitPlugin, dailyLockPlugin, doubleEntryPlugin, fiscalLockPlugin, fxRealizationPlugin, idempotencyPlugin, periodResolver, watermarkResolver };
@@ -1,2 +1,2 @@
1
- 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-CfYy1tB6.mjs";
1
+ 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-DDVK-oYO.mjs";
2
2
  export { createLockPlugin, creditLimitPlugin, dailyLockPlugin, doubleEntryPlugin, fiscalLockPlugin, fxRealizationPlugin, idempotencyPlugin, periodResolver, watermarkResolver };
@@ -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-DTc8kzTD.mjs";
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-DTj-c21f.mjs";
2
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 };