136 lines
6.3 KiB
C#
136 lines
6.3 KiB
C#
using Fitness_core_BE.DTOs.PlatformBilling;
|
|
using Fitness_core_BE.Helpers;
|
|
using Fitness_core_BE.Interfaces.Services;
|
|
using Fitness_core_BE.Models.IOs;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using static Fitness_core_BE.Helpers.JwtMiddleware;
|
|
using static Fitness_core_BE.Helpers.ApiResponseHelper;
|
|
|
|
namespace Fitness_core_BE.Controllers
|
|
{
|
|
// The gym owner's own HexaFitness platform subscription bill — distinct from
|
|
// CustomerPaymentsController, which handles invoices billed to gym members.
|
|
[ApiController]
|
|
[Route("api/client")]
|
|
public class ClientInvoiceController : ControllerBase
|
|
{
|
|
private readonly IClientInvoiceService _clientInvoiceService;
|
|
private readonly IPaymentService _paymentService;
|
|
private readonly IReceiptService _receiptService;
|
|
private readonly IClientPaymentMethodService _clientPaymentMethodService;
|
|
private readonly UserRoleHelper _userRoleHelper;
|
|
|
|
public ClientInvoiceController(
|
|
IClientInvoiceService clientInvoiceService,
|
|
IPaymentService paymentService,
|
|
IReceiptService receiptService,
|
|
IClientPaymentMethodService clientPaymentMethodService,
|
|
UserRoleHelper userRoleHelper)
|
|
{
|
|
_clientInvoiceService = clientInvoiceService;
|
|
_paymentService = paymentService;
|
|
_receiptService = receiptService;
|
|
_clientPaymentMethodService = clientPaymentMethodService;
|
|
_userRoleHelper = userRoleHelper;
|
|
}
|
|
|
|
[CustomMiddleware]
|
|
[TenantResolution]
|
|
[RequiresPermission("billing")]
|
|
[HttpGet("customer-invoices")]
|
|
public async Task<ActionResult<ApiResponse<object>>> GetCustomerInvoices()
|
|
{
|
|
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(HttpContext));
|
|
return Response(await _clientInvoiceService.GetClientInvoicesByClientId(new { clientId }, HttpContext));
|
|
}
|
|
|
|
[CustomMiddleware]
|
|
[TenantResolution]
|
|
[RequiresPermission("billing")]
|
|
[HttpGet("customer-invoices/{id:guid}")]
|
|
public async Task<ActionResult<ApiResponse<object>>> GetCustomerInvoice(Guid id)
|
|
=> Response(await _clientInvoiceService.GetClientInvoiceById(new { clientInvoiceId = id }, HttpContext));
|
|
|
|
// Pay this gym's own HexaFitness platform invoice. Records a pending payment
|
|
// attempt (an admin approves it, which flips the invoice to Paid and issues a receipt).
|
|
[CustomMiddleware]
|
|
[TenantResolution]
|
|
[RequiresPermission("billing")]
|
|
[HttpPost("customer-invoices/{id:guid}/pay")]
|
|
public async Task<ActionResult<ApiResponse<object>>> PayCustomerInvoice(Guid id, [FromBody] PayPlatformInvoiceRequest request)
|
|
=> Response(await _paymentService.CreateClientPayment(new
|
|
{
|
|
clientInvoiceId = id,
|
|
payAmount = request.PayAmount,
|
|
cardId = request.CardId,
|
|
payNote = request.PayNote
|
|
}, HttpContext));
|
|
|
|
// Branded receipt PDF for a platform invoice (download), once paid.
|
|
[CustomMiddleware]
|
|
[TenantResolution]
|
|
[RequiresPermission("billing")]
|
|
[HttpGet("customer-invoices/{id:guid}/receipt.pdf")]
|
|
public async Task<IActionResult> DownloadPlatformInvoiceReceipt(Guid id)
|
|
{
|
|
var clientId = await _userRoleHelper.GetClientId(DataExtractor.GetUserIdFromContext(HttpContext));
|
|
var model = await _receiptService.BuildForClientInvoiceAsync(id, requireClientId: clientId);
|
|
var pdf = _receiptService.GeneratePdf(model);
|
|
return File(pdf, "application/pdf", $"{model.ReceiptNo}.pdf");
|
|
}
|
|
|
|
// The gym's own saved card(s) for paying their HexaFitness platform subscription
|
|
// (real Payment-Service-backed flow — distinct from the manual PayCustomerInvoice
|
|
// above, which just records a pending payment for an admin to approve).
|
|
|
|
[CustomMiddleware]
|
|
[RequiresPermission("billing")]
|
|
[HttpPost("customer-invoices/cards/onboard")]
|
|
public async Task<ActionResult<ApiResponse<StartCardOnboardingResult>>> StartCardOnboarding(
|
|
[FromBody] StartCardOnboardingRequest request)
|
|
=> Response(await _clientPaymentMethodService.StartCardOnboardingAsync(HttpContext, request));
|
|
|
|
[CustomMiddleware]
|
|
[RequiresPermission("billing")]
|
|
[HttpGet("customer-invoices/cards/onboard/complete")]
|
|
public async Task<ActionResult<ApiResponse<CardOnboardingStatusResult>>> CompleteCardOnboarding([FromQuery] string sessionId)
|
|
=> Response(await _clientPaymentMethodService.CompleteCardOnboardingAsync(HttpContext, sessionId));
|
|
|
|
[CustomMiddleware]
|
|
[RequiresPermission("billing")]
|
|
[HttpGet("customer-invoices/cards")]
|
|
public async Task<ActionResult<ApiResponse<List<ClientCardDto>>>> ListCards()
|
|
=> Response(await _clientPaymentMethodService.ListCardsAsync(HttpContext));
|
|
|
|
[CustomMiddleware]
|
|
[RequiresPermission("billing")]
|
|
[HttpDelete("customer-invoices/cards/{cardToken}")]
|
|
public async Task<ActionResult<ApiResponse<object>>> RemoveCard(string cardToken)
|
|
{
|
|
await _clientPaymentMethodService.RemoveCardAsync(HttpContext, cardToken);
|
|
return Response<object>(new { removed = true });
|
|
}
|
|
|
|
[CustomMiddleware]
|
|
[RequiresPermission("billing")]
|
|
[HttpPatch("customer-invoices/cards/{cardToken}/default")]
|
|
public async Task<ActionResult<ApiResponse<ClientCardDto>>> SetDefaultCard(string cardToken)
|
|
=> Response(await _clientPaymentMethodService.SetDefaultCardAsync(HttpContext, cardToken));
|
|
|
|
[CustomMiddleware]
|
|
[RequiresPermission("billing")]
|
|
[HttpGet("customer-invoices/transactions")]
|
|
public async Task<ActionResult<ApiResponse<TransactionHistoryResult>>> GetTransactionHistory(
|
|
[FromQuery] int page = 1,
|
|
[FromQuery] int pageSize = 20)
|
|
=> Response(await _clientPaymentMethodService.GetTransactionHistoryAsync(HttpContext, page, pageSize));
|
|
|
|
public class PayPlatformInvoiceRequest
|
|
{
|
|
public decimal PayAmount { get; set; }
|
|
public string? CardId { get; set; }
|
|
public string? PayNote { get; set; }
|
|
}
|
|
}
|
|
}
|