using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Fitness_core_BE.Models { public class CustomerPlan { [Key] public Guid CustomerPlanId { get; set; } public Guid FKClientId { get; set; } [ForeignKey("FKClientId")] public virtual Client Client { get; set; } public string? PlanName { get; set; } public string? PlanDescription { get; set; } public decimal PlanPrice { get; set; } /// Whether this plan charges a one-time fee when a new subscription starts. public bool HasOnboardingFee { get; set; } = false; /// One-time amount added to the first invoice/installment. public decimal OnboardingFeeAmount { get; set; } = 0m; /// Used when DurationMode == "Rolling"; 0 for FixedRange plans. public int DurationInDays { get; set; } /// "Individual" | "Group" (couple/family — one subscription covers MemberLimit members). public string PlanScope { get; set; } = "Individual"; /// 1 for Individual; >= 2 for Group (couple = 2). public int MemberLimit { get; set; } = 1; /// "Rolling" (DurationInDays from join date) | "FixedRange" (ValidFrom–ValidTo). public string DurationMode { get; set; } = "Rolling"; public DateTime? ValidFrom { get; set; } public DateTime? ValidTo { get; set; } /// Owner decides: when true the price splits into InstallmentCount scheduled parts. public bool AllowSplitPayments { get; set; } = false; /// Number of mostly-equal installments (1 = full payment upfront). public int InstallmentCount { get; set; } = 1; /// Null = unlimited-access plan (existing gym behavior). A number = this plan /// grants that many bookable Facility sessions per billing cycle (e.g. "4 pool sessions /// a month") — enforced by the booking flow, not by this model. public int? SessionsPerCycle { get; set; } /// "NoRollover" (unused sessions are forfeited when the cycle renews) | /// "GracePeriod" (unused sessions stay usable for RolloverGraceDays after renewal). /// Set per package at creation time, per owner's requirement. public string SessionRolloverPolicy { get; set; } = "NoRollover"; /// Days into the new cycle that last cycle's unused sessions remain usable. /// Only meaningful when SessionRolloverPolicy == "GracePeriod". public int RolloverGraceDays { get; set; } = 0; /// "Prepaid" (pay before the cycle starts, existing behavior) | "Postpaid" /// (use first, invoice at cycle end — reuses Client.LockAfterDaysOverdue / /// OverdueLockJob to suspend access if that invoice goes unpaid past due). Asked once, /// per package, at creation time per owner's requirement. public string BillingTiming { get; set; } = "Prepaid"; public bool IsActive { get; set; } = true; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } }