feat(sales): precargar ítems aprobados desde presupuesto en delivery note create closes #39
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (pull_request) Successful in 8m47s

This commit is contained in:
Leandro Hernan Rojas 2026-03-24 18:05:37 -03:00
parent ed06dac9be
commit 80e9a7f146
2 changed files with 100 additions and 7 deletions

View File

@ -2,14 +2,19 @@
@using System.ComponentModel.DataAnnotations
@using Blazored.Typeahead
@using Domain.Constants
@using Domain.Dtos
@using Domain.Dtos.Sales
@using phronCare.UIBlazor.Services.Lookups
@using phronCare.UIBlazor.Services.Sales.DeliveryNotes
@using phronCare.UIBlazor.Services.Sales.Quotes
@using phronCare.UIBlazor.Shared.Modals
@inject NavigationManager Navigation
@inject IDeliveryNoteService DeliveryNoteService
@inject ISalesLookupService SalesLookupService
@inject IQuoteService QuoteService
@inject IToastService toastService
@inject IModalService Modal
<EditForm Model="Model" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
@ -90,7 +95,7 @@
@if (Items.Any())
{
<div class="table-responsive">
<table class="table table-sm table-bordered align-middle mb-0">
<table class="table table-sm table-bordered mb-0 deliverynote-items-table">
<thead class="table-light">
<tr>
<th style="width: 60px;" class="text-center">#</th>
@ -105,9 +110,9 @@
@foreach (var item in Items)
{
<tr>
<td class="text-center">@item.LineNumber</td>
<td class="text-center line-number-cell">@item.LineNumber</td>
<td>
<InputText class="form-control form-control-sm" @bind-Value="item.Description" />
<InputTextArea class="form-control form-control-sm item-description" rows="3" @bind-Value="item.Description" />
</td>
<td>
<InputNumber class="form-control form-control-sm text-end" @bind-Value="item.Quantity" />
@ -121,9 +126,9 @@
</InputSelect>
</td>
<td>
<InputText class="form-control form-control-sm" @bind-Value="item.Notes" />
<InputTextArea class="form-control form-control-sm item-notes" rows="3" @bind-Value="item.Notes" />
</td>
<td class="text-center">
<td class="text-center actions-cell">
<button type="button" class="btn btn-link p-0 text-danger" title="Eliminar" @onclick="() => RemoveItem(item)">
<i class="fas fa-trash"></i>
</button>
@ -203,11 +208,66 @@
return Task.CompletedTask;
}
private Task OnQuoteSelected(ELookUpItem? quote)
private async Task OnQuoteSelected(ELookUpItem? quote)
{
SelectedQuote = quote;
Model.QuoteId = quote?.Id;
return Task.CompletedTask;
if (quote is null)
return;
var quoteDto = await QuoteService.GetDtoByIdAsync(quote.Id);
if (quoteDto is null)
{
toastService.ShowError("No se pudo cargar el presupuesto seleccionado.");
return;
}
var mappedItems = BuildItemsFromApprovedQuote(quoteDto);
if (mappedItems.Count == 0)
{
toastService.ShowWarning("El presupuesto seleccionado no tiene ítems aprobados para precargar.");
return;
}
if (Items.Any())
{
var parameters = new ModalParameters();
parameters.Add(nameof(ConfirmModal.Title), "Reemplazar ítems");
parameters.Add(nameof(ConfirmModal.Message), "Ya hay ítems cargados. ¿Desea reemplazarlos por los ítems aprobados del presupuesto?");
var modal = Modal.Show<ConfirmModal>("Confirmación", parameters);
var result = await modal.Result;
if (result.Cancelled)
return;
}
Items = mappedItems;
ReindexItems();
StateHasChanged();
}
private List<DeliveryNoteItemRow> BuildItemsFromApprovedQuote(QuoteDto quote)
{
return quote.Items
.Where(item => item.Approved)
.Select(item => new
{
Item = item,
Quantity = item.ApprovedQuantity.HasValue && item.ApprovedQuantity.Value > 0
? item.ApprovedQuantity.Value
: item.Quantity
})
.Where(x => x.Quantity > 0)
.Select((x, index) => new DeliveryNoteItemRow
{
LineNumber = index + 1,
OriginType = (byte)DeliveryNoteItemOriginType.QuoteDetail,
QuoteDetailId = x.Item.Id,
Description = x.Item.Description,
Quantity = x.Quantity
})
.ToList();
}
private string? ValidateBeforeSave()

View File

@ -0,0 +1,33 @@
.deliverynote-items-table td {
vertical-align: top;
padding-top: 0.75rem;
padding-bottom: 0.75rem;
}
.deliverynote-items-table .line-number-cell,
.deliverynote-items-table .actions-cell {
vertical-align: middle;
}
.deliverynote-items-table .form-control,
.deliverynote-items-table .form-select {
min-height: 38px;
}
.deliverynote-items-table .item-description,
.deliverynote-items-table .item-notes {
min-height: calc(1.5em * 3 + 1rem + 2px);
resize: vertical;
}
.deliverynote-items-table textarea.form-control {
line-height: 1.35;
}
.deliverynote-items-table .text-end {
min-width: 90px;
}
.deliverynote-items-table .actions-cell .btn {
margin-top: 0.35rem;
}