phronCare/Core/Services/DeliveryNoteService.cs
leandro af91f6be5c
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (pull_request) Successful in 2m21s
feat(sales): implement delivery note persistence on issue
closes #37
2026-03-24 16:34:38 -03:00

130 lines
5.4 KiB
C#

using Core.Interfaces;
using Domain.Dtos.Sales;
using Domain.Entities;
using Domain.Generics;
using Models.Interfaces;
namespace Core.Services
{
public class DeliveryNoteService(IPhSDeliveryNoteRepository deliveryNoteRepository) : IDeliveryNoteDom
{
private readonly IPhSDeliveryNoteRepository _deliveryNoteRepository = deliveryNoteRepository;
public Task<PagedResult<DeliveryNoteSummaryDto>> SearchAsync(
int? customerId,
string? customerText,
string? deliveryNoteNumber,
int? quoteId,
string? quoteNumber,
DateTime? issueDateFrom,
DateTime? issueDateTo,
string? status,
int page = 1,
int pageSize = 50)
{
page = page <= 0 ? 1 : page;
pageSize = pageSize <= 0 ? 50 : pageSize;
return _deliveryNoteRepository.SearchAsync(
customerId,
string.IsNullOrWhiteSpace(customerText) ? null : customerText.Trim(),
string.IsNullOrWhiteSpace(deliveryNoteNumber) ? null : deliveryNoteNumber.Trim(),
quoteId,
string.IsNullOrWhiteSpace(quoteNumber) ? null : quoteNumber.Trim(),
issueDateFrom,
issueDateTo,
string.IsNullOrWhiteSpace(status) ? null : status.Trim(),
page,
pageSize);
}
public Task<DeliveryNoteDto?> GetDtoByIdAsync(int id)
{
if (id <= 0)
throw new ArgumentOutOfRangeException(nameof(id), "El identificador del remito es inválido.");
return _deliveryNoteRepository.GetDtoByIdAsync(id);
}
public Task<DeliveryNoteDto?> GetDtoByDeliveryNoteNumberAsync(string deliveryNoteNumber)
{
if (string.IsNullOrWhiteSpace(deliveryNoteNumber))
throw new ArgumentException("El número de remito es obligatorio.", nameof(deliveryNoteNumber));
return _deliveryNoteRepository.GetDtoByDeliveryNoteNumberAsync(deliveryNoteNumber.Trim());
}
public Task<IEnumerable<DeliveryNoteDto>> GetDtosByQuoteIdAsync(int quoteId)
{
if (quoteId <= 0)
throw new ArgumentOutOfRangeException(nameof(quoteId), "El identificador del presupuesto es inválido.");
return _deliveryNoteRepository.GetDtosByQuoteIdAsync(quoteId);
}
public async 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 deliveryNoteNumber = request.DeliveryNoteNumber.Trim();
if (await _deliveryNoteRepository.ExistsByDeliveryNoteNumberAsync(deliveryNoteNumber))
throw new InvalidOperationException($"Ya existe un remito con el número '{deliveryNoteNumber}'.");
var now = DateTime.Now;
var entity = new EDeliveryNote
{
Deliverynotenumber = deliveryNoteNumber,
QuoteId = request.QuoteId,
Issuedate = request.IssueDate,
CustomerId = request.CustomerId,
Status = "Emitido",
Observations = string.IsNullOrWhiteSpace(request.Observations) ? null : request.Observations.Trim(),
ExtrainfoJson = string.IsNullOrWhiteSpace(request.ExtraInfoJson) ? null : request.ExtraInfoJson.Trim(),
Printcount = 0,
Createdat = now,
PhSDeliveryNoteDetails = request.Items
.Select((item, index) => new EDeliveryNoteDetail
{
LineNumber = index + 1,
OriginType = item.OriginType,
OriginId = item.OriginId,
QuoteDetailId = item.QuoteDetailId,
Description = item.Description.Trim(),
Quantity = item.Quantity,
Notes = string.IsNullOrWhiteSpace(item.Notes) ? string.Empty : item.Notes.Trim(),
Createdat = now
})
.ToList()
};
var created = await _deliveryNoteRepository.CreateAsync(entity);
return new DeliveryNoteCreateResponse
{
Id = created.Id,
DeliveryNoteNumber = created.Deliverynotenumber
};
}
}
}