Initial commit
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
using PowderCoating.Core.Enums;
|
||||
|
||||
namespace PowderCoating.Core.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// Chart of Accounts entry. Supports a flat or one-level hierarchy via ParentAccountId.
|
||||
/// </summary>
|
||||
public class Account : BaseEntity
|
||||
{
|
||||
public string AccountNumber { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public AccountType AccountType { get; set; }
|
||||
public AccountSubType AccountSubType { get; set; }
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>Nullable FK for sub-accounts (one level deep).</summary>
|
||||
public int? ParentAccountId { get; set; }
|
||||
|
||||
/// <summary>System accounts cannot be deleted (seeded defaults).</summary>
|
||||
public bool IsSystem { get; set; } = false;
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
/// <summary>Starting balance when the account was first set up in this system.</summary>
|
||||
public decimal OpeningBalance { get; set; } = 0;
|
||||
/// <summary>The date the opening balance is as-of. Null means it pre-dates all transactions.</summary>
|
||||
public DateTime? OpeningBalanceDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Denormalized running balance kept in sync with each transaction. Positive = normal-balance direction
|
||||
/// (debit-normal for Assets/Expenses/COGS; credit-normal for Liabilities/Equity/Revenue).
|
||||
/// Use AccountsController.RecalculateBalances to rebuild from scratch if needed.
|
||||
/// </summary>
|
||||
public decimal CurrentBalance { get; set; } = 0;
|
||||
|
||||
// Navigation
|
||||
public virtual Account? ParentAccount { get; set; }
|
||||
public virtual ICollection<Account> SubAccounts { get; set; } = new List<Account>();
|
||||
public virtual ICollection<BillLineItem> BillLineItems { get; set; } = new List<BillLineItem>();
|
||||
public virtual ICollection<Bill> Bills { get; set; } = new List<Bill>();
|
||||
public virtual ICollection<BillPayment> BillPayments { get; set; } = new List<BillPayment>();
|
||||
public virtual ICollection<Expense> Expenses { get; set; } = new List<Expense>();
|
||||
public virtual ICollection<Expense> ExpensePaymentAccounts { get; set; } = new List<Expense>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vendor bill (accounts payable). Represents money owed to a supplier.
|
||||
/// </summary>
|
||||
public class Bill : BaseEntity
|
||||
{
|
||||
public string BillNumber { get; set; } = string.Empty;
|
||||
/// <summary>Vendor's own invoice/reference number.</summary>
|
||||
public string? VendorInvoiceNumber { get; set; }
|
||||
|
||||
public int VendorId { get; set; }
|
||||
/// <summary>Which AP account this bill posts to (default: Accounts Payable 2000).</summary>
|
||||
public int APAccountId { get; set; }
|
||||
|
||||
public DateTime BillDate { get; set; } = DateTime.UtcNow;
|
||||
public DateTime? DueDate { get; set; }
|
||||
|
||||
public BillStatus Status { get; set; } = BillStatus.Draft;
|
||||
public string? Terms { get; set; }
|
||||
public string? Memo { get; set; }
|
||||
|
||||
// Financials
|
||||
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; }
|
||||
[System.ComponentModel.DataAnnotations.Schema.NotMapped]
|
||||
public decimal BalanceDue => Total - AmountPaid;
|
||||
|
||||
/// <summary>Blob path to an attached receipt/invoice document (PDF or image).</summary>
|
||||
public string? ReceiptFilePath { get; set; }
|
||||
|
||||
// Navigation
|
||||
public virtual Vendor Vendor { get; set; } = null!;
|
||||
public virtual Account APAccount { get; set; } = null!;
|
||||
public virtual ICollection<BillLineItem> LineItems { get; set; } = new List<BillLineItem>();
|
||||
public virtual ICollection<BillPayment> Payments { get; set; } = new List<BillPayment>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single line on a vendor bill, posted to an expense or asset account.
|
||||
/// </summary>
|
||||
public class BillLineItem : BaseEntity
|
||||
{
|
||||
public int BillId { get; set; }
|
||||
/// <summary>Expense/asset account this line item is categorized under. Nullable for QB-imported bills where account is unknown.</summary>
|
||||
public int? AccountId { get; set; }
|
||||
/// <summary>Optional job costing link.</summary>
|
||||
public int? JobId { get; set; }
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public decimal Quantity { get; set; } = 1;
|
||||
public decimal UnitPrice { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public int DisplayOrder { get; set; }
|
||||
|
||||
// Navigation
|
||||
public virtual Bill Bill { get; set; } = null!;
|
||||
public virtual Account? Account { get; set; }
|
||||
public virtual Job? Job { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A payment made against a vendor bill.
|
||||
/// </summary>
|
||||
public class BillPayment : BaseEntity
|
||||
{
|
||||
public string PaymentNumber { get; set; } = string.Empty;
|
||||
public int BillId { get; set; }
|
||||
/// <summary>Denormalized for AP reporting without joining through Bill.</summary>
|
||||
public int VendorId { get; set; }
|
||||
/// <summary>Bank/cash account the payment came out of.</summary>
|
||||
public int BankAccountId { get; set; }
|
||||
|
||||
public DateTime PaymentDate { get; set; } = DateTime.UtcNow;
|
||||
public decimal Amount { get; set; }
|
||||
public PaymentMethod PaymentMethod { get; set; }
|
||||
public string? CheckNumber { get; set; }
|
||||
public string? Memo { get; set; }
|
||||
|
||||
// Navigation
|
||||
public virtual Bill Bill { get; set; } = null!;
|
||||
public virtual Vendor Vendor { get; set; } = null!;
|
||||
public virtual Account BankAccount { get; set; } = null!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A direct expense paid immediately (not via a bill). Covers cash/card purchases.
|
||||
/// </summary>
|
||||
public class Expense : BaseEntity
|
||||
{
|
||||
public string ExpenseNumber { get; set; } = string.Empty;
|
||||
public DateTime Date { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>Optional vendor the expense was paid to.</summary>
|
||||
public int? VendorId { get; set; }
|
||||
/// <summary>Expense category account (e.g. 6200 Powder & Materials).</summary>
|
||||
public int ExpenseAccountId { get; set; }
|
||||
/// <summary>Account money came out of (e.g. 1000 Checking, 2100 Credit Card).</summary>
|
||||
public int PaymentAccountId { get; set; }
|
||||
/// <summary>Optional job costing link.</summary>
|
||||
public int? JobId { get; set; }
|
||||
|
||||
public PaymentMethod PaymentMethod { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Memo { get; set; }
|
||||
public string? ReceiptFilePath { get; set; }
|
||||
|
||||
// Navigation
|
||||
public virtual Vendor? Vendor { get; set; }
|
||||
public virtual Account ExpenseAccount { get; set; } = null!;
|
||||
public virtual Account PaymentAccount { get; set; } = null!;
|
||||
public virtual Job? Job { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user