feat(sales): precargar ítems aprobados desde presupuesto en delivery note create #40
@ -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()
|
||||
|
||||
@ -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;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user