refactor: Saco los mappers a una clase estatica, si el projecto creciera mucho podriamos usar AutoMapper

This commit is contained in:
javiermengual 2025-12-29 19:32:38 +01:00
parent 1d7182145e
commit 7018efe279
2 changed files with 99 additions and 81 deletions

View File

@ -0,0 +1,96 @@
using System.Globalization;
using DoliMiddlewareApi.Dtos;
using DoliMiddlewareApi.Dtos.Dolibarr;
namespace DoliMiddlewareApi.Mappers;
public static class InvoiceMapper
{
// ===== MAPPER =====
public static InvoiceDto MapToInvoiceDto(InvoiceResponse invoiceResponse)
{
return new InvoiceDto
{
Id = int.TryParse(invoiceResponse.id, out int id) ? id : 0,
Number = invoiceResponse.@ref ?? "SIN-REF",
Date = invoiceResponse.date.HasValue
? DateTimeOffset.FromUnixTimeSeconds(invoiceResponse.date.Value).DateTime
: null,
ExpireDate = invoiceResponse.date_lim_reglement.HasValue
? DateTimeOffset.FromUnixTimeSeconds(invoiceResponse.date_lim_reglement.Value).DateTime
: null,
ClientId = int.TryParse(invoiceResponse.socid, out int clientId) ? clientId : 0,
Total = decimal.TryParse(invoiceResponse.total_ttc, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal total)
? Math.Round(total, 2)
: null,
RemainToPay = decimal.TryParse(invoiceResponse.remaintopay, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal remain)
? Math.Round(remain, 2)
: null,
Status = ConvertStatusToWord(invoiceResponse.statut)
};
}
public static InvoiceDetailDto MapToInvoiceDetailDto(InvoiceDetailResponse data)
{
// Mapear campos base de la factura
var baseDto = MapToInvoiceDto(data);
return new InvoiceDetailDto
{
Id = baseDto.Id,
Number = baseDto.Number,
Date = baseDto.Date,
ExpireDate = baseDto.ExpireDate,
ClientId = baseDto.ClientId,
Total = baseDto.Total,
RemainToPay = baseDto.RemainToPay,
Status = baseDto.Status,
Lines = data.Lines?.Select(MapToInvoiceLineDto).ToList() ?? new List<InvoiceLineDto>()
};
}
public static InvoiceLineDto MapToInvoiceLineDto(InvoiceLineResponse lineResponse)
{
return new InvoiceLineDto
{
Id = int.TryParse(lineResponse.id, out int id) ? id : 0,
Description = lineResponse.description ?? lineResponse.desc ?? "",
Quantity = decimal.TryParse(lineResponse.qty, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal qty)
? qty
: 0,
UnitPrice = decimal.TryParse(lineResponse.subprice, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal price)
? Math.Round(price, 2)
: 0,
TaxRate = decimal.TryParse(lineResponse.tva_tx, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal tax)
? Math.Round(tax, 2)
: 0,
Total = decimal.TryParse(lineResponse.total_ttc, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal total)
? Math.Round(total, 2)
: 0
};
}
private static string ConvertStatusToWord(string? statusNumber)
{
return statusNumber switch
{
"0" => "draft",
"1" => "unpaid",
"2" => "paid",
"3" => "cancelled",
_ => "unknown"
};
}
}

View File

@ -4,6 +4,7 @@ using System.Net.Http.Json;
using DoliMiddlewareApi.Dtos; using DoliMiddlewareApi.Dtos;
using DoliMiddlewareApi.Dtos.Dolibarr; using DoliMiddlewareApi.Dtos.Dolibarr;
using DoliMiddlewareApi.Exceptions; using DoliMiddlewareApi.Exceptions;
using DoliMiddlewareApi.Mappers;
namespace DoliMiddlewareApi.Services; namespace DoliMiddlewareApi.Services;
@ -20,7 +21,7 @@ public class DolibarrApiClient
public async Task<InvoiceDetailDto> GetInvoiceAsync(int id) public async Task<InvoiceDetailDto> GetInvoiceAsync(int id)
{ {
var data = await GetAsync<InvoiceDetailResponse>($"invoices/{id}"); var data = await GetAsync<InvoiceDetailResponse>($"invoices/{id}");
return MapToInvoiceDetailDto(data); return InvoiceMapper.MapToInvoiceDetailDto(data);
} }
public async Task<List<InvoiceDto>> GetInvoicesAsync( public async Task<List<InvoiceDto>> GetInvoicesAsync(
@ -37,88 +38,9 @@ public class DolibarrApiClient
} }
var dataList = await GetListAsync<InvoiceResponse>(endpoint); var dataList = await GetListAsync<InvoiceResponse>(endpoint);
return dataList.Select(MapToInvoiceDto).ToList(); return dataList.Select(InvoiceMapper.MapToInvoiceDto).ToList();
}
// ===== MAPPER =====
private InvoiceDto MapToInvoiceDto(InvoiceResponse invoiceResponse)
{
return new InvoiceDto
{
Id = int.TryParse(invoiceResponse.id, out int id) ? id : 0,
Number = invoiceResponse.@ref ?? "SIN-REF",
Date = invoiceResponse.date.HasValue
? DateTimeOffset.FromUnixTimeSeconds(invoiceResponse.date.Value).DateTime
: null,
ExpireDate = invoiceResponse.date_lim_reglement.HasValue
? DateTimeOffset.FromUnixTimeSeconds(invoiceResponse.date_lim_reglement.Value).DateTime
: null,
ClientId = int.TryParse(invoiceResponse.socid, out int clientId) ? clientId : 0,
Total = decimal.TryParse(invoiceResponse.total_ttc, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal total)
? Math.Round(total, 2)
: null,
RemainToPay = decimal.TryParse(invoiceResponse.remaintopay, NumberStyles.Any, CultureInfo.InvariantCulture,
out decimal remain)
? Math.Round(remain, 2)
: null,
Status = ConvertStatusToWord(invoiceResponse.statut)
};
}
private InvoiceDetailDto MapToInvoiceDetailDto(InvoiceDetailResponse data)
{
// Mapear campos base de la factura
var baseDto = MapToInvoiceDto(data);
return new InvoiceDetailDto
{
Id = baseDto.Id,
Number = baseDto.Number,
Date = baseDto.Date,
ExpireDate = baseDto.ExpireDate,
ClientId = baseDto.ClientId,
Total = baseDto.Total,
RemainToPay = baseDto.RemainToPay,
Status = baseDto.Status,
Lines = data.Lines?.Select(MapToInvoiceLineDto).ToList() ?? new List<InvoiceLineDto>()
};
}
private InvoiceLineDto MapToInvoiceLineDto(InvoiceLineResponse lineResponse)
{
return new InvoiceLineDto
{
Id = int.TryParse(lineResponse.id, out int id) ? id : 0,
Description = lineResponse.description ?? lineResponse.desc ?? "",
Quantity = decimal.TryParse(lineResponse.qty, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal qty)
? qty : 0,
UnitPrice = decimal.TryParse(lineResponse.subprice, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal price)
? Math.Round(price, 2) : 0,
TaxRate = decimal.TryParse(lineResponse.tva_tx, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal tax)
? Math.Round(tax, 2) : 0,
Total = decimal.TryParse(lineResponse.total_ttc, NumberStyles.Any, CultureInfo.InvariantCulture, out decimal total)
? Math.Round(total, 2) : 0
};
} }
private static string ConvertStatusToWord(string? statusNumber)
{
return statusNumber switch
{
"0" => "draft",
"1" => "unpaid",
"2" => "paid",
"3" => "cancelled",
_ => "unknown"
};
}
// ===== MÉTODOS GENÉRICOS ===== // ===== MÉTODOS GENÉRICOS =====
private async Task<T> GetAsync<T>(string endpoint) where T : class private async Task<T> GetAsync<T>(string endpoint) where T : class
{ {