9367e358d9
Stores ProjectName on the Invoice entity (previously only inherited from the linked job at display time). Pre-fills from the job when creating from a job. Migration: AddInvoiceProjectName. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
4.2 KiB
C#
89 lines
4.2 KiB
C#
using PowderCoating.Core.Enums;
|
|
|
|
namespace PowderCoating.Core.Entities;
|
|
|
|
public class Invoice : BaseEntity
|
|
{
|
|
public string InvoiceNumber { get; set; } = string.Empty;
|
|
public int? JobId { get; set; }
|
|
public int CustomerId { get; set; }
|
|
public string? PreparedById { get; set; }
|
|
|
|
public InvoiceStatus Status { get; set; } = InvoiceStatus.Draft;
|
|
|
|
// Dates
|
|
public DateTime InvoiceDate { get; set; } = DateTime.UtcNow;
|
|
public DateTime? DueDate { get; set; }
|
|
public DateTime? SentDate { get; set; }
|
|
public DateTime? PaidDate { get; set; }
|
|
|
|
// Financials
|
|
public decimal SubTotal { get; set; }
|
|
public decimal TaxPercent { get; set; }
|
|
public decimal TaxAmount { get; set; }
|
|
public decimal DiscountAmount { get; set; }
|
|
public decimal Total { get; set; }
|
|
public decimal AmountPaid { get; set; }
|
|
public decimal CreditApplied { get; set; } // Sum of credit memo applications
|
|
public decimal GiftCertificateRedeemed { get; set; } // Sum of gift certificate redemptions
|
|
public decimal BalanceDue => Total - AmountPaid - CreditApplied - GiftCertificateRedeemed;
|
|
|
|
/// <summary>
|
|
/// Permanent public token for the customer-facing invoice view page (/invoice/{token}).
|
|
/// Generated when the invoice is first sent (regardless of Stripe status) and never expires.
|
|
/// Distinct from PaymentLinkToken which is Stripe-gated and expires in 5 days.
|
|
/// </summary>
|
|
public string? PublicViewToken { get; set; }
|
|
|
|
// Online payments (Stripe Connect)
|
|
public OnlinePaymentStatus OnlinePaymentStatus { get; set; } = OnlinePaymentStatus.NotApplicable;
|
|
public string? PaymentLinkToken { get; set; } // Signed token for /pay/{token}
|
|
public DateTime? PaymentLinkExpiresAt { get; set; } // 5 days from generation
|
|
public string? StripePaymentIntentId { get; set; } // Most recent PaymentIntent ID
|
|
public decimal OnlineAmountPaid { get; set; } = 0; // Running total of online payments received
|
|
public decimal OnlineSurchargeCollected { get; set; } = 0; // Surcharge amount collected (for records)
|
|
|
|
// Text
|
|
public string? Notes { get; set; }
|
|
public string? InternalNotes { get; set; }
|
|
public string? Terms { get; set; }
|
|
public string? CustomerPO { get; set; }
|
|
public string? ProjectName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Early payment discount percentage (e.g., 2 means 2% discount).
|
|
/// Parsed from the customer's payment terms when the invoice is created (e.g., "2/10 Net 30").
|
|
/// Informational only — does not automatically reduce the amount due.
|
|
/// </summary>
|
|
public decimal EarlyPaymentDiscountPercent { get; set; }
|
|
|
|
/// <summary>
|
|
/// Number of days after invoice date within which the early payment discount applies.
|
|
/// Parsed from the customer's payment terms (e.g., "2/10 Net 30" → 10 days).
|
|
/// </summary>
|
|
public int EarlyPaymentDiscountDays { get; set; }
|
|
|
|
/// <summary>
|
|
/// Original invoice number from an external system (e.g. QuickBooks invoice # "3048").
|
|
/// Stored for searchability and traceability after import. Searchable from the invoice list.
|
|
/// </summary>
|
|
public string? ExternalReference { get; set; }
|
|
|
|
/// <summary>
|
|
/// Liability account where collected sales tax is tracked (e.g., 2200 Sales Tax Payable).
|
|
/// Populated automatically when TaxAmount > 0.
|
|
/// </summary>
|
|
public int? SalesTaxAccountId { get; set; }
|
|
|
|
// Navigation
|
|
public virtual Job? Job { get; set; }
|
|
public virtual Customer Customer { get; set; } = null!;
|
|
public virtual ApplicationUser? PreparedBy { get; set; }
|
|
public virtual Account? SalesTaxAccount { get; set; }
|
|
public virtual ICollection<InvoiceItem> InvoiceItems { get; set; } = new List<InvoiceItem>();
|
|
public virtual ICollection<Payment> Payments { get; set; } = new List<Payment>();
|
|
public virtual ICollection<Refund> Refunds { get; set; } = new List<Refund>();
|
|
public virtual ICollection<CreditMemoApplication> CreditApplications { get; set; } = new List<CreditMemoApplication>();
|
|
public virtual ICollection<GiftCertificateRedemption> GiftCertificateRedemptions { get; set; } = new List<GiftCertificateRedemption>();
|
|
}
|