@page "/stock/expeditions/create" @using Blazored.Typeahead @using Domain.Dtos.Stock @using Domain.Entities @using Services.Lookups @using Services.Stock.Expeditions @using phronCare.UIBlazor.Pages.Stock.Shared @* @using static phronCare.UIBlazor.Pages.Stock.Shared.StockItemSelectorModal *@ @inject NavigationManager Navigation @inject ExpeditionService expeditionService @* @inject Lookup lookUpService *@ @inject ISalesLookupService lookUpService @inject IToastService toastService @inject IModalService Modal

Nueva Expedición

@item.Nombre @item.Nombre
@if (!string.IsNullOrWhiteSpace(DispatchInstruction)) {
Instrucciones desde presupuesto:
@DispatchInstruction
}
Productos a Expedir
@if (Details.Any()) { @foreach (var item in Details) { }
Producto Cant. Lote Serial Vencimiento Ubicación
@item.ProductId @item.Quantity @item.Batch @item.Serial @item.Expiration?.ToString("yyyy-MM-dd") @item.LocationId
} else {

No hay productos agregados.

}
@code { private ELSExpeditionHeader Model = new(); private ExtraInfoModel ExtraInfo = new(); private string DispatchInstruction = string.Empty; private ELookUpItem? SelectedQuote; private List Details = new(); private List ProductSetItems = new(); private string ticketIdString { get => Model.TicketId?.ToString() ?? string.Empty; set => Model.TicketId = Guid.TryParse(value, out var guid) ? guid : null; } private async Task> SearchQuotes(string filter) { return await lookUpService.SearchApprovedQuotesAsync(filter); } private async Task OnQuoteSelected(ELookUpItem? selected) { if (selected is null || string.IsNullOrWhiteSpace(selected.Nombre)) { SelectedQuote = null; ExtraInfo = new(); // Limpiar datos cargados DispatchInstruction = ""; return; } SelectedQuote = selected; var quoteNumber = selected.Nombre.Split(" - ")[0]; var quote = await expeditionService.GetQuoteByNumberAsync(quoteNumber); if (quote is null) { toastService.ShowError("No se pudo cargar el presupuesto."); return; } ExtraInfo.Professional = quote.ProfessionalName; ExtraInfo.Institution = quote.InstitutionName; ExtraInfo.Patient = quote.PatientName; ExtraInfo.SurgeryDate = quote.EstimatedDate; DispatchInstruction = quote.Observations ?? ""; } private void AddProduct() { // TODO: abrir modal de producto individual } private void AddSet() { // TODO: abrir modal de set } private void ScanProduct() { // TODO: activar input de escáner } private void RemoveItem(ELSExpeditionDetail item) { Details.Remove(item); } private async Task HandleValidSubmit() { // TODO: Lógica de guardado de la expedición completa } private async Task OpenStockItemSelectorModal() { var parameters = new ModalParameters(); parameters.Add(nameof(StockItemSelectorModal.SetItems), ProductSetItems); // o null //parameters.Add(nameof(StockItemSelectorModal.LocationId), SelectedLocationId); var options = new ModalOptions() { Size = ModalSize.Large, HideHeader = true }; var modal = Modal.Show("", parameters, options); var result = await modal.Result; if (!result.Cancelled && result.Data is List selectedItems) { foreach (var s in selectedItems) { var detail = new ELSExpeditionDetail { ProductId = s.ProductId, Quantity = s.Quantity, // si es Serial*, probablemente 1 Batch = s.Batch, Expiration = s.Expiration.HasValue ? DateOnly.FromDateTime(s.Expiration.Value) : (DateOnly?)null, Serial = s.Serial, // si es Serial*, probablemente null LocationId = s.LocationId // si tu detalle lo maneja }; Details.Add(detail); } StateHasChanged(); toastService.ShowSuccess($"{selectedItems.Count} item(s) agregados a la expedición."); } } private class ExtraInfoModel { public string? Professional { get; set; } public string? Institution { get; set; } public string? Patient { get; set; } public DateTime? SurgeryDate { get; set; } } }