import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:omni_datetime_picker/omni_datetime_picker.dart'; import 'package:provider/provider.dart'; import '../../widgets/widgets_components.dart'; import '../../models/models.dart'; import '../../viewmodels/viewmodels.dart'; import 'venta_ticket.dart'; import '../../widgets/widgets.dart'; import '../../themes/themes.dart'; class VentaScreen extends StatefulWidget { @override _VentaScreenState createState() => _VentaScreenState(); } class _VentaScreenState extends State { DateTime? fechaSeleccionada; List pedidosNoCancelados = []; List pedidosCancelados = []; final _busqueda = TextEditingController(text: ''); double totalDelDia = 0.0; double totalCancelados = 0.0; double totalEfectivoDelDia = 0.0; double totalTarjetaDelDia = 0.0; double totalTransferenciaDelDia = 0.0; double cambio = 0.0; double totalSinCambio = 0.0; String formatCurrency(double amount) { final format = NumberFormat("#,##0.00", "es_MX"); return format.format(amount); } void clearSearchAndReset() { setState(() { _busqueda.clear(); fechaSeleccionada = null; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( "Resumen de Pedidos por Día", style: TextStyle(color: AppTheme.secondary), ), iconTheme: IconThemeData(color: AppTheme.secondary)), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ Row( children: [ Expanded( flex: 3, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 0.0), child: tarjeta( ListTile( title: Text( "Fecha", style: TextStyle( color: AppTheme.quaternary, fontWeight: FontWeight.bold), ), subtitle: Text( fechaSeleccionada == null ? "" : DateFormat("dd/MM/yyyy") .format(fechaSeleccionada!), style: TextStyle( color: AppTheme.quaternary, fontWeight: FontWeight.bold), ), trailing: Icon(Icons.calendar_month, color: AppTheme.quaternary), onTap: () async { DateTime? d = await showDatetimePicker( context, fechaSeleccionada, inicia: fechaSeleccionada, tipo: OmniDateTimePickerType.date, solofecha: true); if (d == null) return; setState(() { fechaSeleccionada = d; }); cargarPedidos(fechaSeleccionada!); }), color: AppTheme.tertiary, ), )), const SizedBox( width: 500, ), Expanded( flex: 2, child: Padding( padding: const EdgeInsets.only(top: 0), child: ElevatedButton( onPressed: clearSearchAndReset, style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.0), ), backgroundColor: AppTheme.tertiary, padding: const EdgeInsets.symmetric(vertical: 25), ), child: Text('Limpiar', style: TextStyle( color: AppTheme.quaternary, fontSize: 18)), ), ), ), ], ), Expanded( child: tarjeta( Padding( padding: const EdgeInsets.all(8.0), child: ListView.builder( itemCount: pedidosNoCancelados.length + pedidosCancelados.length, itemBuilder: (context, index) { if (index < pedidosNoCancelados.length) { final pedido = pedidosNoCancelados[index]; return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Folio: ${pedido.folio}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w500), ), Text( "Total: \$${formatCurrency(pedido.totalPedido ?? 0)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w500)), ], ); } else { final pedido = pedidosCancelados[index - pedidosNoCancelados.length]; return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "Folio: ${pedido.folio} (Cancelado)", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w500, color: Colors.red), ), Text( "Total: \$${formatCurrency(pedido.totalPedido ?? 0)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.w500, color: Colors.red)), ], ); } }, ), ), )), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ElevatedButton.icon( icon: Icon( Icons.receipt_long_outlined, color: AppTheme.quaternary, size: 30, ), onPressed: pedidosNoCancelados.isNotEmpty || pedidosCancelados.isNotEmpty ? () => imprimirResumenPedidos( pedidosNoCancelados + pedidosCancelados) : null, label: Text( "Imprimir Resumen", style: TextStyle(color: AppTheme.quaternary, fontSize: 18), ), style: ButtonStyle( backgroundColor: MaterialStatePropertyAll(AppTheme.tertiary), padding: MaterialStatePropertyAll( EdgeInsets.fromLTRB(30, 20, 30, 20))), ), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Padding( padding: const EdgeInsets.all(16.0), child: Text( "Total del día: \$${formatCurrency(totalDelDia)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ), Row( children: [ if (totalTarjetaDelDia > 0) Padding( padding: const EdgeInsets.all(16.0), child: Text( "Total en Tarjeta: \$${formatCurrency(totalTarjetaDelDia)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ), if (totalTransferenciaDelDia > 0) Padding( padding: const EdgeInsets.all(16.0), child: Text( "Total en Transferencia: \$${formatCurrency(totalTransferenciaDelDia)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ), if (totalEfectivoDelDia > 0) Padding( padding: const EdgeInsets.all(16.0), child: Text( "Total en Efectivo: \$${formatCurrency(totalEfectivoDelDia)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ), if (cambio > 0) Padding( padding: const EdgeInsets.all(16.0), child: Text( "Cambio Entregado: \$${formatCurrency(cambio)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold), ), ), ], ), if (totalCancelados > 0) Padding( padding: const EdgeInsets.all(16.0), child: Text( "Total cancelados: \$${formatCurrency(totalCancelados)}", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.red), ), ), ], ), ], ) ], ), ), ); } void cargarPedidos(DateTime fecha) async { // Convertir el inicio y fin del día local a UTC final inicioDelDia = DateTime(fecha.year, fecha.month, fecha.day) .toUtc(); // Convierte la fecha local de inicio del día a UTC final finDelDia = DateTime(fecha.year, fecha.month, fecha.day, 23, 59, 59) .toUtc(); // Convierte la fecha local de fin del día a UTC print('Buscando pedidos desde: $inicioDelDia hasta: $finDelDia (en UTC)'); // Realizar la búsqueda en UTC final pedidos = await Provider.of(context, listen: false) .buscarPorFecha(inicioDelDia, finDelDia); print('Pedidos obtenidos: ${pedidos.length}'); pedidos.forEach((pedido) => print( 'Pedido: ${pedido.folio}, Total: ${pedido.totalPedido}, Estatus: ${pedido.estatus}')); final pedidosNoCancelados = pedidos.where((p) => p.estatus != "CANCELADO").toList(); final pedidosCancelados = pedidos.where((p) => p.estatus == "CANCELADO").toList(); totalDelDia = 0.0; totalCancelados = 0.0; totalEfectivoDelDia = 0.0; totalTarjetaDelDia = 0.0; totalTransferenciaDelDia = 0.0; cambio = 0.0; totalSinCambio = 0.0; for (var pedido in pedidosNoCancelados) { totalDelDia += pedido.totalPedido ?? 0.0; totalEfectivoDelDia += pedido.cantEfectivo ?? 0.0; totalTarjetaDelDia += pedido.cantTarjeta ?? 0.0; totalTransferenciaDelDia += pedido.cantTransferencia ?? 0.0; totalSinCambio = totalEfectivoDelDia + totalTarjetaDelDia + totalTransferenciaDelDia; cambio = totalSinCambio - totalDelDia; } print("Total del dia sin cambios $totalSinCambio"); print("Cambio $cambio"); totalCancelados = pedidosCancelados.fold( 0.0, (sum, current) => sum + (current.totalPedido ?? 0.0)); setState(() { this.pedidosNoCancelados = pedidosNoCancelados; this.pedidosCancelados = pedidosCancelados; }); } Future imprimirResumenPedidos(List pedidos) async { if (fechaSeleccionada == null) { print("No se ha seleccionado una fecha."); return; } await VentaTicket.imprimirResumenPedidos(pedidos, fechaSeleccionada!); } }