import 'dart:async'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:fcs/data/services/services.dart'; import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/entities/shipment.dart'; import 'package:fcs/helpers/paginator.dart'; import 'package:fcs/pages/main/model/base_model.dart'; import 'package:logging/logging.dart'; class ShipmentModel extends BaseModel { final log = Logger('ShipmentModel'); StreamSubscription? listener; List get shipments => _menuSelectedIndex == 1 ? _shipments : List.from(_delivered!.values); List _shipments = []; Paginator? _delivered; bool isLoading = false; int _menuSelectedIndex = 1; set menuSelectedIndex(int index) { _menuSelectedIndex = index; notifyListeners(); } int get menuSelectedIndex => _menuSelectedIndex; initData(bool forCustomer, {bool myPickup = false}) { logout(); _loadShipments(forCustomer, myPickup); _delivered = _getDelivered(forCustomer); _delivered!.load(onFinished: () { isLoading = false; notifyListeners(); }); } @override logout() async { if (_delivered != null) _delivered!.close(); if (listener != null) await listener!.cancel(); _shipments = []; } Future loadMore({bool? isCustomer}) async { if (menuSelectedIndex == 1) return; // when delivered menu is not selected return if (_delivered!.ended) return; isLoading = true; notifyListeners(); await _delivered!.load(onFinished: () { isLoading = false; notifyListeners(); }); } Future refresh({bool? isCustomer}) async { if (menuSelectedIndex == 1) return; // when delivered menu is not selected return await _delivered!.refresh(onFinished: () { notifyListeners(); }); } Paginator _getDelivered(bool isCustomer) { if (!isCustomer) { if (user == null || !((user!.hasPackages() || user!.hasReceiving() || user!.hasProcessing()))) throw "No privilege"; } var pageQuery = FirebaseFirestore.instance .collection("/$shipments_collection") .where("is_delivered", isEqualTo: true) .where("is_deleted", isEqualTo: false); if (isCustomer) { pageQuery = pageQuery.where("user_id", isEqualTo: user!.id); } pageQuery = pageQuery.orderBy("status_date", descending: true); var paginator = new Paginator(pageQuery, rowPerLoad: 20, toObj: (data, id) { return Shipment.fromMap(data, id); }); return paginator; } Future _loadShipments(bool forCustomer, bool myPickup) async { if (user == null) return; if (!forCustomer && !user!.hasShipment()) return; if (listener != null) listener!.cancel(); _shipments = []; try { var q = FirebaseFirestore.instance .collection("$shipments_collection") .where("is_delivered", isEqualTo: false) .where("is_canceled", isEqualTo: false) .where("is_deleted", isEqualTo: false); if (forCustomer) { q = q.where("user_id", isEqualTo: user!.id); } if (myPickup) { q = q.where("pickup_user_id", isEqualTo: user!.id); } q = q.orderBy("created_at", descending: true); listener = q.snapshots().listen((QuerySnapshot snapshot) { _shipments.clear(); _shipments = snapshot.docs.map((documentSnapshot) { var s = Shipment.fromMap( documentSnapshot.data as Map, documentSnapshot.id); return s; }).toList(); notifyListeners(); }); } catch (e) { log.warning("Error!! $e"); } } List shipmentTypes = [ shipment_local_pickup, shipment_courier_pickup, shipment_local_dropoff, shipment_courier_dropoff ]; Shipment? getActiveShipment(String shipmentID) { return _shipments.firstWhere((e) => e.id == shipmentID); } Future getShipment(String shipmentID) async { String path = "/$shipments_collection"; try { var ref = FirebaseFirestore.instance.collection("$path").doc(shipmentID); var snap = await ref.get(const GetOptions(source: Source.server)); if (snap.exists) { var s = Shipment.fromMap(snap.data as Map, snap.id); return s; } } catch (e) { log.warning("Error!! $e"); } return null; } Future?> getShipmentWithHandlingFee( String fcsShipmentID, String userID) async { String path = "/$shipments_collection"; try { var q = FirebaseFirestore.instance .collection("$path") .where("user_id", isEqualTo: userID) .where("is_deleted", isEqualTo: false) .where("handling_fee", isGreaterThan: 0) .where("fcs_shipment_id", isEqualTo: fcsShipmentID); var snaps = await q.get(const GetOptions(source: Source.server)); List shipments = snaps.docs.map((snap) { if (snap.exists) { var s = Shipment.fromMap(snap.data as Map, snap.id); return s; } }).toList(); return shipments; } catch (e) { log.warning("Error!! $e"); } return null; } void initUser(user) { super.initUser(user); } Future createShipment(Shipment shipment) { return Services.instance.shipmentService.createShipment(shipment); } Future updateShipment(Shipment shipment) { return Services.instance.shipmentService.updateShipment(shipment); } Future cancelShipment(Shipment shipment) { return Services.instance.shipmentService.cancelShipment(shipment); } Future assignShipment(Shipment shipment) { return Services.instance.shipmentService.assignShipment(shipment); } Future completeAssignShipment(Shipment shipment) { return Services.instance.shipmentService.completeAssignShipment(shipment); } Future completePickupShipment(Shipment shipment) { return Services.instance.shipmentService.completePickupShipment(shipment); } Future completePackShipment(Shipment shipment) { return Services.instance.shipmentService.completePackShipment(shipment); } Future packShipment(Shipment shipment) { return Services.instance.shipmentService.packShipment(shipment); } Future confirmShipment(Shipment shipment) async { // String path = Path.join(shipment_labels_files_path); // String url = await uploadStorage(path, file); // shipment.shipmentLabelUrl = url; return Services.instance.shipmentService.confirmShipment(shipment); } Future completeConfirmShipment(Shipment shipment) { return Services.instance.shipmentService.completeConfirmShipment(shipment); } Future completeReceiveShipment(Shipment shipment) { return Services.instance.shipmentService.completeReceiveShipment(shipment); } }