añado endpoint para validar factura y campo de notas publicas y privadas en los Dtos

This commit is contained in:
javiermengual 2026-02-03 16:42:32 +01:00
parent 7e7a4f48fa
commit c1c7d4bb37
6 changed files with 29 additions and 35 deletions

View File

@ -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<IActionResult> ValidateInvoice([Range(1, int.MaxValue)] int id)
{
await invoiceService.ValidateInvoiceAsync(id);
return NoContent();
}
}

View File

@ -11,4 +11,6 @@ public class InvoiceDetailDto
public decimal? RemainToPay { get; set; }
public string Status { get; set; }
public List<InvoiceLineDto>? Lines { get; set; }
public string? note_public { get; set; }
public string? note_private { get; set; }
}

View File

@ -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; }
}

View File

@ -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<InvoiceLineDto>()
};

View File

@ -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<InvoiceDetailResponse>($"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<Dictionary<int, string>> GetClientNamesAsync(List<int> clientIds)
{
var uniqueIds = clientIds.Distinct().ToList();

View File

@ -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"