Files
HerramientaCASA/HerramientaCASA/Components/Pages/HerramientaCASATabs/CostesProduccionComponents/CostesVariables.razor
2025-07-25 12:56:07 +02:00

531 lines
19 KiB
Plaintext

@using System.Globalization
<Toasts class="p-3 font-weight-bold" Style="color:white;" AutoHide="true" Delay="4000" Messages="mensajes" Placement="ToastsPlacement.BottomCenter" />
<Modal @ref="popupConfirmarBorrado" title="" IsVerticallyCentered="true" UseStaticBackdrop="true" CloseOnEscape="false">
<BodyTemplate>
<div class="col-12 formatoCampos">
¿Estás seguro que desea eliminarlo?
</div>
</BodyTemplate>
<FooterTemplate>
<Button Color="ButtonColor.Secondary" @onclick="cerrarPopupConfirmarBorrado">Cerrar</Button>
<Button @onclick="@(() => BorrarItem())" Color="ButtonColor.Danger">Eliminar</Button>
</FooterTemplate>
</Modal>
<EditForm EditContext="@editContext" OnValidSubmit="guardarFormulario" OnInvalidSubmit="@MostrarErrores" FormName="tiposForm">
<DataAnnotationsValidator></DataAnnotationsValidator>
<Modal @ref="popupGestionDatos" title="@tituloPopup" IsVerticallyCentered="true" UseStaticBackdrop="true" CloseOnEscape="false">
<BodyTemplate>
<div class="col-12 formatoCampos pt-2">
<label class="tituloLbl">Coste Variable:</label>
<InputSelect @bind-Value="@itemSeleccionadoTemporal.idCoste" class="inputForm" @oninput="e => ValidarYActualizar(e, nameof(itemSeleccionadoTemporal.idCoste))">
@foreach (var grupoTipologia in objetoCASA.Enumerados.ListaCostesVariables)
{
<option value="@grupoTipologia.idEnumeracion">@grupoTipologia.ValorAlfabetico1</option>
}
</InputSelect>
<div class="validation-message">@GetExternalValidationMessage(nameof(itemSeleccionadoTemporal.idCoste))</div>
</div>
<div class="row">
<div class="col-12 formatoCampos pt-2">
<label class="tituloLbl">Coste:</label>
<div class="d-flex" style="gap:3px;">
<InputNumber TValue="double" @bind-Value="itemSeleccionadoTemporal.Coste"
step="any"
@oninput="e => ValidarYActualizar(e, nameof(itemSeleccionadoTemporal.Coste))"
class="inputForm text-end" /> €
</div>
</div>
<div class="validation-message">@GetExternalValidationMessage(nameof(itemSeleccionadoTemporal.Coste))</div>
</div>
</BodyTemplate>
<FooterTemplate>
<Button Color="ButtonColor.Secondary" @onclick="cerrarPopupGestionDatos">Cerrar</Button>
<Button Type="ButtonType.Submit" Color="ButtonColor.Primary">@(nuevoElemento ? "Añadir" : "Modificar")</Button>
</FooterTemplate>
</Modal>
</EditForm>
<div class="row">
<div class="col-md-4 mb-3">
<b>Costes variables</b>
<div class="pt-1 col-md-12 d-flex" style="gap: 40px; height:25px;">
<div class="d-flex">
<RadioInput style="margin-right: 10px;" Label="Calcular" Value="esCalcular" ValueExpression="() => esCalcular" ValueChanged="(value) => esCalcularChanged(value)" />
<RadioInput style="margin-right: 10px; margin-left:10px;" Label="% sobre los costes de producción" Value="esPorcentajeCostes" ValueExpression="() => esPorcentajeCostes" ValueChanged="(value) => esPorcentajeCostesChanged(value)" />
@if (esPorcentajeCostes)
{
<p class="ms-3">
<InputNumber TValue="double" Value="@porcentajeCostes" ValueExpression="() => porcentajeCostes"
step="any"
style="width:60px;"
ValueChanged="(value) => porcentajeCambiado(value)"
class="inputForm text-end" /> %
</p>
}
</div>
</div>
@if (esCalcular)
{
<div style="position:relative;margin-bottom: 19px;">
<Grid TItem="CASA.CosteVariable"
Class="tablaCACOA table"
Data="listCostesVariables"
AllowFiltering="false"
PageSize="10"
Height="100"
EmptyText="No hay registros."
PageSizeSelectorVisible="false"
Responsive="true">
<GridColumns>
<GridColumn TItem="CASA.CosteVariable" HeaderTextAlignment="Alignment.Center" HeaderText="Conceptos" Class="colorB columna50Ancho">
@context.Denominacion
</GridColumn>
<GridColumn TItem="CASA.CosteVariable" HeaderTextAlignment="Alignment.Center" Class="formatoMoneda columna40Ancho text-end" HeaderText="Coste">
@context.Coste.MilesYDecimales() €
</GridColumn>
<GridColumn TItem="CASA.CosteVariable" Class="botonesTabla" HeaderText="">
<div class="btnTablasEspaciado">
<span @onclick="@(() => abrirPopupGestionDatos(@context,false))" class="btnBorrarGuardar">
<Icon CustomIconName="fas fa-edit"></Icon>
</span>
<span @onclick="@(() => abrirPopupConfirmarBorrado(@context))" class="btnBorrarGuardar">
<Icon CustomIconName="fas fa-trash"></Icon>
</span>
</div>
</GridColumn>
</GridColumns>
</Grid>
<table class="table tablaCACOA mb-0" style="position:absolute;bottom:-33px;">
<tfoot>
<tr>
<td colspan="2" class="text-end fw-bold colorC">
<div class="d-flex justify-content-between">
<div class="mt-1" style="height:28px">
<button @onclick="@(() => abrirPopupGestionDatos(new CASA.CosteVariable(),true))" class="btnBlue d-flex align-items-center"> <i class="fas fa-plus-square pe-1"></i> Añadir coste variable</button>
</div>
<div style="align-self: center;">
Total costes variables: <span> @objetoCASA.CostesProduccion.TotalCostesVariables.MilesYDecimales() €</span>
</div>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
}
</div>
<div class="col-md-4" style="align-items: flex-end;">
<div style="height: 49px;">
<b>Coste hora Despacho Profesional</b>
</div>
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Tipo de costes</th>
<th class="colorB fw-bold">Coste/hora</th>
</tr>
</thead>
<tbody>
<tr>
<td class="colorB w4">Costes directos</td>
<td class="text-end">@objetoCASA.DespachoProfesional.CostesDirectos.MilesYDecimales() €/hora</td>
</tr>
<tr>
<td class="colorB ">Costes indirectos</td>
<td class="text-end">@objetoCASA.DespachoProfesional.TasaCostesIndirectos.MilesYDecimales() €/hora</td>
</tr>
<tr>
<td class="colorB ">Costes variables</td>
<td class="text-end">@objetoCASA.CostesProduccion.CostesVariables.MilesYDecimales() €/hora</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" class="text-end fw-bold colorC">
<div style="height:28px; align-content:center;">
Total Coste hora Despacho Profesional: <span> @objetoCASA.CostesProduccion.TotalCostes.MilesYDecimales() €/hora</span>
</div>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="col-md-4">
<div style="height: 49px;">
<b>Coste hora Externalización</b>
</div>
<div class="table-responsive">
<table class="table tablaCACOA tablaCACOA2 mb-0">
<thead>
<tr>
<th class="colorB fw-bold">Externalización</th>
<th class="colorB fw-bold">Porcentaje</th>
</tr>
</thead>
<tbody>
<tr>
<td class="colorFilasIntro w4">Incremento por externalización</td>
<td class="text-end">
<div class="d-flex" style="gap:3px">
<InputNumber TValue="double" Locale="es-ES" Min="0" class="inputForm formatoMoneda inputTabla" Value="@objetoCASA.CostesProduccion.CoeficienteCostesExternalizacion" ValueExpression="() => objetoCASA.CostesProduccion.CoeficienteCostesExternalizacion" ValueChanged="(value) => CosteExtCambiado(value)"></InputNumber> %
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" class="text-end fw-bold colorC">
Coste hora Externalización: <span> @objetoCASA.CostesProduccion.CosteHoraExternalizacion.MilesYDecimales() €/hora</span>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
@code {
[Parameter]
public CASA objetoCASA { get; set; } = new CASA();
List<CASA.CosteVariable> listCostesVariables = new List<CASA.CosteVariable>();
private bool esCalcular = true;
private bool esPorcentajeCostes = false;
private double porcentajeCostes;
private bool editarElemento;
[SupplyParameterFromForm]
private CASA.CosteVariable itemSeleccionado { get; set; } = new CASA.CosteVariable();
private CASA.CosteVariable itemSeleccionadoTemporal { get; set; } = new CASA.CosteVariable();
private string tituloPopup = "";
private Modal popupGestionDatos = default!;
private Modal popupConfirmarBorrado = default!;
private bool nuevoElemento;
private ValidationMessageStore? messageStore;
private EditContext editContext;
List<ToastMessage> mensajes = new List<ToastMessage>();
[CascadingParameter]
public CostesProduccion _Parent { get; set; }
protected override async Task OnInitializedAsync()
{
editContext = new EditContext(itemSeleccionado);
messageStore = new ValidationMessageStore(editContext);
listCostesVariables = objetoCASA.CostesProduccion.ListaCostesVariables.ToList();
porcentajeCostes = objetoCASA.CostesProduccion.porcentaje;
esCalcular = objetoCASA.CostesProduccion.EsCalculado;
if (!esCalcular)
{
esPorcentajeCostes = true;
}
}
private void porcentajeCambiado(double porcentajeCostesCambiado)
{
porcentajeCostes = porcentajeCostesCambiado;
objetoCASA.CostesProduccion.porcentaje = porcentajeCostes;
esPorcentajeCostesChanged(true);
}
private async void CosteExtCambiado(double e)
{
objetoCASA.CostesProduccion.CoeficienteCostesExternalizacion = e;
objetoCASA.CalcularCostesProduccion();
await InvokeAsync(StateHasChanged);
_Parent.RefreshState();
}
private async void esCalcularChanged(bool res)
{
esCalcular = res;
esPorcentajeCostes = !res;
objetoCASA.CostesProduccion.EsCalculado = res;
objetoCASA.CalcularCostesProduccion();
await InvokeAsync(StateHasChanged);
_Parent.RefreshState();
}
private async void esPorcentajeCostesChanged(bool res)
{
esPorcentajeCostes = res;
esCalcular = !res;
objetoCASA.CostesProduccion.EsCalculado = !res;
objetoCASA.CalcularCostesProduccion();
await InvokeAsync(StateHasChanged);
_Parent.RefreshState();
}
private async void CosteVariableCambiado(double e, CASA.CosteVariable objeto)
{
objeto.Coste = (int)e;
objetoCASA.ActualizarCostesVariables(objeto);
await InvokeAsync(StateHasChanged);
_Parent.RefreshState();
}
private async Task GestionarDatos(string accion)
{
switch (accion)
{
case "update":
rellenarItem();
itemSeleccionado.Denominacion = objetoCASA.Enumerados.ListaCostesVariables.First(x => x.idEnumeracion == itemSeleccionado.idCoste).ValorAlfabetico1;
objetoCASA.ActualizarCostesVariables(itemSeleccionado);
await cerrarPopupGestionDatos();
mensajes.Add(new ToastMessage
{
Type = ToastType.Primary,
Message = $"Actualizado correctamente.",
});
break;
case "create":
rellenarItem();
itemSeleccionado.Denominacion = objetoCASA.Enumerados.ListaCostesVariables.First(x => x.idEnumeracion == itemSeleccionado.idCoste).ValorAlfabetico1;
objetoCASA.InsertarCostesVariables(itemSeleccionado);
await cerrarPopupGestionDatos();
mensajes.Add(new ToastMessage
{
Type = ToastType.Primary,
Message = $"Guardado correctamente.",
});
break;
case "delete":
objetoCASA.EliminarCostesVariables(itemSeleccionado);
await cerrarPopupConfirmarBorrado();
mensajes.Add(new ToastMessage
{
Type = ToastType.Primary,
Message = $"Eliminado correctamente.",
});
break;
}
listCostesVariables = objetoCASA.CostesProduccion.ListaCostesVariables.ToList();
await InvokeAsync(StateHasChanged);
_Parent.RefreshState();
}
private async Task BorrarItem()
{
await GestionarDatos("delete");
}
private async Task abrirPopupGestionDatos(CASA.CosteVariable objeto, bool esNuevo)
{
itemSeleccionado = objeto;
if (esNuevo)
{
nuevoElemento = true;
itemSeleccionadoTemporal = new CASA.CosteVariable();
}
else
{
nuevoElemento = false;
itemSeleccionadoTemporal = new CASA.CosteVariable()
{
Coste = objeto.Coste,
Denominacion = objeto.Denominacion,
idCoste = objeto.idCoste
};
}
if (!nuevoElemento)
{
tituloPopup = "Modificar Coste Variable";
}
else
{
tituloPopup = "Nuevo Coste Variable";
}
await popupGestionDatos.ShowAsync();
}
private async Task cerrarPopupGestionDatos()
{
await popupGestionDatos.HideAsync();
}
private void ValidarYActualizar(ChangeEventArgs e, string fieldName)
{
var value = e.Value?.ToString();
var field = new FieldIdentifier(itemSeleccionadoTemporal, fieldName);
switch (fieldName)
{
case nameof(itemSeleccionadoTemporal.Coste):
if (!string.IsNullOrEmpty(value))
{
string parseado = value.Replace(",", ".");
itemSeleccionadoTemporal.Coste = double.Parse(parseado, CultureInfo.InvariantCulture);
}
break;
case nameof(itemSeleccionadoTemporal.idCoste):
if (!string.IsNullOrEmpty(value))
{
itemSeleccionadoTemporal.idCoste = int.Parse(value);
}
else
{
itemSeleccionadoTemporal.idCoste = 0;
}
break;
}
messageStore?.Clear(field);
if (fieldName == nameof(itemSeleccionadoTemporal.Coste) && itemSeleccionadoTemporal.Coste <= 0)
{
messageStore?.Add(field, "El coste debe ser mayor que 0.");
}
if (fieldName == nameof(itemSeleccionadoTemporal.idCoste) && itemSeleccionadoTemporal.idCoste == 0)
{
messageStore?.Add(field, "Seleccione un coste.");
}
editContext?.NotifyValidationStateChanged();
}
private void ValidarTodo()
{
ValidarYActualizar(new ChangeEventArgs { Value = itemSeleccionadoTemporal.Coste }, nameof(itemSeleccionadoTemporal.Coste));
ValidarYActualizar(new ChangeEventArgs { Value = itemSeleccionadoTemporal.idCoste }, nameof(itemSeleccionadoTemporal.idCoste));
}
private string GetExternalValidationMessage(string fieldName)
{
var field = new FieldIdentifier(itemSeleccionadoTemporal, fieldName);
return messageStore?[field].FirstOrDefault() ?? string.Empty;
}
// GUARDAR
private async Task guardarFormulario()
{
try
{
ValidarTodo();
if (!editContext!.GetValidationMessages().Any())
{
string accion = nuevoElemento ? "create" : "update";
GestionarDatos(accion);
}
else
{
mensajes.Add(new ToastMessage
{
Type = ToastType.Warning,
Message = $"Debe rellenar los campos obligatorios.",
});
}
}
catch (Exception)
{
mensajes.Add(new ToastMessage
{
Type = ToastType.Danger,
Message = $"Error al guardar.",
});
}
}
private void MostrarErrores()
{
messageStore?.Clear();
foreach (var field in new[] { nameof(itemSeleccionadoTemporal.Coste), nameof(itemSeleccionadoTemporal.idCoste) })
{
ValidarYActualizar(new ChangeEventArgs { Value = typeof(CASA.CosteVariable).GetProperty(field)?.GetValue(itemSeleccionadoTemporal) }, field);
}
}
//////// PopUp eliminar registro
private async Task abrirPopupConfirmarBorrado(CASA.CosteVariable objeto)
{
itemSeleccionado = objeto;
await popupConfirmarBorrado.ShowAsync();
}
private async Task cerrarPopupConfirmarBorrado()
{
await popupConfirmarBorrado.HideAsync();
}
private async Task OnRowClick(GridRowEventArgs<CASA.CosteVariable> objeto)
{
itemSeleccionado = objeto.Item;
}
private void rellenarItem()
{
itemSeleccionado.idCoste = itemSeleccionadoTemporal.idCoste;
itemSeleccionado.Coste = itemSeleccionadoTemporal.Coste;
itemSeleccionado.Denominacion = itemSeleccionadoTemporal.Denominacion;
}
}