offinance-shared-core 0.1.0-alpha.0 → 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/hostProjectionSink.d.ts +30 -0
- package/dist/data/schemas.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist/services/DbAdapterOffinanceService.d.ts +36 -0
- package/dist/services/OffinanceEnvelopeService.d.ts +32 -32
- package/dist/services/createDbAdapterOfinanceServices.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FinanceAccount } from '../contracts/AccountContract.js';
|
|
2
|
+
import type { JournalDraftInput } from '../contracts/JournalContract.js';
|
|
3
|
+
import type { FinanceAccountServiceContractV2 } from '../contracts/AccountContract.js';
|
|
4
|
+
import type { FinanceJournalServiceContractV2 } from '../contracts/JournalContract.js';
|
|
5
|
+
export type FinanceDbAdapterLike = {
|
|
6
|
+
query<T>(table: string, args?: unknown): Promise<T[]>;
|
|
7
|
+
};
|
|
8
|
+
export type FinanceSyncChange = {
|
|
9
|
+
changeId: string;
|
|
10
|
+
entity: string;
|
|
11
|
+
table: string;
|
|
12
|
+
type: 'CREATE' | 'UPDATE' | 'DELETE';
|
|
13
|
+
data: Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
export type FinanceSyncEnqueuer = (change: FinanceSyncChange) => Promise<void> | void;
|
|
16
|
+
export type FinanceProjectionServicesRef = {
|
|
17
|
+
accountService: Pick<FinanceAccountServiceContractV2, 'createAccount' | 'listAccounts'>;
|
|
18
|
+
journalService: Pick<FinanceJournalServiceContractV2, 'createJournalDraft' | 'postJournal'>;
|
|
19
|
+
};
|
|
20
|
+
export type CreateFinanceProjectionSinkOptions<TProjection> = {
|
|
21
|
+
dbAdapter: FinanceDbAdapterLike;
|
|
22
|
+
resolveFinanceServices: () => FinanceProjectionServicesRef | null;
|
|
23
|
+
resolveLedgerProfileId: () => string;
|
|
24
|
+
resolveSyncEnqueuer?: () => FinanceSyncEnqueuer | null;
|
|
25
|
+
requiredAccounts: FinanceAccount[];
|
|
26
|
+
buildJournalDraft: (projection: TProjection, ledgerProfileId: string) => JournalDraftInput;
|
|
27
|
+
missingServicesErrorCode?: string;
|
|
28
|
+
missingLedgerProfileErrorCode?: string;
|
|
29
|
+
};
|
|
30
|
+
export declare function createFinanceProjectionSink<TProjection>(options: CreateFinanceProjectionSinkOptions<TProjection>): (projection: TProjection) => Promise<void>;
|
package/dist/data/schemas.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare const OFINANCE_TABLES: {
|
|
|
4
4
|
readonly periods: "ofinance_periods";
|
|
5
5
|
readonly journals: "ofinance_journals";
|
|
6
6
|
readonly journalLines: "ofinance_journal_lines";
|
|
7
|
+
readonly rapbPlans: "ofinance_rapb_plans";
|
|
8
|
+
readonly rapbLines: "ofinance_rapb_lines";
|
|
7
9
|
readonly histories: "ofinance_histories";
|
|
8
10
|
};
|
|
9
11
|
export declare function getOfinanceTableSchemas(): TableSchema[];
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from './contracts/AdapterContract.js';
|
|
|
11
11
|
export * from './adapters/builders.js';
|
|
12
12
|
export * from './adapters/accountMapping.js';
|
|
13
13
|
export * from './adapters/scopedBuilders.js';
|
|
14
|
+
export * from './adapters/hostProjectionSink.js';
|
|
14
15
|
export * from './reporting/financialStatements.js';
|
|
15
16
|
export * from './reporting/closing.js';
|
|
16
17
|
export * from './reporting/exporters.js';
|
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
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 a of n){if(!a||!a.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(a.debit<0||a.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=a.debit,t+=a.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 l=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(a=>a.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 a={...t,status:"closed"};return this.state.periods.set(e,a),{...a}}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);let t=P(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let a={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,lines:e.lines.map(r=>({...r})),status:"draft"};return this.state.journals.set(a.id,a),{...a,lines:a.lines.map(r=>({...r}))}}postJournal(e,t=new Date().toISOString()){let a=this.state.journals.get(e);if(!a)throw new Error("JOURNAL_NOT_FOUND");if(a.status==="posted"||a.status==="reversed")return{...a,lines:a.lines.map(o=>({...o}))};this.applyLinesToBalance(a.lines);let r={...a,status:"posted",postedAt:t};return this.state.journals.set(e,r),{...r,lines:r.lines.map(o=>({...o}))}}reverseJournal(e,t){let a=this.state.journals.get(e);if(!a)throw new Error("JOURNAL_NOT_FOUND");if(a.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let r=a.lines.map(c=>({accountId:c.accountId,debit:c.credit,credit:c.debit,memo:c.memo})),o=this.createJournalDraft({id:t,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:`reversal:${a.id}`,lines:r});return this.postJournal(o.id)}getTrialBalance(){return this.getTrialBalanceByScope()}getTrialBalanceByScope(e){let t=this.computeScopedBalances(e);return this.listAccounts().map(r=>{let o=t.get(r.id)??{debit:0,credit:0};return{accountId:r.id,accountCode:r.code,accountName:r.name,accountType:r.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(a=>({...a}))})).sort((t,a)=>t.occurredAt.localeCompare(a.occurredAt))}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 a of this.state.periods.values()){let r=Date.parse(a.startDate),o=Date.parse(a.endDate);if(t>=r&&t<=o)return a}return null}applyLinesToBalance(e){for(let t of e){let a=this.state.balances.get(t.accountId)??{debit:0,credit:0};a.debit+=t.debit,a.credit+=t.credit,this.state.balances.set(t.accountId,a)}}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 a of this.state.journals.values())if(a.status==="posted"&&this.matchesScope(a,e))for(let r of a.lines){let o=t.get(r.accountId)??{debit:0,credit:0};o.debit+=r.debit,o.credit+=r.credit,t.set(r.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(r=>r.budgetedDebit<0||r.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=e.lines.map(r=>{let o=this.state.accounts.get(r.accountId);if(!o)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${r.accountId}`);let c=r.budgetedDebit-r.budgetedCredit;return{accountId:r.accountId,accountCode:o.code,accountName:o.name,accountType:o.type,budgetedDebit:r.budgetedDebit,budgetedCredit:r.budgetedCredit,budgetedNet:c}}),a={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(a.id,a),a}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(a=>a.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(a=>a.periodCode===e.periodCode)),e.branchId&&(t=t.filter(a=>a.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(a=>a.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(a=>a.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let a=this.state.rapbPlans.get(e);if(!a)throw new Error("RAPB_NOT_FOUND");let r=typeof t=="string"?t:t.approvedBy;if(a.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...a,status:"approved",approvedAt:new Date().toISOString(),approvedBy:r};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 a=this.getTrialBalance(),r=new Map(a.map(i=>[i.accountId,i])),o=0,c=0,d=0,g=0,u=t.lines.map(i=>{let R=r.get(i.accountId),f=R?.debit??0,I=R?.credit??0,O=f-I;return i.accountType==="revenue"?(o+=i.budgetedCredit-i.budgetedDebit,c+=I-f):i.accountType==="expense"&&(d+=i.budgetedDebit-i.budgetedCredit,g+=f-I),{accountId:i.accountId,accountCode:i.accountCode,accountName:i.accountName,accountType:i.accountType,budgetedDebit:i.budgetedDebit,budgetedCredit:i.budgetedCredit,budgetedNet:i.budgetedNet,actualDebit:f,actualCredit:I,actualNet:O,varianceDebit:f-i.budgetedDebit,varianceCredit:I-i.budgetedCredit,varianceNet:O-i.budgetedNet}}),h=o-d,E=c-g;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:u,totalBudgetedRevenue:o,totalActualRevenue:c,totalBudgetedExpense:d,totalActualExpense:g,budgetedNetIncome:h,actualNetIncome:E,netVariance:E-h}}};import{CoreRuntime as z}from"ofcore";import{InMemoryDbAdapter as K}from"ofcore";import{asReadonlyStore as X,createStore as Z}from"ofcore";function s(n,e){return{data:n,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function F(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 p(n,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return n instanceof Error?F(e,n.message||t):F(e,t)}var v=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return s(this.legacy.accountService.createAccount(t))}catch(a){return p(a)}},listAccounts:async()=>{try{return s(this.legacy.accountService.listAccounts())}catch(t){return p(t)}}},this.journalService={createJournalDraft:async t=>{try{return s(this.legacy.journalService.createJournalDraft(t))}catch(a){return p(a)}},postJournal:async(t,a)=>{try{return s(this.legacy.journalService.postJournal(t,a))}catch(r){return p(r)}},reverseJournal:async(t,a)=>{try{return s(this.legacy.journalService.reverseJournal(t,a))}catch(r){return p(r)}},listJournals:async t=>{try{return s(this.legacy.journalService.listJournals(t))}catch(a){return p(a)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return s(this.legacy.fiscalService.openFiscalPeriod(t))}catch(a){return p(a)}},closeFiscalPeriod:async t=>{try{return s(this.legacy.fiscalService.closeFiscalPeriod(t))}catch(a){return p(a)}},listFiscalPeriods:async()=>{try{return s(this.legacy.fiscalService.listFiscalPeriods())}catch(t){return p(t)}},getTrialBalance:async()=>{try{return s(this.legacy.fiscalService.getTrialBalance())}catch(t){return p(t)}},getTrialBalanceByScope:async t=>{try{return s(this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(a){return p(a)}}},this.rapbService={createRapb:async t=>{try{return s(this.legacy.rapbService.createRapb(t))}catch(a){return p(a)}},getRapb:async t=>{try{return s(this.legacy.rapbService.getRapb(t))}catch(a){return p(a)}},listRapb:async t=>{try{return s(this.legacy.rapbService.listRapb(t))}catch(a){return p(a)}},approveRapb:async(t,a)=>{try{return s(this.legacy.rapbService.approveRapb(t,a))}catch(r){return p(r)}},evaluateVariance:async t=>{try{return s(this.legacy.rapbService.evaluateVariance(t))}catch(a){return p(a)}}}}};function T(n){return new v({accountService:n,journalService:n,fiscalService:n,rapbService:n})}async function w(n){let e=new l;return{financeService:T(e)}}var m={accounts:"ofinance_accounts",periods:"ofinance_periods",journals:"ofinance_journals",journalLines:"ofinance_journal_lines",histories:"ofinance_histories"},G=[{name:m.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:m.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:m.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:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:m.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:"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:m.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 L(){return G.map(n=>({...n,columns:n.columns.map(e=>({...e}))}))}var x=[{toVersion:1,up:async n=>{let e=L();for(let t of e)try{await n.addTable(t)}catch{}}}];var $={logInfo(){},logWarn(){},logError(){}};async function _(n,e=$){e.logInfo("[offinance] starting database migration process");let t=[...x].sort((o,c)=>o.toVersion-c.toVersion),a=t.length>0?t[t.length-1].toVersion:0,r=await n.getSchemaVersion();if((r==null||r<0)&&(r=0),r>=a){e.logInfo(`[offinance] database already up-to-date at v${r}`);return}for(let o of t)o.toVersion>r&&(e.logInfo(`[offinance] applying migration v${o.toVersion}`),await o.up(n),await n.setSchemaVersion(o.toVersion),r=o.toVersion);e.logInfo(`[offinance] migration completed at v${r}`)}var C=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=X(this.runtimeStateStore)}static builder(){return new D}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(a=>({...a,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()}},D=class{constructor(){this.runtimeBuilder=z.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new K)}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=Z({phase:"idle",started:!1,startCount:0,stopCount:0,lastError:null,lastTransitionAt:new Date().toISOString()}),t={runMigrations:async r=>{let o=r.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");await _(o,r.registry?.loggerAdapter),this.runtimeHooks.runMigrations&&await this.runtimeHooks.runMigrations(r)},...this.runtimeHooks,createDomainServices:async r=>{if(this.domainServicesFactory)return this.domainServicesFactory();let o=r.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");return w(o)}};this.runtimeBuilder.withHooks(t);let a=this.runtimeBuilder.build();return new C(a,e)}};function y(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,lines:e}}function A(n,e){if(!Number.isFinite(n)||n<=0)throw new Error(e)}function M(n,e){A(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,a=e.taxAmount??0;if(t<0||a<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let r=e.grossAmount,o=r-t+a,c=[{accountId:e.paymentAccountId,debit:o,credit:0,memo:"POS sale payment"},{accountId:e.revenueAccountId,debit:0,credit:r,memo:"POS sale revenue"}];if(t>0){if(!e.discountAccountId)throw new Error("POS_SALE_DISCOUNT_ACCOUNT_REQUIRED");c.push({accountId:e.discountAccountId,debit:t,credit:0,memo:"POS sale discount"})}if(a>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");c.push({accountId:e.taxPayableAccountId,debit:0,credit:a,memo:"POS sale tax payable"})}return y(n,c)}function N(n,e){return A(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),y(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 B(n,e){return A(e.amount,"COOP_SAVING_INVALID_AMOUNT"),y(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 J(n,e){return A(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),y(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 j(n,e){A(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,a=e.penaltyAmount??0;if(t<0||a<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(a>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let r=e.principalAmount+t+a,o=[{accountId:e.cashAccountId,debit:r,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"}),a>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:a,memo:"Loan penalty revenue"}),y(n,o)}function U(n,e){return e?{...n,...e}:{...n}}function b(n){let e=n.tenantId?n.scopedMapping.byTenant?.[n.tenantId]:void 0,t=n.tenantId&&n.branchId?`${n.tenantId}:${n.branchId}`:"",a=t?n.scopedMapping.byBranch?.[t]:void 0;return U(U(n.scopedMapping.default,e),a)}function V(n){return b(n)}function k(n){return b(n)}function H(n){return b(n)}function W(n){return b(n)}function q(n){return b(n)}function Fe(n,e){let{scopedAccountMapping:t,...a}=e,r=V({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return M(n,{...a,...r})}function Te(n,e){let{scopedAccountMapping:t,...a}=e,r=k({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return N(n,{...a,...r})}function we(n,e){let{scopedAccountMapping:t,...a}=e,r=W({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return B(n,{...a,...r})}function Le(n,e){let{scopedAccountMapping:t,...a}=e,r=q({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return J(n,{...a,...r})}function xe(n,e){let{scopedAccountMapping:t,...a}=e,r=H({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return j(n,{...a,...r})}function ee(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 S(n,e){return n.filter(t=>t.accountType===e).reduce((t,a)=>t+ee(a),0)}function Me(n){let e=S(n,"revenue"),t=S(n,"expense");return{revenue:e,expense:t,netIncome:e-t}}function Ne(n){return{assets:S(n,"asset"),liabilities:S(n,"liability"),equity:S(n,"equity")}}function Q(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function Je(n){let e=n.filter(a=>a.accountType==="revenue").reduce((a,r)=>a+Math.max(0,Q(r)),0),t=n.filter(a=>a.accountType==="expense").reduce((a,r)=>a+Math.max(0,Q(r)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function je(n,e){let t=[],a=0;for(let r of e){if(r.accountType==="revenue"){let o=r.credit-r.debit;o>0&&(t.push({accountId:r.accountId,debit:o,credit:0,memo:"Close revenue account"}),a+=o)}if(r.accountType==="expense"){let o=r.debit-r.credit;o>0&&(t.push({accountId:r.accountId,debit:0,credit:o,memo:"Close expense account"}),a-=o)}}return a>0?t.push({accountId:n.retainedEarningsAccountId,debit:0,credit:a,memo:"Retained earnings from period close"}):a<0&&t.push({accountId:n.retainedEarningsAccountId,debit:Math.abs(a),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 Ve(n){return{version:"v1",generatedAt:n.generatedAt??new Date().toISOString(),payload:{trialBalance:n.trialBalance.map(e=>({...e})),incomeStatement:{...n.incomeStatement},balanceSheet:{...n.balanceSheet}}}}function te(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function Y(n,e){return e===0?n===0?1:0:Number((n/e).toFixed(4))}function He(n,e){let t=e.map(r=>{let d=((r.accountCodes?.length?n.filter(u=>r.accountCodes?.includes(u.accountCode)):null)??n.filter(u=>r.accountType?u.accountType===r.accountType:!1)).reduce((u,h)=>u+te(h),0),g=d-r.plannedAmount;return{id:r.id,label:r.label,plannedAmount:r.plannedAmount,actualAmount:d,varianceAmount:g,achievementRatio:Y(d,r.plannedAmount)}}),a=t.reduce((r,o)=>(r.plannedAmount+=o.plannedAmount,r.actualAmount+=o.actualAmount,r.varianceAmount+=o.varianceAmount,r),{plannedAmount:0,actualAmount:0,varianceAmount:0});return{rows:t,totals:{...a,achievementRatio:Y(a.actualAmount,a.plannedAmount)}}}function ne(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 Qe(n){let e=new l;for(let t of n)ne(e,t);return e}var ae=[{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 Ge(n="IDR"){return ae.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}var re=[{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 $e(n="IDR"){return re.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}function ze(n){let e=new Set,t=new Set;for(let a of n){if(!a.id||!a.code||!a.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(a.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(a.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(a.id),t.add(a.code)}return{ok:!0}}export{ae as CANONICAL_COA_TEMPLATES,re as COOP_COA_TEMPLATES,m as OFINANCE_TABLES,l as OffinanceCore,v as OffinanceEnvelopeService,C as OfinanceRuntimeCore,D as OfinanceRuntimeCoreBuilder,ne as applyFinanceDomainEvent,_ as applyPendingMigrations,Ne as buildBalanceSheet,He as buildBudgetVsRealization,Je as buildCashflowBaseline,je as buildClosingJournalDraft,Ve as buildFinanceExportEnvelope,Me as buildIncomeStatement,N as buildJournalFromCoopLoanDisbursement,j as buildJournalFromCoopLoanRepayment,B as buildJournalFromCoopSavingDeposit,J as buildJournalFromCoopSavingWithdrawal,M as buildJournalFromPosSale,Te as buildJournalFromScopedCoopLoanDisbursement,xe as buildJournalFromScopedCoopLoanRepayment,we as buildJournalFromScopedCoopSavingDeposit,Le as buildJournalFromScopedCoopSavingWithdrawal,Fe as buildJournalFromScopedPosSale,Ge as createCanonicalCoA,$e as createCoopCoA,w as createDbAdapterOfinanceServices,T as createOffinanceEnvelopeService,p as mapOffinanceErrorToEnvelope,Qe as replayFinanceDomainEvents,k as resolveCoopLoanDisbursementAccountMapping,H as resolveCoopLoanRepaymentAccountMapping,W as resolveCoopSavingDepositAccountMapping,q as resolveCoopSavingWithdrawalAccountMapping,V as resolvePosSaleAccountMapping,b as resolveScopedAccountMapping,F as toOffinanceFailureEnvelope,s as toOffinanceSuccessEnvelope,ze as validateCoaIntegrity,P as validateJournalBalance};
|
|
1
|
+
function D(r){if(!Array.isArray(r)||r.length===0)return{ok:!1,totalDebit:0,totalCredit:0,reason:"JOURNAL_LINES_EMPTY"};let e=0,t=0;for(let n of r){if(!n||!n.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(n.debit<0||n.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=n.debit,t+=n.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 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}}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(n=>n.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 n={...t,status:"closed"};return this.state.periods.set(e,n),{...n}}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);let t=D(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let n={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,lines:e.lines.map(a=>({...a})),status:"draft"};return this.state.journals.set(n.id,n),{...n,lines:n.lines.map(a=>({...a}))}}postJournal(e,t=new Date().toISOString()){let n=this.state.journals.get(e);if(!n)throw new Error("JOURNAL_NOT_FOUND");if(n.status==="posted"||n.status==="reversed")return{...n,lines:n.lines.map(o=>({...o}))};this.applyLinesToBalance(n.lines);let a={...n,status:"posted",postedAt:t};return this.state.journals.set(e,a),{...a,lines:a.lines.map(o=>({...o}))}}reverseJournal(e,t){let n=this.state.journals.get(e);if(!n)throw new Error("JOURNAL_NOT_FOUND");if(n.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let a=n.lines.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo})),o=this.createJournalDraft({id:t,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:`reversal:${n.id}`,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(n=>({...n}))})).sort((t,n)=>t.occurredAt.localeCompare(n.occurredAt))}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 n of this.state.periods.values()){let a=Date.parse(n.startDate),o=Date.parse(n.endDate);if(t>=a&&t<=o)return n}return null}applyLinesToBalance(e){for(let t of e){let n=this.state.balances.get(t.accountId)??{debit:0,credit:0};n.debit+=t.debit,n.credit+=t.credit,this.state.balances.set(t.accountId,n)}}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 n of this.state.journals.values())if(n.status==="posted"&&this.matchesScope(n,e))for(let a of n.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}}),n={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(n.id,n),n}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(n=>n.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(n=>n.periodCode===e.periodCode)),e.branchId&&(t=t.filter(n=>n.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(n=>n.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(n=>n.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let n=this.state.rapbPlans.get(e);if(!n)throw new Error("RAPB_NOT_FOUND");let a=typeof t=="string"?t:t.approvedBy;if(n.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...n,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 n=this.getTrialBalance(),a=new Map(n.map(d=>[d.accountId,d])),o=0,i=0,s=0,u=0,I=t.lines.map(d=>{let h=a.get(d.accountId),m=h?.debit??0,f=h?.credit??0,S=m-f;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=f-m):d.accountType==="expense"&&(s+=d.budgetedDebit-d.budgetedCredit,u+=m-f),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:m,actualCredit:f,actualNet:S,varianceDebit:m-d.budgetedDebit,varianceCredit:f-d.budgetedCredit,varianceNet:S-d.budgetedNet}}),A=o-s,y=i-u;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:I,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:s,totalActualExpense:u,budgetedNetIncome:A,actualNetIncome:y,netVariance:y-A}}};import{CoreRuntime as ae}from"ofcore";import{InMemoryDbAdapter as oe}from"ofcore";import{asReadonlyStore as ie,createStore as ce}from"ofcore";var c={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:c.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:c.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:c.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:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:c.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:"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:c.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:c.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:c.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 _(){return ee.map(r=>({...r,columns:r.columns.map(e=>({...e}))}))}var J=[{toVersion:1,up:async r=>{let e=_();for(let t of e)try{await r.addTable(t)}catch{}}},{toVersion:2,up:async r=>{let e=_().filter(t=>t.name==="ofinance_rapb_plans"||t.name==="ofinance_rapb_lines");for(let t of e)try{await r.addTable(t)}catch{}}}];var te={logInfo(){},logWarn(){},logError(){}};async function R(r,e=te){e.logInfo("[offinance] starting database migration process");let t=[...J].sort((o,i)=>o.toVersion-i.toVersion),n=t.length>0?t[t.length-1].toVersion:0,a=await r.getSchemaVersion();if((a==null||a<0)&&(a=0),a>=n){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(r),await r.setSchemaVersion(o.toVersion),a=o.toVersion);e.logInfo(`[offinance] migration completed at v${a}`)}function l(r,e){return{data:r,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function M(r,e,t={}){return{error:{code:r,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 p(r,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return r instanceof Error?M(e,r.message||t):M(e,t)}var T=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return l(await this.legacy.accountService.createAccount(t))}catch(n){return p(n)}},listAccounts:async()=>{try{return l(await this.legacy.accountService.listAccounts())}catch(t){return p(t)}}},this.journalService={createJournalDraft:async t=>{try{return l(await this.legacy.journalService.createJournalDraft(t))}catch(n){return p(n)}},postJournal:async(t,n)=>{try{return l(await this.legacy.journalService.postJournal(t,n))}catch(a){return p(a)}},reverseJournal:async(t,n)=>{try{return l(await this.legacy.journalService.reverseJournal(t,n))}catch(a){return p(a)}},listJournals:async t=>{try{return l(await this.legacy.journalService.listJournals(t))}catch(n){return p(n)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return l(await this.legacy.fiscalService.openFiscalPeriod(t))}catch(n){return p(n)}},closeFiscalPeriod:async t=>{try{return l(await this.legacy.fiscalService.closeFiscalPeriod(t))}catch(n){return p(n)}},listFiscalPeriods:async()=>{try{return l(await this.legacy.fiscalService.listFiscalPeriods())}catch(t){return p(t)}},getTrialBalance:async()=>{try{return l(await this.legacy.fiscalService.getTrialBalance())}catch(t){return p(t)}},getTrialBalanceByScope:async t=>{try{return l(await this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(n){return p(n)}}},this.rapbService={createRapb:async t=>{try{return l(await this.legacy.rapbService.createRapb(t))}catch(n){return p(n)}},getRapb:async t=>{try{return l(await this.legacy.rapbService.getRapb(t))}catch(n){return p(n)}},listRapb:async t=>{try{return l(await this.legacy.rapbService.listRapb(t))}catch(n){return p(n)}},approveRapb:async(t,n)=>{try{return l(await this.legacy.rapbService.approveRapb(t,n))}catch(a){return p(a)}},evaluateVariance:async t=>{try{return l(await this.legacy.rapbService.evaluateVariance(t))}catch(n){return p(n)}}}}};function B(r){return new T({accountService:r,journalService:r,fiscalService:r,rapbService:r})}function b(r){return JSON.parse(JSON.stringify(r))}function g(){return new Date().toISOString()}function ne(r,e){return`${r}:${e}:${Date.now()}:${Math.random().toString(36).slice(2,8)}`}function re(r,e){return!r||r.deleted?!1:e?!(e.tenantId&&r.tenantId!==e.tenantId||e.branchId&&r.branchId!==e.branchId||e.financeDomainId&&r.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&r.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&r.occurredAt&&r.occurredAt<e.occurredFrom||e.occurredTo&&r.occurredAt&&r.occurredAt>e.occurredTo):!0}var F=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(c.accounts,e.id);if(t&&!t.deleted)throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if((await this.dbAdapter.query(c.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=g(),o={...b(e),lastModified:a,deleted:!1};return t?await this.dbAdapter.update(c.accounts,e.id,o):await this.dbAdapter.create(c.accounts,o),await this.writeHistory("accounts",e.id,"UPSERT",o),b(e)}async listAccounts(){return(await this.dbAdapter.query(c.accounts,{filters:{field:"deleted",value:!1}})).map(({lastModified:t,deleted:n,...a})=>b(a)).sort((t,n)=>t.code.localeCompare(n.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(c.journals,e.id);if(t&&!t.deleted)throw new Error("JOURNAL_ALREADY_EXISTS");await this.assertJournalLinesKnownAccounts(e.lines),await this.assertJournalPeriodOpen(e);let n=D(e.lines);if(!n.ok)throw new Error(n.reason??"JOURNAL_INVALID");let a=g(),o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,status:"draft",postedAt:void 0,lastModified:a,deleted:!1};await this.dbAdapter.create(c.journals,o);for(let i=0;i<e.lines.length;i+=1){let s=e.lines[i],u={id:`${e.id}:line:${i}`,journalId:e.id,accountId:s.accountId,debit:s.debit,credit:s.credit,memo:s.memo,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:a,deleted:!1};await this.dbAdapter.create(c.journalLines,u),await this.writeHistory("journal_lines",u.id,"UPSERT",u)}return await this.writeHistory("journals",e.id,"UPSERT",o),this.toJournalEntry(o,e.lines)}async postJournal(e,t=g()){let n=await this.requireJournal(e),a=await this.listJournalLines(e);if(n.status==="posted"||n.status==="reversed")return this.toJournalEntry(n,a);let o={...n,status:"posted",postedAt:t,lastModified:g()};return await this.dbAdapter.update(c.journals,e,o),await this.writeHistory("journals",e,"UPSERT",o),this.toJournalEntry(o,a)}async reverseJournal(e,t){let n=await this.requireJournal(e);if(n.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");let a=await this.listJournalLines(e),o=await this.createJournalDraft({id:t,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:`reversal:${n.id}`,lines:a.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo}))});return this.postJournal(o.id)}async listJournals(e){let n=(await this.dbAdapter.query(c.journals,{filters:{field:"deleted",value:!1}})).filter(o=>re(o,e)).sort((o,i)=>o.occurredAt.localeCompare(i.occurredAt)),a=[];for(let o of n){let i=await this.listJournalLines(o.id);a.push(this.toJournalEntry(o,i))}return a}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(c.periods,e.id);if(t&&!t.deleted)throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");let n=g(),a={...b(e),status:"open",lastModified:n,deleted:!1};return t?await this.dbAdapter.update(c.periods,e.id,a):await this.dbAdapter.create(c.periods,a),await this.writeHistory("periods",e.id,"UPSERT",a),this.toPeriod(a)}async closeFiscalPeriod(e){let t=await this.dbAdapter.get(c.periods,e);if(!t||t.deleted)throw new Error("FISCAL_PERIOD_NOT_FOUND");let n={...t,status:"closed",lastModified:g()};return await this.dbAdapter.update(c.periods,e,n),await this.writeHistory("periods",e,"UPSERT",n),this.toPeriod(n)}async listFiscalPeriods(){return(await this.dbAdapter.query(c.periods,{filters:{field:"deleted",value:!1}})).map(t=>this.toPeriod(t)).sort((t,n)=>t.startDate.localeCompare(n.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 s of i.lines){let u=o.get(s.accountId)??{debit:0,credit:0};u.debit+=Number(s.debit||0),u.credit+=Number(s.credit||0),o.set(s.accountId,u)}return t.map(i=>{let s=o.get(i.id)??{debit:0,credit:0};return{accountId:i.id,accountCode:i.code,accountName:i.name,accountType:i.type,debit:s.debit,credit:s.credit,net:s.debit-s.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(c.rapbPlans,e.id);if(t&&!t.deleted)throw new Error("RAPB_ALREADY_EXISTS");let n=g(),a=[];for(let i=0;i<e.lines.length;i+=1){let s=e.lines[i],u=await this.dbAdapter.get(c.accounts,s.accountId);if(!u||u.deleted)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${s.accountId}`);a.push({id:`${e.id}:line:${i}`,rapbId:e.id,accountId:s.accountId,accountCode:u.code,accountName:u.name,accountType:u.type,budgetedDebit:s.budgetedDebit,budgetedCredit:s.budgetedCredit,budgetedNet:s.budgetedDebit-s.budgetedCredit,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:n,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:n,approvedAt:void 0,approvedBy:void 0,lastModified:n,deleted:!1};await this.dbAdapter.create(c.rapbPlans,o),await this.writeHistory("rapb_plans",e.id,"UPSERT",o);for(let i of a)await this.dbAdapter.create(c.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(c.rapbPlans,e);if(!t||t.deleted)return null;let n=await this.listRapbLines(e);return this.toRapbPlan(t,n)}async listRapb(e){let n=await this.dbAdapter.query(c.rapbPlans,{filters:{field:"deleted",value:!1}});e&&(e.tenantId&&(n=n.filter(o=>o.tenantId===e.tenantId)),e.periodCode&&(n=n.filter(o=>o.periodCode===e.periodCode)),e.branchId&&(n=n.filter(o=>o.branchId===e.branchId)),e.financeDomainId&&(n=n.filter(o=>o.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(n=n.filter(o=>o.ledgerProfileId===e.ledgerProfileId)));let a=[];for(let o of n.sort((i,s)=>i.createdAt.localeCompare(s.createdAt))){let i=await this.listRapbLines(o.id);a.push(this.toRapbPlan(o,i))}return a}async approveRapb(e,t){let n=await this.dbAdapter.get(c.rapbPlans,e);if(!n||n.deleted)throw new Error("RAPB_NOT_FOUND");if(n.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let a=typeof t=="string"?t:t.approvedBy,o={...n,status:"approved",approvedAt:g(),approvedBy:a,lastModified:g()};await this.dbAdapter.update(c.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 n=await this.getTrialBalanceByScope({tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId}),a=new Map(n.map(d=>[d.accountId,d])),o=0,i=0,s=0,u=0,I=t.lines.map(d=>{let h=a.get(d.accountId),m=h?.debit??0,f=h?.credit??0,S=m-f;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=f-m):d.accountType==="expense"&&(s+=d.budgetedDebit-d.budgetedCredit,u+=m-f),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:m,actualCredit:f,actualNet:S,varianceDebit:m-d.budgetedDebit,varianceCredit:f-d.budgetedCredit,varianceNet:S-d.budgetedNet}}),A=o-s,y=i-u;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:g(),lines:I,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:s,totalActualExpense:u,budgetedNetIncome:A,actualNetIncome:y,netVariance:y-A}}async assertJournalLinesKnownAccounts(e){for(let t of e){let n=await this.dbAdapter.get(c.accounts,t.accountId);if(!n||n.deleted)throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}}async assertJournalPeriodOpen(e){let t=await this.dbAdapter.query(c.periods,{filters:{field:"deleted",value:!1}});if(t.length===0)return;let n=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(!n)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(n.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}async requireJournal(e){let t=await this.dbAdapter.get(c.journals,e);if(!t||t.deleted)throw new Error("JOURNAL_NOT_FOUND");return t}async listJournalLines(e){return(await this.dbAdapter.query(c.journalLines,{filters:{and:[{field:"journalId",value:e},{field:"deleted",value:!1}]}})).sort((n,a)=>n.id.localeCompare(a.id))}async listRapbLines(e){return(await this.dbAdapter.query(c.rapbLines,{filters:{and:[{field:"rapbId",value:e},{field:"deleted",value:!1}]}})).sort((n,a)=>n.id.localeCompare(a.id))}toJournalEntry(e,t){let{lastModified:n,deleted:a,...o}=e;return{...b(o),lines:t.map(i=>b(i))}}toPeriod(e){let{lastModified:t,deleted:n,...a}=e;return b(a)}toRapbPlan(e,t){let{lastModified:n,deleted:a,...o}=e;return{...b(o),lines:t.map(({id:i,rapbId:s,lastModified:u,deleted:I,...A})=>b(A))}}async writeHistory(e,t,n,a){let o=a,i={id:ne(e,t),tableName:e,recordId:t,action:n,changes:b(o),timestamp:g(),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(c.histories,i)}};async function j(r){await R(r);let e=new F(r);return{financeService:B({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)})}}var L=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=ie(this.runtimeStateStore)}static builder(){return new N}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(n=>({...n,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()}},N=class{constructor(){this.runtimeBuilder=ae.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new oe)}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=ce({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 R(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 j(o)}};this.runtimeBuilder.withHooks(t);let n=this.runtimeBuilder.build();return new L(n,e)}};function P(r,e,t){return{id:r.journalId,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:t?`${r.reference??""}${t}`:r.reference,lines:e}}function v(r,e){if(!Number.isFinite(r)||r<=0)throw new Error(e)}function U(r,e){v(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,n=e.taxAmount??0;if(t<0||n<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let a=e.grossAmount,o=a-t+n,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(n>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");i.push({accountId:e.taxPayableAccountId,debit:0,credit:n,memo:"POS sale tax payable"})}return P(r,i)}function V(r,e){return v(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),P(r,[{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(r,e){return v(e.amount,"COOP_SAVING_INVALID_AMOUNT"),P(r,[{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 q(r,e){return v(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),P(r,[{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 H(r,e){v(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,n=e.penaltyAmount??0;if(t<0||n<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(n>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let a=e.principalAmount+t+n,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"}),n>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:n,memo:"Loan penalty revenue"}),P(r,o)}function $(r,e){return e?{...r,...e}:{...r}}function E(r){let e=r.tenantId?r.scopedMapping.byTenant?.[r.tenantId]:void 0,t=r.tenantId&&r.branchId?`${r.tenantId}:${r.branchId}`:"",n=t?r.scopedMapping.byBranch?.[t]:void 0;return $($(r.scopedMapping.default,e),n)}function W(r){return E(r)}function Q(r){return E(r)}function Y(r){return E(r)}function G(r){return E(r)}function X(r){return E(r)}function qe(r,e){let{scopedAccountMapping:t,...n}=e,a=W({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return U(r,{...n,...a})}function He(r,e){let{scopedAccountMapping:t,...n}=e,a=Q({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return V(r,{...n,...a})}function $e(r,e){let{scopedAccountMapping:t,...n}=e,a=G({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return k(r,{...n,...a})}function We(r,e){let{scopedAccountMapping:t,...n}=e,a=X({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return q(r,{...n,...a})}function Qe(r,e){let{scopedAccountMapping:t,...n}=e,a=Y({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return H(r,{...n,...a})}function O(r){return!!(r&&typeof r=="object"&&r.error)}function x(r){return r.startsWith("ofinance_")?`offinance_${r.slice(9)}`:r}async function se(r,e,t){let n=await r.accountService.listAccounts();if(O(n))throw new Error(n.error.message||n.error.code||"FINANCE_ACCOUNT_LIST_FAILED");let a=new Set((n.data||[]).map(o=>o.id));for(let o of e){if(a.has(o.id))continue;let i=await r.accountService.createAccount(o);if(O(i))throw new Error(i.error.message||i.error.code||"FINANCE_ACCOUNT_CREATE_FAILED");await t?.({changeId:`offinance:account:${o.id}`,entity:"FinanceAccount",table:x(c.accounts),type:"CREATE",data:o})}}async function K(r,e,t){return r.query(e,{filters:{and:t}})}async function de(r,e,t){if(!t)return;let n=await K(r,c.journals,[{field:"id",value:e.id}]),a=await K(r,c.journalLines,[{field:"journalId",value:e.id}]);n.length===0&&(n=[{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,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:e.postedAt||e.occurredAt,deleted:!1})));for(let o of n)await t({changeId:`offinance:journal:${o.id}`,entity:"FinanceJournalEntry",table:x(c.journals),type:"CREATE",data:o});for(let o of a)await t({changeId:`offinance:journal-line:${o.id}`,entity:"FinanceJournalLine",table:x(c.journalLines),type:"CREATE",data:o})}function Xe(r){return async e=>{let t=r.resolveFinanceServices();if(!t)throw new Error(r.missingServicesErrorCode||"FINANCE_SERVICES_UNAVAILABLE");let n=r.resolveLedgerProfileId().trim();if(!n)throw new Error(r.missingLedgerProfileErrorCode||"FINANCE_LEDGER_PROFILE_REQUIRED");let a=r.resolveSyncEnqueuer?.()??null;await se(t,r.requiredAccounts,a);let o=r.buildJournalDraft(e,n),i=await t.journalService.createJournalDraft(o);if(O(i)&&i.error.code!=="JOURNAL_ALREADY_EXISTS")throw new Error(i.error.message||i.error.code||"FINANCE_JOURNAL_CREATE_FAILED");let s=await t.journalService.postJournal(o.id,o.occurredAt);if(O(s))throw new Error(s.error.message||s.error.code||"FINANCE_JOURNAL_POST_FAILED");await de(r.dbAdapter,s.data,a)}}function ue(r){switch(r.accountType){case"asset":case"expense":return r.debit-r.credit;case"liability":case"equity":case"revenue":return r.credit-r.debit;default:return 0}}function C(r,e){return r.filter(t=>t.accountType===e).reduce((t,n)=>t+ue(n),0)}function ze(r){let e=C(r,"revenue"),t=C(r,"expense");return{revenue:e,expense:t,netIncome:e-t}}function Ze(r){return{assets:C(r,"asset"),liabilities:C(r,"liability"),equity:C(r,"equity")}}function z(r){return r.accountType==="revenue"?r.credit-r.debit:r.accountType==="expense"?r.debit-r.credit:0}function tt(r){let e=r.filter(n=>n.accountType==="revenue").reduce((n,a)=>n+Math.max(0,z(a)),0),t=r.filter(n=>n.accountType==="expense").reduce((n,a)=>n+Math.max(0,z(a)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function nt(r,e){let t=[],n=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"}),n+=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"}),n-=o)}}return n>0?t.push({accountId:r.retainedEarningsAccountId,debit:0,credit:n,memo:"Retained earnings from period close"}):n<0&&t.push({accountId:r.retainedEarningsAccountId,debit:Math.abs(n),credit:0,memo:"Retained earnings from period close"}),{id:r.journalId,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:r.reference,lines:t}}function at(r){return{version:"v1",generatedAt:r.generatedAt??new Date().toISOString(),payload:{trialBalance:r.trialBalance.map(e=>({...e})),incomeStatement:{...r.incomeStatement},balanceSheet:{...r.balanceSheet}}}}function le(r){return r.accountType==="revenue"?r.credit-r.debit:r.accountType==="expense"?r.debit-r.credit:0}function Z(r,e){return e===0?r===0?1:0:Number((r/e).toFixed(4))}function it(r,e){let t=e.map(a=>{let s=((a.accountCodes?.length?r.filter(I=>a.accountCodes?.includes(I.accountCode)):null)??r.filter(I=>a.accountType?I.accountType===a.accountType:!1)).reduce((I,A)=>I+le(A),0),u=s-a.plannedAmount;return{id:a.id,label:a.label,plannedAmount:a.plannedAmount,actualAmount:s,varianceAmount:u,achievementRatio:Z(s,a.plannedAmount)}}),n=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:{...n,achievementRatio:Z(n.actualAmount,n.plannedAmount)}}}function pe(r,e){switch(e.type){case"finance.account.created":r.createAccount(e.payload);return;case"finance.period.opened":r.openFiscalPeriod(e.payload);return;case"finance.period.closed":r.closeFiscalPeriod(e.payload.periodId);return;case"finance.journal.drafted":r.createJournalDraft(e.payload);return;case"finance.journal.posted":r.postJournal(e.payload.journalId,e.payload.postedAt);return;case"finance.journal.reversed":r.reverseJournal(e.payload.journalId,e.payload.reversalId);return;default:throw new Error("FINANCE_EVENT_UNSUPPORTED")}}function dt(r){let e=new w;for(let t of r)pe(e,t);return e}var me=[{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 lt(r="IDR"){return me.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:r,isActive:!0}))}var fe=[{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 pt(r="IDR"){return fe.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:r,isActive:!0}))}function mt(r){let e=new Set,t=new Set;for(let n of r){if(!n.id||!n.code||!n.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(n.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(n.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(n.id),t.add(n.code)}return{ok:!0}}export{me as CANONICAL_COA_TEMPLATES,fe as COOP_COA_TEMPLATES,c as OFINANCE_TABLES,w as OffinanceCore,T as OffinanceEnvelopeService,L as OfinanceRuntimeCore,N as OfinanceRuntimeCoreBuilder,pe as applyFinanceDomainEvent,R as applyPendingMigrations,Ze as buildBalanceSheet,it as buildBudgetVsRealization,tt as buildCashflowBaseline,nt as buildClosingJournalDraft,at as buildFinanceExportEnvelope,ze as buildIncomeStatement,V as buildJournalFromCoopLoanDisbursement,H as buildJournalFromCoopLoanRepayment,k as buildJournalFromCoopSavingDeposit,q as buildJournalFromCoopSavingWithdrawal,U as buildJournalFromPosSale,He as buildJournalFromScopedCoopLoanDisbursement,Qe as buildJournalFromScopedCoopLoanRepayment,$e as buildJournalFromScopedCoopSavingDeposit,We as buildJournalFromScopedCoopSavingWithdrawal,qe as buildJournalFromScopedPosSale,lt as createCanonicalCoA,pt as createCoopCoA,j as createDbAdapterOfinanceServices,Xe as createFinanceProjectionSink,B as createOffinanceEnvelopeService,p as mapOffinanceErrorToEnvelope,dt as replayFinanceDomainEvents,Q as resolveCoopLoanDisbursementAccountMapping,Y as resolveCoopLoanRepaymentAccountMapping,G as resolveCoopSavingDepositAccountMapping,X as resolveCoopSavingWithdrawalAccountMapping,W as resolvePosSaleAccountMapping,E as resolveScopedAccountMapping,M as toOffinanceFailureEnvelope,l as toOffinanceSuccessEnvelope,mt as validateCoaIntegrity,D as validateJournalBalance};
|
|
2
2
|
/*! For license information please see index.esm.js.LEGAL.txt */
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var R=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var ae=Object.prototype.hasOwnProperty;var re=(n,e)=>{for(var t in e)R(n,t,{get:e[t],enumerable:!0})},oe=(n,e,t,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ne(e))!ae.call(n,r)&&r!==t&&R(n,r,{get:()=>e[r],enumerable:!(a=te(e,r))||a.enumerable});return n};var ie=n=>oe(R({},"__esModule",{value:!0}),n);var Re={};re(Re,{CANONICAL_COA_TEMPLATES:()=>Z,COOP_COA_TEMPLATES:()=>ee,OFINANCE_TABLES:()=>m,OffinanceCore:()=>l,OffinanceEnvelopeService:()=>v,OfinanceRuntimeCore:()=>C,OfinanceRuntimeCoreBuilder:()=>D,applyFinanceDomainEvent:()=>X,applyPendingMigrations:()=>w,buildBalanceSheet:()=>Ie,buildBudgetVsRealization:()=>he,buildCashflowBaseline:()=>ye,buildClosingJournalDraft:()=>Ae,buildFinanceExportEnvelope:()=>be,buildIncomeStatement:()=>fe,buildJournalFromCoopLoanDisbursement:()=>x,buildJournalFromCoopLoanRepayment:()=>N,buildJournalFromCoopSavingDeposit:()=>_,buildJournalFromCoopSavingWithdrawal:()=>M,buildJournalFromPosSale:()=>L,buildJournalFromScopedCoopLoanDisbursement:()=>de,buildJournalFromScopedCoopLoanRepayment:()=>me,buildJournalFromScopedCoopSavingDeposit:()=>ue,buildJournalFromScopedCoopSavingWithdrawal:()=>le,buildJournalFromScopedPosSale:()=>pe,createCanonicalCoA:()=>Ce,createCoopCoA:()=>De,createDbAdapterOfinanceServices:()=>T,createOffinanceEnvelopeService:()=>F,mapOffinanceErrorToEnvelope:()=>s,replayFinanceDomainEvents:()=>ve,resolveCoopLoanDisbursementAccountMapping:()=>J,resolveCoopLoanRepaymentAccountMapping:()=>j,resolveCoopSavingDepositAccountMapping:()=>U,resolveCoopSavingWithdrawalAccountMapping:()=>V,resolvePosSaleAccountMapping:()=>B,resolveScopedAccountMapping:()=>g,toOffinanceFailureEnvelope:()=>P,toOffinanceSuccessEnvelope:()=>c,validateCoaIntegrity:()=>Ee,validateJournalBalance:()=>O});module.exports=ie(Re);function O(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 a of n){if(!a||!a.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(a.debit<0||a.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=a.debit,t+=a.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 l=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(a=>a.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 a={...t,status:"closed"};return this.state.periods.set(e,a),{...a}}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);let t=O(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let a={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,lines:e.lines.map(r=>({...r})),status:"draft"};return this.state.journals.set(a.id,a),{...a,lines:a.lines.map(r=>({...r}))}}postJournal(e,t=new Date().toISOString()){let a=this.state.journals.get(e);if(!a)throw new Error("JOURNAL_NOT_FOUND");if(a.status==="posted"||a.status==="reversed")return{...a,lines:a.lines.map(o=>({...o}))};this.applyLinesToBalance(a.lines);let r={...a,status:"posted",postedAt:t};return this.state.journals.set(e,r),{...r,lines:r.lines.map(o=>({...o}))}}reverseJournal(e,t){let a=this.state.journals.get(e);if(!a)throw new Error("JOURNAL_NOT_FOUND");if(a.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let r=a.lines.map(p=>({accountId:p.accountId,debit:p.credit,credit:p.debit,memo:p.memo})),o=this.createJournalDraft({id:t,tenantId:a.tenantId,branchId:a.branchId,financeDomainId:a.financeDomainId,ledgerProfileId:a.ledgerProfileId,occurredAt:a.occurredAt,reference:`reversal:${a.id}`,lines:r});return this.postJournal(o.id)}getTrialBalance(){return this.getTrialBalanceByScope()}getTrialBalanceByScope(e){let t=this.computeScopedBalances(e);return this.listAccounts().map(r=>{let o=t.get(r.id)??{debit:0,credit:0};return{accountId:r.id,accountCode:r.code,accountName:r.name,accountType:r.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(a=>({...a}))})).sort((t,a)=>t.occurredAt.localeCompare(a.occurredAt))}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 a of this.state.periods.values()){let r=Date.parse(a.startDate),o=Date.parse(a.endDate);if(t>=r&&t<=o)return a}return null}applyLinesToBalance(e){for(let t of e){let a=this.state.balances.get(t.accountId)??{debit:0,credit:0};a.debit+=t.debit,a.credit+=t.credit,this.state.balances.set(t.accountId,a)}}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 a of this.state.journals.values())if(a.status==="posted"&&this.matchesScope(a,e))for(let r of a.lines){let o=t.get(r.accountId)??{debit:0,credit:0};o.debit+=r.debit,o.credit+=r.credit,t.set(r.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(r=>r.budgetedDebit<0||r.budgetedCredit<0))throw new Error("RAPB_NEGATIVE_AMOUNT");let t=e.lines.map(r=>{let o=this.state.accounts.get(r.accountId);if(!o)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${r.accountId}`);let p=r.budgetedDebit-r.budgetedCredit;return{accountId:r.accountId,accountCode:o.code,accountName:o.name,accountType:o.type,budgetedDebit:r.budgetedDebit,budgetedCredit:r.budgetedCredit,budgetedNet:p}}),a={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(a.id,a),a}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(a=>a.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(a=>a.periodCode===e.periodCode)),e.branchId&&(t=t.filter(a=>a.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(a=>a.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(a=>a.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let a=this.state.rapbPlans.get(e);if(!a)throw new Error("RAPB_NOT_FOUND");let r=typeof t=="string"?t:t.approvedBy;if(a.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...a,status:"approved",approvedAt:new Date().toISOString(),approvedBy:r};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 a=this.getTrialBalance(),r=new Map(a.map(i=>[i.accountId,i])),o=0,p=0,d=0,f=0,u=t.lines.map(i=>{let H=r.get(i.accountId),I=H?.debit??0,y=H?.credit??0,W=I-y;return i.accountType==="revenue"?(o+=i.budgetedCredit-i.budgetedDebit,p+=y-I):i.accountType==="expense"&&(d+=i.budgetedDebit-i.budgetedCredit,f+=I-y),{accountId:i.accountId,accountCode:i.accountCode,accountName:i.accountName,accountType:i.accountType,budgetedDebit:i.budgetedDebit,budgetedCredit:i.budgetedCredit,budgetedNet:i.budgetedNet,actualDebit:I,actualCredit:y,actualNet:W,varianceDebit:I-i.budgetedDebit,varianceCredit:y-i.budgetedCredit,varianceNet:W-i.budgetedNet}}),h=o-d,k=p-f;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:u,totalBudgetedRevenue:o,totalActualRevenue:p,totalBudgetedExpense:d,totalActualExpense:f,budgetedNetIncome:h,actualNetIncome:k,netVariance:k-h}}};var Y=require("ofcore"),G=require("ofcore"),E=require("ofcore");function c(n,e){return{data:n,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function P(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 s(n,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return n instanceof Error?P(e,n.message||t):P(e,t)}var v=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return c(this.legacy.accountService.createAccount(t))}catch(a){return s(a)}},listAccounts:async()=>{try{return c(this.legacy.accountService.listAccounts())}catch(t){return s(t)}}},this.journalService={createJournalDraft:async t=>{try{return c(this.legacy.journalService.createJournalDraft(t))}catch(a){return s(a)}},postJournal:async(t,a)=>{try{return c(this.legacy.journalService.postJournal(t,a))}catch(r){return s(r)}},reverseJournal:async(t,a)=>{try{return c(this.legacy.journalService.reverseJournal(t,a))}catch(r){return s(r)}},listJournals:async t=>{try{return c(this.legacy.journalService.listJournals(t))}catch(a){return s(a)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return c(this.legacy.fiscalService.openFiscalPeriod(t))}catch(a){return s(a)}},closeFiscalPeriod:async t=>{try{return c(this.legacy.fiscalService.closeFiscalPeriod(t))}catch(a){return s(a)}},listFiscalPeriods:async()=>{try{return c(this.legacy.fiscalService.listFiscalPeriods())}catch(t){return s(t)}},getTrialBalance:async()=>{try{return c(this.legacy.fiscalService.getTrialBalance())}catch(t){return s(t)}},getTrialBalanceByScope:async t=>{try{return c(this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(a){return s(a)}}},this.rapbService={createRapb:async t=>{try{return c(this.legacy.rapbService.createRapb(t))}catch(a){return s(a)}},getRapb:async t=>{try{return c(this.legacy.rapbService.getRapb(t))}catch(a){return s(a)}},listRapb:async t=>{try{return c(this.legacy.rapbService.listRapb(t))}catch(a){return s(a)}},approveRapb:async(t,a)=>{try{return c(this.legacy.rapbService.approveRapb(t,a))}catch(r){return s(r)}},evaluateVariance:async t=>{try{return c(this.legacy.rapbService.evaluateVariance(t))}catch(a){return s(a)}}}}};function F(n){return new v({accountService:n,journalService:n,fiscalService:n,rapbService:n})}async function T(n){let e=new l;return{financeService:F(e)}}var m={accounts:"ofinance_accounts",periods:"ofinance_periods",journals:"ofinance_journals",journalLines:"ofinance_journal_lines",histories:"ofinance_histories"},ce=[{name:m.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:m.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:m.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:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:m.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:"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:m.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 q(){return ce.map(n=>({...n,columns:n.columns.map(e=>({...e}))}))}var Q=[{toVersion:1,up:async n=>{let e=q();for(let t of e)try{await n.addTable(t)}catch{}}}];var se={logInfo(){},logWarn(){},logError(){}};async function w(n,e=se){e.logInfo("[offinance] starting database migration process");let t=[...Q].sort((o,p)=>o.toVersion-p.toVersion),a=t.length>0?t[t.length-1].toVersion:0,r=await n.getSchemaVersion();if((r==null||r<0)&&(r=0),r>=a){e.logInfo(`[offinance] database already up-to-date at v${r}`);return}for(let o of t)o.toVersion>r&&(e.logInfo(`[offinance] applying migration v${o.toVersion}`),await o.up(n),await n.setSchemaVersion(o.toVersion),r=o.toVersion);e.logInfo(`[offinance] migration completed at v${r}`)}var C=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=(0,E.asReadonlyStore)(this.runtimeStateStore)}static builder(){return new D}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(a=>({...a,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()}},D=class{constructor(){this.runtimeBuilder=Y.CoreRuntime.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new G.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,E.createStore)({phase:"idle",started:!1,startCount:0,stopCount:0,lastError:null,lastTransitionAt:new Date().toISOString()}),t={runMigrations:async r=>{let o=r.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");await w(o,r.registry?.loggerAdapter),this.runtimeHooks.runMigrations&&await this.runtimeHooks.runMigrations(r)},...this.runtimeHooks,createDomainServices:async r=>{if(this.domainServicesFactory)return this.domainServicesFactory();let o=r.registry?.dbAdapter;if(!o)throw new Error("OFINANCE_DB_ADAPTER_REQUIRED");return T(o)}};this.runtimeBuilder.withHooks(t);let a=this.runtimeBuilder.build();return new C(a,e)}};function A(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,lines:e}}function b(n,e){if(!Number.isFinite(n)||n<=0)throw new Error(e)}function L(n,e){b(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,a=e.taxAmount??0;if(t<0||a<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let r=e.grossAmount,o=r-t+a,p=[{accountId:e.paymentAccountId,debit:o,credit:0,memo:"POS sale payment"},{accountId:e.revenueAccountId,debit:0,credit:r,memo:"POS sale revenue"}];if(t>0){if(!e.discountAccountId)throw new Error("POS_SALE_DISCOUNT_ACCOUNT_REQUIRED");p.push({accountId:e.discountAccountId,debit:t,credit:0,memo:"POS sale discount"})}if(a>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");p.push({accountId:e.taxPayableAccountId,debit:0,credit:a,memo:"POS sale tax payable"})}return A(n,p)}function x(n,e){return b(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),A(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 _(n,e){return b(e.amount,"COOP_SAVING_INVALID_AMOUNT"),A(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 M(n,e){return b(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),A(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 N(n,e){b(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,a=e.penaltyAmount??0;if(t<0||a<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(a>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let r=e.principalAmount+t+a,o=[{accountId:e.cashAccountId,debit:r,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"}),a>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:a,memo:"Loan penalty revenue"}),A(n,o)}function $(n,e){return e?{...n,...e}:{...n}}function g(n){let e=n.tenantId?n.scopedMapping.byTenant?.[n.tenantId]:void 0,t=n.tenantId&&n.branchId?`${n.tenantId}:${n.branchId}`:"",a=t?n.scopedMapping.byBranch?.[t]:void 0;return $($(n.scopedMapping.default,e),a)}function B(n){return g(n)}function J(n){return g(n)}function j(n){return g(n)}function U(n){return g(n)}function V(n){return g(n)}function pe(n,e){let{scopedAccountMapping:t,...a}=e,r=B({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return L(n,{...a,...r})}function de(n,e){let{scopedAccountMapping:t,...a}=e,r=J({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return x(n,{...a,...r})}function ue(n,e){let{scopedAccountMapping:t,...a}=e,r=U({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return _(n,{...a,...r})}function le(n,e){let{scopedAccountMapping:t,...a}=e,r=V({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return M(n,{...a,...r})}function me(n,e){let{scopedAccountMapping:t,...a}=e,r=j({tenantId:n.tenantId,branchId:n.branchId,scopedMapping:t});return N(n,{...a,...r})}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 S(n,e){return n.filter(t=>t.accountType===e).reduce((t,a)=>t+ge(a),0)}function fe(n){let e=S(n,"revenue"),t=S(n,"expense");return{revenue:e,expense:t,netIncome:e-t}}function Ie(n){return{assets:S(n,"asset"),liabilities:S(n,"liability"),equity:S(n,"equity")}}function z(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function ye(n){let e=n.filter(a=>a.accountType==="revenue").reduce((a,r)=>a+Math.max(0,z(r)),0),t=n.filter(a=>a.accountType==="expense").reduce((a,r)=>a+Math.max(0,z(r)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function Ae(n,e){let t=[],a=0;for(let r of e){if(r.accountType==="revenue"){let o=r.credit-r.debit;o>0&&(t.push({accountId:r.accountId,debit:o,credit:0,memo:"Close revenue account"}),a+=o)}if(r.accountType==="expense"){let o=r.debit-r.credit;o>0&&(t.push({accountId:r.accountId,debit:0,credit:o,memo:"Close expense account"}),a-=o)}}return a>0?t.push({accountId:n.retainedEarningsAccountId,debit:0,credit:a,memo:"Retained earnings from period close"}):a<0&&t.push({accountId:n.retainedEarningsAccountId,debit:Math.abs(a),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{version:"v1",generatedAt:n.generatedAt??new Date().toISOString(),payload:{trialBalance:n.trialBalance.map(e=>({...e})),incomeStatement:{...n.incomeStatement},balanceSheet:{...n.balanceSheet}}}}function Se(n){return n.accountType==="revenue"?n.credit-n.debit:n.accountType==="expense"?n.debit-n.credit:0}function K(n,e){return e===0?n===0?1:0:Number((n/e).toFixed(4))}function he(n,e){let t=e.map(r=>{let d=((r.accountCodes?.length?n.filter(u=>r.accountCodes?.includes(u.accountCode)):null)??n.filter(u=>r.accountType?u.accountType===r.accountType:!1)).reduce((u,h)=>u+Se(h),0),f=d-r.plannedAmount;return{id:r.id,label:r.label,plannedAmount:r.plannedAmount,actualAmount:d,varianceAmount:f,achievementRatio:K(d,r.plannedAmount)}}),a=t.reduce((r,o)=>(r.plannedAmount+=o.plannedAmount,r.actualAmount+=o.actualAmount,r.varianceAmount+=o.varianceAmount,r),{plannedAmount:0,actualAmount:0,varianceAmount:0});return{rows:t,totals:{...a,achievementRatio:K(a.actualAmount,a.plannedAmount)}}}function X(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 ve(n){let e=new l;for(let t of n)X(e,t);return e}var Z=[{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 Ce(n="IDR"){return Z.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}var ee=[{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 De(n="IDR"){return ee.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:n,isActive:!0}))}function Ee(n){let e=new Set,t=new Set;for(let a of n){if(!a.id||!a.code||!a.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(a.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(a.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(a.id),t.add(a.code)}return{ok:!0}}
|
|
1
|
+
"use strict";var x=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var de=Object.prototype.hasOwnProperty;var ue=(r,e)=>{for(var t in e)x(r,t,{get:e[t],enumerable:!0})},le=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of se(e))!de.call(r,a)&&a!==t&&x(r,a,{get:()=>e[a],enumerable:!(n=ce(e,a))||n.enumerable});return r};var pe=r=>le(x({},"__esModule",{value:!0}),r);var Me={};ue(Me,{CANONICAL_COA_TEMPLATES:()=>oe,COOP_COA_TEMPLATES:()=>ie,OFINANCE_TABLES:()=>c,OffinanceCore:()=>E,OffinanceEnvelopeService:()=>F,OfinanceRuntimeCore:()=>_,OfinanceRuntimeCoreBuilder:()=>T,applyFinanceDomainEvent:()=>ae,applyPendingMigrations:()=>C,buildBalanceSheet:()=>we,buildBudgetVsRealization:()=>Te,buildCashflowBaseline:()=>Re,buildClosingJournalDraft:()=>Fe,buildFinanceExportEnvelope:()=>Oe,buildIncomeStatement:()=>De,buildJournalFromCoopLoanDisbursement:()=>V,buildJournalFromCoopLoanRepayment:()=>H,buildJournalFromCoopSavingDeposit:()=>k,buildJournalFromCoopSavingWithdrawal:()=>q,buildJournalFromPosSale:()=>U,buildJournalFromScopedCoopLoanDisbursement:()=>Ae,buildJournalFromScopedCoopLoanRepayment:()=>Se,buildJournalFromScopedCoopSavingDeposit:()=>ye,buildJournalFromScopedCoopSavingWithdrawal:()=>he,buildJournalFromScopedPosSale:()=>be,createCanonicalCoA:()=>Ne,createCoopCoA:()=>xe,createDbAdapterOfinanceServices:()=>j,createFinanceProjectionSink:()=>Ee,createOffinanceEnvelopeService:()=>B,mapOffinanceErrorToEnvelope:()=>p,replayFinanceDomainEvents:()=>Le,resolveCoopLoanDisbursementAccountMapping:()=>W,resolveCoopLoanRepaymentAccountMapping:()=>Q,resolveCoopSavingDepositAccountMapping:()=>Y,resolveCoopSavingWithdrawalAccountMapping:()=>G,resolvePosSaleAccountMapping:()=>$,resolveScopedAccountMapping:()=>y,toOffinanceFailureEnvelope:()=>M,toOffinanceSuccessEnvelope:()=>l,validateCoaIntegrity:()=>Je,validateJournalBalance:()=>v});module.exports=pe(Me);function v(r){if(!Array.isArray(r)||r.length===0)return{ok:!1,totalDebit:0,totalCredit:0,reason:"JOURNAL_LINES_EMPTY"};let e=0,t=0;for(let n of r){if(!n||!n.accountId)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_ACCOUNT_REQUIRED"};if(n.debit<0||n.credit<0)return{ok:!1,totalDebit:e,totalCredit:t,reason:"JOURNAL_NEGATIVE_AMOUNT"};e+=n.debit,t+=n.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 E=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(n=>n.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 n={...t,status:"closed"};return this.state.periods.set(e,n),{...n}}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);let t=v(e.lines);if(!t.ok)throw new Error(t.reason??"JOURNAL_INVALID");let n={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,lines:e.lines.map(a=>({...a})),status:"draft"};return this.state.journals.set(n.id,n),{...n,lines:n.lines.map(a=>({...a}))}}postJournal(e,t=new Date().toISOString()){let n=this.state.journals.get(e);if(!n)throw new Error("JOURNAL_NOT_FOUND");if(n.status==="posted"||n.status==="reversed")return{...n,lines:n.lines.map(o=>({...o}))};this.applyLinesToBalance(n.lines);let a={...n,status:"posted",postedAt:t};return this.state.journals.set(e,a),{...a,lines:a.lines.map(o=>({...o}))}}reverseJournal(e,t){let n=this.state.journals.get(e);if(!n)throw new Error("JOURNAL_NOT_FOUND");if(n.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");if(this.state.journals.has(t))throw new Error("JOURNAL_ALREADY_EXISTS");let a=n.lines.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo})),o=this.createJournalDraft({id:t,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:`reversal:${n.id}`,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(n=>({...n}))})).sort((t,n)=>t.occurredAt.localeCompare(n.occurredAt))}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 n of this.state.periods.values()){let a=Date.parse(n.startDate),o=Date.parse(n.endDate);if(t>=a&&t<=o)return n}return null}applyLinesToBalance(e){for(let t of e){let n=this.state.balances.get(t.accountId)??{debit:0,credit:0};n.debit+=t.debit,n.credit+=t.credit,this.state.balances.set(t.accountId,n)}}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 n of this.state.journals.values())if(n.status==="posted"&&this.matchesScope(n,e))for(let a of n.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}}),n={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(n.id,n),n}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(n=>n.tenantId===e.tenantId)),e.periodCode&&(t=t.filter(n=>n.periodCode===e.periodCode)),e.branchId&&(t=t.filter(n=>n.branchId===e.branchId)),e.financeDomainId&&(t=t.filter(n=>n.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(t=t.filter(n=>n.ledgerProfileId===e.ledgerProfileId))),t}approveRapb(e,t){let n=this.state.rapbPlans.get(e);if(!n)throw new Error("RAPB_NOT_FOUND");let a=typeof t=="string"?t:t.approvedBy;if(n.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let o={...n,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 n=this.getTrialBalance(),a=new Map(n.map(d=>[d.accountId,d])),o=0,i=0,s=0,u=0,I=t.lines.map(d=>{let S=a.get(d.accountId),m=S?.debit??0,f=S?.credit??0,P=m-f;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=f-m):d.accountType==="expense"&&(s+=d.budgetedDebit-d.budgetedCredit,u+=m-f),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:m,actualCredit:f,actualNet:P,varianceDebit:m-d.budgetedDebit,varianceCredit:f-d.budgetedCredit,varianceNet:P-d.budgetedNet}}),A=o-s,h=i-u;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:new Date().toISOString(),lines:I,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:s,totalActualExpense:u,budgetedNetIncome:A,actualNetIncome:h,netVariance:h-A}}};var z=require("ofcore"),Z=require("ofcore"),L=require("ofcore");var c={accounts:"ofinance_accounts",periods:"ofinance_periods",journals:"ofinance_journals",journalLines:"ofinance_journal_lines",rapbPlans:"ofinance_rapb_plans",rapbLines:"ofinance_rapb_lines",histories:"ofinance_histories"},me=[{name:c.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:c.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:c.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:"status",type:"string",isIndexed:!0},{name:"postedAt",type:"string",isOptional:!0,isIndexed:!0},{name:"lastModified",type:"string"},{name:"deleted",type:"boolean",isIndexed:!0}]},{name:c.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:"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:c.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:c.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:c.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 J(){return me.map(r=>({...r,columns:r.columns.map(e=>({...e}))}))}var K=[{toVersion:1,up:async r=>{let e=J();for(let t of e)try{await r.addTable(t)}catch{}}},{toVersion:2,up:async r=>{let e=J().filter(t=>t.name==="ofinance_rapb_plans"||t.name==="ofinance_rapb_lines");for(let t of e)try{await r.addTable(t)}catch{}}}];var fe={logInfo(){},logWarn(){},logError(){}};async function C(r,e=fe){e.logInfo("[offinance] starting database migration process");let t=[...K].sort((o,i)=>o.toVersion-i.toVersion),n=t.length>0?t[t.length-1].toVersion:0,a=await r.getSchemaVersion();if((a==null||a<0)&&(a=0),a>=n){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(r),await r.setSchemaVersion(o.toVersion),a=o.toVersion);e.logInfo(`[offinance] migration completed at v${a}`)}function l(r,e){return{data:r,meta:{request_id:e??null,timestamp:new Date().toISOString()}}}function M(r,e,t={}){return{error:{code:r,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 p(r,e="FINANCE_NOT_IMPLEMENTED",t="Unhandled offinance error."){return r instanceof Error?M(e,r.message||t):M(e,t)}var F=class{constructor(e){this.legacy=e;this.accountService={createAccount:async t=>{try{return l(await this.legacy.accountService.createAccount(t))}catch(n){return p(n)}},listAccounts:async()=>{try{return l(await this.legacy.accountService.listAccounts())}catch(t){return p(t)}}},this.journalService={createJournalDraft:async t=>{try{return l(await this.legacy.journalService.createJournalDraft(t))}catch(n){return p(n)}},postJournal:async(t,n)=>{try{return l(await this.legacy.journalService.postJournal(t,n))}catch(a){return p(a)}},reverseJournal:async(t,n)=>{try{return l(await this.legacy.journalService.reverseJournal(t,n))}catch(a){return p(a)}},listJournals:async t=>{try{return l(await this.legacy.journalService.listJournals(t))}catch(n){return p(n)}}},this.fiscalService={openFiscalPeriod:async t=>{try{return l(await this.legacy.fiscalService.openFiscalPeriod(t))}catch(n){return p(n)}},closeFiscalPeriod:async t=>{try{return l(await this.legacy.fiscalService.closeFiscalPeriod(t))}catch(n){return p(n)}},listFiscalPeriods:async()=>{try{return l(await this.legacy.fiscalService.listFiscalPeriods())}catch(t){return p(t)}},getTrialBalance:async()=>{try{return l(await this.legacy.fiscalService.getTrialBalance())}catch(t){return p(t)}},getTrialBalanceByScope:async t=>{try{return l(await this.legacy.fiscalService.getTrialBalanceByScope(t))}catch(n){return p(n)}}},this.rapbService={createRapb:async t=>{try{return l(await this.legacy.rapbService.createRapb(t))}catch(n){return p(n)}},getRapb:async t=>{try{return l(await this.legacy.rapbService.getRapb(t))}catch(n){return p(n)}},listRapb:async t=>{try{return l(await this.legacy.rapbService.listRapb(t))}catch(n){return p(n)}},approveRapb:async(t,n)=>{try{return l(await this.legacy.rapbService.approveRapb(t,n))}catch(a){return p(a)}},evaluateVariance:async t=>{try{return l(await this.legacy.rapbService.evaluateVariance(t))}catch(n){return p(n)}}}}};function B(r){return new F({accountService:r,journalService:r,fiscalService:r,rapbService:r})}function b(r){return JSON.parse(JSON.stringify(r))}function g(){return new Date().toISOString()}function ge(r,e){return`${r}:${e}:${Date.now()}:${Math.random().toString(36).slice(2,8)}`}function Ie(r,e){return!r||r.deleted?!1:e?!(e.tenantId&&r.tenantId!==e.tenantId||e.branchId&&r.branchId!==e.branchId||e.financeDomainId&&r.financeDomainId!==e.financeDomainId||e.ledgerProfileId&&r.ledgerProfileId!==e.ledgerProfileId||e.occurredFrom&&r.occurredAt&&r.occurredAt<e.occurredFrom||e.occurredTo&&r.occurredAt&&r.occurredAt>e.occurredTo):!0}var O=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(c.accounts,e.id);if(t&&!t.deleted)throw new Error("FINANCE_ACCOUNT_ALREADY_EXISTS");if((await this.dbAdapter.query(c.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=g(),o={...b(e),lastModified:a,deleted:!1};return t?await this.dbAdapter.update(c.accounts,e.id,o):await this.dbAdapter.create(c.accounts,o),await this.writeHistory("accounts",e.id,"UPSERT",o),b(e)}async listAccounts(){return(await this.dbAdapter.query(c.accounts,{filters:{field:"deleted",value:!1}})).map(({lastModified:t,deleted:n,...a})=>b(a)).sort((t,n)=>t.code.localeCompare(n.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(c.journals,e.id);if(t&&!t.deleted)throw new Error("JOURNAL_ALREADY_EXISTS");await this.assertJournalLinesKnownAccounts(e.lines),await this.assertJournalPeriodOpen(e);let n=v(e.lines);if(!n.ok)throw new Error(n.reason??"JOURNAL_INVALID");let a=g(),o={id:e.id,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,occurredAt:e.occurredAt,reference:e.reference,status:"draft",postedAt:void 0,lastModified:a,deleted:!1};await this.dbAdapter.create(c.journals,o);for(let i=0;i<e.lines.length;i+=1){let s=e.lines[i],u={id:`${e.id}:line:${i}`,journalId:e.id,accountId:s.accountId,debit:s.debit,credit:s.credit,memo:s.memo,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:a,deleted:!1};await this.dbAdapter.create(c.journalLines,u),await this.writeHistory("journal_lines",u.id,"UPSERT",u)}return await this.writeHistory("journals",e.id,"UPSERT",o),this.toJournalEntry(o,e.lines)}async postJournal(e,t=g()){let n=await this.requireJournal(e),a=await this.listJournalLines(e);if(n.status==="posted"||n.status==="reversed")return this.toJournalEntry(n,a);let o={...n,status:"posted",postedAt:t,lastModified:g()};return await this.dbAdapter.update(c.journals,e,o),await this.writeHistory("journals",e,"UPSERT",o),this.toJournalEntry(o,a)}async reverseJournal(e,t){let n=await this.requireJournal(e);if(n.status!=="posted")throw new Error("JOURNAL_NOT_POSTED");let a=await this.listJournalLines(e),o=await this.createJournalDraft({id:t,tenantId:n.tenantId,branchId:n.branchId,financeDomainId:n.financeDomainId,ledgerProfileId:n.ledgerProfileId,occurredAt:n.occurredAt,reference:`reversal:${n.id}`,lines:a.map(i=>({accountId:i.accountId,debit:i.credit,credit:i.debit,memo:i.memo}))});return this.postJournal(o.id)}async listJournals(e){let n=(await this.dbAdapter.query(c.journals,{filters:{field:"deleted",value:!1}})).filter(o=>Ie(o,e)).sort((o,i)=>o.occurredAt.localeCompare(i.occurredAt)),a=[];for(let o of n){let i=await this.listJournalLines(o.id);a.push(this.toJournalEntry(o,i))}return a}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(c.periods,e.id);if(t&&!t.deleted)throw new Error("FISCAL_PERIOD_ALREADY_EXISTS");let n=g(),a={...b(e),status:"open",lastModified:n,deleted:!1};return t?await this.dbAdapter.update(c.periods,e.id,a):await this.dbAdapter.create(c.periods,a),await this.writeHistory("periods",e.id,"UPSERT",a),this.toPeriod(a)}async closeFiscalPeriod(e){let t=await this.dbAdapter.get(c.periods,e);if(!t||t.deleted)throw new Error("FISCAL_PERIOD_NOT_FOUND");let n={...t,status:"closed",lastModified:g()};return await this.dbAdapter.update(c.periods,e,n),await this.writeHistory("periods",e,"UPSERT",n),this.toPeriod(n)}async listFiscalPeriods(){return(await this.dbAdapter.query(c.periods,{filters:{field:"deleted",value:!1}})).map(t=>this.toPeriod(t)).sort((t,n)=>t.startDate.localeCompare(n.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 s of i.lines){let u=o.get(s.accountId)??{debit:0,credit:0};u.debit+=Number(s.debit||0),u.credit+=Number(s.credit||0),o.set(s.accountId,u)}return t.map(i=>{let s=o.get(i.id)??{debit:0,credit:0};return{accountId:i.id,accountCode:i.code,accountName:i.name,accountType:i.type,debit:s.debit,credit:s.credit,net:s.debit-s.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(c.rapbPlans,e.id);if(t&&!t.deleted)throw new Error("RAPB_ALREADY_EXISTS");let n=g(),a=[];for(let i=0;i<e.lines.length;i+=1){let s=e.lines[i],u=await this.dbAdapter.get(c.accounts,s.accountId);if(!u||u.deleted)throw new Error(`RAPB_ACCOUNT_NOT_FOUND:${s.accountId}`);a.push({id:`${e.id}:line:${i}`,rapbId:e.id,accountId:s.accountId,accountCode:u.code,accountName:u.name,accountType:u.type,budgetedDebit:s.budgetedDebit,budgetedCredit:s.budgetedCredit,budgetedNet:s.budgetedDebit-s.budgetedCredit,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:n,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:n,approvedAt:void 0,approvedBy:void 0,lastModified:n,deleted:!1};await this.dbAdapter.create(c.rapbPlans,o),await this.writeHistory("rapb_plans",e.id,"UPSERT",o);for(let i of a)await this.dbAdapter.create(c.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(c.rapbPlans,e);if(!t||t.deleted)return null;let n=await this.listRapbLines(e);return this.toRapbPlan(t,n)}async listRapb(e){let n=await this.dbAdapter.query(c.rapbPlans,{filters:{field:"deleted",value:!1}});e&&(e.tenantId&&(n=n.filter(o=>o.tenantId===e.tenantId)),e.periodCode&&(n=n.filter(o=>o.periodCode===e.periodCode)),e.branchId&&(n=n.filter(o=>o.branchId===e.branchId)),e.financeDomainId&&(n=n.filter(o=>o.financeDomainId===e.financeDomainId)),e.ledgerProfileId&&(n=n.filter(o=>o.ledgerProfileId===e.ledgerProfileId)));let a=[];for(let o of n.sort((i,s)=>i.createdAt.localeCompare(s.createdAt))){let i=await this.listRapbLines(o.id);a.push(this.toRapbPlan(o,i))}return a}async approveRapb(e,t){let n=await this.dbAdapter.get(c.rapbPlans,e);if(!n||n.deleted)throw new Error("RAPB_NOT_FOUND");if(n.status==="approved")throw new Error("RAPB_ALREADY_APPROVED");let a=typeof t=="string"?t:t.approvedBy,o={...n,status:"approved",approvedAt:g(),approvedBy:a,lastModified:g()};await this.dbAdapter.update(c.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 n=await this.getTrialBalanceByScope({tenantId:t.tenantId,branchId:t.branchId,financeDomainId:t.financeDomainId,ledgerProfileId:t.ledgerProfileId}),a=new Map(n.map(d=>[d.accountId,d])),o=0,i=0,s=0,u=0,I=t.lines.map(d=>{let S=a.get(d.accountId),m=S?.debit??0,f=S?.credit??0,P=m-f;return d.accountType==="revenue"?(o+=d.budgetedCredit-d.budgetedDebit,i+=f-m):d.accountType==="expense"&&(s+=d.budgetedDebit-d.budgetedCredit,u+=m-f),{accountId:d.accountId,accountCode:d.accountCode,accountName:d.accountName,accountType:d.accountType,budgetedDebit:d.budgetedDebit,budgetedCredit:d.budgetedCredit,budgetedNet:d.budgetedNet,actualDebit:m,actualCredit:f,actualNet:P,varianceDebit:m-d.budgetedDebit,varianceCredit:f-d.budgetedCredit,varianceNet:P-d.budgetedNet}}),A=o-s,h=i-u;return{rapbId:e,periodCode:t.periodCode,evaluatedAt:g(),lines:I,totalBudgetedRevenue:o,totalActualRevenue:i,totalBudgetedExpense:s,totalActualExpense:u,budgetedNetIncome:A,actualNetIncome:h,netVariance:h-A}}async assertJournalLinesKnownAccounts(e){for(let t of e){let n=await this.dbAdapter.get(c.accounts,t.accountId);if(!n||n.deleted)throw new Error("JOURNAL_ACCOUNT_NOT_FOUND")}}async assertJournalPeriodOpen(e){let t=await this.dbAdapter.query(c.periods,{filters:{field:"deleted",value:!1}});if(t.length===0)return;let n=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(!n)throw new Error("FISCAL_PERIOD_NOT_FOUND_FOR_DATE");if(n.status!=="open")throw new Error("FISCAL_PERIOD_CLOSED")}async requireJournal(e){let t=await this.dbAdapter.get(c.journals,e);if(!t||t.deleted)throw new Error("JOURNAL_NOT_FOUND");return t}async listJournalLines(e){return(await this.dbAdapter.query(c.journalLines,{filters:{and:[{field:"journalId",value:e},{field:"deleted",value:!1}]}})).sort((n,a)=>n.id.localeCompare(a.id))}async listRapbLines(e){return(await this.dbAdapter.query(c.rapbLines,{filters:{and:[{field:"rapbId",value:e},{field:"deleted",value:!1}]}})).sort((n,a)=>n.id.localeCompare(a.id))}toJournalEntry(e,t){let{lastModified:n,deleted:a,...o}=e;return{...b(o),lines:t.map(i=>b(i))}}toPeriod(e){let{lastModified:t,deleted:n,...a}=e;return b(a)}toRapbPlan(e,t){let{lastModified:n,deleted:a,...o}=e;return{...b(o),lines:t.map(({id:i,rapbId:s,lastModified:u,deleted:I,...A})=>b(A))}}async writeHistory(e,t,n,a){let o=a,i={id:ge(e,t),tableName:e,recordId:t,action:n,changes:b(o),timestamp:g(),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(c.histories,i)}};async function j(r){await C(r);let e=new O(r);return{financeService:B({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)})}}var _=class{constructor(e,t){this.runtime=e;this.runtimeStateStore=t;this.runtimeStore=(0,L.asReadonlyStore)(this.runtimeStateStore)}static builder(){return new T}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(n=>({...n,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()}},T=class{constructor(){this.runtimeBuilder=z.CoreRuntime.builder();this.runtimeHooks={};this.runtimeBuilder.withDbAdapter(()=>new Z.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,L.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 C(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 j(o)}};this.runtimeBuilder.withHooks(t);let n=this.runtimeBuilder.build();return new _(n,e)}};function D(r,e,t){return{id:r.journalId,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:t?`${r.reference??""}${t}`:r.reference,lines:e}}function w(r,e){if(!Number.isFinite(r)||r<=0)throw new Error(e)}function U(r,e){w(e.grossAmount,"POS_SALE_INVALID_GROSS_AMOUNT");let t=e.discountAmount??0,n=e.taxAmount??0;if(t<0||n<0)throw new Error("POS_SALE_NEGATIVE_COMPONENT");let a=e.grossAmount,o=a-t+n,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(n>0){if(!e.taxPayableAccountId)throw new Error("POS_SALE_TAX_ACCOUNT_REQUIRED");i.push({accountId:e.taxPayableAccountId,debit:0,credit:n,memo:"POS sale tax payable"})}return D(r,i)}function V(r,e){return w(e.principalAmount,"COOP_LOAN_INVALID_PRINCIPAL"),D(r,[{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(r,e){return w(e.amount,"COOP_SAVING_INVALID_AMOUNT"),D(r,[{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 q(r,e){return w(e.amount,"COOP_SAVING_WITHDRAWAL_INVALID_AMOUNT"),D(r,[{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 H(r,e){w(e.principalAmount,"COOP_LOAN_REPAYMENT_INVALID_PRINCIPAL");let t=e.serviceAmount??0,n=e.penaltyAmount??0;if(t<0||n<0)throw new Error("COOP_LOAN_REPAYMENT_NEGATIVE_COMPONENT");if(t>0&&!e.serviceRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_SERVICE_ACCOUNT_REQUIRED");if(n>0&&!e.penaltyRevenueAccountId)throw new Error("COOP_LOAN_REPAYMENT_PENALTY_ACCOUNT_REQUIRED");let a=e.principalAmount+t+n,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"}),n>0&&o.push({accountId:e.penaltyRevenueAccountId,debit:0,credit:n,memo:"Loan penalty revenue"}),D(r,o)}function ee(r,e){return e?{...r,...e}:{...r}}function y(r){let e=r.tenantId?r.scopedMapping.byTenant?.[r.tenantId]:void 0,t=r.tenantId&&r.branchId?`${r.tenantId}:${r.branchId}`:"",n=t?r.scopedMapping.byBranch?.[t]:void 0;return ee(ee(r.scopedMapping.default,e),n)}function $(r){return y(r)}function W(r){return y(r)}function Q(r){return y(r)}function Y(r){return y(r)}function G(r){return y(r)}function be(r,e){let{scopedAccountMapping:t,...n}=e,a=$({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return U(r,{...n,...a})}function Ae(r,e){let{scopedAccountMapping:t,...n}=e,a=W({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return V(r,{...n,...a})}function ye(r,e){let{scopedAccountMapping:t,...n}=e,a=Y({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return k(r,{...n,...a})}function he(r,e){let{scopedAccountMapping:t,...n}=e,a=G({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return q(r,{...n,...a})}function Se(r,e){let{scopedAccountMapping:t,...n}=e,a=Q({tenantId:r.tenantId,branchId:r.branchId,scopedMapping:t});return H(r,{...n,...a})}function N(r){return!!(r&&typeof r=="object"&&r.error)}function X(r){return r.startsWith("ofinance_")?`offinance_${r.slice(9)}`:r}async function Pe(r,e,t){let n=await r.accountService.listAccounts();if(N(n))throw new Error(n.error.message||n.error.code||"FINANCE_ACCOUNT_LIST_FAILED");let a=new Set((n.data||[]).map(o=>o.id));for(let o of e){if(a.has(o.id))continue;let i=await r.accountService.createAccount(o);if(N(i))throw new Error(i.error.message||i.error.code||"FINANCE_ACCOUNT_CREATE_FAILED");await t?.({changeId:`offinance:account:${o.id}`,entity:"FinanceAccount",table:X(c.accounts),type:"CREATE",data:o})}}async function te(r,e,t){return r.query(e,{filters:{and:t}})}async function ve(r,e,t){if(!t)return;let n=await te(r,c.journals,[{field:"id",value:e.id}]),a=await te(r,c.journalLines,[{field:"journalId",value:e.id}]);n.length===0&&(n=[{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,tenantId:e.tenantId,branchId:e.branchId,financeDomainId:e.financeDomainId,ledgerProfileId:e.ledgerProfileId,lastModified:e.postedAt||e.occurredAt,deleted:!1})));for(let o of n)await t({changeId:`offinance:journal:${o.id}`,entity:"FinanceJournalEntry",table:X(c.journals),type:"CREATE",data:o});for(let o of a)await t({changeId:`offinance:journal-line:${o.id}`,entity:"FinanceJournalLine",table:X(c.journalLines),type:"CREATE",data:o})}function Ee(r){return async e=>{let t=r.resolveFinanceServices();if(!t)throw new Error(r.missingServicesErrorCode||"FINANCE_SERVICES_UNAVAILABLE");let n=r.resolveLedgerProfileId().trim();if(!n)throw new Error(r.missingLedgerProfileErrorCode||"FINANCE_LEDGER_PROFILE_REQUIRED");let a=r.resolveSyncEnqueuer?.()??null;await Pe(t,r.requiredAccounts,a);let o=r.buildJournalDraft(e,n),i=await t.journalService.createJournalDraft(o);if(N(i)&&i.error.code!=="JOURNAL_ALREADY_EXISTS")throw new Error(i.error.message||i.error.code||"FINANCE_JOURNAL_CREATE_FAILED");let s=await t.journalService.postJournal(o.id,o.occurredAt);if(N(s))throw new Error(s.error.message||s.error.code||"FINANCE_JOURNAL_POST_FAILED");await ve(r.dbAdapter,s.data,a)}}function Ce(r){switch(r.accountType){case"asset":case"expense":return r.debit-r.credit;case"liability":case"equity":case"revenue":return r.credit-r.debit;default:return 0}}function R(r,e){return r.filter(t=>t.accountType===e).reduce((t,n)=>t+Ce(n),0)}function De(r){let e=R(r,"revenue"),t=R(r,"expense");return{revenue:e,expense:t,netIncome:e-t}}function we(r){return{assets:R(r,"asset"),liabilities:R(r,"liability"),equity:R(r,"equity")}}function ne(r){return r.accountType==="revenue"?r.credit-r.debit:r.accountType==="expense"?r.debit-r.credit:0}function Re(r){let e=r.filter(n=>n.accountType==="revenue").reduce((n,a)=>n+Math.max(0,ne(a)),0),t=r.filter(n=>n.accountType==="expense").reduce((n,a)=>n+Math.max(0,ne(a)),0);return{operatingInflow:e,operatingOutflow:t,netOperatingCashflow:e-t}}function Fe(r,e){let t=[],n=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"}),n+=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"}),n-=o)}}return n>0?t.push({accountId:r.retainedEarningsAccountId,debit:0,credit:n,memo:"Retained earnings from period close"}):n<0&&t.push({accountId:r.retainedEarningsAccountId,debit:Math.abs(n),credit:0,memo:"Retained earnings from period close"}),{id:r.journalId,tenantId:r.tenantId,branchId:r.branchId,financeDomainId:r.financeDomainId,ledgerProfileId:r.ledgerProfileId,occurredAt:r.occurredAt,reference:r.reference,lines:t}}function Oe(r){return{version:"v1",generatedAt:r.generatedAt??new Date().toISOString(),payload:{trialBalance:r.trialBalance.map(e=>({...e})),incomeStatement:{...r.incomeStatement},balanceSheet:{...r.balanceSheet}}}}function _e(r){return r.accountType==="revenue"?r.credit-r.debit:r.accountType==="expense"?r.debit-r.credit:0}function re(r,e){return e===0?r===0?1:0:Number((r/e).toFixed(4))}function Te(r,e){let t=e.map(a=>{let s=((a.accountCodes?.length?r.filter(I=>a.accountCodes?.includes(I.accountCode)):null)??r.filter(I=>a.accountType?I.accountType===a.accountType:!1)).reduce((I,A)=>I+_e(A),0),u=s-a.plannedAmount;return{id:a.id,label:a.label,plannedAmount:a.plannedAmount,actualAmount:s,varianceAmount:u,achievementRatio:re(s,a.plannedAmount)}}),n=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:{...n,achievementRatio:re(n.actualAmount,n.plannedAmount)}}}function ae(r,e){switch(e.type){case"finance.account.created":r.createAccount(e.payload);return;case"finance.period.opened":r.openFiscalPeriod(e.payload);return;case"finance.period.closed":r.closeFiscalPeriod(e.payload.periodId);return;case"finance.journal.drafted":r.createJournalDraft(e.payload);return;case"finance.journal.posted":r.postJournal(e.payload.journalId,e.payload.postedAt);return;case"finance.journal.reversed":r.reverseJournal(e.payload.journalId,e.payload.reversalId);return;default:throw new Error("FINANCE_EVENT_UNSUPPORTED")}}function Le(r){let e=new E;for(let t of r)ae(e,t);return e}var oe=[{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 Ne(r="IDR"){return oe.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:r,isActive:!0}))}var ie=[{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 xe(r="IDR"){return ie.map(e=>({id:e.id,code:e.code,name:e.name,type:e.type,currency:r,isActive:!0}))}function Je(r){let e=new Set,t=new Set;for(let n of r){if(!n.id||!n.code||!n.name)return{ok:!1,reason:"COA_REQUIRED_FIELDS"};if(e.has(n.id))return{ok:!1,reason:"COA_DUPLICATE_ID"};if(t.has(n.code))return{ok:!1,reason:"COA_DUPLICATE_CODE"};e.add(n.id),t.add(n.code)}return{ok:!0}}
|
|
2
2
|
/*! For license information please see index.js.LEGAL.txt */
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DbAdapter } from 'ofcore';
|
|
2
|
+
import type { FinanceAccount } from '../contracts/AccountContract.js';
|
|
3
|
+
import type { CreateRapbInput, RapbPlan, RapbVariance } from '../contracts/BudgetContract.js';
|
|
4
|
+
import type { FinanceLedgerScope, FiscalPeriod, TrialBalanceRow } from '../contracts/FiscalContract.js';
|
|
5
|
+
import type { FinanceJournalEntry, JournalDraftInput } from '../contracts/JournalContract.js';
|
|
6
|
+
export declare class DbAdapterOffinanceService {
|
|
7
|
+
private readonly dbAdapter;
|
|
8
|
+
constructor(dbAdapter: DbAdapter);
|
|
9
|
+
createAccount(account: FinanceAccount): Promise<FinanceAccount>;
|
|
10
|
+
listAccounts(): Promise<FinanceAccount[]>;
|
|
11
|
+
createJournalDraft(input: JournalDraftInput): Promise<FinanceJournalEntry>;
|
|
12
|
+
postJournal(journalId: string, postedAt?: string): Promise<FinanceJournalEntry>;
|
|
13
|
+
reverseJournal(journalId: string, reversalId: string): Promise<FinanceJournalEntry>;
|
|
14
|
+
listJournals(scope?: FinanceLedgerScope): Promise<FinanceJournalEntry[]>;
|
|
15
|
+
openFiscalPeriod(period: FiscalPeriod): Promise<FiscalPeriod>;
|
|
16
|
+
closeFiscalPeriod(periodId: string): Promise<FiscalPeriod>;
|
|
17
|
+
listFiscalPeriods(): Promise<FiscalPeriod[]>;
|
|
18
|
+
getTrialBalance(): Promise<TrialBalanceRow[]>;
|
|
19
|
+
getTrialBalanceByScope(scope?: FinanceLedgerScope): Promise<TrialBalanceRow[]>;
|
|
20
|
+
createRapb(input: CreateRapbInput): Promise<RapbPlan>;
|
|
21
|
+
getRapb(id: string): Promise<RapbPlan | null>;
|
|
22
|
+
listRapb(scope?: Partial<RapbPlan>): Promise<RapbPlan[]>;
|
|
23
|
+
approveRapb(id: string, options: string | {
|
|
24
|
+
approvedBy: string;
|
|
25
|
+
}): Promise<RapbPlan>;
|
|
26
|
+
evaluateVariance(rapbId: string): Promise<RapbVariance>;
|
|
27
|
+
private assertJournalLinesKnownAccounts;
|
|
28
|
+
private assertJournalPeriodOpen;
|
|
29
|
+
private requireJournal;
|
|
30
|
+
private listJournalLines;
|
|
31
|
+
private listRapbLines;
|
|
32
|
+
private toJournalEntry;
|
|
33
|
+
private toPeriod;
|
|
34
|
+
private toRapbPlan;
|
|
35
|
+
private writeHistory;
|
|
36
|
+
}
|
|
@@ -4,30 +4,30 @@ import type { FinanceLedgerScope, FiscalPeriod, FiscalPeriodServiceContractV2 }
|
|
|
4
4
|
import type { FinanceJournalServiceContractV2, JournalDraftInput } from '../contracts/JournalContract.js';
|
|
5
5
|
export interface OffinanceLegacyServices {
|
|
6
6
|
accountService: {
|
|
7
|
-
createAccount(account: FinanceAccount): FinanceAccount
|
|
8
|
-
listAccounts(): FinanceAccount[]
|
|
7
|
+
createAccount(account: FinanceAccount): FinanceAccount | Promise<FinanceAccount>;
|
|
8
|
+
listAccounts(): FinanceAccount[] | Promise<FinanceAccount[]>;
|
|
9
9
|
};
|
|
10
10
|
journalService: {
|
|
11
|
-
createJournalDraft(input: JournalDraftInput): any
|
|
12
|
-
postJournal(journalId: string, postedAt?: string): any
|
|
13
|
-
reverseJournal(journalId: string, reversalId: string): any
|
|
14
|
-
listJournals(scope?: FinanceLedgerScope): any[]
|
|
11
|
+
createJournalDraft(input: JournalDraftInput): any | Promise<any>;
|
|
12
|
+
postJournal(journalId: string, postedAt?: string): any | Promise<any>;
|
|
13
|
+
reverseJournal(journalId: string, reversalId: string): any | Promise<any>;
|
|
14
|
+
listJournals(scope?: FinanceLedgerScope): any[] | Promise<any[]>;
|
|
15
15
|
};
|
|
16
16
|
fiscalService: {
|
|
17
|
-
openFiscalPeriod(period: FiscalPeriod): FiscalPeriod
|
|
18
|
-
closeFiscalPeriod(periodId: string): FiscalPeriod
|
|
19
|
-
listFiscalPeriods(): FiscalPeriod[]
|
|
20
|
-
getTrialBalance(): any[]
|
|
21
|
-
getTrialBalanceByScope(scope?: FinanceLedgerScope): any[]
|
|
17
|
+
openFiscalPeriod(period: FiscalPeriod): FiscalPeriod | Promise<FiscalPeriod>;
|
|
18
|
+
closeFiscalPeriod(periodId: string): FiscalPeriod | Promise<FiscalPeriod>;
|
|
19
|
+
listFiscalPeriods(): FiscalPeriod[] | Promise<FiscalPeriod[]>;
|
|
20
|
+
getTrialBalance(): any[] | Promise<any[]>;
|
|
21
|
+
getTrialBalanceByScope(scope?: FinanceLedgerScope): any[] | Promise<any[]>;
|
|
22
22
|
};
|
|
23
23
|
rapbService: {
|
|
24
|
-
createRapb(input: any): any
|
|
25
|
-
getRapb(id: string): any
|
|
26
|
-
listRapb(scope?: any): any[]
|
|
24
|
+
createRapb(input: any): any | Promise<any>;
|
|
25
|
+
getRapb(id: string): any | Promise<any>;
|
|
26
|
+
listRapb(scope?: any): any[] | Promise<any[]>;
|
|
27
27
|
approveRapb(id: string, options: string | {
|
|
28
28
|
approvedBy: string;
|
|
29
|
-
}): any
|
|
30
|
-
evaluateVariance(rapbId: string): any
|
|
29
|
+
}): any | Promise<any>;
|
|
30
|
+
evaluateVariance(rapbId: string): any | Promise<any>;
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
33
|
export interface OffinanceEnvelopeServices {
|
|
@@ -45,22 +45,22 @@ export declare class OffinanceEnvelopeService implements OffinanceEnvelopeServic
|
|
|
45
45
|
constructor(legacy: OffinanceLegacyServices);
|
|
46
46
|
}
|
|
47
47
|
export declare function createOffinanceEnvelopeService(legacyService: {
|
|
48
|
-
createAccount(account: FinanceAccount): FinanceAccount
|
|
49
|
-
listAccounts(): FinanceAccount[]
|
|
50
|
-
createJournalDraft(input: JournalDraftInput): any
|
|
51
|
-
postJournal(journalId: string, postedAt?: string): any
|
|
52
|
-
reverseJournal(journalId: string, reversalId: string): any
|
|
53
|
-
listJournals(scope?: FinanceLedgerScope): any[]
|
|
54
|
-
openFiscalPeriod(period: FiscalPeriod): FiscalPeriod
|
|
55
|
-
closeFiscalPeriod(periodId: string): FiscalPeriod
|
|
56
|
-
listFiscalPeriods(): FiscalPeriod[]
|
|
57
|
-
getTrialBalance(): any[]
|
|
58
|
-
getTrialBalanceByScope(scope?: FinanceLedgerScope): any[]
|
|
59
|
-
createRapb(input: any): any
|
|
60
|
-
getRapb(id: string): any
|
|
61
|
-
listRapb(scope?: any): any[]
|
|
48
|
+
createAccount(account: FinanceAccount): FinanceAccount | Promise<FinanceAccount>;
|
|
49
|
+
listAccounts(): FinanceAccount[] | Promise<FinanceAccount[]>;
|
|
50
|
+
createJournalDraft(input: JournalDraftInput): any | Promise<any>;
|
|
51
|
+
postJournal(journalId: string, postedAt?: string): any | Promise<any>;
|
|
52
|
+
reverseJournal(journalId: string, reversalId: string): any | Promise<any>;
|
|
53
|
+
listJournals(scope?: FinanceLedgerScope): any[] | Promise<any[]>;
|
|
54
|
+
openFiscalPeriod(period: FiscalPeriod): FiscalPeriod | Promise<FiscalPeriod>;
|
|
55
|
+
closeFiscalPeriod(periodId: string): FiscalPeriod | Promise<FiscalPeriod>;
|
|
56
|
+
listFiscalPeriods(): FiscalPeriod[] | Promise<FiscalPeriod[]>;
|
|
57
|
+
getTrialBalance(): any[] | Promise<any[]>;
|
|
58
|
+
getTrialBalanceByScope(scope?: FinanceLedgerScope): any[] | Promise<any[]>;
|
|
59
|
+
createRapb(input: any): any | Promise<any>;
|
|
60
|
+
getRapb(id: string): any | Promise<any>;
|
|
61
|
+
listRapb(scope?: any): any[] | Promise<any[]>;
|
|
62
62
|
approveRapb(id: string, options: string | {
|
|
63
63
|
approvedBy: string;
|
|
64
|
-
}): any
|
|
65
|
-
evaluateVariance(rapbId: string): any
|
|
64
|
+
}): any | Promise<any>;
|
|
65
|
+
evaluateVariance(rapbId: string): any | Promise<any>;
|
|
66
66
|
}): OffinanceEnvelopeServices;
|
|
@@ -3,4 +3,4 @@ import { type OffinanceEnvelopeServices } from './OffinanceEnvelopeService.js';
|
|
|
3
3
|
export interface OfinanceDomainServices {
|
|
4
4
|
financeService: OffinanceEnvelopeServices;
|
|
5
5
|
}
|
|
6
|
-
export declare function createDbAdapterOfinanceServices(
|
|
6
|
+
export declare function createDbAdapterOfinanceServices(dbAdapter: DbAdapter): Promise<OfinanceDomainServices>;
|