diff --git a/DoliMiddlewareApi/Controllers/InvoicesController.cs b/DoliMiddlewareApi/Controllers/InvoicesController.cs index b99cc86..51de1f6 100644 --- a/DoliMiddlewareApi/Controllers/InvoicesController.cs +++ b/DoliMiddlewareApi/Controllers/InvoicesController.cs @@ -1,5 +1,6 @@ using System.ComponentModel.DataAnnotations; using DoliMiddlewareApi.Dtos; +using DoliMiddlewareApi.Dtos.command; using DoliMiddlewareApi.Services; using Microsoft.AspNetCore.Mvc; @@ -39,4 +40,14 @@ public class InvoicesController : ControllerBase var invoice = await _invoiceService.GetInvoiceAsync(id); 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> CreateInvoice([FromBody] CreateInvoiceDto createInvoiceDto) + { + var invoiceId= await _invoiceService.CreateInvoiceAsync(createInvoiceDto); + return CreatedAtAction(nameof(GetInvoice), new { id = invoiceId }, invoiceId); + } } \ No newline at end of file diff --git a/DoliMiddlewareApi/Dtos/command/CreateInvoiceDto.cs b/DoliMiddlewareApi/Dtos/command/CreateInvoiceDto.cs index e534444..186ad7b 100644 --- a/DoliMiddlewareApi/Dtos/command/CreateInvoiceDto.cs +++ b/DoliMiddlewareApi/Dtos/command/CreateInvoiceDto.cs @@ -18,6 +18,8 @@ public class CreateInvoiceDto public string? NotePublic { get; set; } public string? NotePrivate { get; set; } + public string Status { get; set; } = "draft"; + [Required] [MinLength(1)] public List Lines { get; set; } = new(); diff --git a/DoliMiddlewareApi/Services/Clients/DolibarrApiClient.cs b/DoliMiddlewareApi/Services/Clients/DolibarrApiClient.cs index 198e598..488e503 100644 --- a/DoliMiddlewareApi/Services/Clients/DolibarrApiClient.cs +++ b/DoliMiddlewareApi/Services/Clients/DolibarrApiClient.cs @@ -32,6 +32,15 @@ public class DolibarrApiClient ?? throw new ApiException( $"Failed to deserialize list response from Dolibarr for endpoint '{endpoint}'"); } + + public async Task 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(); + } diff --git a/DoliMiddlewareApi/Services/InvoiceService.cs b/DoliMiddlewareApi/Services/InvoiceService.cs index de534e0..4507bd2 100644 --- a/DoliMiddlewareApi/Services/InvoiceService.cs +++ b/DoliMiddlewareApi/Services/InvoiceService.cs @@ -1,4 +1,6 @@ +using System.Globalization; using DoliMiddlewareApi.Dtos; +using DoliMiddlewareApi.Dtos.command; using DoliMiddlewareApi.Dtos.Dolibarr; using DoliMiddlewareApi.Mappers; using DoliMiddlewareApi.Services.Clients; @@ -36,4 +38,32 @@ public class InvoiceService var dataList = await _apiClient.GetCollectionAsync(endpoint); return dataList.Select(InvoiceMapper.MapToInvoiceDto).ToList(); } + + public async Task 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); + } } \ No newline at end of file