95 lines
4.1 KiB
C#
95 lines
4.1 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
|
|
{
|
|
// Platform billing (HexaFitness -> gym): pricing configuration and invoicing.
|
|
// The gym-owner side of this same concern lives in ClientInvoiceController.
|
|
[ApiController]
|
|
[Route("api/admin")]
|
|
[CustomMiddleware]
|
|
[TenantResolution]
|
|
public class AdminBillingController : ControllerBase
|
|
{
|
|
private readonly IPlatformBillingService _platformBilling;
|
|
|
|
public AdminBillingController(IPlatformBillingService platformBilling)
|
|
{
|
|
_platformBilling = platformBilling;
|
|
}
|
|
|
|
[HttpGet("pricing-plans")]
|
|
public async Task<ActionResult<ApiResponse<List<PricingPlanDto>>>> ListPricingPlans()
|
|
{
|
|
return Response(await _platformBilling.GetPricingPlansAsync(HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpPut("pricing-plans")]
|
|
public async Task<ActionResult<ApiResponse<PricingPlanDto>>> UpsertPricingPlan([FromBody] UpsertPricingPlanRequest request)
|
|
{
|
|
return Response(await _platformBilling.UpsertPricingPlanAsync(request, HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpGet("device-pricing")]
|
|
public async Task<ActionResult<ApiResponse<DevicePricingDto>>> GetDevicePricing()
|
|
{
|
|
return Response(await _platformBilling.GetDevicePricingAsync(HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpPut("device-pricing")]
|
|
public async Task<ActionResult<ApiResponse<DevicePricingDto>>> UpdateDevicePricing([FromBody] DevicePricingDto request)
|
|
{
|
|
return Response(await _platformBilling.UpdateDevicePricingAsync(request, HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpPost("clients/{id:guid}/pricing-plan")]
|
|
public async Task<ActionResult<ApiResponse<object>>> AssignPricingPlan(Guid id, [FromBody] AssignPricingPlanRequest request)
|
|
{
|
|
var invoice = await _platformBilling.AssignPricingPlanAsync(id, request, HttpContext.RequestAborted);
|
|
return Response<object>(new { assigned = true, clientInvoiceId = invoice.ClientInvoiceId, amount = invoice.Amount });
|
|
}
|
|
|
|
[HttpGet("clients/{id:guid}/platform-fee")]
|
|
public async Task<ActionResult<ApiResponse<PlatformFeeBreakdownDto>>> GetPlatformFee(Guid id)
|
|
{
|
|
return Response(await _platformBilling.ComputeMonthlyFeeAsync(id, HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpGet("invoices/pending")]
|
|
public async Task<ActionResult<ApiResponse<List<PendingPlatformInvoiceDto>>>> ListPendingInvoices()
|
|
{
|
|
return Response(await _platformBilling.GetPendingInvoicesAsync(HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpGet("invoices/completed")]
|
|
public async Task<ActionResult<ApiResponse<List<PendingPlatformInvoiceDto>>>> ListCompletedInvoices()
|
|
{
|
|
return Response(await _platformBilling.GetCompletedInvoicesAsync(HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpPost("invoices/{id:guid}/payments")]
|
|
public async Task<ActionResult<ApiResponse<PendingPlatformInvoiceDto>>> RecordInvoicePayment(Guid id, [FromBody] RecordClientInvoicePaymentRequest request)
|
|
{
|
|
return Response(await _platformBilling.RecordClientInvoicePaymentAsync(id, request.Amount, HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpPost("invoices/{id:guid}/send-payment-link")]
|
|
public async Task<ActionResult<ApiResponse<object>>> SendInvoicePaymentLink(Guid id)
|
|
{
|
|
return Response(await _platformBilling.SendClientPaymentLinkAsync(id, HttpContext.RequestAborted));
|
|
}
|
|
|
|
[HttpPost("billing/run-monthly")]
|
|
public async Task<ActionResult<ApiResponse<object>>> RunMonthlyBilling()
|
|
{
|
|
var invoices = await _platformBilling.RunMonthlyBillingForAllClientsAsync(HttpContext.RequestAborted);
|
|
return Response<object>(new { generated = invoices.Count });
|
|
}
|
|
}
|
|
}
|