using Core.Interfaces.Stock; using Domain.Dtos.Stock; using Domain.Entities; using Domain.Generics; using Models.Interfaces; using System.Reflection; using Transversal.Services; namespace Core.Services.Stock { public class ExpeditionService : IExpeditionDom { #region Declaraciones private readonly IExpeditionRepository _repo; public ExpeditionService(IExpeditionRepository repo) => _repo = repo; #endregion #region Guardado completo de expedicion (encabezado + detalles) public async Task<(int Id, string ExpeditionNumber)> CreateAndIssueAsync( ELSExpeditionHeader header, IEnumerable details, int formSeriesId) { if (header is null) throw new ArgumentNullException(nameof(header)); if (details is null || !details.Any()) throw new InvalidOperationException("Debe incluir al menos un ítem."); if (formSeriesId <= 0) throw new ArgumentOutOfRangeException(nameof(formSeriesId), "Serie inválida."); // Reemplazo directo de la colección (más claro que Clear()+Add) header.PhLsmExpeditionDetails = details.ToList(); return await _repo.CreateFullExpeditionAsync(header, formSeriesId); } public Task GetDtoByExpeditionNumberAsync(string expeditionNumber) { throw new NotImplementedException(); } #endregion public Task> SearchAsync( string? expeditionNumber, string? status, DateTime? issueDateFrom, DateTime? issueDateTo, int? locationId, int page, int pageSize) => _repo.SearchAsync(expeditionNumber, status, issueDateFrom, issueDateTo, locationId, page, pageSize); public Task GetDtoByIdAsync(int id) => _repo.GetDtoByIdAsync(id); public async Task ExportFilteredToExcelAsync(ExpeditionSearchParams searchParams) { try { // Realiza la búsqueda de clientes con los parámetros proporcionados var searchResult = await _repo.SearchAsync( searchParams.Number, searchParams.Status, searchParams.From, searchParams.To, searchParams.LocationId, searchParams.Page, searchParams.PageSize ); // Verifica que se hayan encontrado resultados if (searchResult?.Items is null || !searchResult.Items.Any()) { throw new Exception("No se encontraron clientes para exportar."); } // Llamamos a un método que exporta los datos a Excel var stream = new XLSXExportBase(); // Convertimos los resultados de la búsqueda a un formato adecuado para el exportador var items = searchResult.Items.Select(c => new { c.Expeditionnumber, Issuedate = c.Issuedate.ToString("yyyy-MM-dd"), // ← string Createdat = c.Createdat.ToString("yyyy-MM-dd HH:mm"), // ← string c.Status, c.LocationId, c.ExternalReference, c.TicketId, c.ExtrainfoJson, c.Observations, c.TotalItems }).ToList(); // Genera el archivo Excel var excelFile = stream.ExportExcel(items); // Devuelve el archivo Excel como un array de bytes return excelFile; } catch (Exception ex) { var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod"; throw new Exception($"{ex.Message}", ex); } } } }