feature/leandro/35-issue-delivery-note #36
@ -49,4 +49,9 @@ public interface IDeliveryNoteDom
|
|||||||
/// Puede estar vacía si no existen registros.
|
/// Puede estar vacía si no existen registros.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
Task<IEnumerable<DeliveryNoteDto>> GetDtosByQuoteIdAsync(int quoteId);
|
Task<IEnumerable<DeliveryNoteDto>> GetDtosByQuoteIdAsync(int quoteId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Valida y prepara la emisión de un Delivery Note.
|
||||||
|
/// </summary>
|
||||||
|
Task<DeliveryNoteCreateResponse> CreateAndIssueDeliveryNoteAsync(DeliveryNoteCreateRequest request);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using Core.Interfaces;
|
using Core.Interfaces;
|
||||||
using Domain.Dtos.Sales;
|
using Domain.Dtos.Sales;
|
||||||
|
using Domain.Entities;
|
||||||
using Domain.Generics;
|
using Domain.Generics;
|
||||||
using Models.Interfaces;
|
using Models.Interfaces;
|
||||||
|
|
||||||
@ -60,5 +61,44 @@ namespace Core.Services
|
|||||||
|
|
||||||
return _deliveryNoteRepository.GetDtosByQuoteIdAsync(quoteId);
|
return _deliveryNoteRepository.GetDtosByQuoteIdAsync(quoteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<DeliveryNoteCreateResponse> 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
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
Domain/Dtos/Sales/DeliveryNoteCreateItemRequest.cs
Normal file
12
Domain/Dtos/Sales/DeliveryNoteCreateItemRequest.cs
Normal file
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Domain/Dtos/Sales/DeliveryNoteCreateRequest.cs
Normal file
13
Domain/Dtos/Sales/DeliveryNoteCreateRequest.cs
Normal file
@ -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<DeliveryNoteCreateItemRequest> Items { get; set; } = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
8
Domain/Dtos/Sales/DeliveryNoteCreateResponse.cs
Normal file
8
Domain/Dtos/Sales/DeliveryNoteCreateResponse.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Domain.Dtos.Sales
|
||||||
|
{
|
||||||
|
public class DeliveryNoteCreateResponse
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string DeliveryNoteNumber { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,34 +1,31 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Domain.Entities
|
namespace Domain.Entities
|
||||||
{
|
{
|
||||||
public class EDeliveryNote
|
public class EDeliveryNote
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
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? 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 int CustomerId { get; set; }
|
||||||
|
|
||||||
public string Status { get; set; } = string.Empty;
|
public string Status { get; set; } = null!;
|
||||||
|
|
||||||
public string? Observations { get; set; }
|
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<EDeliveryNoteDetail> PhSDeliveryNoteDetails { get; set; } = new List<EDeliveryNoteDetail>();
|
public virtual ICollection<EDeliveryNoteDetail> PhSDeliveryNoteDetails { get; set; } = new List<EDeliveryNoteDetail>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Domain.Entities
|
namespace Domain.Entities
|
||||||
{
|
{
|
||||||
public class EDeliveryNoteDetail
|
public partial class EDeliveryNoteDetail
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
@ -24,9 +24,9 @@
|
|||||||
|
|
||||||
public DateTime? Modifiedat { get; set; }
|
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; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Domain.Dtos.Sales;
|
using Domain.Dtos.Sales;
|
||||||
|
using Domain.Entities;
|
||||||
using Domain.Generics;
|
using Domain.Generics;
|
||||||
|
|
||||||
namespace Models.Interfaces
|
namespace Models.Interfaces
|
||||||
@ -20,5 +21,8 @@ namespace Models.Interfaces
|
|||||||
Task<DeliveryNoteDto?> GetDtoByIdAsync(int id);
|
Task<DeliveryNoteDto?> GetDtoByIdAsync(int id);
|
||||||
Task<DeliveryNoteDto?> GetDtoByDeliveryNoteNumberAsync(string deliveryNoteNumber);
|
Task<DeliveryNoteDto?> GetDtoByDeliveryNoteNumberAsync(string deliveryNoteNumber);
|
||||||
Task<IEnumerable<DeliveryNoteDto>> GetDtosByQuoteIdAsync(int quoteId);
|
Task<IEnumerable<DeliveryNoteDto>> GetDtosByQuoteIdAsync(int quoteId);
|
||||||
|
|
||||||
|
Task<bool> ExistsByDeliveryNoteNumberAsync(string deliveryNoteNumber);
|
||||||
|
Task<EDeliveryNote> CreateAsync(EDeliveryNote entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using Domain.Dtos.Sales;
|
using Domain.Dtos.Sales;
|
||||||
|
using Domain.Entities;
|
||||||
using Domain.Generics;
|
using Domain.Generics;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Models.Helpers;
|
using Models.Helpers;
|
||||||
@ -115,6 +116,23 @@ namespace Models.Repositories
|
|||||||
return entities.Select(MapDeliveryNoteDto);
|
return entities.Select(MapDeliveryNoteDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> ExistsByDeliveryNoteNumberAsync(string deliveryNoteNumber)
|
||||||
|
{
|
||||||
|
return await _context.PhSDeliveryNotes
|
||||||
|
.AsNoTracking()
|
||||||
|
.AnyAsync(x => x.Deliverynotenumber == deliveryNoteNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<EDeliveryNote> CreateAsync(EDeliveryNote entity)
|
||||||
|
{
|
||||||
|
var mapped = EntityMapper.MapEntity<EDeliveryNote, PhSDeliveryNote>(entity);
|
||||||
|
|
||||||
|
await _context.PhSDeliveryNotes.AddAsync(mapped);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
|
||||||
|
return EntityMapper.MapEntity<PhSDeliveryNote, EDeliveryNote>(mapped);
|
||||||
|
}
|
||||||
|
|
||||||
private static DeliveryNoteDto MapDeliveryNoteDto(PhSDeliveryNote source)
|
private static DeliveryNoteDto MapDeliveryNoteDto(PhSDeliveryNote source)
|
||||||
{
|
{
|
||||||
return new DeliveryNoteDto
|
return new DeliveryNoteDto
|
||||||
|
|||||||
@ -103,5 +103,28 @@ namespace phronCare.API.Controllers.Sales
|
|||||||
return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
return StatusCode(500, $"{methodName} Message: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost("issue")]
|
||||||
|
public async Task<ActionResult<DeliveryNoteCreateResponse>> 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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user