feat(deliverynote): snapshot clínico (ExtraInfo) desde presupuesto #42

Merged
leandro merged 1 commits from feature/leandro/41-deliverynote-extrainfo-snapshot into master 2026-03-25 00:48:31 +00:00

View File

@ -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 @@
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-md-4">
<div class="col-md-2">
<label for="deliveryNoteNumber" class="form-label">Número de remito</label>
<InputText id="deliveryNoteNumber" class="form-control" @bind-Value="Model.DeliveryNoteNumber" />
<ValidationMessage For="@(() => Model.DeliveryNoteNumber)" />
</div>
<div class="col-md-4">
<div class="col-md-2">
<label for="issueDate" class="form-label">Fecha de emisión</label>
<InputDate id="issueDate" class="form-control" @bind-Value="Model.IssueDate" />
<ValidationMessage For="@(() => Model.IssueDate)" />
@ -51,10 +52,7 @@
<SelectedTemplate Context="item">@item.Nombre</SelectedTemplate>
</BlazoredTypeahead>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="col-md-4">
<label for="customerLookup" class="form-label">Cliente</label>
<BlazoredTypeahead id="customerLookup" TItem="ELookUpItem" TValue="ELookUpItem"
SearchMethod="SalesLookupService.SearchCustomersAsync"
@ -69,16 +67,47 @@
</BlazoredTypeahead>
<ValidationMessage For="@(() => Model.CustomerId)" />
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="observations" class="form-label">Observaciones</label>
<InputTextArea id="observations" class="form-control" rows="3" @bind-Value="Model.Observations" />
</div>
<div class="col-md-6">
@if (SelectedQuote is not null)
{
<label for="observations" class="form-label">Vinculado</label>
<div class="alert alert-dark border mb-3">
<strong rows="3">Presupuesto vinculado:</strong> @SelectedQuote.Nombre
</div>
}
</div>
</div>
@if (SelectedQuote is not null)
{
<div class="alert alert-light border mb-0">
<strong>Presupuesto vinculado:</strong> @SelectedQuote.Nombre
<div class="card border-1 bg-light-subtle">
<div class="card-body py-3">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label fw-semibold mb-1">Profesional</label>
<div class="form-control bg-white">@(string.IsNullOrWhiteSpace(ExtraInfo.Professional) ? "No informado" : ExtraInfo.Professional)</div>
</div>
<div class="col-md-6">
<label class="form-label fw-semibold mb-1">Institución</label>
<div class="form-control bg-white">@(string.IsNullOrWhiteSpace(ExtraInfo.Institution) ? "No informada" : ExtraInfo.Institution)</div>
</div>
<div class="col-md-6">
<label class="form-label fw-semibold mb-1">Paciente</label>
<div class="form-control bg-white">@(string.IsNullOrWhiteSpace(ExtraInfo.Patient) ? "No informado" : ExtraInfo.Patient)</div>
</div>
<div class="col-md-6">
<label class="form-label fw-semibold mb-1">Fecha estimada de cirugía</label>
<div class="form-control bg-white">@(ExtraInfo.SurgeryDate.HasValue ? ExtraInfo.SurgeryDate.Value.ToString("dd/MM/yyyy") : "No informada")</div>
</div>
</div>
</div>
</div>
}
</div>
@ -171,6 +200,7 @@
private ELookUpItem? SelectedCustomer;
private ELookUpItem? SelectedQuote;
private DeliveryNoteExtraInfoModel ExtraInfo = new();
private List<DeliveryNoteItemRow> 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<DeliveryNoteItemRow> 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; }