first commit
This commit is contained in:
@@ -0,0 +1,262 @@
|
||||
using Fitness_core_BE.DTOs.Facility;
|
||||
using Fitness_core_BE.Helpers;
|
||||
using Fitness_core_BE.Infra.UoW;
|
||||
using Fitness_core_BE.Interfaces;
|
||||
using Fitness_core_BE.Interfaces.Services;
|
||||
using Fitness_core_BE.Models;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Fitness_core_BE.Services
|
||||
{
|
||||
public class FacilityService : IFacilityService
|
||||
{
|
||||
private static readonly string[] ValidFacilityTypes = { "Gym", "Pool", "Court", "Class" };
|
||||
|
||||
private readonly IFacilityRepository _facilityRepository;
|
||||
private readonly IUnitOfWork _uow;
|
||||
private readonly UserRoleHelper _userRoleHelper;
|
||||
|
||||
public FacilityService(IFacilityRepository facilityRepository, IUnitOfWork uow, UserRoleHelper userRoleHelper)
|
||||
{
|
||||
_facilityRepository = facilityRepository;
|
||||
_uow = uow;
|
||||
_userRoleHelper = userRoleHelper;
|
||||
}
|
||||
|
||||
public async Task<object> GetAllFacilities(object payload, HttpContext httpContext)
|
||||
{
|
||||
var data = DeserializePayload.Deserialize(payload);
|
||||
bool includeInactive = data.ContainsKey("includeInactive") && data["includeInactive"].GetBoolean();
|
||||
|
||||
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(httpContext));
|
||||
var facilities = await _facilityRepository.GetAllFacilities(clientId, includeInactive);
|
||||
|
||||
return facilities.Select(MapToDto).ToList();
|
||||
}
|
||||
|
||||
public async Task<object> CreateFacility(object payload, HttpContext httpContext)
|
||||
{
|
||||
await _uow.BeginAsync();
|
||||
try
|
||||
{
|
||||
var data = DeserializePayload.Deserialize(payload);
|
||||
if (!data.ContainsKey("name")) throw new KeyNotFoundException("name is required");
|
||||
if (!data.ContainsKey("facilityType")) throw new KeyNotFoundException("facilityType is required");
|
||||
|
||||
var facilityType = data["facilityType"].GetString() ?? "";
|
||||
if (!ValidFacilityTypes.Contains(facilityType))
|
||||
throw new ArgumentException($"facilityType must be one of: {string.Join(", ", ValidFacilityTypes)}");
|
||||
|
||||
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(httpContext));
|
||||
|
||||
var facility = new Facility
|
||||
{
|
||||
FKClientId = clientId,
|
||||
Name = data["name"].GetString() ?? "",
|
||||
FacilityType = facilityType,
|
||||
Description = data.ContainsKey("description") ? data["description"].GetString() : null,
|
||||
DefaultCapacity = data.ContainsKey("defaultCapacity") ? data["defaultCapacity"].GetInt32() : 1
|
||||
};
|
||||
|
||||
if (facility.DefaultCapacity < 1)
|
||||
throw new ArgumentException("defaultCapacity must be at least 1");
|
||||
|
||||
var result = await _facilityRepository.CreateFacility(facility);
|
||||
await _uow.CommitAsync();
|
||||
|
||||
return MapToDto(result);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await _uow.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<object> UpdateFacility(object payload, HttpContext httpContext)
|
||||
{
|
||||
await _uow.BeginAsync();
|
||||
try
|
||||
{
|
||||
var data = DeserializePayload.Deserialize(payload);
|
||||
if (!data.ContainsKey("facilityId")) throw new KeyNotFoundException("facilityId is required");
|
||||
|
||||
var facilityId = Guid.Parse(data["facilityId"].GetString()!);
|
||||
var existing = await _facilityRepository.GetFacilityById(facilityId)
|
||||
?? throw new KeyNotFoundException("Facility not found");
|
||||
|
||||
if (data.ContainsKey("name")) existing.Name = data["name"].GetString() ?? existing.Name;
|
||||
if (data.ContainsKey("facilityType"))
|
||||
{
|
||||
var facilityType = data["facilityType"].GetString() ?? existing.FacilityType;
|
||||
if (!ValidFacilityTypes.Contains(facilityType))
|
||||
throw new ArgumentException($"facilityType must be one of: {string.Join(", ", ValidFacilityTypes)}");
|
||||
existing.FacilityType = facilityType;
|
||||
}
|
||||
if (data.ContainsKey("description")) existing.Description = data["description"].GetString();
|
||||
if (data.ContainsKey("defaultCapacity"))
|
||||
{
|
||||
var capacity = data["defaultCapacity"].GetInt32();
|
||||
if (capacity < 1) throw new ArgumentException("defaultCapacity must be at least 1");
|
||||
existing.DefaultCapacity = capacity;
|
||||
}
|
||||
if (data.ContainsKey("isActive")) existing.IsActive = data["isActive"].GetBoolean();
|
||||
|
||||
var result = await _facilityRepository.UpdateFacility(existing);
|
||||
await _uow.CommitAsync();
|
||||
|
||||
return MapToDto(result);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await _uow.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<object> SetFacilityStatus(object payload, HttpContext httpContext)
|
||||
{
|
||||
await _uow.BeginAsync();
|
||||
try
|
||||
{
|
||||
var data = DeserializePayload.Deserialize(payload);
|
||||
var facilityId = Guid.Parse(data["facilityId"].GetString()!);
|
||||
var isActive = data["isActive"].GetBoolean();
|
||||
|
||||
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(httpContext));
|
||||
var facility = await _facilityRepository.SetFacilityActive(facilityId, clientId, isActive)
|
||||
?? throw new KeyNotFoundException("Facility not found");
|
||||
|
||||
await _uow.CommitAsync();
|
||||
return MapToDto(facility);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await _uow.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<object> CreateFacilitySession(object payload, HttpContext httpContext)
|
||||
{
|
||||
await _uow.BeginAsync();
|
||||
try
|
||||
{
|
||||
var data = DeserializePayload.Deserialize(payload);
|
||||
if (!data.ContainsKey("facilityId")) throw new KeyNotFoundException("facilityId is required");
|
||||
if (!data.ContainsKey("startTime")) throw new KeyNotFoundException("startTime is required");
|
||||
if (!data.ContainsKey("endTime")) throw new KeyNotFoundException("endTime is required");
|
||||
|
||||
var facilityId = Guid.Parse(data["facilityId"].GetString()!);
|
||||
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(httpContext));
|
||||
|
||||
var facility = await _facilityRepository.GetFacilityById(facilityId);
|
||||
if (facility == null || facility.FKClientId != clientId)
|
||||
throw new KeyNotFoundException("Facility not found");
|
||||
|
||||
var startTime = DateTime.Parse(data["startTime"].GetString()!).ToUniversalTime();
|
||||
var endTime = DateTime.Parse(data["endTime"].GetString()!).ToUniversalTime();
|
||||
if (endTime <= startTime)
|
||||
throw new ArgumentException("endTime must be after startTime");
|
||||
|
||||
int? capacity = data.ContainsKey("capacity") && data["capacity"].ValueKind != JsonValueKind.Null
|
||||
? data["capacity"].GetInt32()
|
||||
: null;
|
||||
if (capacity.HasValue && capacity.Value < 1)
|
||||
throw new ArgumentException("capacity must be at least 1 when set");
|
||||
|
||||
var session = new FacilitySession
|
||||
{
|
||||
FKFacilityId = facilityId,
|
||||
FKClientId = clientId,
|
||||
StartTime = startTime,
|
||||
EndTime = endTime,
|
||||
Capacity = capacity
|
||||
};
|
||||
|
||||
var result = await _facilityRepository.CreateFacilitySession(session);
|
||||
await _uow.CommitAsync();
|
||||
|
||||
return MapToDto(result, facility.Name, 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await _uow.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<object> GetSessions(object payload, HttpContext httpContext)
|
||||
{
|
||||
var data = DeserializePayload.Deserialize(payload);
|
||||
|
||||
Guid? facilityId = data.ContainsKey("facilityId") && data["facilityId"].ValueKind != JsonValueKind.Null
|
||||
? Guid.Parse(data["facilityId"].GetString()!)
|
||||
: null;
|
||||
|
||||
var fromUtc = data.ContainsKey("fromDate") && data["fromDate"].ValueKind != JsonValueKind.Null
|
||||
? DateTime.Parse(data["fromDate"].GetString()!).ToUniversalTime()
|
||||
: DateTime.UtcNow.Date;
|
||||
var toUtc = data.ContainsKey("toDate") && data["toDate"].ValueKind != JsonValueKind.Null
|
||||
? DateTime.Parse(data["toDate"].GetString()!).ToUniversalTime()
|
||||
: fromUtc.AddDays(7);
|
||||
|
||||
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(httpContext));
|
||||
var sessions = await _facilityRepository.GetSessions(clientId, facilityId, fromUtc, toUtc);
|
||||
|
||||
var result = new List<FacilitySessionDto>();
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
var bookedCount = await _facilityRepository.GetActiveBookingCount(session.FacilitySessionId);
|
||||
result.Add(MapToDto(session, session.Facility?.Name, bookedCount));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<object> CancelFacilitySession(object payload, HttpContext httpContext)
|
||||
{
|
||||
await _uow.BeginAsync();
|
||||
try
|
||||
{
|
||||
var data = DeserializePayload.Deserialize(payload);
|
||||
var facilitySessionId = Guid.Parse(data["facilitySessionId"].GetString()!);
|
||||
|
||||
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(httpContext));
|
||||
var session = await _facilityRepository.CancelFacilitySession(facilitySessionId, clientId)
|
||||
?? throw new KeyNotFoundException("Facility session not found");
|
||||
|
||||
await _uow.CommitAsync();
|
||||
return MapToDto(session);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await _uow.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static FacilityDto MapToDto(Facility facility) => new()
|
||||
{
|
||||
FacilityId = facility.FacilityId,
|
||||
Name = facility.Name,
|
||||
FacilityType = facility.FacilityType,
|
||||
Description = facility.Description,
|
||||
DefaultCapacity = facility.DefaultCapacity,
|
||||
IsActive = facility.IsActive,
|
||||
CreatedAt = facility.CreatedAt
|
||||
};
|
||||
|
||||
private static FacilitySessionDto MapToDto(FacilitySession session, string? facilityName = null, int bookedCount = 0) => new()
|
||||
{
|
||||
FacilitySessionId = session.FacilitySessionId,
|
||||
FacilityId = session.FKFacilityId,
|
||||
FacilityName = facilityName ?? session.Facility?.Name,
|
||||
StartTime = session.StartTime,
|
||||
EndTime = session.EndTime,
|
||||
Capacity = session.Capacity ?? session.Facility?.DefaultCapacity ?? 1,
|
||||
BookedCount = bookedCount,
|
||||
IsCancelled = session.IsCancelled
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user