feat: Añadido endpoints para Delete Invoice y sus Lines , tambien corregido orden de Dto de GetById

This commit is contained in:
javiermengual 2026-02-05 14:33:03 +01:00
parent 45e4af5b39
commit 45913112be
7 changed files with 59 additions and 8 deletions

View File

@ -96,4 +96,30 @@ public class InvoicesController(InvoiceService invoiceService) : ControllerBase
await invoiceService.ValidateInvoiceAsync(id);
return NoContent();
}
[HttpDelete("{id:int}")]
[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> DeleteInvoice([Range(1, int.MaxValue)] int id)
{
await invoiceService.DeleteInvoiceAsync(id);
return NoContent();
}
[HttpDelete("{invoiceId:int}/lines/{lineId:int}")]
[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> DeleteInvoiceLine(
[Range(1, int.MaxValue)] int invoiceId,
[Range(1, int.MaxValue)] int lineId)
{
await invoiceService.DeleteInvoiceLineAsync(invoiceId, lineId);
return NoContent();
}
}

View File

@ -10,7 +10,7 @@ public class InvoiceDetailDto
public decimal? Total { get; set; }
public decimal? RemainToPay { get; set; }
public string Status { get; set; }
public string? NotePublic { get; set; }
public string? NotePrivate { get; set; }
public List<InvoiceLineDto>? Lines { get; set; }
public string? note_public { get; set; }
public string? note_private { get; set; }
}

View File

@ -10,7 +10,7 @@ public class InvoiceDto
public decimal? Total { get; set; }
public decimal? RemainToPay { get; set; }
public string Status { get; set; }
public string? NotePublic { get; set; }
public string? NotePrivate { get; set; }
public string? ClientName { get; set; }
public string? note_public { get; set; }
public string? note_private { get; set; }
}

View File

@ -35,8 +35,8 @@ public static class InvoiceMapper
: null,
Status = ConvertStatusToWord(invoiceResponse.statut),
note_public = invoiceResponse.note_public,
note_private = invoiceResponse.note_private
NotePublic = invoiceResponse.note_public,
NotePrivate = invoiceResponse.note_private
};
}
@ -54,8 +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,
NotePublic = baseDto.NotePublic,
NotePrivate = baseDto.NotePrivate,
Lines = data.Lines?.Select(MapToInvoiceLineDto).ToList() ?? new List<InvoiceLineDto>()
};

View File

@ -57,6 +57,14 @@ public class DolibarrApiClient(HttpClient httpClient, DolibarrTokenCacheService
return await response.Content.ReadAsStringAsync();
}
public async Task DeleteAsync(string endpoint)
{
var request = new HttpRequestMessage(HttpMethod.Delete, endpoint);
AddDolibarrTokenHeader(request);
var response = await httpClient.SendAsync(request);
await EnsureSuccessOrThrowAsync(response, endpoint);
}
private void AddDolibarrTokenHeader(HttpRequestMessage request)
{
var dolibarrToken = tokenCacheService.GetDolibarrToken();

View File

@ -6,4 +6,5 @@ public interface IDolibarrApiClient
Task<List<T>> GetCollectionAsync<T>(string endpoint) where T : class;
Task<string> PostAsync(string endpoint, object requestBody);
Task<string> PutAsync(string endpoint, object requestBody);
Task DeleteAsync(string endpoint);
}

View File

@ -138,6 +138,22 @@ public class InvoiceService(IDolibarrApiClient apiClient)
await apiClient.PostAsync($"invoices/{id}/validate", new { });
}
public async Task DeleteInvoiceAsync(int id)
{
var invoice = await apiClient.GetResourceAsync<InvoiceDetailResponse>($"invoices/{id}");
if (invoice.statut != "0") throw new ForbiddenException("Solo se pueden eliminar facturas en borrador (draft)");
await apiClient.DeleteAsync($"invoices/{id}");
}
public async Task DeleteInvoiceLineAsync(int invoiceId, int lineId)
{
var invoice = await apiClient.GetResourceAsync<InvoiceDetailResponse>($"invoices/{invoiceId}");
if (invoice.statut != "0") throw new ForbiddenException("Solo se pueden eliminar líneas de facturas en borrador (draft)");
await apiClient.DeleteAsync($"invoices/{invoiceId}/lines/{lineId}");
}
private async Task<Dictionary<int, string>> GetClientNamesAsync(List<int> clientIds)
{
var uniqueIds = clientIds.Distinct().ToList();