Przeglądaj źródła

claveSucursal en parametros de productos y categorias y sincronizacion de sucursales

OscarGil03 6 miesięcy temu
rodzic
commit
6c117ee208

+ 1 - 0
lib/main.dart

@@ -45,6 +45,7 @@ void main() async {
       ChangeNotifierProvider(create: (_) => PedidoViewModel()),
       ChangeNotifierProvider(create: (_) => DescuentoViewModel()),
       ChangeNotifierProvider(create: (_) => VariableViewModel()),
+      ChangeNotifierProvider(create: (_) => SucursalViewModel()),
       // Agrega aquí cualquier otro provider que necesites
     ], child: const MyApp()));
   });

+ 1 - 0
lib/models/models.dart

@@ -18,3 +18,4 @@ export '../models/deposito_model.dart';
 export '../models/corte_caja_model.dart';
 export '../models/descuento_model.dart';
 export '../models/variable_model.dart';
+export '../models/sucursal_model.dart';

+ 6 - 2
lib/models/producto_topping_model.dart

@@ -3,11 +3,13 @@ import 'basico_model.dart';
 class ProductoTopping extends Basico {
   int? idProducto;
   int? idTopping;
+  int? idCategoria;
 
   ProductoTopping({
     super.id,
     this.idProducto,
     this.idTopping,
+    this.idCategoria,
   });
 
   @override
@@ -15,13 +17,15 @@ class ProductoTopping extends Basico {
     return {
       'id': id,
       'idProducto': idProducto,
-      'idTopping': idTopping,
+      'idProductoTopping': idTopping,
+      'idCategoriaTopping': idTopping,
     }..addAll(super.toJson());
   }
 
   ProductoTopping.fromJson(Map<String, dynamic> json) {
     super.parseJson(json);
     idProducto = Basico.parseInt(json['idProducto']);
-    idTopping = Basico.parseInt(json['idTopping']);
+    idTopping = Basico.parseInt(json['idProductoTopping']);
+    idCategoria = Basico.parseInt(json['idCategoriaTopping']);
   }
 }

+ 69 - 0
lib/models/sucursal_model.dart

@@ -0,0 +1,69 @@
+import 'basico_model.dart';
+import '../services/services.dart';
+
+class Sucursal extends Basico {
+  String? nombre;
+  String? descripcion;
+  String? direccion;
+  String? ciudad;
+  String? clave;
+  int? activo;
+
+  Sucursal({
+    super.id,
+    this.nombre,
+    this.descripcion,
+    this.direccion,
+    this.ciudad,
+    this.clave,
+    this.activo,
+  });
+
+  @override
+  Map<String, dynamic> toJson() {
+    print("Convirtiendo Sucursal a JSON");
+    print(
+        "ID: $id, Nombre: $nombre, Descripción: $descripcion, Dirección: $direccion, Ciudad: $ciudad, Activo: $activo, Clave: $clave");
+    print("Creado: $creado, Modificado: $modificado, Eliminado: $eliminado");
+
+    return {
+      'id': id,
+      'nombre': nombre ?? '',
+      'descripcion': descripcion ?? '',
+      'direccion': direccion ?? '',
+      'ciudad': ciudad ?? '',
+      'clave': clave ?? '',
+      'activo': activo ?? 0,
+      'creado': creado?.toIso8601String(),
+      'modificado': modificado?.toIso8601String(),
+      'eliminado': eliminado?.toIso8601String(),
+    }..addAll(super.toJson());
+  }
+
+  Sucursal.fromJson(Map<String, dynamic> json) {
+    super.parseJson(json);
+    nombre = Basico.parseString(json['nombre']);
+    descripcion = Basico.parseString(json['descripcion']);
+    direccion = Basico.parseString(json['direccion']);
+    ciudad = Basico.parseString(json['ciudad']);
+    activo = Basico.parseInt(json['activo']);
+    clave = Basico.parseString(json['clave']);
+  }
+
+  Sucursal.fromApi(Map<String, dynamic> json) {
+    super.parseJson(json);
+    nombre = Basico.parseString(json['nombre']);
+    descripcion = Basico.parseString(json['descripcion']);
+    direccion = Basico.parseString(json['direccion']);
+    ciudad = Basico.parseString(json['ciudad']);
+    activo = json['activo'] == 1 ? 1 : 0;
+    clave = Basico.parseString(json['clave']);
+    creado = Basico.parseDate(json['creado']);
+    modificado = Basico.parseDate(json['modificado']);
+    eliminado = Basico.parseDate(json['eliminado']);
+  }
+
+  Future<void> guardar() async {
+    idLocal = await RepoService().guardar(this);
+  }
+}

+ 67 - 1
lib/services/repo_service.dart

@@ -6,7 +6,7 @@ import 'package:sqflite/sqflite.dart';
 import '../models/models.dart';
 
 class RepoService<T> {
-  static int dbVersion = 14;
+  static int dbVersion = 16;
   static String dbName = 'joshipos026.db';
   static const String id = Basico.identificadorWeb;
   static const String idLocal = Basico.identificadorLocal;
@@ -456,10 +456,49 @@ class RepoService<T> {
             ALTER TABLE Producto ADD COLUMN activo INTEGER;
           ''');
 
+          break;
+
         case 13:
           await db.execute('''
             ALTER TABLE Producto ADD COLUMN activo INTEGER;
           ''');
+
+          break;
+
+        case 14:
+          await db.execute('''
+            ALTER TABLE ProductoTopping ADD COLUMN idCategoria INTEGER;
+          ''');
+          await db.execute('''
+            ALTER TABLE ProductoTopping ADD COLUMN creado text;
+          ''');
+          await db.execute('''
+            ALTER TABLE ProductoTopping ADD COLUMN modificado text;
+          ''');
+          await db.execute('''
+            ALTER TABLE ProductoTopping ADD COLUMN eliminado text;
+          ''');
+
+          break;
+
+        case 15:
+          await db.execute('''
+          CREATE TABLE Sucursal (
+            id INTEGER PRIMARY KEY AUTOINCREMENT,
+            nombre TEXT,
+            descripcion TEXT,
+            direccion TEXT,
+            ciudad TEXT,
+            activo INTEGER,
+            clave TEXT,
+            eliminado TEXT,
+            creado TEXT,
+            modificado TEXT,
+            idLocal INTEGER
+          )
+        ''');
+
+          break;
       }
       oldVersion++;
     }
@@ -597,6 +636,9 @@ class RepoService<T> {
       return item.toJson();
     } else if (item is CategoriaProducto) {
       return item.toJson();
+    } else if (item is Sucursal) {
+      print("Serializando Sucursal: ${item.nombre}, ${item.descripcion}");
+      return item.toJson();
     } else if (item is Variable) {
       return item.toJson();
     }
@@ -892,4 +934,28 @@ class RepoService<T> {
       }
     }
   }
+
+  Future<void> sincronizarSucursales(List<Sucursal> sucursalesApi) async {
+    var db = await RepoService().db;
+
+    var sucursalesLocalesQuery = await db!.query('Sucursal');
+    List<Sucursal> sucursalesLocales =
+        sucursalesLocalesQuery.map((e) => Sucursal.fromJson(e)).toList();
+
+    for (var sucursalApi in sucursalesApi) {
+      var sucursalLocal = sucursalesLocales.firstWhere(
+        (sucursal) => sucursal.id == sucursalApi.id,
+        orElse: () => Sucursal(),
+      );
+
+      if (sucursalLocal.id != 0 &&
+          sucursalApi.modificado != null &&
+          (sucursalLocal.modificado == null ||
+              sucursalApi.modificado!.isAfter(sucursalLocal.modificado!))) {
+        await RepoService().guardar(sucursalApi);
+      } else if (sucursalLocal.id == 0) {
+        await RepoService().guardar(sucursalApi);
+      }
+    }
+  }
 }

+ 16 - 2
lib/viewmodels/producto_view_model.dart

@@ -179,8 +179,12 @@ class ProductoViewModel<T> extends ChangeNotifier {
   }
 
   Future<bool> sincronizarCategorias() async {
+    String? claveSucursal = await obtenerClaveSucursal();
+
     try {
-      final response = ApiResponse(await BaseService().get('/pos/categoria'));
+      Map<String, String> parametros = {"claveSucursal": claveSucursal!};
+      final response = ApiResponse(await BaseService()
+          .get('/pos/categoria', queryParameters: parametros));
 
       print(response.resultados);
 
@@ -203,8 +207,13 @@ class ProductoViewModel<T> extends ChangeNotifier {
   }
 
   Future<bool> sincronizarProductos() async {
+    String? claveSucursal = await obtenerClaveSucursal();
+
     try {
-      Map<String, String> parametros = {"limite": "-1"};
+      Map<String, String> parametros = {
+        "limite": "-1",
+        "claveSucursal": claveSucursal!
+      };
       final response = ApiResponse(await BaseService()
           .get('/pos/producto', queryParameters: parametros));
 
@@ -265,4 +274,9 @@ class ProductoViewModel<T> extends ChangeNotifier {
       fetchLocalAll(page: _currentPage - 1);
     }
   }
+
+  Future<String?> obtenerClaveSucursal() async {
+    Variable? sucursal = await RepoService().obtenerPorNombre('Sucursal');
+    return sucursal?.clave;
+  }
 }

+ 66 - 0
lib/viewmodels/sucursal_view_model.dart

@@ -0,0 +1,66 @@
+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 SucursalViewModel<T> extends ChangeNotifier {
+  List<Sucursal> _sucursales = [];
+  bool _isLoading = false;
+
+  List<Sucursal> get sucursales => _sucursales;
+  bool get isLoading => _isLoading;
+
+  Future<void> fetchLocalSucursales() async {
+    var db = await RepoService().db;
+    var query = await db!
+        .query('Sucursal', where: 'eliminado IS NULL', orderBy: 'idLocal asc');
+    _sucursales = query.map((element) => Sucursal.fromJson(element)).toList();
+    notifyListeners();
+  }
+
+  Future<bool> sincronizarSucursales() async {
+    try {
+      // Llamada a la API para obtener las sucursales
+      final response = ApiResponse(await BaseService().get('/pos/sucursal'));
+
+      if (response.isOk && response.resultados != null) {
+        List<Sucursal> sucursalesApi =
+            response.resultados!.map((json) => Sucursal.fromApi(json)).toList();
+
+        if (sucursalesApi.isNotEmpty) {
+          await RepoService().sincronizarSucursales(sucursalesApi);
+          notifyListeners();
+          return true;
+        }
+      }
+      return false;
+    } catch (e) {
+      print('Error al sincronizar sucursales: $e');
+      return false;
+    }
+  }
+
+  Future<void> sincronizarSucursalesDesdeApi() async {
+    setIsLoading(true);
+    try {
+      bool sucursalesSincronizadas = await sincronizarSucursales();
+      if (sucursalesSincronizadas) {
+        await fetchLocalSucursales();
+      }
+      print('Sucursales sincronizadas: $sucursalesSincronizadas');
+    } catch (e, stackTrace) {
+      print("Error al sincronizar sucursales: $e\n$stackTrace");
+    } finally {
+      setIsLoading(false);
+    }
+  }
+
+  void setIsLoading(bool loading) {
+    _isLoading = loading;
+    notifyListeners();
+  }
+}

+ 1 - 0
lib/viewmodels/viewmodels.dart

@@ -9,3 +9,4 @@ export '../viewmodels/media_view_model.dart';
 export '../viewmodels/pedido_view_model.dart';
 export '../viewmodels/descuento_view_model.dart';
 export '../viewmodels/variable_view_model.dart';
+export '../viewmodels/sucursal_view_model.dart';

+ 2 - 0
lib/views/home/home_screen.dart

@@ -27,6 +27,8 @@ class Formulario extends State<HomeScreen> {
     WidgetsBinding.instance.addPostFrameCallback((_) {
       Provider.of<ProductoViewModel>(context, listen: false)
           .sincronizarProductosYCategorias();
+      Provider.of<SucursalViewModel>(context, listen: false)
+          .sincronizarSucursales();
     });
   }
 

+ 75 - 0
lib/views/sucursal/sucursal_screen.dart

@@ -0,0 +1,75 @@
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import '../../viewmodels/viewmodels.dart';
+import '../../models/models.dart';
+import '../../widgets/widgets.dart';
+
+class SucursalesPage extends StatefulWidget {
+  @override
+  _SucursalesPageState createState() => _SucursalesPageState();
+}
+
+class _SucursalesPageState extends State<SucursalesPage> {
+  Sucursal? _selectedSucursal;
+
+  @override
+  void initState() {
+    super.initState();
+    // Cargar las sucursales desde la base de datos local cuando se inicializa la pantalla
+    Provider.of<SucursalViewModel>(context, listen: false)
+        .fetchLocalSucursales();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final sucursalViewModel = Provider.of<SucursalViewModel>(context);
+    final sucursales = sucursalViewModel.sucursales;
+
+    return Scaffold(
+      appBar: AppBar(
+        title: Text('Sucursales'),
+      ),
+      body: Padding(
+        padding: const EdgeInsets.all(16.0),
+        child: Column(
+          crossAxisAlignment: CrossAxisAlignment.stretch,
+          children: [
+            // Dropdown para seleccionar una sucursal
+            DropdownButton<Sucursal>(
+              hint: Text('Seleccione una sucursal'),
+              value: _selectedSucursal,
+              isExpanded: true,
+              onChanged: (Sucursal? newValue) {
+                setState(() {
+                  _selectedSucursal = newValue;
+                });
+              },
+              items: sucursales.map((Sucursal sucursal) {
+                return DropdownMenuItem<Sucursal>(
+                  value: sucursal,
+                  child: Text(sucursal.nombre ?? ''),
+                );
+              }).toList(),
+            ),
+            SizedBox(height: 20),
+            boton("Guardar", () async {
+              _guardarSucursalSeleccionada();
+              if (context.mounted) {
+                Navigator.pop(context);
+              }
+            })
+          ],
+        ),
+      ),
+    );
+  }
+
+  void _guardarSucursalSeleccionada() {
+    if (_selectedSucursal != null) {
+      // Aquí puedes implementar la lógica para guardar la sucursal seleccionada
+      print('Sucursal seleccionada: ${_selectedSucursal?.nombre}');
+      // Puedes guardar la sucursal seleccionada en el estado o base de datos local
+      // Ejemplo: Provider.of<SucursalViewModel>(context, listen: false).guardarSucursalSeleccionada(_selectedSucursal);
+    }
+  }
+}

+ 13 - 0
lib/widgets/app_drawer.dart

@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:yoshi_papas_app/views/categoria_producto/categoria_producto_screen.dart';
 import 'package:yoshi_papas_app/views/pedido/pedido_screen.dart';
 import 'package:yoshi_papas_app/views/producto/producto_screen.dart';
+import 'package:yoshi_papas_app/views/sucursal/sucursal_screen.dart';
 import 'package:yoshi_papas_app/views/variable/variable_screen.dart';
 import 'package:yoshi_papas_app/views/venta/venta_screen.dart';
 import 'package:provider/provider.dart';
@@ -158,6 +159,18 @@ class AppDrawer extends StatelessWidget {
                         ),
                       },
                     ),
+                    ListTile(
+                      leading: circulo(const Icon(Icons.storefront_outlined)),
+                      title: const Text('Sucursales'),
+                      onTap: () => {
+                        Navigator.pop(context),
+                        Navigator.of(context).push(
+                          MaterialPageRoute(
+                            builder: (context) => SucursalesPage(),
+                          ),
+                        ),
+                      },
+                    ),
                   ],
                 ),
               ],