repo_service.dart 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import 'dart:convert';
  2. import 'package:path/path.dart';
  3. import 'package:path_provider/path_provider.dart';
  4. import 'package:sqflite/sqflite.dart';
  5. import '../models/models.dart';
  6. class RepoService<T> {
  7. static int dbVersion = 1;
  8. static String dbName = 'joshipos023.db';
  9. static const String id = Basico.identificadorWeb;
  10. static const String idLocal = Basico.identificadorLocal;
  11. static Database? _db;
  12. final Map<String, dynamic> contexto = {
  13. 'Categoria': CategoriaProducto(),
  14. 'Producto': Producto(),
  15. 'Pedido': Pedido(productos: []),
  16. 'PedidoProducto': PedidoProducto(),
  17. };
  18. Future<Database?> get db async {
  19. if (_db != null) return _db;
  20. _db = await databaseInit();
  21. return _db;
  22. }
  23. Future<Database> databaseInit() async {
  24. String dir = (await getApplicationDocumentsDirectory()).path;
  25. String path = join(dir, dbName);
  26. return await openDatabase(
  27. path,
  28. version: dbVersion,
  29. onCreate: _onCreate,
  30. onUpgrade: _onUpgrade,
  31. );
  32. }
  33. /// Crea la base de datos
  34. _onCreate(Database db, int version) async {
  35. contexto.forEach((String nombre, dynamic modelo) async {
  36. Map<String, dynamic> model = json.decode(json.encode(modelo.toJson()));
  37. String sql =
  38. "CREATE TABLE ${modelo.runtimeType.toString()} (id INTEGER PRIMARY KEY AUTOINCREMENT";
  39. model.forEach((String key, dynamic value) {
  40. if (key != "id") {
  41. // No incluir la columna de identificador local de nuevo
  42. String tipo = value.runtimeType.toString();
  43. String sqlType = "";
  44. if (equals(tipo, 'int')) {
  45. sqlType = "INTEGER";
  46. } else if (equals(tipo, 'double')) {
  47. sqlType = "REAL";
  48. } else if (equals(tipo, 'bool')) {
  49. sqlType = "BOOLEAN";
  50. } else {
  51. sqlType = "TEXT";
  52. }
  53. // Añadir cada campo al SQL, asegurándose de no configurar AUTOINCREMENT en folio
  54. sql += ", $key $sqlType";
  55. }
  56. });
  57. sql += ")";
  58. await db.execute(sql);
  59. });
  60. }
  61. /// Actualiza la version de la base de datos
  62. _onUpgrade(Database db, int oldVersion, int newVersion) async {
  63. while (oldVersion <= newVersion) {
  64. switch (oldVersion) {
  65. case 100:
  66. /* await db.execute("DROP TABLE IF EXISTS Evidencia");
  67. await db.execute('CREATE TABLE TABLAA (idLocal INTEGER PRIMARY KEY)');
  68. List<String> sueltos = [
  69. "ALTER TABLE Evidencia ADD id INTEGER",
  70. ];
  71. for(int i = 0; i < sueltos.length; i++) {
  72. try {
  73. String sql = sueltos.elementAt(i);
  74. await db.execute(sql);
  75. } catch (e) {}
  76. } */
  77. break;
  78. }
  79. oldVersion++;
  80. }
  81. }
  82. /// Guarda un modelo de datos nuevo o modificado en el repositorio
  83. Future<int> guardar(T model) async {
  84. var dbClient = await db;
  85. String nombreTabla = model.runtimeType.toString();
  86. String modelo = json.encode(model, toEncodable: toEncodable);
  87. Map<String, dynamic> modelMap = json.decode(modelo);
  88. // Elimina 'id' si es 0 o null para evitar conflictos con AUTOINCREMENT
  89. if (modelMap['id'] == null || modelMap['id'] == 0) {
  90. modelMap.remove('id');
  91. }
  92. int resultado;
  93. if (modelMap[Basico.identificadorLocal] > 0) {
  94. resultado = await dbClient!.update(
  95. nombreTabla,
  96. modelMap,
  97. where: "$idLocal = ?",
  98. whereArgs: [modelMap[Basico.identificadorLocal]],
  99. );
  100. } else {
  101. resultado = await dbClient!.insert(nombreTabla, modelMap);
  102. var rawQuery =
  103. await dbClient.rawQuery("SELECT last_insert_rowid() as id");
  104. if (rawQuery.isNotEmpty) {
  105. resultado = int.parse(rawQuery.first["id"].toString());
  106. modelMap[Basico.identificadorLocal] =
  107. resultado; // Actualiza el ID del modelo
  108. }
  109. }
  110. if (model is Pedido) {
  111. // Asegúrate de actualizar el ID en el objeto Pedido después de guardar
  112. model.id = resultado;
  113. }
  114. return resultado;
  115. }
  116. dynamic toEncodable(dynamic item) {
  117. Map<String, dynamic> map = {};
  118. item.toJson().forEach((key, value) {
  119. if (value is DateTime) {
  120. map[key] = value.toIso8601String();
  121. } else {
  122. map[key] = value;
  123. }
  124. });
  125. return map;
  126. }
  127. Future<List<T>> obtenerTodos() async {
  128. var dbClient = await db;
  129. String tableName = T
  130. .toString(); // Obtiene el nombre del modelo, que asumimos coincide con el nombre de la tabla
  131. List<Map<String, dynamic>> result = await dbClient!.query(tableName);
  132. return result.map((map) => fromMap<T>(map)).toList();
  133. }
  134. // Necesitarás una función que convierta un Map a un objeto de tipo T
  135. T fromMap<T>(Map<String, dynamic> map) {
  136. switch (T) {
  137. case Pedido:
  138. return Pedido.fromJson(map) as T;
  139. case Producto:
  140. return Producto.fromJson(map) as T;
  141. // Añade más casos si tienes más tipos
  142. default:
  143. throw Exception('Tipo no soportado');
  144. }
  145. }
  146. Future<Pedido?> obtenerPorId(int id) async {
  147. Database? dbClient = await db;
  148. List<Map> maps = await dbClient!.query('Pedido',
  149. where:
  150. 'id = ?', // Asegúrate de que el nombre de la columna sea 'id' y no 'idLocal'
  151. whereArgs: [id]);
  152. if (maps.isNotEmpty) {
  153. return Pedido.fromJson(Map<String, dynamic>.from(maps.first));
  154. }
  155. return null;
  156. }
  157. Future<List<PedidoProducto>> obtenerPorIdPedido(int idPedido) async {
  158. Database? dbClient = await db;
  159. List<Map> maps = await dbClient!
  160. .query('PedidoProducto', where: 'idPedido = ?', whereArgs: [idPedido]);
  161. return maps
  162. .map((map) => PedidoProducto.fromJson(Map<String, dynamic>.from(map)))
  163. .toList();
  164. }
  165. Future<Producto?> obtenerProductoPorId(int idProducto) async {
  166. Database? dbClient = await db;
  167. List<Map> maps = await dbClient!
  168. .query('Producto', where: 'id = ?', whereArgs: [idProducto]);
  169. if (maps.isNotEmpty) {
  170. return Producto.fromJson(Map<String, dynamic>.from(maps.first));
  171. }
  172. return null;
  173. }
  174. Future<int> obtenerProximoFolio() async {
  175. var dbClient = await db;
  176. var result =
  177. await dbClient!.rawQuery('SELECT MAX(folio) as last_folio FROM Pedido');
  178. if (result.isNotEmpty && result.first["last_folio"] != null) {
  179. return int.tryParse(result.first["last_folio"].toString())! + 1;
  180. }
  181. return 1; // Retorna 1 si no hay registros anteriores
  182. }
  183. }