ordine_sync_service.dart 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. import 'package:drift/drift.dart';
  2. import 'package:ristoris/database/daos/agenti_dao.dart';
  3. import 'package:ristoris/database/daos/clienti_agente_dao.dart';
  4. import 'package:ristoris/providers/database_provider.dart';
  5. import 'package:riverpod/src/provider.dart';
  6. import '../api_service.dart';
  7. import '../../database/database.dart';
  8. import '../../database/daos/ordini_dao.dart';
  9. import '../../database/daos/clienti_dao.dart';
  10. import '../../database/daos/filiali_dao.dart';
  11. import '../../dto/sync_order_dto.dart';
  12. class OrdineSyncService {
  13. final ApiService _api;
  14. final OrdiniDao _ordiniDao;
  15. final ClientiDao _clientiDao;
  16. final FilialiDao _filialiDao;
  17. final AgentiDao _agentiDao;
  18. OrdineSyncService(
  19. this._api,
  20. this._ordiniDao,
  21. this._clientiDao,
  22. this._filialiDao,
  23. this._agentiDao,
  24. );
  25. Future<int> uploadNewOrders(
  26. int idAgente,
  27. String codAgente, {
  28. void Function(int current, int total)? onProgress,
  29. }) async {
  30. final orders = await _ordiniDao.getNewOrders();
  31. int sent = 0;
  32. final total = orders.length;
  33. for (int i = 0; i < orders.length; i++) {
  34. onProgress?.call(i + 1, total);
  35. try {
  36. final o = orders[i];
  37. final lines = await _ordiniDao.getOrderLines(o.idOrdine);
  38. final dto = SyncOrderDto(
  39. idOrdine: o.idOrdine,
  40. idOrdineAgente: o.idOrdine,
  41. numeroOrdine: o.numeroOrdine,
  42. idCliente: o.idCliente,
  43. dataOrdine: o.dataOrdine,
  44. dataConsegna: o.dataConsegna,
  45. riferimento: o.riferimento,
  46. stato: o.stato,
  47. dataModifica: o.dataModifica,
  48. idAgente: o.idAgente,
  49. noteCliente: o.noteCliente,
  50. noteOrdine: o.noteOrdine,
  51. idPagamento: o.idPagamento,
  52. righeOrdine: lines
  53. .map(
  54. (l) => SyncOrderLineDto(
  55. idRigaOrdine: l.idRigaOrdine,
  56. idArticolo: l.idArticolo,
  57. idListino: l.idListino,
  58. quantita: l.quantita,
  59. prezzoLordo: l.prezzoLordo,
  60. sconto1: l.sconto1,
  61. sconto2: l.sconto2,
  62. sconto3: l.sconto3,
  63. sconto4: l.sconto4,
  64. sconto5: l.sconto5,
  65. scontoMerce: l.scontoMerce,
  66. prezzoNetto: l.prezzoNetto,
  67. totale: l.totale,
  68. dataConsegna: l.dataConsegna,
  69. qtaEvasa: l.qtaEvasa,
  70. stato: l.stato,
  71. colli: l.colli,
  72. promozione: l.promozione,
  73. rigaPromozione: l.rigaPromozione,
  74. ),
  75. )
  76. .toList(),
  77. );
  78. final resp = await _api.post('/rest/ordini/$codAgente', dto.toJson());
  79. if (resp['status'] == 0) {
  80. final idAssegnato = resp['idAssegnato'] as int?;
  81. if (idAssegnato != null) {
  82. await _ordiniDao.markAsSent(o.idOrdine, idAssegnato);
  83. sent++;
  84. }
  85. }
  86. } catch (_) {}
  87. }
  88. return sent;
  89. }
  90. Future<int> downloadRemoteOrders(
  91. int idAgente,
  92. String codAgente,
  93. String lastUpdate, {
  94. void Function(int current, int total)? onProgress,
  95. }) async {
  96. try {
  97. final data = await _api.getList(
  98. '/rest/ordini/updates/$codAgente/$lastUpdate',
  99. );
  100. final db = _ordiniDao.db;
  101. final cacheCliente = <String, int?>{};
  102. final cacheAgente = <String, Agente>{};
  103. final cacheFilialeById = <int, int?>{};
  104. final cacheFilialeByRemoteId = <int, int?>{};
  105. final total = data.length;
  106. int count = 0;
  107. Agente? agente = null;
  108. await db.transaction(() async {
  109. for (final json in data) {
  110. count++;
  111. onProgress?.call(count, total);
  112. final idOrdine = json['idOrdine'] as int?;
  113. final idOrdineAgente = json['idOrdineAgente'] as int?;
  114. final numeroOrdineSede = json['numeroOrdineSede'] as int?;
  115. final stato = json['stato'] as String?;
  116. if (agente == null) {
  117. agente = await _agentiDao.findById(json['idAgente'] as int);
  118. }
  119. Ordine? existing;
  120. if (idOrdineAgente != null) {
  121. existing ??= await _ordiniDao.getById(idOrdineAgente);
  122. }
  123. if (existing == null && idOrdine != null) {
  124. existing ??= await _ordiniDao.findByIdOrdineSede(idOrdine);
  125. }
  126. if (existing == null && numeroOrdineSede != null) {
  127. final numKey = numeroOrdineSede.toString();
  128. existing ??= await _ordiniDao.findByNumeroOrdineSede(numKey);
  129. }
  130. if (stato == 'X') {
  131. if (existing != null) {
  132. final deleteId = existing.idOrdine;
  133. await (db.delete(
  134. db.ordini,
  135. )..where((t) => t.idOrdine.equals(deleteId)))
  136. .go();
  137. }
  138. continue;
  139. }
  140. final codCliente = json['codCliente'] as String?;
  141. int? localIdCliente;
  142. if (codCliente != null) {
  143. localIdCliente = cacheCliente[codCliente];
  144. if (localIdCliente == null) {
  145. final c = await _clientiDao.getByCode(agente!.idAgente, codCliente);
  146. localIdCliente = c?.idCliente;
  147. cacheCliente[codCliente] = localIdCliente;
  148. }
  149. }
  150. // recupera l'agente attivo per il cliente
  151. /*
  152. if (cacheAgente.containsKey(codCliente)) {
  153. agente = cacheAgente[codCliente];
  154. } else {
  155. agente = await _clientiDao.getAgenteOf(codCliente);
  156. if (agente != null) {
  157. cacheAgente[codCliente!] = agente;
  158. }
  159. }
  160. */
  161. final idFilialeRemoto = json['idFilialeRemoto'] as int?;
  162. final idFiliale = json['idFiliale'] as int?;
  163. int? localIdFiliale;
  164. if (idFilialeRemoto != null) {
  165. localIdFiliale = cacheFilialeById[idFilialeRemoto];
  166. if (localIdFiliale == null) {
  167. final f = await _filialiDao.getById(idFilialeRemoto);
  168. localIdFiliale = f?.idFiliale;
  169. cacheFilialeById[idFilialeRemoto] = localIdFiliale;
  170. }
  171. }
  172. if (localIdFiliale == null && idFiliale != null) {
  173. localIdFiliale = cacheFilialeByRemoteId[idFiliale];
  174. if (localIdFiliale == null) {
  175. final f = await _filialiDao.getByRemoteId(idFiliale);
  176. localIdFiliale = f?.idFiliale;
  177. cacheFilialeByRemoteId[idFiliale] = localIdFiliale;
  178. }
  179. }
  180. final ordineCompanion = OrdiniCompanion(
  181. idOrdine: existing != null ? Value(existing.idOrdine) : Value.absent(),
  182. idOrdineSede: Value(idOrdine),
  183. numeroOrdine: Value(json['numeroOrdine'] as int?),
  184. numeroOrdineSede: Value(numeroOrdineSede?.toString()),
  185. dataOrdine: Value(json['dataOrdine'] as String?),
  186. dataConsegna: Value(json['dataConsegna'] as String?),
  187. dataModifica: Value(json['dataModifica'] as String?),
  188. riferimento: Value(json['riferimento'] as String?),
  189. noteCliente: Value(json['noteCliente'] as String?),
  190. noteOrdine: Value(json['noteOrdine'] as String?),
  191. idCliente: Value(localIdCliente),
  192. idFiliale: Value(localIdFiliale),
  193. stato: Value('T'),
  194. idListino: Value(null),
  195. idAgente: Value(agente!.idAgente),
  196. idPagamento: Value(json['idPagamento'] as int?),
  197. );
  198. final insertedId = await db.into(db.ordini).insertOnConflictUpdate(ordineCompanion);
  199. final savedId = existing?.idOrdine ?? insertedId;
  200. await (db.delete(
  201. db.righeOrdine,
  202. )..where((t) => t.idOrdine.equals(savedId)))
  203. .go();
  204. final righe = json['righeOrdine'] as List<dynamic>?;
  205. if (righe != null && righe.isNotEmpty) {
  206. await db.batch((batch) {
  207. for (final r in righe) {
  208. final rigaJson = r as Map<String, dynamic>;
  209. batch.insert(
  210. db.righeOrdine,
  211. RigheOrdineCompanion(
  212. idOrdine: Value(savedId),
  213. idArticolo: Value(rigaJson['idArticolo'] as int?),
  214. idListino: Value(rigaJson['idListino'] as int?),
  215. quantita: Value(_toDouble(rigaJson['quantita'])),
  216. prezzoLordo: Value(_toDouble(rigaJson['prezzoLordo'])),
  217. sconto1: Value(_toDouble(rigaJson['sconto1'])),
  218. sconto2: Value(_toDouble(rigaJson['sconto2'])),
  219. sconto3: Value(_toDouble(rigaJson['sconto3'])),
  220. sconto4: Value(_toDouble(rigaJson['sconto4'])),
  221. sconto5: Value(_toDouble(rigaJson['sconto5'])),
  222. scontoMerce: Value(_toDouble(rigaJson['scontoMerce'])),
  223. prezzoNetto: Value(_toDouble(rigaJson['prezzoNetto'])),
  224. totale: Value(_toDouble(rigaJson['totale'])),
  225. dataConsegna: Value(rigaJson['dataConsegna'] as String?),
  226. dataModifica: Value(rigaJson['dataModifica'] as String?),
  227. qtaEvasa: Value(_toDouble(rigaJson['qtaEvasa'])),
  228. stato: Value(rigaJson['stato'] as String?),
  229. colli: Value(_toDouble(rigaJson['colli'])),
  230. promozione: Value(rigaJson['promozione'] as int?),
  231. rigaPromozione: Value(rigaJson['rigaPromozione'] as int?),
  232. prezzoManuale: Value(rigaJson['prezzoManuale'] as int?),
  233. ),
  234. );
  235. }
  236. });
  237. }
  238. }
  239. });
  240. return count;
  241. } catch (ex) {
  242. print('Error downloading orders: $ex');
  243. return 0;
  244. }
  245. }
  246. double? _toDouble(dynamic value) {
  247. if (value == null) return null;
  248. if (value is double) return value;
  249. if (value is int) return value.toDouble();
  250. return double.tryParse(value.toString());
  251. }
  252. }