feat: Implemento completamente el POST de facturas , usando un objeto anonimo para la request, y devuelvo el id creado.

This commit is contained in:
javiermengual 2026-01-02 19:01:04 +01:00
parent daded56582
commit 1fd331ac17
4 changed files with 52 additions and 0 deletions

View File

@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using DoliMiddlewareApi.Dtos; using DoliMiddlewareApi.Dtos;
using DoliMiddlewareApi.Dtos.command;
using DoliMiddlewareApi.Services; using DoliMiddlewareApi.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -39,4 +40,14 @@ public class InvoicesController : ControllerBase
var invoice = await _invoiceService.GetInvoiceAsync(id); var invoice = await _invoiceService.GetInvoiceAsync(id);
return Ok(invoice); return Ok(invoice);
} }
[HttpPost]
[ProducesResponseType(typeof(int), StatusCodes.Status201Created)] // Devuelve el ID creado
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<int>> CreateInvoice([FromBody] CreateInvoiceDto createInvoiceDto)
{
var invoiceId= await _invoiceService.CreateInvoiceAsync(createInvoiceDto);
return CreatedAtAction(nameof(GetInvoice), new { id = invoiceId }, invoiceId);
}
} }

View File

@ -18,6 +18,8 @@ public class CreateInvoiceDto
public string? NotePublic { get; set; } public string? NotePublic { get; set; }
public string? NotePrivate { get; set; } public string? NotePrivate { get; set; }
public string Status { get; set; } = "draft";
[Required] [Required]
[MinLength(1)] [MinLength(1)]
public List<CreateInvoiceLineDto> Lines { get; set; } = new(); public List<CreateInvoiceLineDto> Lines { get; set; } = new();

View File

@ -33,6 +33,15 @@ public class DolibarrApiClient
$"Failed to deserialize list response from Dolibarr for endpoint '{endpoint}'"); $"Failed to deserialize list response from Dolibarr for endpoint '{endpoint}'");
} }
public async Task<string> PostAsync(string endpoint, object requestBody)
{
var response = await _httpClient.PostAsJsonAsync(endpoint, requestBody);
await EnsureSuccessOrThrowAsync(response, endpoint);
// porque devuelve el id como response
return await response.Content.ReadAsStringAsync();
}

View File

@ -1,4 +1,6 @@
using System.Globalization;
using DoliMiddlewareApi.Dtos; using DoliMiddlewareApi.Dtos;
using DoliMiddlewareApi.Dtos.command;
using DoliMiddlewareApi.Dtos.Dolibarr; using DoliMiddlewareApi.Dtos.Dolibarr;
using DoliMiddlewareApi.Mappers; using DoliMiddlewareApi.Mappers;
using DoliMiddlewareApi.Services.Clients; using DoliMiddlewareApi.Services.Clients;
@ -36,4 +38,32 @@ public class InvoiceService
var dataList = await _apiClient.GetCollectionAsync<InvoiceResponse>(endpoint); var dataList = await _apiClient.GetCollectionAsync<InvoiceResponse>(endpoint);
return dataList.Select(InvoiceMapper.MapToInvoiceDto).ToList(); return dataList.Select(InvoiceMapper.MapToInvoiceDto).ToList();
} }
public async Task<int> CreateInvoiceAsync(CreateInvoiceDto dto)
{
var requestBody = new
{
socid = dto.ClientId.ToString(),
type = "0",
statut = dto.Status == "unpaid" ? "1" : "0",
date = ((DateTimeOffset)dto.Date).ToUnixTimeSeconds().ToString(),
date_lim_reglement = dto.ExpireDate.HasValue
? ((DateTimeOffset)dto.ExpireDate.Value).ToUnixTimeSeconds().ToString()
: null,
@ref = dto.Reference,
note_public = dto.NotePublic,
note_private = dto.NotePrivate,
lines = dto.Lines.Select(line => new
{
desc = line.Description,
qty = line.Quantity.ToString(CultureInfo.InvariantCulture),
subprice = line.UnitPrice.ToString(CultureInfo.InvariantCulture),
tva_tx = line.TaxRate.ToString(CultureInfo.InvariantCulture)
}).ToArray()
};
var responseBody = await _apiClient.PostAsync("invoices", requestBody);
return int.Parse(responseBody);
}
} }