using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Fitness_core_BE.Models { /// A physical area of the club (e.g. "Pool Area", "Indoor Gym", "Court 1") that can /// both be booked (Booking/FacilitySession below) and fitted with its own fingerprint/face /// terminal for membership-plan access scoping (AccessDevice.FKFacilityId, /// CustomerPlanFacility). Merged from the formerly-separate Facility (bookable capacity) and /// Place (access zone) concepts -- see the booking redesign plan for the migration that /// carried Place's rows over reusing this table's original PlaceId values as FacilityId. public class Facility { [Key] public Guid FacilityId { get; set; } public Guid FKClientId { get; set; } [ForeignKey(nameof(FKClientId))] public Client Client { get; set; } [MaxLength(128)] public string Name { get; set; } = string.Empty; /// Staff pre-creates fixed-time FacilitySessions (classes) that many bookings /// share one capacity pool against. Independent of SupportsBooking -- both can be true, /// e.g. a court that hosts a scheduled class AND accepts ad-hoc walk-in bookings outside /// class hours. public bool SupportsClasses { get; set; } = true; /// A booking can claim one of NumberOfUnits identical units directly for an /// arbitrary time window, no pre-created session needed (courts/pool). At least one of /// SupportsClasses/SupportsBooking must be true. public bool SupportsBooking { get; set; } = false; [MaxLength(500)] public string? Description { get; set; } /// Default per-session headcount limit when SupportsClasses; a specific /// FacilitySession can override. public int DefaultCapacity { get; set; } = 1; /// Number of identical, independently-bookable units when SupportsBooking (e.g. /// 3 for "3 courts") -- availability is this minus overlapping non-cancelled/ /// non-completed WalkIn bookings in the requested window. public int NumberOfUnits { get; set; } = 1; /// Hourly rate used to compute a guest WalkIn booking's suggested AmountCharged /// (PricePerHour * duration-in-hours) at creation time. public decimal PricePerHour { get; set; } = 0m; public bool IsActive { get; set; } = true; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } }