using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Fitness_core_BE.Models { /// Stock going out to a customer. Creating one decrements each line's /// Product.QuantityOnHand -- the whole sale is rejected up front if any line would go /// negative (no backorders). public class Sale { [Key] public Guid SaleId { get; set; } public Guid FKClientId { get; set; } [ForeignKey(nameof(FKClientId))] public Client Client { get; set; } [MaxLength(32)] public string SaleNumber { get; set; } = string.Empty; public DateTime SoldAt { get; set; } = DateTime.UtcNow; /// "Cash" | "Bank" -- same convention as Booking.PaymentMethod. [MaxLength(20)] public string PaymentMethod { get; set; } = "Cash"; /// Optional link to a registered member, purely for identification -- mirrors /// Booking.FKCustomerId (see BookingService.ResolveOptionalCustomerLinkAsync). A walk-in /// buyer leaves this null and uses CustomerName instead. public Guid? FKCustomerId { get; set; } [MaxLength(128)] public string? CustomerName { get; set; } public decimal TotalAmount { get; set; } = 0m; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public virtual ICollection Items { get; set; } = new List(); } public class SaleItem { [Key] public Guid SaleItemId { get; set; } public Guid FKSaleId { get; set; } [ForeignKey(nameof(FKSaleId))] public Sale? Sale { get; set; } public Guid FKProductId { get; set; } [ForeignKey(nameof(FKProductId))] public Product? Product { get; set; } public decimal Quantity { get; set; } public decimal UnitPrice { get; set; } public decimal LineTotal { get; set; } } }