Explorar el Código

Avance pedidos por día

ElPoteito hace 2 meses
padre
commit
35d5bc8b8b
Se han modificado 2 ficheros con 166 adiciones y 1 borrados
  1. 102 0
      lib/views/venta/venta_csv.dart
  2. 64 1
      lib/views/venta/venta_screen.dart

+ 102 - 0
lib/views/venta/venta_csv.dart

@@ -0,0 +1,102 @@
+import 'dart:convert';
+import 'package:csv/csv.dart';
+import 'package:intl/intl.dart';
+import 'package:path_provider/path_provider.dart';
+import 'dart:io';
+import 'package:path/path.dart' as p;
+import 'package:provider/provider.dart';
+import 'package:turquessa_app/viewmodels/propina_view_model.dart';
+import '../../models/models.dart';
+
+Future<void> exportarVentasACSV(List<Pedido> pedidos, List<Propinas> propinas, String fileName) async {
+  List<List<dynamic>> rows = [
+    [
+      "Folio",
+      "Cliente",
+      "Producto",
+      "Cantidad",
+      "Precio Unitario",
+      "Toppings",
+      "Descuento (%)",
+      "Estado",
+      "Fecha",
+      "Total con Descuento",
+      "Tipo de Pago",
+      "Cantidad Efectivo",
+      "Cantidad Tarjeta",
+      "Cantidad Transferencia",
+      "Propina"
+    ]
+  ];
+
+  for (var pedido in pedidos) {
+    for (var producto in pedido.productos) {
+      // Convertir toppings a una cadena de texto y calcular el total adicional de los toppings
+      double totalToppingsPrecio = 0.0;
+      String toppingsText = producto.toppings.isNotEmpty
+          ? producto.toppings.map((t) {
+              String toppingNombre =
+                  t.topping?.nombre ?? 'Topping no especificado';
+              double toppingPrecio = t.topping?.precio ?? 0.0;
+
+              if (toppingPrecio > 0) {
+                toppingNombre += "(+\$${formatCurrency(toppingPrecio)})";
+                totalToppingsPrecio += toppingPrecio;
+              }
+
+              return toppingNombre;
+            }).join(', ')
+          : 'Sin toppings';
+
+      // Calcular el total con descuento para este producto
+      double precioUnitario = producto.producto?.precio ?? 0.0;
+      double subtotal =
+          (precioUnitario + totalToppingsPrecio) * (producto.cantidad ?? 1);
+      double descuento = pedido.descuento?.toDouble() ?? 0.0;
+      double precioDescuento = subtotal * (descuento / 100);
+      double totalConDescuento = subtotal - precioDescuento;
+      double propina = 0.0;
+
+      for (var prop in propinas) {
+        if (prop.idPedido == pedido.id) {
+          propina = propina + prop.cantidad!;
+        }
+      }
+
+      List<dynamic> row = [
+        pedido.folio,
+        pedido.nombreCliente,
+        producto.producto?.nombre ?? 'No especificado',
+        producto.cantidad,
+        formatCurrency(precioUnitario),
+        toppingsText,
+        descuento,
+        pedido.estatus,
+        pedido.peticion ?? '',
+        formatCurrency(totalConDescuento),
+        pedido.tipoPago ?? 'No especificado',
+        formatCurrency(pedido.cantEfectivo ?? 0.0),
+        formatCurrency(pedido.cantTarjeta ?? 0.0),
+        formatCurrency(pedido.cantTransferencia ?? 0.0),
+        formatCurrency(propina ?? 0.0),
+      ];
+      rows.add(row);
+    }
+  }
+
+  String csv = const ListToCsvConverter().convert(rows);
+
+  final directory = await getApplicationDocumentsDirectory();
+  final path = p.join(directory.path, fileName);
+  final file = File(path);
+
+  final utf8Csv = utf8.encode('\uFEFF' + csv);
+  await file.writeAsBytes(utf8Csv, flush: true);
+
+  print('Archivo CSV guardado en $path');
+}
+
+String formatCurrency(double amount) {
+  final format = NumberFormat("#,##0.00", "es_MX");
+  return format.format(amount);
+}

+ 64 - 1
lib/views/venta/venta_screen.dart

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:intl/intl.dart';
 import 'package:intl/intl.dart';
 import 'package:omni_datetime_picker/omni_datetime_picker.dart';
 import 'package:omni_datetime_picker/omni_datetime_picker.dart';
 import 'package:provider/provider.dart';
 import 'package:provider/provider.dart';
+import 'package:turquessa_app/views/venta/venta_csv.dart';
 import '../../widgets/widgets_components.dart';
 import '../../widgets/widgets_components.dart';
 import '../../models/models.dart';
 import '../../models/models.dart';
 import '../../viewmodels/viewmodels.dart';
 import '../../viewmodels/viewmodels.dart';
@@ -52,6 +53,15 @@ class _VentaScreenState extends State<VentaScreen> {
             "Resumen de Pedidos por Periodo",
             "Resumen de Pedidos por Periodo",
             style: TextStyle(color: AppTheme.secondary),
             style: TextStyle(color: AppTheme.secondary),
           ),
           ),
+          actions: <Widget>[
+            IconButton(
+              icon: const Icon(Icons.save_alt),
+              onPressed: () {
+                exportCSV(fechaInicialSeleccionada, fechaFinalSeleccionada);
+              },
+              tooltip: 'Exportar a CSV',
+            ),
+          ],
           iconTheme: IconThemeData(color: AppTheme.secondary)),
           iconTheme: IconThemeData(color: AppTheme.secondary)),
       body: Padding(
       body: Padding(
         padding: const EdgeInsets.all(16.0),
         padding: const EdgeInsets.all(16.0),
@@ -188,7 +198,7 @@ class _VentaScreenState extends State<VentaScreen> {
                                 fontSize: 20, fontWeight: FontWeight.w500),
                                 fontSize: 20, fontWeight: FontWeight.w500),
                           ),
                           ),
                           Text(
                           Text(
-                            "Propina: \$${_propinaPedido(pedido.id)}",
+                            "Propina: \$${formatCurrency(_propinaPedido(pedido.id) ?? 0)}",
                             style: TextStyle(
                             style: TextStyle(
                                 fontSize: 20, fontWeight: FontWeight.w500),
                                 fontSize: 20, fontWeight: FontWeight.w500),
                           ),
                           ),
@@ -212,6 +222,16 @@ class _VentaScreenState extends State<VentaScreen> {
                                 color: Colors.red),
                                 color: Colors.red),
                           ),
                           ),
                           Text(
                           Text(
+                            "Fecha/Hora: ${_formatDateTime(pedido.peticion)}",
+                            style: TextStyle(
+                                fontSize: 20, fontWeight: FontWeight.w500),
+                          ),
+                          Text(
+                            "Propina: \$${formatCurrency(_propinaPedido(pedido.id) ?? 0)}",
+                            style: TextStyle(
+                                fontSize: 20, fontWeight: FontWeight.w500),
+                          ),
+                          Text(
                               "Total: \$${formatCurrency(pedido.totalPedido ?? 0)}",
                               "Total: \$${formatCurrency(pedido.totalPedido ?? 0)}",
                               style: TextStyle(
                               style: TextStyle(
                                   fontSize: 20,
                                   fontSize: 20,
@@ -405,6 +425,49 @@ class _VentaScreenState extends State<VentaScreen> {
     }
     }
   }
   }
 
 
+  void exportCSV(DateTime? fechaInicial, DateTime? fechaFinal) async {
+    final pedidosViewModel =
+        Provider.of<PedidoViewModel>(context, listen: false);
+    List<Pedido> pedidosConProductos = [];
+    List<Propinas> propinas = [];
+    List<Propinas> altPropinas = [];
+
+    for (Pedido pedido in pedidosViewModel.pedidos) {
+      Pedido? pedidoConProductos =
+          await pedidosViewModel.fetchPedidoConProductos(pedido.id);
+      if (pedidoConProductos != null) {
+        pedidosConProductos.add(pedidoConProductos);
+      }
+    }
+
+    if (pedidosConProductos.isNotEmpty) {
+      String fileName = 'Ventas_Turquessa_POS';
+      if (fechaInicial != null && fechaFinal != null) {
+        String startDateStr = DateFormat('dd-MM-yyyy').format(fechaInicial!);
+        String endDateStr = DateFormat('dd-MM-yyyy').format(fechaFinal!);
+        fileName += '_${startDateStr}_al_${endDateStr}';
+      }
+      fileName += '.csv';
+
+      for (var pedido in pedidosConProductos) {
+        altPropinas =
+            await Provider.of<PropinaViewModel>(context, listen: false)
+                .obtenerPropinasPorPedido(pedido.id);
+      }
+
+      for (var alt in altPropinas) {
+        propinas.add(alt);
+      }
+
+      await exportarVentasACSV(pedidosConProductos, propinas, fileName);
+      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
+          content: Text('Archivo CSV descargado! Archivo: $fileName')));
+    } else {
+      ScaffoldMessenger.of(context).showSnackBar(
+          SnackBar(content: Text('No hay pedidos para exportar.')));
+    }
+  }
+
   Future<void> imprimirResumenPedidos(List<Pedido> pedidos) async {
   Future<void> imprimirResumenPedidos(List<Pedido> pedidos) async {
     if (fechaInicialSeleccionada == null) {
     if (fechaInicialSeleccionada == null) {
       print("No se ha seleccionado una fecha inicial.");
       print("No se ha seleccionado una fecha inicial.");