From c1aa6827b06a0130c60beb4cd877f16481ca0c0b Mon Sep 17 00:00:00 2001 From: leandro Date: Tue, 24 Mar 2026 21:47:02 -0300 Subject: [PATCH] =?UTF-8?q?feat(deliverynote):=20snapshot=20cl=C3=ADnico?= =?UTF-8?q?=20(ExtraInfo)=20desde=20presupuesto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Se implementa la construcción automática de ExtrainfoJson al seleccionar un presupuesto en la pantalla de emisión de Delivery Note. - Se genera snapshot clínico con Professional, Institution, Patient y SurgeryDate - Se serializa a JSON plano utilizando System.Text.Json - Se asigna a Model.ExtraInfoJson para persistencia - Se limpia el snapshot al deseleccionar o fallar la carga del presupuesto Se mantiene consistencia con el patrón implementado en Expeditions. No se modifican contratos ni capas Core/API/Data. Closes #41 --- .../DeliveryNotes/DeliveryNoteCreate.razor | 75 +++++++++++++++++-- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/phronCare.UIBlazor/Pages/Sales/DeliveryNotes/DeliveryNoteCreate.razor b/phronCare.UIBlazor/Pages/Sales/DeliveryNotes/DeliveryNoteCreate.razor index 4b86afc..7d4d006 100644 --- a/phronCare.UIBlazor/Pages/Sales/DeliveryNotes/DeliveryNoteCreate.razor +++ b/phronCare.UIBlazor/Pages/Sales/DeliveryNotes/DeliveryNoteCreate.razor @@ -1,5 +1,6 @@ @page "/deliverynotes/create" @using System.ComponentModel.DataAnnotations +@using System.Text.Json @using Blazored.Typeahead @using Domain.Constants @using Domain.Dtos @@ -27,12 +28,12 @@
-
+
-
+
@@ -51,10 +52,7 @@ @item.Nombre
-
- -
-
+
+
+ +
+
+ @if (SelectedQuote is not null) + { + +
+ Presupuesto vinculado: @SelectedQuote.Nombre +
+ } +
@if (SelectedQuote is not null) { -
- Presupuesto vinculado: @SelectedQuote.Nombre +
+
+
+
+ +
@(string.IsNullOrWhiteSpace(ExtraInfo.Professional) ? "No informado" : ExtraInfo.Professional)
+
+
+ +
@(string.IsNullOrWhiteSpace(ExtraInfo.Institution) ? "No informada" : ExtraInfo.Institution)
+
+
+ +
@(string.IsNullOrWhiteSpace(ExtraInfo.Patient) ? "No informado" : ExtraInfo.Patient)
+
+
+ +
@(ExtraInfo.SurgeryDate.HasValue ? ExtraInfo.SurgeryDate.Value.ToString("dd/MM/yyyy") : "No informada")
+
+
+
}
@@ -171,6 +200,7 @@ private ELookUpItem? SelectedCustomer; private ELookUpItem? SelectedQuote; + private DeliveryNoteExtraInfoModel ExtraInfo = new(); private List Items = new(); private bool IsSaving; @@ -214,18 +244,27 @@ Model.QuoteId = quote?.Id; if (quote is null) + { + ExtraInfo = new(); + Model.ExtraInfoJson = null; return; + } var quoteDto = await QuoteService.GetDtoByIdAsync(quote.Id); if (quoteDto is null) { + ExtraInfo = new(); + Model.ExtraInfoJson = null; toastService.ShowError("No se pudo cargar el presupuesto seleccionado."); return; } + ExtraInfo = BuildExtraInfoModel(quoteDto); + var mappedItems = BuildItemsFromApprovedQuote(quoteDto); if (mappedItems.Count == 0) { + Model.ExtraInfoJson = JsonSerializer.Serialize(ExtraInfo); toastService.ShowWarning("El presupuesto seleccionado no tiene ítems aprobados para precargar."); return; } @@ -243,10 +282,22 @@ } Items = mappedItems; + Model.ExtraInfoJson = JsonSerializer.Serialize(ExtraInfo); ReindexItems(); StateHasChanged(); } + private static DeliveryNoteExtraInfoModel BuildExtraInfoModel(QuoteDto quote) + { + return new DeliveryNoteExtraInfoModel + { + Professional = quote.ProfessionalName, + Institution = quote.InstitutionName, + Patient = quote.PatientName, + SurgeryDate = quote.EstimatedDate + }; + } + private List BuildItemsFromApprovedQuote(QuoteDto quote) { return quote.Items @@ -351,6 +402,14 @@ public string? ExtraInfoJson { get; set; } } + private sealed class DeliveryNoteExtraInfoModel + { + public string? Professional { get; set; } + public string? Institution { get; set; } + public string? Patient { get; set; } + public DateTime? SurgeryDate { get; set; } + } + private sealed class DeliveryNoteItemRow { public int LineNumber { get; set; }