diff --git a/Core/Interfaces/IDeliveryNoteDom.cs b/Core/Interfaces/IDeliveryNoteDom.cs index e63f606..bbeff1e 100644 --- a/Core/Interfaces/IDeliveryNoteDom.cs +++ b/Core/Interfaces/IDeliveryNoteDom.cs @@ -49,4 +49,9 @@ public interface IDeliveryNoteDom /// Puede estar vacía si no existen registros. /// Task> GetDtosByQuoteIdAsync(int quoteId); + + /// + /// Valida y prepara la emisión de un Delivery Note. + /// + Task CreateAndIssueDeliveryNoteAsync(DeliveryNoteCreateRequest request); } diff --git a/Core/Services/DeliveryNoteService.cs b/Core/Services/DeliveryNoteService.cs index 6b4894b..c046236 100644 --- a/Core/Services/DeliveryNoteService.cs +++ b/Core/Services/DeliveryNoteService.cs @@ -1,5 +1,6 @@ using Core.Interfaces; using Domain.Dtos.Sales; +using Domain.Entities; using Domain.Generics; using Models.Interfaces; @@ -60,5 +61,44 @@ namespace Core.Services return _deliveryNoteRepository.GetDtosByQuoteIdAsync(quoteId); } + + public Task CreateAndIssueDeliveryNoteAsync(DeliveryNoteCreateRequest request) + { + ArgumentNullException.ThrowIfNull(request); + + if (string.IsNullOrWhiteSpace(request.DeliveryNoteNumber)) + throw new ArgumentException("El número de remito es obligatorio.", nameof(request.DeliveryNoteNumber)); + + if (request.CustomerId <= 0) + throw new ArgumentException("Debe seleccionar un cliente.", nameof(request.CustomerId)); + + if (request.IssueDate == default) + throw new ArgumentException("La fecha de emisión es obligatoria.", nameof(request.IssueDate)); + + if (request.Items is null || request.Items.Count == 0) + throw new InvalidOperationException("Debe incluir al menos un ítem."); + + if (request.Items.Any(i => i.Quantity <= 0)) + throw new InvalidOperationException("Todas las cantidades deben ser mayores a cero."); + + if (request.Items.Any(i => string.IsNullOrWhiteSpace(i.Description))) + throw new InvalidOperationException("Todos los ítems deben incluir descripción."); + + var entity = new EDeliveryNote + { + Deliverynotenumber = request.DeliveryNoteNumber.Trim(), + QuoteId = request.QuoteId, + Issuedate = request.IssueDate, + CustomerId = request.CustomerId, + Observations = request.Observations, + ExtrainfoJson = request.ExtraInfoJson + }; + + return Task.FromResult(new DeliveryNoteCreateResponse + { + Id = entity.Id, + DeliveryNoteNumber = entity.Deliverynotenumber + }); + } } } diff --git a/Domain/Dtos/Sales/DeliveryNoteCreateItemRequest.cs b/Domain/Dtos/Sales/DeliveryNoteCreateItemRequest.cs new file mode 100644 index 0000000..0d8d188 --- /dev/null +++ b/Domain/Dtos/Sales/DeliveryNoteCreateItemRequest.cs @@ -0,0 +1,12 @@ +namespace Domain.Dtos.Sales +{ + public class DeliveryNoteCreateItemRequest + { + public byte OriginType { get; set; } + public int? OriginId { get; set; } + public int? QuoteDetailId { get; set; } + public string Description { get; set; } = string.Empty; + public decimal Quantity { get; set; } + public string? Notes { get; set; } + } +} \ No newline at end of file diff --git a/Domain/Dtos/Sales/DeliveryNoteCreateRequest.cs b/Domain/Dtos/Sales/DeliveryNoteCreateRequest.cs new file mode 100644 index 0000000..3ef0e42 --- /dev/null +++ b/Domain/Dtos/Sales/DeliveryNoteCreateRequest.cs @@ -0,0 +1,13 @@ +namespace Domain.Dtos.Sales +{ + public class DeliveryNoteCreateRequest + { + public string DeliveryNoteNumber { get; set; } = string.Empty; + public int? QuoteId { get; set; } + public DateTime IssueDate { get; set; } + public int CustomerId { get; set; } + public string? Observations { get; set; } + public string? ExtraInfoJson { get; set; } + public List Items { get; set; } = new(); + } +} \ No newline at end of file diff --git a/Domain/Dtos/Sales/DeliveryNoteCreateResponse.cs b/Domain/Dtos/Sales/DeliveryNoteCreateResponse.cs new file mode 100644 index 0000000..8d3cef7 --- /dev/null +++ b/Domain/Dtos/Sales/DeliveryNoteCreateResponse.cs @@ -0,0 +1,8 @@ +namespace Domain.Dtos.Sales +{ + public class DeliveryNoteCreateResponse + { + public int Id { get; set; } + public string DeliveryNoteNumber { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/Domain/Entities/EDeliveryNote.cs b/Domain/Entities/EDeliveryNote.cs index e343237..9f66e89 100644 --- a/Domain/Entities/EDeliveryNote.cs +++ b/Domain/Entities/EDeliveryNote.cs @@ -1,34 +1,31 @@ -using System; -using System.Collections.Generic; - namespace Domain.Entities { public class EDeliveryNote { public int Id { get; set; } - public string DeliveryNoteNumber { get; set; } = string.Empty; + public string Deliverynotenumber { get; set; } = null!; public int? QuoteId { get; set; } - public int? SalesInvoiceId { get; set; } + public int? SalesinvoiceId { get; set; } - public DateTime IssueDate { get; set; } + public DateTime Issuedate { get; set; } public int CustomerId { get; set; } - public string Status { get; set; } = string.Empty; + public string Status { get; set; } = null!; public string? Observations { get; set; } - public string? ExtraInfoJson { get; set; } + public string? ExtrainfoJson { get; set; } - public int PrintCount { get; set; } + public int Printcount { get; set; } - public DateTime CreatedAt { get; set; } + public DateTime Createdat { get; set; } - public DateTime? ModifiedAt { get; set; } + public DateTime? Modifiedat { get; set; } - public List PhSDeliveryNoteDetails { get; set; } = new List(); + public virtual ICollection PhSDeliveryNoteDetails { get; set; } = new List(); } } diff --git a/Domain/Entities/EDeliveryNoteDetail.cs b/Domain/Entities/EDeliveryNoteDetail.cs index 75e1765..ae0b467 100644 --- a/Domain/Entities/EDeliveryNoteDetail.cs +++ b/Domain/Entities/EDeliveryNoteDetail.cs @@ -1,6 +1,6 @@ namespace Domain.Entities { - public class EDeliveryNoteDetail + public partial class EDeliveryNoteDetail { public int Id { get; set; } @@ -24,9 +24,9 @@ public DateTime? Modifiedat { get; set; } - //public virtual PhSDeliveryNote Deliverynote { get; set; } = null!; + //public virtual EDeliveryNote Deliverynote { get; set; } = null!; - //public virtual PhSQuoteDetail? QuoteDetail { get; set; } + //public virtual EQuoteDetail? QuoteDetail { get; set; } } } diff --git a/Models/Interfaces/IPhSDeliveryNoteRepository.cs b/Models/Interfaces/IPhSDeliveryNoteRepository.cs index 77223da..b7793aa 100644 --- a/Models/Interfaces/IPhSDeliveryNoteRepository.cs +++ b/Models/Interfaces/IPhSDeliveryNoteRepository.cs @@ -1,4 +1,5 @@ using Domain.Dtos.Sales; +using Domain.Entities; using Domain.Generics; namespace Models.Interfaces @@ -20,5 +21,8 @@ namespace Models.Interfaces Task GetDtoByIdAsync(int id); Task GetDtoByDeliveryNoteNumberAsync(string deliveryNoteNumber); Task> GetDtosByQuoteIdAsync(int quoteId); + + Task ExistsByDeliveryNoteNumberAsync(string deliveryNoteNumber); + Task CreateAsync(EDeliveryNote entity); } } diff --git a/Models/Repositories/PhSDeliveryNoteRepository.cs b/Models/Repositories/PhSDeliveryNoteRepository.cs index dcf0395..c4d5928 100644 --- a/Models/Repositories/PhSDeliveryNoteRepository.cs +++ b/Models/Repositories/PhSDeliveryNoteRepository.cs @@ -1,4 +1,5 @@ using Domain.Dtos.Sales; +using Domain.Entities; using Domain.Generics; using Microsoft.EntityFrameworkCore; using Models.Helpers; @@ -115,6 +116,23 @@ namespace Models.Repositories return entities.Select(MapDeliveryNoteDto); } + public async Task ExistsByDeliveryNoteNumberAsync(string deliveryNoteNumber) + { + return await _context.PhSDeliveryNotes + .AsNoTracking() + .AnyAsync(x => x.Deliverynotenumber == deliveryNoteNumber); + } + + public async Task CreateAsync(EDeliveryNote entity) + { + var mapped = EntityMapper.MapEntity(entity); + + await _context.PhSDeliveryNotes.AddAsync(mapped); + await _context.SaveChangesAsync(); + + return EntityMapper.MapEntity(mapped); + } + private static DeliveryNoteDto MapDeliveryNoteDto(PhSDeliveryNote source) { return new DeliveryNoteDto diff --git a/phronCare.API/Controllers/Sales/DeliveryNoteController.cs b/phronCare.API/Controllers/Sales/DeliveryNoteController.cs index 345431f..c25215c 100644 --- a/phronCare.API/Controllers/Sales/DeliveryNoteController.cs +++ b/phronCare.API/Controllers/Sales/DeliveryNoteController.cs @@ -103,5 +103,28 @@ namespace phronCare.API.Controllers.Sales return StatusCode(500, $"{methodName} Message: {ex.Message}"); } } + + [HttpPost("issue")] + public async Task> Issue([FromBody] DeliveryNoteCreateRequest request) + { + try + { + var result = await _deliveryNoteService.CreateAndIssueDeliveryNoteAsync(request); + return Ok(result); + } + catch (ArgumentException ex) + { + return BadRequest(ex.Message); + } + catch (InvalidOperationException ex) + { + return BadRequest(ex.Message); + } + catch (Exception ex) + { + var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod"; + return StatusCode(500, $"{methodName} Message: {ex.Message}"); + } + } } }