first commit
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using Fitness_core_BE.Exceptions;
|
||||
using Fitness_core_BE.Helpers;
|
||||
using Fitness_core_BE.Infra.UoW;
|
||||
using Fitness_core_BE.Interfaces;
|
||||
using Fitness_core_BE.DTOs.PaymentsEnablement;
|
||||
using Fitness_core_BE.Interfaces.Services;
|
||||
using Fitness_core_BE.Models.Enums;
|
||||
|
||||
namespace Fitness_core_BE.Services
|
||||
{
|
||||
public class PayoutKycReviewService : IPayoutKycReviewService
|
||||
{
|
||||
private readonly IPaymentsEnablementRepository _paymentsRepository;
|
||||
private readonly UserRoleHelper _userRoleHelper;
|
||||
private readonly IUnitOfWork _uow;
|
||||
|
||||
public PayoutKycReviewService(IPaymentsEnablementRepository paymentsRepository, UserRoleHelper userRoleHelper, IUnitOfWork uow)
|
||||
{
|
||||
_paymentsRepository = paymentsRepository;
|
||||
_userRoleHelper = userRoleHelper;
|
||||
_uow = uow;
|
||||
}
|
||||
|
||||
public async Task<List<ClientPayoutKycDto>> ListAsync(string? status)
|
||||
{
|
||||
var (items, _) = await _paymentsRepository.ListKycAsync(null);
|
||||
var latestPerClient = items
|
||||
.GroupBy(item => item.FKClientId)
|
||||
.Select(group => group
|
||||
.OrderByDescending(item => item.SubmittedAt)
|
||||
.ThenByDescending(item => item.Id)
|
||||
.First());
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status))
|
||||
{
|
||||
if (!Enum.TryParse<KycStatus>(status, true, out var parsedStatus))
|
||||
throw new BadRequestException($"Unknown KYC status '{status}'.");
|
||||
latestPerClient = latestPerClient
|
||||
.Where(item => item.KycStatus == parsedStatus);
|
||||
}
|
||||
|
||||
return latestPerClient
|
||||
.OrderByDescending(item => item.SubmittedAt)
|
||||
.Select(ToDto)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async Task<ClientPayoutKycDto> GetByClientIdAsync(Guid clientId)
|
||||
{
|
||||
var kyc = await _paymentsRepository.GetKycByClientIdAsync(clientId)
|
||||
?? throw new NotFoundException("No KYC submission found for this client.");
|
||||
return ToDto(kyc);
|
||||
}
|
||||
|
||||
public async Task<ClientPayoutKycDto> ReviewAsync(Guid clientId, ReviewPayoutKycRequest request, HttpContext httpContext)
|
||||
{
|
||||
var kyc = await _paymentsRepository.GetKycForUpdateAsync(clientId)
|
||||
?? throw new NotFoundException("No KYC submission found for this client.");
|
||||
|
||||
if (!Enum.TryParse<KycStatus>(request.Status, true, out var newStatus))
|
||||
throw new BadRequestException($"Unknown KYC status '{request.Status}'.");
|
||||
if (newStatus is not KycStatus.Approved and not KycStatus.Rejected)
|
||||
throw new BadRequestException("KYC can only be approved or rejected.");
|
||||
if (kyc.KycStatus != KycStatus.Pending)
|
||||
throw new BadRequestException("Only pending KYC submissions can be reviewed.");
|
||||
if (newStatus == KycStatus.Rejected && string.IsNullOrWhiteSpace(request.Reason))
|
||||
throw new BadRequestException("A rejection reason is required.");
|
||||
|
||||
var adminUserId = DataExtractor.GetUserIdFromContext(httpContext);
|
||||
var adminId = await _userRoleHelper.GetAdminId(adminUserId)
|
||||
?? throw new ForbiddenException("Only admins may review payout KYC.");
|
||||
|
||||
await _uow.BeginAsync();
|
||||
try
|
||||
{
|
||||
kyc.KycStatus = newStatus;
|
||||
kyc.ReviewedAt = DateTime.UtcNow;
|
||||
kyc.ReviewedByAdminId = adminId;
|
||||
kyc.RejectionReason = newStatus == KycStatus.Rejected
|
||||
? request.Reason!.Trim()
|
||||
: null;
|
||||
|
||||
await _uow.CommitAsync();
|
||||
return ToDto(kyc);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await _uow.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// NIC fields used to come from the multi-gym onboarding wizard's OwnerActivation record
|
||||
// (collected during signup); that flow no longer exists for a single already-real club,
|
||||
// so these are always null here now. If gateway KYC needs NIC info going forward, collect
|
||||
// it directly on the KYC submission instead of reintroducing that dependency.
|
||||
private static ClientPayoutKycDto ToDto(Models.ClientPayoutKyc kyc)
|
||||
{
|
||||
return new ClientPayoutKycDto(
|
||||
kyc.Id,
|
||||
kyc.FKClientId,
|
||||
kyc.Client?.ClientName,
|
||||
kyc.SelectedGatewayId,
|
||||
kyc.SelectedGatewayName,
|
||||
kyc.KycStatus.ToString(),
|
||||
kyc.SubmittedAt,
|
||||
kyc.ReviewedAt,
|
||||
kyc.RejectionReason,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user