diff --git a/lib/data/provider/delivery_address_data_provider.dart b/lib/data/provider/delivery_address_data_provider.dart index 70e620b..72d9267 100644 --- a/lib/data/provider/delivery_address_data_provider.dart +++ b/lib/data/provider/delivery_address_data_provider.dart @@ -24,7 +24,7 @@ class DeliveryAddressDataProvider { Future selectDefalutDeliveryAddress( DeliveryAddress deliveryAddress) async { - return await requestAPI("/delivery_address/defalut", "PUT", - payload: deliveryAddress.toMap(), token: await getToken()); + return await requestAPI("/delivery_address/default", "PUT", + payload: deliveryAddress.toMapForDefault(), token: await getToken()); } } diff --git a/lib/domain/constants.dart b/lib/domain/constants.dart index 7641213..05142e1 100644 --- a/lib/domain/constants.dart +++ b/lib/domain/constants.dart @@ -73,6 +73,8 @@ const privilege_invoice = "inv"; const privilege_processing = "pr"; const privilege_receiving = "rc"; const privilege_pickup = "pku"; +const privilege_collect ="col"; +const privilege_report ="rpt"; // Pickup types const shipment_local_pickup = "Local pickup"; diff --git a/lib/domain/entities/package.dart b/lib/domain/entities/package.dart index 2df0c7d..882c2c2 100644 --- a/lib/domain/entities/package.dart +++ b/lib/domain/entities/package.dart @@ -91,7 +91,7 @@ class Package { userName: map['user_name'], phoneNumber: map['phone_number'], remark: map['remark'], - desc: map['desc'], + desc: map['desc'] ?? "", status: map['status'], senderFCSID: map['sender_fcs_id'], senderName: map['sender_name'], @@ -134,11 +134,12 @@ class Package { } bool isChangedForEditProcessing(Package package) { - return package.trackingID != this.trackingID || - package.fcsID != this.fcsID || + return package.fcsID != this.fcsID || + package.senderFCSID != this.senderFCSID || package.market != this.market || package.desc != this.desc || - package.remark != this.remark; + package.remark != this.remark || + package.photoUrls != this.photoUrls; } @override diff --git a/lib/domain/vo/delivery_address.dart b/lib/domain/vo/delivery_address.dart index b212ebc..e62ee5e 100644 --- a/lib/domain/vo/delivery_address.dart +++ b/lib/domain/vo/delivery_address.dart @@ -29,7 +29,7 @@ class DeliveryAddress { city: map['city'], state: map['state'], phoneNumber: map['phone_number'], - isDefault: map['is_defalut'] ?? false, + isDefault: map['is_default'] ?? false, ); } @@ -46,6 +46,10 @@ class DeliveryAddress { }; } + Map toMapForDefault() { + return {"id": id}; + } + bool isChangedForEdit(DeliveryAddress deliveryAddress) { return deliveryAddress.fullName != this.fullName || deliveryAddress.phoneNumber != this.phoneNumber || diff --git a/lib/domain/vo/privilege.dart b/lib/domain/vo/privilege.dart index ac0926b..67dc398 100644 --- a/lib/domain/vo/privilege.dart +++ b/lib/domain/vo/privilege.dart @@ -45,6 +45,10 @@ class Privilege { iconData = MaterialCommunityIcons.inbox_arrow_down; } else if (this.id == privilege_pickup) { iconData = SimpleLineIcons.direction; + } else if (this.id == privilege_collect) { + iconData = MaterialCommunityIcons.layers; + } else if (this.id == privilege_report) { + iconData = Feather.file_text; } else { iconData = MaterialCommunityIcons.account_question; } diff --git a/lib/pages/carton/carton_cargo_table.dart b/lib/pages/carton/carton_cargo_table.dart index 4aca979..a7751de 100644 --- a/lib/pages/carton/carton_cargo_table.dart +++ b/lib/pages/carton/carton_cargo_table.dart @@ -205,7 +205,7 @@ class _CargoTableState extends State { alignment: Alignment.centerRight, child: InkWell( onTap: () async { - String _t = await showDialog( + String? _t = await showDialog( context: context, builder: (_) => DialogInput( label: "shipment.cargo.total", diff --git a/lib/pages/carton/carton_editor.dart b/lib/pages/carton/carton_editor.dart index 4cd1c36..8579e6c 100644 --- a/lib/pages/carton/carton_editor.dart +++ b/lib/pages/carton/carton_editor.dart @@ -853,7 +853,7 @@ class _CartonEditorState extends State { carton.deliveryAddress = _carton!.deliveryAddress; try { - Carton _c = await Navigator.push( + Carton? _c = await Navigator.push( context, CupertinoPageRoute( builder: (context) => PackageCartonEditor( diff --git a/lib/pages/chat/model/message_model.dart b/lib/pages/chat/model/message_model.dart index 64535ef..865a465 100644 --- a/lib/pages/chat/model/message_model.dart +++ b/lib/pages/chat/model/message_model.dart @@ -38,7 +38,7 @@ class MessageModel extends BaseModel { } Future load() async { - if (prevSnap == null) return; + // if (prevSnap == null) return; Query _query = prevSnap != null ? query.startAfterDocument(prevSnap!) : query; QuerySnapshot snapshot = @@ -62,8 +62,8 @@ class MessageModel extends BaseModel { listener = FirebaseFirestore.instance .collection("$user_collection/$userID/$messages_collection") - .endBeforeDocument(snap) .orderBy('date', descending: true) + .endBeforeDocument(snap) .snapshots(includeMetadataChanges: true) .listen((qs) { qs.docChanges.forEach((c) { diff --git a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart index 3667a88..762aa0b 100644 --- a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart +++ b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart @@ -141,8 +141,8 @@ class FcsShipmentModel extends BaseModel { .where("pending_invoice_user_count", isGreaterThan: 0) .get(const GetOptions(source: Source.server)); fcsShipments = snaps.docs.map((documentSnapshot) { - var fcs = FcsShipment.fromMap( - documentSnapshot.data as Map, documentSnapshot.id); + var fcs = + FcsShipment.fromMap(documentSnapshot.data(), documentSnapshot.id); return fcs; }).toList(); } catch (e) { diff --git a/lib/pages/main/home_page.dart b/lib/pages/main/home_page.dart index 3a13a9c..4cade3b 100644 --- a/lib/pages/main/home_page.dart +++ b/lib/pages/main/home_page.dart @@ -299,7 +299,7 @@ class _HomePageState extends State { final staffBtn = TaskButton( "staff.title", - icon: MaterialCommunityIcons.account_tie, + icon: MaterialCommunityIcons.account_hard_hat, btnCallback: () => Navigator.of(context).push(CupertinoPageRoute( builder: (context) => StaffList(), )), @@ -335,12 +335,12 @@ class _HomePageState extends State { widgets.add(notiBtn); if (user.joined) { widgets.add(packagesBtn); - widgets.add(shipmentBtn); + // widgets.add(shipmentBtn); widgets.add(invoicesBtn); if (user.hasAdmin() || user.hasSupport()) widgetsFcs.add(rateBtnFcs); if (user.hasPackages()) widgetsFcs.add(packagesBtnFcs); - if (user.hasShipment()) widgetsFcs.add(shipmentBtnFcs); + // if (user.hasShipment()) widgetsFcs.add(shipmentBtnFcs); if (user.hasShipment()) widgetsFcs.add(pickupBtnFcs); if (user.hasInvoices()) widgetsFcs.add(invoicesBtnFcs); diff --git a/lib/pages/package/model/package_model.dart b/lib/pages/package/model/package_model.dart index 33236fa..dcbf6bc 100644 --- a/lib/pages/package/model/package_model.dart +++ b/lib/pages/package/model/package_model.dart @@ -222,8 +222,7 @@ class PackageModel extends BaseModel { .where("is_deleted", isEqualTo: false) .get(const GetOptions(source: Source.server)); packages = snaps.docs.map((documentSnapshot) { - var p = Package.fromMap( - documentSnapshot.data as Map, documentSnapshot.id); + var p = Package.fromMap(documentSnapshot.data(), documentSnapshot.id); return p; }).toList(); } catch (e) { @@ -271,7 +270,7 @@ class PackageModel extends BaseModel { package.photoUrls = package.photoUrls == null ? [] : package.photoUrls; String path = Path.join(pkg_files_path); List urls = await uploadFiles(path, files); - package.photoUrls =urls; + package.photoUrls = urls; } try { diff --git a/lib/pages/processing/package_editor.dart b/lib/pages/processing/package_editor.dart index 207f662..96fd95c 100644 --- a/lib/pages/processing/package_editor.dart +++ b/lib/pages/processing/package_editor.dart @@ -65,8 +65,8 @@ class _PackageEditorState extends State { } setState(() { selectedMarket = _package!.market ?? ""; - _descCtl.text = _package!.desc!; - _remarkCtl.text = _package!.remark!; + _descCtl.text = _package!.desc ?? ""; + _remarkCtl.text = _package!.remark ?? ""; multiImgController.setImageUrls = _package!.photoUrls; }); } @@ -180,7 +180,7 @@ class _PackageEditorState extends State { List markets = _markets.map((e) => e.name).toList(); markets.insert(0, MANAGE_MARKET); if (!markets.contains(selectedMarket)) { - markets.insert(0, selectedMarket!); + markets.insert(0, selectedMarket); } return Row( @@ -254,13 +254,13 @@ class _PackageEditorState extends State { PackageModel packageModel = Provider.of(context, listen: false); try { - _package!.market = selectedMarket!; + _package!.market = selectedMarket ?? ""; _package!.desc = _descCtl.text; _package!.remark = _remarkCtl.text; _package!.photoFiles = multiImgController.getUpdatedFile; - _package!.fcsID = widget.consignee!.fcsID; + _package!.fcsID = widget.consignee?.fcsID; _package!.senderFCSID = - widget.sender!.fcsID != null ? widget.sender!.fcsID : ""; + widget.sender?.fcsID != null ? widget.sender?.fcsID : ""; await packageModel.updateProcessing(_package!, multiImgController.getAddedFile, multiImgController.getDeletedUrl); @@ -276,9 +276,10 @@ class _PackageEditorState extends State { } isDataChanged() { - return selectedMarket != null || + return _package?.trackingID != null || _descCtl.text != "" || _remarkCtl.text != "" || - multiImgController.getAddedFile.isNotEmpty; + multiImgController.getAddedFile.isNotEmpty || + selectedMarket != null && selectedMarket != ""; } } diff --git a/lib/pages/processing/processing_edit_editor.dart b/lib/pages/processing/processing_edit_editor.dart index 64d9155..6b0c02c 100644 --- a/lib/pages/processing/processing_edit_editor.dart +++ b/lib/pages/processing/processing_edit_editor.dart @@ -34,7 +34,8 @@ class _ProcessingEditEditorState extends State { TextEditingController _descCtl = new TextEditingController(); Package? _package; - User? _user; + User? _consignee; + User? _sender; bool _isLoading = false; @override @@ -45,10 +46,15 @@ class _ProcessingEditEditorState extends State { _descCtl.text = _package!.desc ?? ""; _remarkCtl.text = _package!.remark ?? ""; multiImgController.setImageUrls = _package!.photoUrls; - _user = User( + _consignee = User( fcsID: _package!.fcsID ?? "", name: _package!.userName ?? "", phoneNumber: _package!.phoneNumber ?? ""); + + _sender = User( + fcsID: _package!.senderFCSID ?? "", + name: _package!.senderName ?? "", + phoneNumber: _package!.senderPhoneNumber ?? ""); } final DateFormat dateFormat = DateFormat("d MMM yyyy"); @@ -62,7 +68,7 @@ class _ProcessingEditEditorState extends State { children: [ Expanded( child: DisplayText( - text: _user!.fcsID, + text: _consignee!.fcsID, labelTextKey: "processing.fcs.id", icon: FcsIDIcon(), )), @@ -70,18 +76,18 @@ class _ProcessingEditEditorState extends State { icon: Icon(Icons.search, color: primaryColor), onPressed: () => searchUser(context, onUserSelect: (u) { setState(() { - this._user = u; + this._consignee = u; }); })), ], ); final namebox = DisplayText( - text: _user!.name, - labelTextKey: "processing.name", + text: _consignee!.name, + labelTextKey: "processing.consignee.name", iconData: Icons.person, ); final phoneNumberBox = DisplayText( - text: _user!.phoneNumber, + text: _consignee!.phoneNumber, labelTextKey: "processing.phone", iconData: Icons.phone, ); @@ -110,6 +116,59 @@ class _ProcessingEditEditorState extends State { controller: multiImgController, title: "Receipt File", ); + + final consigneeBox = Container( + child: Column( + children: [ + fcsIDBox, + phoneNumberBox, + namebox, + ], + ), + ); + + var shipperIDBox = Row( + children: [ + Expanded( + child: DisplayText( + text: _sender != null ? _sender!.fcsID : "", + labelTextKey: "processing.fcs.id", + icon: FcsIDIcon(), + )), + IconButton( + icon: Icon(Icons.search, color: primaryColor), + onPressed: () => searchUser(context, onUserSelect: (u) { + setState(() { + this._sender = u; + }); + }, popPage: true)), + ], + ); + + final shipperPhoneNumberBox = DisplayText( + text: _sender != null ? _sender!.phoneNumber : "", + labelTextKey: "processing.phone", + maxLines: 2, + iconData: Icons.phone, + ); + + final shipperNamebox = DisplayText( + text: _sender != null ? _sender!.name : "", + labelTextKey: "processing.shipper.name", + maxLines: 2, + iconData: Icons.person, + ); + + final shipperBox = Container( + child: Column( + children: [ + shipperIDBox, + shipperPhoneNumberBox, + shipperNamebox, + ], + ), + ); + return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( @@ -141,9 +200,12 @@ class _ProcessingEditEditorState extends State { child: ListView( children: [ trackingIdBox, - fcsIDBox, - namebox, - phoneNumberBox, + Row( + children: [ + Flexible(child: consigneeBox), + Flexible(child: shipperBox) + ], + ), marketDropdown(), descBox, remarkBox, @@ -165,11 +227,11 @@ class _ProcessingEditEditorState extends State { List markets = _markets.map((e) => e.name).toList(); markets.insert(0, MANAGE_MARKET); if (!markets.contains(selectedMarket)) { - markets.insert(0, selectedMarket!); + markets.insert(0, selectedMarket); } return Padding( - padding: const EdgeInsets.only(left: 5.0, right: 0), + padding: const EdgeInsets.only(left: 5.0, right: 0, top: 10), child: Row( children: [ Padding( @@ -236,7 +298,7 @@ class _ProcessingEditEditorState extends State { } _completeProcessing() async { - if (_user!.fcsID == null || _user!.fcsID == "") { + if (_consignee!.fcsID == null || _consignee!.fcsID == "") { showMsgDialog(context, "Error", "Expected FCS-ID"); return; } @@ -246,10 +308,11 @@ class _ProcessingEditEditorState extends State { PackageModel packageModel = Provider.of(context, listen: false); try { - _package!.fcsID = _user!.fcsID; + _package!.fcsID = _consignee!.fcsID; + _package!.senderFCSID = _sender!.fcsID; _package!.desc = _descCtl.text; _package!.remark = _remarkCtl.text; - _package!.market = selectedMarket!; + _package!.market = selectedMarket ?? ""; await packageModel.updateProcessing(_package!, multiImgController.getAddedFile, multiImgController.getDeletedUrl); Navigator.pop(context); @@ -264,17 +327,17 @@ class _ProcessingEditEditorState extends State { isDataChanged() { if (isNew) { - return _user!.fcsID != "" || + return _consignee!.fcsID != "" || selectedMarket != null || _descCtl.text != "" || _remarkCtl.text != "" || multiImgController.getAddedFile.isNotEmpty; } else { var _package = Package( - trackingID: widget.package!.trackingID, - fcsID: _user!.fcsID, - market: selectedMarket!, - desc: _descCtl.text, + fcsID: _consignee!.fcsID, + senderFCSID: _sender!.fcsID, + market: selectedMarket, + desc: _descCtl.text , remark: _remarkCtl.text, photoUrls: widget.package!.photoUrls); return widget.package!.isChangedForEditProcessing(_package) || diff --git a/lib/pages/processing/processing_editor.dart b/lib/pages/processing/processing_editor.dart index 3ae2505..ad03853 100644 --- a/lib/pages/processing/processing_editor.dart +++ b/lib/pages/processing/processing_editor.dart @@ -160,7 +160,8 @@ class _ProcesingEditorState extends State { consignee: this.consignee, )), ); - _addPackage(_package!); + + _addPackage(_package); // _savePackage(_package); }), ], @@ -244,14 +245,14 @@ class _ProcesingEditorState extends State { }).toList(); } - _addPackage(Package package) { + _addPackage(Package? package) { if (package == null) return; this.packages.add(package); setState(() {}); } - _savePackage(Package package) { + _savePackage(Package? package) { if (package == null) return; setState(() {}); } diff --git a/lib/pages/processing/processing_info.dart b/lib/pages/processing/processing_info.dart index 2f15404..f0df4d5 100644 --- a/lib/pages/processing/processing_info.dart +++ b/lib/pages/processing/processing_info.dart @@ -215,15 +215,14 @@ class _ProcessingInfoState extends State { bool? deleted = await Navigator.push( context, CupertinoPageRoute( - builder: (context) => ProcessingEditEditor( - package: widget.package, - ))); + builder: (context) => ProcessingEditEditor(package: _package))); if (deleted ?? false) { Navigator.pop(context); } else { PackageModel packageModel = Provider.of(context, listen: false); Package? p = await packageModel.getPackage(_package!.id!); + if(p == null)return; initPackage(p); } } diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index 3732104..4fd30a5 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -21,6 +21,7 @@ import 'package:provider/provider.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import '../../helpers/theme.dart'; +import 'package:collection/collection.dart'; typedef void ProfileCallback(); @@ -202,9 +203,11 @@ class _ProfileState extends State { Provider.of(context, listen: false).privileges; if (user == null || user.isCustomer()) return Container(); + List privileges = []; user.privileges.forEach((e) { - var p = _privileges.firstWhere((p) => p.id == e); + Privilege? p = _privileges.firstWhereOrNull((p) => p.id == e); + if (p != null) { privileges.add(p); } diff --git a/lib/pages/rates/cargo_editor.dart b/lib/pages/rates/cargo_editor.dart index a0728fe..488fe3a 100644 --- a/lib/pages/rates/cargo_editor.dart +++ b/lib/pages/rates/cargo_editor.dart @@ -105,6 +105,10 @@ class _CargoEditorState extends State { } _save() async { + if (_rateController.text == "") { + showMsgDialog(context, "Error", "Please insert rate"); + return; + } setState(() { _isLoading = true; }); diff --git a/lib/pages/rates/custom_editor.dart b/lib/pages/rates/custom_editor.dart index 5e8a9ba..a5d5457 100644 --- a/lib/pages/rates/custom_editor.dart +++ b/lib/pages/rates/custom_editor.dart @@ -118,6 +118,16 @@ class _CustomEditorState extends State { } _save() async { + if (_feeController.text == "") { + showMsgDialog(context, "Error", "Please insert fee"); + return; + } + + if (_shipmentRateController.text == "") { + showMsgDialog(context, "Error", "Please insert shipment rate"); + return; + } + setState(() { _isLoading = true; }); diff --git a/lib/pages/rates/discount_by_weight_editor.dart b/lib/pages/rates/discount_by_weight_editor.dart index f910a51..be1a88a 100644 --- a/lib/pages/rates/discount_by_weight_editor.dart +++ b/lib/pages/rates/discount_by_weight_editor.dart @@ -107,6 +107,16 @@ class _DiscountByWeightEditorState extends State { } _save() async { + if (_weightController.text == "") { + showMsgDialog(context, "Error", "Please insert weight"); + return; + } + + if (_discountController.text == "") { + showMsgDialog(context, "Error", "Please insert discount rate"); + return; + } + setState(() { _isLoading = true; }); diff --git a/lib/pages/receiving/receiving_info.dart b/lib/pages/receiving/receiving_info.dart index eba05cb..dcdf850 100644 --- a/lib/pages/receiving/receiving_info.dart +++ b/lib/pages/receiving/receiving_info.dart @@ -144,9 +144,7 @@ class _ReceivingInfoState extends State { await Navigator.push( context, CupertinoPageRoute( - builder: (context) => ReceivingEditor( - package: widget.package, - )), + builder: (context) => ReceivingEditor(package: _package)), ); PackageModel packageModel = Provider.of(context, listen: false); diff --git a/lib/pages/staff/staff_list.dart b/lib/pages/staff/staff_list.dart index 11fd119..a56232a 100644 --- a/lib/pages/staff/staff_list.dart +++ b/lib/pages/staff/staff_list.dart @@ -5,6 +5,7 @@ import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; @@ -83,7 +84,7 @@ class _StaffListState extends State { padding: new EdgeInsets.symmetric( horizontal: 32.0 - dotSize / 2), child: Icon( - Icons.person, + MaterialCommunityIcons.account_hard_hat, color: primaryColor, size: 40, ), diff --git a/lib/pages/term/term_edit.dart b/lib/pages/term/term_edit.dart index b81ecb1..6bc0e69 100644 --- a/lib/pages/term/term_edit.dart +++ b/lib/pages/term/term_edit.dart @@ -8,7 +8,6 @@ import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart'; import 'package:provider/provider.dart'; import 'package:zefyrka/zefyrka.dart'; // import 'package:zefyr/zefyr.dart';