From f1e7e65c4f53b0d900335ed17f18d010cacdac52 Mon Sep 17 00:00:00 2001 From: Leandro Hernan Rojas Date: Wed, 27 Aug 2025 09:17:00 -0300 Subject: [PATCH] Update Fix2 Expedition And ScanGS! --- .../Stock/Expeditions/ExpeditionCreate.razor | 127 +++++++----------- .../Expeditions/ExpeditionCreate.razor.css | 12 ++ phronCare.UIBlazor/phronCare.UIBlazor.csproj | 4 + 3 files changed, 61 insertions(+), 82 deletions(-) create mode 100644 phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor.css diff --git a/phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor b/phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor index a210aa5..dff0bff 100644 --- a/phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor +++ b/phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor @@ -4,6 +4,7 @@ @using Domain.Entities @using Services.Lookups @using Services.Stock.Expeditions + @using phronCare.UIBlazor.Pages.Stock.Shared @inject NavigationManager Navigation @@ -43,9 +44,7 @@
- +
@@ -104,35 +103,39 @@
@if (Details.Any()) { - - - - - - - - - - - - - - @foreach (var item in Details) - { +
+
ProductoCant.LoteSerialVencimientoUbicación
+ - - - - - - - + + + + + + + - } - -
@item.ProductId@item.Quantity@item.Batch@item.Serial@item.Expiration?.ToString("yyyy-MM-dd")@item.LocationId - - ProductoCant.LoteSerialVencimientoUbicación
+ + + @foreach (var item in Details) + { + + @item.ProductId + @item.Quantity + @item.Batch + @item.Serial + @item.Expiration?.ToString("yyyy-MM-dd") + @item.LocationId + + + + + } + + +
} else { @@ -220,48 +223,6 @@ // 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, - // TraceabilityType=s.TraceabilityType, //agregado al model pero no es registrable en la entidad - // 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 async Task OpenStockItemSelectorModal() { var parameters = new ModalParameters(); @@ -299,10 +260,9 @@ StockKeys.BuildBusinessKey(d.ProductId, d.LocationId, d.Batch ?? string.Empty, d.Expiration, d.Serial ?? string.Empty) == key ); - // Normalizo cantidad pedida desde el modal (total final) var newQty = s.Quantity < 0 ? 0 : s.Quantity; - // Serial ⇒ siempre 1 (ignora lo que venga) + // Serial ⇒ siempre 1 if (!string.IsNullOrWhiteSpace(s.Serial)) newQty = 1; @@ -310,24 +270,29 @@ { if (newQty == 0) { - // Si el modal dejó en 0, se elimina la fila + if (existing.Quantity > 0) + { + // ⚠️ Caso snapshot con 0 → ignorar, mantener la fila + continue; + } + + // 0 explícito válido → borrar Details.Remove(existing); } else { - // SET (no sumar): que quede exactamente como en el modal + // SET: exactamente lo que vino del modal existing.Quantity = newQty; - existing.ProductName = s.ProductName; // opcional, por si viene actualizado + existing.ProductName = s.ProductName; existing.Batch = s.Batch; existing.Serial = s.Serial; existing.Expiration = exp; existing.LocationId = s.LocationId; - existing.TraceabilityType = s.TraceabilityType; // UI only + existing.TraceabilityType = s.TraceabilityType; } } else { - // Si no existía y la cantidad es > 0, crear nueva fila if (newQty > 0) { Details.Add(new ELSExpeditionDetail @@ -337,12 +302,11 @@ Quantity = newQty, Batch = s.Batch, Expiration = exp, - TraceabilityType = s.TraceabilityType, // UI only (no DB) + TraceabilityType = s.TraceabilityType, Serial = s.Serial, LocationId = s.LocationId }); } - // Si newQty == 0 y no existía, no hay nada que hacer } } } @@ -381,5 +345,4 @@ }; }).ToList(); } - } diff --git a/phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor.css b/phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor.css new file mode 100644 index 0000000..c5e7b9c --- /dev/null +++ b/phronCare.UIBlazor/Pages/Stock/Expeditions/ExpeditionCreate.razor.css @@ -0,0 +1,12 @@ +.expedition-table-wrap { + max-height: 200px; /* controla la altura visible */ + overflow-y: auto; /* genera el scrollbar vertical */ +} + +/* Sticky header */ +.expedition-table thead th { + position: sticky; + top: 0; + z-index: 2; + background: #f8f9fa; /* mismo color que .table-light */ +} diff --git a/phronCare.UIBlazor/phronCare.UIBlazor.csproj b/phronCare.UIBlazor/phronCare.UIBlazor.csproj index 89da6f4..395a442 100644 --- a/phronCare.UIBlazor/phronCare.UIBlazor.csproj +++ b/phronCare.UIBlazor/phronCare.UIBlazor.csproj @@ -33,4 +33,8 @@ + + + +