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;
}