import 'package:drift/drift.dart'; import '../database.dart'; class ClientiDao { final AppDatabase db; ClientiDao(this.db); Future getById(int id) { return (db.select(db.clienti)..where((t) => t.idCliente.equals(id))).getSingleOrNull(); } Future getByCode(int idAgente, String code) { return (db.select(db.clienti).join([ innerJoin(db.clientiAgente, db.clientiAgente.idCliente.equalsExp(db.clienti.idCliente) & db.clientiAgente.idAgente.equals(idAgente)), ]) ..where(db.clienti.codCliente.equals(code))) .map((row) => row.readTable(db.clienti)) .getSingleOrNull(); } Future getByRemoteId(int idAgente, int remoteId) { return (db.select(db.clienti)..where((t) => t.idClienteRemoto.equals(remoteId))).getSingleOrNull(); } Future> getClienti(int idAgente, String filter) async { final words = filter.split(' ').where((w) => w.isNotEmpty).toList(); final q = db.select(db.clienti).join([ innerJoin(db.clientiAgente, db.clientiAgente.idCliente.equalsExp(db.clienti.idCliente) & db.clientiAgente.idAgente.equals(idAgente)), ]) ..limit(200); if (words.isNotEmpty) { for (final word in words) { final pattern = '%$word%'; q.where(db.clienti.codCliente.like(pattern) | db.clienti.ragioneSociale.like(pattern) | db.clienti.partitaIva.like(pattern)); } } return q.map((row) => row.readTable(db.clienti)).get(); } Future> getActiveClients(int idAgente) { return (db.select(db.clienti).join([ innerJoin( db.clientiAgente, db.clientiAgente.idCliente.equalsExp(db.clienti.idCliente) & db.clientiAgente.idAgente.equals(idAgente), ), ]) ..where(db.clienti.attivo.equals(1)) ..orderBy([OrderingTerm(expression: db.clienti.ragioneSociale)])) .map((row) => row.readTable(db.clienti)) .get(); } Future> topCustomers(int limit) async { return (db.select(db.topCustomer)..limit(limit)).get(); } Future> getNewCustomers(int idAgente) { return (db.select(db.clienti).join([ innerJoin(db.clientiAgente, db.clientiAgente.idCliente.equalsExp(db.clienti.idCliente) & db.clientiAgente.idAgente.equals(idAgente)), ]) ..where(db.clienti.stato.equals('N'))) .map((row) => row.readTable(db.clienti)) .get(); } Future countNewCustomers() async { final rows = await (db.select(db.clienti)..where((t) => t.stato.equals('N'))).get(); return rows.length; } Future> inactiveCustomers(int idAgente, String sinceDate) async { final recentIds = await (db.select(db.ordini)..where((t) => t.idCliente.isNotNull())).get().then((orders) => orders.map((o) => o.idCliente!).toSet()); return (db.select(db.clienti).join([ innerJoin(db.clientiAgente, db.clientiAgente.idCliente.equalsExp(db.clienti.idCliente) & db.clientiAgente.idAgente.equals(idAgente)), ]) ..where(db.clienti.idCliente.isNotIn(recentIds))) .map((row) => row.readTable(db.clienti)) .get(); } Future countCustomersToSend() async { final rows = await (db.select(db.clienti)..where((t) => t.stato.equals('N'))).get(); return rows.length; } Future countCustomersToSendForAgent(int idAgente) async { final rows = await (db.select(db.clienti).join([ innerJoin(db.clientiAgente, db.clientiAgente.idCliente.equalsExp(db.clienti.idCliente) & db.clientiAgente.idAgente.equals(idAgente)), ]) ..where(db.clienti.stato.equals('N'))) .map((row) => row.readTable(db.clienti)) .get(); return rows.length; } Future markAsSent(int idCliente, int idAssegnato) { return (db.update(db.clienti)..where((t) => t.idCliente.equals(idCliente))).write(ClientiCompanion(stato: const Value('T'))); } Future> getFavoriteItems( int idCliente, String dateToUse, String filter, ) async { var filtro = '%$filter'; if (filtro.length > 13) filtro = filtro.substring(0, 13); filtro += '%'; final sql = ''' SELECT DISTINCT a.idArticolo, a.codArticolo, a.descrizione, 0 "prezzoBase", a.attivo, a."nonDisponibile", CASE WHEN EXISTS ( SELECT pa.idArticolo FROM "PromoArticoli" pa JOIN "Promozioni" p ON pa.progressivo = p.progressivo WHERE pa.idArticolo = a.idArticolo AND date('now') BETWEEN p."dataInizio" AND p."dataFine" ) THEN 1 ELSE 0 END AS inPromo, (SELECT ROUND(sv.importo / sv.qta, 2) FROM "Statistiche_vendita" sv WHERE sv.idCliente = ? AND sv.idArticolo = a.idArticolo ORDER BY sv."dataFattura" DESC LIMIT 1 OFFSET 1) AS ultimoPrezzo, (SELECT sv."dataFattura" FROM "Statistiche_vendita" sv WHERE sv.idCliente = ? AND sv.idArticolo = a.idArticolo ORDER BY sv."dataFattura" DESC LIMIT 1 OFFSET 1) AS lastDateSold FROM "Listini_cliente" lc JOIN "Articoli" a ON lc."idArticolo" = a.idArticolo WHERE lc.idCliente = ? AND (lc."validoDa" IS NULL OR lc."validoDa" <= ?) AND (lc."validoA" IS NULL OR lc."validoA" >= ?) AND a.attivo = 1 AND lc.stato <> 'X' AND lc.prezzo > 0.001 AND (a.descrizione LIKE ? OR a."codArticolo" LIKE ?) ORDER BY a.descrizione '''; final rows = await db.customSelect( sql, variables: [ Variable.withInt(idCliente), Variable.withInt(idCliente), Variable.withInt(idCliente), Variable.withString(dateToUse), Variable.withString(dateToUse), Variable.withString(filtro), Variable.withString(filtro), ], ).get(); return rows.map((row) => ArticoliConPromoData.fromJson(row.data)).toList(); } Future> getAlreadySoldItems( int idAgente, int idCliente, String dateToUse, String filter, ) async { final words = filter.split(' ').where((w) => w.isNotEmpty).toList(); final buffer = StringBuffer(''' SELECT DISTINCT a.idArticolo, a.codArticolo, a.descrizione, 0 "prezzoBase", a.attivo, a."nonDisponibile", 0 AS inPromo, ROUND(sv.importo / sv.qta, 2) AS ultimoPrezzo, sv."dataFattura" AS lastDateSold FROM "Articoli" a JOIN "Statistiche_vendita" sv ON sv.idArticolo = a.idArticolo WHERE a.attivo = 1 and sv.idCliente = ? AND sv.idArticolo = a.idArticolo AND sv."dataFattura" >= ? AND sv."tipoVendita" = 'N' '''); final variables = [ Variable.withInt(idCliente), Variable.withString(dateToUse), ]; if (words.isNotEmpty) { for (final word in words) { buffer.write(' AND (a."codArticolo" LIKE ? OR a.descrizione LIKE ?)'); final pattern = '%$word%'; variables.addAll([ Variable.withString(pattern), Variable.withString(pattern), ]); } } buffer.write(' ORDER BY a.descrizione'); final rows = await db .customSelect( buffer.toString(), variables: variables, ) .get(); return rows.map((row) => ArticoliConPromoData.fromJson(row.data)).toList(); } Future getAgenteOf(String? codCliente) async { if (codCliente == null) return null; return (db.select(db.agenti).join([ innerJoin( db.clientiAgente, db.clientiAgente.idAgente.equalsExp(db.agenti.idAgente) & db.clientiAgente.attivo.equals(1), ), innerJoin( db.clienti, db.clienti.idCliente.equalsExp(db.clientiAgente.idCliente) & db.clienti.codCliente.equals(codCliente), ), ]) ..limit(1)) .map((row) => row.readTable(db.agenti)) .getSingleOrNull(); } }