repo_service.dart 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. import 'dart:convert';
  2. import 'package:conalep_pos/models/mesa_model.dart';
  3. import 'package:intl/intl.dart';
  4. import 'package:path/path.dart';
  5. import 'package:path_provider/path_provider.dart';
  6. import 'package:sqflite/sqflite.dart';
  7. import '../models/models.dart';
  8. class RepoService<T> {
  9. static int dbVersion = 15;
  10. static String dbName = 'conalepPos7.db';
  11. static const String id = Basico.identificadorWeb;
  12. static const String idLocal = Basico.identificadorLocal;
  13. static Database? _db;
  14. final Map<String, dynamic> contexto = {
  15. 'Categoria': CategoriaProducto(),
  16. 'Producto': Producto(),
  17. 'Pedido': Pedido(productos: []),
  18. 'PedidoProducto': PedidoProducto(),
  19. 'Gasto': Gasto(),
  20. 'Deposito': Deposito(),
  21. 'CorteCaja': CorteCaja(),
  22. };
  23. Future<Database?> get db async {
  24. if (_db != null) return _db;
  25. _db = await databaseInit();
  26. return _db;
  27. }
  28. Future<Database> databaseInit() async {
  29. String dir = (await getApplicationDocumentsDirectory()).path;
  30. String path = join(dir, dbName);
  31. print(path);
  32. return await openDatabase(
  33. path,
  34. version: dbVersion,
  35. onCreate: _onCreate,
  36. onUpgrade: _onUpgrade,
  37. );
  38. }
  39. /// Crea la base de datos
  40. _onCreate(Database db, int version) async {
  41. contexto.forEach((String nombre, dynamic modelo) async {
  42. Map<String, dynamic> model = json.decode(json.encode(modelo.toJson()));
  43. String sql =
  44. "CREATE TABLE ${modelo.runtimeType.toString()} (id INTEGER PRIMARY KEY AUTOINCREMENT";
  45. model.forEach((String key, dynamic value) {
  46. if (key != "id") {
  47. String tipo = value.runtimeType.toString();
  48. String sqlType = "";
  49. if (equals(tipo, 'int')) {
  50. sqlType = "INTEGER";
  51. } else if (equals(tipo, 'double')) {
  52. sqlType = "REAL";
  53. } else if (equals(tipo, 'bool')) {
  54. sqlType = "BOOLEAN";
  55. } else {
  56. sqlType = "TEXT";
  57. }
  58. sql += ", $key $sqlType";
  59. }
  60. });
  61. sql += ")";
  62. await db.execute(sql);
  63. await db.execute('''
  64. CREATE TABLE PedidoProductoTopping (
  65. id INTEGER PRIMARY KEY AUTOINCREMENT,
  66. idPedidoProducto INTEGER,
  67. idTopping INTEGER,
  68. FOREIGN KEY (idPedidoProducto) REFERENCES PedidoProducto(id),
  69. FOREIGN KEY (idTopping) REFERENCES Producto(id)
  70. )
  71. ''');
  72. if (modelo.runtimeType.toString() == 'Pedido') {
  73. await db.execute(
  74. 'ALTER TABLE Pedido ADD COLUMN IF NOT EXISTS descuento INTEGER DEFAULT 0');
  75. await db.execute(
  76. 'ALTER TABLE Pedido ADD COLUMN IF NOT EXISTS sincronizado TEXT;');
  77. }
  78. await db.execute('''
  79. CREATE TABLE Descuento (
  80. id INTEGER PRIMARY KEY AUTOINCREMENT,
  81. porcentaje INTEGER
  82. )
  83. ''');
  84. await db.insert('Descuento', {'porcentaje': 0});
  85. await db.insert('Descuento', {'porcentaje': 5});
  86. await db.insert('Descuento', {'porcentaje': 10});
  87. await db.insert('Descuento', {'porcentaje': 15});
  88. await db.insert('Descuento', {'porcentaje': 20});
  89. await db.insert('Descuento', {'porcentaje': 25});
  90. await db.insert('Descuento', {'porcentaje': 30});
  91. });
  92. await db.execute('''
  93. CREATE TABLE ProductoTopping (
  94. id INTEGER PRIMARY KEY AUTOINCREMENT,
  95. idProducto INTEGER,
  96. idTopping INTEGER,
  97. FOREIGN KEY (idProducto) REFERENCES Producto(id),
  98. FOREIGN KEY (idTopping) REFERENCES Producto(id)
  99. )
  100. ''');
  101. await db.execute('''
  102. CREATE TABLE Variable (
  103. id INTEGER PRIMARY KEY AUTOINCREMENT,
  104. nombre TEXT,
  105. clave TEXT,
  106. descripcion TEXT,
  107. activo BOOLEAN,
  108. idLocal INTEGER,
  109. eliminado TEXT
  110. )
  111. ''');
  112. await db.execute('''
  113. CREATE TABLE Mesa (
  114. id INTEGER PRIMARY KEY AUTOINCREMENT,
  115. idLocal INTEGER,
  116. nombre TEXT,
  117. clave TEXT,
  118. activa BOOLEAN,
  119. creado TEXT,
  120. modificado TEXT,
  121. eliminado TEXT
  122. )
  123. ''');
  124. }
  125. /// Actualiza la version de la base de datos
  126. void _onUpgrade(Database db, int oldVersion, int newVersion) async {
  127. while (oldVersion < newVersion) {
  128. switch (oldVersion) {
  129. case 1:
  130. await db.execute(
  131. "ALTER TABLE CategoriaProducto ADD COLUMN IF NOT EXISTS esToping INTEGER DEFAULT 0");
  132. await db.execute(
  133. "ALTER TABLE CategoriaProducto ADD COLUMN IF NOT EXISTS descripcion TEXT DEFAULT ''");
  134. await db.execute(
  135. "ALTER TABLE CategoriaProducto ADD COLUMN IF NOT EXISTS maximo INTEGER");
  136. break;
  137. case 2:
  138. await db.execute('''
  139. CREATE TABLE ProductoTopping (
  140. id INTEGER PRIMARY KEY AUTOINCREMENT,
  141. idProducto INTEGER,
  142. idTopping INTEGER,
  143. FOREIGN KEY (idProducto) REFERENCES Producto(id),
  144. FOREIGN KEY (idTopping) REFERENCES Producto(id)
  145. )
  146. ''');
  147. break;
  148. case 3:
  149. await db.execute('''
  150. CREATE TABLE PedidoProductoTopping (
  151. id INTEGER PRIMARY KEY AUTOINCREMENT,
  152. idPedidoProducto INTEGER,
  153. idTopping INTEGER,
  154. FOREIGN KEY (idPedidoProducto) REFERENCES PedidoProducto(id),
  155. FOREIGN KEY (idTopping) REFERENCES Producto(id)
  156. )
  157. ''');
  158. break;
  159. case 4:
  160. await db.execute('''
  161. ALTER TABLE Pedido ADD COLUMN IF NOT EXISTS descuento INTEGER DEFAULT 0
  162. ''');
  163. break;
  164. case 5:
  165. await db.execute('''
  166. CREATE TABLE IF NOT EXISTS Descuento (
  167. id INTEGER PRIMARY KEY AUTOINCREMENT,
  168. porcentaje INTEGER
  169. )
  170. ''');
  171. await db.insert('Descuento', {'porcentaje': 0});
  172. await db.insert('Descuento', {'porcentaje': 5});
  173. await db.insert('Descuento', {'porcentaje': 10});
  174. await db.insert('Descuento', {'porcentaje': 15});
  175. await db.insert('Descuento', {'porcentaje': 20});
  176. await db.insert('Descuento', {'porcentaje': 25});
  177. await db.insert('Descuento', {'porcentaje': 30});
  178. break;
  179. case 6:
  180. await db.execute('''
  181. ALTER TABLE Pedido ADD COLUMN IF NOT EXISTS tipoPago TEXT DEFAULT '';
  182. ''');
  183. await db.execute('''
  184. ALTER TABLE Pedido ADD COLUMN IF NOT EXISTS cantEfectivo REAL DEFAULT 0;
  185. ''');
  186. await db.execute('''
  187. ALTER TABLE Pedido ADD COLUMN IF NOT EXISTS cantTarjeta REAL DEFAULT 0;
  188. ''');
  189. await db.execute('''
  190. ALTER TABLE Pedido ADD COLUMN IF NOT EXISTS cantTransferencia REAL DEFAULT 0;
  191. ''');
  192. break;
  193. case 7:
  194. await db.execute('''
  195. CREATE TABLE Variable (
  196. id INTEGER PRIMARY KEY AUTOINCREMENT,
  197. nombre TEXT,
  198. clave TEXT,
  199. descripcion TEXT,
  200. activo BOOLEAN,
  201. idLocal INTEGER,
  202. eliminado TEXT
  203. )
  204. ''');
  205. break;
  206. case 8:
  207. await db.execute('''
  208. ALTER TABLE Producto ADD COLUMN IF NOT EXISTS toping INTEGER DEFAULT 0;
  209. ''');
  210. break;
  211. case 9:
  212. await db.execute('''
  213. ALTER TABLE Pedido ADD COLUMN idWeb INTEGER;
  214. ''');
  215. await db.execute('''
  216. ALTER TABLE Pedido ADD COLUMN sincronizado TEXT;
  217. ''');
  218. await db.execute('''
  219. ALTER TABLE PedidoProducto ADD COLUMN idWeb INTEGER;
  220. ''');
  221. await db.execute('''
  222. ALTER TABLE PedidoProducto ADD COLUMN sincronizado TEXT;
  223. ''');
  224. break;
  225. // case 10:
  226. // await db.execute('''
  227. // ALTER TABLE Pedido ADD COLUMN idWeb INTEGER;
  228. // ''');
  229. // await db.execute('''
  230. // ALTER TABLE Pedido ADD COLUMN sincronizado TEXT;
  231. // ''');
  232. // await db.execute('''
  233. // ALTER TABLE PedidoProducto ADD COLUMN idWeb INTEGER;
  234. // ''');
  235. // await db.execute('''
  236. // ALTER TABLE PedidoProducto ADD COLUMN sincronizado TEXT;
  237. // ''');
  238. // break;
  239. // case 11:
  240. // await db.execute('''
  241. // ALTER TABLE Pedido ADD COLUMN idWeb INTEGER;
  242. // ''');
  243. // await db.execute('''
  244. // ALTER TABLE Pedido ADD COLUMN sincronizado TEXT;
  245. // ''');
  246. // await db.execute('''
  247. // ALTER TABLE PedidoProducto ADD COLUMN idWeb INTEGER;
  248. // ''');
  249. // await db.execute('''
  250. // ALTER TABLE PedidoProducto ADD COLUMN sincronizado TEXT;
  251. // ''');
  252. // break;
  253. case 12:
  254. await db.execute('''
  255. update Pedido set sincronizado = null, peticion = strftime('%Y-%m-%dT%H:%M:%S',
  256. datetime(substr(peticion, 7, 4) || '-' ||
  257. substr(peticion, 4, 2) || '-' ||
  258. substr(peticion, 1, 2) || ' ' ||
  259. substr(peticion, 12, 8) || ' -07:00', 'localtime', '+07:00'))
  260. WHERE strftime('%Y-%m-%dT%H:%M:%S',
  261. datetime(substr(peticion, 7, 4) || '-' ||
  262. substr(peticion, 4, 2) || '-' ||
  263. substr(peticion, 1, 2) || ' ' ||
  264. substr(peticion, 12, 8) || ' -07:00', 'localtime', '+07:00')) is not null
  265. ''');
  266. break;
  267. case 13:
  268. await db.execute('DROP TABLE IF EXISTS Producto');
  269. //Se tiene que crear nuevamente para que precio sea Double
  270. await db.execute('''
  271. CREATE TABLE Producto (
  272. id INTEGER PRIMARY KEY AUTOINCREMENT,
  273. idCategoria INTEGER,
  274. idLocal INTEGER,
  275. nombre TEXT,
  276. descripcion TEXT,
  277. imagen TEXT,
  278. venta INTEGER,
  279. existencia INTEGER,
  280. precio REAL,
  281. verMenu INTEGER,
  282. codigo TEXT,
  283. descuento TEXT,
  284. toping INTEGER,
  285. creado TEXT,
  286. modificado TEXT,
  287. eliminado TEXT
  288. )
  289. ''');
  290. await db.execute('DELETE FROM CategoriaProducto');
  291. await db.execute('''
  292. ALTER TABLE CategoriaProducto ADD COLUMN creado TEXT;
  293. ''');
  294. await db.execute('''
  295. ALTER TABLE CategoriaProducto ADD COLUMN modificado TEXT;
  296. ''');
  297. break;
  298. case 14:
  299. await db.execute('DROP TABLE IF EXISTS Mesa');
  300. //Se tiene que crear nuevamente para que precio sea Double
  301. await db.execute('''
  302. CREATE TABLE Mesa (
  303. id INTEGER PRIMARY KEY AUTOINCREMENT,
  304. idLocal INTEGER,
  305. nombre TEXT,
  306. clave TEXT,
  307. activa BOOLEAN,
  308. creado TEXT,
  309. modificado TEXT,
  310. eliminado TEXT
  311. )
  312. ''');
  313. break;
  314. }
  315. oldVersion++;
  316. }
  317. }
  318. Future<int> guardar(T model) async {
  319. try {
  320. print("Guardando modelo en la base de datos: ${model.runtimeType}");
  321. String modelo = json.encode(model, toEncodable: toEncodable);
  322. print("Modelo convertido a JSON: $modelo");
  323. Map<String, dynamic> modelMap = json.decode(modelo);
  324. var dbClient = await db;
  325. String nombreTabla = model.runtimeType.toString();
  326. // Verificar si el modelo tiene ID asignado
  327. int? id = modelMap['id'];
  328. // Eliminar el campo 'id' si es 0 o null para permitir autoincremento
  329. if (id == null || id == 0) {
  330. modelMap.remove('id');
  331. }
  332. List<Map> existing = id != null && id > 0
  333. ? await dbClient!.query(nombreTabla, where: 'id = ?', whereArgs: [id])
  334. : [];
  335. if (existing.isNotEmpty) {
  336. print("Actualizando registro existente con ID: $id");
  337. await dbClient!.update(
  338. nombreTabla,
  339. modelMap,
  340. where: 'id = ?',
  341. whereArgs: [id],
  342. );
  343. } else {
  344. print("Insertando nuevo registro en la tabla $nombreTabla");
  345. id = await dbClient!.insert(nombreTabla, modelMap);
  346. }
  347. return id!;
  348. } catch (e) {
  349. print('Error al guardar en dynamic: $e');
  350. return 0;
  351. }
  352. }
  353. Future<void> _guardarToppings(
  354. Database db, int idProducto, List<Producto>? topings) async {
  355. await db.delete('ProductoTopping',
  356. where: 'idProducto = ?', whereArgs: [idProducto]);
  357. if (topings != null) {
  358. for (var topping in topings) {
  359. await db.insert('ProductoTopping', {
  360. 'idProducto': idProducto,
  361. 'idTopping': topping.id,
  362. });
  363. }
  364. }
  365. }
  366. Future<int> guardarLocal(T model) async {
  367. var dbClient = await db;
  368. String nombreTabla = model.runtimeType.toString();
  369. String modelo = json.encode(model, toEncodable: toEncodable);
  370. Map<String, dynamic> modelMap = json.decode(modelo);
  371. if (nombreTabla == "PedidoProductoTopping") {
  372. modelMap.remove('idLocal');
  373. modelMap.remove('eliminado');
  374. }
  375. int resultado;
  376. int? identificadorLocal = modelMap[Basico.identificadorLocal];
  377. if (modelMap['id'] == null || modelMap['id'] == 0) {
  378. modelMap.remove('id');
  379. identificadorLocal = modelMap[Basico.identificadorLocal];
  380. } else {
  381. identificadorLocal = modelMap['id'];
  382. }
  383. if (identificadorLocal != null && identificadorLocal > 0) {
  384. resultado = await dbClient!.update(
  385. nombreTabla,
  386. modelMap,
  387. where: "$id = ?",
  388. whereArgs: [identificadorLocal],
  389. );
  390. } else {
  391. resultado = await dbClient!.insert(nombreTabla, modelMap);
  392. var rawQuery =
  393. await dbClient.rawQuery("SELECT last_insert_rowid() as id");
  394. if (rawQuery.isNotEmpty) {
  395. resultado = int.parse(rawQuery.first["id"].toString());
  396. modelMap[Basico.identificadorLocal] = resultado;
  397. }
  398. }
  399. if (model is Pedido) {
  400. model.id = resultado;
  401. }
  402. if (model is Producto) {
  403. await _guardarToppings(dbClient!, model.id!, model.topings);
  404. }
  405. return resultado;
  406. }
  407. dynamic toEncodable(dynamic item) {
  408. if (item is Pedido) {
  409. return item.toJson();
  410. } else if (item is PedidoProducto) {
  411. return item.toJson();
  412. } else if (item is PedidoProductoTopping) {
  413. return item.toJson();
  414. } else if (item is Producto) {
  415. print("Convirtiendo Producto a JSON para guardar");
  416. return item.toJson();
  417. } else if (item is CategoriaProducto) {
  418. print("Convirtiendo CategoriaProducto a JSON para guardar");
  419. return item.toJson();
  420. } else if (item is Variable) {
  421. return item.toJson();
  422. } else if (item is Mesa) {
  423. return item.toJson();
  424. }
  425. throw UnsupportedError(
  426. 'Type not supported for serialization: ${item.runtimeType}');
  427. }
  428. Future<List<T>> obtenerTodos({String orderBy = 'id DESC'}) async {
  429. var db = await this.db;
  430. String tableName = T.toString();
  431. var result = await db!
  432. .query(tableName, where: 'eliminado IS NULL', orderBy: orderBy);
  433. return result.map((map) => fromMap<T>(map)).toList();
  434. }
  435. T fromMap<T>(Map<String, dynamic> map) {
  436. switch (T) {
  437. case Pedido:
  438. return Pedido.fromJson(map) as T;
  439. case Producto:
  440. return Producto.fromJson(map) as T;
  441. default:
  442. throw Exception('Tipo no soportado');
  443. }
  444. }
  445. Future<Pedido?> obtenerPorId(int id) async {
  446. Database? dbClient = await db;
  447. List<Map> maps =
  448. await dbClient!.query('Pedido', where: 'id = ?', whereArgs: [id]);
  449. if (maps.isNotEmpty) {
  450. return Pedido.fromJson(Map<String, dynamic>.from(maps.first));
  451. }
  452. return null;
  453. }
  454. Future<List<PedidoProducto>> obtenerPorIdPedido(int idPedido) async {
  455. Database? dbClient = await db;
  456. List<Map> maps = await dbClient!
  457. .query('PedidoProducto', where: 'idPedido = ?', whereArgs: [idPedido]);
  458. return maps
  459. .map((map) => PedidoProducto.fromJson(Map<String, dynamic>.from(map)))
  460. .toList();
  461. }
  462. Future<List<Deposito>> obtenerDepositosPorIdCorteCaja(int idCorteCaja) async {
  463. var dbClient = await db;
  464. List<Map<String, dynamic>> maps = await dbClient!.query(
  465. 'Deposito',
  466. where: 'idCorteCaja = ?',
  467. whereArgs: [idCorteCaja],
  468. );
  469. return maps.map((map) => Deposito.fromJson(map)).toList();
  470. }
  471. Future<List<Gasto>> obtenerGastosPorIdCorteCaja(int idCorteCaja) async {
  472. var dbClient = await db;
  473. List<Map<String, dynamic>> maps = await dbClient!.query(
  474. 'Gasto',
  475. where: 'idCorteCaja = ?',
  476. whereArgs: [idCorteCaja],
  477. );
  478. return maps.map((map) => Gasto.fromJson(map)).toList();
  479. }
  480. Future<int> contarPedidos() async {
  481. Database? dbClient = await db;
  482. var result = await dbClient!.rawQuery('SELECT COUNT(*) FROM Pedido');
  483. return Sqflite.firstIntValue(result) ?? 0;
  484. }
  485. Future<List<Pedido>> obtenerPedidosPaginados(int limit, int offset) async {
  486. Database? dbClient = await db;
  487. List<Map<String, dynamic>> result = await dbClient!.query('Pedido',
  488. limit: limit,
  489. offset: offset,
  490. orderBy: 'id DESC',
  491. where: 'idMesa IS NULL');
  492. return result.map((map) => Pedido.fromJson(map)).toList();
  493. }
  494. Future<List<Pedido>> obtenerMesaPedidosPaginados(
  495. int limit, int offset) async {
  496. Database? dbClient = await db;
  497. List<Map<String, dynamic>> result = await dbClient!.query('Pedido',
  498. limit: limit,
  499. offset: offset,
  500. orderBy: 'id DESC',
  501. where: 'idMesa IS NOT NULL');
  502. return result.map((map) => Pedido.fromJson(map)).toList();
  503. }
  504. Future<Producto?> obtenerProductoPorId(int idProducto) async {
  505. Database? dbClient = await db;
  506. List<Map> maps = await dbClient!
  507. .query('Producto', where: 'id = ?', whereArgs: [idProducto]);
  508. if (maps.isNotEmpty) {
  509. return Producto.fromJson(Map<String, dynamic>.from(maps.first));
  510. }
  511. return null;
  512. }
  513. Future<List<int>> obtenerToppingsPorProducto(int idProducto) async {
  514. var dbClient = await db;
  515. var result = await dbClient!.query(
  516. 'ProductoTopping',
  517. where: 'idProducto = ?',
  518. whereArgs: [idProducto],
  519. );
  520. return result.map((map) => map['idTopping'] as int).toList();
  521. }
  522. Future<List<PedidoProductoTopping>> obtenerToppingsPorPedidoProducto(
  523. int idPedidoProducto) async {
  524. var dbClient = await db;
  525. List<Map> maps = await dbClient!.query('PedidoProductoTopping',
  526. where: 'idPedidoProducto = ?', whereArgs: [idPedidoProducto]);
  527. if (maps.isNotEmpty) {
  528. return maps
  529. .map((map) =>
  530. PedidoProductoTopping.fromJson(Map<String, dynamic>.from(map)))
  531. .toList();
  532. }
  533. return [];
  534. }
  535. Future<int> obtenerProximoFolio() async {
  536. var dbClient = await db;
  537. var result = await dbClient!.rawQuery(
  538. 'SELECT MAX(CAST(folio AS INTEGER)) as last_folio FROM Pedido');
  539. if (result.isNotEmpty && result.first["last_folio"] != null) {
  540. return int.tryParse(result.first["last_folio"].toString())! + 1;
  541. }
  542. return 1;
  543. }
  544. Future<List<T>> buscarPorFolio(String folio) async {
  545. var dbClient = await db;
  546. List<Map<String, dynamic>> maps = await dbClient!.query(
  547. 'Pedido',
  548. where: 'folio LIKE ?',
  549. whereArgs: ['%$folio%'],
  550. );
  551. return maps.map((map) => fromMap<T>(map)).toList();
  552. }
  553. Future<List<Pedido>> buscarPorFecha(
  554. DateTime startDate, DateTime endDate) async {
  555. var dbClient = await db;
  556. String startDateString = startDate.toIso8601String();
  557. String endDateString = endDate.toIso8601String();
  558. print(
  559. 'Ejecutando consulta: SELECT * FROM Pedido WHERE peticion BETWEEN $startDateString AND $endDateString');
  560. List<Map<String, dynamic>> maps = await dbClient!.rawQuery('''
  561. SELECT * FROM Pedido
  562. WHERE peticion BETWEEN ? AND ?
  563. ''', [startDateString, endDateString]);
  564. print('Resultado de la consulta: ${maps.length} pedidos encontrados.');
  565. return maps.map((map) => Pedido.fromJson(map)).toList();
  566. }
  567. Future<List<CorteCaja>> buscarPorFechaCorte(
  568. DateTime startDate, DateTime endDate) async {
  569. var dbClient = await db;
  570. String startDateString = DateFormat('dd-MM-yyyy').format(startDate);
  571. String endDateString = DateFormat('dd-MM-yyyy 23:59:59').format(endDate);
  572. List<Map<String, dynamic>> maps = await dbClient!.query(
  573. 'CorteCaja',
  574. where: 'fecha BETWEEN ? AND ?',
  575. whereArgs: [startDateString, endDateString],
  576. );
  577. return maps.map((map) => CorteCaja.fromJson(map)).toList();
  578. }
  579. Future<void> eliminar<T>(int id) async {
  580. var dbClient = await db;
  581. String tableName = T.toString();
  582. await dbClient!.delete(tableName, where: 'id = ?', whereArgs: [id]);
  583. }
  584. Future<List<Descuento>> obtenerTodosDescuentos() async {
  585. var dbClient = await db;
  586. var result = await dbClient!.query('Descuento', orderBy: 'porcentaje ASC');
  587. return result.map((map) => Descuento.fromJson(map)).toList();
  588. }
  589. Future<int> guardarDescuento(Descuento descuento) async {
  590. var dbClient = await db;
  591. if (descuento.id != null && descuento.id! > 0) {
  592. return await dbClient!.update(
  593. 'Descuento',
  594. descuento.toJson(),
  595. where: 'id = ?',
  596. whereArgs: [descuento.id],
  597. );
  598. } else {
  599. return await dbClient!.insert('Descuento', descuento.toJson());
  600. }
  601. }
  602. Future<int> eliminarDescuento(int id) async {
  603. var dbClient = await db;
  604. return await dbClient!
  605. .delete('Descuento', where: 'id = ?', whereArgs: [id]);
  606. }
  607. Future<Variable?> obtenerPorNombre(String nombre) async {
  608. var dbClient = await db;
  609. List<Map<String, dynamic>> maps = await dbClient!.query(
  610. 'Variable',
  611. where: 'nombre = ?',
  612. whereArgs: [nombre],
  613. );
  614. if (maps.isNotEmpty) {
  615. return Variable.fromJson(Map<String, dynamic>.from(maps.first));
  616. }
  617. return null;
  618. }
  619. Future<List<Pedido>> obtenerPedidosOrdenadosPorFecha() async {
  620. var dbClient = await db;
  621. String orderBy =
  622. "datetime(substr(peticion, 7, 4) || '-' || substr(peticion, 4, 2) || '-' || substr(peticion, 1, 2) || ' ' || substr(peticion, 12)) ASC";
  623. List<Map<String, dynamic>> result = await dbClient!.query(
  624. 'Pedido',
  625. where: 'sincronizado IS NULL',
  626. orderBy: orderBy,
  627. );
  628. return result.map((map) => Pedido.fromJson(map)).toList();
  629. }
  630. Future<void> sincronizarCategorias(
  631. List<CategoriaProducto> categoriasApi) async {
  632. var db = await RepoService().db;
  633. var categoriasLocalesQuery = await db!.query('CategoriaProducto');
  634. List<CategoriaProducto> categoriasLocales = categoriasLocalesQuery
  635. .map((e) => CategoriaProducto.fromJson(e))
  636. .toList();
  637. for (var categoriaApi in categoriasApi) {
  638. var categoriaLocal = categoriasLocales.firstWhere(
  639. (categoria) => categoria.id == categoriaApi.id,
  640. orElse: () => CategoriaProducto(),
  641. );
  642. if (categoriaLocal.id != 0 &&
  643. categoriaApi.modificado != null &&
  644. categoriaLocal.modificado != null &&
  645. categoriaApi.modificado!.isAfter(categoriaLocal.modificado!)) {
  646. await RepoService().guardar(categoriaApi);
  647. } else if (categoriaLocal.id == 0) {
  648. await RepoService().guardar(categoriaApi);
  649. }
  650. }
  651. }
  652. Future<void> sincronizarProductos(List<Producto> productosApi) async {
  653. var db = await RepoService().db;
  654. var productosLocalesQuery = await db!.query('Producto');
  655. List<Producto> productosLocales =
  656. productosLocalesQuery.map((e) => Producto.fromJson(e)).toList();
  657. for (var productoApi in productosApi) {
  658. var productoLocal = productosLocales.firstWhere(
  659. (producto) => producto.id == productoApi.id,
  660. orElse: () => Producto(),
  661. );
  662. if (productoLocal.id != 0 &&
  663. productoApi.modificado != null &&
  664. productoLocal.modificado != null &&
  665. productoApi.modificado!.isAfter(productoLocal.modificado!)) {
  666. await RepoService().guardar(productoApi);
  667. } else if (productoLocal.id == 0) {
  668. await RepoService().guardar(productoApi);
  669. }
  670. }
  671. }
  672. }