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/cargo_type.dart'; import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/domain/vo/message.dart'; import 'package:fcs/domain/vo/shipment_status.dart'; import 'package:fcs/helpers/paginator.dart'; import 'package:fcs/pages/main/model/base_model.dart'; import 'package:fcs/pagination/paginator_listener.dart'; import 'package:logging/logging.dart'; class CartonModel extends BaseModel { List _boxes = []; PaginatorListener cartonsByFilter; final log = Logger('CartonModel'); List get boxes => _selectedIndex == 1 ? _boxes : List.from(_delivered.values); Paginator _delivered; int _selectedIndex = 1; int _selectedIndexFilter = 1; bool isLoading = false; StreamSubscription listener; StreamSubscription cartonListener; static List statusHistory = [ ShipmentStatus(status: "Packed", date: DateTime(2020, 6, 1), done: true), ShipmentStatus(status: "Shipped", date: DateTime(2020, 6, 5), done: false), ShipmentStatus( status: "Delivered", date: DateTime(2020, 6, 15), done: false) ]; List get completed { return boxes.where((e) => e.status == "Delivered").toList() ..sort((e1, e2) { return e2.packageNumber.compareTo(e1.packageNumber); }); } List get processed { return boxes.where((e) => e.status == "Packed").toList() ..sort((e1, e2) { return e2.packageNumber.compareTo(e1.packageNumber); }); } List get upcoming { return boxes .where((e) => e.status == "Packed" || // e.status == "Received" || e.status == "Shipped" || e.status == "Arrived") .toList() ..sort((e1, e2) { return e2.packageNumber.compareTo(e1.packageNumber); }); } List cartonTypes = [ carton_from_packages, carton_from_cartons, carton_mix_box ]; List mixBoxTypes = [mix_delivery, mix_pickup]; List cartonTypesInfo = [ carton_from_packages, carton_from_cartons, carton_mix_box, carton_from_shipments, carton_small_bag ]; set selectedIndex(int index) { _selectedIndex = index; notifyListeners(); } set selectedIndexFilter(int index) { _selectedIndexFilter = index; _loadCartonsByFilter( _selectedIndexFilter == 1 ? "carton_weight" : "user_name"); notifyListeners(); } get selectedIndex => _selectedIndex; get selectedIndexFilter => _selectedIndexFilter; initData() async { _selectedIndex = 1; _selectedIndexFilter = 1; _loadBoxes(); if (_delivered != null) _delivered.close(); _delivered = _getDelivered(); _delivered.load(); } @override void privilegeChanged() { if (user != null || !user.hasCarton()) { _initData(); } } Future _initData() async { logout(); _selectedIndexFilter = 1; cartonsByFilter = PaginatorListener( (data, id) => Carton.fromMap(data, id), onChange: () { notifyListeners(); }, rowPerLoad: 30, insertNewByListener: true); _loadCartonsByFilter( _selectedIndexFilter == 1 ? "carton_weight" : "user_name"); } Future _loadBoxes() async { if (user == null || !user.hasCarton()) return; String path = "/$cartons_collection/"; if (listener != null) listener.cancel(); _boxes = []; try { listener = Firestore.instance .collection("$path") .where("status", whereIn: [carton_packed_status, carton_shipped_status]) .where("is_deleted", isEqualTo: false) .orderBy("created_at", descending: true) .snapshots() .listen((QuerySnapshot snapshot) { _boxes.clear(); _boxes = snapshot.documents.map((documentSnapshot) { var s = Carton.fromMap( documentSnapshot.data, documentSnapshot.documentID); return s; }).toList(); notifyListeners(); }); } catch (e) { log.warning("Error!! $e"); } } Future _loadCartonsByFilter(String orderName) async { if (user == null || !user.hasCarton()) return null; String path = "/$cartons_collection"; try { Query listenerQuery = Firestore.instance .collection("$path") .where("carton_type", whereIn: [carton_from_packages, carton_from_cartons]) .where("status", isEqualTo: carton_packed_status) .orderBy(orderName, descending: true); Query pageQuery = Firestore.instance .collection("$path") .where("carton_type", whereIn: [carton_from_packages, carton_from_cartons]) .where("status", isEqualTo: carton_packed_status) .orderBy(orderName, descending: true); cartonsByFilter.refresh( listeningQuery: listenerQuery, pageQuery: pageQuery); } catch (e) { log.warning("Error!! $e"); } } Paginator _getDelivered() { if (user == null || !user.hasCarton()) return null; var pageQuery = Firestore.instance .collection("/$cartons_collection") .where("is_delivered", isEqualTo: true) .where("is_deleted", isEqualTo: false); var paginator = new Paginator(pageQuery, rowPerLoad: 20, toObj: (data, id) { return Carton.fromMap(data, id); }); return paginator; } Future loadMore() async { if (_delivered.ended || selectedIndex == 1) return; isLoading = true; notifyListeners(); await _delivered.load(onFinished: () { isLoading = false; notifyListeners(); }); } Future refresh() async { if (selectedIndex == 1) return; await _delivered.refresh(onFinished: () { notifyListeners(); }); } void initUser(user) { super.initUser(user); } @override logout() async { if (listener != null) await listener.cancel(); if (cartonListener != null) await cartonListener.cancel(); if (_delivered != null) _delivered.close(); if (cartonsByFilter != null) cartonsByFilter.close(); _boxes = []; } Future> getCartons(String shipmentID) async { String path = "/$cartons_collection"; var querySnap = await Firestore.instance .collection(path) .where("shipment_id", isEqualTo: shipmentID) .getDocuments(); return querySnap.documents .map((e) => Carton.fromMap(e.data, e.documentID)) .toList(); } Future> getCartonsByFcsShipment(String fcsShipmentID) async { String path = "/$cartons_collection"; var querySnap = await Firestore.instance .collection(path) .where("fcs_shipment_id", isEqualTo: fcsShipmentID) .where("is_deleted", isEqualTo: false) .getDocuments(); return querySnap.documents .map((e) => Carton.fromMap(e.data, e.documentID)) .toList(); } Future> getCartonsForInvoice( String fcsShipmentID, String userID) async { String path = "/$cartons_collection"; var querySnap = await Firestore.instance .collection(path) .where("fcs_shipment_id", isEqualTo: fcsShipmentID) .where("user_id", isEqualTo: userID) .where("is_deleted", isEqualTo: false) .where("is_invoiced", isEqualTo: false) .getDocuments(); List cartons = querySnap.documents .map((e) => Carton.fromMap(e.data, e.documentID)) .toList(); return cartons; } Future> getMixCartonsByFcsShipment(String fcsShipmentID) async { String path = "/$cartons_collection"; var querySnap = await Firestore.instance .collection(path) .where("fcs_shipment_id", isEqualTo: fcsShipmentID) .where("carton_type", isEqualTo: carton_mix_box) .where("is_deleted", isEqualTo: false) .getDocuments(); return querySnap.documents .map((e) => Carton.fromMap(e.data, e.documentID)) .toList(); } Future getCarton(String id) async { String path = "/$cartons_collection"; var snap = await Firestore.instance.collection(path).document(id).get(); return Carton.fromMap(snap.data, snap.documentID); } Future createCarton(Carton carton) { return Services.instance.cartonService.createCarton(carton); } Future updateCarton(Carton carton) { return Services.instance.cartonService.updateCarton(carton); } Future deleteCarton(Carton carton) { return Services.instance.cartonService.deleteCarton(carton); } Future> searchCarton(String term) async { return Services.instance.cartonService.searchCarton(term); } }