@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() }; }