import 'package:drift/drift.dart'; import '../api_service.dart'; import '../../database/daos/articoli_dao.dart'; import '../../database/daos/clienti_dao.dart'; import '../../database/daos/listini_dao.dart'; import '../../database/daos/tabelle_dao.dart'; import '../../database/daos/pagamenti_dao.dart'; import '../../database/daos/sconti_dao.dart'; import '../../database/daos/promozioni_dao.dart'; import '../../database/daos/scadenze_dao.dart'; import '../../database/daos/statistiche_dao.dart'; import '../../database/daos/parametri_dao.dart'; import '../../database/database.dart'; import '../../dto/sync_promo_dto.dart'; class ReferenceSyncService { final ApiService _api; final TabelleDao _tabelleDao; final PagamentiDao _pagamentiDao; final ScontiDao _scontiDao; final ArticoliDao _articoliDao; final ListiniDao _listiniDao; final PromozioniDao _promozioniDao; final ScadenzeDao _scadenzeDao; final StatisticheDao _statisticheDao; final ParametriDao _parametriDao; final ClientiDao _clientiDao; ReferenceSyncService( this._api, this._tabelleDao, this._pagamentiDao, this._scontiDao, this._articoliDao, this._listiniDao, this._promozioniDao, this._scadenzeDao, this._statisticheDao, this._parametriDao, this._clientiDao, ); Future downloadTabelle(String lastUpdate) async { try { final data = await _api.getList('/rest/tabelle/updates/$lastUpdate'); final db = _tabelleDao.db; await db.batch((batch) { for (final json in data) { batch.insert( db.tabelle, Tabella( idTabella: json['idTabella'] as int? ?? 0, tipoTabella: json['tipoTabella'] as String? ?? '', codTabella: json['codTabella'] as String?, descrizione: json['descrizione'] as String?, stringa1: json['stringa1'] as String?, stringa2: json['stringa2'] as String?, stringa3: json['stringa3'] as String?, stringa4: json['stringa4'] as String?, stringa5: json['stringa5'] as String?, valore1: _toDouble(json['valore1']), valore2: _toDouble(json['valore2']), valore3: _toDouble(json['valore3']), valore4: _toDouble(json['valore4']), valore5: _toDouble(json['valore5']), dataModifica: json['dataModifica'] as String?, ), mode: InsertMode.insertOrReplace, ); } }); return data.length; } catch (_) { return 0; } } Future downloadPagamenti(String lastUpdate) async { try { final data = await _api.getList('/rest/pagamenti/updates/$lastUpdate'); final db = _pagamentiDao.db; await db.batch((batch) { for (final json in data) { batch.insert( db.pagamenti, Pagamento( idPagamento: json['idPagamento'] as int? ?? 0, codPagamento: json['codPagamento'] as String?, descrizione: json['descrizione'] as String?, dataModifica: json['dataModifica'] as String?, attivo: json['attivo'] as int?, ), mode: InsertMode.insertOrReplace, ); } }); return data.length; } catch (_) { return 0; } } Future downloadSconti(String lastUpdate) async { try { final data = await _api.getList('/rest/sconti/updates/$lastUpdate'); final db = _scontiDao.db; await db.batch((batch) { for (final json in data) { batch.insert( db.sconti, Sconto( idSconto: json['idSconto'] as int? ?? 0, codSconto: json['codSconto'] as String?, descrizione: json['descrizione'] as String?, sconto1: _toDouble(json['sconto1']), sconto2: _toDouble(json['sconto2']), sconto3: _toDouble(json['sconto3']), sconto4: _toDouble(json['sconto4']), sconto5: _toDouble(json['sconto5']), ), mode: InsertMode.insertOrReplace, ); } }); return data.length; } catch (_) { return 0; } } Future downloadArticoli(String lastUpdate) async { try { final data = await _api.getList('/rest/articoli/updates/$lastUpdate'); final db = _articoliDao.db; await db.batch((batch) { for (final json in data) { batch.insert( db.articoli, Articolo( idArticolo: json['idArticolo'] as int? ?? 0, posizione: json['posizione'] as int?, codArticolo: json['codArticolo'] as String? ?? '', descrizione: json['descrizione'] as String?, ean: json['ean'] as String?, idIva: (json['iva'] as Map?)?['idTabella'] as int?, idClassifica1: (json['classifica1'] as Map?)?['idTabella'] as int?, idClassifica2: (json['classifica2'] as Map?)?['idTabella'] as int?, idClassifica3: (json['classifica3'] as Map?)?['idTabella'] as int?, idClassifica4: (json['classifica4'] as Map?)?['idTabella'] as int?, peso: _toDouble(json['peso']), giacenza: _toDouble(json['giacenza']), unitaMisura: json['unitaMisura'] as String?, attivo: json['attivo'] as int? ?? 1, pezziConfezione: _toDouble(json['pezziConfezione']), fileFoto: json['fileFoto'] as String?, schedaProdotto: json['schedaProdotto'] as String?, prezzoBase: json['prezzoBase']?.toString(), stato: json['stato'] as String?, dataModifica: json['dataModifica'] as String?, gruppo: json['gruppo'] as String?, categoria: json['categoria'] as String?, colliPerStrato: json['colliPerStrato']?.toString(), stratiPerPallet: json['stratiPerPallet']?.toString(), ), mode: InsertMode.insertOrReplace, ); } }); return data.length; } catch (_) { return 0; } } Future downloadListini(String lastUpdate) async { try { final data = await _api.getList('/rest/listini/updates/$lastUpdate'); final db = _listiniDao.db; await db.batch((batch) { for (final json in data) { batch.insert( db.listini, Listino( idListino: json['idListino'] as int? ?? 0, codListino: json['codListino'] as String?, descrizione: json['descrizione'] as String?, validoDa: json['validoDa'] as String?, validoA: json['validoA'] as String?, attivo: json['attivo'] as int? ?? 1, dataModifica: json['dataModifica'] as String?, ), mode: InsertMode.insertOrReplace, ); } }); return data.length; } catch (_) { return 0; } } Future downloadListiniArticolo(String lastUpdate) async { try { final data = await _api.getList( '/rest/listinoArticoli/updates/$lastUpdate', ); final db = _listiniDao.db; await db.batch((batch) { for (final json in data) { final articolo = json['articolo'] as Map?; final listino = json['listino'] as Map?; final sconto = json['sconto'] as Map?; batch.insert( db.listiniArticolo, ListinoArticolo( idListinoArticoli: json['idListinoArticoli'] as int? ?? 0, idListino: listino?['idListino'] as int? ?? json['idListino'] as int?, idArticolo: articolo?['idArticolo'] as int? ?? json['idArticolo'] as int?, prezzo: _toDouble(json['prezzo']), idSconto: sconto?['idSconto'] as int? ?? json['idSconto'] as int?, validoDa: json['validoDa'] as String?, validoA: json['validoA'] as String?, attivo: json['attivo'] as int? ?? 1, ), mode: InsertMode.insertOrReplace, ); } }); return data.length; } catch (_) { return 0; } } Future downloadListiniCliente( int idAgente, String codAgente, String lastUpdate, ) async { try { final data = await _api.getList( '/rest/listinoCliente/updates/$codAgente/$lastUpdate', ); final db = _listiniDao.db; final cacheCliente = {}; final items = []; for (final json in data) { final articolo = json['articolo'] as Map?; final listino = json['listino'] as Map?; final sconto = json['sconto'] as Map?; final jsonIdCliente = json['idCliente'] as int?; int? localIdCliente; if (jsonIdCliente != null) { localIdCliente = cacheCliente[jsonIdCliente]; if (localIdCliente == null) { final c = await _clientiDao.getByRemoteId(idAgente, jsonIdCliente); localIdCliente = c?.idCliente; cacheCliente[jsonIdCliente] = localIdCliente; } } items.add( ListinoCliente( idListinoCliente: json['idListinoCliente'] as int? ?? 0, idListino: listino?['idListino'] as int?, idCliente: localIdCliente, idArticolo: articolo?['idArticolo'] as int? ?? json['idArticolo'] as int?, idSconto: sconto?['idSconto'] as int?, validoDa: json['validoDa'] as String?, validoA: json['validoA'] as String?, prezzo: _toDouble(json['prezzo']), attivo: json['attivo'] as int? ?? 1, annullato: json['annullato'] as String? ?? 'N', listinoSostitutivo: json['listinoSostitutivo'] as String?, stato: json['stato'] as String?, ), ); } await db.batch((batch) { for (final item in items) { batch.insert(db.listiniCliente, item, mode: InsertMode.insertOrReplace); } }); return data.length; } catch (_) { return 0; } } Future downloadScontiCliente( int idAgente, String codAgente, String lastUpdate, ) async { try { final data = await _api.getList( '/rest/scontocliente/updates/$codAgente/$lastUpdate', ); final db = _scontiDao.db; await db.batch((batch) { for (final json in data) { batch.insert( db.scontiCliente, ScontoCliente( idScontoCliente: json['idScontoCliente'] as int? ?? 0, idCliente: json['idCliente'] as int?, idArticolo: json['idArticolo'] as int?, linea: json['linea'] as String?, idSconto: json['idSconto'] as int?, validoDa: json['validoDa'] as String?, validoA: json['validoA'] as String?, stato: json['stato'] as String?, dataModifica: json['dataModifica'] as String?, ), mode: InsertMode.insertOrReplace, ); } }); return data.length; } catch (_) { return 0; } } Future downloadPromozioni(String lastUpdate) async { try { final data = await _api.getList('/rest/promozioni/updates/$lastUpdate'); final db = _promozioniDao.db; int count = 0; await db.transaction(() async { await db.delete(db.promoOmaggi).go(); await db.delete(db.promoListini).go(); await db.delete(db.promoArticoli).go(); await db.delete(db.promozioni).go(); for (final json in data) { final dto = SyncPromoDto.fromJson(json as Map); await db.into(db.promozioni).insert( Promozione( progressivo: dto.progressivo ?? 0, tipoPromozione: dto.tipoPromozione, descrizione: dto.descrizione, dataInizio: dto.dataInizio, dataFine: dto.dataFine, limiteQta: dto.limiteQta, quantitaOmaggio: dto.quantitaOmaggio, limiteImporto: dto.limiteImporto, stato: dto.stato, priorita: dto.priorita ?? 0, codice: dto.codice, idArticoloOmaggio: dto.articoloOmaggio?.idArticolo, idSconto: dto.sconto?.idSconto, idListino: dto.listinoOmaggio?.idListino, ), ); for (final art in dto.promozioneArticoli) { await db.into(db.promoArticoli).insert( PromoArticolo( progressivo: dto.progressivo ?? 0, riga: art.promozioneArticoloKey?.riga ?? 0, quantitaOmaggio: art.promozioneArticoloKey?.riga?.toDouble(), idArticolo: art.articolo?.idArticolo, ), ); } for (final l in dto.promozioneListini) { await db.into(db.promoListini).insert( PromoListino( progressivo: dto.progressivo ?? 0, idListino: l.promozioneListinoKey?.idListino ?? 0, ), ); } for (final om in dto.promozioneOmaggio) { await db.into(db.promoOmaggi).insert( PromoOmaggio( progressivo: dto.progressivo ?? 0, riga: om.promozioneOmaggioKey?.riga ?? 0, idArticolo: om.articolo?.idArticolo, quantita: om.quantita, ), ); } count++; } }); return count; } catch (_) { return 0; } } Future downloadScadenze( int idAgente, String codAgente, String lastUpdate, ) async { try { final data = await _api.getList( '/rest/scadenze/updates/$codAgente/$lastUpdate', ); final db = _scadenzeDao.db; await db.transaction(() async { await db.delete(db.scadenze).go(); await db.batch((batch) { for (final json in data) { batch.insert( db.scadenze, Scadenza( idScadenza: json['idScadenza'] as int? ?? 0, idCliente: json['idCliente'] as int?, idAgente: json['idAgente'] as int?, chiave: json['chiave'] as String?, numPartita: json['numPartita'] as String?, dataScadenza: json['dataScadenza'] as String?, segno: json['segno'] as String?, importoFattura: _toDouble(json['importoFattura']), valuta: json['valuta'] as String?, numDoc: json['numDoc'] as String?, serieDoc: json['serieDoc'] as String?, dataDoc: json['dataDoc'] as String?, importoScadenza: _toDouble(json['importoScadenza']), saldo: _toDouble(json['saldo']), tipoPagamento: json['tipoPagamento'] as String?, flgSoppressa: json['flgSoppressa'] as int?, importoAbbuono: _toDouble(json['importoAbbuono']), note: json['note'] as String?, dataModifica: json['dataModifica'] as String?, stato: json['stato'] as String?, ), ); } }); }); return data.length; } catch (ex) { print('Error downloading scadenze: $ex'); return 0; } } Future downloadStatistiche( int idAgente, String codAgente, String lastUpdate, ) async { try { final data = await _api.getList( '/rest/statistiche/updates/$codAgente/$lastUpdate', ); final db = _statisticheDao.db; await db.transaction(() async { await db.delete(db.statisticheVendita).go(); await db.batch((batch) { for (final json in data) { batch.insert( db.statisticheVendita, StatisticheVenditaData( id: json['id'] as int? ?? 0, idAgente: json['idAgente'] as int?, idCliente: json['idCliente'] as int?, idArticolo: json['idArticolo'] as int?, codStatistiche: json['codStatistiche'] as String?, riga: json['riga'] as int?, numeroFattura: json['numeroFattura'] as String?, dataFattura: json['dataFattura'] as String?, qta: _toDouble(json['qta']), importo: _toDouble(json['importo']), tipoVendita: json['tipoVendita'] as String?, ), ); } }); }); return data.length; } catch (_) { return 0; } } Future downloadParametro(String nome) async { try { final resp = await _api.get('/rest/parametro/$nome'); if (resp['status'] == 0 && resp['valore'] != null) { await _parametriDao.set(nome, resp['valore'].toString()); } } catch (_) {} } 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()); } }