using PowderCoating.Core.Enums; namespace PowderCoating.Core.Entities; public class Quote : BaseEntity { public string QuoteNumber { get; set; } = string.Empty; public int? CustomerId { get; set; } // Nullable to support quotes for prospects public string? PreparedById { get; set; } // Changed from int? to string? for Identity FK // Prospect Contact Information (used when CustomerId is null) public string? ProspectCompanyName { get; set; } public string? ProspectContactName { get; set; } public string? ProspectEmail { get; set; } public string? ProspectPhone { get; set; } public string? ProspectAddress { get; set; } public string? ProspectCity { get; set; } public string? ProspectState { get; set; } public string? ProspectZipCode { get; set; } // TCPA compliance: only true when staff explicitly records verbal SMS consent public bool ProspectSmsConsent { get; set; } = false; public DateTime? ProspectSmsConsentedAt { get; set; } // Lookup foreign key (replacing enum) public int QuoteStatusId { get; set; } // Selected oven for this quote (null = use company default rate) public int? OvenCostId { get; set; } // Oven batch pricing public int OvenBatches { get; set; } = 1; public int? OvenCycleMinutes { get; set; } // null = use company DefaultOvenCycleMinutes public bool IsCommercial { get; set; } public bool IsRushJob { get; set; } = false; // Dates public DateTime QuoteDate { get; set; } = DateTime.UtcNow; public DateTime? ExpirationDate { get; set; } public DateTime? SentDate { get; set; } public DateTime? ApprovedDate { get; set; } // Pricing — all values are snapshots captured at save time and must not be recalculated on load public decimal MaterialCosts { get; set; } // Sum of powder/material costs across all items public decimal LaborCosts { get; set; } // Sum of labor costs across all items public decimal EquipmentCosts { get; set; } // Sum of equipment costs across all items public decimal ItemsSubtotal { get; set; } // Sum of item prices before any quote-level costs public decimal OvenBatchCost { get; set; } // Oven batch charge applied at quote level public decimal ShopSuppliesAmount { get; set; } // Shop supplies dollar amount public decimal ShopSuppliesPercent { get; set; } // Shop supplies percentage used public decimal OverheadAmount { get; set; } // Overhead dollar amount public decimal OverheadPercent { get; set; } // Overhead percentage used public decimal ProfitMargin { get; set; } // Profit margin dollar amount public decimal ProfitPercent { get; set; } // Profit margin percentage used public decimal SubTotal { get; set; } // SubtotalBeforeDiscount (items + oven + overhead + profit + shop supplies) // Discount Information public DiscountType DiscountType { get; set; } = DiscountType.None; public decimal DiscountValue { get; set; } = 0; // Value entered by user (percentage or fixed amount) public decimal DiscountPercent { get; set; } // Calculated: actual percentage applied public decimal DiscountAmount { get; set; } // Calculated: actual dollar amount deducted public string? DiscountReason { get; set; } // Why discount was applied public bool HideDiscountFromCustomer { get; set; } = false; // Show only total on PDFs/portal public decimal TaxPercent { get; set; } public decimal TaxAmount { get; set; } public decimal RushFee { get; set; } = 0; public decimal Total { get; set; } // Deposit — require deposit payment before work begins public bool RequiresDeposit { get; set; } = false; public decimal DepositPercent { get; set; } = 0; // e.g. 50 = 50% deposit required // Online deposit payment (Stripe Connect) public string? DepositPaymentLinkToken { get; set; } public DateTime? DepositPaymentLinkExpiresAt { get; set; } public decimal DepositAmountPaid { get; set; } = 0; public string? DepositPaymentIntentId { get; set; } // Additional Information public string? Description { get; set; } public string? Terms { get; set; } public string? Notes { get; set; } public string? CustomerPO { get; set; } public string? Tags { get; set; } // Conversion tracking public int? ConvertedToJobId { get; set; } public DateTime? ConvertedDate { get; set; } // Customer self-service approval public string? ApprovalToken { get; set; } public DateTime? ApprovalTokenExpiresAt { get; set; } public DateTime? ApprovalTokenUsedAt { get; set; } public string? DeclineReason { get; set; } public string? DeclinedByIp { get; set; } // Relationships public virtual OvenCost? OvenCost { get; set; } public virtual Customer? Customer { get; set; } public virtual ApplicationUser? PreparedBy { get; set; } public virtual QuoteStatusLookup QuoteStatus { get; set; } = null!; public virtual ICollection QuoteItems { get; set; } = new List(); public virtual ICollection QuotePrepServices { get; set; } = new List(); public virtual Job? ConvertedToJob { get; set; } public virtual ICollection QuotePhotos { get; set; } = new List(); }