123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- import 'dart:convert';
- import 'package:intl/intl.dart';
- import 'package:path/path.dart';
- import 'package:path_provider/path_provider.dart';
- import 'package:sqflite/sqflite.dart';
- import '../models/models.dart';
- class RepoService<T> {
- static int dbVersion = 4;
- static String dbName = 'joshipos026.db';
- static const String id = Basico.identificadorWeb;
- static const String idLocal = Basico.identificadorLocal;
- static Database? _db;
- final Map<String, dynamic> contexto = {
- 'Categoria': CategoriaProducto(),
- 'Producto': Producto(),
- 'Pedido': Pedido(productos: []),
- 'PedidoProducto': PedidoProducto(),
- 'Gasto': Gasto(),
- 'Deposito': Deposito(),
- 'CorteCaja': CorteCaja(),
- };
- Future<Database?> get db async {
- if (_db != null) return _db;
- _db = await databaseInit();
- return _db;
- }
- Future<Database> databaseInit() async {
- String dir = (await getApplicationDocumentsDirectory()).path;
- String path = join(dir, dbName);
- return await openDatabase(
- path,
- version: dbVersion,
- onCreate: _onCreate,
- onUpgrade: _onUpgrade,
- );
- }
- _onCreate(Database db, int version) async {
- contexto.forEach((String nombre, dynamic modelo) async {
- Map<String, dynamic> model = json.decode(json.encode(modelo.toJson()));
- String sql =
- "CREATE TABLE ${modelo.runtimeType.toString()} (id INTEGER PRIMARY KEY AUTOINCREMENT";
- model.forEach((String key, dynamic value) {
- if (key != "id") {
- String tipo = value.runtimeType.toString();
- String sqlType = "";
- if (equals(tipo, 'int')) {
- sqlType = "INTEGER";
- } else if (equals(tipo, 'double')) {
- sqlType = "REAL";
- } else if (equals(tipo, 'bool')) {
- sqlType = "BOOLEAN";
- } else {
- sqlType = "TEXT";
- }
- sql += ", $key $sqlType";
- }
- });
- sql += ")";
- await db.execute(sql);
- await db.execute('''
- CREATE TABLE PedidoProductoTopping (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- idPedidoProducto INTEGER,
- idTopping INTEGER,
- FOREIGN KEY (idPedidoProducto) REFERENCES PedidoProducto(id),
- FOREIGN KEY (idTopping) REFERENCES Producto(id)
- )
- ''');
- });
- await db.execute('''
- CREATE TABLE ProductoTopping (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- idProducto INTEGER,
- idTopping INTEGER,
- FOREIGN KEY (idProducto) REFERENCES Producto(id),
- FOREIGN KEY (idTopping) REFERENCES Producto(id)
- )
- ''');
- }
- void _onUpgrade(Database db, int oldVersion, int newVersion) async {
- while (oldVersion < newVersion) {
- switch (oldVersion) {
- case 1:
- await db.execute(
- "ALTER TABLE CategoriaProducto ADD COLUMN esToping INTEGER DEFAULT 0");
- await db.execute(
- "ALTER TABLE CategoriaProducto ADD COLUMN descripcion TEXT DEFAULT ''");
- await db.execute(
- "ALTER TABLE CategoriaProducto ADD COLUMN maximo INTEGER");
- await db.insert('CategoriaProducto', {
- 'nombre': 'BASE PRODUCTO',
- 'descripcion': 'Base del producto',
- 'esToping': 1,
- 'maximo': 1,
- });
- await db.insert('CategoriaProducto', {
- 'nombre': 'SALSAS PRODUCTO',
- 'descripcion': 'Elige tus salsas (Máx. 2)',
- 'esToping': 1,
- 'maximo': 2,
- });
- await db.insert('CategoriaProducto', {
- 'nombre': 'ADEREZO PRODUCTO',
- 'descripcion': 'Elige tu aderezo (Máx. 2)',
- 'esToping': 1,
- 'maximo': 2,
- });
- await db.insert('CategoriaProducto', {
- 'nombre': 'TOPPING PRODUCTO',
- 'descripcion': 'Elige tus toppings (Máx. 2)',
- 'esToping': 1,
- 'maximo': 2,
- });
- await db.insert('Producto', {
- 'nombre': 'Papa Gajo',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'Papa Regilla',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'Papa Curly',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'Papa Smile',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'Papa Francesa',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'BBQ',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'HOTBBQ',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'BUFFALO',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'TERIYAKI',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'PARMESAN GARLIC',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'QUESO AMARILLO',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'RANCH',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'CHIPOTLE',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'ADEREZO JALAPEÑO',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'KETCHUP',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'JALAPEÑO',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'QUESO BLANCO',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'TAKIS',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'RUFFLES',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'QUESO PARMESANO',
- 'precio': 0,
- });
- await db.insert('Producto', {
- 'nombre': 'ELOTE',
- 'precio': 0,
- });
- break;
- case 2:
- await db.execute('''
- CREATE TABLE ProductoTopping (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- idProducto INTEGER,
- idTopping INTEGER,
- FOREIGN KEY (idProducto) REFERENCES Producto(id),
- FOREIGN KEY (idTopping) REFERENCES Producto(id)
- )
- ''');
- break;
- case 3:
- await db.execute('''
- CREATE TABLE PedidoProductoTopping (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- idPedidoProducto INTEGER,
- idTopping INTEGER,
- FOREIGN KEY (idPedidoProducto) REFERENCES PedidoProducto(id),
- FOREIGN KEY (idTopping) REFERENCES Producto(id)
- )
- ''');
- break;
- }
- oldVersion++;
- }
- }
- Future<int> guardar(T model) async {
- try {
- var dbClient = await db;
- String nombreTabla = model.runtimeType.toString();
- String modelo = json.encode(model, toEncodable: toEncodable);
- Map<String, dynamic> modelMap = json.decode(modelo);
- int id = 0;
- if (modelMap['id'] != null && modelMap['id'] != 0) {
- await dbClient!.update(
- nombreTabla,
- modelMap,
- where: 'id = ?',
- whereArgs: [modelMap['id']],
- );
- id = modelMap['id'];
- } else {
- modelMap.remove('id');
- id = await dbClient!.insert(nombreTabla, modelMap);
- }
- if (model is Producto) {
- await _guardarToppings(dbClient, id, model.topings);
- }
- return id;
- } catch (e) {
- print('Error al guardar en $T: $e');
- return 0;
- }
- }
- Future<void> _guardarToppings(
- Database db, int idProducto, List<Producto>? topings) async {
- await db.delete('ProductoTopping',
- where: 'idProducto = ?', whereArgs: [idProducto]);
- if (topings != null) {
- for (var topping in topings) {
- await db.insert('ProductoTopping', {
- 'idProducto': idProducto,
- 'idTopping': topping.id,
- });
- }
- }
- }
- Future<int> guardarLocal(T model) async {
- var dbClient = await db;
- String nombreTabla = model.runtimeType.toString();
- String modelo = json.encode(model, toEncodable: toEncodable);
- Map<String, dynamic> modelMap = json.decode(modelo);
- if (nombreTabla == "PedidoProductoTopping") {
- modelMap.remove('idLocal');
- modelMap.remove('eliminado');
- }
- if (modelMap['id'] == null || modelMap['id'] == 0) {
- modelMap.remove('id');
- }
- int resultado;
- int? identificadorLocal = modelMap[Basico.identificadorLocal];
- if (identificadorLocal != null && identificadorLocal > 0) {
- resultado = await dbClient!.update(
- nombreTabla,
- modelMap,
- where: "$idLocal = ?",
- whereArgs: [identificadorLocal],
- );
- } else {
- resultado = await dbClient!.insert(nombreTabla, modelMap);
- var rawQuery =
- await dbClient.rawQuery("SELECT last_insert_rowid() as id");
- if (rawQuery.isNotEmpty) {
- resultado = int.parse(rawQuery.first["id"].toString());
- modelMap[Basico.identificadorLocal] = resultado;
- }
- }
- if (model is Pedido) {
- model.id = resultado;
- }
- if (model is Producto) {
- await _guardarToppings(dbClient!, model.id!, model.topings);
- }
- return resultado;
- }
- dynamic toEncodable(dynamic item) {
- if (item is Pedido) {
- return item.toJson();
- } else if (item is PedidoProducto) {
- return item.toJson();
- } else if (item is PedidoProductoTopping) {
- return item.toJson();
- } else if (item is Producto) {
- return item.toJson();
- } else if (item is CategoriaProducto) {
- return item.toJson();
- }
- throw UnsupportedError(
- 'Type not supported for serialization: ${item.runtimeType}');
- }
- Future<List<T>> obtenerTodos({String orderBy = 'id DESC'}) async {
- var db = await this.db;
- String tableName = T.toString();
- var result = await db!.query(tableName, orderBy: orderBy);
- return result.map((map) => fromMap<T>(map)).toList();
- }
- T fromMap<T>(Map<String, dynamic> map) {
- switch (T) {
- case Pedido:
- return Pedido.fromJson(map) as T;
- case Producto:
- return Producto.fromJson(map) as T;
- default:
- throw Exception('Tipo no soportado');
- }
- }
- Future<Pedido?> obtenerPorId(int id) async {
- Database? dbClient = await db;
- List<Map> maps =
- await dbClient!.query('Pedido', where: 'id = ?', whereArgs: [id]);
- if (maps.isNotEmpty) {
- return Pedido.fromJson(Map<String, dynamic>.from(maps.first));
- }
- return null;
- }
- Future<List<PedidoProducto>> obtenerPorIdPedido(int idPedido) async {
- Database? dbClient = await db;
- List<Map> maps = await dbClient!
- .query('PedidoProducto', where: 'idPedido = ?', whereArgs: [idPedido]);
- return maps
- .map((map) => PedidoProducto.fromJson(Map<String, dynamic>.from(map)))
- .toList();
- }
- Future<int> contarPedidos() async {
- Database? dbClient = await db;
- var result = await dbClient!.rawQuery('SELECT COUNT(*) FROM Pedido');
- return Sqflite.firstIntValue(result) ?? 0;
- }
- Future<List<Pedido>> obtenerPedidosPaginados(int limit, int offset) async {
- Database? dbClient = await db;
- List<Map<String, dynamic>> result = await dbClient!
- .query('Pedido', limit: limit, offset: offset, orderBy: 'id DESC');
- return result.map((map) => Pedido.fromJson(map)).toList();
- }
- Future<Producto?> obtenerProductoPorId(int idProducto) async {
- Database? dbClient = await db;
- List<Map> maps = await dbClient!
- .query('Producto', where: 'id = ?', whereArgs: [idProducto]);
- if (maps.isNotEmpty) {
- return Producto.fromJson(Map<String, dynamic>.from(maps.first));
- }
- return null;
- }
- Future<List<int>> obtenerToppingsPorProducto(int idProducto) async {
- var dbClient = await db;
- var result = await dbClient!.query(
- 'ProductoTopping',
- where: 'idProducto = ?',
- whereArgs: [idProducto],
- );
- return result.map((map) => map['idTopping'] as int).toList();
- }
- Future<List<PedidoProductoTopping>> obtenerToppingsPorPedidoProducto(
- int idPedidoProducto) async {
- var dbClient = await db;
- List<Map> maps = await dbClient!.query('PedidoProductoTopping',
- where: 'idPedidoProducto = ?', whereArgs: [idPedidoProducto]);
- if (maps.isNotEmpty) {
- return maps
- .map((map) =>
- PedidoProductoTopping.fromJson(Map<String, dynamic>.from(map)))
- .toList();
- }
- return [];
- }
- Future<int> obtenerProximoFolio() async {
- var dbClient = await db;
- var result = await dbClient!.rawQuery(
- 'SELECT MAX(CAST(folio AS INTEGER)) as last_folio FROM Pedido');
- if (result.isNotEmpty && result.first["last_folio"] != null) {
- return int.tryParse(result.first["last_folio"].toString())! + 1;
- }
- return 1;
- }
- Future<List<T>> buscarPorFolio(String folio) async {
- var dbClient = await db;
- List<Map<String, dynamic>> maps = await dbClient!.query(
- 'Pedido',
- where: 'folio LIKE ?',
- whereArgs: ['%$folio%'],
- );
- return maps.map((map) => fromMap<T>(map)).toList();
- }
- Future<List<Pedido>> buscarPorFecha(
- DateTime startDate, DateTime endDate) async {
- var dbClient = await db;
- String startDateString = DateFormat('dd-MM-yyyy').format(startDate);
- String endDateString = DateFormat('dd-MM-yyyy 23:59:59').format(endDate);
- List<Map<String, dynamic>> maps = await dbClient!.query(
- 'Pedido',
- where: 'peticion BETWEEN ? AND ?',
- whereArgs: [startDateString, endDateString],
- );
- return maps.map((map) => Pedido.fromJson(map)).toList();
- }
- Future<List<CorteCaja>> buscarPorFechaCorte(
- DateTime startDate, DateTime endDate) async {
- var dbClient = await db;
- String startDateString = DateFormat('dd-MM-yyyy').format(startDate);
- String endDateString = DateFormat('dd-MM-yyyy 23:59:59').format(endDate);
- List<Map<String, dynamic>> maps = await dbClient!.query(
- 'CorteCaja',
- where: 'fecha BETWEEN ? AND ?',
- whereArgs: [startDateString, endDateString],
- );
- return maps.map((map) => CorteCaja.fromJson(map)).toList();
- }
- Future<void> eliminar<T>(int id) async {
- var dbClient = await db;
- String tableName = T.toString();
- await dbClient!.delete(tableName, where: 'id = ?', whereArgs: [id]);
- }
- }
|