All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 10m12s
163 lines
5.8 KiB
C#
163 lines
5.8 KiB
C#
using Domain.Dtos;
|
|
using Domain.Entities;
|
|
using Microsoft.JSInterop;
|
|
using System.Net.Http.Json;
|
|
|
|
namespace phronCare.UIBlazor.Services.Stock.Expeditions
|
|
{
|
|
public class ExpeditionService
|
|
{
|
|
private readonly IJSRuntime _js; //Todavia no se utiliza pero eventualmente para exportaciones seguramente./
|
|
private readonly HttpClient _http;
|
|
public ExpeditionService(HttpClient http, IJSRuntime js)
|
|
{
|
|
_js = js;
|
|
_http = http;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtiene un presupuesto por QuoteNumber.
|
|
/// </summary>
|
|
public async Task<QuoteDto?> GetQuoteByNumberAsync(string quoteNumber)
|
|
{
|
|
try
|
|
{
|
|
var result = await _http.GetFromJsonAsync<QuoteDto?>($"api/quote/summary/{quoteNumber}");
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Error al obtener QuoteDto por QuoteNumber: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Envía el header + details de la expedición junto con el formSeriesId
|
|
/// y recibe el número de expedición generado o un mensaje de error.
|
|
/// </summary>
|
|
public async Task<CreateExpeditionResult> CreateAndIssueAsync(
|
|
ELSExpeditionHeader header,
|
|
IEnumerable<ELSExpeditionDetail> details,
|
|
int formSeriesId)
|
|
{
|
|
// 1) Poner los ítems dentro del header
|
|
header.PhLsmExpeditionDetails = details?.ToList() ?? new List<ELSExpeditionDetail>();
|
|
|
|
var request = new CreateFullExpeditionRequest
|
|
{
|
|
Expedition = header,
|
|
FormSeriesId = formSeriesId
|
|
};
|
|
|
|
var response = await _http.PostAsJsonAsync("/api/expedition/createfull", request);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
var serverMessage = await response.Content.ReadAsStringAsync();
|
|
return new CreateExpeditionResult
|
|
{
|
|
Success = false,
|
|
ErrorMessage = serverMessage
|
|
};
|
|
}
|
|
|
|
var result = await response.Content.ReadFromJsonAsync<CreateExpeditionResult>();
|
|
return result ?? new CreateExpeditionResult { Success = false, ErrorMessage = "Respuesta vacía del servidor." };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Obtiene la expedición completa por ID para visualización (drawer/pantalla de detalle).
|
|
/// </summary>
|
|
public async Task<ExpeditionDto?> GetDtoByIdAsync(int id)
|
|
{
|
|
try
|
|
{
|
|
var dto = await _http.GetFromJsonAsync<ExpeditionDto>($"/expedition/{id}");
|
|
return dto;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine($"Error al obtener ExpeditionDto por ID: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Descarga el PDF de la expedición en el navegador usando saveAsFile (base64).
|
|
/// </summary>
|
|
public async Task ExportPdfAsync(int expeditionId, string expeditionNumber)
|
|
{
|
|
try
|
|
{
|
|
var response = await _http.GetAsync($"/api/expedition/{expeditionId}/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 = $"{expeditionNumber}.pdf";
|
|
|
|
await _js.InvokeVoidAsync("saveAsFile", fileName, base64);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var message = ex.Message ?? "No message";
|
|
throw new Exception($"ExportPdfAsync: {message}", ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Contrato de request simétrico a CreateFullQuoteRequest.
|
|
/// </summary>
|
|
public class CreateFullExpeditionRequest
|
|
{
|
|
public ELSExpeditionHeader Expedition { get; set; } = default!;
|
|
public int FormSeriesId { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resultado del create/issue simétrico a CreateQuoteResult.
|
|
/// </summary>
|
|
public class CreateExpeditionResult
|
|
{
|
|
public bool Success { get; set; }
|
|
public int Id { get; set; }
|
|
public string ExpeditionNumber { get; set; } = string.Empty;
|
|
public string ErrorMessage { get; set; } = string.Empty;
|
|
}
|
|
|
|
// TODO: Ajustar namespace real si es distinto
|
|
public class ExpeditionDto
|
|
{
|
|
// Estructura mínima para compilar si aún no referenciás el DTO real.
|
|
// Reemplazar por el DTO definitivo de Domain.Dtos.
|
|
public int Id { get; set; }
|
|
public string ExpeditionNumber { get; set; } = string.Empty;
|
|
public string Status { get; set; } = string.Empty;
|
|
public DateTime IssueDate { get; set; }
|
|
public string? CustomerName { get; set; }
|
|
public string? ProfessionalName { get; set; }
|
|
public string? InstitutionName { get; set; }
|
|
public string? PatientName { get; set; }
|
|
public List<ExpeditionItemDto> Items { get; set; } = new();
|
|
public string? Observations { get; set; }
|
|
}
|
|
|
|
public class ExpeditionItemDto
|
|
{
|
|
public int ProductId { get; set; }
|
|
public string ProductName { get; set; } = string.Empty;
|
|
public decimal Quantity { get; set; }
|
|
public string? Batch { get; set; }
|
|
public string? Serial { get; set; }
|
|
public DateOnly? Expiration { get; set; }
|
|
public int? LocationId { get; set; }
|
|
}
|
|
|
|
} |