import 'package:drift/drift.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../database/database.dart'; import '../../business/order_manager.dart'; import 'database_provider.dart'; class OrderState { final Ordine? order; final List lines; final List removedLineIds; final bool isLoading; final String? error; const OrderState({ this.order, this.lines = const [], this.removedLineIds = const [], this.isLoading = false, this.error, }); double get totale { return lines.fold(0.0, (sum, l) => sum + (l.totale ?? 0)); } double get totQta { return lines.fold(0.0, (sum, l) => sum + (l.quantita ?? 0)); } } class OrderNotifier extends Notifier { @override OrderState build() => const OrderState(); OrderManager _buildManager() { return OrderManager( ref.read(ordiniDaoProvider), ref.read(clientiDaoProvider), ref.read(filialiDaoProvider), ref.read(articoliDaoProvider), ref.read(listiniDaoProvider), ref.read(scontiDaoProvider), ref.read(pagamentiDaoProvider), ref.read(agentiDaoProvider), ); } Future createOrder(int idAgente, {int? idCliente}) async { final mgr = _buildManager(); mgr.idAgente = idAgente; final order = await mgr.createOrder(idCliente: idCliente); state = OrderState(order: order); } Future loadOrder(int id) async { state = const OrderState(isLoading: true); final mgr = _buildManager(); final order = await mgr.loadOrder(id); if (order != null) { final lines = await ref.read(ordiniDaoProvider).getOrderLinesView(id); state = OrderState(order: order, lines: lines); } else { state = const OrderState(error: 'Ordine non trovato'); } } void setIdCliente(int idCliente) { if (state.order == null) return; state = OrderState( order: state.order!.copyWith(idCliente: Value(idCliente)), lines: state.lines, ); } void addLine(VRigheOrdineData line) { if (state.order == null) return; state = OrderState( order: state.order, lines: [...state.lines, line], removedLineIds: state.removedLineIds, ); } void removeLine(int index) { if (state.order == null || index < 0 || index >= state.lines.length) return; final removed = state.lines[index]; final newLines = List.from(state.lines)..removeAt(index); final newRemovedIds = [ ...state.removedLineIds, if (removed.idRigaOrdine > 0) removed.idRigaOrdine, ]; state = OrderState( order: state.order, lines: newLines, removedLineIds: newRemovedIds, ); } Future saveOrder() async { if (state.order == null) return; final dao = ref.read(ordiniDaoProvider); Ordine order = state.order!; if (order.idOrdine > 0) { await dao.updateOrder(order); } else { final id = await dao.insertOrder(order); order = order.copyWith(idOrdine: id); } for (final viewLine in state.lines) { var lineToSave = RigaOrdine( idRigaOrdine: viewLine.idRigaOrdine, idOrdine: order.idOrdine, idArticolo: viewLine.idArticolo, idListino: viewLine.idListino, quantita: viewLine.quantita, prezzoLordo: viewLine.prezzoLordo, sconto1: viewLine.sconto1, sconto2: viewLine.sconto2, sconto3: viewLine.sconto3, sconto4: viewLine.sconto4, sconto5: viewLine.sconto5, prezzoNetto: viewLine.prezzoNetto, scontoMerce: viewLine.scontoMerce, totale: viewLine.totale, dataConsegna: viewLine.dataConsegna, dataModifica: viewLine.dataModifica, qtaEvasa: viewLine.qtaEvasa, stato: viewLine.stato, colli: viewLine.colli, promozione: viewLine.promozione, rigaPromozione: viewLine.rigaPromozione, prezzoManuale: viewLine.prezzoManuale, ); if (viewLine.idRigaOrdine == 0) { await dao.insertOrderLine(lineToSave); } else { await dao.updateOrderLine(lineToSave); } } for (final idRiga in state.removedLineIds) { await dao.deleteOrderLine(idRiga); } state = OrderState(order: order, lines: state.lines); } Future deleteOrder() async { if (state.order == null) return; final dao = ref.read(ordiniDaoProvider); await dao.deleteOrder(state.order!.idOrdine); state = const OrderState(); } void setIdFiliale(int? v) { if (state.order == null) return; state = OrderState( order: state.order!.copyWith(idFiliale: Value(v)), lines: state.lines, ); } void setIdListino(int? v) { if (state.order == null) return; state = OrderState( order: state.order!.copyWith(idListino: Value(v)), lines: state.lines, ); } void setIdPagamento(int? v) { if (state.order == null) return; state = OrderState( order: state.order!.copyWith(idPagamento: Value(v)), lines: state.lines, ); } void setNoteCliente(String? v) { if (state.order == null) return; state = OrderState( order: state.order!.copyWith(noteCliente: Value(v)), lines: state.lines, ); } void setNoteOrdine(String? v) { if (state.order == null) return; state = OrderState( order: state.order!.copyWith(noteOrdine: Value(v)), lines: state.lines, ); } void setRiferimento(String? v) { if (state.order == null) return; state = OrderState( order: state.order!.copyWith(riferimento: Value(v)), lines: state.lines, ); } } final orderProvider = NotifierProvider(OrderNotifier.new); final ordersViewProvider = FutureProvider.family, int>((ref, idAgente) { return ref.read(ordiniDaoProvider).getOrdersView(idAgente); }); final ordersSearchViewProvider = FutureProvider.family, ({int idAgente, String filter})>( (ref, params) { return ref.read(ordiniDaoProvider).searchOrdersView(params.idAgente, params.filter); }, ); class OrderStats { final int daTrasmettere; final int numeroOrdini; final double volumeMensile; const OrderStats({ this.daTrasmettere = 0, this.numeroOrdini = 0, this.volumeMensile = 0, }); } final orderStatsProvider = FutureProvider.family((ref, idAgente) async { final dao = ref.read(ordiniDaoProvider); final daTrasmettere = await dao.countNewOrdersForAgent(idAgente); final numeroOrdini = await dao.countOrdersForAgent(idAgente); final volumeMensile = await dao.getMonthlyVolume(idAgente); return OrderStats( daTrasmettere: daTrasmettere, numeroOrdini: numeroOrdini, volumeMensile: volumeMensile, ); });