59 lines
2.7 KiB
C#
59 lines
2.7 KiB
C#
using System.ComponentModel.DataAnnotations;
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
|
|
namespace Fitness_core_BE.Models
|
|
{
|
|
/// <summary>A prepaid time balance on an RFID card, deducted by actual use via a tap-in/
|
|
/// tap-out swipe pattern (a 1-hour visit deducts 60 minutes, a 15-minute visit deducts 15 --
|
|
/// see ActiveSessionStartedAt) — separate from Booking's per-session OTP flow. Can belong to
|
|
/// a member (FKCustomerId set, e.g. an add-on to their plan) or be sold standalone to a
|
|
/// walk-in against just the RFID tag.</summary>
|
|
public class TimeBankCard
|
|
{
|
|
[Key]
|
|
public Guid TimeBankCardId { get; set; }
|
|
|
|
public Guid FKClientId { get; set; }
|
|
[ForeignKey(nameof(FKClientId))]
|
|
public Client Client { get; set; }
|
|
|
|
// Tenant-bucket entity: holds a TenantCustomerLinkId, not the central Customer.CusId
|
|
// directly -- see Models/TenantCustomerLink.cs. Null for a card sold to a walk-in with
|
|
// no membership at all.
|
|
public Guid? FKCustomerId { get; set; }
|
|
[ForeignKey(nameof(FKCustomerId))]
|
|
public TenantCustomerLink? TenantCustomerLink { get; set; }
|
|
|
|
[MaxLength(64)]
|
|
public string RfidTagId { get; set; } = string.Empty;
|
|
|
|
public int TotalMinutesPurchased { get; set; }
|
|
public int MinutesRemaining { get; set; }
|
|
|
|
public decimal AmountPaid { get; set; } = 0m;
|
|
public Guid? FKPaymentTransactionId { get; set; }
|
|
[ForeignKey(nameof(FKPaymentTransactionId))]
|
|
public PaymentTransaction? PaymentTransaction { get; set; }
|
|
|
|
public DateTime PurchasedAt { get; set; } = DateTime.UtcNow;
|
|
|
|
/// <summary>Null = balance never expires (spend it whenever); business can still set one.</summary>
|
|
public DateTime? ExpiresAt { get; set; }
|
|
|
|
public bool IsActive { get; set; } = true;
|
|
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
|
|
|
// Tap-in/tap-out state: null = not currently on the floor anywhere. A swipe with this
|
|
// null starts a session (tap-in, no deduction yet); a swipe with this set ends it
|
|
// (tap-out) and deducts the elapsed minutes. One open session per card at a time --
|
|
// a second tap-in without a matching tap-out first is rejected by the service, not
|
|
// silently overwritten, so a lost/forgotten tap-out surfaces instead of losing time.
|
|
public DateTime? ActiveSessionStartedAt { get; set; }
|
|
public Guid? ActiveSessionFacilityId { get; set; }
|
|
[ForeignKey(nameof(ActiveSessionFacilityId))]
|
|
public Facility? ActiveSessionFacility { get; set; }
|
|
|
|
public virtual ICollection<TimeBankCardUsageLog> UsageLogs { get; set; }
|
|
}
|
|
}
|