import 'package:drift/drift.dart'; import 'package:ristoris/database/daos/agenti_dao.dart'; import 'package:ristoris/database/daos/clienti_agente_dao.dart'; import 'package:ristoris/providers/database_provider.dart'; import 'package:riverpod/src/provider.dart'; import '../api_service.dart'; import '../../database/database.dart'; import '../../database/daos/ordini_dao.dart'; import '../../database/daos/clienti_dao.dart'; import '../../database/daos/filiali_dao.dart'; import '../../dto/sync_order_dto.dart'; class OrdineSyncService { final ApiService _api; final OrdiniDao _ordiniDao; final ClientiDao _clientiDao; final FilialiDao _filialiDao; final AgentiDao _agentiDao; OrdineSyncService( this._api, this._ordiniDao, this._clientiDao, this._filialiDao, this._agentiDao, ); Future uploadNewOrders(int idAgente, String codAgente) async { final orders = await _ordiniDao.getNewOrders(); int sent = 0; for (final o in orders) { try { final lines = await _ordiniDao.getOrderLines(o.idOrdine); final dto = SyncOrderDto( idOrdine: o.idOrdine, idOrdineAgente: o.idOrdine, numeroOrdine: o.numeroOrdine, idCliente: o.idCliente, dataOrdine: o.dataOrdine, dataConsegna: o.dataConsegna, riferimento: o.riferimento, stato: o.stato, dataModifica: o.dataModifica, idAgente: o.idAgente, noteCliente: o.noteCliente, noteOrdine: o.noteOrdine, idPagamento: o.idPagamento, righeOrdine: lines .map( (l) => SyncOrderLineDto( idRigaOrdine: l.idRigaOrdine, idArticolo: l.idArticolo, idListino: l.idListino, quantita: l.quantita, prezzoLordo: l.prezzoLordo, sconto1: l.sconto1, sconto2: l.sconto2, sconto3: l.sconto3, sconto4: l.sconto4, sconto5: l.sconto5, scontoMerce: l.scontoMerce, prezzoNetto: l.prezzoNetto, totale: l.totale, dataConsegna: l.dataConsegna, qtaEvasa: l.qtaEvasa, stato: l.stato, colli: l.colli, promozione: l.promozione, rigaPromozione: l.rigaPromozione, ), ) .toList(), ); final resp = await _api.post('/rest/ordini/$codAgente', dto.toJson()); if (resp['status'] == 0) { final idAssegnato = resp['idAssegnato'] as int?; if (idAssegnato != null) { await _ordiniDao.markAsSent(o.idOrdine, idAssegnato); sent++; } } } catch (_) {} } return sent; } Future downloadRemoteOrders( int idAgente, String codAgente, String lastUpdate, ) async { try { final data = await _api.getList( '/rest/ordini/updates/$codAgente/$lastUpdate', ); final db = _ordiniDao.db; final cacheCliente = {}; final cacheAgente = {}; final cacheFilialeById = {}; final cacheFilialeByRemoteId = {}; int count = 0; Agente? agente = null; await db.transaction(() async { for (final json in data) { final idOrdine = json['idOrdine'] as int?; final idOrdineAgente = json['idOrdineAgente'] as int?; final numeroOrdineSede = json['numeroOrdineSede'] as int?; final stato = json['stato'] as String?; if (agente == null) { agente = await _agentiDao.findById(json['idAgente'] as int); } Ordine? existing; if (idOrdineAgente != null) { existing ??= await _ordiniDao.getById(idOrdineAgente); } if (existing == null && idOrdine != null) { existing ??= await _ordiniDao.findByIdOrdineSede(idOrdine); } if (existing == null && numeroOrdineSede != null) { final numKey = numeroOrdineSede.toString(); existing ??= await _ordiniDao.findByNumeroOrdineSede(numKey); } if (stato == 'X') { if (existing != null) { final deleteId = existing.idOrdine; await (db.delete( db.ordini, )..where((t) => t.idOrdine.equals(deleteId))) .go(); } continue; } final codCliente = json['codCliente'] as String?; int? localIdCliente; if (codCliente != null) { localIdCliente = cacheCliente[codCliente]; if (localIdCliente == null) { final c = await _clientiDao.getByCode(agente!.idAgente, codCliente); localIdCliente = c?.idCliente; cacheCliente[codCliente] = localIdCliente; } } // recupera l'agente attivo per il cliente /* if (cacheAgente.containsKey(codCliente)) { agente = cacheAgente[codCliente]; } else { agente = await _clientiDao.getAgenteOf(codCliente); if (agente != null) { cacheAgente[codCliente!] = agente; } } */ final idFilialeRemoto = json['idFilialeRemoto'] as int?; final idFiliale = json['idFiliale'] as int?; int? localIdFiliale; if (idFilialeRemoto != null) { localIdFiliale = cacheFilialeById[idFilialeRemoto]; if (localIdFiliale == null) { final f = await _filialiDao.getById(idFilialeRemoto); localIdFiliale = f?.idFiliale; cacheFilialeById[idFilialeRemoto] = localIdFiliale; } } if (localIdFiliale == null && idFiliale != null) { localIdFiliale = cacheFilialeByRemoteId[idFiliale]; if (localIdFiliale == null) { final f = await _filialiDao.getByRemoteId(idFiliale); localIdFiliale = f?.idFiliale; cacheFilialeByRemoteId[idFiliale] = localIdFiliale; } } final ordineCompanion = OrdiniCompanion( idOrdine: existing != null ? Value(existing.idOrdine) : Value.absent(), idOrdineSede: Value(idOrdine), numeroOrdine: Value(json['numeroOrdine'] as int?), numeroOrdineSede: Value(numeroOrdineSede?.toString()), dataOrdine: Value(json['dataOrdine'] as String?), dataConsegna: Value(json['dataConsegna'] as String?), dataModifica: Value(json['dataModifica'] as String?), riferimento: Value(json['riferimento'] as String?), noteCliente: Value(json['noteCliente'] as String?), noteOrdine: Value(json['noteOrdine'] as String?), idCliente: Value(localIdCliente), idFiliale: Value(localIdFiliale), stato: Value('T'), idListino: Value(null), idAgente: Value(agente!.idAgente), idPagamento: Value(json['idPagamento'] as int?), ); final insertedId = await db.into(db.ordini).insertOnConflictUpdate(ordineCompanion); final savedId = existing?.idOrdine ?? insertedId; await (db.delete( db.righeOrdine, )..where((t) => t.idOrdine.equals(savedId))) .go(); final righe = json['righeOrdine'] as List?; if (righe != null && righe.isNotEmpty) { await db.batch((batch) { for (final r in righe) { final rigaJson = r as Map; batch.insert( db.righeOrdine, RigheOrdineCompanion( idOrdine: Value(savedId), idArticolo: Value(rigaJson['idArticolo'] as int?), idListino: Value(rigaJson['idListino'] as int?), quantita: Value(_toDouble(rigaJson['quantita'])), prezzoLordo: Value(_toDouble(rigaJson['prezzoLordo'])), sconto1: Value(_toDouble(rigaJson['sconto1'])), sconto2: Value(_toDouble(rigaJson['sconto2'])), sconto3: Value(_toDouble(rigaJson['sconto3'])), sconto4: Value(_toDouble(rigaJson['sconto4'])), sconto5: Value(_toDouble(rigaJson['sconto5'])), scontoMerce: Value(_toDouble(rigaJson['scontoMerce'])), prezzoNetto: Value(_toDouble(rigaJson['prezzoNetto'])), totale: Value(_toDouble(rigaJson['totale'])), dataConsegna: Value(rigaJson['dataConsegna'] as String?), dataModifica: Value(rigaJson['dataModifica'] as String?), qtaEvasa: Value(_toDouble(rigaJson['qtaEvasa'])), stato: Value(rigaJson['stato'] as String?), colli: Value(_toDouble(rigaJson['colli'])), promozione: Value(rigaJson['promozione'] as int?), rigaPromozione: Value(rigaJson['rigaPromozione'] as int?), prezzoManuale: Value(rigaJson['prezzoManuale'] as int?), ), ); } }); } count++; } }); return count; } catch (ex) { print('Error downloading orders: $ex'); return 0; } } double? _toDouble(dynamic value) { if (value == null) return null; if (value is double) return value; if (value is int) return value.toDouble(); return double.tryParse(value.toString()); } }