using Domain.Entities; using Domain.Generics; using Models.Helpers; using Models.Interfaces; using System.Reflection; using Transversal.Services; namespace PhronCare.Core.Services.Sales { public class QuoteService( IPhSQuoteHeaderRepository quoteHeaderRepository, IPhSQuoteDetailRepository quoteDetailRepository, IPhSQuoteRoleRepository quoteRoleRepository, IPhSFormSeriesRepository formSeriesRepository ) : IQuoteDom { #region Declaraciones private readonly IPhSQuoteHeaderRepository _quoteHeaderRepository = quoteHeaderRepository; private readonly IPhSQuoteDetailRepository _quoteDetailRepository = quoteDetailRepository; private readonly IPhSQuoteRoleRepository _quoteRoleRepository = quoteRoleRepository; private readonly IPhSFormSeriesRepository _formSeriesRepository = formSeriesRepository; #endregion #region Presupuestos public async Task> GetAllQuotesAsync(int page = 1, int pageSize = 50) { return await _quoteHeaderRepository.GetAllAsync(page, pageSize); } public async Task GetQuoteByIdAsync(int id) { return await _quoteHeaderRepository.GetByIdAsync(id); } public async Task> GetQuotesByCustomerAsync(int customerId) { return await _quoteHeaderRepository.GetByCustomerIdAsync(customerId); } public async Task> SearchQuotesAsync( int? customerId, string? quoteNumber, int? professionalId, int? institutionId, int? patientId, DateTime? issueDateFrom, DateTime? issueDateTo, string? status, int page = 1, int pageSize = 50) { return await _quoteHeaderRepository.SearchAsync( customerId, quoteNumber, professionalId, institutionId, patientId, issueDateFrom, issueDateTo, status, page, pageSize); } public async Task CreateQuoteAsync(EQuoteHeader quote, int formSeriesId) { // Obtener el próximo número de documento var nextNumber = await _formSeriesRepository.GetNextInternalNumberAsync(formSeriesId); quote.Quotenumber = nextNumber.ToString(); // Crear encabezado var newQuote = await _quoteHeaderRepository.AddAsync(quote); // Crear detalles asociados if (quote.PhSQuoteDetails != null) { foreach (var detail in quote.PhSQuoteDetails) { detail.QuoteheaderId = newQuote.Id; await _quoteDetailRepository.AddAsync(detail); } } // Crear roles asociados if (quote.PhSQuoteRoles != null) { foreach (var role in quote.PhSQuoteRoles) { role.QuoteheaderId = newQuote.Id; await _quoteRoleRepository.AddAsync(role); } } return newQuote; } public async Task UpdateQuoteAsync(EQuoteHeader quote) { await _quoteHeaderRepository.UpdateAsync(quote); } public async Task DeleteQuoteAsync(int id) { await _quoteHeaderRepository.DeleteAsync(id); } #endregion #region Ajustes public async Task> GetAdjustmentsByQuoteIdAsync(int quoteId) { return await _quoteHeaderRepository.GetAdjustmentsByQuoteIdAsync(quoteId); } public async Task AddAdjustmentAsync(EQuoteAdjustment adjustment) { return await _quoteHeaderRepository.AddAdjustmentAsync(adjustment); } public async Task UpdateAdjustmentAsync(EQuoteAdjustment adjustment) { await _quoteHeaderRepository.UpdateAdjustmentAsync(adjustment); } public async Task DeleteAdjustmentAsync(int adjustmentId) { await _quoteHeaderRepository.DeleteAdjustmentAsync(adjustmentId); } #endregion #region Impuestos public async Task> GetTaxesByQuoteIdAsync(int quoteId) { return await _quoteHeaderRepository.GetTaxesByQuoteIdAsync(quoteId); } public async Task AddTaxAsync(EQuoteTax tax) { return await _quoteHeaderRepository.AddTaxAsync(tax); } public async Task UpdateTaxAsync(EQuoteTax tax) { await _quoteHeaderRepository.UpdateTaxAsync(tax); } public async Task DeleteTaxAsync(int taxId) { await _quoteHeaderRepository.DeleteTaxAsync(taxId); } #endregion #region Exportación public async Task ExportFilteredQuotesToExcelAsync(QuoteSearchParams searchParams) { try { var searchResult = await SearchQuotesAsync( searchParams.CustomerId, searchParams.QuoteNumber, searchParams.ProfessionalId, searchParams.InstitutionId, searchParams.PatientId, searchParams.IssueDateFrom, searchParams.IssueDateTo, searchParams.Status, searchParams.Page, searchParams.PageSize); if (searchResult?.Items == null || !searchResult.Items.Any()) { throw new Exception("No se encontraron presupuestos para exportar."); } var stream = new XLSXExportBase(); var quotesData = searchResult.Items.Select(q => new { NúmeroPresupuesto = q.Quotenumber, Estado = q.Status, FechaEmisión = q.Issuedate.ToString("yyyy-MM-dd"), FechaTentativa = q.Estimateddate?.ToString("yyyy-MM-dd"), ImporteAprobado = q.Approvedamount, Profesional = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == PhSEntityTypes.Professional)?.Entitytype, Institución = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == PhSEntityTypes.Institution)?.Entitytype, Paciente = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == PhSEntityTypes.Patient)?.Entitytype }).ToList(); return stream.ExportExcel(quotesData); } catch (Exception ex) { var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod"; throw new Exception($"{methodName} Message: {ex.Message}", ex); } } #endregion } }