first commit
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.AccessDevice
|
||||
{
|
||||
public class UnlinkedFingerprintDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public int DeviceUserId { get; set; }
|
||||
public string DeviceEmployeeNo { get; set; } = string.Empty;
|
||||
public string? DeviceReportedName { get; set; }
|
||||
public string? DeviceUserType { get; set; }
|
||||
public int FingerprintCount { get; set; }
|
||||
public Guid DeviceId { get; set; }
|
||||
public string? DeviceName { get; set; }
|
||||
public DateTime DiscoveredAt { get; set; }
|
||||
}
|
||||
|
||||
public class LinkFingerprintRequest
|
||||
{
|
||||
public Guid UnlinkedEnrollmentId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Body of POST client/customers/{id}/face-photo. The browser resizes and re-encodes to
|
||||
/// JPEG before sending, so this carries a ready-to-enrol image; a data: prefix is accepted.
|
||||
/// </summary>
|
||||
public class SetFacePhotoRequest
|
||||
{
|
||||
[Required]
|
||||
public string ImageBase64 { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AccessStatusDto
|
||||
{
|
||||
public long AccessProfileId { get; set; }
|
||||
public string AccessNumber { get; set; } = string.Empty;
|
||||
public string PersonType { get; set; } = string.Empty;
|
||||
public string DesiredAccessState { get; set; } = string.Empty;
|
||||
public string ProvisionStatus { get; set; } = "NoDevice";
|
||||
public string ActualAccessState { get; set; } = "Unknown";
|
||||
public int FingerprintCount { get; set; }
|
||||
public string? LastError { get; set; }
|
||||
public DateTime? LastSyncedAt { get; set; }
|
||||
public int DeviceCount { get; set; }
|
||||
public int SyncedDeviceCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
namespace Fitness_core_BE.DTOs.Agent
|
||||
{
|
||||
// POST /api/agent/enroll (bootstrap, no api-key auth)
|
||||
public class EnrollRequest
|
||||
{
|
||||
public string Code { get; set; }
|
||||
public string AgentName { get; set; }
|
||||
}
|
||||
|
||||
// POST /api/agent/devices
|
||||
public class RegisterDeviceRequest
|
||||
{
|
||||
public string DeviceName { get; set; }
|
||||
public Guid? DeviceId { get; set; }
|
||||
public string? HardwareId { get; set; }
|
||||
}
|
||||
|
||||
// POST /api/agent/attendance
|
||||
public class AgentAttendanceRequest
|
||||
{
|
||||
public Guid DeviceId { get; set; }
|
||||
public List<AgentAttendanceEvent> Events { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AgentAttendanceEvent
|
||||
{
|
||||
public string EmployeeNoString { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public string AttendanceStatus { get; set; }
|
||||
}
|
||||
|
||||
// POST /api/agent/commands/{id}/result
|
||||
public class CommandResultRequest
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string? ResultJson { get; set; }
|
||||
}
|
||||
|
||||
// Full person inventory contains metadata only. Fingerprint template bytes stay
|
||||
// on the terminal and are never uploaded to the cloud.
|
||||
public class DeviceInventoryRequest
|
||||
{
|
||||
public Guid DeviceId { get; set; }
|
||||
public List<DeviceInventoryPerson> People { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DeviceInventoryPerson
|
||||
{
|
||||
public string EmployeeNo { get; set; } = string.Empty;
|
||||
public string? Name { get; set; }
|
||||
public string? UserType { get; set; }
|
||||
public int FingerprintCount { get; set; }
|
||||
}
|
||||
|
||||
// POST /api/agent/heartbeat. Device reachability is measured on the LAN by
|
||||
// the agent; the cloud never attempts to connect to a private terminal.
|
||||
public class AgentHeartbeatRequest
|
||||
{
|
||||
public List<AgentDeviceHealthReport> Devices { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AgentDeviceHealthReport
|
||||
{
|
||||
public Guid DeviceId { get; set; }
|
||||
public bool IsOnline { get; set; }
|
||||
}
|
||||
|
||||
// POST /api/agent/time-bank-cards/redeem -- an RFID-reader-equipped agent station
|
||||
// reporting a card swipe (tap-in or tap-out, see TimeBankCardService.Swipe). FacilityId is
|
||||
// the reader's own fixed station, not something read off the card.
|
||||
public class AgentSwipeTimeBankCardRequest
|
||||
{
|
||||
public string RfidTagId { get; set; } = string.Empty;
|
||||
public Guid FacilityId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Fitness_core_BE.DTOs.Attendance
|
||||
{
|
||||
public class AttendanceCountDTO
|
||||
{
|
||||
public Guid CustomerId { get; set; }
|
||||
public string? CustomerName { get; set; }
|
||||
public int AttendanceCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Fitness_core_BE.DTOs
|
||||
{
|
||||
public class AttendanceDTO
|
||||
{
|
||||
public Guid DeviceId { get; set; }
|
||||
public Guid? CustomerId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public long AccessProfileId { get; set; }
|
||||
public int DeviceUserId { get; set; }
|
||||
public string DeviceEmployeeNo { get; set; } = string.Empty;
|
||||
public DateTime EventTime { get; set; }
|
||||
public string EventType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Fitness_core_BE.DTOs.Attendance
|
||||
{
|
||||
public class TodayAttendanceDTO
|
||||
{
|
||||
public string? CustomerName { get; set; }
|
||||
public DateTime EventTime { get; set; }
|
||||
public string? EventType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Fitness_core_BE.DTOs.Auth
|
||||
{
|
||||
public class AuthResponse
|
||||
{
|
||||
public int StatusCode { get; set; }
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public object? Data { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace Fitness_core_BE.DTOs.Booking
|
||||
{
|
||||
public class BookingDto
|
||||
{
|
||||
public Guid BookingId { get; set; }
|
||||
public Guid FacilitySessionId { get; set; }
|
||||
public string? FacilityName { get; set; }
|
||||
public DateTime? SessionStartTime { get; set; }
|
||||
public DateTime? SessionEndTime { get; set; }
|
||||
|
||||
public bool IsGuest { get; set; }
|
||||
public Guid? CustomerId { get; set; }
|
||||
public string? GuestName { get; set; }
|
||||
public string? GuestPhone { get; set; }
|
||||
|
||||
/// <summary>Only populated in the response right after booking creation -- the
|
||||
/// guest's receipt. Never returned by list/lookup endpoints afterward.</summary>
|
||||
public string? OtpCode { get; set; }
|
||||
public bool OtpVerified { get; set; }
|
||||
|
||||
public string PaymentStatus { get; set; } = string.Empty;
|
||||
public decimal AmountCharged { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime BookedAt { get; set; }
|
||||
public DateTime? CheckedInAt { get; set; }
|
||||
|
||||
/// <summary>A public, unauthenticated link to this booking's confirmation page --
|
||||
/// copy-paste-and-share receipt. Works for both member and guest bookings.</summary>
|
||||
public string? ShareUrl { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Booking
|
||||
{
|
||||
public class CreateMemberBookingRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid FacilitySessionId { get; set; }
|
||||
}
|
||||
|
||||
public class CreateGuestBookingRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid FacilitySessionId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string GuestName { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public string GuestPhone { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class MarkGuestBookingPaidRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid BookingId { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(0.01, double.MaxValue, ErrorMessage = "AmountCharged must be greater than zero")]
|
||||
public decimal AmountCharged { get; set; }
|
||||
}
|
||||
|
||||
public class CheckInBookingRequest
|
||||
{
|
||||
[Required]
|
||||
public string OtpCode { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class CancelBookingRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid BookingId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Fitness_core_BE.DTOs.ClientInvoice
|
||||
{
|
||||
public class ClientInvoiceDto
|
||||
{
|
||||
public Guid ClientInvoiceId { get; set; }
|
||||
public Guid SubscriptionId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public string? UserEmail { get; set; }
|
||||
public string? PackageName { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime ClientInvoiceDate { get; set; }
|
||||
public List<ClientInvoiceItemDto> Items { get; set; } = new List<ClientInvoiceItemDto>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Fitness_core_BE.DTOs.ClientInvoice
|
||||
{
|
||||
public class ClientInvoiceItemDto
|
||||
{
|
||||
public Guid ClientInvoiceItemId { get; set; }
|
||||
public string? ItemName { get; set; }
|
||||
public string? ItemDescription { get; set; }
|
||||
public decimal ItemPrice { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Fitness_core_BE.DTOs.ClientInvoice
|
||||
{
|
||||
public class CreateClientInvoiceRequest
|
||||
{
|
||||
public Guid SubscriptionId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Fitness_core_BE.DTOs.ClientInvoice
|
||||
{
|
||||
public class UpdateClientInvoiceStatusRequest
|
||||
{
|
||||
public Guid ClientInvoiceId { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Fitness_core_BE.DTOs.Customer
|
||||
{
|
||||
public class CreateCustomerRequest
|
||||
{
|
||||
// Customer details
|
||||
public string CusName { get; set; } = string.Empty;
|
||||
|
||||
// User details
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string PhoneNumber { get; set; } = string.Empty;
|
||||
public bool IsActive { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Fitness_core_BE.DTOs.Customer
|
||||
{
|
||||
public class CustomerDto
|
||||
{
|
||||
public Guid CusId { get; set; }
|
||||
public string CusName { get; set; } = string.Empty;
|
||||
public Guid FKUserId { get; set; }
|
||||
public string? UserName { get; set; }
|
||||
public string? UserEmail { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace Fitness_core_BE.DTOs.Customer
|
||||
{
|
||||
public record FollowedPlanDto(Guid PlanId, string? Name, bool IsFollowing, DateTime? CompletedDate);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
using Fitness_core_BE.Models;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Customer
|
||||
{
|
||||
/// <summary>
|
||||
/// One row per gym member for GET api/client/customers. Deliberate superset of
|
||||
/// the previous CustomerSubscription row shape so the frontend change is additive:
|
||||
/// group members each get their own row pointing at the shared subscription.
|
||||
/// </summary>
|
||||
public class MemberListRowDto
|
||||
{
|
||||
public Guid SubscriptionId { get; set; }
|
||||
public Guid FKCustomerPlanId { get; set; }
|
||||
public Guid FKCustomerId { get; set; }
|
||||
public DateTime OnboardDate { get; set; }
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
public DateTime? RenewalDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public Models.Customer? Customer { get; set; }
|
||||
|
||||
public bool IsPrimary { get; set; }
|
||||
/// <summary>False when the member has been unassigned from their plan but is still a member of the gym.</summary>
|
||||
public bool IsPlanAssigned { get; set; } = true;
|
||||
public string? PlanName { get; set; }
|
||||
public string PlanScope { get; set; } = "Individual";
|
||||
public int MemberCount { get; set; } = 1;
|
||||
public int MemberLimit { get; set; } = 1;
|
||||
public decimal InvoiceAmount { get; set; }
|
||||
public decimal PaidAmount { get; set; }
|
||||
public decimal Balance { get; set; }
|
||||
public string PaymentStatus { get; set; } = "Pending";
|
||||
public bool AllowSplitPayments { get; set; }
|
||||
|
||||
// Linked fingerprint/device-access enrollment, if any (name may be null when the
|
||||
// device didn't report one at enrollment time).
|
||||
public int? FingerprintId { get; set; }
|
||||
public string? FingerprintName { get; set; }
|
||||
public long? AccessProfileId { get; set; }
|
||||
public string? AccessNumber { get; set; }
|
||||
public string AccessProvisionStatus { get; set; } = "NotConfigured";
|
||||
public string ActualAccessState { get; set; } = "Unknown";
|
||||
public string DesiredAccessState { get; set; } = "Enabled";
|
||||
public int FingerprintCount { get; set; }
|
||||
public string? AccessLastError { get; set; }
|
||||
|
||||
public bool IsLocked { get; set; }
|
||||
public string? LockReason { get; set; }
|
||||
|
||||
/// <summary>Face-photo enrolment on the gym's access terminals.</summary>
|
||||
public bool HasFacePhoto { get; set; }
|
||||
/// <summary>"None" | "Pending" | "Synced" | "Failed".</summary>
|
||||
public string FacePhotoStatus { get; set; } = "None";
|
||||
public string? FacePhotoError { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Fitness_core_BE.DTOs.Customer
|
||||
{
|
||||
public class UpdateCustomerRequest
|
||||
{
|
||||
// Customer details
|
||||
public string? CusName { get; set; }
|
||||
|
||||
// User details
|
||||
public string? UserName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Fitness_core_BE.DTOs.CustomerInvoice
|
||||
{
|
||||
public class CreateCustomerInvoiceRequest
|
||||
{
|
||||
public Guid SubscriptionId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Fitness_core_BE.DTOs.CustomerInvoice
|
||||
{
|
||||
public class CustomerInvoiceDto
|
||||
{
|
||||
public Guid CustomerInvoiceId { get; set; }
|
||||
public Guid SubscriptionId { get; set; }
|
||||
public Guid FKClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public string? CustomerName { get; set; }
|
||||
public string? UserEmail { get; set; }
|
||||
public string? PackageName { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime CustomerInvoiceDate { get; set; }
|
||||
public List<CustomerInvoiceItemDto> Items { get; set; } = new List<CustomerInvoiceItemDto>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Fitness_core_BE.DTOs.CustomerInvoice
|
||||
{
|
||||
public class CustomerInvoiceItemDto
|
||||
{
|
||||
public Guid CustomerInvoiceItemId { get; set; }
|
||||
public string? ItemName { get; set; }
|
||||
public string? ItemDescription { get; set; }
|
||||
public decimal ItemPrice { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Fitness_core_BE.DTOs.CustomerInvoice
|
||||
{
|
||||
public class UpdateCustomerInvoiceStatusRequest
|
||||
{
|
||||
public Guid CustomerInvoiceId { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.CustomerPlan
|
||||
{
|
||||
public class CreateCustomerPlanRequest
|
||||
{
|
||||
[Required]
|
||||
public string PlanName { get; set; } = string.Empty;
|
||||
|
||||
public string? PlanDescription { get; set; }
|
||||
|
||||
[Required]
|
||||
[Range(0, double.MaxValue, ErrorMessage = "Plan price must be a positive value")]
|
||||
public decimal PlanPrice { get; set; }
|
||||
|
||||
public bool? HasOnboardingFee { get; set; }
|
||||
|
||||
[Range(0, double.MaxValue, ErrorMessage = "Onboarding fee must be zero or greater")]
|
||||
public decimal? OnboardingFeeAmount { get; set; }
|
||||
|
||||
/// <summary>Required when DurationMode is "Rolling" (validated in the service).</summary>
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Duration must be at least 1 day")]
|
||||
public int? DurationInDays { get; set; }
|
||||
|
||||
/// <summary>"Individual" (default) | "Group".</summary>
|
||||
public string? PlanScope { get; set; }
|
||||
|
||||
/// <summary>Required >= 2 when PlanScope is "Group".</summary>
|
||||
public int? MemberLimit { get; set; }
|
||||
|
||||
/// <summary>"Rolling" (default) | "FixedRange".</summary>
|
||||
public string? DurationMode { get; set; }
|
||||
|
||||
public DateTime? ValidFrom { get; set; }
|
||||
public DateTime? ValidTo { get; set; }
|
||||
|
||||
public bool? AllowSplitPayments { get; set; }
|
||||
|
||||
/// <summary>Number of mostly-equal installments; defaults to plan duration in months when split is enabled.</summary>
|
||||
public int? InstallmentCount { get; set; }
|
||||
|
||||
/// <summary>Null (default) = unlimited-access plan. A number = this plan grants that
|
||||
/// many bookable Facility sessions per billing cycle (e.g. "4 pool sessions a month").</summary>
|
||||
[Range(1, int.MaxValue, ErrorMessage = "SessionsPerCycle must be at least 1 when set")]
|
||||
public int? SessionsPerCycle { get; set; }
|
||||
|
||||
/// <summary>"NoRollover" (default) | "GracePeriod". Only meaningful when SessionsPerCycle is set.</summary>
|
||||
public string? SessionRolloverPolicy { get; set; }
|
||||
|
||||
/// <summary>Required (>= 1) when SessionRolloverPolicy is "GracePeriod".</summary>
|
||||
[Range(0, int.MaxValue, ErrorMessage = "RolloverGraceDays must be zero or greater")]
|
||||
public int? RolloverGraceDays { get; set; }
|
||||
|
||||
/// <summary>"Prepaid" (default, pay before the cycle starts) | "Postpaid" (use first,
|
||||
/// invoice at cycle end, access suspended if unpaid past due). Asked once per package.</summary>
|
||||
public string? BillingTiming { get; set; }
|
||||
|
||||
/// <summary>Places this plan grants access to. Null/omitted or empty = unrestricted
|
||||
/// (reaches every active access device, today's behavior).</summary>
|
||||
public List<Guid>? PlaceIds { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace Fitness_core_BE.DTOs.CustomerPlan
|
||||
{
|
||||
public class CustomerPlanDto
|
||||
{
|
||||
public Guid CustomerPlanId { get; set; }
|
||||
public Guid FKClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public string? PlanName { get; set; }
|
||||
public string? PlanDescription { get; set; }
|
||||
public decimal PlanPrice { get; set; }
|
||||
public bool HasOnboardingFee { get; set; }
|
||||
public decimal OnboardingFeeAmount { get; set; }
|
||||
public int DurationInDays { get; set; }
|
||||
public string PlanScope { get; set; } = "Individual";
|
||||
public int MemberLimit { get; set; } = 1;
|
||||
public string DurationMode { get; set; } = "Rolling";
|
||||
public DateTime? ValidFrom { get; set; }
|
||||
public DateTime? ValidTo { get; set; }
|
||||
public bool AllowSplitPayments { get; set; }
|
||||
public int InstallmentCount { get; set; } = 1;
|
||||
public int? SessionsPerCycle { get; set; }
|
||||
public string SessionRolloverPolicy { get; set; } = "NoRollover";
|
||||
public int RolloverGraceDays { get; set; }
|
||||
public string BillingTiming { get; set; } = "Prepaid";
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
// Which Places this plan grants access to. Empty = unrestricted (reaches every
|
||||
// active device) -- see AccessDeviceService's allowed-device resolution.
|
||||
public List<Guid> PlaceIds { get; set; } = new();
|
||||
public List<string> PlaceNames { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.CustomerPlan
|
||||
{
|
||||
/// <summary>
|
||||
/// Body of PATCH client/plans/{id}/status -- activate or deactivate a membership plan
|
||||
/// without resending its configuration.
|
||||
/// </summary>
|
||||
public class SetCustomerPlanStatusRequest
|
||||
{
|
||||
[Required]
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.CustomerPlan
|
||||
{
|
||||
public class UpdateCustomerPlanRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid CustomerPlanId { get; set; }
|
||||
|
||||
public string? PlanName { get; set; }
|
||||
|
||||
public string? PlanDescription { get; set; }
|
||||
|
||||
[Range(0, double.MaxValue, ErrorMessage = "Plan price must be a positive value")]
|
||||
public decimal? PlanPrice { get; set; }
|
||||
|
||||
public bool? HasOnboardingFee { get; set; }
|
||||
|
||||
[Range(0, double.MaxValue, ErrorMessage = "Onboarding fee must be zero or greater")]
|
||||
public decimal? OnboardingFeeAmount { get; set; }
|
||||
|
||||
[Range(1, int.MaxValue, ErrorMessage = "Duration must be at least 1 day")]
|
||||
public int? DurationInDays { get; set; }
|
||||
|
||||
public string? PlanScope { get; set; }
|
||||
|
||||
public int? MemberLimit { get; set; }
|
||||
|
||||
public string? DurationMode { get; set; }
|
||||
|
||||
public DateTime? ValidFrom { get; set; }
|
||||
public DateTime? ValidTo { get; set; }
|
||||
|
||||
public bool? AllowSplitPayments { get; set; }
|
||||
|
||||
public int? InstallmentCount { get; set; }
|
||||
|
||||
[Range(1, int.MaxValue, ErrorMessage = "SessionsPerCycle must be at least 1 when set")]
|
||||
public int? SessionsPerCycle { get; set; }
|
||||
|
||||
public string? SessionRolloverPolicy { get; set; }
|
||||
|
||||
[Range(0, int.MaxValue, ErrorMessage = "RolloverGraceDays must be zero or greater")]
|
||||
public int? RolloverGraceDays { get; set; }
|
||||
|
||||
public string? BillingTiming { get; set; }
|
||||
|
||||
public bool? IsActive { get; set; }
|
||||
|
||||
/// <summary>Replaces this plan's place set when provided (empty array clears it back
|
||||
/// to unrestricted). Omit/null to leave the plan's places unchanged.</summary>
|
||||
public List<Guid>? PlaceIds { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.CustomerSubscription
|
||||
{
|
||||
public class CreateCustomerSubscriptionRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid CustomerId { get; set; }
|
||||
|
||||
[Required]
|
||||
public Guid CustomerPlanId { get; set; }
|
||||
|
||||
public DateTime? OnboardDate { get; set; }
|
||||
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
namespace Fitness_core_BE.DTOs.CustomerSubscription
|
||||
{
|
||||
public class CustomerSubscriptionDto
|
||||
{
|
||||
public Guid SubscriptionId { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public string? CustomerName { get; set; }
|
||||
public Guid CustomerPlanId { get; set; }
|
||||
public string? PlanName { get; set; }
|
||||
public decimal PlanPrice { get; set; }
|
||||
public int DurationInDays { get; set; }
|
||||
public DateTime OnboardDate { get; set; }
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
public DateTime? RenewalDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public string? DiscountType { get; set; }
|
||||
public decimal? DiscountValue { get; set; }
|
||||
public List<CustomerSubItemDto>? SubItems { get; set; }
|
||||
}
|
||||
|
||||
public class CustomerSubItemDto
|
||||
{
|
||||
public Guid CustomerSubItemId { get; set; }
|
||||
public string? SubItemName { get; set; }
|
||||
public string? SubItemDescription { get; set; }
|
||||
public decimal SubItemPrice { get; set; }
|
||||
public string Frequency { get; set; } = "OneTime";
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
||||
|
||||
public class AddExtraFeeRequest
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string Frequency { get; set; } = "OneTime"; // "OneTime" | "Recurring"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
namespace Fitness_core_BE.DTOs.CustomerSubscription
|
||||
{
|
||||
/// <summary>Full picture of one subscription: plan config, members, money, schedule.</summary>
|
||||
public class SubscriptionSummaryDto
|
||||
{
|
||||
public Guid SubscriptionId { get; set; }
|
||||
public Guid CustomerPlanId { get; set; }
|
||||
public string? PlanName { get; set; }
|
||||
public string PlanScope { get; set; } = "Individual";
|
||||
public int MemberLimit { get; set; } = 1;
|
||||
public string DurationMode { get; set; } = "Rolling";
|
||||
public bool AllowSplitPayments { get; set; }
|
||||
public decimal PlanPrice { get; set; }
|
||||
public DateTime OnboardDate { get; set; }
|
||||
public DateTime? ExpiryDate { get; set; }
|
||||
public DateTime? RenewalDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
public Guid? CustomerInvoiceId { get; set; }
|
||||
public decimal InvoiceAmount { get; set; }
|
||||
public decimal PaidAmount { get; set; }
|
||||
public decimal Balance { get; set; }
|
||||
public string PaymentStatus { get; set; } = "Pending";
|
||||
|
||||
public List<SubscriptionMemberDto> Members { get; set; } = new();
|
||||
public List<SubscriptionInstallmentDto> Installments { get; set; } = new();
|
||||
|
||||
public bool AutoChargeEnabled { get; set; }
|
||||
public AutoChargeCardDto? AutoChargeCard { get; set; }
|
||||
}
|
||||
|
||||
public class AutoChargeCardDto
|
||||
{
|
||||
public Guid CardId { get; set; }
|
||||
public string? CardLast4 { get; set; }
|
||||
public string? CardType { get; set; }
|
||||
}
|
||||
|
||||
public class SubscriptionMemberDto
|
||||
{
|
||||
public Guid SubscriptionMemberId { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public string? CusName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? PrimaryPH { get; set; }
|
||||
public bool IsPrimary { get; set; }
|
||||
public DateTime JoinedAt { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
/// <summary>False when unassigned from the plan but still a member of the gym.</summary>
|
||||
public bool IsPlanAssigned { get; set; } = true;
|
||||
}
|
||||
|
||||
public class SubscriptionInstallmentDto
|
||||
{
|
||||
public Guid SubscriptionInstallmentId { get; set; }
|
||||
public int InstallmentNo { get; set; }
|
||||
public DateTime DueDate { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public decimal PaidAmount { get; set; }
|
||||
public string Status { get; set; } = "Pending";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Fitness_core_BE.DTOs
|
||||
{
|
||||
public class DocumentDownloadModel
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
public string FileType { get; set; }
|
||||
public byte[] FileData { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace Fitness_core_BE.DTOs.Facility
|
||||
{
|
||||
public class FacilityDto
|
||||
{
|
||||
public Guid FacilityId { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string FacilityType { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public int DefaultCapacity { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
}
|
||||
|
||||
public class FacilitySessionDto
|
||||
{
|
||||
public Guid FacilitySessionId { get; set; }
|
||||
public Guid FacilityId { get; set; }
|
||||
public string? FacilityName { get; set; }
|
||||
public DateTime StartTime { get; set; }
|
||||
public DateTime EndTime { get; set; }
|
||||
public int Capacity { get; set; }
|
||||
public int BookedCount { get; set; }
|
||||
public bool IsCancelled { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Facility
|
||||
{
|
||||
public class CreateFacilityRequest
|
||||
{
|
||||
[Required]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>"Gym" | "Pool" | "Court" | "Class".</summary>
|
||||
[Required]
|
||||
public string FacilityType { get; set; } = "Class";
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
[Range(1, int.MaxValue, ErrorMessage = "DefaultCapacity must be at least 1")]
|
||||
public int DefaultCapacity { get; set; } = 1;
|
||||
}
|
||||
|
||||
public class UpdateFacilityRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid FacilityId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? FacilityType { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public int? DefaultCapacity { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class SetFacilityStatusRequest
|
||||
{
|
||||
[Required]
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class CreateFacilitySessionRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid FacilityId { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime StartTime { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime EndTime { get; set; }
|
||||
|
||||
/// <summary>Overrides the facility's default capacity for this specific session.</summary>
|
||||
public int? Capacity { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
namespace Fitness_core_BE.DTOs.Ledger
|
||||
{
|
||||
public class LedgerEntryDto
|
||||
{
|
||||
public Guid? Id { get; set; } // null for derived (non-manual) entries
|
||||
public string EntryType { get; set; } = "Expense"; // "Income" | "Expense"
|
||||
public string Category { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public DateTime EntryDate { get; set; }
|
||||
public bool IsManual { get; set; }
|
||||
}
|
||||
|
||||
public class AddLedgerEntryRequest
|
||||
{
|
||||
public string EntryType { get; set; } = "Expense"; // "Income" | "Expense"
|
||||
public string Category { get; set; } = "Other";
|
||||
public string? Description { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public DateTime? EntryDate { get; set; }
|
||||
}
|
||||
|
||||
public class CategoryTotalDto
|
||||
{
|
||||
public string Category { get; set; } = string.Empty;
|
||||
public decimal Amount { get; set; }
|
||||
}
|
||||
|
||||
public class ProfitLossDto
|
||||
{
|
||||
public DateTime From { get; set; }
|
||||
public DateTime To { get; set; }
|
||||
public decimal TotalIncome { get; set; }
|
||||
public decimal TotalExpense { get; set; }
|
||||
public decimal NetProfit { get; set; }
|
||||
public List<CategoryTotalDto> IncomeByCategory { get; set; } = new();
|
||||
public List<CategoryTotalDto> ExpenseByCategory { get; set; } = new();
|
||||
public List<LedgerEntryDto> Entries { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Fitness_core_BE.DTOs.Meal
|
||||
{
|
||||
public class CustomerMealDto
|
||||
{
|
||||
public Guid CustomerMealId { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public string? CustomerName { get; set; }
|
||||
public Guid MealPlanId { get; set; }
|
||||
public string? MealPlanName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsFollowing { get; set; }
|
||||
public DateTime AssignedDate { get; set; }
|
||||
public DateTime? CompletedDate { get; set; }
|
||||
public string? Notes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Fitness_core_BE.DTOs.Meal
|
||||
{
|
||||
public class MealCategoryDto
|
||||
{
|
||||
public Guid MealCategoryId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace Fitness_core_BE.DTOs.Meal
|
||||
{
|
||||
public class MealDto
|
||||
{
|
||||
public Guid MealId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public decimal? Calories { get; set; }
|
||||
public decimal? Protein { get; set; }
|
||||
public decimal? Carbohydrates { get; set; }
|
||||
public decimal? Fats { get; set; }
|
||||
public string? ServingSize { get; set; }
|
||||
public object? MealItems { get; set; }
|
||||
public string? PreparationNotes { get; set; }
|
||||
public Guid MealPlanId { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Fitness_core_BE.DTOs.Meal
|
||||
{
|
||||
public class MealPlanDetailDto
|
||||
{
|
||||
public Guid MealPlanId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsTemplate { get; set; }
|
||||
public Guid MealCategoryId { get; set; }
|
||||
public string MealCategoryName { get; set; }
|
||||
public Guid? ClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
public List<MealDto> MealItems { get; set; } = new List<MealDto>();
|
||||
public List<CustomerMealDto> AssignedCustomers { get; set; } = new List<CustomerMealDto>();
|
||||
public decimal? TotalCalories { get; set; }
|
||||
public decimal? TotalProtein { get; set; }
|
||||
public decimal? TotalCarbohydrates { get; set; }
|
||||
public decimal? TotalFats { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Fitness_core_BE.DTOs.Meal
|
||||
{
|
||||
public class MealPlanDto
|
||||
{
|
||||
public Guid MealPlanId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsTemplate { get; set; }
|
||||
public Guid MealCategoryId { get; set; }
|
||||
public string MealCategoryName { get; set; }
|
||||
public Guid? ClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
public List<CustomerMealDto> AssignedCustomers { get; set; } = new List<CustomerMealDto>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
namespace Fitness_core_BE.DTOs.Mobile
|
||||
{
|
||||
public class SendOtpRequest
|
||||
{
|
||||
public string Identifier { get; set; } = string.Empty;
|
||||
public int NumberOfDigits { get; set; } = 4;
|
||||
public bool NewUser { get; set; }
|
||||
}
|
||||
|
||||
public class VerifyOtpLoginRequest
|
||||
{
|
||||
public string OtpCode { get; set; } = string.Empty;
|
||||
public string ReferenceNumber { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class VerifyOtpAltRequest
|
||||
{
|
||||
public string OtpCode { get; set; } = string.Empty;
|
||||
public string ReferenceNumber { get; set; } = string.Empty;
|
||||
public string? IdentifireType { get; set; }
|
||||
public string? Identifier { get; set; }
|
||||
}
|
||||
|
||||
public class RefreshTokenRequest
|
||||
{
|
||||
public string? RefreshToken { get; set; }
|
||||
}
|
||||
|
||||
public class RegisterCustomerRequest
|
||||
{
|
||||
public string Gender { get; set; } = string.Empty;
|
||||
public string Bod { get; set; } = string.Empty;
|
||||
public string UserTypeId { get; set; } = string.Empty;
|
||||
public string RoleId { get; set; } = string.Empty;
|
||||
public bool ChkUser { get; set; }
|
||||
public string? DeviceName { get; set; }
|
||||
public string? PushTokenId { get; set; }
|
||||
public string Fullname { get; set; } = string.Empty;
|
||||
public string MobileNumber { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class ForgotPasswordRequest
|
||||
{
|
||||
public string Identifier { get; set; } = string.Empty;
|
||||
public bool UseResetLink { get; set; }
|
||||
public int NumberOfDigits { get; set; } = 6;
|
||||
}
|
||||
|
||||
public class ResetPasswordRequest
|
||||
{
|
||||
public string ReferenceNumber { get; set; } = string.Empty;
|
||||
public string NewPassword { get; set; } = string.Empty;
|
||||
public string ConfirmPassword { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
// Verifies an OTP for a customer's own channel and sets the matching verified flag.
|
||||
public class VerifyChannelRequest
|
||||
{
|
||||
// "PrimaryPH" | "SecondaryPH" | "Email"
|
||||
public string IdentifireType { get; set; } = string.Empty;
|
||||
public string OtpCode { get; set; } = string.Empty;
|
||||
public string ReferenceNumber { get; set; } = string.Empty;
|
||||
public string Identifier { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Fitness_core_BE.DTOs.Mobile
|
||||
{
|
||||
public class GetOrCreateChatRequest
|
||||
{
|
||||
public Guid OtherUserId { get; set; }
|
||||
}
|
||||
|
||||
public class SendChatMessageRequest
|
||||
{
|
||||
public Guid ChatId { get; set; }
|
||||
public Guid SenderId { get; set; }
|
||||
public string Message { get; set; } = string.Empty;
|
||||
public string Type { get; set; } = "text";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
namespace Fitness_core_BE.DTOs.Mobile
|
||||
{
|
||||
/// <summary>Self-service profile update (mobile). Distinct from DTOs/Customer/UpdateCustomerRequest,
|
||||
/// which is the client-managed shape used by ClientController.</summary>
|
||||
public class UpdateCustomerProfileRequest
|
||||
{
|
||||
public string? Fullname { get; set; }
|
||||
public string? Gender { get; set; }
|
||||
public DateOnly? Bod { get; set; }
|
||||
public string? PrimaryPH { get; set; }
|
||||
public string? SecondaryPH { get; set; }
|
||||
public string? Nic { get; set; }
|
||||
public string? Address { get; set; }
|
||||
public string? Email { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateHealthRequest
|
||||
{
|
||||
public string? BloodGroup { get; set; }
|
||||
public string? Disabilities { get; set; }
|
||||
}
|
||||
|
||||
public class CreateProgressRequest
|
||||
{
|
||||
public decimal? Height { get; set; }
|
||||
public decimal? CurrentWeight { get; set; }
|
||||
public decimal? TargetWeight { get; set; }
|
||||
public string? Goal { get; set; }
|
||||
public int? Age { get; set; }
|
||||
public string? Gender { get; set; }
|
||||
public string? ActivityLevel { get; set; }
|
||||
public decimal? TimePeriod { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Updates the customer's latest height and/or weight measurement.</summary>
|
||||
public class UpdateProgressRequest
|
||||
{
|
||||
public decimal? Height { get; set; }
|
||||
public decimal? Weight { get; set; }
|
||||
public DateTime? ProgressDate { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Member self-serve "add card" for auto-deduct. cardToken is an opaque client-side
|
||||
/// value (mock today, would be real PayHere/Stripe tokenization once a gateway is wired up).</summary>
|
||||
public class SaveCardRequest
|
||||
{
|
||||
public string CardToken { get; set; } = string.Empty;
|
||||
public string? CardLast4 { get; set; }
|
||||
public string? CardType { get; set; }
|
||||
public string? NickName { get; set; }
|
||||
/// <summary>Must be explicitly true — this is the member's auto-deduct consent.</summary>
|
||||
public bool Consent { get; set; }
|
||||
}
|
||||
|
||||
public class SetAutoChargeRequest
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public Guid? CardId { get; set; }
|
||||
}
|
||||
|
||||
public class UpdatePushTokenRequest
|
||||
{
|
||||
public string PushTokenId { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>documentId comes from POST /customer/documents' upload response — the client
|
||||
/// uploads the picked image first, then links it here as the profile picture.</summary>
|
||||
public class UpdateProfileImageRequest
|
||||
{
|
||||
public int DocumentId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Fitness_core_BE.DTOs.Mobile
|
||||
{
|
||||
public class AcceptGymTermsRequest
|
||||
{
|
||||
public int Version { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Fitness_core_BE.DTOs.Mobile
|
||||
{
|
||||
public class CreateTicketRequest
|
||||
{
|
||||
public string MainReason { get; set; } = string.Empty;
|
||||
public string? TicketCategoryId { get; set; }
|
||||
public string? TicketStatus { get; set; }
|
||||
}
|
||||
|
||||
public class SendTicketMessageRequest
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class SubmitTicketFeedbackRequest
|
||||
{
|
||||
public int Rating { get; set; }
|
||||
public string? Feedback { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
namespace Fitness_core_BE.DTOs.PaymentGateways
|
||||
{
|
||||
// Mirrors Payment-Service's DTOs/Payments/*.cs for the HMAC-signed, per-platform
|
||||
// Cards/Payments/Refunds surface (IPaymentGatewayClient) — distinct from
|
||||
// PaymentGatewayDtos.cs, which is the X-Internal-Key admin/catalog surface.
|
||||
|
||||
public class OnboardCardRequest
|
||||
{
|
||||
public string GatewayName { get; set; } = "DirectPay";
|
||||
public string CustomerId { get; set; } = string.Empty;
|
||||
public string CardLabel { get; set; } = string.Empty;
|
||||
public string CardholderName { get; set; } = string.Empty;
|
||||
public bool IsDefault { get; set; } = false;
|
||||
public string? ReturnUrl { get; set; }
|
||||
}
|
||||
|
||||
public class OnboardCardResult
|
||||
{
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public string? RedirectUrl { get; set; }
|
||||
public string CardToken { get; set; } = string.Empty;
|
||||
public string MaskedPan { get; set; } = string.Empty;
|
||||
public string CardLabel { get; set; } = string.Empty;
|
||||
public string CardBrand { get; set; } = string.Empty;
|
||||
public int ExpiryMonth { get; set; }
|
||||
public int ExpiryYear { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public string GatewayRef { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class CardDetailsResult
|
||||
{
|
||||
public string CardToken { get; set; } = string.Empty;
|
||||
public string MaskedPan { get; set; } = string.Empty;
|
||||
public string CardLabel { get; set; } = string.Empty;
|
||||
public string CardBrand { get; set; } = string.Empty;
|
||||
public int ExpiryMonth { get; set; }
|
||||
public int ExpiryYear { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public string GatewayName { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AttemptPaymentRequest
|
||||
{
|
||||
public string IdempotencyKey { get; set; } = string.Empty;
|
||||
public string GatewayName { get; set; } = "DirectPay";
|
||||
public string CardToken { get; set; } = string.Empty;
|
||||
public decimal AmountMinorUnits { get; set; }
|
||||
public string Currency { get; set; } = "LKR";
|
||||
public string Description { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class AttemptPaymentResult
|
||||
{
|
||||
public Guid PaymentId { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public string? GatewayRef { get; set; }
|
||||
public DateTime CreatedAtUtc { get; set; }
|
||||
}
|
||||
|
||||
public class RefundPaymentResult
|
||||
{
|
||||
public Guid PaymentId { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public string GatewayRef { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class SetDefaultCardResult
|
||||
{
|
||||
public string CardToken { get; set; } = string.Empty;
|
||||
public bool IsDefault { get; set; }
|
||||
}
|
||||
|
||||
public class PaymentListItemResult
|
||||
{
|
||||
public Guid PaymentId { get; set; }
|
||||
public decimal AmountMinorUnits { get; set; }
|
||||
public string Currency { get; set; } = string.Empty;
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime CreatedAtUtc { get; set; }
|
||||
}
|
||||
|
||||
public class PaymentListResult
|
||||
{
|
||||
public int Total { get; set; }
|
||||
public int Page { get; set; }
|
||||
public List<PaymentListItemResult> Items { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
namespace Fitness_core_BE.DTOs.PaymentGateways
|
||||
{
|
||||
// Mirrors Payment-Service's DTOs/Gateways/GatewayDtos.cs - Fitness_Core_BE's
|
||||
// AdminController proxies to Payment-Service rather than exposing it directly
|
||||
// to the admin frontend (see Phase 0 decision: no admin/JWT auth surface there).
|
||||
public class GatewayDefinitionDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string GatewayName { get; set; } = string.Empty;
|
||||
public string DisplayName { get; set; } = string.Empty;
|
||||
public bool IsEnabled { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public string Mode { get; set; } = "Sandbox";
|
||||
public bool SupportsWebhooks { get; set; }
|
||||
}
|
||||
|
||||
public class UpsertGatewayDefinitionRequest
|
||||
{
|
||||
public string GatewayName { get; set; } = string.Empty;
|
||||
public string DisplayName { get; set; } = string.Empty;
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
public bool IsDefault { get; set; } = false;
|
||||
public string Mode { get; set; } = "Sandbox";
|
||||
public bool SupportsWebhooks { get; set; } = true;
|
||||
}
|
||||
|
||||
public class SetGatewayEnabledRequest
|
||||
{
|
||||
public bool IsEnabled { get; set; }
|
||||
}
|
||||
|
||||
public class UpsertPlatformGatewayCredentialRequest
|
||||
{
|
||||
public Guid PlatformId { get; set; }
|
||||
public string GatewayName { get; set; } = string.Empty;
|
||||
public string CredentialsJson { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace Fitness_core_BE.DTOs.PaymentsEnablement
|
||||
{
|
||||
// Gym owner's own payout track selection, KYC submission, wallet and payout schedule —
|
||||
// distinct from Fitness_Core_BE.DTOs.PaymentGateways, which is the platform-admin's
|
||||
// gateway catalog (proxied to Payment-Service).
|
||||
public record PaymentTrackOption(string Track, object FeeSummary);
|
||||
public record SelectPaymentTrackRequest(string Track);
|
||||
public record PaymentTrackSelectionResult(string Track, bool KycRequired);
|
||||
|
||||
public record SubmitGatewayOnboardingRequest(Guid GatewayId);
|
||||
|
||||
public record GatewayOnboardingStatusDto(
|
||||
string KycStatus,
|
||||
Guid? GatewayId,
|
||||
string? GatewayName,
|
||||
string? RejectionReason);
|
||||
|
||||
public record ClientPayoutKycDto(
|
||||
Guid Id,
|
||||
Guid ClientId,
|
||||
string? ClientName,
|
||||
Guid? GatewayId,
|
||||
string? GatewayName,
|
||||
string KycStatus,
|
||||
DateTime SubmittedAt,
|
||||
DateTime? ReviewedAt,
|
||||
string? RejectionReason,
|
||||
string? NicNumber,
|
||||
int? NicFrontDocId,
|
||||
int? NicBackDocId);
|
||||
|
||||
public record ReviewPayoutKycRequest(string Status, string? Reason);
|
||||
|
||||
public record WalletDto(decimal Balance, string Currency, List<WalletLedgerEntryDto> Ledger, DateTime? LastPayoutDate);
|
||||
public record WalletLedgerEntryDto(Guid Id, string EntryType, decimal Amount, string? Description, DateTime CreatedAt);
|
||||
public record PayoutScheduleDto(DateTime NextPayoutDate, string Cadence, decimal PendingAmount);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Fitness_core_BE.DTOs.Place
|
||||
{
|
||||
public class PlaceDto
|
||||
{
|
||||
public Guid PlaceId { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
// At most one for now -- see AccessDevice.FKPlaceId.
|
||||
public Guid? DeviceId { get; set; }
|
||||
public string? DeviceName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Place
|
||||
{
|
||||
public class CreatePlaceRequest
|
||||
{
|
||||
[Required]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
}
|
||||
|
||||
public class UpdatePlaceRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid PlaceId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class SetPlaceStatusRequest
|
||||
{
|
||||
[Required]
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class AssignPlaceDeviceRequest
|
||||
{
|
||||
// Null unassigns the place's current device.
|
||||
public Guid? DeviceId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
namespace Fitness_core_BE.DTOs.PlatformBilling
|
||||
{
|
||||
// The gym's own saved card(s) for paying their HexaFitness platform subscription
|
||||
// (ClientCard), and the transaction history behind those charges. Distinct from
|
||||
// PaymentGatewayDtos.cs (admin gateway catalog) and PaymentsEnablementDtos.cs
|
||||
// (payout track/KYC/wallet) — this is the "gym pays HexaFitness" card-charging surface.
|
||||
|
||||
// Fetched live from Payment-Service on every call — CardToken is the identifier (not a
|
||||
// local id), and none of these fields are ever cached in Core's own database.
|
||||
public class ClientCardDto
|
||||
{
|
||||
public string CardToken { get; set; } = string.Empty;
|
||||
public string MaskedPan { get; set; } = string.Empty;
|
||||
public string CardBrand { get; set; } = string.Empty;
|
||||
public int ExpiryMonth { get; set; }
|
||||
public int ExpiryYear { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
}
|
||||
|
||||
public class StartCardOnboardingRequest
|
||||
{
|
||||
public string? CardLabel { get; set; }
|
||||
public string? ReturnUrl { get; set; }
|
||||
}
|
||||
|
||||
public class StartCardOnboardingResult
|
||||
{
|
||||
public string RedirectUrl { get; set; } = string.Empty;
|
||||
public string SessionId { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class CardOnboardingStatusResult
|
||||
{
|
||||
public bool IsComplete { get; set; }
|
||||
public ClientCardDto? Card { get; set; }
|
||||
}
|
||||
|
||||
public class TransactionHistoryItemDto
|
||||
{
|
||||
public Guid PaymentId { get; set; }
|
||||
public decimal AmountMinorUnits { get; set; }
|
||||
public string Currency { get; set; } = string.Empty;
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime CreatedAtUtc { get; set; }
|
||||
}
|
||||
|
||||
public class TransactionHistoryResult
|
||||
{
|
||||
public int Total { get; set; }
|
||||
public int Page { get; set; }
|
||||
public List<TransactionHistoryItemDto> Items { get; set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
namespace Fitness_core_BE.DTOs.PlatformBilling
|
||||
{
|
||||
public class PricingPlanDto
|
||||
{
|
||||
public Guid ClientPackageId { get; set; }
|
||||
public string? PackageName { get; set; }
|
||||
public string? PackageDescription { get; set; }
|
||||
public decimal PerMemberRate { get; set; }
|
||||
public decimal MinimumMonthlyBill { get; set; }
|
||||
public decimal? MonthlyCap { get; set; }
|
||||
public decimal SetupFee { get; set; }
|
||||
public int IncludedMemberCount { get; set; }
|
||||
public int? MaxBillableMemberCount { get; set; }
|
||||
public decimal OwnGatewayFeePercent { get; set; }
|
||||
public decimal OwnGatewayFeeFixed { get; set; }
|
||||
public decimal OurGatewayFeePercent { get; set; }
|
||||
public decimal OurGatewayFeeFixed { get; set; }
|
||||
public int PayoutDayOfMonth { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class UpsertPricingPlanRequest
|
||||
{
|
||||
public Guid? ClientPackageId { get; set; }
|
||||
public string PackageName { get; set; } = string.Empty;
|
||||
public string? PackageDescription { get; set; }
|
||||
public decimal PerMemberRate { get; set; }
|
||||
public decimal MinimumMonthlyBill { get; set; }
|
||||
public decimal? MonthlyCap { get; set; }
|
||||
public decimal SetupFee { get; set; }
|
||||
public int IncludedMemberCount { get; set; }
|
||||
public int? MaxBillableMemberCount { get; set; }
|
||||
public decimal OwnGatewayFeePercent { get; set; }
|
||||
public decimal OwnGatewayFeeFixed { get; set; }
|
||||
public decimal OurGatewayFeePercent { get; set; }
|
||||
public decimal OurGatewayFeeFixed { get; set; }
|
||||
public int PayoutDayOfMonth { get; set; } = 1;
|
||||
public bool IsDefault { get; set; }
|
||||
}
|
||||
|
||||
public class DevicePricingDto
|
||||
{
|
||||
public decimal DeviceRentalFeePerMonth { get; set; }
|
||||
public decimal DeviceInstallationFee { get; set; }
|
||||
public decimal DeviceConfigureExistingFee { get; set; }
|
||||
}
|
||||
|
||||
public class AssignPricingPlanRequest
|
||||
{
|
||||
public Guid ClientPackageId { get; set; }
|
||||
// Optional: decide the fingerprint-machine charge at the same time as the plan assignment.
|
||||
public string? DeviceBillingMode { get; set; } // "FullPurchase" | "Rental" | null (no device charge)
|
||||
public decimal? DeviceAgreedAmount { get; set; }
|
||||
public decimal? DeviceSetupFee { get; set; }
|
||||
}
|
||||
|
||||
public class ClientDeviceBillingDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Mode { get; set; } = "Rental";
|
||||
public decimal AgreedAmount { get; set; }
|
||||
public decimal SetupFee { get; set; }
|
||||
public DateTime AssignedAt { get; set; }
|
||||
}
|
||||
|
||||
public class RecordClientInvoicePaymentRequest
|
||||
{
|
||||
public decimal Amount { get; set; }
|
||||
}
|
||||
|
||||
public class PlatformFeeBreakdownDto
|
||||
{
|
||||
public Guid ClientId { get; set; }
|
||||
public string? PlanName { get; set; }
|
||||
public int ActiveMemberCount { get; set; }
|
||||
public decimal PerMemberRate { get; set; }
|
||||
public decimal MinimumMonthlyBill { get; set; }
|
||||
public decimal? MonthlyCap { get; set; }
|
||||
public decimal BaseFee { get; set; }
|
||||
public int DeviceCount { get; set; }
|
||||
public decimal DeviceFee { get; set; }
|
||||
public decimal GatewayFee { get; set; }
|
||||
public decimal TotalFee { get; set; }
|
||||
}
|
||||
|
||||
public class ClientInvoiceItemDto
|
||||
{
|
||||
public string? ItemName { get; set; }
|
||||
public string? ItemDescription { get; set; }
|
||||
public decimal ItemPrice { get; set; }
|
||||
}
|
||||
|
||||
public class ClientInvoiceSummaryDto
|
||||
{
|
||||
public Guid ClientInvoiceId { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime ClientInvoiceDate { get; set; }
|
||||
public List<ClientInvoiceItemDto> Items { get; set; } = new();
|
||||
}
|
||||
|
||||
public class PendingPlatformInvoiceDto
|
||||
{
|
||||
public Guid ClientInvoiceId { get; set; }
|
||||
public Guid ClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public string? City { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public decimal PaidAmount { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public DateTime ClientInvoiceDate { get; set; }
|
||||
public int DaysOverdue { get; set; }
|
||||
}
|
||||
|
||||
// Result of one worker run: RunAndChargeSubscriptionBillingAsync both generates any
|
||||
// invoices newly due this period and drives them (and any still-in-flight from a prior
|
||||
// run) toward Paid/Failed via Payment-Service.
|
||||
public class SubscriptionChargeRunResult
|
||||
{
|
||||
public int InvoicesGenerated { get; set; }
|
||||
public int ChargesAttempted { get; set; }
|
||||
public int Paid { get; set; }
|
||||
public int StillProcessing { get; set; }
|
||||
public int Failed { get; set; }
|
||||
public int SkippedNoCard { get; set; }
|
||||
// A prior attempt already came back Failed — Payment-Service payments can never leave
|
||||
// Failed, so these are left Pending for the existing manual pay-link fallback rather
|
||||
// than retried automatically here.
|
||||
public int SkippedPreviouslyFailed { get; set; }
|
||||
// The invoice's balance changed (e.g. an admin recorded a manual partial payment) since
|
||||
// an in-flight charge was created for the old balance — retrying would either overcharge
|
||||
// or hit Payment-Service's idempotency-conflict check, so this is left for manual review.
|
||||
public int SkippedAmountMismatch { get; set; }
|
||||
public int Errors { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
namespace Fitness_core_BE.DTOs.Rbac
|
||||
{
|
||||
public class NavItemDto
|
||||
{
|
||||
public string Key { get; set; } = string.Empty;
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string? ShortLabel { get; set; }
|
||||
public string Href { get; set; } = string.Empty;
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class NavResponseDto
|
||||
{
|
||||
public bool IsOwner { get; set; }
|
||||
public List<NavItemDto> Items { get; set; } = new();
|
||||
}
|
||||
|
||||
public class GymRoleDto
|
||||
{
|
||||
public Guid GymRoleId { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public bool IsActive { get; set; }
|
||||
public List<string> NavKeys { get; set; } = new();
|
||||
}
|
||||
|
||||
public class CreateGymRoleRequest
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class UpdateGymRoleRequest
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public bool? IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class SetRolePermissionsRequest
|
||||
{
|
||||
public List<string> NavKeys { get; set; } = new();
|
||||
}
|
||||
|
||||
public class AssignStaffRoleRequest
|
||||
{
|
||||
// Nullable to support unassigning a staff member's role.
|
||||
public Guid? GymRoleId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Staff
|
||||
{
|
||||
public class CreateStaffRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid ClientId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string UserName { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[EmailAddress]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[Phone]
|
||||
public string PhoneNumber { get; set; } = string.Empty;
|
||||
|
||||
public string? StaffPosition { get; set; }
|
||||
|
||||
public string? Department { get; set; }
|
||||
|
||||
public DateTime? HireDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace Fitness_core_BE.DTOs.Staff
|
||||
{
|
||||
public class StaffDto
|
||||
{
|
||||
public Guid StaffId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public string? UserName { get; set; }
|
||||
public string? Email { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
public Guid ClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public Guid? GymRoleId { get; set; }
|
||||
public string? GymRoleName { get; set; }
|
||||
public string? StaffPosition { get; set; }
|
||||
public string? Department { get; set; }
|
||||
public DateTime HireDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public long? AccessProfileId { get; set; }
|
||||
public string? AccessNumber { get; set; }
|
||||
public string AccessProvisionStatus { get; set; } = "NotConfigured";
|
||||
public string ActualAccessState { get; set; } = "Unknown";
|
||||
public string DesiredAccessState { get; set; } = "Enabled";
|
||||
public int FingerprintCount { get; set; }
|
||||
public string? AccessLastError { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace Fitness_core_BE.DTOs.Staff
|
||||
{
|
||||
public class StaffPayRateDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string RateType { get; set; } = "Monthly";
|
||||
public decimal Amount { get; set; }
|
||||
public DateTime EffectiveFrom { get; set; }
|
||||
}
|
||||
|
||||
public class UpsertStaffPayRateRequest
|
||||
{
|
||||
public string RateType { get; set; } = "Monthly"; // "Monthly" | "Hourly"
|
||||
public decimal Amount { get; set; }
|
||||
}
|
||||
|
||||
public class StaffPaymentDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public decimal Amount { get; set; }
|
||||
public string? Note { get; set; }
|
||||
public DateTime PaidAt { get; set; }
|
||||
}
|
||||
|
||||
public class RecordStaffPaymentRequest
|
||||
{
|
||||
public decimal Amount { get; set; }
|
||||
public string? Note { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Staff
|
||||
{
|
||||
public class UpdateStaffRequest
|
||||
{
|
||||
[Required]
|
||||
public Guid StaffId { get; set; }
|
||||
|
||||
public string? UserName { get; set; }
|
||||
|
||||
[EmailAddress]
|
||||
public string? Email { get; set; }
|
||||
|
||||
[Phone]
|
||||
public string? PhoneNumber { get; set; }
|
||||
|
||||
public string? StaffPosition { get; set; }
|
||||
|
||||
public string? Department { get; set; }
|
||||
|
||||
public bool? IsActive { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace Fitness_core_BE.DTOs.Stats
|
||||
{
|
||||
public class ClientStatSummaryDto
|
||||
{
|
||||
public int TotalCustomerCount { get; set; }
|
||||
public int ThisMonthCustomerCount { get; set; }
|
||||
public int LastMonthCustomerCount { get; set; }
|
||||
public decimal CustomerGrowthPercentage { get; set; }
|
||||
public decimal ThisMonthRevenue { get; set; }
|
||||
public decimal LastMonthRevenue { get; set; }
|
||||
public decimal RevenueGrowthPercentage { get; set; }
|
||||
public decimal TotalRevenue { get; set; }
|
||||
public int OverdueCount { get; set; }
|
||||
public int ExpiringWithin7DaysCount { get; set; }
|
||||
public int TodayPaymentsCount { get; set; }
|
||||
public decimal TodayPaymentsTotal { get; set; }
|
||||
// Muscle Beast-only pilot feature (their explicit request) -- gated server-side so the
|
||||
// frontend never needs to know any gym's ClientId to decide whether to show it.
|
||||
public bool ShowTodayPayments { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Fitness_core_BE.DTOs.Stats
|
||||
{
|
||||
public class MonthlyRevenueStat
|
||||
{
|
||||
public int Year { get; set; }
|
||||
public int Month { get; set; }
|
||||
public string MonthLabel { get; set; }
|
||||
public decimal Revenue { get; set; }
|
||||
public int NewMemberCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using Fitness_core_BE.Models.Enums;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Ticket
|
||||
{
|
||||
public class TicketDetailDto
|
||||
{
|
||||
public Guid TicketId { get; set; }
|
||||
public string MainReason { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
// User Information
|
||||
public Guid UserId { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string UserEmail { get; set; }
|
||||
public string UserPhoneNumber { get; set; }
|
||||
|
||||
// Admin Information (nullable)
|
||||
public Guid? AdminId { get; set; }
|
||||
public string? AdminName { get; set; }
|
||||
public string? AdminPhoneNumber { get; set; }
|
||||
|
||||
// Category Information
|
||||
public Guid? TicketCategoryId { get; set; }
|
||||
public string? TicketCategoryName { get; set; }
|
||||
public PriorityLevel? PriorityLevel { get; set; }
|
||||
|
||||
// Status Information
|
||||
public TicketStatusEnum TicketStatus { get; set; }
|
||||
|
||||
// Feedback Information
|
||||
public int? UserRating { get; set; }
|
||||
public string? UserFeedback { get; set; }
|
||||
public DateTime? FeedbackAt { get; set; }
|
||||
|
||||
// Messages
|
||||
public List<TicketMessageDto> Messages { get; set; } = new List<TicketMessageDto>();
|
||||
}
|
||||
|
||||
public class TicketMessageDto
|
||||
{
|
||||
public Guid MessageId { get; set; }
|
||||
public bool IsSentByAdmin { get; set; }
|
||||
public string Message { get; set; }
|
||||
public string? AttachmentURL { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
public int? FKDocumentId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Fitness_core_BE.Models.Enums;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.Ticket
|
||||
{
|
||||
public class TicketDto
|
||||
{
|
||||
public Guid TicketId { get; set; }
|
||||
public string MainReason { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
// User Information
|
||||
public Guid UserId { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string UserEmail { get; set; }
|
||||
|
||||
// Admin Information (nullable)
|
||||
public Guid? AdminId { get; set; }
|
||||
public string? AdminName { get; set; }
|
||||
|
||||
// Category Information
|
||||
public Guid? TicketCategoryId { get; set; }
|
||||
public string? TicketCategoryName { get; set; }
|
||||
public PriorityLevel? PriorityLevel { get; set; }
|
||||
|
||||
// Rating
|
||||
public int? UserRating { get; set; }
|
||||
|
||||
// Status Information
|
||||
public TicketStatusEnum TicketStatus { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace Fitness_core_BE.DTOs.TimeBankCard
|
||||
{
|
||||
public class TimeBankCardDto
|
||||
{
|
||||
public Guid TimeBankCardId { get; set; }
|
||||
public string RfidTagId { get; set; } = string.Empty;
|
||||
public Guid? CustomerId { get; set; }
|
||||
public int TotalMinutesPurchased { get; set; }
|
||||
public int MinutesRemaining { get; set; }
|
||||
public decimal AmountPaid { get; set; }
|
||||
public DateTime PurchasedAt { get; set; }
|
||||
public DateTime? ExpiresAt { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>True right after a tap-in swipe (session open, clock running); false after
|
||||
/// tap-out or when the card has no open session.</summary>
|
||||
public bool SessionOpen { get; set; }
|
||||
public DateTime? SessionStartedAt { get; set; }
|
||||
public string? SessionFacilityName { get; set; }
|
||||
|
||||
/// <summary>Only populated in the response to a tap-out swipe.</summary>
|
||||
public int? MinutesDeductedThisSwipe { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Fitness_core_BE.DTOs.TimeBankCard
|
||||
{
|
||||
public class IssueTimeBankCardRequest
|
||||
{
|
||||
[Required]
|
||||
public string RfidTagId { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[Range(1, int.MaxValue, ErrorMessage = "TotalMinutesPurchased must be at least 1")]
|
||||
public int TotalMinutesPurchased { get; set; }
|
||||
|
||||
[Range(0, double.MaxValue, ErrorMessage = "AmountPaid must be zero or greater")]
|
||||
public decimal AmountPaid { get; set; }
|
||||
|
||||
/// <summary>Ties the card to a member's own account; omit for a walk-in-only card.</summary>
|
||||
public Guid? CustomerId { get; set; }
|
||||
|
||||
public DateTime? ExpiresAt { get; set; }
|
||||
}
|
||||
|
||||
// No MinutesToDeduct -- the swipe itself is tap-in (first swipe, starts the clock) or
|
||||
// tap-out (second swipe, deducts the elapsed time). See TimeBankCard.ActiveSessionStartedAt.
|
||||
public class SwipeTimeBankCardRequest
|
||||
{
|
||||
[Required]
|
||||
public string RfidTagId { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public Guid FacilityId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Fitness_core_BE.DTOs.Tute
|
||||
{
|
||||
public class UpdateTuteItemRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string? Notes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace Fitness_core_BE.DTOs.Workout
|
||||
{
|
||||
public class CustomerWorkoutDto
|
||||
{
|
||||
public Guid CustomerWorkoutId { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public string? CustomerName { get; set; }
|
||||
public Guid WorkoutPlanId { get; set; }
|
||||
public string? WorkoutPlanName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsFollowing { get; set; }
|
||||
public DateTime AssignedDate { get; set; }
|
||||
public DateTime? CompletedDate { get; set; }
|
||||
public string? Notes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Fitness_core_BE.DTOs.Workout
|
||||
{
|
||||
public class WorkoutCategoryDto
|
||||
{
|
||||
public Guid WorkoutCategoryId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Fitness_core_BE.DTOs.Workout
|
||||
{
|
||||
public class WorkoutExerciseDto
|
||||
{
|
||||
public Guid WorkoutExerciseId { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? MuscleGroup { get; set; }
|
||||
public int? Sets { get; set; }
|
||||
public string? Reps { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public string? BreathIn { get; set; }
|
||||
public string? BreathOut { get; set; }
|
||||
public string? VideoUrl { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
public bool IsCompleted { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Fitness_core_BE.DTOs.Workout
|
||||
{
|
||||
public class WorkoutItemDto
|
||||
{
|
||||
public Guid WorkoutItemId { get; set; }
|
||||
public string ExerciseDay { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public string? Exercises { get; set; }
|
||||
public string? HowToDo { get; set; }
|
||||
public string? DoURL { get; set; }
|
||||
public string? Duration { get; set; }
|
||||
public string? WormUp { get; set; }
|
||||
public string? Cooldown { get; set; }
|
||||
public Guid WorkoutPlanId { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
public List<WorkoutExerciseDto> WorkoutExercises { get; set; } = new List<WorkoutExerciseDto>();
|
||||
public int TotalExercises { get; set; }
|
||||
public int CompletedExercises { get; set; }
|
||||
public bool IsCompleted { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Fitness_core_BE.DTOs.Workout
|
||||
{
|
||||
public class WorkoutPlanDetailDto
|
||||
{
|
||||
public Guid WorkoutPlanId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsTemplate { get; set; }
|
||||
public Guid WorkoutCategoryId { get; set; }
|
||||
public string WorkoutCategoryName { get; set; }
|
||||
public Guid? ClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
public List<WorkoutItemDto> WorkoutItems { get; set; } = new List<WorkoutItemDto>();
|
||||
public List<CustomerWorkoutDto> AssignedCustomers { get; set; } = new List<CustomerWorkoutDto>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Fitness_core_BE.DTOs.Workout
|
||||
{
|
||||
public class WorkoutPlanDto
|
||||
{
|
||||
public Guid WorkoutPlanId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool IsTemplate { get; set; }
|
||||
public Guid WorkoutCategoryId { get; set; }
|
||||
public string WorkoutCategoryName { get; set; }
|
||||
public Guid? ClientId { get; set; }
|
||||
public string? ClientName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public DateTime CreateDate { get; set; }
|
||||
public List<CustomerWorkoutDto> AssignedCustomers { get; set; } = new List<CustomerWorkoutDto>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user