| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- import '../database/daos/ordini_dao.dart';
- import '../database/daos/promozioni_dao.dart';
- import '../database/daos/articoli_dao.dart';
- import '../database/daos/sconti_dao.dart';
- import '../database/database.dart';
- class ApplicaPromoResult {
- final int tipoRisultato;
- final List<RigaOrdine> righe;
- final List<ArticoloOmaggio> omaggi;
- static const int resultNone = 0;
- static const int resultRighe = 1;
- static const int resultOmaggi = 2;
- ApplicaPromoResult({
- this.tipoRisultato = resultNone,
- this.righe = const [],
- this.omaggi = const [],
- });
- }
- class ArticoloOmaggio {
- final int idArticolo;
- final String descrizione;
- final double quantita;
- final double quantitaDisponibile;
- final int progressivo;
- ArticoloOmaggio({
- required this.idArticolo,
- required this.descrizione,
- required this.quantita,
- required this.quantitaDisponibile,
- required this.progressivo,
- });
- }
- class PromoHandler {
- final OrdiniDao _ordiniDao;
- final PromozioniDao _promozioniDao;
- final ArticoliDao _articoliDao;
- final ScontiDao _scontiDao;
- PromoHandler(this._ordiniDao, this._promozioniDao, this._articoliDao, this._scontiDao);
- Future<List<Promozione>> getApplicablePromos(int idOrdine) async {
- final oggi = DateTime.now().toIso8601String();
- return _promozioniDao.getActivePromos(oggi);
- }
- Future<ApplicaPromoResult> applicaPromo(int progressivo, int idOrdine) async {
- final promos = await _promozioniDao.getActivePromos('');
- final promo = promos.where((p) => p.progressivo == progressivo).firstOrNull;
- if (promo == null) return ApplicaPromoResult();
- final lines = await _ordiniDao.getOrderLines(idOrdine);
- final eligibleLines = lines.where((l) =>
- (l.promozione == null || l.promozione == 0) &&
- (l.rigaPromozione == null || l.rigaPromozione == 0) &&
- (l.scontoMerce == null || l.scontoMerce == 0)
- ).toList();
- switch (promo.tipoPromozione) {
- case 2: return _applicaTipo2(promo, eligibleLines, idOrdine);
- case 3: return _applicaTipo3(promo, eligibleLines, idOrdine);
- case 4: return _applicaTipo4(promo, eligibleLines, idOrdine);
- case 5: return _applicaTipo5(promo, eligibleLines, idOrdine);
- case 6: return _applicaTipo6(promo, eligibleLines, idOrdine);
- case 9: return _applicaTipo9(promo, eligibleLines, idOrdine);
- default: return ApplicaPromoResult();
- }
- }
- Future<ApplicaPromoResult> _applicaTipo2(Promozione promo, List<RigaOrdine> lines, int idOrdine) async {
- final promoArts = await _promozioniDao.getPromoArticoli(promo.progressivo);
- final newLines = <RigaOrdine>[];
- for (final line in lines) {
- if (line.colli == null || line.colli! < (promo.limiteQta ?? 0)) continue;
- final isMatch = promoArts.any((a) => a.idArticolo == line.idArticolo);
- if (!isMatch) continue;
- final giftQty = promo.quantitaOmaggio ?? 1;
- newLines.add(RigaOrdine(
- idRigaOrdine: 0,
- idOrdine: idOrdine,
- idArticolo: promo.idArticoloOmaggio ?? line.idArticolo,
- quantita: giftQty,
- prezzoLordo: 0,
- prezzoNetto: 0,
- totale: 0,
- promozione: promo.progressivo,
- rigaPromozione: 1,
- colli: 0,
- ));
- }
- return ApplicaPromoResult(
- tipoRisultato: newLines.isEmpty ? ApplicaPromoResult.resultNone : ApplicaPromoResult.resultRighe,
- righe: newLines,
- );
- }
- Future<ApplicaPromoResult> _applicaTipo3(Promozione promo, List<RigaOrdine> lines, int idOrdine) async {
- final promoListini = await _promozioniDao.getPromoListini(promo.progressivo);
- final promoArts = await _promozioniDao.getPromoArticoli(promo.progressivo);
- final newLines = <RigaOrdine>[];
- for (final line in lines) {
- if (line.colli == null || line.colli! < (promo.limiteQta ?? 0)) continue;
- final listinoMatch = promoListini.any((l) => l.idListino == line.idListino);
- if (!listinoMatch) continue;
- if (promoArts.isNotEmpty && !promoArts.any((a) => a.idArticolo == line.idArticolo)) continue;
- final giftQty = promo.quantitaOmaggio ?? 1;
- newLines.add(RigaOrdine(
- idRigaOrdine: 0,
- idOrdine: idOrdine,
- idArticolo: promo.idArticoloOmaggio ?? line.idArticolo,
- quantita: giftQty,
- prezzoLordo: 0,
- prezzoNetto: 0,
- totale: 0,
- promozione: promo.progressivo,
- rigaPromozione: 1,
- colli: 0,
- ));
- }
- return ApplicaPromoResult(
- tipoRisultato: newLines.isEmpty ? ApplicaPromoResult.resultNone : ApplicaPromoResult.resultRighe,
- righe: newLines,
- );
- }
- Future<ApplicaPromoResult> _applicaTipo4(Promozione promo, List<RigaOrdine> lines, int idOrdine) async {
- final totalColli = lines.fold(0.0, (sum, l) => sum + (l.colli ?? 0));
- if (totalColli < (promo.limiteQta ?? 0)) return ApplicaPromoResult();
- final omaggi = await _promozioniDao.getPromoOmaggi(promo.progressivo);
- final articoliOmaggio = <ArticoloOmaggio>[];
- for (final om in omaggi) {
- if (om.idArticolo == null) continue;
- articoliOmaggio.add(ArticoloOmaggio(
- idArticolo: om.idArticolo!,
- descrizione: 'Articolo ${om.idArticolo}',
- quantita: om.quantita ?? 1,
- quantitaDisponibile: om.quantita ?? 1,
- progressivo: promo.progressivo,
- ));
- }
- if (articoliOmaggio.length == 1) {
- final newLines = <RigaOrdine>[];
- newLines.add(RigaOrdine(
- idRigaOrdine: 0,
- idOrdine: idOrdine,
- idArticolo: articoliOmaggio.first.idArticolo,
- quantita: articoliOmaggio.first.quantita,
- prezzoLordo: 0,
- prezzoNetto: 0,
- totale: 0,
- promozione: promo.progressivo,
- rigaPromozione: 1,
- colli: 0,
- ));
- return ApplicaPromoResult(tipoRisultato: ApplicaPromoResult.resultRighe, righe: newLines);
- }
- return ApplicaPromoResult(
- tipoRisultato: ApplicaPromoResult.resultOmaggi,
- omaggi: articoliOmaggio,
- );
- }
- Future<ApplicaPromoResult> _applicaTipo5(Promozione promo, List<RigaOrdine> lines, int idOrdine) async {
- final promoArts = await _promozioniDao.getPromoArticoli(promo.progressivo);
- final promoListini = await _promozioniDao.getPromoListini(promo.progressivo);
- final newLines = <RigaOrdine>[];
- double totalColli = 0;
- final matchingLines = <RigaOrdine>[];
- for (final line in lines) {
- bool match = true;
- if (promoArts.isNotEmpty && !promoArts.any((a) => a.idArticolo == line.idArticolo)) match = false;
- if (promoListini.isNotEmpty && !promoListini.any((l) => l.idListino == line.idListino)) match = false;
- if (match) {
- totalColli += (line.colli ?? 0);
- matchingLines.add(line);
- }
- }
- if (totalColli < (promo.limiteQta ?? 0)) return ApplicaPromoResult();
- final giftMultiplier = (totalColli / (promo.limiteQta ?? 1)).floor();
- final totalGiftQty = (giftMultiplier * (promo.quantitaOmaggio ?? 1)).toDouble();
- if (promo.idArticoloOmaggio != null) {
- newLines.add(RigaOrdine(
- idRigaOrdine: 0,
- idOrdine: idOrdine,
- idArticolo: promo.idArticoloOmaggio!,
- quantita: totalGiftQty,
- prezzoLordo: 0,
- prezzoNetto: 0,
- totale: 0,
- promozione: promo.progressivo,
- rigaPromozione: 1,
- colli: 0,
- ));
- }
- return ApplicaPromoResult(
- tipoRisultato: newLines.isEmpty ? ApplicaPromoResult.resultNone : ApplicaPromoResult.resultRighe,
- righe: newLines,
- );
- }
- Future<ApplicaPromoResult> _applicaTipo6(Promozione promo, List<RigaOrdine> lines, int idOrdine) async {
- final totalImporto = lines.fold(0.0, (sum, l) => sum + (l.totale ?? 0));
- if (totalImporto < (promo.limiteImporto ?? 0)) return ApplicaPromoResult();
- final giftMultiplier = (totalImporto / (promo.limiteImporto ?? 1)).floor();
- final totalGiftQty = (giftMultiplier * (promo.quantitaOmaggio ?? 1)).toDouble();
- final newLines = <RigaOrdine>[];
- if (promo.idArticoloOmaggio != null) {
- newLines.add(RigaOrdine(
- idRigaOrdine: 0,
- idOrdine: idOrdine,
- idArticolo: promo.idArticoloOmaggio!,
- quantita: totalGiftQty,
- prezzoLordo: 0,
- prezzoNetto: 0,
- totale: 0,
- promozione: promo.progressivo,
- rigaPromozione: 1,
- colli: 0,
- ));
- }
- return ApplicaPromoResult(
- tipoRisultato: newLines.isEmpty ? ApplicaPromoResult.resultNone : ApplicaPromoResult.resultRighe,
- righe: newLines,
- );
- }
- Future<ApplicaPromoResult> _applicaTipo9(Promozione promo, List<RigaOrdine> lines, int idOrdine) async {
- final promoArts = await _promozioniDao.getPromoArticoli(promo.progressivo);
- final promoListini = await _promozioniDao.getPromoListini(promo.progressivo);
- final newLines = <RigaOrdine>[];
- final modifiedLines = <RigaOrdine>[];
- for (final line in lines) {
- if (line.quantita == null || line.quantita! < (promo.limiteQta ?? 0)) continue;
- bool match = true;
- if (promoArts.isNotEmpty && !promoArts.any((a) => a.idArticolo == line.idArticolo)) match = false;
- if (promoListini.isNotEmpty && !promoListini.any((l) => l.idListino == line.idListino)) match = false;
- if (!match) continue;
- final freeQty = ((line.quantita! / (promo.limiteQta ?? 1)).floor() * (promo.quantitaOmaggio ?? 1)).toDouble();
- if (freeQty <= 0) continue;
- newLines.add(RigaOrdine(
- idRigaOrdine: 0,
- idOrdine: idOrdine,
- idArticolo: line.idArticolo,
- idListino: line.idListino,
- quantita: freeQty,
- prezzoLordo: 0,
- prezzoNetto: 0,
- totale: 0,
- promozione: promo.progressivo,
- rigaPromozione: 1,
- colli: line.colli,
- ));
- }
- return ApplicaPromoResult(
- tipoRisultato: newLines.isEmpty ? ApplicaPromoResult.resultNone : ApplicaPromoResult.resultRighe,
- righe: newLines,
- );
- }
- Future<ApplicaPromoResult> selezionaOmaggio(int progressivo, int idArticoloScelto, int idOrdine) async {
- final promo = await _promozioniDao.getActivePromos('');
- final p = promo.where((x) => x.progressivo == progressivo).firstOrNull;
- if (p == null) return ApplicaPromoResult();
- final newLines = <RigaOrdine>[
- RigaOrdine(
- idRigaOrdine: 0,
- idOrdine: idOrdine,
- idArticolo: idArticoloScelto,
- quantita: p.quantitaOmaggio ?? 1,
- prezzoLordo: 0,
- prezzoNetto: 0,
- totale: 0,
- promozione: progressivo,
- rigaPromozione: 1,
- colli: 0,
- ),
- ];
- return ApplicaPromoResult(tipoRisultato: ApplicaPromoResult.resultRighe, righe: newLines);
- }
- }
|