Leandro Hernan Rojas 0361d4c978
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 6m2s
Add Export QUOTES & refactoring
2025-09-11 22:41:46 -03:00

205 lines
7.3 KiB
C#

using Domain.Dtos;
using Domain.Entities;
using Domain.Generics;
using Microsoft.JSInterop;
using System.Net.Http.Json;
using System.Reflection;
using System.Text;
using System.Text.Json;
namespace phronCare.UIBlazor.Services.Sales.Quotes
{
public class QuoteService:IQuoteService
{
private readonly IJSRuntime _js;
private readonly HttpClient _http;
public QuoteService(HttpClient http, IJSRuntime js)
{
_js = js;
_http = http;
}
/// <summary>
/// Envía el EQuoteHeader junto con el formSeriesId al backend
/// y recibe el número de presupuesto generado o un error.
/// </summary>
public async Task<CreateQuoteResult> CreateFullQuoteAsync(EQuoteHeader quote, int formSeriesId)
{
var request = new CreateFullQuoteRequest
{
Quote = quote,
FormSeriesId = formSeriesId
};
var response = await _http.PostAsJsonAsync("/api/quote/createfull", request);
if (!response.IsSuccessStatusCode)
{
var serverMessage = await response.Content.ReadAsStringAsync();
return new CreateQuoteResult
{
Success = false,
ErrorMessage = serverMessage
};
}
var result = await response.Content.ReadFromJsonAsync<CreateQuoteResult>();
return result!;
}
/// <summary>
/// Busca presupuestos con filtros y paginación.
/// </summary>
public async Task<PagedResult<QuoteDto>> SearchAsync(
int? customerId = null,
string? customerText = null,
string? quoteNumber = null,
int? professionalId = null,
string? professionalText = null,
int? institutionId = null,
string? institutionText = null,
int? patientId = null,
string? patientText = null,
string? status = null,
DateTime? issueDateFrom = null,
DateTime? issueDateTo = null,
int page = 1,
int pageSize = 10)
{
// Construir manualmente la query string
var queryParams = new List<string>();
void AddParam(string key, string? value)
{
if (!string.IsNullOrWhiteSpace(value))
queryParams.Add($"{key}={Uri.EscapeDataString(value!)}");
}
AddParam("customerId", customerId?.ToString());
AddParam("customerText", customerText);
AddParam("quoteNumber", quoteNumber);
AddParam("professionalId", professionalId?.ToString());
AddParam("professionalText", professionalText);
AddParam("institutionId", institutionId?.ToString());
AddParam("institutionText", institutionText);
AddParam("patientId", patientId?.ToString());
AddParam("patientText", patientText);
AddParam("status", status);
AddParam("issueDateFrom", issueDateFrom?.ToString("o"));
AddParam("issueDateTo", issueDateTo?.ToString("o"));
AddParam("page", page.ToString());
AddParam("pageSize", pageSize.ToString());
var url = "/api/quote/search";
if (queryParams.Any())
url += "?" + string.Join("&", queryParams);
// Llamada al endpoint
var result = await _http.GetFromJsonAsync<PagedResult<QuoteDto>>(url);
return result!;
}
/// <summary>
/// Obtiene el PDF del presupuesto por ID como array de bytes.
/// </summary>
public async Task ExportPdfAsync(int quoteId, string quoteNumber)
{
try
{
var response = await _http.GetAsync($"/api/quote/{quoteId}/pdf");
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
throw new Exception($"Error al generar PDF: {error}");
}
var bytes = await response.Content.ReadAsByteArrayAsync();
var base64 = Convert.ToBase64String(bytes);
var fileName = $"{quoteNumber}.pdf";
await _js.InvokeVoidAsync("saveAsFile", fileName, base64);
}
catch (Exception ex)
{
var message = ex.Message ?? "No message";
throw new Exception($"ExportPdfAsync: {message}", ex);
}
}
/// <summary>
/// Envía una solicitud al backend para autorizar un presupuesto específico.
/// </summary>
public async Task<bool> AuthorizeQuoteAsync(QuoteAuthorizationRequest request)
{
var response = await _http.PostAsJsonAsync("/api/quote/authorize", request);
if (!response.IsSuccessStatusCode)
{
var serverMessage = await response.Content.ReadAsStringAsync();
throw new Exception($"Error al autorizar el presupuesto: {serverMessage}");
}
return true;
}
/// <summary>
/// Obtiene un presupuesto completo por ID para su visualización y autorización.
/// </summary>
public async Task<QuoteDto?> GetDtoByIdAsync(int id)
{
try
{
var result = await _http.GetFromJsonAsync<QuoteDto>($"/api/quote/{id}");
return result;
}
catch (Exception ex)
{
Console.WriteLine($"Error al obtener QuoteDto por ID: {ex.Message}");
return null;
}
}
public async Task ExportFilteredAsync(QuoteSearchParams searchParams)
{
try
{
var content = new StringContent(JsonSerializer.Serialize(searchParams), Encoding.UTF8, "application/json");
var response = await _http.PostAsync("api/quote/exportfiltered", content);
//response.EnsureSuccessStatusCode();
if (!response.IsSuccessStatusCode)
{
var errorContent = await response.Content.ReadAsStringAsync();
throw new Exception(errorContent);
}
var bytes = await response.Content.ReadAsByteArrayAsync();
var base64 = Convert.ToBase64String(bytes);
var timestamp = DateTime.Now.ToString("yyyyMMddHHmm");
var fileName = $"{timestamp}_quotes.xlsx";
await _js.InvokeVoidAsync("saveAsFile", fileName, base64);
}
catch (Exception ex)
{
var methodName = MethodBase.GetCurrentMethod()?.Name ?? "UnknownMethod";
var message = ex.Message ?? "No message provided";
throw new Exception($"{message}", ex);
}
}
}
public class CreateQuoteResult
{
public bool Success { get; set; }
public int Id { get; set; }
public string QuoteNumber { get; set; } = string.Empty;
public string ErrorMessage { get; set; } = string.Empty;
}
public class CreateFullQuoteRequest
{
public EQuoteHeader Quote { get; set; } = default!;
public int FormSeriesId { get; set; }
}
}