refactor: sacar los metodos de cada DTO a su propio servicio porque si no se me hara un god object , y lo mantendre simple sin mucha abstraccion.

This commit is contained in:
javiermengual 2025-12-31 15:15:00 +01:00
parent 1a752c007f
commit ab80901280
4 changed files with 68 additions and 38 deletions

View File

@ -9,11 +9,11 @@ namespace DoliMiddlewareApi.Controllers;
[Route("api/[controller]")] [Route("api/[controller]")]
public class InvoicesController : ControllerBase public class InvoicesController : ControllerBase
{ {
private readonly DolibarrApiClient _dolibarrClient; private readonly InvoiceService _invoiceService;
public InvoicesController(DolibarrApiClient dolibarrClient) public InvoicesController(InvoiceService invoiceService)
{ {
_dolibarrClient = dolibarrClient; _invoiceService = invoiceService;
} }
[HttpGet] [HttpGet]
@ -24,7 +24,7 @@ public class InvoicesController : ControllerBase
[FromQuery] [Range(1, int.MaxValue)] int page = 1, [FromQuery] [Range(1, int.MaxValue)] int page = 1,
[FromQuery] string? status = null) [FromQuery] string? status = null)
{ {
var invoices = await _dolibarrClient.GetInvoicesAsync(limit, page, status); var invoices = await _invoiceService.GetInvoicesAsync(limit, page, status);
return Ok(invoices); return Ok(invoices);
} }
@ -34,7 +34,7 @@ public class InvoicesController : ControllerBase
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<InvoiceDetailDto>> GetInvoice(int id) public async Task<ActionResult<InvoiceDetailDto>> GetInvoice(int id)
{ {
var invoice = await _dolibarrClient.GetInvoiceAsync(id); var invoice = await _invoiceService.GetInvoiceAsync(id);
return Ok(invoice); return Ok(invoice);
} }
} }

View File

@ -1,5 +1,6 @@
using DoliMiddlewareApi.Exceptions; using DoliMiddlewareApi.Exceptions;
using DoliMiddlewareApi.Services; using DoliMiddlewareApi.Services;
using DoliMiddlewareApi.Services.Clients;
using Microsoft.AspNetCore.Diagnostics; using Microsoft.AspNetCore.Diagnostics;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
@ -27,6 +28,9 @@ builder.Services.AddHttpClient<DolibarrApiClient>(client =>
client.DefaultRequestHeaders.Add("DOLAPIKEY", builder.Configuration["Dolibarr:ApiKey"]!); client.DefaultRequestHeaders.Add("DOLAPIKEY", builder.Configuration["Dolibarr:ApiKey"]!);
}); });
// Registrar servicios de negocio
builder.Services.AddScoped<InvoiceService>();
var app = builder.Build(); var app = builder.Build();
// Global exception handler // Global exception handler

View File

@ -1,12 +1,7 @@
using System.Globalization;
using System.Net; using System.Net;
using System.Net.Http.Json;
using DoliMiddlewareApi.Dtos;
using DoliMiddlewareApi.Dtos.Dolibarr;
using DoliMiddlewareApi.Exceptions; using DoliMiddlewareApi.Exceptions;
using DoliMiddlewareApi.Mappers;
namespace DoliMiddlewareApi.Services; namespace DoliMiddlewareApi.Services.Clients;
public class DolibarrApiClient public class DolibarrApiClient
{ {
@ -16,33 +11,10 @@ public class DolibarrApiClient
{ {
_httpClient = httpClient; _httpClient = httpClient;
} }
// ===== FACTURAS =====
public async Task<InvoiceDetailDto> GetInvoiceAsync(int id)
{
var data = await GetResourceAsync<InvoiceDetailResponse>($"invoices/{id}");
return InvoiceMapper.MapToInvoiceDetailDto(data);
}
public async Task<List<InvoiceDto>> GetInvoicesAsync(
int limit = 50,
int page = 1,
string? status = null)
{
// empieza por 1 para el frontend
var endpoint = $"invoices?limit={limit}&page={page - 1}";
if (!string.IsNullOrEmpty(status))
{
endpoint += $"&status={status}";
}
var dataList = await GetCollectionAsync<InvoiceResponse>(endpoint);
return dataList.Select(InvoiceMapper.MapToInvoiceDto).ToList();
}
// ===== MÉTODOS GENÉRICOS ===== // ===== MÉTODOS GENÉRICOS =====
private async Task<T> GetResourceAsync<T>(string endpoint) where T : class public async Task<T> GetResourceAsync<T>(string endpoint) where T : class
{ {
var response = await _httpClient.GetAsync(endpoint); var response = await _httpClient.GetAsync(endpoint);
await EnsureSuccessOrThrowAsync(response, endpoint); await EnsureSuccessOrThrowAsync(response, endpoint);
@ -51,7 +23,7 @@ public class DolibarrApiClient
?? throw new ApiException($"Failed to deserialize response from Dolibarr for endpoint '{endpoint}'"); ?? throw new ApiException($"Failed to deserialize response from Dolibarr for endpoint '{endpoint}'");
} }
private async Task<List<T>> GetCollectionAsync<T>(string endpoint) where T : class public async Task<List<T>> GetCollectionAsync<T>(string endpoint) where T : class
{ {
var response = await _httpClient.GetAsync(endpoint); var response = await _httpClient.GetAsync(endpoint);
await EnsureSuccessOrThrowAsync(response, endpoint); await EnsureSuccessOrThrowAsync(response, endpoint);
@ -61,6 +33,21 @@ public class DolibarrApiClient
$"Failed to deserialize list response from Dolibarr for endpoint '{endpoint}'"); $"Failed to deserialize list response from Dolibarr for endpoint '{endpoint}'");
} }
private async Task EnsureSuccessOrThrowAsync(HttpResponseMessage response, string endpoint) private async Task EnsureSuccessOrThrowAsync(HttpResponseMessage response, string endpoint)
{ {
if (response.IsSuccessStatusCode) return; if (response.IsSuccessStatusCode) return;

View File

@ -0,0 +1,39 @@
using DoliMiddlewareApi.Dtos;
using DoliMiddlewareApi.Dtos.Dolibarr;
using DoliMiddlewareApi.Mappers;
using DoliMiddlewareApi.Services.Clients;
namespace DoliMiddlewareApi.Services;
public class InvoiceService
{
private readonly DolibarrApiClient _apiClient;
public InvoiceService(DolibarrApiClient apiClient)
{
_apiClient = apiClient;
}
public async Task<InvoiceDetailDto> GetInvoiceAsync(int id)
{
var data = await _apiClient.GetResourceAsync<InvoiceDetailResponse>($"invoices/{id}");
return InvoiceMapper.MapToInvoiceDetailDto(data);
}
public async Task<List<InvoiceDto>> GetInvoicesAsync(
int limit = 50,
int page = 1,
string? status = null)
{
// empieza por 1 para el frontend
var endpoint = $"invoices?limit={limit}&page={page - 1}";
if (!string.IsNullOrEmpty(status))
{
endpoint += $"&status={status}";
}
var dataList = await _apiClient.GetCollectionAsync<InvoiceResponse>(endpoint);
return dataList.Select(InvoiceMapper.MapToInvoiceDto).ToList();
}
}