Selaa lähdekoodia

Merge branch 'OGdev' into tablet

OscarGil03 8 kuukautta sitten
vanhempi
commit
131e10fa08

+ 12 - 11
lib/services/repo_service.dart

@@ -6,7 +6,7 @@ import 'package:sqflite/sqflite.dart';
 import '../models/models.dart';
 
 class RepoService<T> {
-  static int dbVersion = 16;
+  static int dbVersion = 14;
   static String dbName = 'conalepPos7.db';
   static const String id = Basico.identificadorWeb;
   static const String idLocal = Basico.identificadorLocal;
@@ -262,7 +262,7 @@ class RepoService<T> {
         // ''');
         //   break;
 
-        case 14:
+        case 12:
           await db.execute('''
           update Pedido set sincronizado = null, peticion = strftime('%Y-%m-%dT%H:%M:%S',
                 datetime(substr(peticion, 7, 4) || '-' ||
@@ -277,7 +277,7 @@ class RepoService<T> {
         ''');
           break;
 
-        case 15:
+        case 13:
           await db.execute('DROP TABLE IF EXISTS Producto');
 
           //Se tiene que crear nuevamente para que precio sea Double
@@ -569,17 +569,18 @@ class RepoService<T> {
       DateTime startDate, DateTime endDate) async {
     var dbClient = await db;
 
-    String startDateString =
-        DateFormat('yyyy-MM-dd 00:00:00').format(startDate);
-    String endDateString = DateFormat('yyyy-MM-dd 23:59:59').format(endDate);
+    String startDateString = startDate.toIso8601String();
+    String endDateString = endDate.toIso8601String();
+
+    print(
+        'Ejecutando consulta: SELECT * FROM Pedido WHERE peticion BETWEEN $startDateString AND $endDateString');
 
     List<Map<String, dynamic>> maps = await dbClient!.rawQuery('''
     SELECT * FROM Pedido 
-    WHERE 
-      (datetime(substr(peticion, 7, 4) || '-' || substr(peticion, 4, 2) || '-' || substr(peticion, 1, 2) || ' ' || substr(peticion, 12)) BETWEEN ? AND ?)
-    OR 
-      (datetime(substr(peticion, 7, 4) || '-' || substr(peticion, 1, 2) || '-' || substr(peticion, 4, 2) || ' ' || substr(peticion, 12)) BETWEEN ? AND ?)
-  ''', [startDateString, endDateString, startDateString, endDateString]);
+    WHERE peticion BETWEEN ? AND ?
+  ''', [startDateString, endDateString]);
+
+    print('Resultado de la consulta: ${maps.length} pedidos encontrados.');
 
     return maps.map((map) => Pedido.fromJson(map)).toList();
   }

+ 8 - 0
lib/viewmodels/pedido_view_model.dart

@@ -209,7 +209,15 @@ class PedidoViewModel extends ChangeNotifier {
       DateTime startDate, DateTime endDate) async {
     setIsLoading(true);
     RepoService<Pedido> repoPedido = RepoService<Pedido>();
+
+    print('Consulta SQL de pedidos desde: $startDate hasta: $endDate');
+
     List<Pedido> pedidos = await repoPedido.buscarPorFecha(startDate, endDate);
+
+    print('Pedidos obtenidos desde la base de datos: ${pedidos.length}');
+    pedidos.forEach((pedido) => print(
+        'Pedido Folio: ${pedido.folio}, Estatus: ${pedido.estatus}, Total: ${pedido.totalPedido}'));
+
     setIsLoading(false);
     notifyListeners();
     return pedidos;

+ 23 - 18
lib/viewmodels/producto_view_model.dart

@@ -1,8 +1,11 @@
 import 'package:flutter/material.dart';
 import 'package:sqflite/sqflite.dart';
+
 import '../data/api_response.dart';
+import '../services/base_service.dart';
 import '../models/models.dart';
 import '../services/services.dart';
+import '../services/repo_service.dart';
 
 class ProductoViewModel<T> extends ChangeNotifier {
   String _busqueda = "";
@@ -82,7 +85,6 @@ class ProductoViewModel<T> extends ChangeNotifier {
 
   Future<void> fetchLocalByName({required String nombre}) async {
     var db = await RepoService().db;
-    // Realiza la búsqueda sin filtrar por categoría
     var query = await db!.query(
       'Producto',
       where: 'nombre LIKE ?',
@@ -176,23 +178,6 @@ class ProductoViewModel<T> extends ChangeNotifier {
     return null;
   }
 
-  void setIsLoading(bool loading) {
-    _isLoading = loading;
-    notifyListeners();
-  }
-
-  void nextPage() {
-    if (_currentPage < totalPages) {
-      fetchLocalAll(page: _currentPage + 1);
-    }
-  }
-
-  void previousPage() {
-    if (_currentPage > 1) {
-      fetchLocalAll(page: _currentPage - 1);
-    }
-  }
-
   Future<bool> sincronizarCategorias() async {
     try {
       final response = ApiResponse(await BaseService().get('/pos/categoria'));
@@ -239,15 +224,18 @@ class ProductoViewModel<T> extends ChangeNotifier {
   }
 
   Future<void> sincronizarProductosYCategorias() async {
+    print('Sincronizando productos');
     setIsLoading(true);
     try {
       bool categoriasSincronizadas = await sincronizarCategorias();
+      print('Categorias sincronizadas: $categoriasSincronizadas');
 
       if (categoriasSincronizadas) {
         bool productosSincronizados = await sincronizarProductos();
         if (productosSincronizados) {
           await fetchLocalAll();
         }
+        print('Productos sincronizados: $productosSincronizados');
       }
       notifyListeners();
     } catch (e, stackTrace) {
@@ -258,4 +246,21 @@ class ProductoViewModel<T> extends ChangeNotifier {
       setIsLoading(false);
     }
   }
+
+  void setIsLoading(bool loading) {
+    _isLoading = loading;
+    notifyListeners();
+  }
+
+  void nextPage() {
+    if (_currentPage < totalPages) {
+      fetchLocalAll(page: _currentPage + 1);
+    }
+  }
+
+  void previousPage() {
+    if (_currentPage > 1) {
+      fetchLocalAll(page: _currentPage - 1);
+    }
+  }
 }

+ 13 - 11
lib/views/categoria_producto/categoria_producto_screen.dart

@@ -16,6 +16,7 @@ class CategoriaProductoScreen extends StatefulWidget {
 class _CategoriaProductoScreenState extends State<CategoriaProductoScreen> {
   final _busqueda = TextEditingController(text: '');
   ScrollController horizontalScrollController = ScrollController();
+  int _versionTapCount = 0;
 
   @override
   void initState() {
@@ -184,18 +185,19 @@ class _CategoriaProductoScreenState extends State<CategoriaProductoScreen> {
       appBar: AppBar(
         title: GestureDetector(
           onTap: () async {
-            final productoViewModel =
-                Provider.of<ProductoViewModel>(context, listen: false);
+            _versionTapCount++;
+            if (_versionTapCount == 5) {
+              final productoViewModel =
+                  Provider.of<ProductoViewModel>(context, listen: false);
 
-            try {
-              // Iniciar la sincronización
-              await productoViewModel.sincronizarProductosYCategorias();
-              // Mostrar resultado de éxito en el modal
-              _mostrarResultado(
-                  context, 'La sincronización se completó exitosamente.', true);
-            } catch (e) {
-              // Mostrar el error detallado en el modal
-              _mostrarResultado(context, e.toString(), false);
+              try {
+                await productoViewModel.sincronizarProductosYCategorias();
+                _mostrarResultado(context,
+                    'La sincronización se completó exitosamente.', true);
+              } catch (e) {
+                _mostrarResultado(context, e.toString(), false);
+              }
+              _versionTapCount = 0;
             }
           },
           child: Text(

+ 224 - 224
lib/views/pedido/pedido_ticket.dart

@@ -169,197 +169,6 @@ pw.Page generarPaginaPrimerTicket(Pedido pedido, pw.MemoryImage image) {
 
 //Ticket PC
 
-// Future<pw.Page> generarPaginaSegundoTicket(
-//     BuildContext context, Pedido pedido) async {
-//   final numberFormat = NumberFormat('#,##0.00', 'es_MX');
-//   double subtotal = 0;
-//   double totalConDescuento = 0;
-//   double descuento = pedido.descuento?.toDouble() ?? 0.0;
-//   double precioDescuento = 0;
-
-//   final sucursalVariable =
-//       await Provider.of<VariableViewModel>(context, listen: false)
-//           .getVariableByClave('Sucursal');
-//   final sucursalDescripcion = sucursalVariable?.descripcion ?? '';
-
-//   List<pw.Widget> content = [
-//     pw.Padding(
-//       padding: pw.EdgeInsets.only(right: 10),
-//       child: pw.Row(
-//         mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
-//         children: [
-//           pw.Text('${pedido.folio}/ ',
-//               style:
-//                   pw.TextStyle(fontSize: 10.5, fontWeight: pw.FontWeight.bold)),
-//           if (sucursalDescripcion.isNotEmpty)
-//             pw.Text('$sucursalDescripcion/ ',
-//                 style: pw.TextStyle(
-//                     fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
-//         ],
-//       ),
-//     ),
-//     pw.SizedBox(height: 2),
-//     pw.Row(
-//       mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
-//       children: [
-//         pw.Text('${_formatDateTime(pedido.peticion)}',
-//             style:
-//                 pw.TextStyle(fontSize: 10.5, fontWeight: pw.FontWeight.bold)),
-//       ],
-//     ),
-//     pw.SizedBox(height: 2),
-//     if (pedido.nombreCliente != null && pedido.nombreCliente!.isNotEmpty)
-//       pw.Text('Cliente: ${pedido.nombreCliente}',
-//           style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
-//     pw.SizedBox(height: 2),
-//   ];
-
-//   // Mostrar los productos con la cantidad, el precio total y el precio de los toppings
-//   content.addAll(pedido.productos
-//       .map((producto) {
-//         final productPrice = producto.producto?.precio ?? 0.0;
-//         final productTotal = productPrice * (producto.cantidad ?? 1);
-//         subtotal += productTotal;
-
-//         final toppingsList = producto.toppings.map((topping) {
-//           final toppingPrice = topping.topping?.precio ?? 0.0;
-//           final toppingTotal = toppingPrice * (producto.cantidad ?? 1);
-//           subtotal += toppingTotal;
-
-//           return pw.Row(
-//             mainAxisAlignment: pw.MainAxisAlignment.start,
-//             children: [
-//               pw.Expanded(
-//                 flex: 3,
-//                 child: pw.Text(
-//                     '-${topping.topping?.nombre ?? "Topping no especificado"}',
-//                     style: const pw.TextStyle(fontSize: 8.5)),
-//               ),
-//               if (toppingPrice > 0)
-//                 pw.Expanded(
-//                   flex: 1,
-//                   child: pw.Text(
-//                     '\$${numberFormat.format(toppingTotal)}',
-//                     style: const pw.TextStyle(fontSize: 8.5),
-//                     textAlign: pw.TextAlign.right,
-//                   ),
-//                 ),
-//             ],
-//           );
-//         }).toList();
-
-//         return [
-//           pw.Row(
-//             mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
-//             children: [
-//               pw.Expanded(
-//                 flex: 1,
-//                 child: pw.Text('${producto.cantidad}',
-//                     style: const pw.TextStyle(fontSize: 10.5)),
-//               ),
-//               pw.Expanded(
-//                 flex: 6,
-//                 child: pw.Text(
-//                     producto.producto?.nombre ?? "Producto no especificado",
-//                     style: const pw.TextStyle(fontSize: 10.5)),
-//               ),
-//               pw.Expanded(
-//                   flex: 4,
-//                   child: pw.Align(
-//                     alignment: pw.Alignment.centerLeft,
-//                     child: pw.Text(
-//                       '\$${numberFormat.format(productTotal)}',
-//                       style: const pw.TextStyle(fontSize: 10.5),
-//                     ),
-//                   )),
-//             ],
-//           ),
-//           ...toppingsList,
-//         ];
-//       })
-//       .expand((e) => e)
-//       .toList());
-
-//   // Calcular el descuento y el total final
-//   precioDescuento = subtotal * (descuento / 100);
-//   totalConDescuento = subtotal - precioDescuento;
-
-//   content.add(pw.Divider());
-
-//   if (descuento > 0) {
-//     content.addAll([
-//       pw.Row(
-//         mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
-//         children: [
-//           pw.Text('Subtotal:',
-//               style:
-//                   pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
-//           pw.Padding(
-//               padding: pw.EdgeInsets.only(right: 15),
-//               child: pw.Text('\$${numberFormat.format(subtotal)}',
-//                   style: pw.TextStyle(
-//                       fontWeight: pw.FontWeight.bold, fontSize: 10.5))),
-//         ],
-//       ),
-//       pw.Row(
-//         mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
-//         children: [
-//           pw.Text('Descuento:',
-//               style:
-//                   pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
-//           pw.Padding(
-//               padding: pw.EdgeInsets.only(right: 15),
-//               child: pw.Text('-\$${numberFormat.format(precioDescuento)}',
-//                   style: pw.TextStyle(
-//                       fontWeight: pw.FontWeight.bold, fontSize: 10.5))),
-//         ],
-//       ),
-//     ]);
-//   }
-
-//   content.add(
-//     pw.Row(
-//       mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
-//       children: [
-//         pw.Text('Total:',
-//             style:
-//                 pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
-//         pw.Padding(
-//             padding: pw.EdgeInsets.only(right: 20),
-//             child: pw.Text(
-//                 '\$${numberFormat.format(descuento > 0 ? totalConDescuento : subtotal)}',
-//                 style: pw.TextStyle(
-//                     fontWeight: pw.FontWeight.bold, fontSize: 10.5))),
-//       ],
-//     ),
-//   );
-
-//   if (pedido.comentarios != null && pedido.comentarios!.isNotEmpty) {
-//     content.add(pw.SizedBox(height: 1));
-//     content.add(pw.Text('Comentarios:',
-//         style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)));
-//     content.add(pw.Padding(
-//       padding: const pw.EdgeInsets.only(right: 15),
-//       child: pw.Text(pedido.comentarios!,
-//           style: const pw.TextStyle(fontSize: 10.5)),
-//     ));
-//   }
-
-//   content.add(pw.SizedBox(height: 15));
-//   content.add(pw.Text('.', style: pw.TextStyle(fontSize: 1)));
-
-//   return pw.Page(
-//     pageFormat: PdfPageFormat.roll57,
-//     margin: pw.EdgeInsets.all(5),
-//     build: (pw.Context context) {
-//       return pw.Column(
-//           crossAxisAlignment: pw.CrossAxisAlignment.center, children: content);
-//     },
-//   );
-// }
-
-//Ticket Tablet
-
 Future<pw.Page> generarPaginaSegundoTicket(
     BuildContext context, Pedido pedido) async {
   final numberFormat = NumberFormat('#,##0.00', 'es_MX');
@@ -374,28 +183,34 @@ Future<pw.Page> generarPaginaSegundoTicket(
   final sucursalDescripcion = sucursalVariable?.descripcion ?? '';
 
   List<pw.Widget> content = [
-    pw.Row(
-      mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
-      children: [
-        pw.Text('${pedido.folio}/ ',
-            style: pw.TextStyle(fontSize: 7, fontWeight: pw.FontWeight.bold)),
-        if (sucursalDescripcion.isNotEmpty)
-          pw.Text('$sucursalDescripcion/ ',
-              style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
-      ],
+    pw.Padding(
+      padding: pw.EdgeInsets.only(right: 10),
+      child: pw.Row(
+        mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
+        children: [
+          pw.Text('${pedido.folio}/ ',
+              style:
+                  pw.TextStyle(fontSize: 10.5, fontWeight: pw.FontWeight.bold)),
+          if (sucursalDescripcion.isNotEmpty)
+            pw.Text('$sucursalDescripcion/ ',
+                style: pw.TextStyle(
+                    fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
+        ],
+      ),
     ),
     pw.SizedBox(height: 2),
     pw.Row(
       mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
       children: [
         pw.Text('${_formatDateTime(pedido.peticion)}',
-            style: pw.TextStyle(fontSize: 7, fontWeight: pw.FontWeight.bold)),
+            style:
+                pw.TextStyle(fontSize: 10.5, fontWeight: pw.FontWeight.bold)),
       ],
     ),
     pw.SizedBox(height: 2),
     if (pedido.nombreCliente != null && pedido.nombreCliente!.isNotEmpty)
       pw.Text('Cliente: ${pedido.nombreCliente}',
-          style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+          style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
     pw.SizedBox(height: 2),
   ];
 
@@ -418,14 +233,14 @@ Future<pw.Page> generarPaginaSegundoTicket(
                 flex: 3,
                 child: pw.Text(
                     '-${topping.topping?.nombre ?? "Topping no especificado"}',
-                    style: const pw.TextStyle(fontSize: 6)),
+                    style: const pw.TextStyle(fontSize: 8.5)),
               ),
               if (toppingPrice > 0)
                 pw.Expanded(
                   flex: 1,
                   child: pw.Text(
                     '\$${numberFormat.format(toppingTotal)}',
-                    style: const pw.TextStyle(fontSize: 6),
+                    style: const pw.TextStyle(fontSize: 8.5),
                     textAlign: pw.TextAlign.right,
                   ),
                 ),
@@ -440,21 +255,21 @@ Future<pw.Page> generarPaginaSegundoTicket(
               pw.Expanded(
                 flex: 1,
                 child: pw.Text('${producto.cantidad}',
-                    style: const pw.TextStyle(fontSize: 7)),
+                    style: const pw.TextStyle(fontSize: 10.5)),
               ),
               pw.Expanded(
-                flex: 5,
+                flex: 6,
                 child: pw.Text(
                     producto.producto?.nombre ?? "Producto no especificado",
-                    style: const pw.TextStyle(fontSize: 7)),
+                    style: const pw.TextStyle(fontSize: 10.5)),
               ),
               pw.Expanded(
-                  flex: 2,
+                  flex: 4,
                   child: pw.Align(
-                    alignment: pw.Alignment.centerRight,
+                    alignment: pw.Alignment.centerLeft,
                     child: pw.Text(
                       '\$${numberFormat.format(productTotal)}',
-                      style: const pw.TextStyle(fontSize: 7),
+                      style: const pw.TextStyle(fontSize: 10.5),
                     ),
                   )),
             ],
@@ -477,18 +292,26 @@ Future<pw.Page> generarPaginaSegundoTicket(
         mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
         children: [
           pw.Text('Subtotal:',
-              style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
-          pw.Text('\$${numberFormat.format(subtotal)}',
-              style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+              style:
+                  pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
+          pw.Padding(
+              padding: pw.EdgeInsets.only(right: 15),
+              child: pw.Text('\$${numberFormat.format(subtotal)}',
+                  style: pw.TextStyle(
+                      fontWeight: pw.FontWeight.bold, fontSize: 10.5))),
         ],
       ),
       pw.Row(
         mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
         children: [
           pw.Text('Descuento:',
-              style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
-          pw.Text('-\$${numberFormat.format(precioDescuento)}',
-              style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+              style:
+                  pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
+          pw.Padding(
+              padding: pw.EdgeInsets.only(right: 15),
+              child: pw.Text('-\$${numberFormat.format(precioDescuento)}',
+                  style: pw.TextStyle(
+                      fontWeight: pw.FontWeight.bold, fontSize: 10.5))),
         ],
       ),
     ]);
@@ -499,10 +322,14 @@ Future<pw.Page> generarPaginaSegundoTicket(
       mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
       children: [
         pw.Text('Total:',
-            style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
-        pw.Text(
-            '\$${numberFormat.format(descuento > 0 ? totalConDescuento : subtotal)}',
-            style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+            style:
+                pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)),
+        pw.Padding(
+            padding: pw.EdgeInsets.only(right: 20),
+            child: pw.Text(
+                '\$${numberFormat.format(descuento > 0 ? totalConDescuento : subtotal)}',
+                style: pw.TextStyle(
+                    fontWeight: pw.FontWeight.bold, fontSize: 10.5))),
       ],
     ),
   );
@@ -510,15 +337,16 @@ Future<pw.Page> generarPaginaSegundoTicket(
   if (pedido.comentarios != null && pedido.comentarios!.isNotEmpty) {
     content.add(pw.SizedBox(height: 1));
     content.add(pw.Text('Comentarios:',
-        style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)));
+        style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 10.5)));
     content.add(pw.Padding(
       padding: const pw.EdgeInsets.only(right: 15),
-      child:
-          pw.Text(pedido.comentarios!, style: const pw.TextStyle(fontSize: 7)),
+      child: pw.Text(pedido.comentarios!,
+          style: const pw.TextStyle(fontSize: 10.5)),
     ));
   }
 
-  content.add(pw.SizedBox(height: 1));
+  content.add(pw.SizedBox(height: 15));
+  content.add(pw.Text('.', style: pw.TextStyle(fontSize: 1)));
 
   return pw.Page(
     pageFormat: PdfPageFormat.roll57,
@@ -530,6 +358,178 @@ Future<pw.Page> generarPaginaSegundoTicket(
   );
 }
 
+//Ticket Tablet
+
+// Future<pw.Page> generarPaginaSegundoTicket(
+//     BuildContext context, Pedido pedido) async {
+//   final numberFormat = NumberFormat('#,##0.00', 'es_MX');
+//   double subtotal = 0;
+//   double totalConDescuento = 0;
+//   double descuento = pedido.descuento?.toDouble() ?? 0.0;
+//   double precioDescuento = 0;
+
+//   final sucursalVariable =
+//       await Provider.of<VariableViewModel>(context, listen: false)
+//           .getVariableByClave('Sucursal');
+//   final sucursalDescripcion = sucursalVariable?.descripcion ?? '';
+
+//   List<pw.Widget> content = [
+//     pw.Row(
+//       mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
+//       children: [
+//         pw.Text('${pedido.folio}/ ',
+//             style: pw.TextStyle(fontSize: 7, fontWeight: pw.FontWeight.bold)),
+//         if (sucursalDescripcion.isNotEmpty)
+//           pw.Text('$sucursalDescripcion/ ',
+//               style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//       ],
+//     ),
+//     pw.SizedBox(height: 2),
+//     pw.Row(
+//       mainAxisAlignment: pw.MainAxisAlignment.spaceAround,
+//       children: [
+//         pw.Text('${_formatDateTime(pedido.peticion)}',
+//             style: pw.TextStyle(fontSize: 7, fontWeight: pw.FontWeight.bold)),
+//       ],
+//     ),
+//     pw.SizedBox(height: 2),
+//     if (pedido.nombreCliente != null && pedido.nombreCliente!.isNotEmpty)
+//       pw.Text('Cliente: ${pedido.nombreCliente}',
+//           style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//     pw.SizedBox(height: 2),
+//   ];
+
+//   // Mostrar los productos con la cantidad, el precio total y el precio de los toppings
+//   content.addAll(pedido.productos
+//       .map((producto) {
+//         final productPrice = producto.producto?.precio ?? 0.0;
+//         final productTotal = productPrice * (producto.cantidad ?? 1);
+//         subtotal += productTotal;
+
+//         final toppingsList = producto.toppings.map((topping) {
+//           final toppingPrice = topping.topping?.precio ?? 0.0;
+//           final toppingTotal = toppingPrice * (producto.cantidad ?? 1);
+//           subtotal += toppingTotal;
+
+//           return pw.Row(
+//             mainAxisAlignment: pw.MainAxisAlignment.start,
+//             children: [
+//               pw.Expanded(
+//                 flex: 3,
+//                 child: pw.Text(
+//                     '-${topping.topping?.nombre ?? "Topping no especificado"}',
+//                     style: const pw.TextStyle(fontSize: 6)),
+//               ),
+//               if (toppingPrice > 0)
+//                 pw.Expanded(
+//                   flex: 1,
+//                   child: pw.Text(
+//                     '\$${numberFormat.format(toppingTotal)}',
+//                     style: const pw.TextStyle(fontSize: 6),
+//                     textAlign: pw.TextAlign.right,
+//                   ),
+//                 ),
+//             ],
+//           );
+//         }).toList();
+
+//         return [
+//           pw.Row(
+//             mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
+//             children: [
+//               pw.Expanded(
+//                 flex: 1,
+//                 child: pw.Text('${producto.cantidad}',
+//                     style: const pw.TextStyle(fontSize: 7)),
+//               ),
+//               pw.Expanded(
+//                 flex: 5,
+//                 child: pw.Text(
+//                     producto.producto?.nombre ?? "Producto no especificado",
+//                     style: const pw.TextStyle(fontSize: 7)),
+//               ),
+//               pw.Expanded(
+//                   flex: 2,
+//                   child: pw.Align(
+//                     alignment: pw.Alignment.centerRight,
+//                     child: pw.Text(
+//                       '\$${numberFormat.format(productTotal)}',
+//                       style: const pw.TextStyle(fontSize: 7),
+//                     ),
+//                   )),
+//             ],
+//           ),
+//           ...toppingsList,
+//         ];
+//       })
+//       .expand((e) => e)
+//       .toList());
+
+//   // Calcular el descuento y el total final
+//   precioDescuento = subtotal * (descuento / 100);
+//   totalConDescuento = subtotal - precioDescuento;
+
+//   content.add(pw.Divider());
+
+//   if (descuento > 0) {
+//     content.addAll([
+//       pw.Row(
+//         mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
+//         children: [
+//           pw.Text('Subtotal:',
+//               style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//           pw.Text('\$${numberFormat.format(subtotal)}',
+//               style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//         ],
+//       ),
+//       pw.Row(
+//         mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
+//         children: [
+//           pw.Text('Descuento:',
+//               style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//           pw.Text('-\$${numberFormat.format(precioDescuento)}',
+//               style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//         ],
+//       ),
+//     ]);
+//   }
+
+//   content.add(
+//     pw.Row(
+//       mainAxisAlignment: pw.MainAxisAlignment.spaceBetween,
+//       children: [
+//         pw.Text('Total:',
+//             style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//         pw.Text(
+//             '\$${numberFormat.format(descuento > 0 ? totalConDescuento : subtotal)}',
+//             style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)),
+//       ],
+//     ),
+//   );
+
+//   if (pedido.comentarios != null && pedido.comentarios!.isNotEmpty) {
+//     content.add(pw.SizedBox(height: 1));
+//     content.add(pw.Text('Comentarios:',
+//         style: pw.TextStyle(fontWeight: pw.FontWeight.bold, fontSize: 7)));
+//     content.add(pw.Padding(
+//       padding: const pw.EdgeInsets.only(right: 15),
+//       child:
+//           pw.Text(pedido.comentarios!, style: const pw.TextStyle(fontSize: 7)),
+//     ));
+//   }
+
+//   content.add(pw.SizedBox(height: 1));
+
+//   return pw.Page(
+//     pageFormat: PdfPageFormat.roll57,
+//     margin: pw.EdgeInsets.all(5),
+//     build: (pw.Context context) {
+//       return pw.Column(
+//           crossAxisAlignment: pw.CrossAxisAlignment.center, children: content);
+//     },
+//   );
+// }
+
 Future<void> printPdf(Uint8List pdfBytes) async {
   await Printing.layoutPdf(
     onLayout: (PdfPageFormat format) => pdfBytes,

+ 65 - 29
lib/views/venta/venta_screen.dart

@@ -25,6 +25,8 @@ class _VentaScreenState extends State<VentaScreen> {
   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");
@@ -200,33 +202,46 @@ class _VentaScreenState extends State<VentaScreen> {
                             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 (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),
-                        ),
-                      ),
+                    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),
@@ -249,11 +264,23 @@ class _VentaScreenState extends State<VentaScreen> {
   }
 
   void cargarPedidos(DateTime fecha) async {
-    final inicioDelDia = DateTime(fecha.year, fecha.month, fecha.day);
-    final finDelDia = DateTime(fecha.year, fecha.month, fecha.day, 23, 59, 59);
+    // 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<PedidoViewModel>(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 =
@@ -264,14 +291,23 @@ class _VentaScreenState extends State<VentaScreen> {
     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));
 

+ 23 - 14
lib/views/venta/venta_ticket.dart

@@ -38,6 +38,9 @@ class VentaTicket {
     double totalTransferencia = pedidosNoCancelados.fold(
         0.0, (sum, p) => sum + (p.cantTransferencia ?? 0.0));
 
+    double totalSinCambio = totalEfectivo + totalTarjeta + totalTransferencia;
+    double cambio = totalSinCambio - totalNoCancelados;
+
     final spelling = SpellingNumber(lang: 'es');
     String totalEnLetras = toTitleCase(spelling.convert(totalNoCancelados));
 
@@ -48,14 +51,12 @@ class VentaTicket {
     String formattedTotalTarjeta = numberFormat.format(totalTarjeta);
     String formattedTotalTransferencia =
         numberFormat.format(totalTransferencia);
+    String formattedCambio = numberFormat.format(cambio);
 
     int centavos =
         ((totalNoCancelados - totalNoCancelados.floor()) * 100).round();
     String centavosEnLetras = centavos.toString().padLeft(2, '0') + "/100 M.N.";
 
-    print("Total en letras: $totalEnLetras $centavosEnLetras");
-    print("Total formateado: $formattedTotalNoCancelados");
-
     pdf.addPage(pw.Page(
         pageFormat: PdfPageFormat.roll57,
         build: (pw.Context context) {
@@ -94,19 +95,27 @@ class VentaTicket {
                 child: pw.Column(
                   crossAxisAlignment: pw.CrossAxisAlignment.start,
                   children: [
-                    // pw.Text("- Total en Efectivo: \$${formattedTotalEfectivo}",
-                    //     style: pw.TextStyle(
-                    //         fontWeight: pw.FontWeight.bold, fontSize: 11)),
-                    pw.Text("- Total en Tarjeta: \$${formattedTotalTarjeta}",
-                        style: pw.TextStyle(
-                            fontWeight: pw.FontWeight.bold, fontSize: 11)),
-                    pw.Text(
-                        "- Total en Transferencia: \$${formattedTotalTransferencia}",
-                        style: pw.TextStyle(
-                            fontWeight: pw.FontWeight.bold, fontSize: 11)),
+                    if (totalTarjeta > 0)
+                      pw.Text("- Total en Tarjeta: \$${formattedTotalTarjeta}",
+                          style: pw.TextStyle(
+                              fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
+                    if (totalTransferencia > 0)
+                      pw.Text(
+                          "- Total en Transferencia: \$${formattedTotalTransferencia}",
+                          style: pw.TextStyle(
+                              fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
+                    if (totalEfectivo > 0)
+                      pw.Text(
+                          "- Total en Efectivo: \$${formattedTotalEfectivo}",
+                          style: pw.TextStyle(
+                              fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
+                    if (cambio > 0)
+                      pw.Text("- Cambio Entregado: \$${formattedCambio}",
+                          style: pw.TextStyle(
+                              fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
                     pw.Text("- Total General: \$${formattedTotalNoCancelados}",
                         style: pw.TextStyle(
-                            fontWeight: pw.FontWeight.bold, fontSize: 11)),
+                            fontWeight: pw.FontWeight.bold, fontSize: 9.5)),
                     pw.Text("Son: $totalEnLetras Pesos $centavosEnLetras",
                         style: pw.TextStyle(fontSize: 10))
                   ],

+ 1 - 1
lib/widgets/app_drawer.dart

@@ -216,7 +216,7 @@ class _AppDrawerState extends State<AppDrawer> {
               child: Align(
                 alignment: Alignment.bottomCenter,
                 child: Text(
-                  'v1.24.09.12+13',
+                  'v1.24.10.04',
                   style: TextStyle(fontWeight: FontWeight.w300),
                 ),
               ),