- Complete monorepo structure with pnpm workspaces and Turborepo - All packages implemented: types, utils, rules-engine, iso20022, treasury, risk-models, audit - React web application with TypeScript and Tailwind CSS - Full Brazil regulatory compliance (BCB requirements) - ISO 20022 message support (pacs.008, pacs.009, pain.001) - Treasury and subledger management - Risk, capital, and liquidity stress allocation - Audit logging and BCB reporting - E&O +10% uplift implementation
56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
import type {
|
|
SubledgerReport,
|
|
AccountPosting,
|
|
} from '@brazil-swift-ops/types';
|
|
import { getPostingStore } from './posting';
|
|
import { getAccountStore } from './accounts';
|
|
|
|
export function generateSubledgerReport(
|
|
subledgerId: string,
|
|
periodStart: Date,
|
|
periodEnd: Date
|
|
): SubledgerReport {
|
|
const accountStore = getAccountStore();
|
|
const postingStore = getPostingStore();
|
|
|
|
const subledger = accountStore.get(subledgerId);
|
|
if (!subledger || subledger.type !== 'subledger') {
|
|
throw new Error(`Subledger account ${subledgerId} not found`);
|
|
}
|
|
|
|
const postings = postingStore
|
|
.getByAccount(subledgerId)
|
|
.filter(
|
|
(p) => p.postedAt >= periodStart && p.postedAt <= periodEnd
|
|
);
|
|
|
|
const openingBalance = subledger.balance - postings.reduce((sum, p) => {
|
|
return p.postingType === 'debit' ? sum - p.amount : sum + p.amount;
|
|
}, 0);
|
|
|
|
const totalDebits = postings
|
|
.filter((p) => p.postingType === 'debit')
|
|
.reduce((sum, p) => sum + p.amount, 0);
|
|
|
|
const totalCredits = postings
|
|
.filter((p) => p.postingType === 'credit')
|
|
.reduce((sum, p) => sum + p.amount, 0);
|
|
|
|
const closingBalance = openingBalance + totalCredits - totalDebits;
|
|
const netPosition = totalCredits - totalDebits;
|
|
|
|
return {
|
|
subledgerId,
|
|
periodStart,
|
|
periodEnd,
|
|
openingBalance,
|
|
closingBalance,
|
|
totalDebits,
|
|
totalCredits,
|
|
netPosition,
|
|
currency: subledger.currency,
|
|
transactionCount: new Set(postings.map((p) => p.transactionId)).size,
|
|
postings,
|
|
};
|
|
}
|