using PowderCoating.Core.Enums; namespace PowderCoating.Application.DTOs.Accounting; // Accounting method badge — set on report DTOs so views can show "Cash Basis" / "Accrual Basis" // without needing a separate round-trip to the company settings. // ── Cash Flow Statement ────────────────────────────────────────────────────── /// /// Cash Flow Statement using the direct (cash-basis) method for operating activities. /// Investing and Financing sections contain line items derived from account-level changes. /// BeginningCash + NetChangeInCash should equal EndingCash (within rounding tolerances). /// public class CashFlowStatementDto { public string CompanyName { get; set; } = string.Empty; public DateTime From { get; set; } public DateTime To { get; set; } public AccountingMethod Method { get; set; } // ── Operating (direct / cash method) ─────────────────────────────────── /// Customer invoice payments received in the period. public decimal CashFromCustomers { get; set; } /// Vendor bill payments made in the period. public decimal CashToVendors { get; set; } /// Direct expense payments made in the period (not via bills). public decimal CashForExpenses { get; set; } public decimal NetOperating => CashFromCustomers - CashToVendors - CashForExpenses; // ── Investing ────────────────────────────────────────────────────────── public List InvestingLines { get; set; } = new(); public decimal NetInvesting => InvestingLines.Sum(l => l.Amount); // ── Financing ────────────────────────────────────────────────────────── public List FinancingLines { get; set; } = new(); public decimal NetFinancing => FinancingLines.Sum(l => l.Amount); // ── Summary ──────────────────────────────────────────────────────────── public decimal BeginningCash { get; set; } public decimal NetChangeInCash => NetOperating + NetInvesting + NetFinancing; public decimal EndingCash => BeginningCash + NetChangeInCash; } /// A single line in the Investing or Financing section of the Cash Flow Statement. public class CashFlowLineDto { public string Label { get; set; } = string.Empty; /// Positive = cash inflow, negative = cash outflow. public decimal Amount { get; set; } } // ── Customer / Vendor Statements ───────────────────────────────────────────── public class CustomerStatementDto { public int CustomerId { get; set; } public string CustomerName { get; set; } = string.Empty; public string CompanyName { get; set; } = string.Empty; public string? CustomerAddress { get; set; } public DateTime From { get; set; } public DateTime To { get; set; } public decimal OpeningBalance { get; set; } public List Lines { get; set; } = new(); public decimal ClosingBalance { get; set; } } public class VendorStatementDto { public int VendorId { get; set; } public string VendorName { get; set; } = string.Empty; public string CompanyName { get; set; } = string.Empty; public DateTime From { get; set; } public DateTime To { get; set; } public decimal OpeningBalance { get; set; } public List Lines { get; set; } = new(); public decimal ClosingBalance { get; set; } } public class StatementLineDto { public DateTime Date { get; set; } /// E.g., "Invoice", "Payment", "Credit Applied", "Deposit Applied". public string Type { get; set; } = string.Empty; public string Reference { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; /// Amount added to the balance (invoice for customer, bill for vendor). public decimal? Debit { get; set; } /// Amount reducing the balance (payment, credit). public decimal? Credit { get; set; } public decimal RunningBalance { get; set; } } // ── AP Aging ────────────────────────────────────────────────────────────────── public class ApAgingReportDto { public DateTime AsOf { get; set; } public string CompanyName { get; set; } = string.Empty; public List Vendors { get; set; } = new(); public decimal TotalCurrent { get; set; } public decimal Total1to30 { get; set; } public decimal Total31to60 { get; set; } public decimal Total61to90 { get; set; } public decimal TotalOver90 { get; set; } public decimal TotalOutstanding => TotalCurrent + Total1to30 + Total31to60 + Total61to90 + TotalOver90; } public class ApAgingVendorDto { public int VendorId { get; set; } public string VendorName { get; set; } = string.Empty; public List Bills { get; set; } = new(); public decimal TotalCurrent { get; set; } public decimal Total1to30 { get; set; } public decimal Total31to60 { get; set; } public decimal Total61to90 { get; set; } public decimal TotalOver90 { get; set; } public decimal TotalBalance => TotalCurrent + Total1to30 + Total31to60 + Total61to90 + TotalOver90; } public class ApAgingBillDto { public int BillId { get; set; } public string BillNumber { get; set; } = string.Empty; public DateTime BillDate { get; set; } public DateTime? DueDate { get; set; } public decimal BalanceDue { get; set; } public int DaysOverdue { get; set; } } // ── Trial Balance ───────────────────────────────────────────────────────────── public class TrialBalanceDto { public DateTime AsOf { get; set; } public string CompanyName { get; set; } = string.Empty; public List Lines { get; set; } = new(); public decimal TotalDebits { get; set; } public decimal TotalCredits { get; set; } public bool IsBalanced => Math.Abs(TotalDebits - TotalCredits) < 0.01m; } public class TrialBalanceLine { public int AccountId { get; set; } public string AccountNumber { get; set; } = string.Empty; public string AccountName { get; set; } = string.Empty; public AccountType AccountType { get; set; } public decimal DebitBalance { get; set; } public decimal CreditBalance { get; set; } } // ── Profit & Loss ───────────────────────────────────────────────────────────── public class ProfitAndLossDto { public DateTime From { get; set; } public DateTime To { get; set; } public string CompanyName { get; set; } = string.Empty; public AccountingMethod AccountingMethod { get; set; } = AccountingMethod.Accrual; public List RevenueLines { get; set; } = new(); public decimal TotalRevenue { get; set; } public List CogsLines { get; set; } = new(); public decimal TotalCogs { get; set; } public decimal GrossProfit => TotalRevenue - TotalCogs; public decimal GrossMarginPercent => TotalRevenue == 0 ? 0 : Math.Round(GrossProfit / TotalRevenue * 100, 1); public List ExpenseLines { get; set; } = new(); public decimal TotalExpenses { get; set; } public decimal OperatingIncome => GrossProfit - TotalExpenses; public decimal NetIncome => OperatingIncome; // Extend later for other income/tax } public class FinancialReportLine { public int AccountId { get; set; } public string AccountNumber { get; set; } = string.Empty; public string AccountName { get; set; } = string.Empty; public decimal Amount { get; set; } } // ── Balance Sheet ───────────────────────────────────────────────────────────── public class BalanceSheetDto { public DateTime AsOf { get; set; } public string CompanyName { get; set; } = string.Empty; public AccountingMethod AccountingMethod { get; set; } = AccountingMethod.Accrual; // Assets public List CurrentAssets { get; set; } = new(); public List FixedAssets { get; set; } = new(); public List OtherAssets { get; set; } = new(); public decimal TotalAssets { get; set; } // Liabilities public List CurrentLiabilities { get; set; } = new(); public List LongTermLiabilities { get; set; } = new(); public decimal TotalLiabilities { get; set; } // Equity public List EquityLines { get; set; } = new(); public decimal RetainedEarnings { get; set; } // Computed net income to date public decimal TotalEquity { get; set; } public decimal TotalLiabilitiesAndEquity => TotalLiabilities + TotalEquity; // Helper: is the sheet balanced? public bool IsBalanced => Math.Abs(TotalAssets - TotalLiabilitiesAndEquity) < 0.01m; } // ── AR Aging ────────────────────────────────────────────────────────────────── public class ArAgingReportDto { public DateTime AsOf { get; set; } public string CompanyName { get; set; } = string.Empty; public List Customers { get; set; } = new(); public decimal TotalCurrent { get; set; } public decimal Total1to30 { get; set; } public decimal Total31to60 { get; set; } public decimal Total61to90 { get; set; } public decimal TotalOver90 { get; set; } public decimal TotalOutstanding => TotalCurrent + Total1to30 + Total31to60 + Total61to90 + TotalOver90; } public class ArAgingCustomerDto { public int CustomerId { get; set; } public string CustomerName { get; set; } = string.Empty; public List Invoices { get; set; } = new(); public decimal TotalCurrent { get; set; } public decimal Total1to30 { get; set; } public decimal Total31to60 { get; set; } public decimal Total61to90 { get; set; } public decimal TotalOver90 { get; set; } public decimal TotalBalance => TotalCurrent + Total1to30 + Total31to60 + Total61to90 + TotalOver90; } public class ArAgingInvoiceDto { public int InvoiceId { get; set; } public string InvoiceNumber { get; set; } = string.Empty; public DateTime InvoiceDate { get; set; } public DateTime? DueDate { get; set; } public decimal BalanceDue { get; set; } public int DaysOverdue { get; set; } } // ── Sales & Income ──────────────────────────────────────────────────────────── public class SalesIncomeReportDto { public DateTime From { get; set; } public DateTime To { get; set; } public string CompanyName { get; set; } = string.Empty; public decimal TotalInvoiced { get; set; } public decimal TotalCollected { get; set; } public decimal TotalTax { get; set; } public decimal TotalDiscount { get; set; } public decimal NetRevenue => TotalInvoiced - TotalDiscount; public int InvoiceCount { get; set; } public int CustomerCount { get; set; } public decimal AverageInvoiceValue => InvoiceCount == 0 ? 0 : Math.Round(TotalInvoiced / InvoiceCount, 2); public List ByCustomer { get; set; } = new(); public List ByMonth { get; set; } = new(); public List Invoices { get; set; } = new(); } public class SalesByCustomerDto { public int CustomerId { get; set; } public string CustomerName { get; set; } = string.Empty; public int InvoiceCount { get; set; } public decimal TotalInvoiced { get; set; } public decimal TotalPaid { get; set; } public decimal BalanceDue { get; set; } } public class SalesByMonthDto { public int Year { get; set; } public int Month { get; set; } public string Label { get; set; } = string.Empty; public decimal TotalInvoiced { get; set; } public decimal TotalCollected { get; set; } public int InvoiceCount { get; set; } } public class SalesInvoiceLineDto { public int InvoiceId { get; set; } public string InvoiceNumber { get; set; } = string.Empty; public string CustomerName { get; set; } = string.Empty; public DateTime InvoiceDate { get; set; } public DateTime? DueDate { get; set; } public string Status { get; set; } = string.Empty; public decimal SubTotal { get; set; } public decimal TaxAmount { get; set; } public decimal Total { get; set; } public decimal AmountPaid { get; set; } public decimal BalanceDue { get; set; } } // ============================================================ // SALES TAX REPORT // ============================================================ public class SalesTaxReportDto { public DateTime From { get; set; } public DateTime To { get; set; } public string CompanyName { get; set; } = string.Empty; /// Subtotal of invoices where TaxAmount > 0. public decimal TotalTaxableSales { get; set; } /// Subtotal of invoices where TaxAmount == 0. public decimal TotalNonTaxableSales { get; set; } /// Sum of all TaxAmount values across the period. public decimal TotalTaxBilled { get; set; } public int TaxableInvoiceCount { get; set; } public int NonTaxableInvoiceCount { get; set; } public decimal EffectiveTaxRate => TotalTaxableSales == 0 ? 0 : Math.Round(TotalTaxBilled / TotalTaxableSales * 100, 2); public List ByAccount { get; set; } = new(); public List ByMonth { get; set; } = new(); public List Invoices { get; set; } = new(); } public class SalesTaxByAccountDto { public int? AccountId { get; set; } public string AccountName { get; set; } = string.Empty; public string AccountNumber { get; set; } = string.Empty; public decimal TaxableSales { get; set; } public decimal TaxBilled { get; set; } public int InvoiceCount { get; set; } } public class SalesTaxByMonthDto { public int Year { get; set; } public int Month { get; set; } public string Label { get; set; } = string.Empty; public decimal TaxableSales { get; set; } public decimal TaxBilled { get; set; } public int InvoiceCount { get; set; } } public class SalesTaxInvoiceLineDto { public int InvoiceId { get; set; } public string InvoiceNumber { get; set; } = string.Empty; public string CustomerName { get; set; } = string.Empty; public DateTime InvoiceDate { get; set; } public string Status { get; set; } = string.Empty; public decimal SubTotal { get; set; } public decimal TaxPercent { get; set; } public decimal TaxAmount { get; set; } public decimal Total { get; set; } public decimal AmountPaid { get; set; } public decimal BalanceDue { get; set; } public string TaxAccountName { get; set; } = string.Empty; }