import 'package:drift/drift.dart'; import '../api_service.dart'; import '../../database/daos/clienti_dao.dart'; import '../../database/daos/clienti_agente_dao.dart'; import '../../database/database.dart'; import '../../dto/sync_customer_dto.dart'; class ClienteSyncService { final ApiService _api; final ClientiDao _clientiDao; final ClientiAgenteDao _clientiAgenteDao; ClienteSyncService(this._api, this._clientiDao, this._clientiAgenteDao); Future uploadNewCustomers( int idAgente, String codAgente, { void Function(int current, int total)? onProgress, }) async { final newClients = await _clientiDao.getNewCustomers(idAgente); int sent = 0; final total = newClients.length; for (int i = 0; i < newClients.length; i++) { onProgress?.call(i + 1, total); try { final c = newClients[i]; final dto = _toDto(c); final resp = await _api.post('/rest/clienti/$codAgente', dto.toJson()); if (resp['status'] == 0) { final idAssegnato = resp['idAssegnato'] as int?; if (idAssegnato != null) { await _clientiDao.markAsSent(c.idCliente, idAssegnato); sent++; } } } catch (_) {} } return sent; } Future downloadCustomers( int idAgente, String codAgente, String lastUpdate, { void Function(int current, int total)? onProgress, }) async { try { final data = await _api.getList( '/rest/clienti/updates/$codAgente/$lastUpdate', ); final db = _clientiDao.db; final cacheRemoteId = {}; final cacheCode = {}; final cacheAssoc = {}; final total = data.length; int count = 0; await db.transaction(() async { for (final json in data) { count++; onProgress?.call(count, total); final dto = SyncCustomerDto.fromJson(json as Map); Cliente? existing; if (dto.idCliente != null) { existing = cacheRemoteId.putIfAbsent(dto.idCliente!, () => null); if (existing == null) { existing = await _clientiDao.getByRemoteId( idAgente, dto.idCliente!, ); cacheRemoteId[dto.idCliente!] = existing; } } if (existing == null && dto.codCliente != null) { existing = cacheCode.putIfAbsent(dto.codCliente!, () => null); if (existing == null) { existing = await _clientiDao.getByCode(idAgente, dto.codCliente!); cacheCode[dto.codCliente!] = existing; } } int? savedId = existing?.idCliente; if (existing != null) { await db .update(db.clienti) .replace( Cliente( idCliente: existing.idCliente, idClienteRemoto: dto.idCliente, codCliente: dto.codCliente, ragioneSociale: dto.ragioneSociale, indirizzo: dto.indirizzo, citta: dto.citta, provincia: dto.provincia, cap: dto.cap, frazione: dto.frazione, nazione: dto.nazione, telefono: dto.telefono, cellulare: dto.cellulare, partitaIva: dto.partitaIva, codiceFiscale: dto.codiceFiscale, note: dto.note, noteOrdine: dto.noteOrdine, stato: 'T', attivo: dto.attivo ?? 1, idPagamento: dto.idPagamento, idListino: dto.idListino, dataModifica: dto.dataModifica, sdi: dto.sdi, pec: dto.pec, altreNote: dto.altreNote, numeroCivico: dto.numeroCivico, pod: dto.pod, pdr: dto.pdr, ubicazione: dto.ubicazione, banca: dto.banca, bancaFiliale: dto.bancaFiliale, codBlocco: dto.codBlocco, creditScoreColor: dto.creditScoreColor, dataCreditScore: dto.dataCreditScore, ), ); } else { savedId = await db .into(db.clienti) .insert( ClientiCompanion( idClienteRemoto: Value(dto.idCliente), codCliente: Value(dto.codCliente), ragioneSociale: Value(dto.ragioneSociale), indirizzo: Value(dto.indirizzo), citta: Value(dto.citta), provincia: Value(dto.provincia), cap: Value(dto.cap), frazione: Value(dto.frazione), nazione: Value(dto.nazione), telefono: Value(dto.telefono), cellulare: Value(dto.cellulare), fax: Value(dto.fax), email: Value(dto.email), partitaIva: Value(dto.partitaIva), codiceFiscale: Value(dto.codiceFiscale), note: Value(dto.note), noteOrdine: Value(dto.noteOrdine), stato: const Value('T'), attivo: Value(dto.attivo ?? 1), idPagamento: Value(dto.idPagamento), idListino: Value(dto.idListino), dataModifica: Value(dto.dataModifica), sdi: Value(dto.sdi), pec: Value(dto.pec), altreNote: Value(dto.altreNote), numeroCivico: Value(dto.numeroCivico), pod: Value(dto.pod), pdr: Value(dto.pdr), ubicazione: Value(dto.ubicazione), banca: Value(dto.banca), bancaFiliale: Value(dto.bancaFiliale), codBlocco: Value(dto.codBlocco), creditScoreColor: Value(dto.creditScoreColor), dataCreditScore: Value(dto.dataCreditScore), ), ); } final assocKey = '$savedId-$idAgente'; if (!cacheAssoc.containsKey(assocKey)) { final assoc = await _clientiAgenteDao.findByClienteAgente( savedId!, idAgente, ); if (assoc == null) { await db .into(db.clientiAgente) .insert( ClientiAgenteCompanion( idCliente: Value(savedId), idAgente: Value(idAgente), attivo: const Value(1), ), ); } cacheAssoc[assocKey] = true; } } }); return count; } catch (ex) { print('Error occurred while downloading customers: $ex'); return 0; } } SyncCustomerDto _toDto(Cliente c) { return SyncCustomerDto( idCliente: c.idCliente, codCliente: c.codCliente, ragioneSociale: c.ragioneSociale, indirizzo: c.indirizzo, citta: c.citta, provincia: c.provincia, cap: c.cap, frazione: c.frazione, nazione: c.nazione, telefono: c.telefono, cellulare: c.cellulare, fax: c.fax, email: c.email, partitaIva: c.partitaIva, codiceFiscale: c.codiceFiscale, note: c.note, noteOrdine: c.noteOrdine, stato: c.stato, attivo: c.attivo, idPagamento: c.idPagamento, idListino: c.idListino, dataModifica: c.dataModifica, sdi: c.sdi, pec: c.pec, altreNote: c.altreNote, numeroCivico: c.numeroCivico, pod: c.pod, pdr: c.pdr, ubicazione: c.ubicazione, banca: c.banca, bancaFiliale: c.bancaFiliale, codBlocco: c.codBlocco, creditScoreColor: c.creditScoreColor, dataCreditScore: c.dataCreditScore, ); } }