From c1c7d4bb374f13827bbe4530af51a45dcdca48d3 Mon Sep 17 00:00:00 2001 From: javiermengual Date: Tue, 3 Feb 2026 16:42:32 +0100 Subject: [PATCH] =?UTF-8?q?a=C3=B1ado=20endpoint=20para=20validar=20factur?= =?UTF-8?q?a=20y=20campo=20de=20notas=20publicas=20y=20privadas=20en=20los?= =?UTF-8?q?=20Dtos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/InvoicesController.cs | 12 +++++++ .../Dtos/query/InvoiceDetailDto.cs | 2 ++ DoliMiddlewareApi/Dtos/query/InvoiceDto.cs | 2 ++ DoliMiddlewareApi/Mappers/InvoiceMapper.cs | 7 ++-- DoliMiddlewareApi/Services/InvoiceService.cs | 8 +++++ generate-openapi.sh | 33 ------------------- 6 files changed, 29 insertions(+), 35 deletions(-) delete mode 100755 generate-openapi.sh diff --git a/DoliMiddlewareApi/Controllers/InvoicesController.cs b/DoliMiddlewareApi/Controllers/InvoicesController.cs index e14e518..162f147 100644 --- a/DoliMiddlewareApi/Controllers/InvoicesController.cs +++ b/DoliMiddlewareApi/Controllers/InvoicesController.cs @@ -84,4 +84,16 @@ public class InvoicesController(InvoiceService invoiceService) : ControllerBase await invoiceService.ChangeInvoiceStatusAsync(id, updateStatusDto.Status); return NoContent(); } + + [HttpPost("{id:int}/validate")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status403Forbidden)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] + [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)] + public async Task ValidateInvoice([Range(1, int.MaxValue)] int id) + { + await invoiceService.ValidateInvoiceAsync(id); + return NoContent(); + } } diff --git a/DoliMiddlewareApi/Dtos/query/InvoiceDetailDto.cs b/DoliMiddlewareApi/Dtos/query/InvoiceDetailDto.cs index a518ed2..12a5cee 100644 --- a/DoliMiddlewareApi/Dtos/query/InvoiceDetailDto.cs +++ b/DoliMiddlewareApi/Dtos/query/InvoiceDetailDto.cs @@ -11,4 +11,6 @@ public class InvoiceDetailDto public decimal? RemainToPay { get; set; } public string Status { get; set; } public List? Lines { get; set; } + public string? note_public { get; set; } + public string? note_private { get; set; } } \ No newline at end of file diff --git a/DoliMiddlewareApi/Dtos/query/InvoiceDto.cs b/DoliMiddlewareApi/Dtos/query/InvoiceDto.cs index 23d4f75..66da608 100644 --- a/DoliMiddlewareApi/Dtos/query/InvoiceDto.cs +++ b/DoliMiddlewareApi/Dtos/query/InvoiceDto.cs @@ -11,4 +11,6 @@ public class InvoiceDto public decimal? RemainToPay { get; set; } public string Status { get; set; } public string? ClientName { get; set; } + public string? note_public { get; set; } + public string? note_private { get; set; } } \ No newline at end of file diff --git a/DoliMiddlewareApi/Mappers/InvoiceMapper.cs b/DoliMiddlewareApi/Mappers/InvoiceMapper.cs index 67b4547..848a7c7 100644 --- a/DoliMiddlewareApi/Mappers/InvoiceMapper.cs +++ b/DoliMiddlewareApi/Mappers/InvoiceMapper.cs @@ -34,13 +34,14 @@ public static class InvoiceMapper ? Math.Round(remain, 2) : null, - Status = ConvertStatusToWord(invoiceResponse.statut) + Status = ConvertStatusToWord(invoiceResponse.statut), + note_public = invoiceResponse.note_public, + note_private = invoiceResponse.note_private }; } public static InvoiceDetailDto MapToInvoiceDetailDto(InvoiceDetailResponse data) { - // Mapear campos base de la factura var baseDto = MapToInvoiceDto(data); return new InvoiceDetailDto @@ -53,6 +54,8 @@ public static class InvoiceMapper Total = baseDto.Total, RemainToPay = baseDto.RemainToPay, Status = baseDto.Status, + note_public = baseDto.note_public, + note_private = baseDto.note_private, Lines = data.Lines?.Select(MapToInvoiceLineDto).ToList() ?? new List() }; diff --git a/DoliMiddlewareApi/Services/InvoiceService.cs b/DoliMiddlewareApi/Services/InvoiceService.cs index 854f3dc..79a4211 100644 --- a/DoliMiddlewareApi/Services/InvoiceService.cs +++ b/DoliMiddlewareApi/Services/InvoiceService.cs @@ -130,6 +130,14 @@ public class InvoiceService(IDolibarrApiClient apiClient) await apiClient.PostAsync(endpoint, new { }); } + public async Task ValidateInvoiceAsync(int id) + { + var invoice = await apiClient.GetResourceAsync($"invoices/{id}"); + if (invoice.statut != "0") throw new ForbiddenException("Solo se pueden validar facturas en borrador (draft)"); + + await apiClient.PostAsync($"invoices/{id}/validate", new { }); + } + private async Task> GetClientNamesAsync(List clientIds) { var uniqueIds = clientIds.Distinct().ToList(); diff --git a/generate-openapi.sh b/generate-openapi.sh deleted file mode 100755 index 0188534..0000000 --- a/generate-openapi.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -set -e - -echo "🚀 Generando openapi.json..." - -# Variables -PORT=5123 -PROJECT_DIR="DoliMiddlewareApi" -OUTPUT_FILE="openapi.json" - -# Levantar la API en background -cd "$PROJECT_DIR" -dotnet run --urls "http://localhost:$PORT" > /dev/null 2>&1 & -PID=$! - -# Esperar a que arranque -echo "⏳ Esperando a que la API arranque..." -sleep 8 - -# Descargar el OpenAPI spec -echo "📥 Descargando openapi.json..." -curl -s "http://localhost:$PORT/openapi/v1.json" -o "../$OUTPUT_FILE" - -# Matar el proceso -kill $PID 2>/dev/null || true - -echo "✅ openapi.json generado exitosamente en: $OUTPUT_FILE" -echo "" -echo "📦 Para generar cliente TypeScript:" -echo " npx @openapitools/openapi-generator-cli generate -i openapi.json -g typescript-fetch -o ./client" -echo "" -echo "📦 Para importar en Postman:" -echo " File > Import > Selecciona openapi.json"