offinance-shared-core 0.1.0-alpha.3 → 0.1.0-alpha.4

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.
@@ -3,6 +3,7 @@ import type { FinanceJournalEntry, JournalDraftInput } from './contracts/Journal
3
3
  import type { FinanceOpenItemAgingQuery, FinanceOpenItemAgingSummary, FinanceOpenItemPosition, FinanceOpenItemScope } from './contracts/OpenItemContract.js';
4
4
  import type { FinanceOpenItemReconciliationInput, FinanceOpenItemReconciliationSummary } from './contracts/ReconciliationContract.js';
5
5
  import type { FinanceCashBankMovementEntry, FinanceCashBankMovementScope, FinanceCashBankMovementSummary } from './contracts/CashMovementContract.js';
6
+ import type { FinanceAuditTrailEntry, FinanceAuditTrailScope } from './contracts/AuditTrailContract.js';
6
7
  import type { FiscalPeriod, TrialBalanceRow, FinanceLedgerScope } from './contracts/FiscalContract.js';
7
8
  import type { RapbPlan, CreateRapbInput, RapbVariance } from './contracts/BudgetContract.js';
8
9
  interface LedgerAccumulator {
@@ -15,6 +16,7 @@ export interface OffinanceCoreState {
15
16
  journals: Map<string, FinanceJournalEntry>;
16
17
  balances: Map<string, LedgerAccumulator>;
17
18
  rapbPlans: Map<string, RapbPlan>;
19
+ auditTrail: FinanceAuditTrailEntry[];
18
20
  }
19
21
  export declare class OffinanceCore {
20
22
  private readonly state;
@@ -35,6 +37,7 @@ export declare class OffinanceCore {
35
37
  reconcileOpenItems(input: FinanceOpenItemReconciliationInput): FinanceOpenItemReconciliationSummary;
36
38
  listCashBankMovements(scope: FinanceCashBankMovementScope): FinanceCashBankMovementEntry[];
37
39
  summarizeCashBankMovements(scope: FinanceCashBankMovementScope): FinanceCashBankMovementSummary;
40
+ listFinancialAuditTrail(scope?: FinanceAuditTrailScope): FinanceAuditTrailEntry[];
38
41
  private assertJournalLinesKnownAccounts;
39
42
  private assertJournalPeriodOpen;
40
43
  private findPeriodByDate;
@@ -48,5 +51,7 @@ export declare class OffinanceCore {
48
51
  approvedBy: string;
49
52
  }): RapbPlan;
50
53
  evaluateVariance(rapbId: string): RapbVariance;
54
+ private recordAuditTrail;
55
+ private matchesAuditScope;
51
56
  }
52
57
  export {};
@@ -0,0 +1,27 @@
1
+ import type { ResponseEnvelope, ScopeRef } from 'ofcore';
2
+ import type { FinanceLedgerScope } from './FiscalContract.js';
3
+ export type FinanceAuditTrailEventType = 'journal_drafted' | 'journal_posted' | 'journal_reversal_posted' | 'fiscal_period_opened' | 'fiscal_period_closed' | 'rapb_created' | 'rapb_approved';
4
+ export type FinanceAuditTrailRecordType = 'journal' | 'fiscal_period' | 'rapb_plan';
5
+ export interface FinanceAuditTrailScope extends FinanceLedgerScope {
6
+ recordId?: string;
7
+ journalId?: string;
8
+ eventTypes?: FinanceAuditTrailEventType[];
9
+ }
10
+ export interface FinanceAuditTrailEntry extends ScopeRef {
11
+ id: string;
12
+ financeDomainId?: string;
13
+ ledgerProfileId?: string;
14
+ occurredAt: string;
15
+ eventType: FinanceAuditTrailEventType;
16
+ recordType: FinanceAuditTrailRecordType;
17
+ recordId: string;
18
+ journalId?: string;
19
+ sourceJournalId?: string;
20
+ reference?: string;
21
+ evidenceRef?: string;
22
+ summary: string;
23
+ metadata?: Record<string, unknown>;
24
+ }
25
+ export interface FinanceAuditTrailServiceContractV2 {
26
+ listFinancialAuditTrail(scope?: FinanceAuditTrailScope): Promise<ResponseEnvelope<FinanceAuditTrailEntry[]>>;
27
+ }
@@ -1,6 +1,8 @@
1
1
  import type { ResponseEnvelope } from 'ofcore';
2
2
  import type { FinanceLedgerScope } from './FiscalContract.js';
3
3
  export type FinanceCashBankMovementDirection = 'in' | 'out' | 'transfer_in' | 'transfer_out';
4
+ export type FinanceCashBankMovementKind = 'external' | 'internal_transfer' | 'reversal';
5
+ export type FinanceCashBankMovementLifecycleStatus = 'posted' | 'reversal_posted';
4
6
  export interface FinanceCashBankMovementScope extends FinanceLedgerScope {
5
7
  trackedAccountIds: string[];
6
8
  }
@@ -15,7 +17,11 @@ export interface FinanceCashBankMovementEntry {
15
17
  evidenceRef?: string;
16
18
  accountId: string;
17
19
  direction: FinanceCashBankMovementDirection;
20
+ movementKind: FinanceCashBankMovementKind;
21
+ lifecycleStatus: FinanceCashBankMovementLifecycleStatus;
18
22
  amount: number;
23
+ signedAmount: number;
24
+ sourceJournalId?: string;
19
25
  counterpartAccountIds: string[];
20
26
  trackedAccountIdsInJournal: string[];
21
27
  }
@@ -25,6 +31,7 @@ export interface FinanceCashBankMovementSummary {
25
31
  totalTransferIn: number;
26
32
  totalTransferOut: number;
27
33
  netExternalMovement: number;
34
+ netByTrackedAccountId: Record<string, number>;
28
35
  entries: FinanceCashBankMovementEntry[];
29
36
  }
30
37
  export interface FinanceCashBankMovementServiceContractV2 {
@@ -3,6 +3,7 @@ import type { FinanceAccountType } from './AccountContract.js';
3
3
  export interface FiscalPeriod extends ScopeRef {
4
4
  id: string;
5
5
  financeDomainId?: string;
6
+ ledgerProfileId?: string;
6
7
  code: string;
7
8
  startDate: string;
8
9
  endDate: string;
@@ -1,6 +1,8 @@
1
1
  import type { ResponseEnvelope, ScopeRef } from 'ofcore';
2
2
  import type { FinanceOpenItemScope, FinanceOpenItemType } from './OpenItemContract.js';
3
3
  export type FinanceReconciliationStatus = 'matched' | 'missing' | 'under' | 'over' | 'mismatch';
4
+ export type FinanceReconciliationLifecycleStatus = 'resolved' | 'unresolved' | 'exception' | 'writeoff_candidate';
5
+ export type FinanceReconciliationSuggestedAction = 'none' | 'collect_follow_up' | 'investigate' | 'refund_or_apply_credit' | 'write_off_review';
4
6
  export interface FinanceObservedSettlementItem {
5
7
  openItemId: string;
6
8
  openItemType?: FinanceOpenItemType;
@@ -13,6 +15,8 @@ export interface FinanceObservedSettlementItem {
13
15
  export interface FinanceOpenItemReconciliationInput extends FinanceOpenItemScope {
14
16
  observations: FinanceObservedSettlementItem[];
15
17
  toleranceAmount?: number;
18
+ asOf?: string;
19
+ writeOffPastDueDays?: number;
16
20
  }
17
21
  export interface FinanceOpenItemReconciliationRow extends ScopeRef {
18
22
  financeDomainId?: string;
@@ -27,7 +31,10 @@ export interface FinanceOpenItemReconciliationRow extends ScopeRef {
27
31
  observedAmount: number;
28
32
  varianceAmount: number;
29
33
  status: FinanceReconciliationStatus;
34
+ lifecycleStatus: FinanceReconciliationLifecycleStatus;
35
+ suggestedAction: FinanceReconciliationSuggestedAction;
30
36
  reason?: string;
37
+ pastDueDays?: number;
31
38
  observedReferences: string[];
32
39
  }
33
40
  export interface FinanceOpenItemReconciliationSummary {
@@ -35,6 +42,10 @@ export interface FinanceOpenItemReconciliationSummary {
35
42
  totalExpectedAmount: number;
36
43
  totalObservedAmount: number;
37
44
  totalVarianceAmount: number;
45
+ resolvedCount: number;
46
+ unresolvedCount: number;
47
+ exceptionCount: number;
48
+ writeoffCandidateCount: number;
38
49
  rows: FinanceOpenItemReconciliationRow[];
39
50
  }
40
51
  export interface FinanceReconciliationServiceContractV2 {
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from './contracts/OpenItemContract.js';
9
9
  export * from './contracts/ReconciliationContract.js';
10
10
  export * from './contracts/ComplianceExportContract.js';
11
11
  export * from './contracts/CashMovementContract.js';
12
+ export * from './contracts/AuditTrailContract.js';
12
13
  export * from './contracts/FiscalContract.js';
13
14
  export * from './contracts/BudgetContract.js';
14
15
  export * from './contracts/AdapterContract.js';
package/dist/index.esm.js CHANGED
@@ -1,3 +1,3 @@
1
- function P(n){if(!Array.isArray(n)||n.length===0)return{ok:!1,totalDebit:0,totalCredit:0,reason:"JOURNAL_LINES_EMPTY"};let e=0,t=0;for(let r of n){if(!r||!r.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(r.debit<0||r.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=r.debit,t+=r.credit}return Math.abs(e-t)>1e-6?{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NOT_BALANCED"}:{ok:!0,totalDebit:e,totalCredit:t}}var ue=[{key:"current",label:"Current",maxDaysPastDue:0},{key:"1-30",label:"1-30 days",minDaysPastDue:1,maxDaysPastDue:30},{key:"31-60",label:"31-60 days",minDaysPastDue:31,maxDaysPastDue:60},{key:"61-90",label:"61-90 days",minDaysPastDue:61,maxDaysPastDue:90},{key:"90+",label:"90+ days",minDaysPastDue:91}];function pe(n,e,t){return n==="receivable"?e-t:t-e}function le(n,e){return[n.tenantId??"",n.branchId??"",n.financeDomainId??"",n.ledgerProfileId??"",e.accountId,e.openItemType??"",e.openItemId??""].join("::")}function V(n){return n<0?"overpaid":Math.abs(n)<1e-6?"settled":"open"}function me(n,e){if(!e)return 0;let t=Date.parse(n)-Date.parse(e);return!Number.isFinite(t)||t<=0?0:Math.floor(t/864e5)}function Ie(n,e){return e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.openItemType&&n.openItemType!==e.openItemType||e.counterpartyRef&&n.counterpartyRef!==e.counterpartyRef||!e.includeSettled&&n.status==="settled"):!0}function O(n){for(let e of n){let t=!!(e.openItemId||e.openItemType),r=!!(e.counterpartyRef||e.documentRef||e.dueAt);if(!(!t&&!r)){if(!e.openItemId)throw new Error("JOURNAL_OPEN_ITEM_ID_REQUIRED");if(!e.openItemType)throw new Error("JOURNAL_OPEN_ITEM_TYPE_REQUIRED");if(e.openItemType!=="receivable"&&e.openItemType!=="payable")throw new Error("JOURNAL_OPEN_ITEM_TYPE_INVALID");if(e.dueAt&&Number.isNaN(Date.parse(e.dueAt)))throw new Error("JOURNAL_OPEN_ITEM_DUE_AT_INVALID")}}}function F(n,e){let t=new Map;for(let r of n)if(r.status==="posted")for(let a of r.lines){if(!a.openItemId||!a.openItemType)continue;let o=le(r,a),i=pe(a.openItemType,a.debit,a.credit),c=t.get(o);if(!c){let s={tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,openItemId:a.openItemId,openItemType:a.openItemType,accountId:a.accountId,counterpartyRef:a.counterpartyRef,documentRef:a.documentRef,dueAt:a.dueAt,originatedAt:r.occurredAt,lastActivityAt:r.occurredAt,originalAmount:i>0?i:0,settledAmount:i<0?Math.abs(i):0,outstandingAmount:i,status:V(i)};t.set(o,{item:s});continue}c.item.originatedAt=c.item.originatedAt<r.occurredAt?c.item.originatedAt:r.occurredAt,c.item.lastActivityAt=c.item.lastActivityAt>r.occurredAt?c.item.lastActivityAt:r.occurredAt,c.item.counterpartyRef=a.counterpartyRef??c.item.counterpartyRef,c.item.documentRef=a.documentRef??c.item.documentRef,c.item.dueAt=a.dueAt??c.item.dueAt,i>0?c.item.originalAmount+=i:i<0&&(c.item.settledAmount+=Math.abs(i)),c.item.outstandingAmount+=i,c.item.status=V(c.item.outstandingAmount)}return Array.from(t.values()).map(({item:r})=>({...r})).filter(r=>Ie(r,e)).sort((r,a)=>r.originatedAt!==a.originatedAt?r.originatedAt.localeCompare(a.originatedAt):r.openItemId.localeCompare(a.openItemId))}function D(n,e){if(Number.isNaN(Date.parse(e.asOf)))throw new Error("FINANCE_OPEN_ITEM_AGING_AS_OF_INVALID");let t=(e.buckets?.length?e.buckets:ue).map(a=>({...a,amount:0,itemCount:0})),r=0;for(let a of n){if(a.outstandingAmount<=0)continue;r+=a.outstandingAmount;let o=me(e.asOf,a.dueAt),i=t.find(c=>{let s=c.minDaysPastDue??Number.NEGATIVE_INFINITY,p=c.maxDaysPastDue??Number.POSITIVE_INFINITY;return o>=s&&o<=p});if(!i)throw new Error("FINANCE_OPEN_ITEM_AGING_BUCKET_UNRESOLVED");i.amount+=a.outstandingAmount,i.itemCount+=1}return{asOf:e.asOf,openItemType:e.openItemType,totalOutstanding:r,buckets:t}}function H(n,e){return`${e??""}::${n}`}function fe(n){if(!n.openItemId?.trim())throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_ID_REQUIRED");if(!Number.isFinite(n.observedAmount)||n.observedAmount<0)throw new Error("FINANCE_RECONCILIATION_OBSERVED_AMOUNT_INVALID");if(n.openItemType&&n.openItemType!=="receivable"&&n.openItemType!=="payable")throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_TYPE_INVALID")}function ge(n,e){let t=new Map;for(let r of n){fe(r);let a=r.openItemType??e,o=H(r.openItemId,a),i=t.get(o);if(!i){t.set(o,{openItemId:r.openItemId,openItemType:a,observedAmount:r.observedAmount,counterpartyRef:r.counterpartyRef,documentRef:r.documentRef,references:r.reference?[r.reference]:[]});continue}i.observedAmount+=r.observedAmount,i.counterpartyRef=r.counterpartyRef??i.counterpartyRef,i.documentRef=r.documentRef??i.documentRef,r.reference&&i.references.push(r.reference)}return t}function ye(n,e,t){let r=n.outstandingAmount,a=e?.observedAmount??0,o=a-r;if(!e)return{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:r,observedAmount:a,varianceAmount:o,status:"missing",reason:"FINANCE_RECONCILIATION_OBSERVATION_MISSING",observedReferences:[]};let i=e.counterpartyRef&&n.counterpartyRef&&e.counterpartyRef!==n.counterpartyRef||e.documentRef&&n.documentRef&&e.documentRef!==n.documentRef,c="matched",s;return i?(c="mismatch",s="FINANCE_RECONCILIATION_METADATA_MISMATCH"):Math.abs(o)<=t?c="matched":o<0?(c="under",s="FINANCE_RECONCILIATION_OBSERVED_UNDER"):o>0&&(c="over",s="FINANCE_RECONCILIATION_OBSERVED_OVER"),{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:r,observedAmount:a,varianceAmount:o,status:c,reason:s,observedReferences:[...e.references]}}function Ae(n,e){return{tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType??e.openItemType,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,expectedAmount:0,observedAmount:n.observedAmount,varianceAmount:n.observedAmount,status:"mismatch",reason:"FINANCE_RECONCILIATION_EXPECTED_ITEM_NOT_FOUND",observedReferences:[...n.references]}}function w(n,e){let t=e.toleranceAmount??0;if(!Number.isFinite(t)||t<0)throw new Error("FINANCE_RECONCILIATION_TOLERANCE_INVALID");let r=ge(e.observations,e.openItemType),a=[];for(let s of n){let p=H(s.openItemId,s.openItemType),f=r.get(p);a.push(ye(s,f,t)),r.delete(p)}for(let s of r.values())a.push(Ae(s,e));a.sort((s,p)=>(s.financeDomainId??"")!==(p.financeDomainId??"")?(s.financeDomainId??"").localeCompare(p.financeDomainId??""):(s.ledgerProfileId??"")!==(p.ledgerProfileId??"")?(s.ledgerProfileId??"").localeCompare(p.ledgerProfileId??""):s.openItemId.localeCompare(p.openItemId));let o=a.reduce((s,p)=>s+p.expectedAmount,0),i=a.reduce((s,p)=>s+p.observedAmount,0),c=a.reduce((s,p)=>s+p.varianceAmount,0);return{openItemType:e.openItemType,totalExpectedAmount:o,totalObservedAmount:i,totalVarianceAmount:c,rows:a}}function be(n){if(!Array.isArray(n.trackedAccountIds)||n.trackedAccountIds.length===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");let e=new Set(n.trackedAccountIds.map(t=>t.trim()).filter(Boolean));if(e.size===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");return e}function he(n,e){return!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt>e.occurredTo)}function _(n,e){let t=be(e),r=[];for(let a of n){if(a.status!=="posted"||!he(a,e))continue;let o=a.lines.filter(l=>t.has(l.accountId)&&(l.debit>0||l.credit>0));if(o.length===0)continue;let i=Array.from(new Set(o.map(l=>l.accountId))).sort(),c=Array.from(new Set(a.lines.filter(l=>!t.has(l.accountId)&&(l.debit>0||l.credit>0)).map(l=>l.accountId))).sort(),s=o.some(l=>l.debit>0),p=o.some(l=>l.credit>0),f=i.length>1&&s&&p;for(let l of o)l.debit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:l.accountId,direction:f?"transfer_in":"in",amount:l.debit,counterpartAccountIds:c,trackedAccountIdsInJournal:i}),l.credit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:l.accountId,direction:f?"transfer_out":"out",amount:l.credit,counterpartAccountIds:c,trackedAccountIdsInJournal:i})}return r.sort((a,o)=>a.occurredAt!==o.occurredAt?a.occurredAt.localeCompare(o.occurredAt):a.journalId!==o.journalId?a.journalId.localeCompare(o.journalId):a.accountId.localeCompare(o.accountId))}function T(n){let e=0,t=0,r=0,a=0;for(let o of n)o.direction==="in"&&(e+=o.amount),o.direction==="out"&&(t+=o.amount),o.direction==="transfer_in"&&(r+=o.amount),o.direction==="transfer_out"&&(a+=o.amount);return{totalInflow:e,totalOutflow:t,totalTransferIn:r,totalTransferOut:a,netExternalMovement:e-t,entries:n.map(o=>({...o,counterpartAccountIds:[...o.counterpartAccountIds],trackedAccountIdsInJournal:[...o.trackedAccountIdsInJournal]}))}}var N=class{constructor(e){this.state={accounts:e?.accounts??new Map,periods:e?.periods??new Map,journals:e?.journals??new Map,balances:e?.balances??new Map,rapbPlans:e?.rapbPlans??new Map}}createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");if(this.state.accounts.has(e.id))throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if(Array.from(this.state.accounts.values()).some(r=>r.code===e.code))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");return this.state.accounts.set(e.id,{...e}),{...e}}listAccounts(){return Array.from(this.state.accounts.values()).map(e=>({...e})).sort((e,t)=>e.code.localeCompare(t.code))}openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(this.state.periods.has(e.id))throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t={...e,status:"open"};return this.state.periods.set(t.id,t),{...t}}closeFiscalPeriod(e){let t=this.state.periods.get(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed"};return this.state.periods.set(e,r),{...r}}listFiscalPeriods(){return Array.from(this.state.periods.values()).map(e=>({...e})).sort((e,t)=>e.startDate.localeCompare(t.startDate))}createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(this.state.journals.has(e.id))throw new Error("JOURNAL_ALREADY_EXISTS");this.assertJournalLinesKnownAccounts(e.lines),this.assertJournalPeriodOpen(e.occurredAt),O(e.lines);let t=P(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,lines:e.lines.map(a=>({...a})),status:"draft"};return this.state.journals.set(r.id,r),{...r,lines:r.lines.map(a=>({...a}))}}postJournal(e,t=new Date().toISOString()){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status==="posted"||r.status==="reversed")return{...r,lines:r.lines.map(o=>({...o}))};this.applyLinesToBalance(r.lines);let a={...r,status:"posted",postedAt:t};return this.state.journals.set(e,a),{...a,lines:a.lines.map(o=>({...o}))}}reverseJournal(e,t){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let a=r.lines.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo,openItemId:i.openItemId,openItemType:i.openItemType,counterpartyRef:i.counterpartyRef,documentRef:i.documentRef,dueAt:i.dueAt})),o=this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a});return this.postJournal(o.id)}getTrialBalance(){return this.getTrialBalanceByScope()}getTrialBalanceByScope(e){let t=this.computeScopedBalances(e);return this.listAccounts().map(a=>{let o=t.get(a.id)??{debit:0,credit:0};return{accountId:a.id,accountCode:a.code,accountName:a.name,accountType:a.type,debit:o.debit,credit:o.credit,net:o.debit-o.credit}})}listJournals(e){return Array.from(this.state.journals.values()).filter(t=>this.matchesScope(t,e)).map(t=>({...t,lines:t.lines.map(r=>({...r}))})).sort((t,r)=>t.occurredAt.localeCompare(r.occurredAt))}listOpenItems(e){return F(this.listJournals(e),e)}getOpenItemAging(e){return D(this.listOpenItems(e),e)}reconcileOpenItems(e){return w(this.listOpenItems(e),e)}listCashBankMovements(e){return _(this.listJournals(e),e)}summarizeCashBankMovements(e){return T(this.listCashBankMovements(e))}assertJournalLinesKnownAccounts(e){for(let t of e)if(!this.state.accounts.has(t.accountId))throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}assertJournalPeriodOpen(e){if(this.state.periods.size===0)return;let t=this.findPeriodByDate(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(t.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}findPeriodByDate(e){let t=Date.parse(e);for(let r of this.state.periods.values()){let a=Date.parse(r.startDate),o=Date.parse(r.endDate);if(t>=a&&t<=o)return r}return null}applyLinesToBalance(e){for(let t of e){let r=this.state.balances.get(t.accountId)??{debit:0,credit:0};r.debit+=t.debit,r.credit+=t.credit,this.state.balances.set(t.accountId,r)}}computeScopedBalances(e){if(!e||!e.tenantId&&!e.branchId&&!e.financeDomainId&&!e.ledgerProfileId&&!e.occurredFrom&&!e.occurredTo)return this.state.balances;let t=new Map;for(let r of this.state.journals.values())if(r.status==="posted"&&this.matchesScope(r,e))for(let a of r.lines){let o=t.get(a.accountId)??{debit:0,credit:0};o.debit+=a.debit,o.credit+=a.credit,t.set(a.accountId,o)}return t}matchesScope(e,t){return t?!(t.tenantId&&e.tenantId!==t.tenantId||t.branchId&&e.branchId!==t.branchId||t.financeDomainId&&e.financeDomainId!==t.financeDomainId||t.ledgerProfileId&&e.ledgerProfileId!==t.ledgerProfileId||t.occurredFrom&&e.occurredAt<t.occurredFrom||t.occurredTo&&e.occurredAt>t.occurredTo):!0}createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(this.state.rapbPlans.has(e.id))throw new Error("RAPB_ALREADY_EXISTS");if(e.lines.some(a=>a.budgetedDebit<0||a.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=e.lines.map(a=>{let o=this.state.accounts.get(a.accountId);if(!o)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${a.accountId}`);let i=a.budgetedDebit-a.budgetedCredit;return{accountId:a.accountId,accountCode:o.code,accountName:o.name,accountType:o.type,budgetedDebit:a.budgetedDebit,budgetedCredit:a.budgetedCredit,budgetedNet:i}}),r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",lines:t,notes:e.notes,createdAt:new Date().toISOString()};return this.state.rapbPlans.set(r.id,r),r}getRapb(e){return this.state.rapbPlans.get(e)??null}listRapb(e){let t=Array.from(this.state.rapbPlans.values());return e&&(e.tenantId&&(t=t.filter(r=>r.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(r=>r.periodCode===e.periodCode)),e.branchId&&(t=t.filter(r=>r.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(r=>r.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(r=>r.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let r=this.state.rapbPlans.get(e);if(!r)throw new Error("RAPB_NOT_FOUND");let a=typeof t=="string"?t:t.approvedBy;if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...r,status:"approved",approvedAt:new Date().toISOString(),approvedBy:a};return this.state.rapbPlans.set(e,o),o}evaluateVariance(e){let t=this.state.rapbPlans.get(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=this.getTrialBalance(),a=new Map(r.map(u=>[u.accountId,u])),o=0,i=0,c=0,s=0,p=t.lines.map(u=>{let C=a.get(u.accountId),g=C?.debit??0,y=C?.credit??0,E=g-y;return u.accountType==="revenue"?(o+=u.budgetedCredit-u.budgetedDebit,i+=y-g):u.accountType==="expense"&&(c+=u.budgetedDebit-u.budgetedCredit,s+=g-y),{accountId:u.accountId,accountCode:u.accountCode,accountName:u.accountName,accountType:u.accountType,budgetedDebit:u.budgetedDebit,budgetedCredit:u.budgetedCredit,budgetedNet:u.budgetedNet,actualDebit:g,actualCredit:y,actualNet:E,varianceDebit:g-u.budgetedDebit,varianceCredit:y-u.budgetedCredit,varianceNet:E-u.budgetedNet}}),f=o-c,l=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:p,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:f,actualNetIncome:l,netVariance:l-f}}};import{CoreRuntime as Re}from"ofcore";import{InMemoryDbAdapter as Pe}from"ofcore";import{asReadonlyStore as Oe,createStore as Fe}from"ofcore";var d={accounts:"ofinance_accounts",periods:"ofinance_periods",journals:"ofinance_journals",journalLines:"ofinance_journal_lines",rapbPlans:"ofinance_rapb_plans",rapbLines:"ofinance_rapb_lines",histories:"ofinance_histories"},Se=[{name:d.accounts,columns:[{name:"id",type:"string"},{name:"code",type:"string",isIndexed:!0},{name:"name",type:"string"},{name:"type",type:"string",isIndexed:!0},{name:"currency",type:"string"},{name:"isActive",type:"boolean",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.periods,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"code",type:"string",isIndexed:!0},{name:"startDate",type:"string",isIndexed:!0},{name:"endDate",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.journals,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"occurredAt",type:"string",isIndexed:!0},{name:"reference",type:"string",isOptional:!0,isIndexed:!0},{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.journalLines,columns:[{name:"id",type:"string"},{name:"journalId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"debit",type:"number"},{name:"credit",type:"number"},{name:"memo",type:"string",isOptional:!0},{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.rapbPlans,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"periodCode",type:"string",isIndexed:!0},{name:"title",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"notes",type:"string",isOptional:!0},{name:"createdAt",type:"string",isIndexed:!0},{name:"approvedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"approvedBy",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.rapbLines,columns:[{name:"id",type:"string"},{name:"rapbId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"accountCode",type:"string",isIndexed:!0},{name:"accountName",type:"string"},{name:"accountType",type:"string",isIndexed:!0},{name:"budgetedDebit",type:"number"},{name:"budgetedCredit",type:"number"},{name:"budgetedNet",type:"number"},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.histories,columns:[{name:"id",type:"string"},{name:"tableName",type:"string",isIndexed:!0},{name:"recordId",type:"string",isIndexed:!0},{name:"action",type:"string",isIndexed:!0},{name:"changes",type:"json",isOptional:!0},{name:"timestamp",type:"string",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0}]}];function B(){return Se.map(n=>({...n,columns:n.columns.map(e=>({...e}))}))}var Q=[{toVersion:1,up:async n=>{let e=B();for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:2,up:async n=>{let e=B().filter(t=>t.name==="ofinance_rapb_plans"||t.name==="ofinance_rapb_lines");for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:3,up:async n=>{try{await n.addColumn("ofinance_journals",{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0})}catch{}}},{toVersion:4,up:async n=>{let e=[{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0}];for(let t of e)try{await n.addColumn("ofinance_journal_lines",t)}catch{}}}];var Ce={logInfo(){},logWarn(){},logError(){}};async function L(n,e=Ce){e.logInfo("[offinance] starting database migration process");let t=[...Q].sort((o,i)=>o.toVersion-i.toVersion),r=t.length>0?t[t.length-1].toVersion:0,a=await n.getSchemaVersion();if((a==null||a<0)&&(a=0),a>=r){e.logInfo(`[offinance] database already up-to-date at v${a}`);return}for(let o of t)o.toVersion>a&&(e.logInfo(`[offinance] applying migration v${o.toVersion}`),await o.up(n),await n.setSchemaVersion(o.toVersion),a=o.toVersion);e.logInfo(`[offinance] migration completed at v${a}`)}function m(n,e){return{data:n,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function q(n,e,t={}){return{error:{code:n,message:e,details:t.details,retryable:t.retryable,correlationId:t.correlationId,timestamp:new Date().toISOString()},meta:{request_id:t.requestId??null,timestamp:new Date().toISOString()}}}function I(n,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return n instanceof Error?q(e,n.message||t):q(e,t)}var J=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return m(await this.legacy.accountService.createAccount(t))}catch(r){return I(r)}},listAccounts:async()=>{try{return m(await this.legacy.accountService.listAccounts())}catch(t){return I(t)}}},this.journalService={createJournalDraft:async t=>{try{return m(await this.legacy.journalService.createJournalDraft(t))}catch(r){return I(r)}},postJournal:async(t,r)=>{try{return m(await this.legacy.journalService.postJournal(t,r))}catch(a){return I(a)}},reverseJournal:async(t,r)=>{try{return m(await this.legacy.journalService.reverseJournal(t,r))}catch(a){return I(a)}},listJournals:async t=>{try{return m(await this.legacy.journalService.listJournals(t))}catch(r){return I(r)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return m(await this.legacy.fiscalService.openFiscalPeriod(t))}catch(r){return I(r)}},closeFiscalPeriod:async t=>{try{return m(await this.legacy.fiscalService.closeFiscalPeriod(t))}catch(r){return I(r)}},listFiscalPeriods:async()=>{try{return m(await this.legacy.fiscalService.listFiscalPeriods())}catch(t){return I(t)}},getTrialBalance:async()=>{try{return m(await this.legacy.fiscalService.getTrialBalance())}catch(t){return I(t)}},getTrialBalanceByScope:async t=>{try{return m(await this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(r){return I(r)}}},this.rapbService={createRapb:async t=>{try{return m(await this.legacy.rapbService.createRapb(t))}catch(r){return I(r)}},getRapb:async t=>{try{return m(await this.legacy.rapbService.getRapb(t))}catch(r){return I(r)}},listRapb:async t=>{try{return m(await this.legacy.rapbService.listRapb(t))}catch(r){return I(r)}},approveRapb:async(t,r)=>{try{return m(await this.legacy.rapbService.approveRapb(t,r))}catch(a){return I(a)}},evaluateVariance:async t=>{try{return m(await this.legacy.rapbService.evaluateVariance(t))}catch(r){return I(r)}}},this.openItemService={listOpenItems:async t=>{try{return m(await this.legacy.openItemService.listOpenItems(t))}catch(r){return I(r)}},getOpenItemAging:async t=>{try{return m(await this.legacy.openItemService.getOpenItemAging(t))}catch(r){return I(r)}}},this.reconciliationService={reconcileOpenItems:async t=>{try{return m(await this.legacy.reconciliationService.reconcileOpenItems(t))}catch(r){return I(r)}}},this.cashMovementService={listCashBankMovements:async t=>{try{return m(await this.legacy.cashMovementService.listCashBankMovements(t))}catch(r){return I(r)}},summarizeCashBankMovements:async t=>{try{return m(await this.legacy.cashMovementService.summarizeCashBankMovements(t))}catch(r){return I(r)}}}}};function $(n){return new J({accountService:n,journalService:n,fiscalService:n,rapbService:n,openItemService:n,reconciliationService:n,cashMovementService:n})}function b(n){return JSON.parse(JSON.stringify(n))}function A(){return new Date().toISOString()}function Ee(n,e){return`${n}:${e}:${Date.now()}:${Math.random().toString(36).slice(2,8)}`}function ve(n,e){return!n||n.deleted?!1:e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt&&n.occurredAt>e.occurredTo):!0}var x=class{constructor(e){this.dbAdapter=e}async createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");let t=await this.dbAdapter.get(d.accounts,e.id);if(t&&!t.deleted)throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if((await this.dbAdapter.query(d.accounts,{filters:{and:[{field:"code",value:e.code},{field:"deleted",value:!1}]}})).some(i=>i.id!==e.id))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");let a=A(),o={...b(e),lastModified:a,deleted:!1};return t?await this.dbAdapter.update(d.accounts,e.id,o):await this.dbAdapter.create(d.accounts,o),await this.writeHistory("accounts",e.id,"UPSERT",o),b(e)}async listAccounts(){return(await this.dbAdapter.query(d.accounts,{filters:{field:"deleted",value:!1}})).map(({lastModified:t,deleted:r,...a})=>b(a)).sort((t,r)=>t.code.localeCompare(r.code))}async createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(!e.ledgerProfileId)throw new Error("JOURNAL_REQUIRED_FIELDS");let t=await this.dbAdapter.get(d.journals,e.id);if(t&&!t.deleted)throw new Error("JOURNAL_ALREADY_EXISTS");await this.assertJournalLinesKnownAccounts(e.lines),await this.assertJournalPeriodOpen(e),O(e.lines);let r=P(e.lines);if(!r.ok)throw new Error(r.reason??"JOURNAL_INVALID");let a=A(),o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,status:"draft",postedAt:void 0,lastModified:a,deleted:!1};await this.dbAdapter.create(d.journals,o);for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s={id:`${e.id}:line:${i}`,journalId:e.id,accountId:c.accountId,debit:c.debit,credit:c.credit,memo:c.memo,openItemId:c.openItemId,openItemType:c.openItemType,counterpartyRef:c.counterpartyRef,documentRef:c.documentRef,dueAt:c.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:a,deleted:!1};await this.dbAdapter.create(d.journalLines,s),await this.writeHistory("journal_lines",s.id,"UPSERT",s)}return await this.writeHistory("journals",e.id,"UPSERT",o),this.toJournalEntry(o,e.lines)}async postJournal(e,t=A()){let r=await this.requireJournal(e),a=await this.listJournalLines(e);if(r.status==="posted"||r.status==="reversed")return this.toJournalEntry(r,a);let o={...r,status:"posted",postedAt:t,lastModified:A()};return await this.dbAdapter.update(d.journals,e,o),await this.writeHistory("journals",e,"UPSERT",o),this.toJournalEntry(o,a)}async reverseJournal(e,t){let r=await this.requireJournal(e);if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");let a=await this.listJournalLines(e),o=await this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo,openItemId:i.openItemId,openItemType:i.openItemType,counterpartyRef:i.counterpartyRef,documentRef:i.documentRef,dueAt:i.dueAt}))});return this.postJournal(o.id)}async listJournals(e){let r=(await this.dbAdapter.query(d.journals,{filters:{field:"deleted",value:!1}})).filter(o=>ve(o,e)).sort((o,i)=>o.occurredAt.localeCompare(i.occurredAt)),a=[];for(let o of r){let i=await this.listJournalLines(o.id);a.push(this.toJournalEntry(o,i))}return a}async listOpenItems(e){return F(await this.listJournals(e),e)}async getOpenItemAging(e){return D(await this.listOpenItems(e),e)}async reconcileOpenItems(e){return w(await this.listOpenItems(e),e)}async listCashBankMovements(e){return _(await this.listJournals(e),e)}async summarizeCashBankMovements(e){return T(await this.listCashBankMovements(e))}async openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t=await this.dbAdapter.get(d.periods,e.id);if(t&&!t.deleted)throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");let r=A(),a={...b(e),status:"open",lastModified:r,deleted:!1};return t?await this.dbAdapter.update(d.periods,e.id,a):await this.dbAdapter.create(d.periods,a),await this.writeHistory("periods",e.id,"UPSERT",a),this.toPeriod(a)}async closeFiscalPeriod(e){let t=await this.dbAdapter.get(d.periods,e);if(!t||t.deleted)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed",lastModified:A()};return await this.dbAdapter.update(d.periods,e,r),await this.writeHistory("periods",e,"UPSERT",r),this.toPeriod(r)}async listFiscalPeriods(){return(await this.dbAdapter.query(d.periods,{filters:{field:"deleted",value:!1}})).map(t=>this.toPeriod(t)).sort((t,r)=>t.startDate.localeCompare(r.startDate))}async getTrialBalance(){return this.getTrialBalanceByScope()}async getTrialBalanceByScope(e){let t=await this.listAccounts(),a=(await this.listJournals(e)).filter(i=>i.status==="posted"),o=new Map;for(let i of a)for(let c of i.lines){let s=o.get(c.accountId)??{debit:0,credit:0};s.debit+=Number(c.debit||0),s.credit+=Number(c.credit||0),o.set(c.accountId,s)}return t.map(i=>{let c=o.get(i.id)??{debit:0,credit:0};return{accountId:i.id,accountCode:i.code,accountName:i.name,accountType:i.type,debit:c.debit,credit:c.credit,net:c.debit-c.credit}})}async createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(e.lines.some(i=>i.budgetedDebit<0||i.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=await this.dbAdapter.get(d.rapbPlans,e.id);if(t&&!t.deleted)throw new Error("RAPB_ALREADY_EXISTS");let r=A(),a=[];for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s=await this.dbAdapter.get(d.accounts,c.accountId);if(!s||s.deleted)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${c.accountId}`);a.push({id:`${e.id}:line:${i}`,rapbId:e.id,accountId:c.accountId,accountCode:s.code,accountName:s.name,accountType:s.type,budgetedDebit:c.budgetedDebit,budgetedCredit:c.budgetedCredit,budgetedNet:c.budgetedDebit-c.budgetedCredit,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:r,deleted:!1})}let o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",notes:e.notes,createdAt:r,approvedAt:void 0,approvedBy:void 0,lastModified:r,deleted:!1};await this.dbAdapter.create(d.rapbPlans,o),await this.writeHistory("rapb_plans",e.id,"UPSERT",o);for(let i of a)await this.dbAdapter.create(d.rapbLines,i),await this.writeHistory("rapb_lines",i.id,"UPSERT",i);return this.toRapbPlan(o,a)}async getRapb(e){let t=await this.dbAdapter.get(d.rapbPlans,e);if(!t||t.deleted)return null;let r=await this.listRapbLines(e);return this.toRapbPlan(t,r)}async listRapb(e){let r=await this.dbAdapter.query(d.rapbPlans,{filters:{field:"deleted",value:!1}});e&&(e.tenantId&&(r=r.filter(o=>o.tenantId===e.tenantId)),e.periodCode&&(r=r.filter(o=>o.periodCode===e.periodCode)),e.branchId&&(r=r.filter(o=>o.branchId===e.branchId)),e.financeDomainId&&(r=r.filter(o=>o.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(r=r.filter(o=>o.ledgerProfileId===e.ledgerProfileId)));let a=[];for(let o of r.sort((i,c)=>i.createdAt.localeCompare(c.createdAt))){let i=await this.listRapbLines(o.id);a.push(this.toRapbPlan(o,i))}return a}async approveRapb(e,t){let r=await this.dbAdapter.get(d.rapbPlans,e);if(!r||r.deleted)throw new Error("RAPB_NOT_FOUND");if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let a=typeof t=="string"?t:t.approvedBy,o={...r,status:"approved",approvedAt:A(),approvedBy:a,lastModified:A()};await this.dbAdapter.update(d.rapbPlans,e,o),await this.writeHistory("rapb_plans",e,"UPSERT",o);let i=await this.listRapbLines(e);return this.toRapbPlan(o,i)}async evaluateVariance(e){let t=await this.getRapb(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=await this.getTrialBalanceByScope({tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId}),a=new Map(r.map(u=>[u.accountId,u])),o=0,i=0,c=0,s=0,p=t.lines.map(u=>{let C=a.get(u.accountId),g=C?.debit??0,y=C?.credit??0,E=g-y;return u.accountType==="revenue"?(o+=u.budgetedCredit-u.budgetedDebit,i+=y-g):u.accountType==="expense"&&(c+=u.budgetedDebit-u.budgetedCredit,s+=g-y),{accountId:u.accountId,accountCode:u.accountCode,accountName:u.accountName,accountType:u.accountType,budgetedDebit:u.budgetedDebit,budgetedCredit:u.budgetedCredit,budgetedNet:u.budgetedNet,actualDebit:g,actualCredit:y,actualNet:E,varianceDebit:g-u.budgetedDebit,varianceCredit:y-u.budgetedCredit,varianceNet:E-u.budgetedNet}}),f=o-c,l=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:A(),lines:p,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:f,actualNetIncome:l,netVariance:l-f}}async assertJournalLinesKnownAccounts(e){for(let t of e){let r=await this.dbAdapter.get(d.accounts,t.accountId);if(!r||r.deleted)throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}}async assertJournalPeriodOpen(e){let t=await this.dbAdapter.query(d.periods,{filters:{field:"deleted",value:!1}});if(t.length===0)return;let r=t.find(a=>!(a.tenantId!==e.tenantId||Date.parse(a.startDate)>Date.parse(e.occurredAt)||Date.parse(a.endDate)<Date.parse(e.occurredAt)||e.ledgerProfileId&&a.ledgerProfileId&&a.ledgerProfileId!==e.ledgerProfileId||e.financeDomainId&&a.financeDomainId&&a.financeDomainId!==e.financeDomainId));if(!r)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(r.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}async requireJournal(e){let t=await this.dbAdapter.get(d.journals,e);if(!t||t.deleted)throw new Error("JOURNAL_NOT_FOUND");return t}async listJournalLines(e){return(await this.dbAdapter.query(d.journalLines,{filters:{and:[{field:"journalId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}async listRapbLines(e){return(await this.dbAdapter.query(d.rapbLines,{filters:{and:[{field:"rapbId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}toJournalEntry(e,t){let{lastModified:r,deleted:a,...o}=e;return{...b(o),lines:t.map(i=>b(i))}}toPeriod(e){let{lastModified:t,deleted:r,...a}=e;return b(a)}toRapbPlan(e,t){let{lastModified:r,deleted:a,...o}=e;return{...b(o),lines:t.map(({id:i,rapbId:c,lastModified:s,deleted:p,...f})=>b(f))}}async writeHistory(e,t,r,a){let o=a,i={id:Ee(e,t),tableName:e,recordId:t,action:r,changes:b(o),timestamp:A(),tenantId:typeof o.tenantId=="string"?o.tenantId:void 0,branchId:typeof o.branchId=="string"?o.branchId:void 0,financeDomainId:typeof o.financeDomainId=="string"?o.financeDomainId:void 0,ledgerProfileId:typeof o.ledgerProfileId=="string"?o.ledgerProfileId:void 0};await this.dbAdapter.create(d.histories,i)}};async function G(n){await L(n);let e=new x(n);return{financeService:$({createAccount:e.createAccount.bind(e),listAccounts:e.listAccounts.bind(e),createJournalDraft:e.createJournalDraft.bind(e),postJournal:e.postJournal.bind(e),reverseJournal:e.reverseJournal.bind(e),listJournals:e.listJournals.bind(e),openFiscalPeriod:e.openFiscalPeriod.bind(e),closeFiscalPeriod:e.closeFiscalPeriod.bind(e),listFiscalPeriods:e.listFiscalPeriods.bind(e),getTrialBalance:e.getTrialBalance.bind(e),getTrialBalanceByScope:e.getTrialBalanceByScope.bind(e),createRapb:e.createRapb.bind(e),getRapb:e.getRapb.bind(e),listRapb:e.listRapb.bind(e),approveRapb:e.approveRapb.bind(e),evaluateVariance:e.evaluateVariance.bind(e),listOpenItems:e.listOpenItems.bind(e),getOpenItemAging:e.getOpenItemAging.bind(e),reconcileOpenItems:e.reconcileOpenItems.bind(e),listCashBankMovements:e.listCashBankMovements.bind(e),summarizeCashBankMovements:e.summarizeCashBankMovements.bind(e)})}}var k=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=Oe(this.runtimeStateStore)}static builder(){return new j}get registry(){return this.runtime.registry}async start(e={}){this.runtimeStateStore.setState({phase:"starting",started:!1,lastError:null,lastTransitionAt:new Date().toISOString(),startCount:this.runtimeStateStore.getState().startCount,stopCount:this.runtimeStateStore.getState().stopCount});try{await this.runtime.start(e),this.domainServices=this.runtime.domainServices,this.runtimeStateStore.setState(t=>({...t,phase:"started",started:!0,startCount:t.startCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(t){throw this.runtimeStateStore.setState(r=>({...r,phase:"error",started:!1,lastError:t instanceof Error?t.message:String(t),lastTransitionAt:new Date().toISOString()})),t}}async stop(){this.runtimeStateStore.setState(e=>({...e,phase:"stopping",started:this.runtime.isStarted(),lastError:null,lastTransitionAt:new Date().toISOString()}));try{await this.runtime.stop(),this.runtimeStateStore.setState(e=>({...e,phase:"stopped",started:!1,stopCount:e.stopCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(e){throw this.runtimeStateStore.setState(t=>({...t,phase:"error",started:this.runtime.isStarted(),lastError:e instanceof Error?e.message:String(e),lastTransitionAt:new Date().toISOString()})),e}}isStarted(){return this.runtime.isStarted()}},j=class{constructor(){this.runtimeBuilder=Re.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new Pe)}withPlatformAdapter(e){return this.runtimeBuilder.withPlatformAdapter(e),this}withDbAdapter(e){return this.runtimeBuilder.withDbAdapter(e),this}withHttpAdapter(e){return this.runtimeBuilder.withHttpAdapter(e),this}withSocketAdapter(e){return this.runtimeBuilder.withSocketAdapter(e),this}withLoggerAdapter(e){return this.runtimeBuilder.withLoggerAdapter(e),this}withActivitySink(e){return this.runtimeBuilder.withActivitySink(e),this}withExtension(e,t){return this.runtimeBuilder.withExtension(e,t),this}withDomainServicesFactory(e){return this.domainServicesFactory=e,this}withRuntimeHooks(e){return this.runtimeHooks={...this.runtimeHooks,...e},this}build(){let e=Fe({phase:"idle",started:!1,startCount:0,stopCount:0,lastError:null,lastTransitionAt:new Date().toISOString()}),t={runMigrations:async a=>{let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");await L(o,a.registry?.loggerAdapter),this.runtimeHooks.runMigrations&&await this.runtimeHooks.runMigrations(a)},...this.runtimeHooks,createDomainServices:async a=>{if(this.domainServicesFactory)return this.domainServicesFactory();let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");return G(o)}};this.runtimeBuilder.withHooks(t);let r=this.runtimeBuilder.build();return new k(r,e)}};function Y(n){return!Array.isArray(n.components)||n.components.length===0?[]:n.components.map(e=>{if(!e.accountId?.trim())throw new Error("FINANCE_TAX_ACCOUNT_REQUIRED");if(!Number.isFinite(e.amount)||e.amount<=0)throw new Error("FINANCE_TAX_AMOUNT_INVALID");if(e.direction!=="payable"&&e.direction!=="receivable")throw new Error("FINANCE_TAX_DIRECTION_INVALID");let t=`${n.memoPrefix??"Finance tax"} ${e.direction}`;return{accountId:e.accountId,debit:e.direction==="receivable"?e.amount:0,credit:e.direction==="payable"?e.amount:0,memo:e.memo??t}})}function h(n,e,t){return{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:t?`${n.reference??""}${t}`:n.reference,evidenceRef:n.evidenceRef,lines:e}}function S(n,e){if(!Number.isFinite(n)||n<=0)throw new Error(e)}function z(n,e){S(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,r=e.taxAmount??0;if(t<0||r<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let a=e.grossAmount,o=a-t+r,i=[{accountId:e.paymentAccountId,debit:o,credit:0,memo:"POS sale payment"},{accountId:e.revenueAccountId,debit:0,credit:a,memo:"POS sale revenue"}];if(t>0){if(!e.discountAccountId)throw new Error("POS_SALE_DISCOUNT_ACCOUNT_REQUIRED");i.push({accountId:e.discountAccountId,debit:t,credit:0,memo:"POS sale discount"})}if(r>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");i.push(...Y({memoPrefix:"POS sale tax",components:[{accountId:e.taxPayableAccountId,amount:r,direction:"payable",memo:"POS sale tax payable"}]}))}return h(n,i)}function W(n,e){return S(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),h(n,[{accountId:e.receivableAccountId,debit:e.principalAmount,credit:0,memo:"Loan receivable principal"},{accountId:e.cashAccountId,debit:0,credit:e.principalAmount,memo:"Loan cash out"}])}function X(n,e){return S(e.amount,"COOP_SAVING_INVALID_AMOUNT"),h(n,[{accountId:e.cashAccountId,debit:e.amount,credit:0,memo:"Saving deposit cash in"},{accountId:e.savingLiabilityAccountId,debit:0,credit:e.amount,memo:"Saving liability increase"}])}function K(n,e){return S(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),h(n,[{accountId:e.savingLiabilityAccountId,debit:e.amount,credit:0,memo:"Saving liability decrease"},{accountId:e.cashAccountId,debit:0,credit:e.amount,memo:"Saving withdrawal cash out"}])}function Z(n,e){S(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,r=e.penaltyAmount??0;if(t<0||r<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(r>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let a=e.principalAmount+t+r,o=[{accountId:e.cashAccountId,debit:a,credit:0,memo:"Loan repayment cash in"},{accountId:e.receivableAccountId,debit:0,credit:e.principalAmount,memo:"Loan receivable principal repayment"}];return t>0&&o.push({accountId:e.serviceRevenueAccountId,debit:0,credit:t,memo:"Loan service revenue"}),r>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:r,memo:"Loan penalty revenue"}),h(n,o)}function vn(n,e){if(S(e.amount,"COOP_SHU_PARTICIPATION_INVALID_AMOUNT"),!n.evidenceRef?.trim())throw new Error("COOP_SHU_PARTICIPATION_EVIDENCE_REQUIRED");return h(n,[{accountId:e.debitAccountId,debit:e.amount,credit:0,memo:e.memo??"Coop SHU participation manual recap debit"},{accountId:e.creditAccountId,debit:0,credit:e.amount,memo:e.memo??"Coop SHU participation manual recap credit"}])}function ee(n,e){return e?{...n,...e}:{...n}}function v(n){let e=n.tenantId?n.scopedMapping.byTenant?.[n.tenantId]:void 0,t=n.tenantId&&n.branchId?`${n.tenantId}:${n.branchId}`:"",r=t?n.scopedMapping.byBranch?.[t]:void 0;return ee(ee(n.scopedMapping.default,e),r)}function ne(n){return v(n)}function te(n){return v(n)}function re(n){return v(n)}function ae(n){return v(n)}function oe(n){return v(n)}function Dn(n,e){let{scopedAccountMapping:t,...r}=e,a=ne({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return z(n,{...r,...a})}function wn(n,e){let{scopedAccountMapping:t,...r}=e,a=te({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return W(n,{...r,...a})}function _n(n,e){let{scopedAccountMapping:t,...r}=e,a=ae({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return X(n,{...r,...a})}function Tn(n,e){let{scopedAccountMapping:t,...r}=e,a=oe({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return K(n,{...r,...a})}function Nn(n,e){let{scopedAccountMapping:t,...r}=e,a=re({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return Z(n,{...r,...a})}function M(n){return!!(n&&typeof n=="object"&&n.error)}function U(n){return n.startsWith("ofinance_")?`offinance_${n.slice(9)}`:n}async function De(n,e,t){let r=await n.accountService.listAccounts();if(M(r))throw new Error(r.error.message||r.error.code||"FINANCE_ACCOUNT_LIST_FAILED");let a=new Set((r.data||[]).map(o=>o.id));for(let o of e){if(a.has(o.id))continue;let i=await n.accountService.createAccount(o);if(M(i))throw new Error(i.error.message||i.error.code||"FINANCE_ACCOUNT_CREATE_FAILED");await t?.({changeId:`offinance:account:${o.id}`,entity:"FinanceAccount",table:U(d.accounts),type:"CREATE",data:o})}}async function ie(n,e,t){return n.query(e,{filters:{and:t}})}async function we(n,e,t){if(!t)return;let r=await ie(n,d.journals,[{field:"id",value:e.id}]),a=await ie(n,d.journalLines,[{field:"journalId",value:e.id}]);r.length===0&&(r=[{id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,status:e.status,postedAt:e.postedAt,lastModified:e.postedAt||e.occurredAt,deleted:!1}]),a.length===0&&(a=e.lines.map((o,i)=>({id:`${e.id}:line:${i}`,journalId:e.id,accountId:o.accountId,debit:o.debit,credit:o.credit,memo:o.memo,openItemId:o.openItemId,openItemType:o.openItemType,counterpartyRef:o.counterpartyRef,documentRef:o.documentRef,dueAt:o.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:e.postedAt||e.occurredAt,deleted:!1})));for(let o of r)await t({changeId:`offinance:journal:${o.id}`,entity:"FinanceJournalEntry",table:U(d.journals),type:"CREATE",data:o});for(let o of a)await t({changeId:`offinance:journal-line:${o.id}`,entity:"FinanceJournalLine",table:U(d.journalLines),type:"CREATE",data:o})}function Mn(n){return async e=>{let t=n.resolveFinanceServices();if(!t)throw new Error(n.missingServicesErrorCode||"FINANCE_SERVICES_UNAVAILABLE");let r=n.resolveLedgerProfileId().trim();if(!r)throw new Error(n.missingLedgerProfileErrorCode||"FINANCE_LEDGER_PROFILE_REQUIRED");let a=n.resolveSyncEnqueuer?.()??null;await De(t,n.requiredAccounts,a);let o=n.buildJournalDraft(e,r),i=await t.journalService.createJournalDraft(o);if(M(i)&&i.error.code!=="JOURNAL_ALREADY_EXISTS")throw new Error(i.error.message||i.error.code||"FINANCE_JOURNAL_CREATE_FAILED");let c=await t.journalService.postJournal(o.id,o.occurredAt);if(M(c))throw new Error(c.error.message||c.error.code||"FINANCE_JOURNAL_POST_FAILED");await we(n.dbAdapter,c.data,a)}}function _e(n){switch(n.accountType){case"asset":case"expense":return n.debit-n.credit;case"liability":case"equity":case"revenue":return n.credit-n.debit;default:return 0}}function R(n,e){return n.filter(t=>t.accountType===e).reduce((t,r)=>t+_e(r),0)}function Jn(n){let e=R(n,"revenue"),t=R(n,"expense");return{revenue:e,expense:t,netIncome:e-t}}function kn(n){return{assets:R(n,"asset"),liabilities:R(n,"liability"),equity:R(n,"equity")}}function ce(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function Un(n){let e=n.filter(r=>r.accountType==="revenue").reduce((r,a)=>r+Math.max(0,ce(a)),0),t=n.filter(r=>r.accountType==="expense").reduce((r,a)=>r+Math.max(0,ce(a)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function Vn(n,e){let t=[],r=0;for(let a of e){if(a.accountType==="revenue"){let o=a.credit-a.debit;o>0&&(t.push({accountId:a.accountId,debit:o,credit:0,memo:"Close revenue account"}),r+=o)}if(a.accountType==="expense"){let o=a.debit-a.credit;o>0&&(t.push({accountId:a.accountId,debit:0,credit:o,memo:"Close expense account"}),r-=o)}}return r>0?t.push({accountId:n.retainedEarningsAccountId,debit:0,credit:r,memo:"Retained earnings from period close"}):r<0&&t.push({accountId:n.retainedEarningsAccountId,debit:Math.abs(r),credit:0,memo:"Retained earnings from period close"}),{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:n.reference,lines:t}}function Te(n){return Array.isArray(n)?n.length:n&&typeof n=="object"?1:n===null||typeof n>"u"?0:1}function Ne(n){return n==="json"?"application/json":"text/csv"}function Le(n,e){if(n==="json")return`${JSON.stringify(e,null,2)}
2
- `;if(typeof e!="string")throw new Error("FINANCE_COMPLIANCE_EXPORT_CSV_PAYLOAD_STRING_REQUIRED");return e}function xe(n){let e=2166136261;for(let t=0;t<n.length;t+=1)e^=n.charCodeAt(t),e=Math.imul(e,16777619);return`fnv1a32-${(e>>>0).toString(16).padStart(8,"0")}`}function Me(n){if(!n.key?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_REQUIRED");if(!n.fileName?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_FILE_NAME_REQUIRED");if(n.format!=="json"&&n.format!=="csv")throw new Error("FINANCE_COMPLIANCE_EXPORT_FORMAT_INVALID")}function Be(n){return n??"custom"}function se(n){if(!Array.isArray(n.datasets)||n.datasets.length===0)throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASETS_REQUIRED");let e=new Set,t={},r=[];for(let o of n.datasets){if(Me(o),e.has(o.key))throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_DUPLICATE");e.add(o.key);let i=Le(o.format,o.payload);t[o.fileName]=i,r.push({key:o.key,fileName:o.fileName,format:o.format,semantic:Be(o.semantic),contentType:o.contentType??Ne(o.format),recordCount:Te(o.payload),checksum:xe(i)})}return{contract:{contractVersion:"fcx-v1",tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt??new Date().toISOString(),period:{from:n.period?.from??null,to:n.period?.to??null,label:n.period?.label??null},currency:{baseCurrencyCode:n.baseCurrencyCode??"IDR"},datasets:r,summary:{datasetCount:r.length,totalRecordCount:r.reduce((o,i)=>o+i.recordCount,0)}},files:t}}function $n(n){return{version:"v1",generatedAt:n.generatedAt??new Date().toISOString(),payload:{trialBalance:n.trialBalance.map(e=>({...e})),incomeStatement:{...n.incomeStatement},balanceSheet:{...n.balanceSheet}}}}function Gn(n){let e=[{key:"trial-balance",fileName:"trial_balance.json",format:"json",semantic:"trial_balance",payload:n.trialBalance},{key:"income-statement",fileName:"income_statement.json",format:"json",semantic:"income_statement",payload:n.incomeStatement},{key:"balance-sheet",fileName:"balance_sheet.json",format:"json",semantic:"balance_sheet",payload:n.balanceSheet}];return typeof n.openItems<"u"&&e.push({key:"open-items",fileName:"open_items.json",format:"json",semantic:"open_items",payload:n.openItems}),typeof n.agingSummary<"u"&&e.push({key:"aging-summary",fileName:"aging_summary.json",format:"json",semantic:"aging_summary",payload:n.agingSummary}),typeof n.reconciliationSummary<"u"&&e.push({key:"reconciliation-summary",fileName:"reconciliation_summary.json",format:"json",semantic:"reconciliation",payload:n.reconciliationSummary}),typeof n.cashMovements<"u"&&e.push({key:"cash-movements",fileName:"cash_movements.json",format:"json",semantic:"cash_movements",payload:n.cashMovements}),se({tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt,period:n.period,baseCurrencyCode:n.baseCurrencyCode,datasets:e})}function Je(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function de(n,e){return e===0?n===0?1:0:Number((n/e).toFixed(4))}function zn(n,e){let t=e.map(a=>{let c=((a.accountCodes?.length?n.filter(p=>a.accountCodes?.includes(p.accountCode)):null)??n.filter(p=>a.accountType?p.accountType===a.accountType:!1)).reduce((p,f)=>p+Je(f),0),s=c-a.plannedAmount;return{id:a.id,label:a.label,plannedAmount:a.plannedAmount,actualAmount:c,varianceAmount:s,achievementRatio:de(c,a.plannedAmount)}}),r=t.reduce((a,o)=>(a.plannedAmount+=o.plannedAmount,a.actualAmount+=o.actualAmount,a.varianceAmount+=o.varianceAmount,a),{plannedAmount:0,actualAmount:0,varianceAmount:0});return{rows:t,totals:{...r,achievementRatio:de(r.actualAmount,r.plannedAmount)}}}function ke(n,e){switch(e.type){case"finance.account.created":n.createAccount(e.payload);return;case"finance.period.opened":n.openFiscalPeriod(e.payload);return;case"finance.period.closed":n.closeFiscalPeriod(e.payload.periodId);return;case"finance.journal.drafted":n.createJournalDraft(e.payload);return;case"finance.journal.posted":n.postJournal(e.payload.journalId,e.payload.postedAt);return;case"finance.journal.reversed":n.reverseJournal(e.payload.journalId,e.payload.reversalId);return;default:throw new Error("FINANCE_EVENT_UNSUPPORTED")}}function Kn(n){let e=new N;for(let t of n)ke(e,t);return e}var je=[{id:"coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coa-ar",code:"1201",name:"Piutang Usaha",type:"asset"},{id:"coa-ap",code:"2101",name:"Utang Usaha",type:"liability"},{id:"coa-retained",code:"3201",name:"Laba Ditahan",type:"equity"},{id:"coa-revenue",code:"4101",name:"Pendapatan Operasional",type:"revenue"},{id:"coa-expense",code:"5101",name:"Biaya Operasional",type:"expense"}];function et(n="IDR"){return je.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}var Ue=[{id:"coop-coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coop-coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coop-coa-loan-ar",code:"1201",name:"Piutang Pinjaman Anggota",type:"asset"},{id:"coop-coa-other-ar",code:"1202",name:"Piutang Lain-lain",type:"asset"},{id:"coop-coa-prepaid",code:"1301",name:"Biaya Dibayar Dimuka",type:"asset"},{id:"coop-coa-fixed-asset",code:"1401",name:"Aset Tetap",type:"asset"},{id:"coop-coa-accum-depr",code:"1402",name:"Akumulasi Penyusutan",type:"asset"},{id:"coop-coa-simp-pokok",code:"2101",name:"Simpanan Pokok",type:"liability"},{id:"coop-coa-simp-wajib",code:"2102",name:"Simpanan Wajib",type:"liability"},{id:"coop-coa-simp-sukarela",code:"2103",name:"Simpanan Sukarela",type:"liability"},{id:"coop-coa-simp-berjangka",code:"2104",name:"Simpanan Berjangka",type:"liability"},{id:"coop-coa-ap",code:"2201",name:"Utang Usaha",type:"liability"},{id:"coop-coa-ext-loan",code:"2301",name:"Pinjaman Luar",type:"liability"},{id:"coop-coa-tax-payable",code:"2401",name:"Utang Pajak",type:"liability"},{id:"coop-coa-modal-awal",code:"3101",name:"Modal Awal",type:"equity"},{id:"coop-coa-cadangan-umum",code:"3201",name:"Dana Cadangan Umum",type:"equity"},{id:"coop-coa-cadangan-tujuan",code:"3202",name:"Dana Cadangan Tujuan",type:"equity"},{id:"coop-coa-shu-prior",code:"3301",name:"SHU Tahun Lalu",type:"equity"},{id:"coop-coa-shu-current",code:"3302",name:"SHU Berjalan",type:"equity"},{id:"coop-coa-shu-reserve",code:"3303",name:"Dana SHU Belum Dibagi",type:"equity"},{id:"coop-coa-jasa-pinjaman",code:"4101",name:"Pendapatan Jasa Pinjaman",type:"revenue"},{id:"coop-coa-provisi",code:"4102",name:"Pendapatan Provisi",type:"revenue"},{id:"coop-coa-rev-other",code:"4103",name:"Pendapatan Lain-lain",type:"revenue"},{id:"coop-coa-beban-bunga",code:"5101",name:"Beban Bunga Simpanan",type:"expense"},{id:"coop-coa-beban-ops",code:"5102",name:"Beban Operasional",type:"expense"},{id:"coop-coa-beban-gaji",code:"5103",name:"Beban Gaji dan Tunjangan",type:"expense"},{id:"coop-coa-beban-admin",code:"5104",name:"Beban Administrasi",type:"expense"},{id:"coop-coa-beban-depr",code:"5105",name:"Beban Penyusutan",type:"expense"},{id:"coop-coa-prov-kredit",code:"5106",name:"Cadangan Kerugian Piutang",type:"expense"}];function nt(n="IDR"){return Ue.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}function tt(n){let e=new Set,t=new Set;for(let r of n){if(!r.id||!r.code||!r.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(r.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(r.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(r.id),t.add(r.code)}return{ok:!0}}export{je as CANONICAL_COA_TEMPLATES,Ue as COOP_COA_TEMPLATES,d as OFINANCE_TABLES,N as OffinanceCore,J as OffinanceEnvelopeService,k as OfinanceRuntimeCore,j as OfinanceRuntimeCoreBuilder,ke as applyFinanceDomainEvent,L as applyPendingMigrations,kn as buildBalanceSheet,zn as buildBudgetVsRealization,Un as buildCashflowBaseline,Vn as buildClosingJournalDraft,se as buildFinanceComplianceExportBundle,$n as buildFinanceExportEnvelope,D as buildFinanceOpenItemAging,Gn as buildFinanceOperationalComplianceBundle,Y as buildFinanceTaxPostingLines,Jn as buildIncomeStatement,W as buildJournalFromCoopLoanDisbursement,Z as buildJournalFromCoopLoanRepayment,X as buildJournalFromCoopSavingDeposit,K as buildJournalFromCoopSavingWithdrawal,vn as buildJournalFromCoopShuParticipationManualRecap,z as buildJournalFromPosSale,wn as buildJournalFromScopedCoopLoanDisbursement,Nn as buildJournalFromScopedCoopLoanRepayment,_n as buildJournalFromScopedCoopSavingDeposit,Tn as buildJournalFromScopedCoopSavingWithdrawal,Dn as buildJournalFromScopedPosSale,et as createCanonicalCoA,nt as createCoopCoA,G as createDbAdapterOfinanceServices,Mn as createFinanceProjectionSink,$ as createOffinanceEnvelopeService,I as mapOffinanceErrorToEnvelope,_ as projectFinanceCashBankMovements,F as projectFinanceOpenItems,w as reconcileFinanceOpenItems,Kn as replayFinanceDomainEvents,te as resolveCoopLoanDisbursementAccountMapping,re as resolveCoopLoanRepaymentAccountMapping,ae as resolveCoopSavingDepositAccountMapping,oe as resolveCoopSavingWithdrawalAccountMapping,ne as resolvePosSaleAccountMapping,v as resolveScopedAccountMapping,T as summarizeFinanceCashBankMovements,q as toOffinanceFailureEnvelope,m as toOffinanceSuccessEnvelope,tt as validateCoaIntegrity,P as validateJournalBalance,O as validateOpenItemLineMetadata};
1
+ function P(n){if(!Array.isArray(n)||n.length===0)return{ok:!1,totalDebit:0,totalCredit:0,reason:"JOURNAL_LINES_EMPTY"};let e=0,t=0;for(let r of n){if(!r||!r.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(r.debit<0||r.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=r.debit,t+=r.credit}return Math.abs(e-t)>1e-6?{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NOT_BALANCED"}:{ok:!0,totalDebit:e,totalCredit:t}}var le=[{key:"current",label:"Current",maxDaysPastDue:0},{key:"1-30",label:"1-30 days",minDaysPastDue:1,maxDaysPastDue:30},{key:"31-60",label:"31-60 days",minDaysPastDue:31,maxDaysPastDue:60},{key:"61-90",label:"61-90 days",minDaysPastDue:61,maxDaysPastDue:90},{key:"90+",label:"90+ days",minDaysPastDue:91}];function pe(n,e,t){return n==="receivable"?e-t:t-e}function me(n,e){return[n.tenantId??"",n.branchId??"",n.financeDomainId??"",n.ledgerProfileId??"",e.accountId,e.openItemType??"",e.openItemId??""].join("::")}function V(n){return n<0?"overpaid":Math.abs(n)<1e-6?"settled":"open"}function fe(n,e){if(!e)return 0;let t=Date.parse(n)-Date.parse(e);return!Number.isFinite(t)||t<=0?0:Math.floor(t/864e5)}function Ie(n,e){return e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.openItemType&&n.openItemType!==e.openItemType||e.counterpartyRef&&n.counterpartyRef!==e.counterpartyRef||!e.includeSettled&&n.status==="settled"):!0}function F(n){for(let e of n){let t=!!(e.openItemId||e.openItemType),r=!!(e.counterpartyRef||e.documentRef||e.dueAt);if(!(!t&&!r)){if(!e.openItemId)throw new Error("JOURNAL_OPEN_ITEM_ID_REQUIRED");if(!e.openItemType)throw new Error("JOURNAL_OPEN_ITEM_TYPE_REQUIRED");if(e.openItemType!=="receivable"&&e.openItemType!=="payable")throw new Error("JOURNAL_OPEN_ITEM_TYPE_INVALID");if(e.dueAt&&Number.isNaN(Date.parse(e.dueAt)))throw new Error("JOURNAL_OPEN_ITEM_DUE_AT_INVALID")}}}function D(n,e){let t=new Map;for(let r of n)if(r.status==="posted")for(let a of r.lines){if(!a.openItemId||!a.openItemType)continue;let o=me(r,a),i=pe(a.openItemType,a.debit,a.credit),c=t.get(o);if(!c){let s={tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,openItemId:a.openItemId,openItemType:a.openItemType,accountId:a.accountId,counterpartyRef:a.counterpartyRef,documentRef:a.documentRef,dueAt:a.dueAt,originatedAt:r.occurredAt,lastActivityAt:r.occurredAt,originalAmount:i>0?i:0,settledAmount:i<0?Math.abs(i):0,outstandingAmount:i,status:V(i)};t.set(o,{item:s});continue}c.item.originatedAt=c.item.originatedAt<r.occurredAt?c.item.originatedAt:r.occurredAt,c.item.lastActivityAt=c.item.lastActivityAt>r.occurredAt?c.item.lastActivityAt:r.occurredAt,c.item.counterpartyRef=a.counterpartyRef??c.item.counterpartyRef,c.item.documentRef=a.documentRef??c.item.documentRef,c.item.dueAt=a.dueAt??c.item.dueAt,i>0?c.item.originalAmount+=i:i<0&&(c.item.settledAmount+=Math.abs(i)),c.item.outstandingAmount+=i,c.item.status=V(c.item.outstandingAmount)}return Array.from(t.values()).map(({item:r})=>({...r})).filter(r=>Ie(r,e)).sort((r,a)=>r.originatedAt!==a.originatedAt?r.originatedAt.localeCompare(a.originatedAt):r.openItemId.localeCompare(a.openItemId))}function O(n,e){if(Number.isNaN(Date.parse(e.asOf)))throw new Error("FINANCE_OPEN_ITEM_AGING_AS_OF_INVALID");let t=(e.buckets?.length?e.buckets:le).map(a=>({...a,amount:0,itemCount:0})),r=0;for(let a of n){if(a.outstandingAmount<=0)continue;r+=a.outstandingAmount;let o=fe(e.asOf,a.dueAt),i=t.find(c=>{let s=c.minDaysPastDue??Number.NEGATIVE_INFINITY,m=c.maxDaysPastDue??Number.POSITIVE_INFINITY;return o>=s&&o<=m});if(!i)throw new Error("FINANCE_OPEN_ITEM_AGING_BUCKET_UNRESOLVED");i.amount+=a.outstandingAmount,i.itemCount+=1}return{asOf:e.asOf,openItemType:e.openItemType,totalOutstanding:r,buckets:t}}function H(n,e){return`${e??""}::${n}`}function ge(n){if(!n.openItemId?.trim())throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_ID_REQUIRED");if(!Number.isFinite(n.observedAmount)||n.observedAmount<0)throw new Error("FINANCE_RECONCILIATION_OBSERVED_AMOUNT_INVALID");if(n.openItemType&&n.openItemType!=="receivable"&&n.openItemType!=="payable")throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_TYPE_INVALID")}function Ae(n,e){let t=new Map;for(let r of n){ge(r);let a=r.openItemType??e,o=H(r.openItemId,a),i=t.get(o);if(!i){t.set(o,{openItemId:r.openItemId,openItemType:a,observedAmount:r.observedAmount,counterpartyRef:r.counterpartyRef,documentRef:r.documentRef,references:r.reference?[r.reference]:[]});continue}i.observedAmount+=r.observedAmount,i.counterpartyRef=r.counterpartyRef??i.counterpartyRef,i.documentRef=r.documentRef??i.documentRef,r.reference&&i.references.push(r.reference)}return t}function ye(n,e,t,r,a){let o=n.outstandingAmount,i=e?.observedAmount??0,c=i-o,s=he(n.dueAt,r);if(!e){let A=$("missing",s,a);return{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:o,observedAmount:i,varianceAmount:c,status:"missing",lifecycleStatus:A.lifecycleStatus,suggestedAction:A.suggestedAction,reason:"FINANCE_RECONCILIATION_OBSERVATION_MISSING",pastDueDays:s,observedReferences:[]}}let m=e.counterpartyRef&&n.counterpartyRef&&e.counterpartyRef!==n.counterpartyRef||e.documentRef&&n.documentRef&&e.documentRef!==n.documentRef,p="matched",g="resolved",d="none",u;if(m)p="mismatch",g="exception",d="investigate",u="FINANCE_RECONCILIATION_METADATA_MISMATCH";else if(Math.abs(c)<=t)p="matched";else if(c<0){p="under";let A=$("under",s,a);g=A.lifecycleStatus,d=A.suggestedAction,u="FINANCE_RECONCILIATION_OBSERVED_UNDER"}else c>0&&(p="over",g="unresolved",d="refund_or_apply_credit",u="FINANCE_RECONCILIATION_OBSERVED_OVER");return{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:o,observedAmount:i,varianceAmount:c,status:p,lifecycleStatus:g,suggestedAction:d,reason:u,pastDueDays:s,observedReferences:[...e.references]}}function be(n,e){return{tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType??e.openItemType,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,expectedAmount:0,observedAmount:n.observedAmount,varianceAmount:n.observedAmount,status:"mismatch",lifecycleStatus:"exception",suggestedAction:"investigate",reason:"FINANCE_RECONCILIATION_EXPECTED_ITEM_NOT_FOUND",observedReferences:[...n.references]}}function he(n,e){if(!n||!e)return;let t=Date.parse(n),r=Date.parse(e);if(!Number.isFinite(t)||!Number.isFinite(r))throw new Error("FINANCE_RECONCILIATION_AS_OF_INVALID");let a=r-t;return a<=0?0:Math.floor(a/864e5)}function $(n,e,t){return typeof t=="number"&&typeof e=="number"&&e>=t?{lifecycleStatus:"writeoff_candidate",suggestedAction:"write_off_review"}:{lifecycleStatus:"unresolved",suggestedAction:n==="missing"||n==="under"?"collect_follow_up":"investigate"}}function T(n,e){let t=e.toleranceAmount??0;if(!Number.isFinite(t)||t<0)throw new Error("FINANCE_RECONCILIATION_TOLERANCE_INVALID");if(e.asOf&&!Number.isFinite(Date.parse(e.asOf)))throw new Error("FINANCE_RECONCILIATION_AS_OF_INVALID");if(typeof e.writeOffPastDueDays=="number"&&(!Number.isFinite(e.writeOffPastDueDays)||e.writeOffPastDueDays<0))throw new Error("FINANCE_RECONCILIATION_WRITE_OFF_DAYS_INVALID");let r=Ae(e.observations,e.openItemType),a=[];for(let d of n){let u=H(d.openItemId,d.openItemType),A=r.get(u);a.push(ye(d,A,t,e.asOf,e.writeOffPastDueDays)),r.delete(u)}for(let d of r.values())a.push(be(d,e));a.sort((d,u)=>(d.financeDomainId??"")!==(u.financeDomainId??"")?(d.financeDomainId??"").localeCompare(u.financeDomainId??""):(d.ledgerProfileId??"")!==(u.ledgerProfileId??"")?(d.ledgerProfileId??"").localeCompare(u.ledgerProfileId??""):d.openItemId.localeCompare(u.openItemId));let o=a.reduce((d,u)=>d+u.expectedAmount,0),i=a.reduce((d,u)=>d+u.observedAmount,0),c=a.reduce((d,u)=>d+u.varianceAmount,0),s=a.filter(d=>d.lifecycleStatus==="resolved").length,m=a.filter(d=>d.lifecycleStatus==="unresolved").length,p=a.filter(d=>d.lifecycleStatus==="exception").length,g=a.filter(d=>d.lifecycleStatus==="writeoff_candidate").length;return{openItemType:e.openItemType,totalExpectedAmount:o,totalObservedAmount:i,totalVarianceAmount:c,resolvedCount:s,unresolvedCount:m,exceptionCount:p,writeoffCandidateCount:g,rows:a}}function Se(n){if(!Array.isArray(n.trackedAccountIds)||n.trackedAccountIds.length===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");let e=new Set(n.trackedAccountIds.map(t=>t.trim()).filter(Boolean));if(e.size===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");return e}function Ce(n,e){return!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt>e.occurredTo)}function ve(n){return n?.startsWith("reversal:")&&n.slice(9).trim()||void 0}function _(n,e){let t=Se(e),r=[];for(let a of n){if(a.status!=="posted"||!Ce(a,e))continue;let o=a.lines.filter(u=>t.has(u.accountId)&&(u.debit>0||u.credit>0));if(o.length===0)continue;let i=Array.from(new Set(o.map(u=>u.accountId))).sort(),c=Array.from(new Set(a.lines.filter(u=>!t.has(u.accountId)&&(u.debit>0||u.credit>0)).map(u=>u.accountId))).sort(),s=o.some(u=>u.debit>0),m=o.some(u=>u.credit>0),p=ve(a.reference),g=!!p,d=i.length>1&&s&&m&&c.length===0;if(i.length>1&&c.length>0)throw new Error("FINANCE_CASH_MOVEMENT_MIXED_TRACKED_JOURNAL_UNSUPPORTED");if(d){let u=o.reduce((y,S)=>y+S.debit,0),A=o.reduce((y,S)=>y+S.credit,0);if(Math.abs(u-A)>1e-6)throw new Error("FINANCE_CASH_MOVEMENT_TRANSFER_IMBALANCED")}for(let u of o)u.debit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:u.accountId,direction:d?"transfer_in":"in",movementKind:g?"reversal":d?"internal_transfer":"external",lifecycleStatus:g?"reversal_posted":"posted",amount:u.debit,signedAmount:u.debit,sourceJournalId:p,counterpartAccountIds:c,trackedAccountIdsInJournal:i}),u.credit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:u.accountId,direction:d?"transfer_out":"out",movementKind:g?"reversal":d?"internal_transfer":"external",lifecycleStatus:g?"reversal_posted":"posted",amount:u.credit,signedAmount:-u.credit,sourceJournalId:p,counterpartAccountIds:c,trackedAccountIdsInJournal:i})}return r.sort((a,o)=>a.occurredAt!==o.occurredAt?a.occurredAt.localeCompare(o.occurredAt):a.journalId!==o.journalId?a.journalId.localeCompare(o.journalId):a.accountId.localeCompare(o.accountId))}function w(n){let e=0,t=0,r=0,a=0,o=new Map;for(let i of n)i.direction==="in"&&(e+=i.amount),i.direction==="out"&&(t+=i.amount),i.direction==="transfer_in"&&(r+=i.amount),i.direction==="transfer_out"&&(a+=i.amount),o.set(i.accountId,(o.get(i.accountId)??0)+i.signedAmount);return{totalInflow:e,totalOutflow:t,totalTransferIn:r,totalTransferOut:a,netExternalMovement:e-t,netByTrackedAccountId:Object.fromEntries(Array.from(o.entries()).sort(([i],[c])=>i.localeCompare(c))),entries:n.map(i=>({...i,counterpartAccountIds:[...i.counterpartAccountIds],trackedAccountIdsInJournal:[...i.trackedAccountIdsInJournal]}))}}var N=class{constructor(e){this.state={accounts:e?.accounts??new Map,periods:e?.periods??new Map,journals:e?.journals??new Map,balances:e?.balances??new Map,rapbPlans:e?.rapbPlans??new Map,auditTrail:e?.auditTrail?.map(t=>({...t}))??[]}}createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");if(this.state.accounts.has(e.id))throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if(Array.from(this.state.accounts.values()).some(r=>r.code===e.code))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");return this.state.accounts.set(e.id,{...e}),{...e}}listAccounts(){return Array.from(this.state.accounts.values()).map(e=>({...e})).sort((e,t)=>e.code.localeCompare(t.code))}openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(this.state.periods.has(e.id))throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t={...e,status:"open"};return this.state.periods.set(t.id,t),this.recordAuditTrail({eventType:"fiscal_period_opened",recordType:"fiscal_period",recordId:t.id,tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId,occurredAt:new Date().toISOString(),summary:`Fiscal period ${t.code} opened`,metadata:{code:t.code,startDate:t.startDate,endDate:t.endDate}}),{...t}}closeFiscalPeriod(e){let t=this.state.periods.get(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed"};return this.state.periods.set(e,r),this.recordAuditTrail({eventType:"fiscal_period_closed",recordType:"fiscal_period",recordId:r.id,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:new Date().toISOString(),summary:`Fiscal period ${r.code} closed`,metadata:{code:r.code}}),{...r}}listFiscalPeriods(){return Array.from(this.state.periods.values()).map(e=>({...e})).sort((e,t)=>e.startDate.localeCompare(t.startDate))}createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(this.state.journals.has(e.id))throw new Error("JOURNAL_ALREADY_EXISTS");this.assertJournalLinesKnownAccounts(e.lines),this.assertJournalPeriodOpen(e.occurredAt),F(e.lines);let t=P(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,lines:e.lines.map(a=>({...a})),status:"draft"};return this.state.journals.set(r.id,r),this.recordAuditTrail({eventType:"journal_drafted",recordType:"journal",recordId:r.id,journalId:r.id,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:new Date().toISOString(),reference:r.reference,evidenceRef:r.evidenceRef,summary:`Journal ${r.id} drafted`,metadata:{journalOccurredAt:r.occurredAt,status:r.status}}),{...r,lines:r.lines.map(a=>({...a}))}}postJournal(e,t=new Date().toISOString()){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status==="posted"||r.status==="reversed")return{...r,lines:r.lines.map(i=>({...i}))};this.applyLinesToBalance(r.lines);let a={...r,status:"posted",postedAt:t};this.state.journals.set(e,a);let o=new Date().toISOString();return this.recordAuditTrail({eventType:"journal_posted",recordType:"journal",recordId:a.id,journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:o,reference:a.reference,evidenceRef:a.evidenceRef,summary:`Journal ${a.id} posted`,metadata:{journalOccurredAt:a.occurredAt,postedAt:t,status:a.status}}),{...a,lines:a.lines.map(i=>({...i}))}}reverseJournal(e,t){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let a=r.lines.map(s=>({accountId:s.accountId,debit:s.credit,credit:s.debit,memo:s.memo,openItemId:s.openItemId,openItemType:s.openItemType,counterpartyRef:s.counterpartyRef,documentRef:s.documentRef,dueAt:s.dueAt})),o=this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a}),i=this.postJournal(o.id),c=new Date().toISOString();return this.recordAuditTrail({eventType:"journal_reversal_posted",recordType:"journal",recordId:i.id,journalId:i.id,sourceJournalId:r.id,tenantId:i.tenantId,branchId:i.branchId,financeDomainId:i.financeDomainId,ledgerProfileId:i.ledgerProfileId,occurredAt:c,reference:i.reference,evidenceRef:i.evidenceRef,summary:`Reversal journal ${i.id} posted for ${r.id}`,metadata:{journalOccurredAt:i.occurredAt,postedAt:i.postedAt,status:i.status}}),i}getTrialBalance(){return this.getTrialBalanceByScope()}getTrialBalanceByScope(e){let t=this.computeScopedBalances(e);return this.listAccounts().map(a=>{let o=t.get(a.id)??{debit:0,credit:0};return{accountId:a.id,accountCode:a.code,accountName:a.name,accountType:a.type,debit:o.debit,credit:o.credit,net:o.debit-o.credit}})}listJournals(e){return Array.from(this.state.journals.values()).filter(t=>this.matchesScope(t,e)).map(t=>({...t,lines:t.lines.map(r=>({...r}))})).sort((t,r)=>t.occurredAt.localeCompare(r.occurredAt))}listOpenItems(e){return D(this.listJournals(e),e)}getOpenItemAging(e){return O(this.listOpenItems(e),e)}reconcileOpenItems(e){return T(this.listOpenItems(e),e)}listCashBankMovements(e){return _(this.listJournals(e),e)}summarizeCashBankMovements(e){return w(this.listCashBankMovements(e))}listFinancialAuditTrail(e){return this.state.auditTrail.filter(t=>this.matchesAuditScope(t,e)).sort((t,r)=>t.occurredAt!==r.occurredAt?t.occurredAt.localeCompare(r.occurredAt):t.id.localeCompare(r.id)).map(t=>({...t,metadata:t.metadata?{...t.metadata}:void 0}))}assertJournalLinesKnownAccounts(e){for(let t of e)if(!this.state.accounts.has(t.accountId))throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}assertJournalPeriodOpen(e){if(this.state.periods.size===0)return;let t=this.findPeriodByDate(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(t.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}findPeriodByDate(e){let t=Date.parse(e);for(let r of this.state.periods.values()){let a=Date.parse(r.startDate),o=Date.parse(r.endDate);if(t>=a&&t<=o)return r}return null}applyLinesToBalance(e){for(let t of e){let r=this.state.balances.get(t.accountId)??{debit:0,credit:0};r.debit+=t.debit,r.credit+=t.credit,this.state.balances.set(t.accountId,r)}}computeScopedBalances(e){if(!e||!e.tenantId&&!e.branchId&&!e.financeDomainId&&!e.ledgerProfileId&&!e.occurredFrom&&!e.occurredTo)return this.state.balances;let t=new Map;for(let r of this.state.journals.values())if(r.status==="posted"&&this.matchesScope(r,e))for(let a of r.lines){let o=t.get(a.accountId)??{debit:0,credit:0};o.debit+=a.debit,o.credit+=a.credit,t.set(a.accountId,o)}return t}matchesScope(e,t){return t?!(t.tenantId&&e.tenantId!==t.tenantId||t.branchId&&e.branchId!==t.branchId||t.financeDomainId&&e.financeDomainId!==t.financeDomainId||t.ledgerProfileId&&e.ledgerProfileId!==t.ledgerProfileId||t.occurredFrom&&e.occurredAt<t.occurredFrom||t.occurredTo&&e.occurredAt>t.occurredTo):!0}createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(this.state.rapbPlans.has(e.id))throw new Error("RAPB_ALREADY_EXISTS");if(e.lines.some(a=>a.budgetedDebit<0||a.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=e.lines.map(a=>{let o=this.state.accounts.get(a.accountId);if(!o)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${a.accountId}`);let i=a.budgetedDebit-a.budgetedCredit;return{accountId:a.accountId,accountCode:o.code,accountName:o.name,accountType:o.type,budgetedDebit:a.budgetedDebit,budgetedCredit:a.budgetedCredit,budgetedNet:i}}),r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",lines:t,notes:e.notes,createdAt:new Date().toISOString()};return this.state.rapbPlans.set(r.id,r),this.recordAuditTrail({eventType:"rapb_created",recordType:"rapb_plan",recordId:r.id,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.createdAt,summary:`RAPB ${r.title} created`,metadata:{periodCode:r.periodCode,status:r.status}}),r}getRapb(e){return this.state.rapbPlans.get(e)??null}listRapb(e){let t=Array.from(this.state.rapbPlans.values());return e&&(e.tenantId&&(t=t.filter(r=>r.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(r=>r.periodCode===e.periodCode)),e.branchId&&(t=t.filter(r=>r.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(r=>r.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(r=>r.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let r=this.state.rapbPlans.get(e);if(!r)throw new Error("RAPB_NOT_FOUND");let a=typeof t=="string"?t:t.approvedBy;if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...r,status:"approved",approvedAt:new Date().toISOString(),approvedBy:a};return this.state.rapbPlans.set(e,o),this.recordAuditTrail({eventType:"rapb_approved",recordType:"rapb_plan",recordId:o.id,tenantId:o.tenantId,branchId:o.branchId,financeDomainId:o.financeDomainId,ledgerProfileId:o.ledgerProfileId,occurredAt:o.approvedAt??new Date().toISOString(),summary:`RAPB ${o.title} approved`,metadata:{periodCode:o.periodCode,approvedBy:a,status:o.status}}),o}evaluateVariance(e){let t=this.state.rapbPlans.get(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=this.getTrialBalance(),a=new Map(r.map(d=>[d.accountId,d])),o=0,i=0,c=0,s=0,m=t.lines.map(d=>{let u=a.get(d.accountId),A=u?.debit??0,y=u?.credit??0,S=A-y;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=y-A):d.accountType==="expense"&&(c+=d.budgetedDebit-d.budgetedCredit,s+=A-y),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:A,actualCredit:y,actualNet:S,varianceDebit:A-d.budgetedDebit,varianceCredit:y-d.budgetedCredit,varianceNet:S-d.budgetedNet}}),p=o-c,g=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:m,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:p,actualNetIncome:g,netVariance:g-p}}recordAuditTrail(e){this.state.auditTrail.push({id:`audit:${this.state.auditTrail.length+1}:${Date.now()}`,...e,metadata:e.metadata?{...e.metadata}:void 0})}matchesAuditScope(e,t){return t?!(t.tenantId&&e.tenantId!==t.tenantId||t.branchId&&e.branchId!==t.branchId||t.financeDomainId&&e.financeDomainId!==t.financeDomainId||t.ledgerProfileId&&e.ledgerProfileId!==t.ledgerProfileId||t.occurredFrom&&e.occurredAt<t.occurredFrom||t.occurredTo&&e.occurredAt>t.occurredTo||t.recordId&&e.recordId!==t.recordId||t.journalId&&e.journalId!==t.journalId||t.eventTypes&&t.eventTypes.length>0&&!t.eventTypes.includes(e.eventType)):!0}};import{CoreRuntime as Te}from"ofcore";import{InMemoryDbAdapter as _e}from"ofcore";import{asReadonlyStore as we,createStore as Ne}from"ofcore";var l={accounts:"ofinance_accounts",periods:"ofinance_periods",journals:"ofinance_journals",journalLines:"ofinance_journal_lines",rapbPlans:"ofinance_rapb_plans",rapbLines:"ofinance_rapb_lines",histories:"ofinance_histories"},Ee=[{name:l.accounts,columns:[{name:"id",type:"string"},{name:"code",type:"string",isIndexed:!0},{name:"name",type:"string"},{name:"type",type:"string",isIndexed:!0},{name:"currency",type:"string"},{name:"isActive",type:"boolean",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.periods,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"code",type:"string",isIndexed:!0},{name:"startDate",type:"string",isIndexed:!0},{name:"endDate",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.journals,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"occurredAt",type:"string",isIndexed:!0},{name:"reference",type:"string",isOptional:!0,isIndexed:!0},{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.journalLines,columns:[{name:"id",type:"string"},{name:"journalId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"debit",type:"number"},{name:"credit",type:"number"},{name:"memo",type:"string",isOptional:!0},{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.rapbPlans,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"periodCode",type:"string",isIndexed:!0},{name:"title",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"notes",type:"string",isOptional:!0},{name:"createdAt",type:"string",isIndexed:!0},{name:"approvedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"approvedBy",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.rapbLines,columns:[{name:"id",type:"string"},{name:"rapbId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"accountCode",type:"string",isIndexed:!0},{name:"accountName",type:"string"},{name:"accountType",type:"string",isIndexed:!0},{name:"budgetedDebit",type:"number"},{name:"budgetedCredit",type:"number"},{name:"budgetedNet",type:"number"},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.histories,columns:[{name:"id",type:"string"},{name:"tableName",type:"string",isIndexed:!0},{name:"recordId",type:"string",isIndexed:!0},{name:"action",type:"string",isIndexed:!0},{name:"changes",type:"json",isOptional:!0},{name:"timestamp",type:"string",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0}]}];function B(){return Ee.map(n=>({...n,columns:n.columns.map(e=>({...e}))}))}var Q=[{toVersion:1,up:async n=>{let e=B();for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:2,up:async n=>{let e=B().filter(t=>t.name==="ofinance_rapb_plans"||t.name==="ofinance_rapb_lines");for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:3,up:async n=>{try{await n.addColumn("ofinance_journals",{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0})}catch{}}},{toVersion:4,up:async n=>{let e=[{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0}];for(let t of e)try{await n.addColumn("ofinance_journal_lines",t)}catch{}}}];var Re={logInfo(){},logWarn(){},logError(){}};async function L(n,e=Re){e.logInfo("[offinance] starting database migration process");let t=[...Q].sort((o,i)=>o.toVersion-i.toVersion),r=t.length>0?t[t.length-1].toVersion:0,a=await n.getSchemaVersion();if((a==null||a<0)&&(a=0),a>=r){e.logInfo(`[offinance] database already up-to-date at v${a}`);return}for(let o of t)o.toVersion>a&&(e.logInfo(`[offinance] applying migration v${o.toVersion}`),await o.up(n),await n.setSchemaVersion(o.toVersion),a=o.toVersion);e.logInfo(`[offinance] migration completed at v${a}`)}function f(n,e){return{data:n,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function q(n,e,t={}){return{error:{code:n,message:e,details:t.details,retryable:t.retryable,correlationId:t.correlationId,timestamp:new Date().toISOString()},meta:{request_id:t.requestId??null,timestamp:new Date().toISOString()}}}function I(n,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return n instanceof Error?q(e,n.message||t):q(e,t)}var J=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return f(await this.legacy.accountService.createAccount(t))}catch(r){return I(r)}},listAccounts:async()=>{try{return f(await this.legacy.accountService.listAccounts())}catch(t){return I(t)}}},this.journalService={createJournalDraft:async t=>{try{return f(await this.legacy.journalService.createJournalDraft(t))}catch(r){return I(r)}},postJournal:async(t,r)=>{try{return f(await this.legacy.journalService.postJournal(t,r))}catch(a){return I(a)}},reverseJournal:async(t,r)=>{try{return f(await this.legacy.journalService.reverseJournal(t,r))}catch(a){return I(a)}},listJournals:async t=>{try{return f(await this.legacy.journalService.listJournals(t))}catch(r){return I(r)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return f(await this.legacy.fiscalService.openFiscalPeriod(t))}catch(r){return I(r)}},closeFiscalPeriod:async t=>{try{return f(await this.legacy.fiscalService.closeFiscalPeriod(t))}catch(r){return I(r)}},listFiscalPeriods:async()=>{try{return f(await this.legacy.fiscalService.listFiscalPeriods())}catch(t){return I(t)}},getTrialBalance:async()=>{try{return f(await this.legacy.fiscalService.getTrialBalance())}catch(t){return I(t)}},getTrialBalanceByScope:async t=>{try{return f(await this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(r){return I(r)}}},this.rapbService={createRapb:async t=>{try{return f(await this.legacy.rapbService.createRapb(t))}catch(r){return I(r)}},getRapb:async t=>{try{return f(await this.legacy.rapbService.getRapb(t))}catch(r){return I(r)}},listRapb:async t=>{try{return f(await this.legacy.rapbService.listRapb(t))}catch(r){return I(r)}},approveRapb:async(t,r)=>{try{return f(await this.legacy.rapbService.approveRapb(t,r))}catch(a){return I(a)}},evaluateVariance:async t=>{try{return f(await this.legacy.rapbService.evaluateVariance(t))}catch(r){return I(r)}}},this.openItemService={listOpenItems:async t=>{try{return f(await this.legacy.openItemService.listOpenItems(t))}catch(r){return I(r)}},getOpenItemAging:async t=>{try{return f(await this.legacy.openItemService.getOpenItemAging(t))}catch(r){return I(r)}}},this.reconciliationService={reconcileOpenItems:async t=>{try{return f(await this.legacy.reconciliationService.reconcileOpenItems(t))}catch(r){return I(r)}}},this.cashMovementService={listCashBankMovements:async t=>{try{return f(await this.legacy.cashMovementService.listCashBankMovements(t))}catch(r){return I(r)}},summarizeCashBankMovements:async t=>{try{return f(await this.legacy.cashMovementService.summarizeCashBankMovements(t))}catch(r){return I(r)}}},this.auditTrailService={listFinancialAuditTrail:async t=>{try{return f(await this.legacy.auditTrailService.listFinancialAuditTrail(t))}catch(r){return I(r)}}}}};function Y(n){return new J({accountService:n,journalService:n,fiscalService:n,rapbService:n,openItemService:n,reconciliationService:n,cashMovementService:n,auditTrailService:n})}function h(n){return JSON.parse(JSON.stringify(n))}function b(){return new Date().toISOString()}function Pe(n,e){return`${n}:${e}:${Date.now()}:${Math.random().toString(36).slice(2,8)}`}function Fe(n,e){return!n||n.deleted?!1:e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt&&n.occurredAt>e.occurredTo):!0}function De(n,e){return e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt>e.occurredTo||e.recordId&&n.recordId!==e.recordId||e.journalId&&n.journalId!==e.journalId||e.eventTypes&&e.eventTypes.length>0&&!e.eventTypes.includes(n.eventType)):!0}function Oe(n){return typeof n!="string"||!n.startsWith("reversal:")?void 0:n.slice(9).trim()||void 0}var M=class{constructor(e){this.dbAdapter=e}async createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");let t=await this.dbAdapter.get(l.accounts,e.id);if(t&&!t.deleted)throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if((await this.dbAdapter.query(l.accounts,{filters:{and:[{field:"code",value:e.code},{field:"deleted",value:!1}]}})).some(i=>i.id!==e.id))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");let a=b(),o={...h(e),lastModified:a,deleted:!1};return t?await this.dbAdapter.update(l.accounts,e.id,o):await this.dbAdapter.create(l.accounts,o),await this.writeHistory("accounts",e.id,"UPSERT",o),h(e)}async listAccounts(){return(await this.dbAdapter.query(l.accounts,{filters:{field:"deleted",value:!1}})).map(({lastModified:t,deleted:r,...a})=>h(a)).sort((t,r)=>t.code.localeCompare(r.code))}async createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(!e.ledgerProfileId)throw new Error("JOURNAL_REQUIRED_FIELDS");let t=await this.dbAdapter.get(l.journals,e.id);if(t&&!t.deleted)throw new Error("JOURNAL_ALREADY_EXISTS");await this.assertJournalLinesKnownAccounts(e.lines),await this.assertJournalPeriodOpen(e),F(e.lines);let r=P(e.lines);if(!r.ok)throw new Error(r.reason??"JOURNAL_INVALID");let a=b(),o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,status:"draft",postedAt:void 0,lastModified:a,deleted:!1};await this.dbAdapter.create(l.journals,o);for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s={id:`${e.id}:line:${i}`,journalId:e.id,accountId:c.accountId,debit:c.debit,credit:c.credit,memo:c.memo,openItemId:c.openItemId,openItemType:c.openItemType,counterpartyRef:c.counterpartyRef,documentRef:c.documentRef,dueAt:c.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:a,deleted:!1};await this.dbAdapter.create(l.journalLines,s),await this.writeHistory("journal_lines",s.id,"UPSERT",s)}return await this.writeHistory("journals",e.id,"UPSERT",o),this.toJournalEntry(o,e.lines)}async postJournal(e,t=b()){let r=await this.requireJournal(e),a=await this.listJournalLines(e);if(r.status==="posted"||r.status==="reversed")return this.toJournalEntry(r,a);let o={...r,status:"posted",postedAt:t,lastModified:b()};return await this.dbAdapter.update(l.journals,e,o),await this.writeHistory("journals",e,"UPSERT",o),this.toJournalEntry(o,a)}async reverseJournal(e,t){let r=await this.requireJournal(e);if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");let a=await this.listJournalLines(e),o=await this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo,openItemId:i.openItemId,openItemType:i.openItemType,counterpartyRef:i.counterpartyRef,documentRef:i.documentRef,dueAt:i.dueAt}))});return this.postJournal(o.id)}async listJournals(e){let r=(await this.dbAdapter.query(l.journals,{filters:{field:"deleted",value:!1}})).filter(o=>Fe(o,e)).sort((o,i)=>o.occurredAt.localeCompare(i.occurredAt)),a=[];for(let o of r){let i=await this.listJournalLines(o.id);a.push(this.toJournalEntry(o,i))}return a}async listOpenItems(e){return D(await this.listJournals(e),e)}async getOpenItemAging(e){return O(await this.listOpenItems(e),e)}async reconcileOpenItems(e){return T(await this.listOpenItems(e),e)}async listCashBankMovements(e){return _(await this.listJournals(e),e)}async summarizeCashBankMovements(e){return w(await this.listCashBankMovements(e))}async listFinancialAuditTrail(e){return(await this.dbAdapter.query(l.histories,{})).map(r=>this.toAuditTrailEntry(r)).filter(r=>r!==null).filter(r=>De(r,e)).sort((r,a)=>r.occurredAt!==a.occurredAt?r.occurredAt.localeCompare(a.occurredAt):r.id.localeCompare(a.id))}async openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t=await this.dbAdapter.get(l.periods,e.id);if(t&&!t.deleted)throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");let r=b(),a={...h(e),status:"open",lastModified:r,deleted:!1};return t?await this.dbAdapter.update(l.periods,e.id,a):await this.dbAdapter.create(l.periods,a),await this.writeHistory("periods",e.id,"UPSERT",a),this.toPeriod(a)}async closeFiscalPeriod(e){let t=await this.dbAdapter.get(l.periods,e);if(!t||t.deleted)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed",lastModified:b()};return await this.dbAdapter.update(l.periods,e,r),await this.writeHistory("periods",e,"UPSERT",r),this.toPeriod(r)}async listFiscalPeriods(){return(await this.dbAdapter.query(l.periods,{filters:{field:"deleted",value:!1}})).map(t=>this.toPeriod(t)).sort((t,r)=>t.startDate.localeCompare(r.startDate))}async getTrialBalance(){return this.getTrialBalanceByScope()}async getTrialBalanceByScope(e){let t=await this.listAccounts(),a=(await this.listJournals(e)).filter(i=>i.status==="posted"),o=new Map;for(let i of a)for(let c of i.lines){let s=o.get(c.accountId)??{debit:0,credit:0};s.debit+=Number(c.debit||0),s.credit+=Number(c.credit||0),o.set(c.accountId,s)}return t.map(i=>{let c=o.get(i.id)??{debit:0,credit:0};return{accountId:i.id,accountCode:i.code,accountName:i.name,accountType:i.type,debit:c.debit,credit:c.credit,net:c.debit-c.credit}})}async createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(e.lines.some(i=>i.budgetedDebit<0||i.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=await this.dbAdapter.get(l.rapbPlans,e.id);if(t&&!t.deleted)throw new Error("RAPB_ALREADY_EXISTS");let r=b(),a=[];for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s=await this.dbAdapter.get(l.accounts,c.accountId);if(!s||s.deleted)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${c.accountId}`);a.push({id:`${e.id}:line:${i}`,rapbId:e.id,accountId:c.accountId,accountCode:s.code,accountName:s.name,accountType:s.type,budgetedDebit:c.budgetedDebit,budgetedCredit:c.budgetedCredit,budgetedNet:c.budgetedDebit-c.budgetedCredit,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:r,deleted:!1})}let o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",notes:e.notes,createdAt:r,approvedAt:void 0,approvedBy:void 0,lastModified:r,deleted:!1};await this.dbAdapter.create(l.rapbPlans,o),await this.writeHistory("rapb_plans",e.id,"UPSERT",o);for(let i of a)await this.dbAdapter.create(l.rapbLines,i),await this.writeHistory("rapb_lines",i.id,"UPSERT",i);return this.toRapbPlan(o,a)}async getRapb(e){let t=await this.dbAdapter.get(l.rapbPlans,e);if(!t||t.deleted)return null;let r=await this.listRapbLines(e);return this.toRapbPlan(t,r)}async listRapb(e){let r=await this.dbAdapter.query(l.rapbPlans,{filters:{field:"deleted",value:!1}});e&&(e.tenantId&&(r=r.filter(o=>o.tenantId===e.tenantId)),e.periodCode&&(r=r.filter(o=>o.periodCode===e.periodCode)),e.branchId&&(r=r.filter(o=>o.branchId===e.branchId)),e.financeDomainId&&(r=r.filter(o=>o.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(r=r.filter(o=>o.ledgerProfileId===e.ledgerProfileId)));let a=[];for(let o of r.sort((i,c)=>i.createdAt.localeCompare(c.createdAt))){let i=await this.listRapbLines(o.id);a.push(this.toRapbPlan(o,i))}return a}async approveRapb(e,t){let r=await this.dbAdapter.get(l.rapbPlans,e);if(!r||r.deleted)throw new Error("RAPB_NOT_FOUND");if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let a=typeof t=="string"?t:t.approvedBy,o={...r,status:"approved",approvedAt:b(),approvedBy:a,lastModified:b()};await this.dbAdapter.update(l.rapbPlans,e,o),await this.writeHistory("rapb_plans",e,"UPSERT",o);let i=await this.listRapbLines(e);return this.toRapbPlan(o,i)}async evaluateVariance(e){let t=await this.getRapb(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=await this.getTrialBalanceByScope({tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId}),a=new Map(r.map(d=>[d.accountId,d])),o=0,i=0,c=0,s=0,m=t.lines.map(d=>{let u=a.get(d.accountId),A=u?.debit??0,y=u?.credit??0,S=A-y;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=y-A):d.accountType==="expense"&&(c+=d.budgetedDebit-d.budgetedCredit,s+=A-y),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:A,actualCredit:y,actualNet:S,varianceDebit:A-d.budgetedDebit,varianceCredit:y-d.budgetedCredit,varianceNet:S-d.budgetedNet}}),p=o-c,g=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:b(),lines:m,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:p,actualNetIncome:g,netVariance:g-p}}async assertJournalLinesKnownAccounts(e){for(let t of e){let r=await this.dbAdapter.get(l.accounts,t.accountId);if(!r||r.deleted)throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}}async assertJournalPeriodOpen(e){let t=await this.dbAdapter.query(l.periods,{filters:{field:"deleted",value:!1}});if(t.length===0)return;let r=t.find(a=>!(a.tenantId!==e.tenantId||Date.parse(a.startDate)>Date.parse(e.occurredAt)||Date.parse(a.endDate)<Date.parse(e.occurredAt)||e.ledgerProfileId&&a.ledgerProfileId&&a.ledgerProfileId!==e.ledgerProfileId||e.financeDomainId&&a.financeDomainId&&a.financeDomainId!==e.financeDomainId));if(!r)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(r.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}async requireJournal(e){let t=await this.dbAdapter.get(l.journals,e);if(!t||t.deleted)throw new Error("JOURNAL_NOT_FOUND");return t}async listJournalLines(e){return(await this.dbAdapter.query(l.journalLines,{filters:{and:[{field:"journalId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}async listRapbLines(e){return(await this.dbAdapter.query(l.rapbLines,{filters:{and:[{field:"rapbId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}toJournalEntry(e,t){let{lastModified:r,deleted:a,...o}=e;return{...h(o),lines:t.map(i=>h(i))}}toPeriod(e){let{lastModified:t,deleted:r,...a}=e;return h(a)}toRapbPlan(e,t){let{lastModified:r,deleted:a,...o}=e;return{...h(o),lines:t.map(({id:i,rapbId:c,lastModified:s,deleted:m,...p})=>h(p))}}async writeHistory(e,t,r,a){let o=a,i={id:Pe(e,t),tableName:e,recordId:t,action:r,changes:h(o),timestamp:b(),tenantId:typeof o.tenantId=="string"?o.tenantId:void 0,branchId:typeof o.branchId=="string"?o.branchId:void 0,financeDomainId:typeof o.financeDomainId=="string"?o.financeDomainId:void 0,ledgerProfileId:typeof o.ledgerProfileId=="string"?o.ledgerProfileId:void 0};await this.dbAdapter.create(l.histories,i)}toAuditTrailEntry(e){let t=e.changes??{},r=typeof t.tenantId=="string"?t.tenantId:e.tenantId,a=typeof t.branchId=="string"?t.branchId:e.branchId,o=typeof t.financeDomainId=="string"?t.financeDomainId:e.financeDomainId,i=typeof t.ledgerProfileId=="string"?t.ledgerProfileId:e.ledgerProfileId;if(e.tableName==="journals"){let c=typeof t.reference=="string"?t.reference:void 0,s=typeof t.evidenceRef=="string"?t.evidenceRef:void 0,m=typeof t.status=="string"?t.status:void 0,p=Oe(c),g=m==="draft"?"journal_drafted":m==="posted"&&p?"journal_reversal_posted":m==="posted"?"journal_posted":null;return g?{id:e.id,occurredAt:e.timestamp,eventType:g,recordType:"journal",recordId:e.recordId,journalId:e.recordId,sourceJournalId:p,tenantId:r,branchId:a,financeDomainId:o,ledgerProfileId:i,reference:c,evidenceRef:s,summary:g==="journal_reversal_posted"?`Reversal journal ${e.recordId} posted for ${p}`:`Journal ${e.recordId} ${g==="journal_drafted"?"drafted":"posted"}`,metadata:{journalOccurredAt:t.occurredAt,status:m}}:null}if(e.tableName==="periods"){let c=typeof t.status=="string"?t.status:void 0;return c!=="open"&&c!=="closed"?null:{id:e.id,occurredAt:e.timestamp,eventType:c==="open"?"fiscal_period_opened":"fiscal_period_closed",recordType:"fiscal_period",recordId:e.recordId,tenantId:r,branchId:a,financeDomainId:o,ledgerProfileId:i,summary:`Fiscal period ${String(t.code??e.recordId)} ${c}`,metadata:{code:t.code,status:c,startDate:t.startDate,endDate:t.endDate}}}if(e.tableName==="rapb_plans"){let c=typeof t.status=="string"?t.status:void 0,s=c==="draft"?"rapb_created":c==="approved"?"rapb_approved":null;return s?{id:e.id,occurredAt:e.timestamp,eventType:s,recordType:"rapb_plan",recordId:e.recordId,tenantId:r,branchId:a,financeDomainId:o,ledgerProfileId:i,summary:s==="rapb_created"?`RAPB ${String(t.title??e.recordId)} created`:`RAPB ${String(t.title??e.recordId)} approved`,metadata:{title:t.title,status:c,periodCode:t.periodCode,approvedBy:t.approvedBy}}:null}return null}};async function G(n){await L(n);let e=new M(n);return{financeService:Y({createAccount:e.createAccount.bind(e),listAccounts:e.listAccounts.bind(e),createJournalDraft:e.createJournalDraft.bind(e),postJournal:e.postJournal.bind(e),reverseJournal:e.reverseJournal.bind(e),listJournals:e.listJournals.bind(e),openFiscalPeriod:e.openFiscalPeriod.bind(e),closeFiscalPeriod:e.closeFiscalPeriod.bind(e),listFiscalPeriods:e.listFiscalPeriods.bind(e),getTrialBalance:e.getTrialBalance.bind(e),getTrialBalanceByScope:e.getTrialBalanceByScope.bind(e),createRapb:e.createRapb.bind(e),getRapb:e.getRapb.bind(e),listRapb:e.listRapb.bind(e),approveRapb:e.approveRapb.bind(e),evaluateVariance:e.evaluateVariance.bind(e),listOpenItems:e.listOpenItems.bind(e),getOpenItemAging:e.getOpenItemAging.bind(e),reconcileOpenItems:e.reconcileOpenItems.bind(e),listCashBankMovements:e.listCashBankMovements.bind(e),summarizeCashBankMovements:e.summarizeCashBankMovements.bind(e),listFinancialAuditTrail:e.listFinancialAuditTrail.bind(e)})}}var j=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=we(this.runtimeStateStore)}static builder(){return new k}get registry(){return this.runtime.registry}async start(e={}){this.runtimeStateStore.setState({phase:"starting",started:!1,lastError:null,lastTransitionAt:new Date().toISOString(),startCount:this.runtimeStateStore.getState().startCount,stopCount:this.runtimeStateStore.getState().stopCount});try{await this.runtime.start(e),this.domainServices=this.runtime.domainServices,this.runtimeStateStore.setState(t=>({...t,phase:"started",started:!0,startCount:t.startCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(t){throw this.runtimeStateStore.setState(r=>({...r,phase:"error",started:!1,lastError:t instanceof Error?t.message:String(t),lastTransitionAt:new Date().toISOString()})),t}}async stop(){this.runtimeStateStore.setState(e=>({...e,phase:"stopping",started:this.runtime.isStarted(),lastError:null,lastTransitionAt:new Date().toISOString()}));try{await this.runtime.stop(),this.runtimeStateStore.setState(e=>({...e,phase:"stopped",started:!1,stopCount:e.stopCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(e){throw this.runtimeStateStore.setState(t=>({...t,phase:"error",started:this.runtime.isStarted(),lastError:e instanceof Error?e.message:String(e),lastTransitionAt:new Date().toISOString()})),e}}isStarted(){return this.runtime.isStarted()}},k=class{constructor(){this.runtimeBuilder=Te.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new _e)}withPlatformAdapter(e){return this.runtimeBuilder.withPlatformAdapter(e),this}withDbAdapter(e){return this.runtimeBuilder.withDbAdapter(e),this}withHttpAdapter(e){return this.runtimeBuilder.withHttpAdapter(e),this}withSocketAdapter(e){return this.runtimeBuilder.withSocketAdapter(e),this}withLoggerAdapter(e){return this.runtimeBuilder.withLoggerAdapter(e),this}withActivitySink(e){return this.runtimeBuilder.withActivitySink(e),this}withExtension(e,t){return this.runtimeBuilder.withExtension(e,t),this}withDomainServicesFactory(e){return this.domainServicesFactory=e,this}withRuntimeHooks(e){return this.runtimeHooks={...this.runtimeHooks,...e},this}build(){let e=Ne({phase:"idle",started:!1,startCount:0,stopCount:0,lastError:null,lastTransitionAt:new Date().toISOString()}),t={runMigrations:async a=>{let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");await L(o,a.registry?.loggerAdapter),this.runtimeHooks.runMigrations&&await this.runtimeHooks.runMigrations(a)},...this.runtimeHooks,createDomainServices:async a=>{if(this.domainServicesFactory)return this.domainServicesFactory();let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");return G(o)}};this.runtimeBuilder.withHooks(t);let r=this.runtimeBuilder.build();return new j(r,e)}};function W(n){return!Array.isArray(n.components)||n.components.length===0?[]:n.components.map(e=>{if(!e.accountId?.trim())throw new Error("FINANCE_TAX_ACCOUNT_REQUIRED");if(!Number.isFinite(e.amount)||e.amount<=0)throw new Error("FINANCE_TAX_AMOUNT_INVALID");if(e.direction!=="payable"&&e.direction!=="receivable")throw new Error("FINANCE_TAX_DIRECTION_INVALID");let t=`${n.memoPrefix??"Finance tax"} ${e.direction}`;return{accountId:e.accountId,debit:e.direction==="receivable"?e.amount:0,credit:e.direction==="payable"?e.amount:0,memo:e.memo??t}})}function C(n,e,t){return{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:t?`${n.reference??""}${t}`:n.reference,evidenceRef:n.evidenceRef,lines:e}}function v(n,e){if(!Number.isFinite(n)||n<=0)throw new Error(e)}function z(n,e){v(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,r=e.taxAmount??0;if(t<0||r<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let a=e.grossAmount,o=a-t+r,i=[{accountId:e.paymentAccountId,debit:o,credit:0,memo:"POS sale payment"},{accountId:e.revenueAccountId,debit:0,credit:a,memo:"POS sale revenue"}];if(t>0){if(!e.discountAccountId)throw new Error("POS_SALE_DISCOUNT_ACCOUNT_REQUIRED");i.push({accountId:e.discountAccountId,debit:t,credit:0,memo:"POS sale discount"})}if(r>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");i.push(...W({memoPrefix:"POS sale tax",components:[{accountId:e.taxPayableAccountId,amount:r,direction:"payable",memo:"POS sale tax payable"}]}))}return C(n,i)}function X(n,e){return v(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),C(n,[{accountId:e.receivableAccountId,debit:e.principalAmount,credit:0,memo:"Loan receivable principal"},{accountId:e.cashAccountId,debit:0,credit:e.principalAmount,memo:"Loan cash out"}])}function K(n,e){return v(e.amount,"COOP_SAVING_INVALID_AMOUNT"),C(n,[{accountId:e.cashAccountId,debit:e.amount,credit:0,memo:"Saving deposit cash in"},{accountId:e.savingLiabilityAccountId,debit:0,credit:e.amount,memo:"Saving liability increase"}])}function Z(n,e){return v(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),C(n,[{accountId:e.savingLiabilityAccountId,debit:e.amount,credit:0,memo:"Saving liability decrease"},{accountId:e.cashAccountId,debit:0,credit:e.amount,memo:"Saving withdrawal cash out"}])}function ee(n,e){v(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,r=e.penaltyAmount??0;if(t<0||r<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(r>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let a=e.principalAmount+t+r,o=[{accountId:e.cashAccountId,debit:a,credit:0,memo:"Loan repayment cash in"},{accountId:e.receivableAccountId,debit:0,credit:e.principalAmount,memo:"Loan receivable principal repayment"}];return t>0&&o.push({accountId:e.serviceRevenueAccountId,debit:0,credit:t,memo:"Loan service revenue"}),r>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:r,memo:"Loan penalty revenue"}),C(n,o)}function Dt(n,e){if(v(e.amount,"COOP_SHU_PARTICIPATION_INVALID_AMOUNT"),!n.evidenceRef?.trim())throw new Error("COOP_SHU_PARTICIPATION_EVIDENCE_REQUIRED");return C(n,[{accountId:e.debitAccountId,debit:e.amount,credit:0,memo:e.memo??"Coop SHU participation manual recap debit"},{accountId:e.creditAccountId,debit:0,credit:e.amount,memo:e.memo??"Coop SHU participation manual recap credit"}])}function te(n,e){return e?{...n,...e}:{...n}}function E(n){let e=n.tenantId?n.scopedMapping.byTenant?.[n.tenantId]:void 0,t=n.tenantId&&n.branchId?`${n.tenantId}:${n.branchId}`:"",r=t?n.scopedMapping.byBranch?.[t]:void 0;return te(te(n.scopedMapping.default,e),r)}function ne(n){return E(n)}function re(n){return E(n)}function ae(n){return E(n)}function oe(n){return E(n)}function ie(n){return E(n)}function Nt(n,e){let{scopedAccountMapping:t,...r}=e,a=ne({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return z(n,{...r,...a})}function Lt(n,e){let{scopedAccountMapping:t,...r}=e,a=re({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return X(n,{...r,...a})}function Mt(n,e){let{scopedAccountMapping:t,...r}=e,a=oe({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return K(n,{...r,...a})}function xt(n,e){let{scopedAccountMapping:t,...r}=e,a=ie({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return Z(n,{...r,...a})}function Bt(n,e){let{scopedAccountMapping:t,...r}=e,a=ae({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return ee(n,{...r,...a})}function x(n){return!!(n&&typeof n=="object"&&n.error)}function U(n){return n.startsWith("ofinance_")?`offinance_${n.slice(9)}`:n}async function Le(n,e,t){let r=await n.accountService.listAccounts();if(x(r))throw new Error(r.error.message||r.error.code||"FINANCE_ACCOUNT_LIST_FAILED");let a=new Set((r.data||[]).map(o=>o.id));for(let o of e){if(a.has(o.id))continue;let i=await n.accountService.createAccount(o);if(x(i))throw new Error(i.error.message||i.error.code||"FINANCE_ACCOUNT_CREATE_FAILED");await t?.({changeId:`offinance:account:${o.id}`,entity:"FinanceAccount",table:U(l.accounts),type:"CREATE",data:o})}}async function ce(n,e,t){return n.query(e,{filters:{and:t}})}async function Me(n,e,t){if(!t)return;let r=await ce(n,l.journals,[{field:"id",value:e.id}]),a=await ce(n,l.journalLines,[{field:"journalId",value:e.id}]);r.length===0&&(r=[{id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,status:e.status,postedAt:e.postedAt,lastModified:e.postedAt||e.occurredAt,deleted:!1}]),a.length===0&&(a=e.lines.map((o,i)=>({id:`${e.id}:line:${i}`,journalId:e.id,accountId:o.accountId,debit:o.debit,credit:o.credit,memo:o.memo,openItemId:o.openItemId,openItemType:o.openItemType,counterpartyRef:o.counterpartyRef,documentRef:o.documentRef,dueAt:o.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:e.postedAt||e.occurredAt,deleted:!1})));for(let o of r)await t({changeId:`offinance:journal:${o.id}`,entity:"FinanceJournalEntry",table:U(l.journals),type:"CREATE",data:o});for(let o of a)await t({changeId:`offinance:journal-line:${o.id}`,entity:"FinanceJournalLine",table:U(l.journalLines),type:"CREATE",data:o})}function kt(n){return async e=>{let t=n.resolveFinanceServices();if(!t)throw new Error(n.missingServicesErrorCode||"FINANCE_SERVICES_UNAVAILABLE");let r=n.resolveLedgerProfileId().trim();if(!r)throw new Error(n.missingLedgerProfileErrorCode||"FINANCE_LEDGER_PROFILE_REQUIRED");let a=n.resolveSyncEnqueuer?.()??null;await Le(t,n.requiredAccounts,a);let o=n.buildJournalDraft(e,r),i=await t.journalService.createJournalDraft(o);if(x(i)&&i.error.code!=="JOURNAL_ALREADY_EXISTS")throw new Error(i.error.message||i.error.code||"FINANCE_JOURNAL_CREATE_FAILED");let c=await t.journalService.postJournal(o.id,o.occurredAt);if(x(c))throw new Error(c.error.message||c.error.code||"FINANCE_JOURNAL_POST_FAILED");await Me(n.dbAdapter,c.data,a)}}function xe(n){switch(n.accountType){case"asset":case"expense":return n.debit-n.credit;case"liability":case"equity":case"revenue":return n.credit-n.debit;default:return 0}}function R(n,e){return n.filter(t=>t.accountType===e).reduce((t,r)=>t+xe(r),0)}function Vt(n){let e=R(n,"revenue"),t=R(n,"expense");return{revenue:e,expense:t,netIncome:e-t}}function $t(n){return{assets:R(n,"asset"),liabilities:R(n,"liability"),equity:R(n,"equity")}}function de(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function Qt(n){let e=n.filter(r=>r.accountType==="revenue").reduce((r,a)=>r+Math.max(0,de(a)),0),t=n.filter(r=>r.accountType==="expense").reduce((r,a)=>r+Math.max(0,de(a)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function qt(n,e){let t=[],r=0;for(let a of e){if(a.accountType==="revenue"){let o=a.credit-a.debit;o>0&&(t.push({accountId:a.accountId,debit:o,credit:0,memo:"Close revenue account"}),r+=o)}if(a.accountType==="expense"){let o=a.debit-a.credit;o>0&&(t.push({accountId:a.accountId,debit:0,credit:o,memo:"Close expense account"}),r-=o)}}return r>0?t.push({accountId:n.retainedEarningsAccountId,debit:0,credit:r,memo:"Retained earnings from period close"}):r<0&&t.push({accountId:n.retainedEarningsAccountId,debit:Math.abs(r),credit:0,memo:"Retained earnings from period close"}),{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:n.reference,lines:t}}function Be(n){return Array.isArray(n)?n.length:n&&typeof n=="object"?1:n===null||typeof n>"u"?0:1}function Je(n){return n==="json"?"application/json":"text/csv"}function je(n,e){if(n==="json")return`${JSON.stringify(e,null,2)}
2
+ `;if(typeof e!="string")throw new Error("FINANCE_COMPLIANCE_EXPORT_CSV_PAYLOAD_STRING_REQUIRED");return e}function ke(n){let e=2166136261;for(let t=0;t<n.length;t+=1)e^=n.charCodeAt(t),e=Math.imul(e,16777619);return`fnv1a32-${(e>>>0).toString(16).padStart(8,"0")}`}function Ue(n){if(!n.key?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_REQUIRED");if(!n.fileName?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_FILE_NAME_REQUIRED");if(n.format!=="json"&&n.format!=="csv")throw new Error("FINANCE_COMPLIANCE_EXPORT_FORMAT_INVALID")}function Ve(n){return n??"custom"}function se(n){if(!Array.isArray(n.datasets)||n.datasets.length===0)throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASETS_REQUIRED");let e=new Set,t={},r=[];for(let o of n.datasets){if(Ue(o),e.has(o.key))throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_DUPLICATE");e.add(o.key);let i=je(o.format,o.payload);t[o.fileName]=i,r.push({key:o.key,fileName:o.fileName,format:o.format,semantic:Ve(o.semantic),contentType:o.contentType??Je(o.format),recordCount:Be(o.payload),checksum:ke(i)})}return{contract:{contractVersion:"fcx-v1",tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt??new Date().toISOString(),period:{from:n.period?.from??null,to:n.period?.to??null,label:n.period?.label??null},currency:{baseCurrencyCode:n.baseCurrencyCode??"IDR"},datasets:r,summary:{datasetCount:r.length,totalRecordCount:r.reduce((o,i)=>o+i.recordCount,0)}},files:t}}function zt(n){return{version:"v1",generatedAt:n.generatedAt??new Date().toISOString(),payload:{trialBalance:n.trialBalance.map(e=>({...e})),incomeStatement:{...n.incomeStatement},balanceSheet:{...n.balanceSheet}}}}function Xt(n){let e=[{key:"trial-balance",fileName:"trial_balance.json",format:"json",semantic:"trial_balance",payload:n.trialBalance},{key:"income-statement",fileName:"income_statement.json",format:"json",semantic:"income_statement",payload:n.incomeStatement},{key:"balance-sheet",fileName:"balance_sheet.json",format:"json",semantic:"balance_sheet",payload:n.balanceSheet}];return typeof n.openItems<"u"&&e.push({key:"open-items",fileName:"open_items.json",format:"json",semantic:"open_items",payload:n.openItems}),typeof n.agingSummary<"u"&&e.push({key:"aging-summary",fileName:"aging_summary.json",format:"json",semantic:"aging_summary",payload:n.agingSummary}),typeof n.reconciliationSummary<"u"&&e.push({key:"reconciliation-summary",fileName:"reconciliation_summary.json",format:"json",semantic:"reconciliation",payload:n.reconciliationSummary}),typeof n.cashMovements<"u"&&e.push({key:"cash-movements",fileName:"cash_movements.json",format:"json",semantic:"cash_movements",payload:n.cashMovements}),se({tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt,period:n.period,baseCurrencyCode:n.baseCurrencyCode,datasets:e})}function $e(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function ue(n,e){return e===0?n===0?1:0:Number((n/e).toFixed(4))}function Zt(n,e){let t=e.map(a=>{let c=((a.accountCodes?.length?n.filter(m=>a.accountCodes?.includes(m.accountCode)):null)??n.filter(m=>a.accountType?m.accountType===a.accountType:!1)).reduce((m,p)=>m+$e(p),0),s=c-a.plannedAmount;return{id:a.id,label:a.label,plannedAmount:a.plannedAmount,actualAmount:c,varianceAmount:s,achievementRatio:ue(c,a.plannedAmount)}}),r=t.reduce((a,o)=>(a.plannedAmount+=o.plannedAmount,a.actualAmount+=o.actualAmount,a.varianceAmount+=o.varianceAmount,a),{plannedAmount:0,actualAmount:0,varianceAmount:0});return{rows:t,totals:{...r,achievementRatio:ue(r.actualAmount,r.plannedAmount)}}}function He(n,e){switch(e.type){case"finance.account.created":n.createAccount(e.payload);return;case"finance.period.opened":n.openFiscalPeriod(e.payload);return;case"finance.period.closed":n.closeFiscalPeriod(e.payload.periodId);return;case"finance.journal.drafted":n.createJournalDraft(e.payload);return;case"finance.journal.posted":n.postJournal(e.payload.journalId,e.payload.postedAt);return;case"finance.journal.reversed":n.reverseJournal(e.payload.journalId,e.payload.reversalId);return;default:throw new Error("FINANCE_EVENT_UNSUPPORTED")}}function nn(n){let e=new N;for(let t of n)He(e,t);return e}var Qe=[{id:"coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coa-ar",code:"1201",name:"Piutang Usaha",type:"asset"},{id:"coa-ap",code:"2101",name:"Utang Usaha",type:"liability"},{id:"coa-retained",code:"3201",name:"Laba Ditahan",type:"equity"},{id:"coa-revenue",code:"4101",name:"Pendapatan Operasional",type:"revenue"},{id:"coa-expense",code:"5101",name:"Biaya Operasional",type:"expense"}];function an(n="IDR"){return Qe.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}var qe=[{id:"coop-coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coop-coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coop-coa-loan-ar",code:"1201",name:"Piutang Pinjaman Anggota",type:"asset"},{id:"coop-coa-other-ar",code:"1202",name:"Piutang Lain-lain",type:"asset"},{id:"coop-coa-prepaid",code:"1301",name:"Biaya Dibayar Dimuka",type:"asset"},{id:"coop-coa-fixed-asset",code:"1401",name:"Aset Tetap",type:"asset"},{id:"coop-coa-accum-depr",code:"1402",name:"Akumulasi Penyusutan",type:"asset"},{id:"coop-coa-simp-pokok",code:"2101",name:"Simpanan Pokok",type:"liability"},{id:"coop-coa-simp-wajib",code:"2102",name:"Simpanan Wajib",type:"liability"},{id:"coop-coa-simp-sukarela",code:"2103",name:"Simpanan Sukarela",type:"liability"},{id:"coop-coa-simp-berjangka",code:"2104",name:"Simpanan Berjangka",type:"liability"},{id:"coop-coa-ap",code:"2201",name:"Utang Usaha",type:"liability"},{id:"coop-coa-ext-loan",code:"2301",name:"Pinjaman Luar",type:"liability"},{id:"coop-coa-tax-payable",code:"2401",name:"Utang Pajak",type:"liability"},{id:"coop-coa-modal-awal",code:"3101",name:"Modal Awal",type:"equity"},{id:"coop-coa-cadangan-umum",code:"3201",name:"Dana Cadangan Umum",type:"equity"},{id:"coop-coa-cadangan-tujuan",code:"3202",name:"Dana Cadangan Tujuan",type:"equity"},{id:"coop-coa-shu-prior",code:"3301",name:"SHU Tahun Lalu",type:"equity"},{id:"coop-coa-shu-current",code:"3302",name:"SHU Berjalan",type:"equity"},{id:"coop-coa-shu-reserve",code:"3303",name:"Dana SHU Belum Dibagi",type:"equity"},{id:"coop-coa-jasa-pinjaman",code:"4101",name:"Pendapatan Jasa Pinjaman",type:"revenue"},{id:"coop-coa-provisi",code:"4102",name:"Pendapatan Provisi",type:"revenue"},{id:"coop-coa-rev-other",code:"4103",name:"Pendapatan Lain-lain",type:"revenue"},{id:"coop-coa-beban-bunga",code:"5101",name:"Beban Bunga Simpanan",type:"expense"},{id:"coop-coa-beban-ops",code:"5102",name:"Beban Operasional",type:"expense"},{id:"coop-coa-beban-gaji",code:"5103",name:"Beban Gaji dan Tunjangan",type:"expense"},{id:"coop-coa-beban-admin",code:"5104",name:"Beban Administrasi",type:"expense"},{id:"coop-coa-beban-depr",code:"5105",name:"Beban Penyusutan",type:"expense"},{id:"coop-coa-prov-kredit",code:"5106",name:"Cadangan Kerugian Piutang",type:"expense"}];function on(n="IDR"){return qe.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}function cn(n){let e=new Set,t=new Set;for(let r of n){if(!r.id||!r.code||!r.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(r.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(r.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(r.id),t.add(r.code)}return{ok:!0}}export{Qe as CANONICAL_COA_TEMPLATES,qe as COOP_COA_TEMPLATES,l as OFINANCE_TABLES,N as OffinanceCore,J as OffinanceEnvelopeService,j as OfinanceRuntimeCore,k as OfinanceRuntimeCoreBuilder,He as applyFinanceDomainEvent,L as applyPendingMigrations,$t as buildBalanceSheet,Zt as buildBudgetVsRealization,Qt as buildCashflowBaseline,qt as buildClosingJournalDraft,se as buildFinanceComplianceExportBundle,zt as buildFinanceExportEnvelope,O as buildFinanceOpenItemAging,Xt as buildFinanceOperationalComplianceBundle,W as buildFinanceTaxPostingLines,Vt as buildIncomeStatement,X as buildJournalFromCoopLoanDisbursement,ee as buildJournalFromCoopLoanRepayment,K as buildJournalFromCoopSavingDeposit,Z as buildJournalFromCoopSavingWithdrawal,Dt as buildJournalFromCoopShuParticipationManualRecap,z as buildJournalFromPosSale,Lt as buildJournalFromScopedCoopLoanDisbursement,Bt as buildJournalFromScopedCoopLoanRepayment,Mt as buildJournalFromScopedCoopSavingDeposit,xt as buildJournalFromScopedCoopSavingWithdrawal,Nt as buildJournalFromScopedPosSale,an as createCanonicalCoA,on as createCoopCoA,G as createDbAdapterOfinanceServices,kt as createFinanceProjectionSink,Y as createOffinanceEnvelopeService,I as mapOffinanceErrorToEnvelope,_ as projectFinanceCashBankMovements,D as projectFinanceOpenItems,T as reconcileFinanceOpenItems,nn as replayFinanceDomainEvents,re as resolveCoopLoanDisbursementAccountMapping,ae as resolveCoopLoanRepaymentAccountMapping,oe as resolveCoopSavingDepositAccountMapping,ie as resolveCoopSavingWithdrawalAccountMapping,ne as resolvePosSaleAccountMapping,E as resolveScopedAccountMapping,w as summarizeFinanceCashBankMovements,q as toOffinanceFailureEnvelope,f as toOffinanceSuccessEnvelope,cn as validateCoaIntegrity,P as validateJournalBalance,F as validateOpenItemLineMetadata};
3
3
  /*! For license information please see index.esm.js.LEGAL.txt */
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var U=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var he=(n,e)=>{for(var t in e)U(n,t,{get:e[t],enumerable:!0})},Se=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of Ae(e))!be.call(n,a)&&a!==t&&U(n,a,{get:()=>e[a],enumerable:!(r=ye(e,a))||r.enumerable});return n};var Ce=n=>Se(U({},"__esModule",{value:!0}),n);var mn={};he(mn,{CANONICAL_COA_TEMPLATES:()=>fe,COOP_COA_TEMPLATES:()=>ge,OFINANCE_TABLES:()=>d,OffinanceCore:()=>T,OffinanceEnvelopeService:()=>x,OfinanceRuntimeCore:()=>B,OfinanceRuntimeCoreBuilder:()=>J,applyFinanceDomainEvent:()=>Ie,applyPendingMigrations:()=>N,buildBalanceSheet:()=>ze,buildBudgetVsRealization:()=>sn,buildCashflowBaseline:()=>We,buildClosingJournalDraft:()=>Xe,buildFinanceComplianceExportBundle:()=>ae,buildFinanceExportEnvelope:()=>an,buildFinanceOpenItemAging:()=>F,buildFinanceOperationalComplianceBundle:()=>on,buildFinanceTaxPostingLines:()=>$,buildIncomeStatement:()=>Ye,buildJournalFromCoopLoanDisbursement:()=>Y,buildJournalFromCoopLoanRepayment:()=>X,buildJournalFromCoopSavingDeposit:()=>z,buildJournalFromCoopSavingWithdrawal:()=>W,buildJournalFromCoopShuParticipationManualRecap:()=>Je,buildJournalFromPosSale:()=>G,buildJournalFromScopedCoopLoanDisbursement:()=>je,buildJournalFromScopedCoopLoanRepayment:()=>He,buildJournalFromScopedCoopSavingDeposit:()=>Ue,buildJournalFromScopedCoopSavingWithdrawal:()=>Ve,buildJournalFromScopedPosSale:()=>ke,createCanonicalCoA:()=>un,createCoopCoA:()=>pn,createDbAdapterOfinanceServices:()=>q,createFinanceProjectionSink:()=>$e,createOffinanceEnvelopeService:()=>Q,mapOffinanceErrorToEnvelope:()=>I,projectFinanceCashBankMovements:()=>w,projectFinanceOpenItems:()=>O,reconcileFinanceOpenItems:()=>D,replayFinanceDomainEvents:()=>dn,resolveCoopLoanDisbursementAccountMapping:()=>Z,resolveCoopLoanRepaymentAccountMapping:()=>ee,resolveCoopSavingDepositAccountMapping:()=>ne,resolveCoopSavingWithdrawalAccountMapping:()=>te,resolvePosSaleAccountMapping:()=>K,resolveScopedAccountMapping:()=>C,summarizeFinanceCashBankMovements:()=>_,toOffinanceFailureEnvelope:()=>H,toOffinanceSuccessEnvelope:()=>m,validateCoaIntegrity:()=>ln,validateJournalBalance:()=>R,validateOpenItemLineMetadata:()=>P});module.exports=Ce(mn);function R(n){if(!Array.isArray(n)||n.length===0)return{ok:!1,totalDebit:0,totalCredit:0,reason:"JOURNAL_LINES_EMPTY"};let e=0,t=0;for(let r of n){if(!r||!r.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(r.debit<0||r.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=r.debit,t+=r.credit}return Math.abs(e-t)>1e-6?{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NOT_BALANCED"}:{ok:!0,totalDebit:e,totalCredit:t}}var Ee=[{key:"current",label:"Current",maxDaysPastDue:0},{key:"1-30",label:"1-30 days",minDaysPastDue:1,maxDaysPastDue:30},{key:"31-60",label:"31-60 days",minDaysPastDue:31,maxDaysPastDue:60},{key:"61-90",label:"61-90 days",minDaysPastDue:61,maxDaysPastDue:90},{key:"90+",label:"90+ days",minDaysPastDue:91}];function ve(n,e,t){return n==="receivable"?e-t:t-e}function Re(n,e){return[n.tenantId??"",n.branchId??"",n.financeDomainId??"",n.ledgerProfileId??"",e.accountId,e.openItemType??"",e.openItemId??""].join("::")}function oe(n){return n<0?"overpaid":Math.abs(n)<1e-6?"settled":"open"}function Pe(n,e){if(!e)return 0;let t=Date.parse(n)-Date.parse(e);return!Number.isFinite(t)||t<=0?0:Math.floor(t/864e5)}function Oe(n,e){return e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.openItemType&&n.openItemType!==e.openItemType||e.counterpartyRef&&n.counterpartyRef!==e.counterpartyRef||!e.includeSettled&&n.status==="settled"):!0}function P(n){for(let e of n){let t=!!(e.openItemId||e.openItemType),r=!!(e.counterpartyRef||e.documentRef||e.dueAt);if(!(!t&&!r)){if(!e.openItemId)throw new Error("JOURNAL_OPEN_ITEM_ID_REQUIRED");if(!e.openItemType)throw new Error("JOURNAL_OPEN_ITEM_TYPE_REQUIRED");if(e.openItemType!=="receivable"&&e.openItemType!=="payable")throw new Error("JOURNAL_OPEN_ITEM_TYPE_INVALID");if(e.dueAt&&Number.isNaN(Date.parse(e.dueAt)))throw new Error("JOURNAL_OPEN_ITEM_DUE_AT_INVALID")}}}function O(n,e){let t=new Map;for(let r of n)if(r.status==="posted")for(let a of r.lines){if(!a.openItemId||!a.openItemType)continue;let o=Re(r,a),i=ve(a.openItemType,a.debit,a.credit),c=t.get(o);if(!c){let s={tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,openItemId:a.openItemId,openItemType:a.openItemType,accountId:a.accountId,counterpartyRef:a.counterpartyRef,documentRef:a.documentRef,dueAt:a.dueAt,originatedAt:r.occurredAt,lastActivityAt:r.occurredAt,originalAmount:i>0?i:0,settledAmount:i<0?Math.abs(i):0,outstandingAmount:i,status:oe(i)};t.set(o,{item:s});continue}c.item.originatedAt=c.item.originatedAt<r.occurredAt?c.item.originatedAt:r.occurredAt,c.item.lastActivityAt=c.item.lastActivityAt>r.occurredAt?c.item.lastActivityAt:r.occurredAt,c.item.counterpartyRef=a.counterpartyRef??c.item.counterpartyRef,c.item.documentRef=a.documentRef??c.item.documentRef,c.item.dueAt=a.dueAt??c.item.dueAt,i>0?c.item.originalAmount+=i:i<0&&(c.item.settledAmount+=Math.abs(i)),c.item.outstandingAmount+=i,c.item.status=oe(c.item.outstandingAmount)}return Array.from(t.values()).map(({item:r})=>({...r})).filter(r=>Oe(r,e)).sort((r,a)=>r.originatedAt!==a.originatedAt?r.originatedAt.localeCompare(a.originatedAt):r.openItemId.localeCompare(a.openItemId))}function F(n,e){if(Number.isNaN(Date.parse(e.asOf)))throw new Error("FINANCE_OPEN_ITEM_AGING_AS_OF_INVALID");let t=(e.buckets?.length?e.buckets:Ee).map(a=>({...a,amount:0,itemCount:0})),r=0;for(let a of n){if(a.outstandingAmount<=0)continue;r+=a.outstandingAmount;let o=Pe(e.asOf,a.dueAt),i=t.find(c=>{let s=c.minDaysPastDue??Number.NEGATIVE_INFINITY,p=c.maxDaysPastDue??Number.POSITIVE_INFINITY;return o>=s&&o<=p});if(!i)throw new Error("FINANCE_OPEN_ITEM_AGING_BUCKET_UNRESOLVED");i.amount+=a.outstandingAmount,i.itemCount+=1}return{asOf:e.asOf,openItemType:e.openItemType,totalOutstanding:r,buckets:t}}function ie(n,e){return`${e??""}::${n}`}function Fe(n){if(!n.openItemId?.trim())throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_ID_REQUIRED");if(!Number.isFinite(n.observedAmount)||n.observedAmount<0)throw new Error("FINANCE_RECONCILIATION_OBSERVED_AMOUNT_INVALID");if(n.openItemType&&n.openItemType!=="receivable"&&n.openItemType!=="payable")throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_TYPE_INVALID")}function De(n,e){let t=new Map;for(let r of n){Fe(r);let a=r.openItemType??e,o=ie(r.openItemId,a),i=t.get(o);if(!i){t.set(o,{openItemId:r.openItemId,openItemType:a,observedAmount:r.observedAmount,counterpartyRef:r.counterpartyRef,documentRef:r.documentRef,references:r.reference?[r.reference]:[]});continue}i.observedAmount+=r.observedAmount,i.counterpartyRef=r.counterpartyRef??i.counterpartyRef,i.documentRef=r.documentRef??i.documentRef,r.reference&&i.references.push(r.reference)}return t}function we(n,e,t){let r=n.outstandingAmount,a=e?.observedAmount??0,o=a-r;if(!e)return{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:r,observedAmount:a,varianceAmount:o,status:"missing",reason:"FINANCE_RECONCILIATION_OBSERVATION_MISSING",observedReferences:[]};let i=e.counterpartyRef&&n.counterpartyRef&&e.counterpartyRef!==n.counterpartyRef||e.documentRef&&n.documentRef&&e.documentRef!==n.documentRef,c="matched",s;return i?(c="mismatch",s="FINANCE_RECONCILIATION_METADATA_MISMATCH"):Math.abs(o)<=t?c="matched":o<0?(c="under",s="FINANCE_RECONCILIATION_OBSERVED_UNDER"):o>0&&(c="over",s="FINANCE_RECONCILIATION_OBSERVED_OVER"),{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:r,observedAmount:a,varianceAmount:o,status:c,reason:s,observedReferences:[...e.references]}}function _e(n,e){return{tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType??e.openItemType,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,expectedAmount:0,observedAmount:n.observedAmount,varianceAmount:n.observedAmount,status:"mismatch",reason:"FINANCE_RECONCILIATION_EXPECTED_ITEM_NOT_FOUND",observedReferences:[...n.references]}}function D(n,e){let t=e.toleranceAmount??0;if(!Number.isFinite(t)||t<0)throw new Error("FINANCE_RECONCILIATION_TOLERANCE_INVALID");let r=De(e.observations,e.openItemType),a=[];for(let s of n){let p=ie(s.openItemId,s.openItemType),f=r.get(p);a.push(we(s,f,t)),r.delete(p)}for(let s of r.values())a.push(_e(s,e));a.sort((s,p)=>(s.financeDomainId??"")!==(p.financeDomainId??"")?(s.financeDomainId??"").localeCompare(p.financeDomainId??""):(s.ledgerProfileId??"")!==(p.ledgerProfileId??"")?(s.ledgerProfileId??"").localeCompare(p.ledgerProfileId??""):s.openItemId.localeCompare(p.openItemId));let o=a.reduce((s,p)=>s+p.expectedAmount,0),i=a.reduce((s,p)=>s+p.observedAmount,0),c=a.reduce((s,p)=>s+p.varianceAmount,0);return{openItemType:e.openItemType,totalExpectedAmount:o,totalObservedAmount:i,totalVarianceAmount:c,rows:a}}function Te(n){if(!Array.isArray(n.trackedAccountIds)||n.trackedAccountIds.length===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");let e=new Set(n.trackedAccountIds.map(t=>t.trim()).filter(Boolean));if(e.size===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");return e}function Ne(n,e){return!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt>e.occurredTo)}function w(n,e){let t=Te(e),r=[];for(let a of n){if(a.status!=="posted"||!Ne(a,e))continue;let o=a.lines.filter(l=>t.has(l.accountId)&&(l.debit>0||l.credit>0));if(o.length===0)continue;let i=Array.from(new Set(o.map(l=>l.accountId))).sort(),c=Array.from(new Set(a.lines.filter(l=>!t.has(l.accountId)&&(l.debit>0||l.credit>0)).map(l=>l.accountId))).sort(),s=o.some(l=>l.debit>0),p=o.some(l=>l.credit>0),f=i.length>1&&s&&p;for(let l of o)l.debit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:l.accountId,direction:f?"transfer_in":"in",amount:l.debit,counterpartAccountIds:c,trackedAccountIdsInJournal:i}),l.credit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:l.accountId,direction:f?"transfer_out":"out",amount:l.credit,counterpartAccountIds:c,trackedAccountIdsInJournal:i})}return r.sort((a,o)=>a.occurredAt!==o.occurredAt?a.occurredAt.localeCompare(o.occurredAt):a.journalId!==o.journalId?a.journalId.localeCompare(o.journalId):a.accountId.localeCompare(o.accountId))}function _(n){let e=0,t=0,r=0,a=0;for(let o of n)o.direction==="in"&&(e+=o.amount),o.direction==="out"&&(t+=o.amount),o.direction==="transfer_in"&&(r+=o.amount),o.direction==="transfer_out"&&(a+=o.amount);return{totalInflow:e,totalOutflow:t,totalTransferIn:r,totalTransferOut:a,netExternalMovement:e-t,entries:n.map(o=>({...o,counterpartAccountIds:[...o.counterpartAccountIds],trackedAccountIdsInJournal:[...o.trackedAccountIdsInJournal]}))}}var T=class{constructor(e){this.state={accounts:e?.accounts??new Map,periods:e?.periods??new Map,journals:e?.journals??new Map,balances:e?.balances??new Map,rapbPlans:e?.rapbPlans??new Map}}createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");if(this.state.accounts.has(e.id))throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if(Array.from(this.state.accounts.values()).some(r=>r.code===e.code))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");return this.state.accounts.set(e.id,{...e}),{...e}}listAccounts(){return Array.from(this.state.accounts.values()).map(e=>({...e})).sort((e,t)=>e.code.localeCompare(t.code))}openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(this.state.periods.has(e.id))throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t={...e,status:"open"};return this.state.periods.set(t.id,t),{...t}}closeFiscalPeriod(e){let t=this.state.periods.get(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed"};return this.state.periods.set(e,r),{...r}}listFiscalPeriods(){return Array.from(this.state.periods.values()).map(e=>({...e})).sort((e,t)=>e.startDate.localeCompare(t.startDate))}createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(this.state.journals.has(e.id))throw new Error("JOURNAL_ALREADY_EXISTS");this.assertJournalLinesKnownAccounts(e.lines),this.assertJournalPeriodOpen(e.occurredAt),P(e.lines);let t=R(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,lines:e.lines.map(a=>({...a})),status:"draft"};return this.state.journals.set(r.id,r),{...r,lines:r.lines.map(a=>({...a}))}}postJournal(e,t=new Date().toISOString()){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status==="posted"||r.status==="reversed")return{...r,lines:r.lines.map(o=>({...o}))};this.applyLinesToBalance(r.lines);let a={...r,status:"posted",postedAt:t};return this.state.journals.set(e,a),{...a,lines:a.lines.map(o=>({...o}))}}reverseJournal(e,t){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let a=r.lines.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo,openItemId:i.openItemId,openItemType:i.openItemType,counterpartyRef:i.counterpartyRef,documentRef:i.documentRef,dueAt:i.dueAt})),o=this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a});return this.postJournal(o.id)}getTrialBalance(){return this.getTrialBalanceByScope()}getTrialBalanceByScope(e){let t=this.computeScopedBalances(e);return this.listAccounts().map(a=>{let o=t.get(a.id)??{debit:0,credit:0};return{accountId:a.id,accountCode:a.code,accountName:a.name,accountType:a.type,debit:o.debit,credit:o.credit,net:o.debit-o.credit}})}listJournals(e){return Array.from(this.state.journals.values()).filter(t=>this.matchesScope(t,e)).map(t=>({...t,lines:t.lines.map(r=>({...r}))})).sort((t,r)=>t.occurredAt.localeCompare(r.occurredAt))}listOpenItems(e){return O(this.listJournals(e),e)}getOpenItemAging(e){return F(this.listOpenItems(e),e)}reconcileOpenItems(e){return D(this.listOpenItems(e),e)}listCashBankMovements(e){return w(this.listJournals(e),e)}summarizeCashBankMovements(e){return _(this.listCashBankMovements(e))}assertJournalLinesKnownAccounts(e){for(let t of e)if(!this.state.accounts.has(t.accountId))throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}assertJournalPeriodOpen(e){if(this.state.periods.size===0)return;let t=this.findPeriodByDate(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(t.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}findPeriodByDate(e){let t=Date.parse(e);for(let r of this.state.periods.values()){let a=Date.parse(r.startDate),o=Date.parse(r.endDate);if(t>=a&&t<=o)return r}return null}applyLinesToBalance(e){for(let t of e){let r=this.state.balances.get(t.accountId)??{debit:0,credit:0};r.debit+=t.debit,r.credit+=t.credit,this.state.balances.set(t.accountId,r)}}computeScopedBalances(e){if(!e||!e.tenantId&&!e.branchId&&!e.financeDomainId&&!e.ledgerProfileId&&!e.occurredFrom&&!e.occurredTo)return this.state.balances;let t=new Map;for(let r of this.state.journals.values())if(r.status==="posted"&&this.matchesScope(r,e))for(let a of r.lines){let o=t.get(a.accountId)??{debit:0,credit:0};o.debit+=a.debit,o.credit+=a.credit,t.set(a.accountId,o)}return t}matchesScope(e,t){return t?!(t.tenantId&&e.tenantId!==t.tenantId||t.branchId&&e.branchId!==t.branchId||t.financeDomainId&&e.financeDomainId!==t.financeDomainId||t.ledgerProfileId&&e.ledgerProfileId!==t.ledgerProfileId||t.occurredFrom&&e.occurredAt<t.occurredFrom||t.occurredTo&&e.occurredAt>t.occurredTo):!0}createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(this.state.rapbPlans.has(e.id))throw new Error("RAPB_ALREADY_EXISTS");if(e.lines.some(a=>a.budgetedDebit<0||a.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=e.lines.map(a=>{let o=this.state.accounts.get(a.accountId);if(!o)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${a.accountId}`);let i=a.budgetedDebit-a.budgetedCredit;return{accountId:a.accountId,accountCode:o.code,accountName:o.name,accountType:o.type,budgetedDebit:a.budgetedDebit,budgetedCredit:a.budgetedCredit,budgetedNet:i}}),r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",lines:t,notes:e.notes,createdAt:new Date().toISOString()};return this.state.rapbPlans.set(r.id,r),r}getRapb(e){return this.state.rapbPlans.get(e)??null}listRapb(e){let t=Array.from(this.state.rapbPlans.values());return e&&(e.tenantId&&(t=t.filter(r=>r.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(r=>r.periodCode===e.periodCode)),e.branchId&&(t=t.filter(r=>r.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(r=>r.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(r=>r.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let r=this.state.rapbPlans.get(e);if(!r)throw new Error("RAPB_NOT_FOUND");let a=typeof t=="string"?t:t.approvedBy;if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...r,status:"approved",approvedAt:new Date().toISOString(),approvedBy:a};return this.state.rapbPlans.set(e,o),o}evaluateVariance(e){let t=this.state.rapbPlans.get(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=this.getTrialBalance(),a=new Map(r.map(u=>[u.accountId,u])),o=0,i=0,c=0,s=0,p=t.lines.map(u=>{let E=a.get(u.accountId),g=E?.debit??0,y=E?.credit??0,v=g-y;return u.accountType==="revenue"?(o+=u.budgetedCredit-u.budgetedDebit,i+=y-g):u.accountType==="expense"&&(c+=u.budgetedDebit-u.budgetedCredit,s+=g-y),{accountId:u.accountId,accountCode:u.accountCode,accountName:u.accountName,accountType:u.accountType,budgetedDebit:u.budgetedDebit,budgetedCredit:u.budgetedCredit,budgetedNet:u.budgetedNet,actualDebit:g,actualCredit:y,actualNet:v,varianceDebit:g-u.budgetedDebit,varianceCredit:y-u.budgetedCredit,varianceNet:v-u.budgetedNet}}),f=o-c,l=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:p,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:f,actualNetIncome:l,netVariance:l-f}}};var se=require("ofcore"),de=require("ofcore"),k=require("ofcore");var d={accounts:"ofinance_accounts",periods:"ofinance_periods",journals:"ofinance_journals",journalLines:"ofinance_journal_lines",rapbPlans:"ofinance_rapb_plans",rapbLines:"ofinance_rapb_lines",histories:"ofinance_histories"},Le=[{name:d.accounts,columns:[{name:"id",type:"string"},{name:"code",type:"string",isIndexed:!0},{name:"name",type:"string"},{name:"type",type:"string",isIndexed:!0},{name:"currency",type:"string"},{name:"isActive",type:"boolean",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.periods,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"code",type:"string",isIndexed:!0},{name:"startDate",type:"string",isIndexed:!0},{name:"endDate",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.journals,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"occurredAt",type:"string",isIndexed:!0},{name:"reference",type:"string",isOptional:!0,isIndexed:!0},{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.journalLines,columns:[{name:"id",type:"string"},{name:"journalId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"debit",type:"number"},{name:"credit",type:"number"},{name:"memo",type:"string",isOptional:!0},{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.rapbPlans,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"periodCode",type:"string",isIndexed:!0},{name:"title",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"notes",type:"string",isOptional:!0},{name:"createdAt",type:"string",isIndexed:!0},{name:"approvedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"approvedBy",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.rapbLines,columns:[{name:"id",type:"string"},{name:"rapbId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"accountCode",type:"string",isIndexed:!0},{name:"accountName",type:"string"},{name:"accountType",type:"string",isIndexed:!0},{name:"budgetedDebit",type:"number"},{name:"budgetedCredit",type:"number"},{name:"budgetedNet",type:"number"},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:d.histories,columns:[{name:"id",type:"string"},{name:"tableName",type:"string",isIndexed:!0},{name:"recordId",type:"string",isIndexed:!0},{name:"action",type:"string",isIndexed:!0},{name:"changes",type:"json",isOptional:!0},{name:"timestamp",type:"string",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0}]}];function V(){return Le.map(n=>({...n,columns:n.columns.map(e=>({...e}))}))}var ce=[{toVersion:1,up:async n=>{let e=V();for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:2,up:async n=>{let e=V().filter(t=>t.name==="ofinance_rapb_plans"||t.name==="ofinance_rapb_lines");for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:3,up:async n=>{try{await n.addColumn("ofinance_journals",{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0})}catch{}}},{toVersion:4,up:async n=>{let e=[{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0}];for(let t of e)try{await n.addColumn("ofinance_journal_lines",t)}catch{}}}];var xe={logInfo(){},logWarn(){},logError(){}};async function N(n,e=xe){e.logInfo("[offinance] starting database migration process");let t=[...ce].sort((o,i)=>o.toVersion-i.toVersion),r=t.length>0?t[t.length-1].toVersion:0,a=await n.getSchemaVersion();if((a==null||a<0)&&(a=0),a>=r){e.logInfo(`[offinance] database already up-to-date at v${a}`);return}for(let o of t)o.toVersion>a&&(e.logInfo(`[offinance] applying migration v${o.toVersion}`),await o.up(n),await n.setSchemaVersion(o.toVersion),a=o.toVersion);e.logInfo(`[offinance] migration completed at v${a}`)}function m(n,e){return{data:n,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function H(n,e,t={}){return{error:{code:n,message:e,details:t.details,retryable:t.retryable,correlationId:t.correlationId,timestamp:new Date().toISOString()},meta:{request_id:t.requestId??null,timestamp:new Date().toISOString()}}}function I(n,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return n instanceof Error?H(e,n.message||t):H(e,t)}var x=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return m(await this.legacy.accountService.createAccount(t))}catch(r){return I(r)}},listAccounts:async()=>{try{return m(await this.legacy.accountService.listAccounts())}catch(t){return I(t)}}},this.journalService={createJournalDraft:async t=>{try{return m(await this.legacy.journalService.createJournalDraft(t))}catch(r){return I(r)}},postJournal:async(t,r)=>{try{return m(await this.legacy.journalService.postJournal(t,r))}catch(a){return I(a)}},reverseJournal:async(t,r)=>{try{return m(await this.legacy.journalService.reverseJournal(t,r))}catch(a){return I(a)}},listJournals:async t=>{try{return m(await this.legacy.journalService.listJournals(t))}catch(r){return I(r)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return m(await this.legacy.fiscalService.openFiscalPeriod(t))}catch(r){return I(r)}},closeFiscalPeriod:async t=>{try{return m(await this.legacy.fiscalService.closeFiscalPeriod(t))}catch(r){return I(r)}},listFiscalPeriods:async()=>{try{return m(await this.legacy.fiscalService.listFiscalPeriods())}catch(t){return I(t)}},getTrialBalance:async()=>{try{return m(await this.legacy.fiscalService.getTrialBalance())}catch(t){return I(t)}},getTrialBalanceByScope:async t=>{try{return m(await this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(r){return I(r)}}},this.rapbService={createRapb:async t=>{try{return m(await this.legacy.rapbService.createRapb(t))}catch(r){return I(r)}},getRapb:async t=>{try{return m(await this.legacy.rapbService.getRapb(t))}catch(r){return I(r)}},listRapb:async t=>{try{return m(await this.legacy.rapbService.listRapb(t))}catch(r){return I(r)}},approveRapb:async(t,r)=>{try{return m(await this.legacy.rapbService.approveRapb(t,r))}catch(a){return I(a)}},evaluateVariance:async t=>{try{return m(await this.legacy.rapbService.evaluateVariance(t))}catch(r){return I(r)}}},this.openItemService={listOpenItems:async t=>{try{return m(await this.legacy.openItemService.listOpenItems(t))}catch(r){return I(r)}},getOpenItemAging:async t=>{try{return m(await this.legacy.openItemService.getOpenItemAging(t))}catch(r){return I(r)}}},this.reconciliationService={reconcileOpenItems:async t=>{try{return m(await this.legacy.reconciliationService.reconcileOpenItems(t))}catch(r){return I(r)}}},this.cashMovementService={listCashBankMovements:async t=>{try{return m(await this.legacy.cashMovementService.listCashBankMovements(t))}catch(r){return I(r)}},summarizeCashBankMovements:async t=>{try{return m(await this.legacy.cashMovementService.summarizeCashBankMovements(t))}catch(r){return I(r)}}}}};function Q(n){return new x({accountService:n,journalService:n,fiscalService:n,rapbService:n,openItemService:n,reconciliationService:n,cashMovementService:n})}function b(n){return JSON.parse(JSON.stringify(n))}function A(){return new Date().toISOString()}function Me(n,e){return`${n}:${e}:${Date.now()}:${Math.random().toString(36).slice(2,8)}`}function Be(n,e){return!n||n.deleted?!1:e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt&&n.occurredAt>e.occurredTo):!0}var M=class{constructor(e){this.dbAdapter=e}async createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");let t=await this.dbAdapter.get(d.accounts,e.id);if(t&&!t.deleted)throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if((await this.dbAdapter.query(d.accounts,{filters:{and:[{field:"code",value:e.code},{field:"deleted",value:!1}]}})).some(i=>i.id!==e.id))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");let a=A(),o={...b(e),lastModified:a,deleted:!1};return t?await this.dbAdapter.update(d.accounts,e.id,o):await this.dbAdapter.create(d.accounts,o),await this.writeHistory("accounts",e.id,"UPSERT",o),b(e)}async listAccounts(){return(await this.dbAdapter.query(d.accounts,{filters:{field:"deleted",value:!1}})).map(({lastModified:t,deleted:r,...a})=>b(a)).sort((t,r)=>t.code.localeCompare(r.code))}async createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(!e.ledgerProfileId)throw new Error("JOURNAL_REQUIRED_FIELDS");let t=await this.dbAdapter.get(d.journals,e.id);if(t&&!t.deleted)throw new Error("JOURNAL_ALREADY_EXISTS");await this.assertJournalLinesKnownAccounts(e.lines),await this.assertJournalPeriodOpen(e),P(e.lines);let r=R(e.lines);if(!r.ok)throw new Error(r.reason??"JOURNAL_INVALID");let a=A(),o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,status:"draft",postedAt:void 0,lastModified:a,deleted:!1};await this.dbAdapter.create(d.journals,o);for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s={id:`${e.id}:line:${i}`,journalId:e.id,accountId:c.accountId,debit:c.debit,credit:c.credit,memo:c.memo,openItemId:c.openItemId,openItemType:c.openItemType,counterpartyRef:c.counterpartyRef,documentRef:c.documentRef,dueAt:c.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:a,deleted:!1};await this.dbAdapter.create(d.journalLines,s),await this.writeHistory("journal_lines",s.id,"UPSERT",s)}return await this.writeHistory("journals",e.id,"UPSERT",o),this.toJournalEntry(o,e.lines)}async postJournal(e,t=A()){let r=await this.requireJournal(e),a=await this.listJournalLines(e);if(r.status==="posted"||r.status==="reversed")return this.toJournalEntry(r,a);let o={...r,status:"posted",postedAt:t,lastModified:A()};return await this.dbAdapter.update(d.journals,e,o),await this.writeHistory("journals",e,"UPSERT",o),this.toJournalEntry(o,a)}async reverseJournal(e,t){let r=await this.requireJournal(e);if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");let a=await this.listJournalLines(e),o=await this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo,openItemId:i.openItemId,openItemType:i.openItemType,counterpartyRef:i.counterpartyRef,documentRef:i.documentRef,dueAt:i.dueAt}))});return this.postJournal(o.id)}async listJournals(e){let r=(await this.dbAdapter.query(d.journals,{filters:{field:"deleted",value:!1}})).filter(o=>Be(o,e)).sort((o,i)=>o.occurredAt.localeCompare(i.occurredAt)),a=[];for(let o of r){let i=await this.listJournalLines(o.id);a.push(this.toJournalEntry(o,i))}return a}async listOpenItems(e){return O(await this.listJournals(e),e)}async getOpenItemAging(e){return F(await this.listOpenItems(e),e)}async reconcileOpenItems(e){return D(await this.listOpenItems(e),e)}async listCashBankMovements(e){return w(await this.listJournals(e),e)}async summarizeCashBankMovements(e){return _(await this.listCashBankMovements(e))}async openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t=await this.dbAdapter.get(d.periods,e.id);if(t&&!t.deleted)throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");let r=A(),a={...b(e),status:"open",lastModified:r,deleted:!1};return t?await this.dbAdapter.update(d.periods,e.id,a):await this.dbAdapter.create(d.periods,a),await this.writeHistory("periods",e.id,"UPSERT",a),this.toPeriod(a)}async closeFiscalPeriod(e){let t=await this.dbAdapter.get(d.periods,e);if(!t||t.deleted)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed",lastModified:A()};return await this.dbAdapter.update(d.periods,e,r),await this.writeHistory("periods",e,"UPSERT",r),this.toPeriod(r)}async listFiscalPeriods(){return(await this.dbAdapter.query(d.periods,{filters:{field:"deleted",value:!1}})).map(t=>this.toPeriod(t)).sort((t,r)=>t.startDate.localeCompare(r.startDate))}async getTrialBalance(){return this.getTrialBalanceByScope()}async getTrialBalanceByScope(e){let t=await this.listAccounts(),a=(await this.listJournals(e)).filter(i=>i.status==="posted"),o=new Map;for(let i of a)for(let c of i.lines){let s=o.get(c.accountId)??{debit:0,credit:0};s.debit+=Number(c.debit||0),s.credit+=Number(c.credit||0),o.set(c.accountId,s)}return t.map(i=>{let c=o.get(i.id)??{debit:0,credit:0};return{accountId:i.id,accountCode:i.code,accountName:i.name,accountType:i.type,debit:c.debit,credit:c.credit,net:c.debit-c.credit}})}async createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(e.lines.some(i=>i.budgetedDebit<0||i.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=await this.dbAdapter.get(d.rapbPlans,e.id);if(t&&!t.deleted)throw new Error("RAPB_ALREADY_EXISTS");let r=A(),a=[];for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s=await this.dbAdapter.get(d.accounts,c.accountId);if(!s||s.deleted)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${c.accountId}`);a.push({id:`${e.id}:line:${i}`,rapbId:e.id,accountId:c.accountId,accountCode:s.code,accountName:s.name,accountType:s.type,budgetedDebit:c.budgetedDebit,budgetedCredit:c.budgetedCredit,budgetedNet:c.budgetedDebit-c.budgetedCredit,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:r,deleted:!1})}let o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",notes:e.notes,createdAt:r,approvedAt:void 0,approvedBy:void 0,lastModified:r,deleted:!1};await this.dbAdapter.create(d.rapbPlans,o),await this.writeHistory("rapb_plans",e.id,"UPSERT",o);for(let i of a)await this.dbAdapter.create(d.rapbLines,i),await this.writeHistory("rapb_lines",i.id,"UPSERT",i);return this.toRapbPlan(o,a)}async getRapb(e){let t=await this.dbAdapter.get(d.rapbPlans,e);if(!t||t.deleted)return null;let r=await this.listRapbLines(e);return this.toRapbPlan(t,r)}async listRapb(e){let r=await this.dbAdapter.query(d.rapbPlans,{filters:{field:"deleted",value:!1}});e&&(e.tenantId&&(r=r.filter(o=>o.tenantId===e.tenantId)),e.periodCode&&(r=r.filter(o=>o.periodCode===e.periodCode)),e.branchId&&(r=r.filter(o=>o.branchId===e.branchId)),e.financeDomainId&&(r=r.filter(o=>o.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(r=r.filter(o=>o.ledgerProfileId===e.ledgerProfileId)));let a=[];for(let o of r.sort((i,c)=>i.createdAt.localeCompare(c.createdAt))){let i=await this.listRapbLines(o.id);a.push(this.toRapbPlan(o,i))}return a}async approveRapb(e,t){let r=await this.dbAdapter.get(d.rapbPlans,e);if(!r||r.deleted)throw new Error("RAPB_NOT_FOUND");if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let a=typeof t=="string"?t:t.approvedBy,o={...r,status:"approved",approvedAt:A(),approvedBy:a,lastModified:A()};await this.dbAdapter.update(d.rapbPlans,e,o),await this.writeHistory("rapb_plans",e,"UPSERT",o);let i=await this.listRapbLines(e);return this.toRapbPlan(o,i)}async evaluateVariance(e){let t=await this.getRapb(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=await this.getTrialBalanceByScope({tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId}),a=new Map(r.map(u=>[u.accountId,u])),o=0,i=0,c=0,s=0,p=t.lines.map(u=>{let E=a.get(u.accountId),g=E?.debit??0,y=E?.credit??0,v=g-y;return u.accountType==="revenue"?(o+=u.budgetedCredit-u.budgetedDebit,i+=y-g):u.accountType==="expense"&&(c+=u.budgetedDebit-u.budgetedCredit,s+=g-y),{accountId:u.accountId,accountCode:u.accountCode,accountName:u.accountName,accountType:u.accountType,budgetedDebit:u.budgetedDebit,budgetedCredit:u.budgetedCredit,budgetedNet:u.budgetedNet,actualDebit:g,actualCredit:y,actualNet:v,varianceDebit:g-u.budgetedDebit,varianceCredit:y-u.budgetedCredit,varianceNet:v-u.budgetedNet}}),f=o-c,l=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:A(),lines:p,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:f,actualNetIncome:l,netVariance:l-f}}async assertJournalLinesKnownAccounts(e){for(let t of e){let r=await this.dbAdapter.get(d.accounts,t.accountId);if(!r||r.deleted)throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}}async assertJournalPeriodOpen(e){let t=await this.dbAdapter.query(d.periods,{filters:{field:"deleted",value:!1}});if(t.length===0)return;let r=t.find(a=>!(a.tenantId!==e.tenantId||Date.parse(a.startDate)>Date.parse(e.occurredAt)||Date.parse(a.endDate)<Date.parse(e.occurredAt)||e.ledgerProfileId&&a.ledgerProfileId&&a.ledgerProfileId!==e.ledgerProfileId||e.financeDomainId&&a.financeDomainId&&a.financeDomainId!==e.financeDomainId));if(!r)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(r.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}async requireJournal(e){let t=await this.dbAdapter.get(d.journals,e);if(!t||t.deleted)throw new Error("JOURNAL_NOT_FOUND");return t}async listJournalLines(e){return(await this.dbAdapter.query(d.journalLines,{filters:{and:[{field:"journalId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}async listRapbLines(e){return(await this.dbAdapter.query(d.rapbLines,{filters:{and:[{field:"rapbId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}toJournalEntry(e,t){let{lastModified:r,deleted:a,...o}=e;return{...b(o),lines:t.map(i=>b(i))}}toPeriod(e){let{lastModified:t,deleted:r,...a}=e;return b(a)}toRapbPlan(e,t){let{lastModified:r,deleted:a,...o}=e;return{...b(o),lines:t.map(({id:i,rapbId:c,lastModified:s,deleted:p,...f})=>b(f))}}async writeHistory(e,t,r,a){let o=a,i={id:Me(e,t),tableName:e,recordId:t,action:r,changes:b(o),timestamp:A(),tenantId:typeof o.tenantId=="string"?o.tenantId:void 0,branchId:typeof o.branchId=="string"?o.branchId:void 0,financeDomainId:typeof o.financeDomainId=="string"?o.financeDomainId:void 0,ledgerProfileId:typeof o.ledgerProfileId=="string"?o.ledgerProfileId:void 0};await this.dbAdapter.create(d.histories,i)}};async function q(n){await N(n);let e=new M(n);return{financeService:Q({createAccount:e.createAccount.bind(e),listAccounts:e.listAccounts.bind(e),createJournalDraft:e.createJournalDraft.bind(e),postJournal:e.postJournal.bind(e),reverseJournal:e.reverseJournal.bind(e),listJournals:e.listJournals.bind(e),openFiscalPeriod:e.openFiscalPeriod.bind(e),closeFiscalPeriod:e.closeFiscalPeriod.bind(e),listFiscalPeriods:e.listFiscalPeriods.bind(e),getTrialBalance:e.getTrialBalance.bind(e),getTrialBalanceByScope:e.getTrialBalanceByScope.bind(e),createRapb:e.createRapb.bind(e),getRapb:e.getRapb.bind(e),listRapb:e.listRapb.bind(e),approveRapb:e.approveRapb.bind(e),evaluateVariance:e.evaluateVariance.bind(e),listOpenItems:e.listOpenItems.bind(e),getOpenItemAging:e.getOpenItemAging.bind(e),reconcileOpenItems:e.reconcileOpenItems.bind(e),listCashBankMovements:e.listCashBankMovements.bind(e),summarizeCashBankMovements:e.summarizeCashBankMovements.bind(e)})}}var B=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=(0,k.asReadonlyStore)(this.runtimeStateStore)}static builder(){return new J}get registry(){return this.runtime.registry}async start(e={}){this.runtimeStateStore.setState({phase:"starting",started:!1,lastError:null,lastTransitionAt:new Date().toISOString(),startCount:this.runtimeStateStore.getState().startCount,stopCount:this.runtimeStateStore.getState().stopCount});try{await this.runtime.start(e),this.domainServices=this.runtime.domainServices,this.runtimeStateStore.setState(t=>({...t,phase:"started",started:!0,startCount:t.startCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(t){throw this.runtimeStateStore.setState(r=>({...r,phase:"error",started:!1,lastError:t instanceof Error?t.message:String(t),lastTransitionAt:new Date().toISOString()})),t}}async stop(){this.runtimeStateStore.setState(e=>({...e,phase:"stopping",started:this.runtime.isStarted(),lastError:null,lastTransitionAt:new Date().toISOString()}));try{await this.runtime.stop(),this.runtimeStateStore.setState(e=>({...e,phase:"stopped",started:!1,stopCount:e.stopCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(e){throw this.runtimeStateStore.setState(t=>({...t,phase:"error",started:this.runtime.isStarted(),lastError:e instanceof Error?e.message:String(e),lastTransitionAt:new Date().toISOString()})),e}}isStarted(){return this.runtime.isStarted()}},J=class{constructor(){this.runtimeBuilder=se.CoreRuntime.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new de.InMemoryDbAdapter)}withPlatformAdapter(e){return this.runtimeBuilder.withPlatformAdapter(e),this}withDbAdapter(e){return this.runtimeBuilder.withDbAdapter(e),this}withHttpAdapter(e){return this.runtimeBuilder.withHttpAdapter(e),this}withSocketAdapter(e){return this.runtimeBuilder.withSocketAdapter(e),this}withLoggerAdapter(e){return this.runtimeBuilder.withLoggerAdapter(e),this}withActivitySink(e){return this.runtimeBuilder.withActivitySink(e),this}withExtension(e,t){return this.runtimeBuilder.withExtension(e,t),this}withDomainServicesFactory(e){return this.domainServicesFactory=e,this}withRuntimeHooks(e){return this.runtimeHooks={...this.runtimeHooks,...e},this}build(){let e=(0,k.createStore)({phase:"idle",started:!1,startCount:0,stopCount:0,lastError:null,lastTransitionAt:new Date().toISOString()}),t={runMigrations:async a=>{let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");await N(o,a.registry?.loggerAdapter),this.runtimeHooks.runMigrations&&await this.runtimeHooks.runMigrations(a)},...this.runtimeHooks,createDomainServices:async a=>{if(this.domainServicesFactory)return this.domainServicesFactory();let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");return q(o)}};this.runtimeBuilder.withHooks(t);let r=this.runtimeBuilder.build();return new B(r,e)}};function $(n){return!Array.isArray(n.components)||n.components.length===0?[]:n.components.map(e=>{if(!e.accountId?.trim())throw new Error("FINANCE_TAX_ACCOUNT_REQUIRED");if(!Number.isFinite(e.amount)||e.amount<=0)throw new Error("FINANCE_TAX_AMOUNT_INVALID");if(e.direction!=="payable"&&e.direction!=="receivable")throw new Error("FINANCE_TAX_DIRECTION_INVALID");let t=`${n.memoPrefix??"Finance tax"} ${e.direction}`;return{accountId:e.accountId,debit:e.direction==="receivable"?e.amount:0,credit:e.direction==="payable"?e.amount:0,memo:e.memo??t}})}function h(n,e,t){return{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:t?`${n.reference??""}${t}`:n.reference,evidenceRef:n.evidenceRef,lines:e}}function S(n,e){if(!Number.isFinite(n)||n<=0)throw new Error(e)}function G(n,e){S(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,r=e.taxAmount??0;if(t<0||r<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let a=e.grossAmount,o=a-t+r,i=[{accountId:e.paymentAccountId,debit:o,credit:0,memo:"POS sale payment"},{accountId:e.revenueAccountId,debit:0,credit:a,memo:"POS sale revenue"}];if(t>0){if(!e.discountAccountId)throw new Error("POS_SALE_DISCOUNT_ACCOUNT_REQUIRED");i.push({accountId:e.discountAccountId,debit:t,credit:0,memo:"POS sale discount"})}if(r>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");i.push(...$({memoPrefix:"POS sale tax",components:[{accountId:e.taxPayableAccountId,amount:r,direction:"payable",memo:"POS sale tax payable"}]}))}return h(n,i)}function Y(n,e){return S(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),h(n,[{accountId:e.receivableAccountId,debit:e.principalAmount,credit:0,memo:"Loan receivable principal"},{accountId:e.cashAccountId,debit:0,credit:e.principalAmount,memo:"Loan cash out"}])}function z(n,e){return S(e.amount,"COOP_SAVING_INVALID_AMOUNT"),h(n,[{accountId:e.cashAccountId,debit:e.amount,credit:0,memo:"Saving deposit cash in"},{accountId:e.savingLiabilityAccountId,debit:0,credit:e.amount,memo:"Saving liability increase"}])}function W(n,e){return S(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),h(n,[{accountId:e.savingLiabilityAccountId,debit:e.amount,credit:0,memo:"Saving liability decrease"},{accountId:e.cashAccountId,debit:0,credit:e.amount,memo:"Saving withdrawal cash out"}])}function X(n,e){S(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,r=e.penaltyAmount??0;if(t<0||r<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(r>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let a=e.principalAmount+t+r,o=[{accountId:e.cashAccountId,debit:a,credit:0,memo:"Loan repayment cash in"},{accountId:e.receivableAccountId,debit:0,credit:e.principalAmount,memo:"Loan receivable principal repayment"}];return t>0&&o.push({accountId:e.serviceRevenueAccountId,debit:0,credit:t,memo:"Loan service revenue"}),r>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:r,memo:"Loan penalty revenue"}),h(n,o)}function Je(n,e){if(S(e.amount,"COOP_SHU_PARTICIPATION_INVALID_AMOUNT"),!n.evidenceRef?.trim())throw new Error("COOP_SHU_PARTICIPATION_EVIDENCE_REQUIRED");return h(n,[{accountId:e.debitAccountId,debit:e.amount,credit:0,memo:e.memo??"Coop SHU participation manual recap debit"},{accountId:e.creditAccountId,debit:0,credit:e.amount,memo:e.memo??"Coop SHU participation manual recap credit"}])}function ue(n,e){return e?{...n,...e}:{...n}}function C(n){let e=n.tenantId?n.scopedMapping.byTenant?.[n.tenantId]:void 0,t=n.tenantId&&n.branchId?`${n.tenantId}:${n.branchId}`:"",r=t?n.scopedMapping.byBranch?.[t]:void 0;return ue(ue(n.scopedMapping.default,e),r)}function K(n){return C(n)}function Z(n){return C(n)}function ee(n){return C(n)}function ne(n){return C(n)}function te(n){return C(n)}function ke(n,e){let{scopedAccountMapping:t,...r}=e,a=K({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return G(n,{...r,...a})}function je(n,e){let{scopedAccountMapping:t,...r}=e,a=Z({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return Y(n,{...r,...a})}function Ue(n,e){let{scopedAccountMapping:t,...r}=e,a=ne({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return z(n,{...r,...a})}function Ve(n,e){let{scopedAccountMapping:t,...r}=e,a=te({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return W(n,{...r,...a})}function He(n,e){let{scopedAccountMapping:t,...r}=e,a=ee({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return X(n,{...r,...a})}function j(n){return!!(n&&typeof n=="object"&&n.error)}function re(n){return n.startsWith("ofinance_")?`offinance_${n.slice(9)}`:n}async function Qe(n,e,t){let r=await n.accountService.listAccounts();if(j(r))throw new Error(r.error.message||r.error.code||"FINANCE_ACCOUNT_LIST_FAILED");let a=new Set((r.data||[]).map(o=>o.id));for(let o of e){if(a.has(o.id))continue;let i=await n.accountService.createAccount(o);if(j(i))throw new Error(i.error.message||i.error.code||"FINANCE_ACCOUNT_CREATE_FAILED");await t?.({changeId:`offinance:account:${o.id}`,entity:"FinanceAccount",table:re(d.accounts),type:"CREATE",data:o})}}async function pe(n,e,t){return n.query(e,{filters:{and:t}})}async function qe(n,e,t){if(!t)return;let r=await pe(n,d.journals,[{field:"id",value:e.id}]),a=await pe(n,d.journalLines,[{field:"journalId",value:e.id}]);r.length===0&&(r=[{id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,status:e.status,postedAt:e.postedAt,lastModified:e.postedAt||e.occurredAt,deleted:!1}]),a.length===0&&(a=e.lines.map((o,i)=>({id:`${e.id}:line:${i}`,journalId:e.id,accountId:o.accountId,debit:o.debit,credit:o.credit,memo:o.memo,openItemId:o.openItemId,openItemType:o.openItemType,counterpartyRef:o.counterpartyRef,documentRef:o.documentRef,dueAt:o.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:e.postedAt||e.occurredAt,deleted:!1})));for(let o of r)await t({changeId:`offinance:journal:${o.id}`,entity:"FinanceJournalEntry",table:re(d.journals),type:"CREATE",data:o});for(let o of a)await t({changeId:`offinance:journal-line:${o.id}`,entity:"FinanceJournalLine",table:re(d.journalLines),type:"CREATE",data:o})}function $e(n){return async e=>{let t=n.resolveFinanceServices();if(!t)throw new Error(n.missingServicesErrorCode||"FINANCE_SERVICES_UNAVAILABLE");let r=n.resolveLedgerProfileId().trim();if(!r)throw new Error(n.missingLedgerProfileErrorCode||"FINANCE_LEDGER_PROFILE_REQUIRED");let a=n.resolveSyncEnqueuer?.()??null;await Qe(t,n.requiredAccounts,a);let o=n.buildJournalDraft(e,r),i=await t.journalService.createJournalDraft(o);if(j(i)&&i.error.code!=="JOURNAL_ALREADY_EXISTS")throw new Error(i.error.message||i.error.code||"FINANCE_JOURNAL_CREATE_FAILED");let c=await t.journalService.postJournal(o.id,o.occurredAt);if(j(c))throw new Error(c.error.message||c.error.code||"FINANCE_JOURNAL_POST_FAILED");await qe(n.dbAdapter,c.data,a)}}function Ge(n){switch(n.accountType){case"asset":case"expense":return n.debit-n.credit;case"liability":case"equity":case"revenue":return n.credit-n.debit;default:return 0}}function L(n,e){return n.filter(t=>t.accountType===e).reduce((t,r)=>t+Ge(r),0)}function Ye(n){let e=L(n,"revenue"),t=L(n,"expense");return{revenue:e,expense:t,netIncome:e-t}}function ze(n){return{assets:L(n,"asset"),liabilities:L(n,"liability"),equity:L(n,"equity")}}function le(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function We(n){let e=n.filter(r=>r.accountType==="revenue").reduce((r,a)=>r+Math.max(0,le(a)),0),t=n.filter(r=>r.accountType==="expense").reduce((r,a)=>r+Math.max(0,le(a)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function Xe(n,e){let t=[],r=0;for(let a of e){if(a.accountType==="revenue"){let o=a.credit-a.debit;o>0&&(t.push({accountId:a.accountId,debit:o,credit:0,memo:"Close revenue account"}),r+=o)}if(a.accountType==="expense"){let o=a.debit-a.credit;o>0&&(t.push({accountId:a.accountId,debit:0,credit:o,memo:"Close expense account"}),r-=o)}}return r>0?t.push({accountId:n.retainedEarningsAccountId,debit:0,credit:r,memo:"Retained earnings from period close"}):r<0&&t.push({accountId:n.retainedEarningsAccountId,debit:Math.abs(r),credit:0,memo:"Retained earnings from period close"}),{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:n.reference,lines:t}}function Ke(n){return Array.isArray(n)?n.length:n&&typeof n=="object"?1:n===null||typeof n>"u"?0:1}function Ze(n){return n==="json"?"application/json":"text/csv"}function en(n,e){if(n==="json")return`${JSON.stringify(e,null,2)}
2
- `;if(typeof e!="string")throw new Error("FINANCE_COMPLIANCE_EXPORT_CSV_PAYLOAD_STRING_REQUIRED");return e}function nn(n){let e=2166136261;for(let t=0;t<n.length;t+=1)e^=n.charCodeAt(t),e=Math.imul(e,16777619);return`fnv1a32-${(e>>>0).toString(16).padStart(8,"0")}`}function tn(n){if(!n.key?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_REQUIRED");if(!n.fileName?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_FILE_NAME_REQUIRED");if(n.format!=="json"&&n.format!=="csv")throw new Error("FINANCE_COMPLIANCE_EXPORT_FORMAT_INVALID")}function rn(n){return n??"custom"}function ae(n){if(!Array.isArray(n.datasets)||n.datasets.length===0)throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASETS_REQUIRED");let e=new Set,t={},r=[];for(let o of n.datasets){if(tn(o),e.has(o.key))throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_DUPLICATE");e.add(o.key);let i=en(o.format,o.payload);t[o.fileName]=i,r.push({key:o.key,fileName:o.fileName,format:o.format,semantic:rn(o.semantic),contentType:o.contentType??Ze(o.format),recordCount:Ke(o.payload),checksum:nn(i)})}return{contract:{contractVersion:"fcx-v1",tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt??new Date().toISOString(),period:{from:n.period?.from??null,to:n.period?.to??null,label:n.period?.label??null},currency:{baseCurrencyCode:n.baseCurrencyCode??"IDR"},datasets:r,summary:{datasetCount:r.length,totalRecordCount:r.reduce((o,i)=>o+i.recordCount,0)}},files:t}}function an(n){return{version:"v1",generatedAt:n.generatedAt??new Date().toISOString(),payload:{trialBalance:n.trialBalance.map(e=>({...e})),incomeStatement:{...n.incomeStatement},balanceSheet:{...n.balanceSheet}}}}function on(n){let e=[{key:"trial-balance",fileName:"trial_balance.json",format:"json",semantic:"trial_balance",payload:n.trialBalance},{key:"income-statement",fileName:"income_statement.json",format:"json",semantic:"income_statement",payload:n.incomeStatement},{key:"balance-sheet",fileName:"balance_sheet.json",format:"json",semantic:"balance_sheet",payload:n.balanceSheet}];return typeof n.openItems<"u"&&e.push({key:"open-items",fileName:"open_items.json",format:"json",semantic:"open_items",payload:n.openItems}),typeof n.agingSummary<"u"&&e.push({key:"aging-summary",fileName:"aging_summary.json",format:"json",semantic:"aging_summary",payload:n.agingSummary}),typeof n.reconciliationSummary<"u"&&e.push({key:"reconciliation-summary",fileName:"reconciliation_summary.json",format:"json",semantic:"reconciliation",payload:n.reconciliationSummary}),typeof n.cashMovements<"u"&&e.push({key:"cash-movements",fileName:"cash_movements.json",format:"json",semantic:"cash_movements",payload:n.cashMovements}),ae({tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt,period:n.period,baseCurrencyCode:n.baseCurrencyCode,datasets:e})}function cn(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function me(n,e){return e===0?n===0?1:0:Number((n/e).toFixed(4))}function sn(n,e){let t=e.map(a=>{let c=((a.accountCodes?.length?n.filter(p=>a.accountCodes?.includes(p.accountCode)):null)??n.filter(p=>a.accountType?p.accountType===a.accountType:!1)).reduce((p,f)=>p+cn(f),0),s=c-a.plannedAmount;return{id:a.id,label:a.label,plannedAmount:a.plannedAmount,actualAmount:c,varianceAmount:s,achievementRatio:me(c,a.plannedAmount)}}),r=t.reduce((a,o)=>(a.plannedAmount+=o.plannedAmount,a.actualAmount+=o.actualAmount,a.varianceAmount+=o.varianceAmount,a),{plannedAmount:0,actualAmount:0,varianceAmount:0});return{rows:t,totals:{...r,achievementRatio:me(r.actualAmount,r.plannedAmount)}}}function Ie(n,e){switch(e.type){case"finance.account.created":n.createAccount(e.payload);return;case"finance.period.opened":n.openFiscalPeriod(e.payload);return;case"finance.period.closed":n.closeFiscalPeriod(e.payload.periodId);return;case"finance.journal.drafted":n.createJournalDraft(e.payload);return;case"finance.journal.posted":n.postJournal(e.payload.journalId,e.payload.postedAt);return;case"finance.journal.reversed":n.reverseJournal(e.payload.journalId,e.payload.reversalId);return;default:throw new Error("FINANCE_EVENT_UNSUPPORTED")}}function dn(n){let e=new T;for(let t of n)Ie(e,t);return e}var fe=[{id:"coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coa-ar",code:"1201",name:"Piutang Usaha",type:"asset"},{id:"coa-ap",code:"2101",name:"Utang Usaha",type:"liability"},{id:"coa-retained",code:"3201",name:"Laba Ditahan",type:"equity"},{id:"coa-revenue",code:"4101",name:"Pendapatan Operasional",type:"revenue"},{id:"coa-expense",code:"5101",name:"Biaya Operasional",type:"expense"}];function un(n="IDR"){return fe.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}var ge=[{id:"coop-coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coop-coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coop-coa-loan-ar",code:"1201",name:"Piutang Pinjaman Anggota",type:"asset"},{id:"coop-coa-other-ar",code:"1202",name:"Piutang Lain-lain",type:"asset"},{id:"coop-coa-prepaid",code:"1301",name:"Biaya Dibayar Dimuka",type:"asset"},{id:"coop-coa-fixed-asset",code:"1401",name:"Aset Tetap",type:"asset"},{id:"coop-coa-accum-depr",code:"1402",name:"Akumulasi Penyusutan",type:"asset"},{id:"coop-coa-simp-pokok",code:"2101",name:"Simpanan Pokok",type:"liability"},{id:"coop-coa-simp-wajib",code:"2102",name:"Simpanan Wajib",type:"liability"},{id:"coop-coa-simp-sukarela",code:"2103",name:"Simpanan Sukarela",type:"liability"},{id:"coop-coa-simp-berjangka",code:"2104",name:"Simpanan Berjangka",type:"liability"},{id:"coop-coa-ap",code:"2201",name:"Utang Usaha",type:"liability"},{id:"coop-coa-ext-loan",code:"2301",name:"Pinjaman Luar",type:"liability"},{id:"coop-coa-tax-payable",code:"2401",name:"Utang Pajak",type:"liability"},{id:"coop-coa-modal-awal",code:"3101",name:"Modal Awal",type:"equity"},{id:"coop-coa-cadangan-umum",code:"3201",name:"Dana Cadangan Umum",type:"equity"},{id:"coop-coa-cadangan-tujuan",code:"3202",name:"Dana Cadangan Tujuan",type:"equity"},{id:"coop-coa-shu-prior",code:"3301",name:"SHU Tahun Lalu",type:"equity"},{id:"coop-coa-shu-current",code:"3302",name:"SHU Berjalan",type:"equity"},{id:"coop-coa-shu-reserve",code:"3303",name:"Dana SHU Belum Dibagi",type:"equity"},{id:"coop-coa-jasa-pinjaman",code:"4101",name:"Pendapatan Jasa Pinjaman",type:"revenue"},{id:"coop-coa-provisi",code:"4102",name:"Pendapatan Provisi",type:"revenue"},{id:"coop-coa-rev-other",code:"4103",name:"Pendapatan Lain-lain",type:"revenue"},{id:"coop-coa-beban-bunga",code:"5101",name:"Beban Bunga Simpanan",type:"expense"},{id:"coop-coa-beban-ops",code:"5102",name:"Beban Operasional",type:"expense"},{id:"coop-coa-beban-gaji",code:"5103",name:"Beban Gaji dan Tunjangan",type:"expense"},{id:"coop-coa-beban-admin",code:"5104",name:"Beban Administrasi",type:"expense"},{id:"coop-coa-beban-depr",code:"5105",name:"Beban Penyusutan",type:"expense"},{id:"coop-coa-prov-kredit",code:"5106",name:"Cadangan Kerugian Piutang",type:"expense"}];function pn(n="IDR"){return ge.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}function ln(n){let e=new Set,t=new Set;for(let r of n){if(!r.id||!r.code||!r.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(r.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(r.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(r.id),t.add(r.code)}return{ok:!0}}
1
+ "use strict";var U=Object.defineProperty;var ye=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var he=Object.prototype.hasOwnProperty;var Se=(n,e)=>{for(var t in e)U(n,t,{get:e[t],enumerable:!0})},Ce=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of be(e))!he.call(n,a)&&a!==t&&U(n,a,{get:()=>e[a],enumerable:!(r=ye(e,a))||r.enumerable});return n};var ve=n=>Ce(U({},"__esModule",{value:!0}),n);var At={};Se(At,{CANONICAL_COA_TEMPLATES:()=>ge,COOP_COA_TEMPLATES:()=>Ae,OFINANCE_TABLES:()=>l,OffinanceCore:()=>w,OffinanceEnvelopeService:()=>M,OfinanceRuntimeCore:()=>B,OfinanceRuntimeCoreBuilder:()=>J,applyFinanceDomainEvent:()=>Ie,applyPendingMigrations:()=>N,buildBalanceSheet:()=>et,buildBudgetVsRealization:()=>pt,buildCashflowBaseline:()=>tt,buildClosingJournalDraft:()=>nt,buildFinanceComplianceExportBundle:()=>ae,buildFinanceExportEnvelope:()=>st,buildFinanceOpenItemAging:()=>D,buildFinanceOperationalComplianceBundle:()=>ut,buildFinanceTaxPostingLines:()=>q,buildIncomeStatement:()=>Ze,buildJournalFromCoopLoanDisbursement:()=>G,buildJournalFromCoopLoanRepayment:()=>X,buildJournalFromCoopSavingDeposit:()=>W,buildJournalFromCoopSavingWithdrawal:()=>z,buildJournalFromCoopShuParticipationManualRecap:()=>$e,buildJournalFromPosSale:()=>Y,buildJournalFromScopedCoopLoanDisbursement:()=>Qe,buildJournalFromScopedCoopLoanRepayment:()=>Ge,buildJournalFromScopedCoopSavingDeposit:()=>qe,buildJournalFromScopedCoopSavingWithdrawal:()=>Ye,buildJournalFromScopedPosSale:()=>He,createCanonicalCoA:()=>ft,createCoopCoA:()=>It,createDbAdapterOfinanceServices:()=>Q,createFinanceProjectionSink:()=>Xe,createOffinanceEnvelopeService:()=>H,mapOffinanceErrorToEnvelope:()=>f,projectFinanceCashBankMovements:()=>T,projectFinanceOpenItems:()=>F,reconcileFinanceOpenItems:()=>O,replayFinanceDomainEvents:()=>mt,resolveCoopLoanDisbursementAccountMapping:()=>Z,resolveCoopLoanRepaymentAccountMapping:()=>ee,resolveCoopSavingDepositAccountMapping:()=>te,resolveCoopSavingWithdrawalAccountMapping:()=>ne,resolvePosSaleAccountMapping:()=>K,resolveScopedAccountMapping:()=>E,summarizeFinanceCashBankMovements:()=>_,toOffinanceFailureEnvelope:()=>$,toOffinanceSuccessEnvelope:()=>m,validateCoaIntegrity:()=>gt,validateJournalBalance:()=>R,validateOpenItemLineMetadata:()=>P});module.exports=ve(At);function R(n){if(!Array.isArray(n)||n.length===0)return{ok:!1,totalDebit:0,totalCredit:0,reason:"JOURNAL_LINES_EMPTY"};let e=0,t=0;for(let r of n){if(!r||!r.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(r.debit<0||r.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=r.debit,t+=r.credit}return Math.abs(e-t)>1e-6?{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NOT_BALANCED"}:{ok:!0,totalDebit:e,totalCredit:t}}var Ee=[{key:"current",label:"Current",maxDaysPastDue:0},{key:"1-30",label:"1-30 days",minDaysPastDue:1,maxDaysPastDue:30},{key:"31-60",label:"31-60 days",minDaysPastDue:31,maxDaysPastDue:60},{key:"61-90",label:"61-90 days",minDaysPastDue:61,maxDaysPastDue:90},{key:"90+",label:"90+ days",minDaysPastDue:91}];function Re(n,e,t){return n==="receivable"?e-t:t-e}function Pe(n,e){return[n.tenantId??"",n.branchId??"",n.financeDomainId??"",n.ledgerProfileId??"",e.accountId,e.openItemType??"",e.openItemId??""].join("::")}function oe(n){return n<0?"overpaid":Math.abs(n)<1e-6?"settled":"open"}function Fe(n,e){if(!e)return 0;let t=Date.parse(n)-Date.parse(e);return!Number.isFinite(t)||t<=0?0:Math.floor(t/864e5)}function De(n,e){return e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.openItemType&&n.openItemType!==e.openItemType||e.counterpartyRef&&n.counterpartyRef!==e.counterpartyRef||!e.includeSettled&&n.status==="settled"):!0}function P(n){for(let e of n){let t=!!(e.openItemId||e.openItemType),r=!!(e.counterpartyRef||e.documentRef||e.dueAt);if(!(!t&&!r)){if(!e.openItemId)throw new Error("JOURNAL_OPEN_ITEM_ID_REQUIRED");if(!e.openItemType)throw new Error("JOURNAL_OPEN_ITEM_TYPE_REQUIRED");if(e.openItemType!=="receivable"&&e.openItemType!=="payable")throw new Error("JOURNAL_OPEN_ITEM_TYPE_INVALID");if(e.dueAt&&Number.isNaN(Date.parse(e.dueAt)))throw new Error("JOURNAL_OPEN_ITEM_DUE_AT_INVALID")}}}function F(n,e){let t=new Map;for(let r of n)if(r.status==="posted")for(let a of r.lines){if(!a.openItemId||!a.openItemType)continue;let o=Pe(r,a),i=Re(a.openItemType,a.debit,a.credit),c=t.get(o);if(!c){let s={tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,openItemId:a.openItemId,openItemType:a.openItemType,accountId:a.accountId,counterpartyRef:a.counterpartyRef,documentRef:a.documentRef,dueAt:a.dueAt,originatedAt:r.occurredAt,lastActivityAt:r.occurredAt,originalAmount:i>0?i:0,settledAmount:i<0?Math.abs(i):0,outstandingAmount:i,status:oe(i)};t.set(o,{item:s});continue}c.item.originatedAt=c.item.originatedAt<r.occurredAt?c.item.originatedAt:r.occurredAt,c.item.lastActivityAt=c.item.lastActivityAt>r.occurredAt?c.item.lastActivityAt:r.occurredAt,c.item.counterpartyRef=a.counterpartyRef??c.item.counterpartyRef,c.item.documentRef=a.documentRef??c.item.documentRef,c.item.dueAt=a.dueAt??c.item.dueAt,i>0?c.item.originalAmount+=i:i<0&&(c.item.settledAmount+=Math.abs(i)),c.item.outstandingAmount+=i,c.item.status=oe(c.item.outstandingAmount)}return Array.from(t.values()).map(({item:r})=>({...r})).filter(r=>De(r,e)).sort((r,a)=>r.originatedAt!==a.originatedAt?r.originatedAt.localeCompare(a.originatedAt):r.openItemId.localeCompare(a.openItemId))}function D(n,e){if(Number.isNaN(Date.parse(e.asOf)))throw new Error("FINANCE_OPEN_ITEM_AGING_AS_OF_INVALID");let t=(e.buckets?.length?e.buckets:Ee).map(a=>({...a,amount:0,itemCount:0})),r=0;for(let a of n){if(a.outstandingAmount<=0)continue;r+=a.outstandingAmount;let o=Fe(e.asOf,a.dueAt),i=t.find(c=>{let s=c.minDaysPastDue??Number.NEGATIVE_INFINITY,I=c.maxDaysPastDue??Number.POSITIVE_INFINITY;return o>=s&&o<=I});if(!i)throw new Error("FINANCE_OPEN_ITEM_AGING_BUCKET_UNRESOLVED");i.amount+=a.outstandingAmount,i.itemCount+=1}return{asOf:e.asOf,openItemType:e.openItemType,totalOutstanding:r,buckets:t}}function ce(n,e){return`${e??""}::${n}`}function Oe(n){if(!n.openItemId?.trim())throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_ID_REQUIRED");if(!Number.isFinite(n.observedAmount)||n.observedAmount<0)throw new Error("FINANCE_RECONCILIATION_OBSERVED_AMOUNT_INVALID");if(n.openItemType&&n.openItemType!=="receivable"&&n.openItemType!=="payable")throw new Error("FINANCE_RECONCILIATION_OPEN_ITEM_TYPE_INVALID")}function Te(n,e){let t=new Map;for(let r of n){Oe(r);let a=r.openItemType??e,o=ce(r.openItemId,a),i=t.get(o);if(!i){t.set(o,{openItemId:r.openItemId,openItemType:a,observedAmount:r.observedAmount,counterpartyRef:r.counterpartyRef,documentRef:r.documentRef,references:r.reference?[r.reference]:[]});continue}i.observedAmount+=r.observedAmount,i.counterpartyRef=r.counterpartyRef??i.counterpartyRef,i.documentRef=r.documentRef??i.documentRef,r.reference&&i.references.push(r.reference)}return t}function _e(n,e,t,r,a){let o=n.outstandingAmount,i=e?.observedAmount??0,c=i-o,s=Ne(n.dueAt,r);if(!e){let A=ie("missing",s,a);return{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:o,observedAmount:i,varianceAmount:c,status:"missing",lifecycleStatus:A.lifecycleStatus,suggestedAction:A.suggestedAction,reason:"FINANCE_RECONCILIATION_OBSERVATION_MISSING",pastDueDays:s,observedReferences:[]}}let I=e.counterpartyRef&&n.counterpartyRef&&e.counterpartyRef!==n.counterpartyRef||e.documentRef&&n.documentRef&&e.documentRef!==n.documentRef,p="matched",g="resolved",d="none",u;if(I)p="mismatch",g="exception",d="investigate",u="FINANCE_RECONCILIATION_METADATA_MISMATCH";else if(Math.abs(c)<=t)p="matched";else if(c<0){p="under";let A=ie("under",s,a);g=A.lifecycleStatus,d=A.suggestedAction,u="FINANCE_RECONCILIATION_OBSERVED_UNDER"}else c>0&&(p="over",g="unresolved",d="refund_or_apply_credit",u="FINANCE_RECONCILIATION_OBSERVED_OVER");return{tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType,accountId:n.accountId,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,dueAt:n.dueAt,expectedAmount:o,observedAmount:i,varianceAmount:c,status:p,lifecycleStatus:g,suggestedAction:d,reason:u,pastDueDays:s,observedReferences:[...e.references]}}function we(n,e){return{tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,openItemId:n.openItemId,openItemType:n.openItemType??e.openItemType,counterpartyRef:n.counterpartyRef,documentRef:n.documentRef,expectedAmount:0,observedAmount:n.observedAmount,varianceAmount:n.observedAmount,status:"mismatch",lifecycleStatus:"exception",suggestedAction:"investigate",reason:"FINANCE_RECONCILIATION_EXPECTED_ITEM_NOT_FOUND",observedReferences:[...n.references]}}function Ne(n,e){if(!n||!e)return;let t=Date.parse(n),r=Date.parse(e);if(!Number.isFinite(t)||!Number.isFinite(r))throw new Error("FINANCE_RECONCILIATION_AS_OF_INVALID");let a=r-t;return a<=0?0:Math.floor(a/864e5)}function ie(n,e,t){return typeof t=="number"&&typeof e=="number"&&e>=t?{lifecycleStatus:"writeoff_candidate",suggestedAction:"write_off_review"}:{lifecycleStatus:"unresolved",suggestedAction:n==="missing"||n==="under"?"collect_follow_up":"investigate"}}function O(n,e){let t=e.toleranceAmount??0;if(!Number.isFinite(t)||t<0)throw new Error("FINANCE_RECONCILIATION_TOLERANCE_INVALID");if(e.asOf&&!Number.isFinite(Date.parse(e.asOf)))throw new Error("FINANCE_RECONCILIATION_AS_OF_INVALID");if(typeof e.writeOffPastDueDays=="number"&&(!Number.isFinite(e.writeOffPastDueDays)||e.writeOffPastDueDays<0))throw new Error("FINANCE_RECONCILIATION_WRITE_OFF_DAYS_INVALID");let r=Te(e.observations,e.openItemType),a=[];for(let d of n){let u=ce(d.openItemId,d.openItemType),A=r.get(u);a.push(_e(d,A,t,e.asOf,e.writeOffPastDueDays)),r.delete(u)}for(let d of r.values())a.push(we(d,e));a.sort((d,u)=>(d.financeDomainId??"")!==(u.financeDomainId??"")?(d.financeDomainId??"").localeCompare(u.financeDomainId??""):(d.ledgerProfileId??"")!==(u.ledgerProfileId??"")?(d.ledgerProfileId??"").localeCompare(u.ledgerProfileId??""):d.openItemId.localeCompare(u.openItemId));let o=a.reduce((d,u)=>d+u.expectedAmount,0),i=a.reduce((d,u)=>d+u.observedAmount,0),c=a.reduce((d,u)=>d+u.varianceAmount,0),s=a.filter(d=>d.lifecycleStatus==="resolved").length,I=a.filter(d=>d.lifecycleStatus==="unresolved").length,p=a.filter(d=>d.lifecycleStatus==="exception").length,g=a.filter(d=>d.lifecycleStatus==="writeoff_candidate").length;return{openItemType:e.openItemType,totalExpectedAmount:o,totalObservedAmount:i,totalVarianceAmount:c,resolvedCount:s,unresolvedCount:I,exceptionCount:p,writeoffCandidateCount:g,rows:a}}function Le(n){if(!Array.isArray(n.trackedAccountIds)||n.trackedAccountIds.length===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");let e=new Set(n.trackedAccountIds.map(t=>t.trim()).filter(Boolean));if(e.size===0)throw new Error("FINANCE_CASH_MOVEMENT_TRACKED_ACCOUNTS_REQUIRED");return e}function Me(n,e){return!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt>e.occurredTo)}function xe(n){return n?.startsWith("reversal:")&&n.slice(9).trim()||void 0}function T(n,e){let t=Le(e),r=[];for(let a of n){if(a.status!=="posted"||!Me(a,e))continue;let o=a.lines.filter(u=>t.has(u.accountId)&&(u.debit>0||u.credit>0));if(o.length===0)continue;let i=Array.from(new Set(o.map(u=>u.accountId))).sort(),c=Array.from(new Set(a.lines.filter(u=>!t.has(u.accountId)&&(u.debit>0||u.credit>0)).map(u=>u.accountId))).sort(),s=o.some(u=>u.debit>0),I=o.some(u=>u.credit>0),p=xe(a.reference),g=!!p,d=i.length>1&&s&&I&&c.length===0;if(i.length>1&&c.length>0)throw new Error("FINANCE_CASH_MOVEMENT_MIXED_TRACKED_JOURNAL_UNSUPPORTED");if(d){let u=o.reduce((y,S)=>y+S.debit,0),A=o.reduce((y,S)=>y+S.credit,0);if(Math.abs(u-A)>1e-6)throw new Error("FINANCE_CASH_MOVEMENT_TRANSFER_IMBALANCED")}for(let u of o)u.debit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:u.accountId,direction:d?"transfer_in":"in",movementKind:g?"reversal":d?"internal_transfer":"external",lifecycleStatus:g?"reversal_posted":"posted",amount:u.debit,signedAmount:u.debit,sourceJournalId:p,counterpartAccountIds:c,trackedAccountIdsInJournal:i}),u.credit>0&&r.push({journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:a.reference,evidenceRef:a.evidenceRef,accountId:u.accountId,direction:d?"transfer_out":"out",movementKind:g?"reversal":d?"internal_transfer":"external",lifecycleStatus:g?"reversal_posted":"posted",amount:u.credit,signedAmount:-u.credit,sourceJournalId:p,counterpartAccountIds:c,trackedAccountIdsInJournal:i})}return r.sort((a,o)=>a.occurredAt!==o.occurredAt?a.occurredAt.localeCompare(o.occurredAt):a.journalId!==o.journalId?a.journalId.localeCompare(o.journalId):a.accountId.localeCompare(o.accountId))}function _(n){let e=0,t=0,r=0,a=0,o=new Map;for(let i of n)i.direction==="in"&&(e+=i.amount),i.direction==="out"&&(t+=i.amount),i.direction==="transfer_in"&&(r+=i.amount),i.direction==="transfer_out"&&(a+=i.amount),o.set(i.accountId,(o.get(i.accountId)??0)+i.signedAmount);return{totalInflow:e,totalOutflow:t,totalTransferIn:r,totalTransferOut:a,netExternalMovement:e-t,netByTrackedAccountId:Object.fromEntries(Array.from(o.entries()).sort(([i],[c])=>i.localeCompare(c))),entries:n.map(i=>({...i,counterpartAccountIds:[...i.counterpartAccountIds],trackedAccountIdsInJournal:[...i.trackedAccountIdsInJournal]}))}}var w=class{constructor(e){this.state={accounts:e?.accounts??new Map,periods:e?.periods??new Map,journals:e?.journals??new Map,balances:e?.balances??new Map,rapbPlans:e?.rapbPlans??new Map,auditTrail:e?.auditTrail?.map(t=>({...t}))??[]}}createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");if(this.state.accounts.has(e.id))throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if(Array.from(this.state.accounts.values()).some(r=>r.code===e.code))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");return this.state.accounts.set(e.id,{...e}),{...e}}listAccounts(){return Array.from(this.state.accounts.values()).map(e=>({...e})).sort((e,t)=>e.code.localeCompare(t.code))}openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(this.state.periods.has(e.id))throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t={...e,status:"open"};return this.state.periods.set(t.id,t),this.recordAuditTrail({eventType:"fiscal_period_opened",recordType:"fiscal_period",recordId:t.id,tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId,occurredAt:new Date().toISOString(),summary:`Fiscal period ${t.code} opened`,metadata:{code:t.code,startDate:t.startDate,endDate:t.endDate}}),{...t}}closeFiscalPeriod(e){let t=this.state.periods.get(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed"};return this.state.periods.set(e,r),this.recordAuditTrail({eventType:"fiscal_period_closed",recordType:"fiscal_period",recordId:r.id,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:new Date().toISOString(),summary:`Fiscal period ${r.code} closed`,metadata:{code:r.code}}),{...r}}listFiscalPeriods(){return Array.from(this.state.periods.values()).map(e=>({...e})).sort((e,t)=>e.startDate.localeCompare(t.startDate))}createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(this.state.journals.has(e.id))throw new Error("JOURNAL_ALREADY_EXISTS");this.assertJournalLinesKnownAccounts(e.lines),this.assertJournalPeriodOpen(e.occurredAt),P(e.lines);let t=R(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,lines:e.lines.map(a=>({...a})),status:"draft"};return this.state.journals.set(r.id,r),this.recordAuditTrail({eventType:"journal_drafted",recordType:"journal",recordId:r.id,journalId:r.id,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:new Date().toISOString(),reference:r.reference,evidenceRef:r.evidenceRef,summary:`Journal ${r.id} drafted`,metadata:{journalOccurredAt:r.occurredAt,status:r.status}}),{...r,lines:r.lines.map(a=>({...a}))}}postJournal(e,t=new Date().toISOString()){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status==="posted"||r.status==="reversed")return{...r,lines:r.lines.map(i=>({...i}))};this.applyLinesToBalance(r.lines);let a={...r,status:"posted",postedAt:t};this.state.journals.set(e,a);let o=new Date().toISOString();return this.recordAuditTrail({eventType:"journal_posted",recordType:"journal",recordId:a.id,journalId:a.id,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:o,reference:a.reference,evidenceRef:a.evidenceRef,summary:`Journal ${a.id} posted`,metadata:{journalOccurredAt:a.occurredAt,postedAt:t,status:a.status}}),{...a,lines:a.lines.map(i=>({...i}))}}reverseJournal(e,t){let r=this.state.journals.get(e);if(!r)throw new Error("JOURNAL_NOT_FOUND");if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let a=r.lines.map(s=>({accountId:s.accountId,debit:s.credit,credit:s.debit,memo:s.memo,openItemId:s.openItemId,openItemType:s.openItemType,counterpartyRef:s.counterpartyRef,documentRef:s.documentRef,dueAt:s.dueAt})),o=this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a}),i=this.postJournal(o.id),c=new Date().toISOString();return this.recordAuditTrail({eventType:"journal_reversal_posted",recordType:"journal",recordId:i.id,journalId:i.id,sourceJournalId:r.id,tenantId:i.tenantId,branchId:i.branchId,financeDomainId:i.financeDomainId,ledgerProfileId:i.ledgerProfileId,occurredAt:c,reference:i.reference,evidenceRef:i.evidenceRef,summary:`Reversal journal ${i.id} posted for ${r.id}`,metadata:{journalOccurredAt:i.occurredAt,postedAt:i.postedAt,status:i.status}}),i}getTrialBalance(){return this.getTrialBalanceByScope()}getTrialBalanceByScope(e){let t=this.computeScopedBalances(e);return this.listAccounts().map(a=>{let o=t.get(a.id)??{debit:0,credit:0};return{accountId:a.id,accountCode:a.code,accountName:a.name,accountType:a.type,debit:o.debit,credit:o.credit,net:o.debit-o.credit}})}listJournals(e){return Array.from(this.state.journals.values()).filter(t=>this.matchesScope(t,e)).map(t=>({...t,lines:t.lines.map(r=>({...r}))})).sort((t,r)=>t.occurredAt.localeCompare(r.occurredAt))}listOpenItems(e){return F(this.listJournals(e),e)}getOpenItemAging(e){return D(this.listOpenItems(e),e)}reconcileOpenItems(e){return O(this.listOpenItems(e),e)}listCashBankMovements(e){return T(this.listJournals(e),e)}summarizeCashBankMovements(e){return _(this.listCashBankMovements(e))}listFinancialAuditTrail(e){return this.state.auditTrail.filter(t=>this.matchesAuditScope(t,e)).sort((t,r)=>t.occurredAt!==r.occurredAt?t.occurredAt.localeCompare(r.occurredAt):t.id.localeCompare(r.id)).map(t=>({...t,metadata:t.metadata?{...t.metadata}:void 0}))}assertJournalLinesKnownAccounts(e){for(let t of e)if(!this.state.accounts.has(t.accountId))throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}assertJournalPeriodOpen(e){if(this.state.periods.size===0)return;let t=this.findPeriodByDate(e);if(!t)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(t.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}findPeriodByDate(e){let t=Date.parse(e);for(let r of this.state.periods.values()){let a=Date.parse(r.startDate),o=Date.parse(r.endDate);if(t>=a&&t<=o)return r}return null}applyLinesToBalance(e){for(let t of e){let r=this.state.balances.get(t.accountId)??{debit:0,credit:0};r.debit+=t.debit,r.credit+=t.credit,this.state.balances.set(t.accountId,r)}}computeScopedBalances(e){if(!e||!e.tenantId&&!e.branchId&&!e.financeDomainId&&!e.ledgerProfileId&&!e.occurredFrom&&!e.occurredTo)return this.state.balances;let t=new Map;for(let r of this.state.journals.values())if(r.status==="posted"&&this.matchesScope(r,e))for(let a of r.lines){let o=t.get(a.accountId)??{debit:0,credit:0};o.debit+=a.debit,o.credit+=a.credit,t.set(a.accountId,o)}return t}matchesScope(e,t){return t?!(t.tenantId&&e.tenantId!==t.tenantId||t.branchId&&e.branchId!==t.branchId||t.financeDomainId&&e.financeDomainId!==t.financeDomainId||t.ledgerProfileId&&e.ledgerProfileId!==t.ledgerProfileId||t.occurredFrom&&e.occurredAt<t.occurredFrom||t.occurredTo&&e.occurredAt>t.occurredTo):!0}createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(this.state.rapbPlans.has(e.id))throw new Error("RAPB_ALREADY_EXISTS");if(e.lines.some(a=>a.budgetedDebit<0||a.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=e.lines.map(a=>{let o=this.state.accounts.get(a.accountId);if(!o)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${a.accountId}`);let i=a.budgetedDebit-a.budgetedCredit;return{accountId:a.accountId,accountCode:o.code,accountName:o.name,accountType:o.type,budgetedDebit:a.budgetedDebit,budgetedCredit:a.budgetedCredit,budgetedNet:i}}),r={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",lines:t,notes:e.notes,createdAt:new Date().toISOString()};return this.state.rapbPlans.set(r.id,r),this.recordAuditTrail({eventType:"rapb_created",recordType:"rapb_plan",recordId:r.id,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.createdAt,summary:`RAPB ${r.title} created`,metadata:{periodCode:r.periodCode,status:r.status}}),r}getRapb(e){return this.state.rapbPlans.get(e)??null}listRapb(e){let t=Array.from(this.state.rapbPlans.values());return e&&(e.tenantId&&(t=t.filter(r=>r.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(r=>r.periodCode===e.periodCode)),e.branchId&&(t=t.filter(r=>r.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(r=>r.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(r=>r.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let r=this.state.rapbPlans.get(e);if(!r)throw new Error("RAPB_NOT_FOUND");let a=typeof t=="string"?t:t.approvedBy;if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...r,status:"approved",approvedAt:new Date().toISOString(),approvedBy:a};return this.state.rapbPlans.set(e,o),this.recordAuditTrail({eventType:"rapb_approved",recordType:"rapb_plan",recordId:o.id,tenantId:o.tenantId,branchId:o.branchId,financeDomainId:o.financeDomainId,ledgerProfileId:o.ledgerProfileId,occurredAt:o.approvedAt??new Date().toISOString(),summary:`RAPB ${o.title} approved`,metadata:{periodCode:o.periodCode,approvedBy:a,status:o.status}}),o}evaluateVariance(e){let t=this.state.rapbPlans.get(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=this.getTrialBalance(),a=new Map(r.map(d=>[d.accountId,d])),o=0,i=0,c=0,s=0,I=t.lines.map(d=>{let u=a.get(d.accountId),A=u?.debit??0,y=u?.credit??0,S=A-y;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=y-A):d.accountType==="expense"&&(c+=d.budgetedDebit-d.budgetedCredit,s+=A-y),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:A,actualCredit:y,actualNet:S,varianceDebit:A-d.budgetedDebit,varianceCredit:y-d.budgetedCredit,varianceNet:S-d.budgetedNet}}),p=o-c,g=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:I,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:p,actualNetIncome:g,netVariance:g-p}}recordAuditTrail(e){this.state.auditTrail.push({id:`audit:${this.state.auditTrail.length+1}:${Date.now()}`,...e,metadata:e.metadata?{...e.metadata}:void 0})}matchesAuditScope(e,t){return t?!(t.tenantId&&e.tenantId!==t.tenantId||t.branchId&&e.branchId!==t.branchId||t.financeDomainId&&e.financeDomainId!==t.financeDomainId||t.ledgerProfileId&&e.ledgerProfileId!==t.ledgerProfileId||t.occurredFrom&&e.occurredAt<t.occurredFrom||t.occurredTo&&e.occurredAt>t.occurredTo||t.recordId&&e.recordId!==t.recordId||t.journalId&&e.journalId!==t.journalId||t.eventTypes&&t.eventTypes.length>0&&!t.eventTypes.includes(e.eventType)):!0}};var se=require("ofcore"),ue=require("ofcore"),j=require("ofcore");var l={accounts:"ofinance_accounts",periods:"ofinance_periods",journals:"ofinance_journals",journalLines:"ofinance_journal_lines",rapbPlans:"ofinance_rapb_plans",rapbLines:"ofinance_rapb_lines",histories:"ofinance_histories"},Be=[{name:l.accounts,columns:[{name:"id",type:"string"},{name:"code",type:"string",isIndexed:!0},{name:"name",type:"string"},{name:"type",type:"string",isIndexed:!0},{name:"currency",type:"string"},{name:"isActive",type:"boolean",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.periods,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"code",type:"string",isIndexed:!0},{name:"startDate",type:"string",isIndexed:!0},{name:"endDate",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.journals,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"occurredAt",type:"string",isIndexed:!0},{name:"reference",type:"string",isOptional:!0,isIndexed:!0},{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.journalLines,columns:[{name:"id",type:"string"},{name:"journalId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"debit",type:"number"},{name:"credit",type:"number"},{name:"memo",type:"string",isOptional:!0},{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.rapbPlans,columns:[{name:"id",type:"string"},{name:"tenantId",type:"string",isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"periodCode",type:"string",isIndexed:!0},{name:"title",type:"string",isIndexed:!0},{name:"status",type:"string",isIndexed:!0},{name:"notes",type:"string",isOptional:!0},{name:"createdAt",type:"string",isIndexed:!0},{name:"approvedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"approvedBy",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.rapbLines,columns:[{name:"id",type:"string"},{name:"rapbId",type:"string",isIndexed:!0},{name:"accountId",type:"string",isIndexed:!0},{name:"accountCode",type:"string",isIndexed:!0},{name:"accountName",type:"string"},{name:"accountType",type:"string",isIndexed:!0},{name:"budgetedDebit",type:"number"},{name:"budgetedCredit",type:"number"},{name:"budgetedNet",type:"number"},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:l.histories,columns:[{name:"id",type:"string"},{name:"tableName",type:"string",isIndexed:!0},{name:"recordId",type:"string",isIndexed:!0},{name:"action",type:"string",isIndexed:!0},{name:"changes",type:"json",isOptional:!0},{name:"timestamp",type:"string",isIndexed:!0},{name:"tenantId",type:"string",isOptional:!0,isIndexed:!0},{name:"branchId",type:"string",isOptional:!0,isIndexed:!0},{name:"financeDomainId",type:"string",isOptional:!0,isIndexed:!0},{name:"ledgerProfileId",type:"string",isOptional:!0,isIndexed:!0}]}];function V(){return Be.map(n=>({...n,columns:n.columns.map(e=>({...e}))}))}var de=[{toVersion:1,up:async n=>{let e=V();for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:2,up:async n=>{let e=V().filter(t=>t.name==="ofinance_rapb_plans"||t.name==="ofinance_rapb_lines");for(let t of e)try{await n.addTable(t)}catch{}}},{toVersion:3,up:async n=>{try{await n.addColumn("ofinance_journals",{name:"evidenceRef",type:"string",isOptional:!0,isIndexed:!0})}catch{}}},{toVersion:4,up:async n=>{let e=[{name:"openItemId",type:"string",isOptional:!0,isIndexed:!0},{name:"openItemType",type:"string",isOptional:!0,isIndexed:!0},{name:"counterpartyRef",type:"string",isOptional:!0,isIndexed:!0},{name:"documentRef",type:"string",isOptional:!0,isIndexed:!0},{name:"dueAt",type:"string",isOptional:!0,isIndexed:!0}];for(let t of e)try{await n.addColumn("ofinance_journal_lines",t)}catch{}}}];var Je={logInfo(){},logWarn(){},logError(){}};async function N(n,e=Je){e.logInfo("[offinance] starting database migration process");let t=[...de].sort((o,i)=>o.toVersion-i.toVersion),r=t.length>0?t[t.length-1].toVersion:0,a=await n.getSchemaVersion();if((a==null||a<0)&&(a=0),a>=r){e.logInfo(`[offinance] database already up-to-date at v${a}`);return}for(let o of t)o.toVersion>a&&(e.logInfo(`[offinance] applying migration v${o.toVersion}`),await o.up(n),await n.setSchemaVersion(o.toVersion),a=o.toVersion);e.logInfo(`[offinance] migration completed at v${a}`)}function m(n,e){return{data:n,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function $(n,e,t={}){return{error:{code:n,message:e,details:t.details,retryable:t.retryable,correlationId:t.correlationId,timestamp:new Date().toISOString()},meta:{request_id:t.requestId??null,timestamp:new Date().toISOString()}}}function f(n,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return n instanceof Error?$(e,n.message||t):$(e,t)}var M=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return m(await this.legacy.accountService.createAccount(t))}catch(r){return f(r)}},listAccounts:async()=>{try{return m(await this.legacy.accountService.listAccounts())}catch(t){return f(t)}}},this.journalService={createJournalDraft:async t=>{try{return m(await this.legacy.journalService.createJournalDraft(t))}catch(r){return f(r)}},postJournal:async(t,r)=>{try{return m(await this.legacy.journalService.postJournal(t,r))}catch(a){return f(a)}},reverseJournal:async(t,r)=>{try{return m(await this.legacy.journalService.reverseJournal(t,r))}catch(a){return f(a)}},listJournals:async t=>{try{return m(await this.legacy.journalService.listJournals(t))}catch(r){return f(r)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return m(await this.legacy.fiscalService.openFiscalPeriod(t))}catch(r){return f(r)}},closeFiscalPeriod:async t=>{try{return m(await this.legacy.fiscalService.closeFiscalPeriod(t))}catch(r){return f(r)}},listFiscalPeriods:async()=>{try{return m(await this.legacy.fiscalService.listFiscalPeriods())}catch(t){return f(t)}},getTrialBalance:async()=>{try{return m(await this.legacy.fiscalService.getTrialBalance())}catch(t){return f(t)}},getTrialBalanceByScope:async t=>{try{return m(await this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(r){return f(r)}}},this.rapbService={createRapb:async t=>{try{return m(await this.legacy.rapbService.createRapb(t))}catch(r){return f(r)}},getRapb:async t=>{try{return m(await this.legacy.rapbService.getRapb(t))}catch(r){return f(r)}},listRapb:async t=>{try{return m(await this.legacy.rapbService.listRapb(t))}catch(r){return f(r)}},approveRapb:async(t,r)=>{try{return m(await this.legacy.rapbService.approveRapb(t,r))}catch(a){return f(a)}},evaluateVariance:async t=>{try{return m(await this.legacy.rapbService.evaluateVariance(t))}catch(r){return f(r)}}},this.openItemService={listOpenItems:async t=>{try{return m(await this.legacy.openItemService.listOpenItems(t))}catch(r){return f(r)}},getOpenItemAging:async t=>{try{return m(await this.legacy.openItemService.getOpenItemAging(t))}catch(r){return f(r)}}},this.reconciliationService={reconcileOpenItems:async t=>{try{return m(await this.legacy.reconciliationService.reconcileOpenItems(t))}catch(r){return f(r)}}},this.cashMovementService={listCashBankMovements:async t=>{try{return m(await this.legacy.cashMovementService.listCashBankMovements(t))}catch(r){return f(r)}},summarizeCashBankMovements:async t=>{try{return m(await this.legacy.cashMovementService.summarizeCashBankMovements(t))}catch(r){return f(r)}}},this.auditTrailService={listFinancialAuditTrail:async t=>{try{return m(await this.legacy.auditTrailService.listFinancialAuditTrail(t))}catch(r){return f(r)}}}}};function H(n){return new M({accountService:n,journalService:n,fiscalService:n,rapbService:n,openItemService:n,reconciliationService:n,cashMovementService:n,auditTrailService:n})}function h(n){return JSON.parse(JSON.stringify(n))}function b(){return new Date().toISOString()}function je(n,e){return`${n}:${e}:${Date.now()}:${Math.random().toString(36).slice(2,8)}`}function ke(n,e){return!n||n.deleted?!1:e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt&&n.occurredAt>e.occurredTo):!0}function Ue(n,e){return e?!(e.tenantId&&n.tenantId!==e.tenantId||e.branchId&&n.branchId!==e.branchId||e.financeDomainId&&n.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&n.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&n.occurredAt<e.occurredFrom||e.occurredTo&&n.occurredAt>e.occurredTo||e.recordId&&n.recordId!==e.recordId||e.journalId&&n.journalId!==e.journalId||e.eventTypes&&e.eventTypes.length>0&&!e.eventTypes.includes(n.eventType)):!0}function Ve(n){return typeof n!="string"||!n.startsWith("reversal:")?void 0:n.slice(9).trim()||void 0}var x=class{constructor(e){this.dbAdapter=e}async createAccount(e){if(!e.id||!e.code||!e.name)throw new Error("FINANCE_ACCOUNT_REQUIRED_FIELDS");let t=await this.dbAdapter.get(l.accounts,e.id);if(t&&!t.deleted)throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if((await this.dbAdapter.query(l.accounts,{filters:{and:[{field:"code",value:e.code},{field:"deleted",value:!1}]}})).some(i=>i.id!==e.id))throw new Error("FINANCE_ACCOUNT_CODE_DUPLICATE");let a=b(),o={...h(e),lastModified:a,deleted:!1};return t?await this.dbAdapter.update(l.accounts,e.id,o):await this.dbAdapter.create(l.accounts,o),await this.writeHistory("accounts",e.id,"UPSERT",o),h(e)}async listAccounts(){return(await this.dbAdapter.query(l.accounts,{filters:{field:"deleted",value:!1}})).map(({lastModified:t,deleted:r,...a})=>h(a)).sort((t,r)=>t.code.localeCompare(r.code))}async createJournalDraft(e){if(!e.id||!e.tenantId||!e.occurredAt)throw new Error("JOURNAL_REQUIRED_FIELDS");if(!e.ledgerProfileId)throw new Error("JOURNAL_REQUIRED_FIELDS");let t=await this.dbAdapter.get(l.journals,e.id);if(t&&!t.deleted)throw new Error("JOURNAL_ALREADY_EXISTS");await this.assertJournalLinesKnownAccounts(e.lines),await this.assertJournalPeriodOpen(e),P(e.lines);let r=R(e.lines);if(!r.ok)throw new Error(r.reason??"JOURNAL_INVALID");let a=b(),o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,evidenceRef:e.evidenceRef,status:"draft",postedAt:void 0,lastModified:a,deleted:!1};await this.dbAdapter.create(l.journals,o);for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s={id:`${e.id}:line:${i}`,journalId:e.id,accountId:c.accountId,debit:c.debit,credit:c.credit,memo:c.memo,openItemId:c.openItemId,openItemType:c.openItemType,counterpartyRef:c.counterpartyRef,documentRef:c.documentRef,dueAt:c.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:a,deleted:!1};await this.dbAdapter.create(l.journalLines,s),await this.writeHistory("journal_lines",s.id,"UPSERT",s)}return await this.writeHistory("journals",e.id,"UPSERT",o),this.toJournalEntry(o,e.lines)}async postJournal(e,t=b()){let r=await this.requireJournal(e),a=await this.listJournalLines(e);if(r.status==="posted"||r.status==="reversed")return this.toJournalEntry(r,a);let o={...r,status:"posted",postedAt:t,lastModified:b()};return await this.dbAdapter.update(l.journals,e,o),await this.writeHistory("journals",e,"UPSERT",o),this.toJournalEntry(o,a)}async reverseJournal(e,t){let r=await this.requireJournal(e);if(r.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");let a=await this.listJournalLines(e),o=await this.createJournalDraft({id:t,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:`reversal:${r.id}`,evidenceRef:r.evidenceRef,lines:a.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo,openItemId:i.openItemId,openItemType:i.openItemType,counterpartyRef:i.counterpartyRef,documentRef:i.documentRef,dueAt:i.dueAt}))});return this.postJournal(o.id)}async listJournals(e){let r=(await this.dbAdapter.query(l.journals,{filters:{field:"deleted",value:!1}})).filter(o=>ke(o,e)).sort((o,i)=>o.occurredAt.localeCompare(i.occurredAt)),a=[];for(let o of r){let i=await this.listJournalLines(o.id);a.push(this.toJournalEntry(o,i))}return a}async listOpenItems(e){return F(await this.listJournals(e),e)}async getOpenItemAging(e){return D(await this.listOpenItems(e),e)}async reconcileOpenItems(e){return O(await this.listOpenItems(e),e)}async listCashBankMovements(e){return T(await this.listJournals(e),e)}async summarizeCashBankMovements(e){return _(await this.listCashBankMovements(e))}async listFinancialAuditTrail(e){return(await this.dbAdapter.query(l.histories,{})).map(r=>this.toAuditTrailEntry(r)).filter(r=>r!==null).filter(r=>Ue(r,e)).sort((r,a)=>r.occurredAt!==a.occurredAt?r.occurredAt.localeCompare(a.occurredAt):r.id.localeCompare(a.id))}async openFiscalPeriod(e){if(!e.id||!e.tenantId||!e.code||!e.startDate||!e.endDate)throw new Error("FISCAL_PERIOD_REQUIRED_FIELDS");if(Date.parse(e.startDate)>Date.parse(e.endDate))throw new Error("FISCAL_PERIOD_INVALID_RANGE");let t=await this.dbAdapter.get(l.periods,e.id);if(t&&!t.deleted)throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");let r=b(),a={...h(e),status:"open",lastModified:r,deleted:!1};return t?await this.dbAdapter.update(l.periods,e.id,a):await this.dbAdapter.create(l.periods,a),await this.writeHistory("periods",e.id,"UPSERT",a),this.toPeriod(a)}async closeFiscalPeriod(e){let t=await this.dbAdapter.get(l.periods,e);if(!t||t.deleted)throw new Error("FISCAL_PERIOD_NOT_FOUND");let r={...t,status:"closed",lastModified:b()};return await this.dbAdapter.update(l.periods,e,r),await this.writeHistory("periods",e,"UPSERT",r),this.toPeriod(r)}async listFiscalPeriods(){return(await this.dbAdapter.query(l.periods,{filters:{field:"deleted",value:!1}})).map(t=>this.toPeriod(t)).sort((t,r)=>t.startDate.localeCompare(r.startDate))}async getTrialBalance(){return this.getTrialBalanceByScope()}async getTrialBalanceByScope(e){let t=await this.listAccounts(),a=(await this.listJournals(e)).filter(i=>i.status==="posted"),o=new Map;for(let i of a)for(let c of i.lines){let s=o.get(c.accountId)??{debit:0,credit:0};s.debit+=Number(c.debit||0),s.credit+=Number(c.credit||0),o.set(c.accountId,s)}return t.map(i=>{let c=o.get(i.id)??{debit:0,credit:0};return{accountId:i.id,accountCode:i.code,accountName:i.name,accountType:i.type,debit:c.debit,credit:c.credit,net:c.debit-c.credit}})}async createRapb(e){if(!e.id||!e.tenantId||!e.periodCode||!e.title)throw new Error("RAPB_REQUIRED_FIELDS");if(!e.lines||e.lines.length===0)throw new Error("RAPB_LINES_REQUIRED");if(e.lines.some(i=>i.budgetedDebit<0||i.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=await this.dbAdapter.get(l.rapbPlans,e.id);if(t&&!t.deleted)throw new Error("RAPB_ALREADY_EXISTS");let r=b(),a=[];for(let i=0;i<e.lines.length;i+=1){let c=e.lines[i],s=await this.dbAdapter.get(l.accounts,c.accountId);if(!s||s.deleted)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${c.accountId}`);a.push({id:`${e.id}:line:${i}`,rapbId:e.id,accountId:c.accountId,accountCode:s.code,accountName:s.name,accountType:s.type,budgetedDebit:c.budgetedDebit,budgetedCredit:c.budgetedCredit,budgetedNet:c.budgetedDebit-c.budgetedCredit,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:r,deleted:!1})}let o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,periodCode:e.periodCode,title:e.title,status:"draft",notes:e.notes,createdAt:r,approvedAt:void 0,approvedBy:void 0,lastModified:r,deleted:!1};await this.dbAdapter.create(l.rapbPlans,o),await this.writeHistory("rapb_plans",e.id,"UPSERT",o);for(let i of a)await this.dbAdapter.create(l.rapbLines,i),await this.writeHistory("rapb_lines",i.id,"UPSERT",i);return this.toRapbPlan(o,a)}async getRapb(e){let t=await this.dbAdapter.get(l.rapbPlans,e);if(!t||t.deleted)return null;let r=await this.listRapbLines(e);return this.toRapbPlan(t,r)}async listRapb(e){let r=await this.dbAdapter.query(l.rapbPlans,{filters:{field:"deleted",value:!1}});e&&(e.tenantId&&(r=r.filter(o=>o.tenantId===e.tenantId)),e.periodCode&&(r=r.filter(o=>o.periodCode===e.periodCode)),e.branchId&&(r=r.filter(o=>o.branchId===e.branchId)),e.financeDomainId&&(r=r.filter(o=>o.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(r=r.filter(o=>o.ledgerProfileId===e.ledgerProfileId)));let a=[];for(let o of r.sort((i,c)=>i.createdAt.localeCompare(c.createdAt))){let i=await this.listRapbLines(o.id);a.push(this.toRapbPlan(o,i))}return a}async approveRapb(e,t){let r=await this.dbAdapter.get(l.rapbPlans,e);if(!r||r.deleted)throw new Error("RAPB_NOT_FOUND");if(r.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let a=typeof t=="string"?t:t.approvedBy,o={...r,status:"approved",approvedAt:b(),approvedBy:a,lastModified:b()};await this.dbAdapter.update(l.rapbPlans,e,o),await this.writeHistory("rapb_plans",e,"UPSERT",o);let i=await this.listRapbLines(e);return this.toRapbPlan(o,i)}async evaluateVariance(e){let t=await this.getRapb(e);if(!t)throw new Error("RAPB_NOT_FOUND");let r=await this.getTrialBalanceByScope({tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId}),a=new Map(r.map(d=>[d.accountId,d])),o=0,i=0,c=0,s=0,I=t.lines.map(d=>{let u=a.get(d.accountId),A=u?.debit??0,y=u?.credit??0,S=A-y;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=y-A):d.accountType==="expense"&&(c+=d.budgetedDebit-d.budgetedCredit,s+=A-y),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:A,actualCredit:y,actualNet:S,varianceDebit:A-d.budgetedDebit,varianceCredit:y-d.budgetedCredit,varianceNet:S-d.budgetedNet}}),p=o-c,g=i-s;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:b(),lines:I,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:c,totalActualExpense:s,budgetedNetIncome:p,actualNetIncome:g,netVariance:g-p}}async assertJournalLinesKnownAccounts(e){for(let t of e){let r=await this.dbAdapter.get(l.accounts,t.accountId);if(!r||r.deleted)throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}}async assertJournalPeriodOpen(e){let t=await this.dbAdapter.query(l.periods,{filters:{field:"deleted",value:!1}});if(t.length===0)return;let r=t.find(a=>!(a.tenantId!==e.tenantId||Date.parse(a.startDate)>Date.parse(e.occurredAt)||Date.parse(a.endDate)<Date.parse(e.occurredAt)||e.ledgerProfileId&&a.ledgerProfileId&&a.ledgerProfileId!==e.ledgerProfileId||e.financeDomainId&&a.financeDomainId&&a.financeDomainId!==e.financeDomainId));if(!r)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(r.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}async requireJournal(e){let t=await this.dbAdapter.get(l.journals,e);if(!t||t.deleted)throw new Error("JOURNAL_NOT_FOUND");return t}async listJournalLines(e){return(await this.dbAdapter.query(l.journalLines,{filters:{and:[{field:"journalId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}async listRapbLines(e){return(await this.dbAdapter.query(l.rapbLines,{filters:{and:[{field:"rapbId",value:e},{field:"deleted",value:!1}]}})).sort((r,a)=>r.id.localeCompare(a.id))}toJournalEntry(e,t){let{lastModified:r,deleted:a,...o}=e;return{...h(o),lines:t.map(i=>h(i))}}toPeriod(e){let{lastModified:t,deleted:r,...a}=e;return h(a)}toRapbPlan(e,t){let{lastModified:r,deleted:a,...o}=e;return{...h(o),lines:t.map(({id:i,rapbId:c,lastModified:s,deleted:I,...p})=>h(p))}}async writeHistory(e,t,r,a){let o=a,i={id:je(e,t),tableName:e,recordId:t,action:r,changes:h(o),timestamp:b(),tenantId:typeof o.tenantId=="string"?o.tenantId:void 0,branchId:typeof o.branchId=="string"?o.branchId:void 0,financeDomainId:typeof o.financeDomainId=="string"?o.financeDomainId:void 0,ledgerProfileId:typeof o.ledgerProfileId=="string"?o.ledgerProfileId:void 0};await this.dbAdapter.create(l.histories,i)}toAuditTrailEntry(e){let t=e.changes??{},r=typeof t.tenantId=="string"?t.tenantId:e.tenantId,a=typeof t.branchId=="string"?t.branchId:e.branchId,o=typeof t.financeDomainId=="string"?t.financeDomainId:e.financeDomainId,i=typeof t.ledgerProfileId=="string"?t.ledgerProfileId:e.ledgerProfileId;if(e.tableName==="journals"){let c=typeof t.reference=="string"?t.reference:void 0,s=typeof t.evidenceRef=="string"?t.evidenceRef:void 0,I=typeof t.status=="string"?t.status:void 0,p=Ve(c),g=I==="draft"?"journal_drafted":I==="posted"&&p?"journal_reversal_posted":I==="posted"?"journal_posted":null;return g?{id:e.id,occurredAt:e.timestamp,eventType:g,recordType:"journal",recordId:e.recordId,journalId:e.recordId,sourceJournalId:p,tenantId:r,branchId:a,financeDomainId:o,ledgerProfileId:i,reference:c,evidenceRef:s,summary:g==="journal_reversal_posted"?`Reversal journal ${e.recordId} posted for ${p}`:`Journal ${e.recordId} ${g==="journal_drafted"?"drafted":"posted"}`,metadata:{journalOccurredAt:t.occurredAt,status:I}}:null}if(e.tableName==="periods"){let c=typeof t.status=="string"?t.status:void 0;return c!=="open"&&c!=="closed"?null:{id:e.id,occurredAt:e.timestamp,eventType:c==="open"?"fiscal_period_opened":"fiscal_period_closed",recordType:"fiscal_period",recordId:e.recordId,tenantId:r,branchId:a,financeDomainId:o,ledgerProfileId:i,summary:`Fiscal period ${String(t.code??e.recordId)} ${c}`,metadata:{code:t.code,status:c,startDate:t.startDate,endDate:t.endDate}}}if(e.tableName==="rapb_plans"){let c=typeof t.status=="string"?t.status:void 0,s=c==="draft"?"rapb_created":c==="approved"?"rapb_approved":null;return s?{id:e.id,occurredAt:e.timestamp,eventType:s,recordType:"rapb_plan",recordId:e.recordId,tenantId:r,branchId:a,financeDomainId:o,ledgerProfileId:i,summary:s==="rapb_created"?`RAPB ${String(t.title??e.recordId)} created`:`RAPB ${String(t.title??e.recordId)} approved`,metadata:{title:t.title,status:c,periodCode:t.periodCode,approvedBy:t.approvedBy}}:null}return null}};async function Q(n){await N(n);let e=new x(n);return{financeService:H({createAccount:e.createAccount.bind(e),listAccounts:e.listAccounts.bind(e),createJournalDraft:e.createJournalDraft.bind(e),postJournal:e.postJournal.bind(e),reverseJournal:e.reverseJournal.bind(e),listJournals:e.listJournals.bind(e),openFiscalPeriod:e.openFiscalPeriod.bind(e),closeFiscalPeriod:e.closeFiscalPeriod.bind(e),listFiscalPeriods:e.listFiscalPeriods.bind(e),getTrialBalance:e.getTrialBalance.bind(e),getTrialBalanceByScope:e.getTrialBalanceByScope.bind(e),createRapb:e.createRapb.bind(e),getRapb:e.getRapb.bind(e),listRapb:e.listRapb.bind(e),approveRapb:e.approveRapb.bind(e),evaluateVariance:e.evaluateVariance.bind(e),listOpenItems:e.listOpenItems.bind(e),getOpenItemAging:e.getOpenItemAging.bind(e),reconcileOpenItems:e.reconcileOpenItems.bind(e),listCashBankMovements:e.listCashBankMovements.bind(e),summarizeCashBankMovements:e.summarizeCashBankMovements.bind(e),listFinancialAuditTrail:e.listFinancialAuditTrail.bind(e)})}}var B=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=(0,j.asReadonlyStore)(this.runtimeStateStore)}static builder(){return new J}get registry(){return this.runtime.registry}async start(e={}){this.runtimeStateStore.setState({phase:"starting",started:!1,lastError:null,lastTransitionAt:new Date().toISOString(),startCount:this.runtimeStateStore.getState().startCount,stopCount:this.runtimeStateStore.getState().stopCount});try{await this.runtime.start(e),this.domainServices=this.runtime.domainServices,this.runtimeStateStore.setState(t=>({...t,phase:"started",started:!0,startCount:t.startCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(t){throw this.runtimeStateStore.setState(r=>({...r,phase:"error",started:!1,lastError:t instanceof Error?t.message:String(t),lastTransitionAt:new Date().toISOString()})),t}}async stop(){this.runtimeStateStore.setState(e=>({...e,phase:"stopping",started:this.runtime.isStarted(),lastError:null,lastTransitionAt:new Date().toISOString()}));try{await this.runtime.stop(),this.runtimeStateStore.setState(e=>({...e,phase:"stopped",started:!1,stopCount:e.stopCount+1,lastError:null,lastTransitionAt:new Date().toISOString()}))}catch(e){throw this.runtimeStateStore.setState(t=>({...t,phase:"error",started:this.runtime.isStarted(),lastError:e instanceof Error?e.message:String(e),lastTransitionAt:new Date().toISOString()})),e}}isStarted(){return this.runtime.isStarted()}},J=class{constructor(){this.runtimeBuilder=se.CoreRuntime.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new ue.InMemoryDbAdapter)}withPlatformAdapter(e){return this.runtimeBuilder.withPlatformAdapter(e),this}withDbAdapter(e){return this.runtimeBuilder.withDbAdapter(e),this}withHttpAdapter(e){return this.runtimeBuilder.withHttpAdapter(e),this}withSocketAdapter(e){return this.runtimeBuilder.withSocketAdapter(e),this}withLoggerAdapter(e){return this.runtimeBuilder.withLoggerAdapter(e),this}withActivitySink(e){return this.runtimeBuilder.withActivitySink(e),this}withExtension(e,t){return this.runtimeBuilder.withExtension(e,t),this}withDomainServicesFactory(e){return this.domainServicesFactory=e,this}withRuntimeHooks(e){return this.runtimeHooks={...this.runtimeHooks,...e},this}build(){let e=(0,j.createStore)({phase:"idle",started:!1,startCount:0,stopCount:0,lastError:null,lastTransitionAt:new Date().toISOString()}),t={runMigrations:async a=>{let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");await N(o,a.registry?.loggerAdapter),this.runtimeHooks.runMigrations&&await this.runtimeHooks.runMigrations(a)},...this.runtimeHooks,createDomainServices:async a=>{if(this.domainServicesFactory)return this.domainServicesFactory();let o=a.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");return Q(o)}};this.runtimeBuilder.withHooks(t);let r=this.runtimeBuilder.build();return new B(r,e)}};function q(n){return!Array.isArray(n.components)||n.components.length===0?[]:n.components.map(e=>{if(!e.accountId?.trim())throw new Error("FINANCE_TAX_ACCOUNT_REQUIRED");if(!Number.isFinite(e.amount)||e.amount<=0)throw new Error("FINANCE_TAX_AMOUNT_INVALID");if(e.direction!=="payable"&&e.direction!=="receivable")throw new Error("FINANCE_TAX_DIRECTION_INVALID");let t=`${n.memoPrefix??"Finance tax"} ${e.direction}`;return{accountId:e.accountId,debit:e.direction==="receivable"?e.amount:0,credit:e.direction==="payable"?e.amount:0,memo:e.memo??t}})}function C(n,e,t){return{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:t?`${n.reference??""}${t}`:n.reference,evidenceRef:n.evidenceRef,lines:e}}function v(n,e){if(!Number.isFinite(n)||n<=0)throw new Error(e)}function Y(n,e){v(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,r=e.taxAmount??0;if(t<0||r<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let a=e.grossAmount,o=a-t+r,i=[{accountId:e.paymentAccountId,debit:o,credit:0,memo:"POS sale payment"},{accountId:e.revenueAccountId,debit:0,credit:a,memo:"POS sale revenue"}];if(t>0){if(!e.discountAccountId)throw new Error("POS_SALE_DISCOUNT_ACCOUNT_REQUIRED");i.push({accountId:e.discountAccountId,debit:t,credit:0,memo:"POS sale discount"})}if(r>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");i.push(...q({memoPrefix:"POS sale tax",components:[{accountId:e.taxPayableAccountId,amount:r,direction:"payable",memo:"POS sale tax payable"}]}))}return C(n,i)}function G(n,e){return v(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),C(n,[{accountId:e.receivableAccountId,debit:e.principalAmount,credit:0,memo:"Loan receivable principal"},{accountId:e.cashAccountId,debit:0,credit:e.principalAmount,memo:"Loan cash out"}])}function W(n,e){return v(e.amount,"COOP_SAVING_INVALID_AMOUNT"),C(n,[{accountId:e.cashAccountId,debit:e.amount,credit:0,memo:"Saving deposit cash in"},{accountId:e.savingLiabilityAccountId,debit:0,credit:e.amount,memo:"Saving liability increase"}])}function z(n,e){return v(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),C(n,[{accountId:e.savingLiabilityAccountId,debit:e.amount,credit:0,memo:"Saving liability decrease"},{accountId:e.cashAccountId,debit:0,credit:e.amount,memo:"Saving withdrawal cash out"}])}function X(n,e){v(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,r=e.penaltyAmount??0;if(t<0||r<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(r>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let a=e.principalAmount+t+r,o=[{accountId:e.cashAccountId,debit:a,credit:0,memo:"Loan repayment cash in"},{accountId:e.receivableAccountId,debit:0,credit:e.principalAmount,memo:"Loan receivable principal repayment"}];return t>0&&o.push({accountId:e.serviceRevenueAccountId,debit:0,credit:t,memo:"Loan service revenue"}),r>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:r,memo:"Loan penalty revenue"}),C(n,o)}function $e(n,e){if(v(e.amount,"COOP_SHU_PARTICIPATION_INVALID_AMOUNT"),!n.evidenceRef?.trim())throw new Error("COOP_SHU_PARTICIPATION_EVIDENCE_REQUIRED");return C(n,[{accountId:e.debitAccountId,debit:e.amount,credit:0,memo:e.memo??"Coop SHU participation manual recap debit"},{accountId:e.creditAccountId,debit:0,credit:e.amount,memo:e.memo??"Coop SHU participation manual recap credit"}])}function le(n,e){return e?{...n,...e}:{...n}}function E(n){let e=n.tenantId?n.scopedMapping.byTenant?.[n.tenantId]:void 0,t=n.tenantId&&n.branchId?`${n.tenantId}:${n.branchId}`:"",r=t?n.scopedMapping.byBranch?.[t]:void 0;return le(le(n.scopedMapping.default,e),r)}function K(n){return E(n)}function Z(n){return E(n)}function ee(n){return E(n)}function te(n){return E(n)}function ne(n){return E(n)}function He(n,e){let{scopedAccountMapping:t,...r}=e,a=K({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return Y(n,{...r,...a})}function Qe(n,e){let{scopedAccountMapping:t,...r}=e,a=Z({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return G(n,{...r,...a})}function qe(n,e){let{scopedAccountMapping:t,...r}=e,a=te({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return W(n,{...r,...a})}function Ye(n,e){let{scopedAccountMapping:t,...r}=e,a=ne({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return z(n,{...r,...a})}function Ge(n,e){let{scopedAccountMapping:t,...r}=e,a=ee({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return X(n,{...r,...a})}function k(n){return!!(n&&typeof n=="object"&&n.error)}function re(n){return n.startsWith("ofinance_")?`offinance_${n.slice(9)}`:n}async function We(n,e,t){let r=await n.accountService.listAccounts();if(k(r))throw new Error(r.error.message||r.error.code||"FINANCE_ACCOUNT_LIST_FAILED");let a=new Set((r.data||[]).map(o=>o.id));for(let o of e){if(a.has(o.id))continue;let i=await n.accountService.createAccount(o);if(k(i))throw new Error(i.error.message||i.error.code||"FINANCE_ACCOUNT_CREATE_FAILED");await t?.({changeId:`offinance:account:${o.id}`,entity:"FinanceAccount",table:re(l.accounts),type:"CREATE",data:o})}}async function pe(n,e,t){return n.query(e,{filters:{and:t}})}async function ze(n,e,t){if(!t)return;let r=await pe(n,l.journals,[{field:"id",value:e.id}]),a=await pe(n,l.journalLines,[{field:"journalId",value:e.id}]);r.length===0&&(r=[{id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,status:e.status,postedAt:e.postedAt,lastModified:e.postedAt||e.occurredAt,deleted:!1}]),a.length===0&&(a=e.lines.map((o,i)=>({id:`${e.id}:line:${i}`,journalId:e.id,accountId:o.accountId,debit:o.debit,credit:o.credit,memo:o.memo,openItemId:o.openItemId,openItemType:o.openItemType,counterpartyRef:o.counterpartyRef,documentRef:o.documentRef,dueAt:o.dueAt,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:e.postedAt||e.occurredAt,deleted:!1})));for(let o of r)await t({changeId:`offinance:journal:${o.id}`,entity:"FinanceJournalEntry",table:re(l.journals),type:"CREATE",data:o});for(let o of a)await t({changeId:`offinance:journal-line:${o.id}`,entity:"FinanceJournalLine",table:re(l.journalLines),type:"CREATE",data:o})}function Xe(n){return async e=>{let t=n.resolveFinanceServices();if(!t)throw new Error(n.missingServicesErrorCode||"FINANCE_SERVICES_UNAVAILABLE");let r=n.resolveLedgerProfileId().trim();if(!r)throw new Error(n.missingLedgerProfileErrorCode||"FINANCE_LEDGER_PROFILE_REQUIRED");let a=n.resolveSyncEnqueuer?.()??null;await We(t,n.requiredAccounts,a);let o=n.buildJournalDraft(e,r),i=await t.journalService.createJournalDraft(o);if(k(i)&&i.error.code!=="JOURNAL_ALREADY_EXISTS")throw new Error(i.error.message||i.error.code||"FINANCE_JOURNAL_CREATE_FAILED");let c=await t.journalService.postJournal(o.id,o.occurredAt);if(k(c))throw new Error(c.error.message||c.error.code||"FINANCE_JOURNAL_POST_FAILED");await ze(n.dbAdapter,c.data,a)}}function Ke(n){switch(n.accountType){case"asset":case"expense":return n.debit-n.credit;case"liability":case"equity":case"revenue":return n.credit-n.debit;default:return 0}}function L(n,e){return n.filter(t=>t.accountType===e).reduce((t,r)=>t+Ke(r),0)}function Ze(n){let e=L(n,"revenue"),t=L(n,"expense");return{revenue:e,expense:t,netIncome:e-t}}function et(n){return{assets:L(n,"asset"),liabilities:L(n,"liability"),equity:L(n,"equity")}}function me(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function tt(n){let e=n.filter(r=>r.accountType==="revenue").reduce((r,a)=>r+Math.max(0,me(a)),0),t=n.filter(r=>r.accountType==="expense").reduce((r,a)=>r+Math.max(0,me(a)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function nt(n,e){let t=[],r=0;for(let a of e){if(a.accountType==="revenue"){let o=a.credit-a.debit;o>0&&(t.push({accountId:a.accountId,debit:o,credit:0,memo:"Close revenue account"}),r+=o)}if(a.accountType==="expense"){let o=a.debit-a.credit;o>0&&(t.push({accountId:a.accountId,debit:0,credit:o,memo:"Close expense account"}),r-=o)}}return r>0?t.push({accountId:n.retainedEarningsAccountId,debit:0,credit:r,memo:"Retained earnings from period close"}):r<0&&t.push({accountId:n.retainedEarningsAccountId,debit:Math.abs(r),credit:0,memo:"Retained earnings from period close"}),{id:n.journalId,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:n.reference,lines:t}}function rt(n){return Array.isArray(n)?n.length:n&&typeof n=="object"?1:n===null||typeof n>"u"?0:1}function at(n){return n==="json"?"application/json":"text/csv"}function ot(n,e){if(n==="json")return`${JSON.stringify(e,null,2)}
2
+ `;if(typeof e!="string")throw new Error("FINANCE_COMPLIANCE_EXPORT_CSV_PAYLOAD_STRING_REQUIRED");return e}function it(n){let e=2166136261;for(let t=0;t<n.length;t+=1)e^=n.charCodeAt(t),e=Math.imul(e,16777619);return`fnv1a32-${(e>>>0).toString(16).padStart(8,"0")}`}function ct(n){if(!n.key?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_REQUIRED");if(!n.fileName?.trim())throw new Error("FINANCE_COMPLIANCE_EXPORT_FILE_NAME_REQUIRED");if(n.format!=="json"&&n.format!=="csv")throw new Error("FINANCE_COMPLIANCE_EXPORT_FORMAT_INVALID")}function dt(n){return n??"custom"}function ae(n){if(!Array.isArray(n.datasets)||n.datasets.length===0)throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASETS_REQUIRED");let e=new Set,t={},r=[];for(let o of n.datasets){if(ct(o),e.has(o.key))throw new Error("FINANCE_COMPLIANCE_EXPORT_DATASET_KEY_DUPLICATE");e.add(o.key);let i=ot(o.format,o.payload);t[o.fileName]=i,r.push({key:o.key,fileName:o.fileName,format:o.format,semantic:dt(o.semantic),contentType:o.contentType??at(o.format),recordCount:rt(o.payload),checksum:it(i)})}return{contract:{contractVersion:"fcx-v1",tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt??new Date().toISOString(),period:{from:n.period?.from??null,to:n.period?.to??null,label:n.period?.label??null},currency:{baseCurrencyCode:n.baseCurrencyCode??"IDR"},datasets:r,summary:{datasetCount:r.length,totalRecordCount:r.reduce((o,i)=>o+i.recordCount,0)}},files:t}}function st(n){return{version:"v1",generatedAt:n.generatedAt??new Date().toISOString(),payload:{trialBalance:n.trialBalance.map(e=>({...e})),incomeStatement:{...n.incomeStatement},balanceSheet:{...n.balanceSheet}}}}function ut(n){let e=[{key:"trial-balance",fileName:"trial_balance.json",format:"json",semantic:"trial_balance",payload:n.trialBalance},{key:"income-statement",fileName:"income_statement.json",format:"json",semantic:"income_statement",payload:n.incomeStatement},{key:"balance-sheet",fileName:"balance_sheet.json",format:"json",semantic:"balance_sheet",payload:n.balanceSheet}];return typeof n.openItems<"u"&&e.push({key:"open-items",fileName:"open_items.json",format:"json",semantic:"open_items",payload:n.openItems}),typeof n.agingSummary<"u"&&e.push({key:"aging-summary",fileName:"aging_summary.json",format:"json",semantic:"aging_summary",payload:n.agingSummary}),typeof n.reconciliationSummary<"u"&&e.push({key:"reconciliation-summary",fileName:"reconciliation_summary.json",format:"json",semantic:"reconciliation",payload:n.reconciliationSummary}),typeof n.cashMovements<"u"&&e.push({key:"cash-movements",fileName:"cash_movements.json",format:"json",semantic:"cash_movements",payload:n.cashMovements}),ae({tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,generatedAt:n.generatedAt,period:n.period,baseCurrencyCode:n.baseCurrencyCode,datasets:e})}function lt(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function fe(n,e){return e===0?n===0?1:0:Number((n/e).toFixed(4))}function pt(n,e){let t=e.map(a=>{let c=((a.accountCodes?.length?n.filter(I=>a.accountCodes?.includes(I.accountCode)):null)??n.filter(I=>a.accountType?I.accountType===a.accountType:!1)).reduce((I,p)=>I+lt(p),0),s=c-a.plannedAmount;return{id:a.id,label:a.label,plannedAmount:a.plannedAmount,actualAmount:c,varianceAmount:s,achievementRatio:fe(c,a.plannedAmount)}}),r=t.reduce((a,o)=>(a.plannedAmount+=o.plannedAmount,a.actualAmount+=o.actualAmount,a.varianceAmount+=o.varianceAmount,a),{plannedAmount:0,actualAmount:0,varianceAmount:0});return{rows:t,totals:{...r,achievementRatio:fe(r.actualAmount,r.plannedAmount)}}}function Ie(n,e){switch(e.type){case"finance.account.created":n.createAccount(e.payload);return;case"finance.period.opened":n.openFiscalPeriod(e.payload);return;case"finance.period.closed":n.closeFiscalPeriod(e.payload.periodId);return;case"finance.journal.drafted":n.createJournalDraft(e.payload);return;case"finance.journal.posted":n.postJournal(e.payload.journalId,e.payload.postedAt);return;case"finance.journal.reversed":n.reverseJournal(e.payload.journalId,e.payload.reversalId);return;default:throw new Error("FINANCE_EVENT_UNSUPPORTED")}}function mt(n){let e=new w;for(let t of n)Ie(e,t);return e}var ge=[{id:"coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coa-ar",code:"1201",name:"Piutang Usaha",type:"asset"},{id:"coa-ap",code:"2101",name:"Utang Usaha",type:"liability"},{id:"coa-retained",code:"3201",name:"Laba Ditahan",type:"equity"},{id:"coa-revenue",code:"4101",name:"Pendapatan Operasional",type:"revenue"},{id:"coa-expense",code:"5101",name:"Biaya Operasional",type:"expense"}];function ft(n="IDR"){return ge.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}var Ae=[{id:"coop-coa-cash",code:"1101",name:"Kas",type:"asset"},{id:"coop-coa-bank",code:"1102",name:"Bank",type:"asset"},{id:"coop-coa-loan-ar",code:"1201",name:"Piutang Pinjaman Anggota",type:"asset"},{id:"coop-coa-other-ar",code:"1202",name:"Piutang Lain-lain",type:"asset"},{id:"coop-coa-prepaid",code:"1301",name:"Biaya Dibayar Dimuka",type:"asset"},{id:"coop-coa-fixed-asset",code:"1401",name:"Aset Tetap",type:"asset"},{id:"coop-coa-accum-depr",code:"1402",name:"Akumulasi Penyusutan",type:"asset"},{id:"coop-coa-simp-pokok",code:"2101",name:"Simpanan Pokok",type:"liability"},{id:"coop-coa-simp-wajib",code:"2102",name:"Simpanan Wajib",type:"liability"},{id:"coop-coa-simp-sukarela",code:"2103",name:"Simpanan Sukarela",type:"liability"},{id:"coop-coa-simp-berjangka",code:"2104",name:"Simpanan Berjangka",type:"liability"},{id:"coop-coa-ap",code:"2201",name:"Utang Usaha",type:"liability"},{id:"coop-coa-ext-loan",code:"2301",name:"Pinjaman Luar",type:"liability"},{id:"coop-coa-tax-payable",code:"2401",name:"Utang Pajak",type:"liability"},{id:"coop-coa-modal-awal",code:"3101",name:"Modal Awal",type:"equity"},{id:"coop-coa-cadangan-umum",code:"3201",name:"Dana Cadangan Umum",type:"equity"},{id:"coop-coa-cadangan-tujuan",code:"3202",name:"Dana Cadangan Tujuan",type:"equity"},{id:"coop-coa-shu-prior",code:"3301",name:"SHU Tahun Lalu",type:"equity"},{id:"coop-coa-shu-current",code:"3302",name:"SHU Berjalan",type:"equity"},{id:"coop-coa-shu-reserve",code:"3303",name:"Dana SHU Belum Dibagi",type:"equity"},{id:"coop-coa-jasa-pinjaman",code:"4101",name:"Pendapatan Jasa Pinjaman",type:"revenue"},{id:"coop-coa-provisi",code:"4102",name:"Pendapatan Provisi",type:"revenue"},{id:"coop-coa-rev-other",code:"4103",name:"Pendapatan Lain-lain",type:"revenue"},{id:"coop-coa-beban-bunga",code:"5101",name:"Beban Bunga Simpanan",type:"expense"},{id:"coop-coa-beban-ops",code:"5102",name:"Beban Operasional",type:"expense"},{id:"coop-coa-beban-gaji",code:"5103",name:"Beban Gaji dan Tunjangan",type:"expense"},{id:"coop-coa-beban-admin",code:"5104",name:"Beban Administrasi",type:"expense"},{id:"coop-coa-beban-depr",code:"5105",name:"Beban Penyusutan",type:"expense"},{id:"coop-coa-prov-kredit",code:"5106",name:"Cadangan Kerugian Piutang",type:"expense"}];function It(n="IDR"){return Ae.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}function gt(n){let e=new Set,t=new Set;for(let r of n){if(!r.id||!r.code||!r.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(r.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(r.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(r.id),t.add(r.code)}return{ok:!0}}
3
3
  /*! For license information please see index.js.LEGAL.txt */
@@ -6,6 +6,7 @@ import type { FinanceJournalEntry, JournalDraftInput } from '../contracts/Journa
6
6
  import type { FinanceOpenItemAgingQuery, FinanceOpenItemAgingSummary, FinanceOpenItemPosition, FinanceOpenItemScope } from '../contracts/OpenItemContract.js';
7
7
  import type { FinanceOpenItemReconciliationInput, FinanceOpenItemReconciliationSummary } from '../contracts/ReconciliationContract.js';
8
8
  import type { FinanceCashBankMovementEntry, FinanceCashBankMovementScope, FinanceCashBankMovementSummary } from '../contracts/CashMovementContract.js';
9
+ import type { FinanceAuditTrailEntry, FinanceAuditTrailScope } from '../contracts/AuditTrailContract.js';
9
10
  export declare class DbAdapterOffinanceService {
10
11
  private readonly dbAdapter;
11
12
  constructor(dbAdapter: DbAdapter);
@@ -20,6 +21,7 @@ export declare class DbAdapterOffinanceService {
20
21
  reconcileOpenItems(input: FinanceOpenItemReconciliationInput): Promise<FinanceOpenItemReconciliationSummary>;
21
22
  listCashBankMovements(scope: FinanceCashBankMovementScope): Promise<FinanceCashBankMovementEntry[]>;
22
23
  summarizeCashBankMovements(scope: FinanceCashBankMovementScope): Promise<FinanceCashBankMovementSummary>;
24
+ listFinancialAuditTrail(scope?: FinanceAuditTrailScope): Promise<FinanceAuditTrailEntry[]>;
23
25
  openFiscalPeriod(period: FiscalPeriod): Promise<FiscalPeriod>;
24
26
  closeFiscalPeriod(periodId: string): Promise<FiscalPeriod>;
25
27
  listFiscalPeriods(): Promise<FiscalPeriod[]>;
@@ -41,4 +43,5 @@ export declare class DbAdapterOffinanceService {
41
43
  private toPeriod;
42
44
  private toRapbPlan;
43
45
  private writeHistory;
46
+ private toAuditTrailEntry;
44
47
  }
@@ -5,6 +5,7 @@ import type { FinanceJournalServiceContractV2, JournalDraftInput } from '../cont
5
5
  import type { FinanceOpenItemAgingQuery, FinanceOpenItemServiceContractV2, FinanceOpenItemScope } from '../contracts/OpenItemContract.js';
6
6
  import type { FinanceOpenItemReconciliationInput, FinanceReconciliationServiceContractV2 } from '../contracts/ReconciliationContract.js';
7
7
  import type { FinanceCashBankMovementScope, FinanceCashBankMovementServiceContractV2 } from '../contracts/CashMovementContract.js';
8
+ import type { FinanceAuditTrailScope, FinanceAuditTrailServiceContractV2 } from '../contracts/AuditTrailContract.js';
8
9
  export interface OffinanceLegacyServices {
9
10
  accountService: {
10
11
  createAccount(account: FinanceAccount): FinanceAccount | Promise<FinanceAccount>;
@@ -43,6 +44,9 @@ export interface OffinanceLegacyServices {
43
44
  listCashBankMovements(scope: FinanceCashBankMovementScope): any[] | Promise<any[]>;
44
45
  summarizeCashBankMovements(scope: FinanceCashBankMovementScope): any | Promise<any>;
45
46
  };
47
+ auditTrailService: {
48
+ listFinancialAuditTrail(scope?: FinanceAuditTrailScope): any[] | Promise<any[]>;
49
+ };
46
50
  }
47
51
  export interface OffinanceEnvelopeServices {
48
52
  accountService: FinanceAccountServiceContractV2;
@@ -52,6 +56,7 @@ export interface OffinanceEnvelopeServices {
52
56
  openItemService: FinanceOpenItemServiceContractV2;
53
57
  reconciliationService: FinanceReconciliationServiceContractV2;
54
58
  cashMovementService: FinanceCashBankMovementServiceContractV2;
59
+ auditTrailService: FinanceAuditTrailServiceContractV2;
55
60
  }
56
61
  export declare class OffinanceEnvelopeService implements OffinanceEnvelopeServices {
57
62
  private readonly legacy;
@@ -62,6 +67,7 @@ export declare class OffinanceEnvelopeService implements OffinanceEnvelopeServic
62
67
  readonly openItemService: FinanceOpenItemServiceContractV2;
63
68
  readonly reconciliationService: FinanceReconciliationServiceContractV2;
64
69
  readonly cashMovementService: FinanceCashBankMovementServiceContractV2;
70
+ readonly auditTrailService: FinanceAuditTrailServiceContractV2;
65
71
  constructor(legacy: OffinanceLegacyServices);
66
72
  }
67
73
  export declare function createOffinanceEnvelopeService(legacyService: {
@@ -88,4 +94,5 @@ export declare function createOffinanceEnvelopeService(legacyService: {
88
94
  reconcileOpenItems(input: FinanceOpenItemReconciliationInput): any | Promise<any>;
89
95
  listCashBankMovements(scope: FinanceCashBankMovementScope): any[] | Promise<any[]>;
90
96
  summarizeCashBankMovements(scope: FinanceCashBankMovementScope): any | Promise<any>;
97
+ listFinancialAuditTrail(scope?: FinanceAuditTrailScope): any[] | Promise<any[]>;
91
98
  }): OffinanceEnvelopeServices;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "offinance-shared-core",
3
- "version": "0.1.0-alpha.3",
3
+ "version": "0.1.0-alpha.4",
4
4
  "private": false,
5
5
  "description": "Offline-first platform-agnostic db-agnostic finance shared core",
6
6
  "author": {
@@ -41,7 +41,7 @@
41
41
  "vitest": "^1.6.1"
42
42
  },
43
43
  "dependencies": {
44
- "ofcore": "0.2.0-alpha.1"
44
+ "ofcore": "0.2.0-alpha.2"
45
45
  },
46
46
  "repository": {
47
47
  "type": "git",