From 0295a29c44d87311bab2df672ce1849f2a723ccb Mon Sep 17 00:00:00 2001 From: tzw Date: Mon, 17 Feb 2025 20:13:30 +0630 Subject: [PATCH] update carton and fcs shipment --- assets/local/localization_en.json | 2 + assets/local/localization_mu.json | 6 +- lib/app.dart | 6 +- lib/constants.dart | 3 + lib/data/provider/shipment_data_provider.dart | 78 --- lib/data/services/services.dart | 8 - lib/data/services/shipment_imp.dart | 79 --- lib/data/services/shipment_service.dart | 17 - lib/domain/entities/fcs_shipment.dart | 63 +- lib/domain/entities/package.dart | 23 +- lib/domain/vo/local_popupmenu.dart | 5 +- lib/domain/vo/shipment_status.dart | 8 +- lib/pages/carton/carton_filter.dart | 5 +- lib/pages/carton/carton_info.dart | 12 +- .../carton/model/carton_selection_model.dart | 4 +- .../carton/model/package_selection_model.dart | 4 +- lib/pages/chat/message_detail.dart | 18 - lib/pages/fcs_shipment/fcs_shipment_info.dart | 44 +- .../model/fcs_shipment_model.dart | 15 +- lib/pages/invoice/editor/invoice_editor.dart | 13 +- lib/pages/invoice/model/invoice_model.dart | 25 + lib/pages/main/home_page.dart | 4 +- lib/pages/shipment/box_row.dart | 115 ---- lib/pages/shipment/cargo_type_editor.dart | 116 ---- lib/pages/shipment/model/shipment_model.dart | 227 ------- lib/pages/shipment/shipment_assign.dart | 157 ----- lib/pages/shipment/shipment_box_editor.dart | 306 ---------- lib/pages/shipment/shipment_confirm.dart | 114 ---- lib/pages/shipment/shipment_editor.dart | 334 ----------- lib/pages/shipment/shipment_info.dart | 567 ------------------ lib/pages/shipment/shipment_pack.dart | 140 ----- lib/pages/shipment/widgets.dart | 24 - lib/pages/widgets/status_tree.dart | 12 +- 33 files changed, 171 insertions(+), 2383 deletions(-) delete mode 100644 lib/data/provider/shipment_data_provider.dart delete mode 100644 lib/data/services/shipment_imp.dart delete mode 100644 lib/data/services/shipment_service.dart delete mode 100644 lib/pages/shipment/box_row.dart delete mode 100644 lib/pages/shipment/cargo_type_editor.dart delete mode 100644 lib/pages/shipment/model/shipment_model.dart delete mode 100644 lib/pages/shipment/shipment_assign.dart delete mode 100644 lib/pages/shipment/shipment_box_editor.dart delete mode 100644 lib/pages/shipment/shipment_confirm.dart delete mode 100644 lib/pages/shipment/shipment_editor.dart delete mode 100644 lib/pages/shipment/shipment_info.dart delete mode 100644 lib/pages/shipment/shipment_pack.dart delete mode 100644 lib/pages/shipment/widgets.dart diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index 4fa9b95..623a9f0 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -433,6 +433,8 @@ "FCSshipment.ship.confirm":"Ship this shipment?", "FCSshipment.cancel.btn":"Cancel this shipment", "FCSshipment.cancel.confirm":"Cancel this shipment?", + "FCSshipment.deliver.btn":"Deliver this shipment", + "FCSshipment.deliver.confrim":"Deliver this shipment?", "FCSshipment.carton":"Cartons", "FCSshipment.package":"Packages", "FCSshipment.process.confirm":"Process this shipment?", diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index a2647be..78afcdd 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -426,8 +426,8 @@ "FCSshipment.cargo_manifest":"ကုန်ပစ္စည်းကိုဒေါင်းမည်", "FCSshipment.create":"တင်ပို့ခြင်းအသစ်ပြုလုပ်မည်", "FCSshipment.update":"တင်ပို့ခြင်းပြုပြင်မည်", - "FCSshipment.ship.btn":"ပို့ဆောင်နေသည်", - "FCSshipment.process.btn":"လုပ်ဆောင်နေသည်", + "FCSshipment.ship.btn":"ပို့ဆောင်မည်", + "FCSshipment.process.btn":"လုပ်ဆောင်မည်", "FCSshipment.arrive.btn":"ရောက်ရှိသည်", "FCSshipment.invoiced.btn":"ပြေစာယူသည်", "FCSshipment.ship.confirm":"Ship this shipment?", @@ -436,6 +436,8 @@ "FCSshipment.popupmenu.all":"All shipments", "FCSshipment.popupmenu.active":"Active shipments", "FCSshipment.popupmenu.shipped":"Shipped shipments", + "FCSshipment.deliver.btn":"ပို့ဆောင်မည်", + "FCSshipment.deliver.confrim":"Deliver this shipment?", "FCSshipment.carton":"FCS ပုံးများ", "FCSshipment.package":"FCS အထုပ်", "FCSshipment.process.confirm":"လုပ်ငန်းစဉ်ကို အတည်ပြုပါ ?", diff --git a/lib/app.dart b/lib/app.dart index 7b739ba..50e8f66 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -20,7 +20,6 @@ import 'package:fcs/pages/payment_methods/model/payment_method_model.dart'; import 'package:fcs/pages/pickup/model/pickup_model.dart'; import 'package:fcs/pages/processing/model/processing_model.dart'; import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; import 'package:fcs/pages/main/splash_page.dart'; import 'package:fcs/pages/staff/model/staff_model.dart'; import 'package:fcs/pages/term/model/term_model.dart'; @@ -54,7 +53,6 @@ class _AppState extends State { final PaymentMethodModel paymentMethodModel = new PaymentMethodModel(); final FcsShipmentModel fcsShipmentModel = new FcsShipmentModel(); final LanguageModel lanuguageModel = new LanguageModel(); - final ShipmentModel shipmentModel = new ShipmentModel(); final ShipmentRateModel shipmentRateModel = new ShipmentRateModel(); final CartonModel boxModel = new CartonModel(); final MessageModel messageModel = new MessageModel(); @@ -93,7 +91,6 @@ class _AppState extends State { ..addModel(discountModel) ..addModel(shipmentRateModel) ..addModel(boxModel) - ..addModel(shipmentModel) ..addModel(invoiceModel) ..addModel(marketModel) ..addModel(deliveryModel) @@ -135,7 +132,6 @@ class _AppState extends State { ChangeNotifierProvider.value(value: mainModel), ChangeNotifierProvider.value(value: staffModel), ChangeNotifierProvider.value(value: lanuguageModel), - ChangeNotifierProvider.value(value: shipmentModel), ChangeNotifierProvider.value(value: shipmentRateModel), ChangeNotifierProvider.value(value: deliveryAddressModel), ChangeNotifierProvider.value(value: packageModel), @@ -167,7 +163,7 @@ class _AppState extends State { theme: ThemeData( // useMaterial3: false, textSelectionTheme: - const TextSelectionThemeData(cursorColor: primaryColor), + const TextSelectionThemeData(cursorColor: primaryColor), dividerTheme: DividerThemeData(color: Colors.grey.shade200), colorScheme: ColorScheme.light(primary: Colors.white), dialogTheme: DialogTheme( diff --git a/lib/constants.dart b/lib/constants.dart index 9e63128..3881dd4 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -1,3 +1,5 @@ +// ignore_for_file: constant_identifier_names + const uploadPhotoLimit = 10; const shipmentCountForCartonFilter = 10; const resendCountSec = 30; @@ -61,6 +63,7 @@ const fcs_shipment_processed_status = "processed"; const fcs_shipment_shipped_status = "shipped"; const fcs_shipment_arrived_status = "arrived"; const fcs_shipment_invoiced_status = "invoiced"; +const fcs_shipment_delivered_status = "delivered"; // Package status const package_received_status = "received"; diff --git a/lib/data/provider/shipment_data_provider.dart b/lib/data/provider/shipment_data_provider.dart deleted file mode 100644 index 44479e3..0000000 --- a/lib/data/provider/shipment_data_provider.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'dart:async'; - -import 'package:fcs/domain/entities/shipment.dart'; -import 'package:fcs/helpers/api_helper.dart'; -import 'package:fcs/helpers/firebase_helper.dart'; -import 'package:logging/logging.dart'; - -class ShipmentDataProvider { - final log = Logger('ShipmentDataProvider'); - - static final ShipmentDataProvider instance = ShipmentDataProvider._(); - ShipmentDataProvider._(); - - Future createShipment(Shipment shipment) async { - return await requestAPI("/shipments", "POST", - payload: shipment.toMap(), token: await getToken()); - } - - Future updateShipment(Shipment shipment) async { - return await requestAPI("/shipments", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future cancelShipment(Shipment shipment) async { - return await requestAPI("/shipments/cancel", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future assignShipment(Shipment shipment) async { - return await requestAPI("/shipments/assign", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future completeAssignShipment(Shipment shipment) async { - return await requestAPI("/shipments/assign/complete", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future completePickupShipment(Shipment shipment) async { - return await requestAPI("/shipments/pickup/complete", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future packShipment(Shipment shipment) async { - return await requestAPI("/shipments/pack", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future completePackShipment(Shipment shipment) async { - return await requestAPI("/shipments/pack/complete", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future confirmShipment(Shipment shipment) async { - return await requestAPI("/shipments/confirm", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future completeConfirmShipment(Shipment shipment) async { - return await requestAPI("/shipments/confirm/complete", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future completeReceiveShipment(Shipment shipment) async { - return await requestAPI("/shipments/receive/complete", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future pickupShipment(Shipment shipment) async { - return await requestAPI("/shipment_pickup", "PUT", - payload: shipment.toMap(), token: await getToken()); - } - - Future receiveShipment(Shipment shipment) async { - return await requestAPI("/shipment_receive", "PUT", - payload: shipment.toMap(), token: await getToken()); - } -} diff --git a/lib/data/services/services.dart b/lib/data/services/services.dart index 6310578..5bd07b4 100644 --- a/lib/data/services/services.dart +++ b/lib/data/services/services.dart @@ -7,7 +7,6 @@ import 'package:fcs/data/provider/invoice_data_provider.dart'; import 'package:fcs/data/provider/package_data_provider.dart'; import 'package:fcs/data/provider/pickup_data_provider.dart'; import 'package:fcs/data/provider/rate_data_provider.dart'; -import 'package:fcs/data/provider/shipment_data_provider.dart'; import 'package:fcs/data/provider/user_data_provider.dart'; import 'package:fcs/data/services/carton_imp.dart'; import 'package:fcs/data/services/carton_service.dart'; @@ -21,8 +20,6 @@ import 'package:fcs/data/services/pickup_imp.dart'; import 'package:fcs/data/services/pickup_service.dart'; import 'package:fcs/data/services/rate_imp.dart'; import 'package:fcs/data/services/rate_service.dart'; -import 'package:fcs/data/services/shipment_imp.dart'; -import 'package:fcs/data/services/shipment_service.dart'; import '../../domain/entities/setting.dart'; import 'auth_imp.dart'; @@ -49,7 +46,6 @@ class Services { late FcsShipmentService _fcsShipmentService; late DeliveryAddressService _deliveryAddressService; late RateService _rateService; - late ShipmentService _shipmentService; late CartonService _cartonService; late InvoiceService _invoiceService; late PickupService _pickupService; @@ -72,9 +68,6 @@ class Services { deliveryAddressDataProvider: DeliveryAddressDataProvider()); _rateService = RateServiceImp( rateDataProvider: RateDataProvider.instance, connectivity: null); - _shipmentService = ShipmentServiceImp( - shipmentDataProvider: ShipmentDataProvider.instance, - connectivity: null); _cartonService = CartonServiceImp( cartonDataProvider: CartonDataProvider.instance, connectivity: null); _invoiceService = InvoiceServiceImp( @@ -91,7 +84,6 @@ class Services { FcsShipmentService get fcsShipmentService => _fcsShipmentService; DeliveryAddressService get deliveryAddressService => _deliveryAddressService; RateService get rateService => _rateService; - ShipmentService get shipmentService => _shipmentService; CartonService get cartonService => _cartonService; InvoiceService get invoiceService => _invoiceService; PickupService get pickupService => _pickupService; diff --git a/lib/data/services/shipment_imp.dart b/lib/data/services/shipment_imp.dart deleted file mode 100644 index 0b3a784..0000000 --- a/lib/data/services/shipment_imp.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:fcs/data/provider/shipment_data_provider.dart'; -import 'package:fcs/data/services/shipment_service.dart'; -import 'package:fcs/domain/entities/connectivity.dart'; -import 'package:fcs/domain/entities/shipment.dart'; - -class ShipmentServiceImp implements ShipmentService { - ShipmentServiceImp({ - required this.shipmentDataProvider, - required this.connectivity, - }); - - final Connectivity? connectivity; - final ShipmentDataProvider shipmentDataProvider; - - @override - Future cancelShipment(Shipment shipment) { - return shipmentDataProvider.cancelShipment(shipment); - } - - @override - Future confirmShipment(Shipment shipment) { - return shipmentDataProvider.confirmShipment(shipment); - } - - @override - Future createShipment(Shipment shipment) { - return shipmentDataProvider.createShipment(shipment); - } - - @override - Future pickupShipment(Shipment shipment) { - return shipmentDataProvider.pickupShipment(shipment); - } - - @override - Future receiveShipment(Shipment shipment) { - return shipmentDataProvider.receiveShipment(shipment); - } - - @override - Future updateShipment(Shipment shipment) { - return shipmentDataProvider.updateShipment(shipment); - } - - @override - Future assignShipment(Shipment shipment) { - return shipmentDataProvider.assignShipment(shipment); - } - - @override - Future completeAssignShipment(Shipment shipment) { - return shipmentDataProvider.completeAssignShipment(shipment); - } - - @override - Future completePickupShipment(Shipment shipment) { - return shipmentDataProvider.completePickupShipment(shipment); - } - - @override - Future completePackShipment(Shipment shipment) { - return shipmentDataProvider.completePackShipment(shipment); - } - - @override - Future packShipment(Shipment shipment) { - return shipmentDataProvider.packShipment(shipment); - } - - @override - Future completeConfirmShipment(Shipment shipment) { - return shipmentDataProvider.completeConfirmShipment(shipment); - } - - @override - Future completeReceiveShipment(Shipment shipment) { - return shipmentDataProvider.completeReceiveShipment(shipment); - } -} diff --git a/lib/data/services/shipment_service.dart b/lib/data/services/shipment_service.dart deleted file mode 100644 index 7761416..0000000 --- a/lib/data/services/shipment_service.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:fcs/domain/entities/shipment.dart'; - -abstract class ShipmentService { - Future createShipment(Shipment shipment); - Future updateShipment(Shipment shipment); - Future cancelShipment(Shipment shipment); - Future confirmShipment(Shipment shipment); - Future completeConfirmShipment(Shipment shipment); - Future completeReceiveShipment(Shipment shipment); - Future pickupShipment(Shipment shipment); - Future receiveShipment(Shipment shipment); - Future assignShipment(Shipment shipment); - Future completeAssignShipment(Shipment shipment); - Future completePickupShipment(Shipment shipment); - Future packShipment(Shipment shipment); - Future completePackShipment(Shipment shipment); -} diff --git a/lib/domain/entities/fcs_shipment.dart b/lib/domain/entities/fcs_shipment.dart index 5e6c604..f894a79 100644 --- a/lib/domain/entities/fcs_shipment.dart +++ b/lib/domain/entities/fcs_shipment.dart @@ -16,35 +16,38 @@ class FcsShipment { String? destinationPortName; String? status; String? reportName; + int packageCount; + int cartonCount; - FcsShipment({ - this.id, - this.shipmentNumber, - this.cutoffDate, - this.shipmentTypeId, - this.shipmentTypeName, - this.status, - this.etaDate, - this.departureDate, - this.consigneeId, - this.consigneeName, - this.loadingPortId, - this.loadingPortName, - this.destinationPortId, - this.destinationPortName, - this.reportName, - }); + FcsShipment( + {this.id, + this.shipmentNumber, + this.cutoffDate, + this.shipmentTypeId, + this.shipmentTypeName, + this.status, + this.etaDate, + this.departureDate, + this.consigneeId, + this.consigneeName, + this.loadingPortId, + this.loadingPortName, + this.destinationPortId, + this.destinationPortName, + this.reportName, + this.packageCount = 0, + this.cartonCount = 0}); factory FcsShipment.fromMap(Map map, String docID) { - var _cutoffDate = + var cutoffDate = map['cutoff_date'] == null ? null : (map['cutoff_date'] as Timestamp); - var _arrivalDate = + var arrivalDate = map['eta_date'] == null ? null : (map['eta_date'] as Timestamp); return FcsShipment( id: docID, - cutoffDate: _cutoffDate != null ? _cutoffDate.toDate() : null, - etaDate: _arrivalDate != null ? _arrivalDate.toDate() : null, + cutoffDate: cutoffDate?.toDate(), + etaDate: arrivalDate?.toDate(), shipmentNumber: map['shipment_number'], shipmentTypeId: map['shipment_type_id'] ?? "", shipmentTypeName: map['shipment_type_name'], @@ -54,7 +57,9 @@ class FcsShipment { loadingPortId: map['loading_port_id'], loadingPortName: map['loading_port_name'], destinationPortId: map['destination_port_id'], - destinationPortName: map['destination_port_name']); + destinationPortName: map['destination_port_name'], + packageCount: map['package_count'] ?? 0, + cartonCount: map['carton_count'] ?? 0); } Map toMap() { @@ -71,13 +76,13 @@ class FcsShipment { } bool isChangedForEdit(FcsShipment fcsShipment) { - return fcsShipment.shipmentNumber != this.shipmentNumber || - fcsShipment.cutoffDate != this.cutoffDate || - fcsShipment.etaDate != this.etaDate || - fcsShipment.shipmentTypeId != this.shipmentTypeId || - fcsShipment.consigneeId != this.consigneeId || - fcsShipment.loadingPortId != this.loadingPortId || - fcsShipment.destinationPortId != this.destinationPortId; + return fcsShipment.shipmentNumber != shipmentNumber || + fcsShipment.cutoffDate != cutoffDate || + fcsShipment.etaDate != etaDate || + fcsShipment.shipmentTypeId != shipmentTypeId || + fcsShipment.consigneeId != consigneeId || + fcsShipment.loadingPortId != loadingPortId || + fcsShipment.destinationPortId != destinationPortId; } @override diff --git a/lib/domain/entities/package.dart b/lib/domain/entities/package.dart index eb94e4f..c57e8ec 100644 --- a/lib/domain/entities/package.dart +++ b/lib/domain/entities/package.dart @@ -74,17 +74,20 @@ class Package { this.cartonIds = const []}); factory Package.fromMap(Map map, String docID) { - var _currentStatusDate = (map['status_date'] as Timestamp); + var currentStatusDate = + map['status_date'] != null ? (map['status_date'] as Timestamp) : null; - List _shipmentStatus = List.from(map['all_status']) + List shipmentStatus = List.from(map['all_status']) .map((e) => ShipmentStatus.fromMap(Map.from(e))) .toList(); - List _photoUrls = + List photoUrls = map['photo_urls'] == null ? [] : List.from(map['photo_urls']); - var da = map['delivery_address']; - var _da = da != null ? DeliveryAddress.fromMap(da, da["id"]) : null; + var deliveryAddress = map['delivery_address']; + var da = deliveryAddress != null + ? DeliveryAddress.fromMap(deliveryAddress, deliveryAddress["id"]) + : null; - List cartonIds = + List cartonIds = map['carton_ids'] == null ? [] : List.from(map['carton_ids']); return Package( @@ -101,10 +104,10 @@ class Package { senderFCSID: map['sender_fcs_id'], senderName: map['sender_name'], senderPhoneNumber: map['sender_phone_number'], - deliveryAddress: _da, - currentStatusDate: _currentStatusDate.toDate().toLocal(), - photoUrls: _photoUrls, - shipmentHistory: _shipmentStatus, + deliveryAddress: da, + currentStatusDate: currentStatusDate?.toDate().toLocal(), + photoUrls: photoUrls, + shipmentHistory: shipmentStatus, cartonIds: cartonIds); } diff --git a/lib/domain/vo/local_popupmenu.dart b/lib/domain/vo/local_popupmenu.dart index 482793e..4926898 100644 --- a/lib/domain/vo/local_popupmenu.dart +++ b/lib/domain/vo/local_popupmenu.dart @@ -13,13 +13,14 @@ class LocalPopupMenu { this.highlight = false, this.enabled = true}); } + List shipFiteringMenu = [ - LocalPopupMenu(id: 0, text :"All"), + LocalPopupMenu(id: 0, text: "All"), LocalPopupMenu(id: 1, text: "Pending"), LocalPopupMenu(id: 2, text: "Processed"), LocalPopupMenu(id: 3, text: "Shipped"), LocalPopupMenu(id: 4, text: "Arrived"), LocalPopupMenu(id: 5, text: "Invoiced"), + LocalPopupMenu(id: 7, text: "Delivered"), LocalPopupMenu(id: 6, text: "Canceled"), ]; - diff --git a/lib/domain/vo/shipment_status.dart b/lib/domain/vo/shipment_status.dart index 7783190..1cd833e 100644 --- a/lib/domain/vo/shipment_status.dart +++ b/lib/domain/vo/shipment_status.dart @@ -2,22 +2,22 @@ import 'package:cloud_firestore/cloud_firestore.dart'; class ShipmentStatus { String status; - DateTime date; + DateTime? date; bool? done; String? staffId; String? staffName; ShipmentStatus( {required this.status, - required this.date, + this.date, this.done, this.staffId, this.staffName}); factory ShipmentStatus.fromMap(Map map) { - var _date = (map['date'] as Timestamp); + var _date = map['date'] != null ? (map['date'] as Timestamp) : null; return ShipmentStatus( status: map['status'], - date: _date.toDate(), + date: _date?.toDate(), done: map['done'], staffId: map['staff_id'], staffName: map['staff_name']); diff --git a/lib/pages/carton/carton_filter.dart b/lib/pages/carton/carton_filter.dart index 6c1344a..d95a601 100644 --- a/lib/pages/carton/carton_filter.dart +++ b/lib/pages/carton/carton_filter.dart @@ -32,11 +32,12 @@ class _CartonFilterState extends State { List statusList = [ all_status, - carton_processing_status, + carton_packed_status, carton_shipped_status, carton_arrived_status, carton_invoiced_status, - carton_canceled_status + carton_delivered_status, + carton_canceled_status, ]; final TextEditingController _consigneeCtl = TextEditingController(); diff --git a/lib/pages/carton/carton_info.dart b/lib/pages/carton/carton_info.dart index 873e754..1dcaab4 100644 --- a/lib/pages/carton/carton_info.dart +++ b/lib/pages/carton/carton_info.dart @@ -376,9 +376,11 @@ class _CartonInfoState extends State { labelColor: primaryColor, arrowColor: primaryColor, actions: [ - IconButton( - icon: Icon(Icons.edit, color: primaryColor), - onPressed: _gotoEditor), + _carton.status == carton_packed_status + ? IconButton( + icon: Icon(Icons.edit, color: primaryColor), + onPressed: _gotoEditor) + : const SizedBox(), ]), body: Container( padding: const EdgeInsets.only(left: 20, right: 20), @@ -452,7 +454,9 @@ class _CartonInfoState extends State { _carton.photoUrls.isNotEmpty ? const SizedBox(height: 40) : const SizedBox(), - deleteBtn, + _carton.status == carton_packed_status + ? deleteBtn + : const SizedBox(), const SizedBox(height: 20) ])))); } diff --git a/lib/pages/carton/model/carton_selection_model.dart b/lib/pages/carton/model/carton_selection_model.dart index c78f367..9f6dc3a 100644 --- a/lib/pages/carton/model/carton_selection_model.dart +++ b/lib/pages/carton/model/carton_selection_model.dart @@ -46,8 +46,8 @@ class CartonSelectionModel extends BaseModel { String path = "/$cartons_collection"; Query query = FirebaseFirestore.instance .collection(path) - // .where("fcs_shipment_id", isEqualTo: shipmentId) - // .where("status", isEqualTo: carton_processing_status) + .where("fcs_shipment_id", isEqualTo: shipmentId) + .where("status", isEqualTo: carton_packed_status) .where("is_deleted", isEqualTo: false); if (term != "") { diff --git a/lib/pages/carton/model/package_selection_model.dart b/lib/pages/carton/model/package_selection_model.dart index eea831e..5ac2bb2 100644 --- a/lib/pages/carton/model/package_selection_model.dart +++ b/lib/pages/carton/model/package_selection_model.dart @@ -65,8 +65,8 @@ class PackageSelectionModel extends BaseModel { String path = "/$packages_collection"; Query query = FirebaseFirestore.instance .collection(path) - // .where("fcs_shipment_id", isEqualTo: shipmentId) - // .where("status", isEqualTo: package_processed_status) + .where("status", + whereIn: [package_processed_status, package_packed_status]) .where("sender_id", isEqualTo: senderId) .where("user_id", isEqualTo: consigneeId) .where("is_deleted", isEqualTo: false); diff --git a/lib/pages/chat/message_detail.dart b/lib/pages/chat/message_detail.dart index e566ff9..f8df737 100644 --- a/lib/pages/chat/message_detail.dart +++ b/lib/pages/chat/message_detail.dart @@ -1,6 +1,5 @@ import 'package:fcs/constants.dart'; import 'package:fcs/domain/entities/package.dart'; -import 'package:fcs/domain/entities/shipment.dart'; import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/domain/vo/message.dart'; import 'package:fcs/helpers/theme.dart'; @@ -12,8 +11,6 @@ import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/package/model/package_model.dart'; import 'package:fcs/pages/package/package_info.dart'; import 'package:fcs/pages/profile/profile_page.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; -import 'package:fcs/pages/shipment/shipment_info.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -193,20 +190,5 @@ class MessageDetail extends StatelessWidget { builder: (context) => CustomerEditor(customer: user))); } } - if (message.messageType == message_type_shipment && - message.messageID != null && - message.messageID != "") { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - Shipment? s = await shipmentModel.getShipment(message.messageID!); - if (s == null) return; - await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ShipmentInfo( - shipment: s, - isCustomer: true, - ))); - } } } diff --git a/lib/pages/fcs_shipment/fcs_shipment_info.dart b/lib/pages/fcs_shipment/fcs_shipment_info.dart index f642a68..db1559d 100644 --- a/lib/pages/fcs_shipment/fcs_shipment_info.dart +++ b/lib/pages/fcs_shipment/fcs_shipment_info.dart @@ -29,6 +29,8 @@ class FcsShipmentInfo extends StatefulWidget { class _FcsShipmentInfoState extends State { var dateFormatter = new DateFormat('dd MMM yyyy'); + final NumberFormat numberFormatter = NumberFormat("#,###"); + late FcsShipment _fcsShipment; bool _isLoading = false; TextEditingController _shipmentNumberController = new TextEditingController(); @@ -83,13 +85,15 @@ class _FcsShipmentInfoState extends State { labelTextKey: "FCSshipment.ETA", iconData: Icons.date_range, ); + final cartonBox = DisplayText( - //text: _arrivalDateController.text, + text: numberFormatter.format(_fcsShipment.cartonCount), labelTextKey: "FCSshipment.carton", iconData: MaterialCommunityIcons.package, ); + final packageBox = DisplayText( - //text: _arrivalDateController.text, + text: numberFormatter.format(_fcsShipment.packageCount), labelTextKey: "FCSshipment.package", iconData: Octicons.package, ); @@ -131,6 +135,7 @@ class _FcsShipmentInfoState extends State { callBack: _ship, ), ); + final processBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( @@ -138,6 +143,7 @@ class _FcsShipmentInfoState extends State { callBack: _process, ), ); + final arriveBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( @@ -145,6 +151,7 @@ class _FcsShipmentInfoState extends State { callBack: _arrive, ), ); + final invoiceBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( @@ -153,6 +160,14 @@ class _FcsShipmentInfoState extends State { ), ); + final deliverBtn = Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: LocalButton( + textKey: "FCSshipment.deliver.btn", + callBack: _deliver, + ), + ); + final cancelBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( @@ -228,6 +243,9 @@ class _FcsShipmentInfoState extends State { _fcsShipment.status == fcs_shipment_arrived_status ? invoiceBtn : Container(), + _fcsShipment.status == fcs_shipment_invoiced_status + ? deliverBtn + : Container(), SizedBox(height: 20) ]), ), @@ -387,6 +405,28 @@ class _FcsShipmentInfoState extends State { } } + _deliver() { + showConfirmDialog(context, "FCSshipment.deliver.confrim", () { + _deliverFcsShipment(); + }); + } + + _deliverFcsShipment() async { + setState(() { + _isLoading = true; + }); + try { + await context.read().deliver(_fcsShipment.id!); + Navigator.pop(context, true); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _isLoading = false; + }); + } + } + _showPDF(int id) async { setState(() { _isLoading = true; diff --git a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart index de1c285..72254b1 100644 --- a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart +++ b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart @@ -95,6 +95,13 @@ class FcsShipmentModel extends BaseModel { pageQuery.where("status", isEqualTo: fcs_shipment_canceled_status); } + // delivered status + if (index == 7) { + col = col.where("status", isEqualTo: fcs_shipment_delivered_status); + pageQuery = + pageQuery.where("status", isEqualTo: fcs_shipment_delivered_status); + } + pageQuery = pageQuery.orderBy("update_time", descending: true); fcsShipments?.close(); @@ -272,6 +279,11 @@ class FcsShipmentModel extends BaseModel { .updateFcsShipmentStatus(id, fcs_shipment_canceled_status); } + Future deliver(String id) { + return Services.instance.fcsShipmentService + .updateFcsShipmentStatus(id, fcs_shipment_delivered_status); + } + Future report(FcsShipment fcsShipment) { return Services.instance.fcsShipmentService.report(fcsShipment); } @@ -285,7 +297,8 @@ class FcsShipmentModel extends BaseModel { fcs_shipment_processed_status, fcs_shipment_shipped_status, fcs_shipment_arrived_status, - fcs_shipment_invoiced_status + fcs_shipment_invoiced_status, + fcs_shipment_delivered_status ]) .where("is_deleted", isEqualTo: false) .orderBy("update_time", descending: true) diff --git a/lib/pages/invoice/editor/invoice_editor.dart b/lib/pages/invoice/editor/invoice_editor.dart index 35b9c34..b737c9f 100644 --- a/lib/pages/invoice/editor/invoice_editor.dart +++ b/lib/pages/invoice/editor/invoice_editor.dart @@ -22,7 +22,6 @@ import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/payment_methods/model/payment_method_model.dart'; import 'package:fcs/pages/rates/custom_list.dart'; import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/fcs_icons.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; @@ -104,8 +103,8 @@ class _InvoiceEditorState extends State { } _loadShipments() async { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); + InvoiceModel shipmentModel = + Provider.of(context, listen: false); List? shipments = await shipmentModel.getShipmentWithHandlingFee( widget.fcsShipment!.id!, widget.customer!.id!); shipments!.forEach((s) { @@ -361,14 +360,6 @@ class _InvoiceEditorState extends State { ); } - _addCustom(CustomDuty customDuty) { - if (customDuty == null) return; - setState(() { - _invoice!.customDuties.remove(customDuty); - _invoice!.customDuties.add(customDuty); - }); - } - _addShipment(Shipment shipment) { if (shipment == null) return; shipment.isSelected = true; diff --git a/lib/pages/invoice/model/invoice_model.dart b/lib/pages/invoice/model/invoice_model.dart index 13ace1f..2434d7b 100644 --- a/lib/pages/invoice/model/invoice_model.dart +++ b/lib/pages/invoice/model/invoice_model.dart @@ -11,6 +11,7 @@ import 'package:fcs/pages/main/model/base_model.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as Path; +import '../../../domain/entities/shipment.dart'; import '../../../pagination/paginator_listener.dart'; class InvoiceModel extends BaseModel { @@ -105,4 +106,28 @@ class InvoiceModel extends BaseModel { Future cancelInvoice(Invoice invoice) { return Services.instance.invoiceService.cancelInvoice(invoice); } + + 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; + } } diff --git a/lib/pages/main/home_page.dart b/lib/pages/main/home_page.dart index 6e17e53..500e27d 100644 --- a/lib/pages/main/home_page.dart +++ b/lib/pages/main/home_page.dart @@ -360,10 +360,10 @@ class _HomePageState extends State { // if (user.hasShipment()) widgetsFcs.add(pickupBtnFcs); // if (user.hasInvoices()) widgetsFcs.add(invoicesBtnFcs); - // if (user.hasFcsShipments()) widgetsFcs.add(fcsShipmentBtn); + if (user.hasFcsShipments()) widgetsFcs.add(fcsShipmentBtn); if (user.hasReceiving()) widgetsFcs.add(receivingBtn); if (user.hasProcessing()) widgetsFcs.add(processingBtn); - // if (user.hasCarton()) widgetsFcs.add(cartonBtn); + if (user.hasCarton()) widgetsFcs.add(cartonBtn); // if (user.hasDeliveries()) widgetsFcs.add(deliveryBtn); if (user.hasCustomers()) widgetsFcs.add(customersBtn); if (user.hasAdmin()) widgetsFcs.add(discountBtn); diff --git a/lib/pages/shipment/box_row.dart b/lib/pages/shipment/box_row.dart deleted file mode 100644 index d4793a2..0000000 --- a/lib/pages/shipment/box_row.dart +++ /dev/null @@ -1,115 +0,0 @@ -import 'package:fcs/domain/entities/carton.dart'; -import 'package:flutter/material.dart'; - -class BoxRow extends StatelessWidget { - final Carton box; - - const BoxRow({Key? key, required this.box}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.only(left: 10), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: new Padding( - padding: const EdgeInsets.symmetric(vertical: 10.0), - child: new Row( - children: [ - new Expanded( - child: new Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - box.deliveryAddress?.fullName ?? "", - style: new TextStyle( - fontSize: 15.0, - color: Colors.black, - fontWeight: FontWeight.bold), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - box.deliveryAddress?.addressLine1 ?? "", - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - box.deliveryAddress?.addressLine2 ?? "", - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - box.deliveryAddress?.city ?? "", - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - box.deliveryAddress?.state ?? "", - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - box.deliveryAddress?.phoneNumber ?? "", - style: new TextStyle( - fontSize: 14.0, color: Colors.grey), - ), - ), - ], - ), - ), - ], - ), - ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - "${box.cartonNumber ?? ""}", - style: new TextStyle(fontSize: 15.0, color: Colors.black), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - "L${box.length}xW${box.width}xH${box.height}", - style: new TextStyle(fontSize: 15.0, color: Colors.black), - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: new Text( - "Actual Weight:${box.actualWeight.toStringAsFixed(2)}lb", - style: new TextStyle(fontSize: 14.0, color: Colors.grey), - ), - ), - ], - ) - ], - ), - ], - ), - ); - } -} diff --git a/lib/pages/shipment/cargo_type_editor.dart b/lib/pages/shipment/cargo_type_editor.dart deleted file mode 100644 index 1d6572c..0000000 --- a/lib/pages/shipment/cargo_type_editor.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'package:fcs/domain/entities/cargo_type.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; -import 'package:fcs/pages/widgets/input_text.dart'; -import 'package:fcs/pages/widgets/local_dropdown.dart'; -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:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:provider/provider.dart'; - -class CargoTypeEditor extends StatefulWidget { - final CargoType? cargo; - CargoTypeEditor({this.cargo}); - - @override - _CargoTypeEditorState createState() => _CargoTypeEditorState(); -} - -class _CargoTypeEditorState extends State { - TextEditingController _weightController = new TextEditingController(); - - bool _isLoading = false; - CargoType? _cargo; - - @override - void initState() { - super.initState(); - if (widget.cargo != null) { - _cargo = widget.cargo; - _weightController.text = _cargo!.weight.toStringAsFixed(2); - } else { - _loadDefalut(); - } - } - - _loadDefalut() { - ShipmentRateModel shipmentRateModel = - Provider.of(context, listen: false); - _cargo = shipmentRateModel.rate.defaultCargoType.clone(); - } - - @override - void dispose() { - super.dispose(); - } - - @override - Widget build(BuildContext context) { - ShipmentRateModel shipmentRateModel = - Provider.of(context); - List cargos = shipmentRateModel.rate.cargoTypes; - - final rateBox = InputText( - labelTextKey: 'cargo.weight', - iconData: FontAwesomeIcons.weightHanging, - textInputType: TextInputType.number, - controller: _weightController); - - var cargoTypeBox = LocalDropdown( - callback: (v) { - setState(() { - _cargo = v; - }); - }, - labelKey: "cargo.type", - iconData: Icons.text_format, - selectedValue: _cargo!, - values: cargos, - ); - - final saveBtn = fcsButton( - context, - getLocalString(context, 'box.cargo.save.btn'), - callack: () { - _cargo!.weight = double.tryParse(_weightController.text) ?? 0; - Navigator.pop(context, _cargo); - }, - ); - return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: - new Icon(CupertinoIcons.back, color: primaryColor, size: 30), - onPressed: () => Navigator.of(context).pop(), - ), - shadowColor: Colors.transparent, - backgroundColor: Colors.white, - title: LocalText( - context, - "cargo.form.title", - fontSize: 20, - color: primaryColor, - )), - body: Container( - padding: EdgeInsets.all(18), - child: ListView( - shrinkWrap: true, - children: [ - cargoTypeBox, - rateBox, - SizedBox(height: 40), - saveBtn, - SizedBox(height: 20), - ], - ), - ), - ), - ); - } -} diff --git a/lib/pages/shipment/model/shipment_model.dart b/lib/pages/shipment/model/shipment_model.dart deleted file mode 100644 index 5c6612d..0000000 --- a/lib/pages/shipment/model/shipment_model.dart +++ /dev/null @@ -1,227 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:fcs/data/services/services.dart'; -import 'package:fcs/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); - } -} diff --git a/lib/pages/shipment/shipment_assign.dart b/lib/pages/shipment/shipment_assign.dart deleted file mode 100644 index c9347a2..0000000 --- a/lib/pages/shipment/shipment_assign.dart +++ /dev/null @@ -1,157 +0,0 @@ -import 'package:fcs/domain/entities/shipment.dart'; -import 'package:fcs/domain/entities/user.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; -import 'package:fcs/pages/staff/model/staff_model.dart'; -import 'package:fcs/pages/widgets/input_text.dart'; -import 'package:fcs/pages/widgets/local_button.dart'; -import 'package:fcs/pages/widgets/local_dropdown.dart'; -import 'package:fcs/pages/widgets/local_text.dart'; -import 'package:fcs/pages/widgets/local_title.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:intl/intl.dart'; -import 'package:provider/provider.dart'; - -import 'widgets.dart'; - -class ShipmentAssign extends StatefulWidget { - final Shipment? shipment; - ShipmentAssign({this.shipment}); - - @override - _ShipmentAssignState createState() => _ShipmentAssignState(); -} - -class _ShipmentAssignState extends State { - var dateFormatter = new DateFormat('dd MMM yyyy'); - var timeFormatter = new DateFormat('jm'); - - TextEditingController _fromTimeEditingController = - new TextEditingController(); - TextEditingController _toTimeEditingController = new TextEditingController(); - TextEditingController _pickupDate = new TextEditingController(); - TextEditingController _handlingFee = new TextEditingController(); - - Shipment? _shipment; - bool _isLoading = false; - var now = new DateTime.now(); - - User? _user; - List? _users; - - @override - void initState() { - super.initState(); - - _shipment = widget.shipment; - _loadUsers(); - - _fromTimeEditingController.text = _shipment!.pickupTimeStart!; - _toTimeEditingController.text = _shipment!.pickupTimeEnd!; - _pickupDate.text = dateFormatter.format(_shipment!.pickupDate ?? now); - _handlingFee.text = _shipment!.handlingFee.toString(); - } - - _loadUsers() async { - StaffModel staffModel = Provider.of(context, listen: false); - var users = await staffModel.getPickupEmployees(); - var selectUser = users.firstWhere((e) => e.id == _shipment!.pickupUserID); - setState(() { - _users = users; - _user = selectUser; - }); - } - - @override - Widget build(BuildContext context) { - final shipmentNumberBox = getShipmentNumberStatus(context, _shipment!); - - var usersBox = LocalDropdown( - callback: (v) { - setState(() { - _user = v; - }); - }, - labelKey: "shipment.staff", - iconData: MaterialCommunityIcons.worker, - display: (u) => u.name, - selectedValue: _user, - values: _users, - ); - - final assignBtn = LocalButton( - textKey: "shipment.assign.btn", - callBack: _save, - ); - final handlingFeeBox = InputText( - labelTextKey: "shipment.handling.fee", - controller: _handlingFee, - iconData: FontAwesome.truck, - ); - return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: new Icon( - CupertinoIcons.back, - color: primaryColor, - ), - onPressed: () => Navigator.of(context).pop(), - ), - shadowColor: Colors.transparent, - backgroundColor: Colors.white, - title: LocalText( - context, - "shipment.assign.title", - fontSize: 20, - color: primaryColor, - ), - ), - body: Padding( - padding: const EdgeInsets.all(10.0), - child: ListView( - children: [ - Center(child: shipmentNumberBox), - SizedBox( - height: 10, - ), - LocalTitle(textKey: "shipment.assign.for.pickup"), - usersBox, - handlingFeeBox, - SizedBox( - height: 10, - ), - assignBtn, - ], - ), - ), - ), - ); - } - - _save() async { - _shipment!.pickupUserID = this._user!.id; - _shipment!.handlingFee = double.tryParse(_handlingFee.text) ?? 0; - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.assignShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } -} diff --git a/lib/pages/shipment/shipment_box_editor.dart b/lib/pages/shipment/shipment_box_editor.dart deleted file mode 100644 index 76e27a7..0000000 --- a/lib/pages/shipment/shipment_box_editor.dart +++ /dev/null @@ -1,306 +0,0 @@ -import 'package:fcs/domain/entities/carton.dart'; -import 'package:fcs/domain/entities/cargo_type.dart'; -import 'package:fcs/domain/vo/delivery_address.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/shipment/cargo_type_editor.dart'; -import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; -import 'package:fcs/pages/main/model/main_model.dart'; -import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; -import 'package:fcs/pages/widgets/defalut_delivery_address.dart'; -import 'package:fcs/pages/widgets/delivery_address_selection.dart'; -import 'package:fcs/pages/widgets/display_text.dart'; -import 'package:fcs/pages/widgets/length_picker.dart'; -import 'package:fcs/pages/widgets/local_button.dart'; -import 'package:fcs/pages/widgets/local_text.dart'; -import 'package:fcs/pages/widgets/local_title.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'; - -class ShipmentBoxEditor extends StatefulWidget { - final Carton? box; - ShipmentBoxEditor({this.box}); - - @override - _ShipmentBoxEditorState createState() => _ShipmentBoxEditorState(); -} - -class _ShipmentBoxEditorState extends State { - TextEditingController _lengthCtl = new TextEditingController(); - TextEditingController _widthCtl = new TextEditingController(); - TextEditingController _heightCtl = new TextEditingController(); - - Carton? _box; - bool _isLoading = false; - late bool _isNew; - double volumetricRatio = 0; - double shipmentWeight = 0; - - @override - void initState() { - super.initState(); - - volumetricRatio = Provider.of(context, listen: false) - .rate - .volumetricRatio; - - if (widget.box != null) { - _box = widget.box; - _isNew = false; - _lengthCtl.text = _box!.length.toString(); - _widthCtl.text = _box!.width.toString(); - _heightCtl.text = _box!.height.toString(); - } else { - var shipmentModel = - Provider.of(context, listen: false); - - _isNew = true; - _box = Carton(cargoTypes: []); - _box!.deliveryAddress = shipmentModel.defalutAddress; - - _lengthCtl.text = "12"; - _widthCtl.text = "12"; - _heightCtl.text = "12"; - } - _lengthCtl.addListener(_calShipmentWeight); - _widthCtl.addListener(_calShipmentWeight); - _heightCtl.addListener(_calShipmentWeight); - _calShipmentWeight(); - } - - _calShipmentWeight() { - double l = double.parse(_lengthCtl.text); - double w = double.parse(_widthCtl.text); - double h = double.parse(_heightCtl.text); - setState(() { - shipmentWeight = (l * w * h / volumetricRatio).ceilToDouble(); - }); - } - - @override - Widget build(BuildContext context) { - var mainModel = Provider.of(context); - - final shipmentWeightBox = DisplayText( - labelTextKey: "shipment.box.shipment.weight", - text: shipmentWeight.toStringAsFixed(0), - iconData: MaterialCommunityIcons.weight, - ); - - final lengthBox = LengthPicker( - controller: _lengthCtl, - lableKey: "shipment.box.length", - ); - final widthBox = LengthPicker( - controller: _widthCtl, - lableKey: "shipment.box.width", - ); - final heightBox = LengthPicker( - controller: _heightCtl, - lableKey: "shipment.box.height", - ); - final dimBox = Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: Icon(FontAwesome.arrow_circle_right, color: primaryColor), - ), - SizedBox(child: lengthBox, width: 80), - SizedBox(child: widthBox, width: 80), - SizedBox(child: heightBox, width: 80), - ], - ); - final createBtn = LocalButton( - textKey: "shipment.box.add", - callBack: _creatCarton, - ); - return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: new Icon( - CupertinoIcons.back, - color: primaryColor, - ), - onPressed: () => Navigator.of(context).pop(), - ), - shadowColor: Colors.transparent, - backgroundColor: Colors.white, - title: LocalText( - context, - _isNew ? "boxes.create.title" : "box.edit.title", - fontSize: 20, - color: primaryColor, - ), - ), - body: Padding( - padding: const EdgeInsets.all(8.0), - child: ListView( - children: [ - LocalTitle( - textKey: "shipment.box.cargo.type", - trailing: IconButton( - icon: Icon( - Icons.add_circle, - color: primaryColor, - ), - onPressed: () async { - CargoType? cargo = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => CargoTypeEditor())); - if (cargo == null) return; - _addCargo(cargo); - }), - ), - DataTable( - headingRowHeight: 40, - showCheckboxColumn: false, - columns: [ - DataColumn( - label: LocalText( - context, - "cargo.type", - color: Colors.grey, - ), - ), - DataColumn( - label: LocalText( - context, - "cargo.weight", - color: Colors.grey, - ), - ), - ], - rows: getCargoRows(context), - ), - SizedBox( - height: 30, - ), - LocalTitle(textKey: "shipment.box.dimemsion"), - dimBox, - shipmentWeightBox, - LocalTitle(textKey: "shipment.box.delivery"), - DefaultDeliveryAddress( - deliveryAddress: _box!.deliveryAddress, - labelKey: "shipment.box.delivery", - onTap: () async { - DeliveryAddress? d = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => DeliveryAddressSelection( - deliveryAddress: _box!.deliveryAddress, - user: mainModel.user)), - ); - if (d == null) return; - setState(() { - _box!.deliveryAddress = d; - }); - }), - createBtn - ], - ), - ), - ), - ); - } - - List getCargoRows(BuildContext context) { - if (_box!.cargoTypes.isEmpty) { - return []; - } - double total = 0; - var rows = _box!.cargoTypes.map((c) { - total += c.weight; - return DataRow( - onSelectChanged: (bool? selected) async { - CargoType? cargo = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => CargoTypeEditor( - cargo: c, - ))); - if (cargo == null) return; - _addCargo(cargo); - }, - cells: [ - DataCell(new Text( - c.name == null ? "" : c.name!, - style: textStyle, - )), - DataCell( - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Text(c.weight.toStringAsFixed(2), style: textStyle), - IconButton( - icon: Icon( - Icons.remove_circle, - color: primaryColor, - ), - onPressed: () => {_removeCargo(c)}, - ) - ], - ), - ), - ], - ); - }).toList(); - - var totalRow = DataRow( - onSelectChanged: (bool? selected) {}, - cells: [ - DataCell(Align( - alignment: Alignment.centerRight, - child: LocalText( - context, - "shipment.cargo.total", - color: Colors.black87, - fontWeight: FontWeight.bold, - ), - )), - DataCell( - Padding( - padding: const EdgeInsets.only(right: 48.0), - child: Align( - alignment: Alignment.centerRight, - child: Text(total.toStringAsFixed(2), - style: TextStyle(fontWeight: FontWeight.bold))), - ), - ), - ], - ); - rows.add(totalRow); - return rows; - } - - _addCargo(CargoType? cargo) { - if (cargo == null) return; - setState(() { - _box!.cargoTypes.remove(cargo); - _box!.cargoTypes.add(cargo); - }); - } - - _removeCargo(CargoType cargo) { - setState(() { - _box!.cargoTypes.remove(cargo); - }); - } - - _creatCarton() { - double l = double.parse(_lengthCtl.text); - double w = double.parse(_widthCtl.text); - double h = double.parse(_heightCtl.text); - _box!.length = l; - _box!.width = w; - _box!.height = h; - Navigator.pop(context, _box); - } -} diff --git a/lib/pages/shipment/shipment_confirm.dart b/lib/pages/shipment/shipment_confirm.dart deleted file mode 100644 index b7e45fc..0000000 --- a/lib/pages/shipment/shipment_confirm.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'package:fcs/domain/entities/shipment.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; -import 'package:fcs/pages/widgets/input_text.dart'; -import 'package:fcs/pages/widgets/local_button.dart'; -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:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; - -import 'widgets.dart'; - -class ShipmentConfirm extends StatefulWidget { - final Shipment? shipment; - ShipmentConfirm({this.shipment}); - - @override - _ShipmentConfirmState createState() => _ShipmentConfirmState(); -} - -class _ShipmentConfirmState extends State { - var dateFormatter = new DateFormat('dd MMM yyyy'); - var timeFormatter = new DateFormat('jm'); - TextEditingController _handlingFee = new TextEditingController(); - - Shipment? _shipment; - bool _isLoading = false; - var now = new DateTime.now(); - - @override - void initState() { - super.initState(); - - _shipment = widget.shipment; - _handlingFee.text = _shipment!.handlingFee.toString(); - } - - @override - Widget build(BuildContext context) { - final shipmentNumberBox = getShipmentNumberStatus(context, _shipment!); - - final handlingFeeBox = InputText( - labelTextKey: "shipment.handling.fee", - controller: _handlingFee, - iconData: FontAwesomeIcons.truck, - ); - final confirmbtn = LocalButton( - textKey: "shipment.confirm.btn", - callBack: _save, - ); - return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: new Icon( - CupertinoIcons.back, - color: primaryColor, - ), - onPressed: () => Navigator.of(context).pop(), - ), - shadowColor: Colors.transparent, - backgroundColor: Colors.white, - title: LocalText( - context, - "shipment.confirm.menuitem", - fontSize: 20, - color: primaryColor, - ), - ), - body: Padding( - padding: const EdgeInsets.all(10.0), - child: ListView( - children: [ - Center(child: shipmentNumberBox), - SizedBox( - height: 10, - ), - SizedBox( - height: 10, - ), - handlingFeeBox, - confirmbtn, - ], - ), - ), - ), - ); - } - - _save() async { - _shipment!.handlingFee = double.tryParse(_handlingFee.text) ?? 0; - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.confirmShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } -} diff --git a/lib/pages/shipment/shipment_editor.dart b/lib/pages/shipment/shipment_editor.dart deleted file mode 100644 index 98f969e..0000000 --- a/lib/pages/shipment/shipment_editor.dart +++ /dev/null @@ -1,334 +0,0 @@ -import 'package:fcs/constants.dart'; -import 'package:fcs/domain/entities/carton.dart'; -import 'package:fcs/domain/entities/shipment.dart'; -import 'package:fcs/domain/vo/delivery_address.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; -import 'package:fcs/pages/main/model/main_model.dart'; -import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; -import 'package:fcs/pages/widgets/defalut_delivery_address.dart'; -import 'package:fcs/pages/widgets/delivery_address_selection.dart'; -import 'package:fcs/pages/widgets/display_text.dart'; -import 'package:fcs/pages/widgets/fcs_id_icon.dart'; -import 'package:fcs/pages/widgets/input_date.dart'; -import 'package:fcs/pages/widgets/input_time.dart'; -import 'package:fcs/pages/widgets/local_button.dart'; -import 'package:fcs/pages/widgets/local_radio_buttons.dart'; -import 'package:fcs/pages/widgets/local_text.dart'; -import 'package:fcs/pages/widgets/local_title.dart'; -import 'package:fcs/pages/widgets/progress.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import 'box_row.dart'; -import 'shipment_box_editor.dart'; -import 'widgets.dart'; - -class ShipmentEditor extends StatefulWidget { - final Shipment? shipment; - ShipmentEditor({this.shipment}); - - @override - _ShipmentEditorState createState() => _ShipmentEditorState(); -} - -class _ShipmentEditorState extends State { - var dateFormatter = new DateFormat('dd MMM yyyy'); - var timeFormatter = new DateFormat('jm'); - - TextEditingController _fromTimeEditingController = - new TextEditingController(); - TextEditingController _toTimeEditingController = new TextEditingController(); - TextEditingController _pickupDate = new TextEditingController(); - - Shipment? _shipment; - bool _isLoading = false; - var now = new DateTime.now(); - late bool _isNew; - - String? _selectedShipmentType; - - @override - void initState() { - super.initState(); - - if (widget.shipment != null) { - _isNew = false; - _shipment = widget.shipment; - _selectedShipmentType = _shipment!.shipmentType; - _fromTimeEditingController.text = _shipment!.pickupTimeStart ?? ""; - _toTimeEditingController.text = _shipment!.pickupTimeEnd ?? ""; - _pickupDate.text = dateFormatter.format(_shipment!.pickupDate ?? now); - } else { - _isNew = true; - _selectedShipmentType = shipment_local_pickup; - _pickupDate.text = dateFormatter.format(now); - _fromTimeEditingController.text = "${timeFormatter.format(now)}"; - _toTimeEditingController.text = "${timeFormatter.format(now)}"; - // _shipment = Shipment(boxes: []); - - Shipment _s = Shipment( - pickupAddress: context.read().defalutAddress, - boxes: []); - _shipment = _s; - _pickupDate.text = dateFormatter.format(now); - } - } - - @override - void dispose() { - super.dispose(); - } - - @override - Widget build(BuildContext context) { - MainModel mainModel = Provider.of(context); - ShipmentModel pickupModel = Provider.of(context); - final shipmentNumberBox = getShipmentNumberStatus(context, _shipment); - bool isLocalPickup = _selectedShipmentType == shipment_local_pickup; - bool isCourierPickup = _selectedShipmentType == shipment_courier_pickup; - bool isLocalDropoff = _selectedShipmentType == shipment_local_dropoff; - bool isCourierDropoff = _selectedShipmentType == shipment_courier_dropoff; - - final fromTimeBox = InputTime( - labelTextKey: 'shipment.from', - iconData: Icons.timer, - controller: _fromTimeEditingController); - - final toTimeBox = Container( - width: 150, - child: InputTime( - iconData: Icons.timer_off, - labelTextKey: 'shipment.to', - controller: _toTimeEditingController)); - - final pickupDateBox = InputDate( - labelTextKey: "shipment.date", - iconData: Icons.date_range, - controller: _pickupDate, - ); - final curierDropoffAddress = Padding( - padding: EdgeInsets.all(8), - child: FloatingActionButton.extended( - onPressed: _openCourierWebsite, - icon: Icon(Icons.open_in_new, color: primaryColor), - label: Text( - 'Visit courier websie \nfor nearest drop-off', - style: TextStyle(fontSize: 16, color: primaryColor), - ), - backgroundColor: Colors.white, - )); - final pickupAddressBox = DefaultDeliveryAddress( - deliveryAddress: _shipment?.pickupAddress, - iconData: Icons.location_on, - labelKey: "shipment.location", - onTap: () async { - DeliveryAddress? address = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => DeliveryAddressSelection( - deliveryAddress: _shipment?.pickupAddress, - user: mainModel.user)), - ); - - if (address == null) return; - - setState(() { - Shipment _s = Shipment(pickupAddress: address); - _shipment = _s; - }); - }, - ); - var localDropoffAddressBox = Row(children: [ - FcsIDIcon(), - Expanded( - child: DisplayText( - text: mainModel.setting!.usaAddress, - ), - ) - ]); - final createBtn = LocalButton( - textKey: "shipment.create", - callBack: _save, - ); - - final updateBtn = LocalButton( - textKey: "shipment.update", - callBack: _save, - ); - - return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: new Icon( - CupertinoIcons.back, - color: primaryColor, - ), - onPressed: () { - if (isDataChanged()) { - showConfirmDialog(context, "back.button_confirm", () { - Navigator.of(context).pop(); - }); - } else { - Navigator.of(context).pop(); - } - }, - ), - shadowColor: Colors.transparent, - backgroundColor: Colors.white, - title: LocalText( - context, - _isNew ? "shipment.new.title" : "shipment.edit.title", - fontSize: 20, - color: primaryColor, - ), - ), - body: Padding( - padding: const EdgeInsets.all(10.0), - child: ListView( - children: [ - _isNew ? Container() : Center(child: shipmentNumberBox), - LocalTitle(textKey: "shipment.type"), - LocalRadioButtons( - values: pickupModel.shipmentTypes, - selectedValue: _selectedShipmentType, - callback: (String? v) { - setState(() { - _selectedShipmentType = v; - }); - }), - ...(isLocalDropoff - ? [ - LocalTitle(textKey: "shipment.location.dropoff"), - localDropoffAddressBox - ] - : []), - ...(isCourierDropoff - ? [ - LocalTitle(textKey: "shipment.courier.dropoff"), - curierDropoffAddress - ] - : []), - ...(isCourierPickup || isLocalPickup - ? [ - LocalTitle(textKey: "shipment.location"), - pickupAddressBox, - LocalTitle(textKey: "shipment.date.time"), - pickupDateBox, - fromTimeBox, - toTimeBox, - ] - : []), - LocalTitle( - textKey: "boxes.name", - trailing: IconButton( - icon: Icon( - Icons.add_circle, - color: primaryColor, - ), - onPressed: () async { - Carton? box = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ShipmentBoxEditor()), - ); - if (box == null) return; - _addBox(box); - }, - ), - ), - Column( - children: getBoxList(context, _shipment?.boxes ?? []), - ), - _isNew ? createBtn : updateBtn, - ], - ), - ), - ), - ); - } - - List getBoxList(BuildContext context, List boxes) { - return boxes.asMap().entries.map((_box) { - return InkWell( - onTap: () async { - Carton box = await Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => ShipmentBoxEditor(box: _box.value))); - _saveBox(box); - }, - child: Row( - children: [ - Expanded(child: BoxRow(box: _box.value)), - InkWell( - onTap: () => _removeBox(_box.value), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Icon(Icons.remove_circle, color: primaryColor), - ), - ), - ], - ), - ); - }).toList(); - } - - _addBox(Carton? box) { - if (box == null) return; - box.cartonType = carton_from_shipments; - _shipment!.boxes.add(box); - setState(() {}); - } - - _saveBox(Carton? box) { - if (box == null) return; - setState(() {}); - } - - _removeBox(Carton? box) { - if (box == null) return; - _shipment!.boxes.remove(box); - setState(() {}); - } - - _save() async { - _shipment!.shipmentType = this._selectedShipmentType; - _shipment!.pickupDate = dateFormatter.parse(_pickupDate.text); - _shipment!.pickupTimeStart = _fromTimeEditingController.text; - _shipment!.pickupTimeEnd = _toTimeEditingController.text; - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - if (_isNew) { - await shipmentModel.createShipment(_shipment!); - } else { - await shipmentModel.updateShipment(_shipment!); - } - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - _openCourierWebsite() { - MainModel mainModel = Provider.of(context, listen: false); - launch("${mainModel.setting!.courierWebsite}"); - } - - isDataChanged() { - return _shipment?.boxes.isNotEmpty; - } -} diff --git a/lib/pages/shipment/shipment_info.dart b/lib/pages/shipment/shipment_info.dart deleted file mode 100644 index 7abe9fb..0000000 --- a/lib/pages/shipment/shipment_info.dart +++ /dev/null @@ -1,567 +0,0 @@ -import 'package:fcs/constants.dart'; -import 'package:fcs/domain/entities/carton.dart'; -import 'package:fcs/domain/entities/shipment.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/carton/model/carton_model.dart'; -import 'package:fcs/pages/main/model/main_model.dart'; -import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; -import 'package:fcs/pages/shipment/shipment_pack.dart'; -import 'package:fcs/pages/widgets/defalut_delivery_address.dart'; -import 'package:fcs/pages/widgets/display_text.dart'; -import 'package:fcs/pages/widgets/fcs_id_icon.dart'; -import 'package:fcs/pages/widgets/local_button.dart'; -import 'package:fcs/pages/widgets/local_popup_menu_button.dart'; -import 'package:fcs/domain/vo/local_popupmenu.dart'; -import 'package:fcs/pages/widgets/local_radio_buttons.dart'; -import 'package:fcs/pages/widgets/local_text.dart'; -import 'package:fcs/pages/widgets/local_title.dart'; -import 'package:fcs/pages/widgets/multi_img_controller.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:intl/intl.dart'; -import 'package:provider/provider.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import 'box_row.dart'; -import 'shipment_assign.dart'; -import 'shipment_confirm.dart'; -import 'shipment_editor.dart'; -import 'widgets.dart'; - -class ShipmentInfo extends StatefulWidget { - final bool? isCustomer; - final Shipment? shipment; - ShipmentInfo({this.shipment, this.isCustomer}); - - @override - _ShipmentInfoState createState() => _ShipmentInfoState(); -} - -class _ShipmentInfoState extends State { - var dateFormatter = new DateFormat('dd MMM yyyy'); - final numberFormatter = new NumberFormat("#,###"); - MultiImgController multiImgController = MultiImgController(); - var timeFormatter = new DateFormat('jm'); - - TextEditingController _addressEditingController = new TextEditingController(); - TextEditingController _fromTimeEditingController = - new TextEditingController(); - TextEditingController _toTimeEditingController = new TextEditingController(); - TextEditingController _noOfPackageEditingController = - new TextEditingController(); - TextEditingController _weightEditingController = new TextEditingController(); - TextEditingController _pickupDate = new TextEditingController(); - - Shipment? _shipment; - bool _isLoading = false; - late bool _isCustomer; - var now = new DateTime.now(); - - @override - void initState() { - super.initState(); - _shipment = widget.shipment; - _isCustomer = widget.isCustomer!; - _loadCartons(_shipment!.id!); - - _addressEditingController.text = _shipment!.address ?? ""; - _fromTimeEditingController.text = _shipment!.pickupTimeStart ?? ""; - _toTimeEditingController.text = _shipment!.pickupTimeEnd ?? ""; - _noOfPackageEditingController.text = _shipment!.numberOfPackage.toString(); - _weightEditingController.text = _shipment!.weight.toString(); - _pickupDate.text = dateFormatter.format(_shipment!.pickupDate ?? now); - } - - _loadCartons(String shipmentID) async { - CartonModel cartonModel = Provider.of(context, listen: false); - var cartons = await cartonModel.getCartons(shipmentID); - setState(() { - _shipment!.boxes = cartons; - }); - } - - _loadShipment(String id) async { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - Shipment? s = await shipmentModel.getShipment(id); - s!.boxes = _shipment!.boxes; - setState(() { - _shipment = s; - }); - } - - @override - void dispose() { - super.dispose(); - } - - @override - Widget build(BuildContext context) { - MainModel mainModel = Provider.of(context); - ShipmentModel pickupModel = Provider.of(context); - bool isLocalPickup = _shipment!.shipmentType == shipment_local_pickup; - bool isCourierPickup = _shipment!.shipmentType == shipment_courier_pickup; - bool isLocalDropoff = _shipment!.shipmentType == shipment_local_dropoff; - bool isCourierDropoff = _shipment!.shipmentType == shipment_courier_dropoff; - bool isEditable = widget.isCustomer! - ? (_shipment!.isPending || _shipment!.isAssigned) - : (_shipment!.isPending || - _shipment!.isAssigned || - _shipment!.isPickuped); - bool canCancel = - _shipment!.isPending || _shipment!.isConfirmed || _shipment!.isAssigned; - - final popupMenu = LocalPopupMenuButton( - popmenus: [ - LocalPopupMenu( - enabled: _shipment!.isPending && isLocalPickup, - id: 1, - textKey: "shipment.assign.for.pickup", - ), - LocalPopupMenu( - enabled: - (_shipment!.isPickuped && isLocalPickup) || _shipment!.isReceived, - id: 3, - textKey: "shipment.pack.menuitem", - ), - LocalPopupMenu( - enabled: - _shipment!.isPending && (isCourierPickup || isCourierDropoff), - id: 4, - textKey: "shipment.confirm.menuitem", - ), - LocalPopupMenu( - enabled: canCancel, - id: 2, - textKey: "btn.cancel", - ), - ], - selectable: false, - buttonIcon: Icons.more_vert, - popupMenuCallback: (p) => p.id == 1 - ? _gotoAssign() - : p.id == 2 - ? _cancel() - : p.id == 3 - ? _gotoPack() - : p.id == 4 - ? _gotoConfirm() - : null, - ); - final popupMenuCustomer = LocalPopupMenuButton( - popmenus: [ - LocalPopupMenu( - enabled: canCancel, - id: 2, - textKey: "btn.cancel", - ), - ], - selectable: false, - buttonIcon: Icons.more_vert, - popupMenuCallback: (p) => p.id == 2 ? _cancel() : null, - ); - final shipmentNumberBox = getShipmentNumberStatus(context, _shipment!); - - final fromTimeBox = DisplayText( - labelTextKey: 'shipment.from', - iconData: Icons.timer, - text: _shipment!.pickupTimeStart ?? "", - ); - final toTimeBox = DisplayText( - labelTextKey: 'shipment.to', - iconData: Icons.timer_off, - text: _shipment!.pickupTimeEnd ?? "", - ); - - final pickupDateBox = DisplayText( - labelTextKey: "shipment.date", - iconData: Icons.date_range, - text: _shipment!.pickupDate != null - ? dateFormatter.format(_shipment!.pickupDate!) - : '', - ); - var localDropoffAddressBox = Row(children: [ - FcsIDIcon(), - Expanded( - child: DisplayText( - text: mainModel.setting!.usaAddress ?? "", - ), - ) - ]); - final curierDropoffAddress = Padding( - padding: EdgeInsets.all(8), - child: FloatingActionButton.extended( - onPressed: _openCourierWebsite, - icon: Icon(Icons.open_in_new, color: primaryColor), - label: Text( - 'Visit courier website \nfor nearest drop-off', - style: TextStyle(fontSize: 16, color: primaryColor), - ), - backgroundColor: Colors.white, - )); - final pickupAddressBox = DefaultDeliveryAddress( - deliveryAddress: _shipment!.pickupAddress, - iconData: Icons.location_on, - labelKey: "shipment.location", - ); - var usersBox = DisplayText( - labelTextKey: "shipment.staff", - text: _shipment!.pickupUserName ?? "", - iconData: MaterialCommunityIcons.worker); - var handlingFeeBox = DisplayText( - labelTextKey: "shipment.handling.fee", - text: (_shipment!.handlingFee).toString(), - iconData: FontAwesome.truck); - - final assignCompleteBtn = LocalButton( - textKey: "shipment.assign.complete.btn", - callBack: _completeAssign, - ); - final completePickupBtn = LocalButton( - textKey: "shipment.pickup.complete.btn", - callBack: _pickup, - ); - final completePackBtn = LocalButton( - textKey: "shipment.pack.complete.btn", - callBack: _pack, - ); - final confirmCompleteBtn = LocalButton( - textKey: "shipment.confirm.complete.btn", - callBack: _confirm, - ); - - final fcsShipmentNumberBox = DisplayText( - text: _shipment!.fcsShipmentNumber ?? "", - labelTextKey: "FCSshipment.number", - iconData: Ionicons.ios_airplane, - ); - final completeReceiveBtn = LocalButton( - textKey: "shipment.receive.complete.btn", - callBack: _receive, - ); - - return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: new Icon( - CupertinoIcons.back, - color: primaryColor, - ), - onPressed: () => Navigator.of(context).pop(), - ), - shadowColor: Colors.transparent, - backgroundColor: Colors.white, - title: LocalText( - context, - "shipment.info", - fontSize: 20, - color: primaryColor, - ), - actions: [ - IconButton( - icon: Icon(Icons.edit, - color: isEditable ? primaryColor : Colors.grey), - onPressed: isEditable ? _edit : null, - ), - widget.isCustomer! ? popupMenuCustomer : popupMenu, - ]), - body: Padding( - padding: const EdgeInsets.all(10.0), - child: ListView( - children: [ - shipmentNumberBox, - LocalTitle(textKey: "shipment.type"), - LocalRadioButtons( - readOnly: true, - values: pickupModel.shipmentTypes, - selectedValue: _shipment!.shipmentType, - ), - ...(isLocalDropoff - ? [ - LocalTitle(textKey: "shipment.location.dropoff"), - localDropoffAddressBox - ] - : []), - ...(isCourierDropoff - ? [ - LocalTitle(textKey: "shipment.courier.dropoff"), - curierDropoffAddress - ] - : []), - ...(isCourierPickup || isLocalPickup - ? [ - LocalTitle(textKey: "shipment.location"), - pickupAddressBox, - LocalTitle(textKey: "shipment.date.time"), - pickupDateBox, - fromTimeBox, - toTimeBox, - ] - : []), - LocalTitle( - textKey: "boxes.name", - trailing: Text( - "${_shipment!.totalCount} Cartons - ${_shipment!.totalWeight} lb"), - ), - Column( - children: getBoxList(context, _shipment!.boxes), - ), - !_isCustomer ? fcsShipmentNumberBox : Container(), - ...(!_shipment!.isPending - ? [ - handlingFeeBox, - ] - : []), - ...(isLocalPickup - ? [ - LocalTitle(textKey: "shipment.assign.for.pickup"), - usersBox, - ] - : []), - ...(isLocalPickup && !_isCustomer - ? [ - _shipment!.isPending ? assignCompleteBtn : Container(), - _shipment!.isAssigned ? completePickupBtn : Container(), - _shipment!.isPickuped ? completePackBtn : Container(), - ] - : []), - ...((isCourierPickup || isCourierDropoff) && !_isCustomer - ? [ - _shipment!.isPending ? confirmCompleteBtn : Container(), - _shipment!.isConfirmed ? completeReceiveBtn : Container(), - _shipment!.isReceived ? completePackBtn : Container(), - ] - : []), - ...((isLocalDropoff) && !_isCustomer - ? [ - _shipment!.isPending ? completeReceiveBtn : Container(), - _shipment!.isReceived ? completePackBtn : Container(), - ] - : []), - ], - ), - ), - ), - ); - } - - List getBoxList(BuildContext context, List boxes) { - if (boxes.isEmpty) return []; - return boxes.asMap().entries.map((_box) { - return Row( - children: [ - Expanded(child: BoxRow(box: _box.value)), - ], - ); - }).toList(); - } - - _edit() async { - bool? updated = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ShipmentEditor( - shipment: _shipment, - )), - ); - if (updated ?? false) { - await _loadShipment(_shipment!.id!); - await _loadCartons(_shipment!.id!); - } - } - - _cancel() { - showConfirmDialog(context, "shipment.cancel.confirm", () { - _cancelShipment(); - }); - } - - _cancelShipment() async { - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.cancelShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - _openCourierWebsite() { - MainModel mainModel = Provider.of(context, listen: false); - launch("${mainModel.setting!.courierWebsite}"); - } - - _gotoAssign() async { - bool? assigned = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ShipmentAssign( - shipment: _shipment, - )), - ); - if (assigned ?? false) { - await _loadShipment(_shipment!.id!); - } - } - - _completeAssign() { - showConfirmDialog(context, "shipment.assign.complete.confirm", () { - _completeAssignShipment(); - }); - } - - _completeAssignShipment() async { - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.completeAssignShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - _pickup() { - showConfirmDialog(context, "shipment.pickup.complete.confirm", () { - _pickupShipment(); - }); - } - - _pickupShipment() async { - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.completePickupShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - _gotoPack() async { - bool? assigned = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ShipmentPack( - shipment: _shipment!, - )), - ); - if (assigned ?? false) { - await _loadShipment(_shipment!.id!); - await _loadCartons(_shipment!.id!); - } - } - - _pack() { - showConfirmDialog(context, "shipment.pack.complete.confirm", () { - _packShipment(); - }); - } - - _packShipment() async { - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.completePackShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - _gotoConfirm() async { - bool? assigned = await Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => ShipmentConfirm( - shipment: _shipment, - )), - ); - if (assigned ?? false) { - await _loadShipment(_shipment!.id!); - } - } - - _confirm() { - showConfirmDialog(context, "shipment.confirm.complete.confirm", () { - _confirmShipment(); - }); - } - - _confirmShipment() async { - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.completeConfirmShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } - - _receive() { - showConfirmDialog(context, "shipment.receive.complete.confirm", () { - _receiveShipment(); - }); - } - - _receiveShipment() async { - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.completeReceiveShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } -} diff --git a/lib/pages/shipment/shipment_pack.dart b/lib/pages/shipment/shipment_pack.dart deleted file mode 100644 index affdfad..0000000 --- a/lib/pages/shipment/shipment_pack.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'package:fcs/domain/entities/fcs_shipment.dart'; -import 'package:fcs/domain/entities/shipment.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart'; -import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/shipment/model/shipment_model.dart'; -import 'package:fcs/pages/widgets/local_button.dart'; -import 'package:fcs/pages/widgets/local_dropdown.dart'; -import 'package:fcs/pages/widgets/local_text.dart'; -import 'package:fcs/pages/widgets/local_title.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:intl/intl.dart'; -import 'package:provider/provider.dart'; - -import 'widgets.dart'; - -class ShipmentPack extends StatefulWidget { - final Shipment? shipment; - ShipmentPack({this.shipment}); - - @override - _ShipmentPackState createState() => _ShipmentPackState(); -} - -class _ShipmentPackState extends State { - var dateFormatter = new DateFormat('dd MMM yyyy'); - var timeFormatter = new DateFormat('jm'); - - Shipment? _shipment; - bool _isLoading = false; - var now = new DateTime.now(); - - FcsShipment? _fcsShipment; - List? _fcsShipments; - - @override - void initState() { - super.initState(); - - _shipment = widget.shipment; - _loadFcsShipments(); - } - - _loadFcsShipments() async { - FcsShipmentModel fcsShipmentModel = - Provider.of(context, listen: false); - var fcsShipments = await fcsShipmentModel.getActiveFcsShipments(); - var fcsShipment = - fcsShipments.firstWhere((e) => e.id == _shipment?.fcsShipmentID); - setState(() { - _fcsShipments = fcsShipments; - _fcsShipment = fcsShipment; - }); - } - - @override - Widget build(BuildContext context) { - final shipmentNumberBox = getShipmentNumberStatus(context, _shipment!); - - var fcsShipmentsBox = LocalDropdown( - callback: (v) { - setState(() { - _fcsShipment = v; - }); - }, - labelKey: "shipment.pack.fcs.shipment", - iconData: MaterialCommunityIcons.worker, - display: (u) => u.shipmentNumber, - selectedValue: _fcsShipment, - values: _fcsShipments, - ); - - final packbtn = LocalButton( - textKey: "shipment.pack.btn", - callBack: _save, - ); - return LocalProgress( - inAsyncCall: _isLoading, - child: Scaffold( - appBar: AppBar( - centerTitle: true, - leading: new IconButton( - icon: new Icon( - CupertinoIcons.back, - color: primaryColor, - ), - onPressed: () => Navigator.of(context).pop(), - ), - shadowColor: Colors.transparent, - backgroundColor: Colors.white, - title: LocalText( - context, - "shipment.pack.menuitem", - fontSize: 20, - color: primaryColor, - ), - ), - body: Padding( - padding: const EdgeInsets.all(10.0), - child: ListView( - children: [ - Center(child: shipmentNumberBox), - SizedBox( - height: 10, - ), - LocalTitle(textKey: "shipment.pack.fcs.shipment"), - fcsShipmentsBox, - SizedBox( - height: 10, - ), - packbtn, - ], - ), - ), - ), - ); - } - - _save() async { - _shipment!.fcsShipmentID = this._fcsShipment!.id; - setState(() { - _isLoading = true; - }); - try { - ShipmentModel shipmentModel = - Provider.of(context, listen: false); - await shipmentModel.packShipment(_shipment!); - Navigator.pop(context, true); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } - } -} diff --git a/lib/pages/shipment/widgets.dart b/lib/pages/shipment/widgets.dart deleted file mode 100644 index b11d98d..0000000 --- a/lib/pages/shipment/widgets.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:fcs/domain/entities/shipment.dart'; -import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/widgets/local_text.dart'; -import 'package:flutter/material.dart'; - -Widget getShipmentNumberStatus(BuildContext context, Shipment? shipment) { - return Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - LocalText( - context, - '', - text: shipment?.shipmentNumber ?? "", - color: primaryColor, - fontSize: 18, - fontWeight: FontWeight.bold, - ), - Padding( - padding: const EdgeInsets.only(left: 8.0), - child: Chip(label: Text(shipment?.status ?? "")), - ), - ], - ); -} diff --git a/lib/pages/widgets/status_tree.dart b/lib/pages/widgets/status_tree.dart index 6df504f..f29a025 100644 --- a/lib/pages/widgets/status_tree.dart +++ b/lib/pages/widgets/status_tree.dart @@ -79,7 +79,9 @@ class StatusTree extends StatelessWidget { fontSize: 16, fontWeight: FontWeight.bold)), e.done! || isPacked - ? Text(dateFormatter.format(e.date)) + ? e.date != null + ? Text(dateFormatter.format(e.date!)) + : const SizedBox() : Container(), e.staffName == null ? Container() @@ -89,13 +91,13 @@ class StatusTree extends StatelessWidget { ), icon: e == null ? null - : e.status == "shipped" + : e.status == package_shipped_status ? shippedIcon - : e.status == "delivered" + : e.status == package_delivered_status ? deliveredIcon - : e.status == "packed" + : e.status == package_packed_status ? packedIcon - : e.status == "processed" + : e.status == package_processed_status ? processedIcon : receivedIcon, position: MarkerPosition.left,