@page "/facturacion"
@attribute [Authorize]
@inject ISalesService SalesSvc
@inject IWorkshopService WorkshopSvc
@inject AuthenticationStateProvider AuthState
@inject IDialogService DialogSvc
@inject NavigationManager Nav
@inject ISnackbar Snackbar
Facturación - AutoTaller ERP
Todos
Emitida
Pagada parcial
Pagada
Vencida
Anulada
@total comprobante(s)
Comprobante
Fecha
Vencimiento
Cliente
OT
Total
Pagado
Saldo
Estado
Acciones
@context.Serie-@context.Numero
@context.Tipo
@context.Fecha.ToString("dd/MM/yyyy")
@context.FechaVencimiento.ToString("dd/MM/yyyy")
@if (context.Vencida)
{
Vencida
}
@context.Cliente
@if (!string.IsNullOrEmpty(context.NumeroOT))
{
@context.NumeroOT
}
S/. @context.Total.ToString("N2")
S/. @context.MontoPagado.ToString("N2")
@if (context.SaldoPendiente > 0)
{
S/. @context.SaldoPendiente.ToString("N2")
}
else
{
—
}
@EstadoTexto(context.Estado)
@if (context.SaldoPendiente > 0 && context.Estado != EstadoFactura.Anulada)
{
}
@if (context.Estado != EstadoFactura.Pagada && context.Estado != EstadoFactura.PagadaParcial && context.Estado != EstadoFactura.Anulada)
{
}
No hay comprobantes
@if (totalPages > 1)
{
}
@code {
private string? buscar;
private EstadoFactura? estadoFiltro;
private List facturas = new();
private bool cargando = true;
private int page = 1;
private const int pageSize = 15;
private int total = 0;
private int totalPages = 0;
private CancellationTokenSource? _debounceCts;
protected override async Task OnInitializedAsync() => await CargarAsync();
private async Task CargarAsync()
{
cargando = true;
var resultado = await SalesSvc.ListarFacturasAsync(buscar, estadoFiltro, page, pageSize);
facturas = resultado.Items;
total = resultado.Total;
totalPages = resultado.TotalPages;
cargando = false;
}
private async Task OnBuscarChanged()
{
_debounceCts?.Cancel();
_debounceCts = new CancellationTokenSource();
var token = _debounceCts.Token;
try
{
await Task.Delay(350, token);
page = 1;
await CargarAsync();
}
catch (TaskCanceledException) { }
}
private async Task OnPageChanged(int p)
{
page = p;
await CargarAsync();
}
private void VerDetalle(int id) => Nav.NavigateTo($"/facturacion/{id}");
private async Task FacturarDesdeOT()
{
var ots = (await WorkshopSvc.ListarTodasOrdenesAsync())
.Where(o => o.Estado is EstadoOT.Listo or EstadoOT.Entregado).ToList();
var parametros = new DialogParameters { ["OTs"] = ots };
var opciones = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Small, FullWidth = true };
var dialog = await DialogSvc.ShowAsync("Facturar desde OT", parametros, opciones);
var r = await dialog.Result;
if (r is { Canceled: false, Data: int facturaId })
{
Snackbar.Add("Factura generada", Severity.Success);
Nav.NavigateTo($"/facturacion/{facturaId}");
}
}
private async Task RegistrarPago(FacturaListDto f)
{
var pago = new PagoFormDto { FacturaId = f.Id, Monto = f.SaldoPendiente };
var parametros = new DialogParameters { ["Pago"] = pago, ["SaldoMaximo"] = f.SaldoPendiente, ["Comprobante"] = $"{f.Serie}-{f.Numero}" };
var opciones = new DialogOptions { CloseButton = true, MaxWidth = MaxWidth.Small, FullWidth = true };
var dialog = await DialogSvc.ShowAsync("Registrar pago", parametros, opciones);
var r = await dialog.Result;
if (r is { Canceled: false })
{
Snackbar.Add("Pago registrado", Severity.Success);
await CargarAsync();
}
}
private async Task Anular(FacturaListDto f)
{
var confirmar = await DialogSvc.ShowMessageBox("Anular factura",
$"¿Anular el comprobante {f.Serie}-{f.Numero}? Esta acción no se puede revertir.",
yesText: "Sí, anular", cancelText: "Cancelar");
if (confirmar == true)
{
try
{
var auth = await AuthState.GetAuthenticationStateAsync();
await SalesSvc.AnularFacturaAsync(f.Id, auth.User.Identity?.Name);
Snackbar.Add("Factura anulada", Severity.Info);
await CargarAsync();
}
catch (Exception ex) { Snackbar.Add(ex.Message, Severity.Error); }
}
}
private static Color EstadoColor(EstadoFactura e) => e switch
{
EstadoFactura.Borrador => Color.Default,
EstadoFactura.Emitida => Color.Info,
EstadoFactura.PagadaParcial => Color.Warning,
EstadoFactura.Pagada => Color.Success,
EstadoFactura.Vencida => Color.Error,
EstadoFactura.Anulada => Color.Default,
_ => Color.Default
};
private static string EstadoTexto(EstadoFactura e) => e switch
{
EstadoFactura.PagadaParcial => "Pago parcial",
_ => e.ToString()
};
}