/** * Billing Domain Entities * * Business entities for billing calculations and summaries */ export interface BillingSummaryData { totalOutstanding: number; totalOverdue: number; totalPaid: number; currency: string; currencySymbol?: string; invoiceCount: { total: number; unpaid: number; overdue: number; paid: number; }; } // Money representation (business concept) export interface Money { amount: number; currency: string; } // Currency formatting options (business rules) export interface CurrencyFormatOptions { currency?: string; locale?: string; minimumFractionDigits?: number; maximumFractionDigits?: number; } // Business logic for billing calculations export function calculateBillingSummary(invoices: Array<{ total: number; status: string; dueDate?: string; paidDate?: string; }>): Omit { const now = new Date(); return invoices.reduce((summary, invoice) => { const isOverdue = invoice.dueDate && new Date(invoice.dueDate) < now && !invoice.paidDate; const isPaid = !!invoice.paidDate; const isUnpaid = !isPaid; return { totalOutstanding: summary.totalOutstanding + (isUnpaid ? invoice.total : 0), totalOverdue: summary.totalOverdue + (isOverdue ? invoice.total : 0), totalPaid: summary.totalPaid + (isPaid ? invoice.total : 0), invoiceCount: { total: summary.invoiceCount.total + 1, unpaid: summary.invoiceCount.unpaid + (isUnpaid ? 1 : 0), overdue: summary.invoiceCount.overdue + (isOverdue ? 1 : 0), paid: summary.invoiceCount.paid + (isPaid ? 1 : 0), }, }; }, { totalOutstanding: 0, totalOverdue: 0, totalPaid: 0, invoiceCount: { total: 0, unpaid: 0, overdue: 0, paid: 0, }, }); }