68 lines
3.2 KiB
C#
68 lines
3.2 KiB
C#
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; }
|
||
|
||
/// <summary>Whether this plan charges a one-time fee when a new subscription starts.</summary>
|
||
public bool HasOnboardingFee { get; set; } = false;
|
||
|
||
/// <summary>One-time amount added to the first invoice/installment.</summary>
|
||
public decimal OnboardingFeeAmount { get; set; } = 0m;
|
||
|
||
/// <summary>Used when DurationMode == "Rolling"; 0 for FixedRange plans.</summary>
|
||
public int DurationInDays { get; set; }
|
||
|
||
/// <summary>"Individual" | "Group" (couple/family — one subscription covers MemberLimit members).</summary>
|
||
public string PlanScope { get; set; } = "Individual";
|
||
|
||
/// <summary>1 for Individual; >= 2 for Group (couple = 2).</summary>
|
||
public int MemberLimit { get; set; } = 1;
|
||
|
||
/// <summary>"Rolling" (DurationInDays from join date) | "FixedRange" (ValidFrom–ValidTo).</summary>
|
||
public string DurationMode { get; set; } = "Rolling";
|
||
|
||
public DateTime? ValidFrom { get; set; }
|
||
public DateTime? ValidTo { get; set; }
|
||
|
||
/// <summary>Owner decides: when true the price splits into InstallmentCount scheduled parts.</summary>
|
||
public bool AllowSplitPayments { get; set; } = false;
|
||
|
||
/// <summary>Number of mostly-equal installments (1 = full payment upfront).</summary>
|
||
public int InstallmentCount { get; set; } = 1;
|
||
|
||
/// <summary>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.</summary>
|
||
public int? SessionsPerCycle { get; set; }
|
||
|
||
/// <summary>"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.</summary>
|
||
public string SessionRolloverPolicy { get; set; } = "NoRollover";
|
||
|
||
/// <summary>Days into the new cycle that last cycle's unused sessions remain usable.
|
||
/// Only meaningful when SessionRolloverPolicy == "GracePeriod".</summary>
|
||
public int RolloverGraceDays { get; set; } = 0;
|
||
|
||
/// <summary>"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.</summary>
|
||
public string BillingTiming { get; set; } = "Prepaid";
|
||
|
||
public bool IsActive { get; set; } = true;
|
||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||
}
|
||
}
|