From e208734dfad6af4569df991f426bedea66f10876 Mon Sep 17 00:00:00 2001 From: tzw Date: Wed, 12 Mar 2025 17:49:27 +0630 Subject: [PATCH] update carton and cargo type --- assets/local/localization_en.json | 6 +- assets/local/localization_mu.json | 6 +- lib/app.dart | 53 +++-- lib/domain/entities/cargo_type.dart | 38 ++-- lib/domain/entities/carton.dart | 2 +- lib/domain/vo/local_popupmenu.dart | 9 + lib/pages/carton/carton_info.dart | 54 +++-- lib/pages/carton/carton_list.dart | 67 +++--- lib/pages/carton/carton_package_editor.dart | 7 +- lib/pages/carton/carton_package_form.dart | 5 +- lib/pages/carton/carton_size_widget.dart | 2 +- lib/pages/carton/mix_carton_detail_list.dart | 114 ++++++++++ .../carton/model/package_selection_model.dart | 29 +++ lib/pages/carton/package_detail_list.dart | 111 +++++++++ lib/pages/carton/packages_widget.dart | 211 ++++++++++++++++++ lib/pages/fcs_shipment/fcs_shipment_list.dart | 119 +++++----- .../fcs_shipment/fcs_shipment_list_row.dart | 20 +- lib/pages/package/model/package_model.dart | 90 +++++--- lib/pages/package/package_list.dart | 104 +++++++-- lib/pages/package/package_list_row.dart | 32 ++- lib/pages/processing/processing_list_row.dart | 29 ++- lib/pages/profile/profile_page.dart | 8 +- lib/pages/rates/cargo_editor.dart | 104 ++++++--- lib/pages/rates/cargo_type_list.dart | 17 +- lib/pages/rates/custom_editor.dart | 83 +++---- lib/pages/rates/custom_list.dart | 18 +- lib/pages/rates/discount_by weight_list.dart | 20 +- .../rates/discount_by_weight_editor.dart | 50 +++-- lib/pages/rates/shipment_rates_calculate.dart | 57 ++--- lib/pages/rates/shipment_rates_edit.dart | 76 ++++--- lib/pages/receiving/receiving_list_row.dart | 29 ++- .../widgets/local_popup_menu_button.dart | 33 +-- 32 files changed, 1141 insertions(+), 462 deletions(-) create mode 100644 lib/pages/carton/mix_carton_detail_list.dart create mode 100644 lib/pages/carton/package_detail_list.dart create mode 100644 lib/pages/carton/packages_widget.dart diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index 2b38e20..22b7b3c 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -371,7 +371,7 @@ "box.crete.carton":"Create carton", "box.carton.type":"Carton type", "box.select.delivery":"Last mile", - "box.select.package":"Select packages", + "box.select.package":"Packages", "box.no_package":"There is no packages.", "box.input_cargo_weight":"Cargo type (lb)", "box.input_surcharge_item":"Surcharge items", @@ -523,6 +523,7 @@ "rate.discount.rate":"Discount rate", "rate.custom_duty.title":"Custom Fee", "rate.custom_duty":"Custom Fee", + "rate.custom_new":"New custom fee", "rate.cargo.type":"Cargo Types", "rate.discount_by_weight":"Discounts by weight", "rate.discount_by_weight.edit.delete.confirm":"Delete this discount by weight?", @@ -530,6 +531,8 @@ "Rate End ================================================================":"", "Cargo Start ================================================================":"", + "cargo.title":"Cargoes", + "cargo.new":"New cargo", "cargo.form.title":"Cargo", "cargo.type":"Cargo type", "cargo.weight":"Weight", @@ -539,6 +542,7 @@ "cargo.edit.delete.confirm":"Delete this cargo type?", "cargo.display_index":"Display index", "cargo.is_default":"Default Cargo", + "cargo.is_mix":"Mix cargo", "Cargo End ================================================================":"", "Invoices Start ================================================================":"", diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index 849ea11..10b6e41 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -371,7 +371,7 @@ "box.crete.carton":"Create carton", "box.carton.type":"ပုံး အမျိုးအစား", "box.select.delivery":"Last mile", - "box.select.package":"Select packages", + "box.select.package":"Packages", "box.no_package":"There is no packages.", "box.input_cargo_weight":"Cargo type (lb)", "box.input_surcharge_item":"Surcharge items", @@ -526,6 +526,7 @@ "rate.discount.rate":"လျှော့စျေးနှုန်း", "rate.custom_duty.title":"အကောက်ခွန်များ", "rate.custom_duty":"အကောက်ခွန်", + "rate.custom_new":"အကောက်ခွန်အသစ်", "rate.cargo.type":"ကုန်ပစ္စည်းအမျိုးအစား", "rate.discount_by_weight":"အထူးလျှော့စျေး", "rate.discount_by_weight.edit.delete.confirm":"လျှော့စျေးနှုန်းကို ဖျက်မလား?", @@ -533,6 +534,8 @@ "Rate End ================================================================":"", "Cargo Start ================================================================":"", + "cargo.title":"ကုန်ပစ္စည်းများ", + "cargo.new":"ကုန်ပစ္စည်းအသစ်", "cargo.form.title":"ကုန်ပစ္စည်း", "cargo.type":"ကုန်ပစ္စည်းအမျိုးအစား", "cargo.weight":"အလေးချိန်", @@ -542,6 +545,7 @@ "cargo.edit.delete.confirm":"ကုန်ပစ္စည်းကို ဖျက်မလား?", "cargo.display_index":"Display index", "cargo.is_default":"Default Cargo", + "cargo.is_mix":"Mix cargo", "Cargo End ================================================================":"", "Invoices Start ================================================================":"", diff --git a/lib/app.dart b/lib/app.dart index 50e8f66..af36f2b 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -46,35 +46,34 @@ class App extends StatefulWidget { } class _AppState extends State { - final MainModel mainModel = new MainModel(); - final ContactModel contactModel = new ContactModel(); - final TermModel termModel = new TermModel(); - final FAQModel faqModel = new FAQModel(); - final PaymentMethodModel paymentMethodModel = new PaymentMethodModel(); - final FcsShipmentModel fcsShipmentModel = new FcsShipmentModel(); - final LanguageModel lanuguageModel = new LanguageModel(); - final ShipmentRateModel shipmentRateModel = new ShipmentRateModel(); - final CartonModel boxModel = new CartonModel(); - final MessageModel messageModel = new MessageModel(); - final InvoiceModel invoiceModel = new InvoiceModel(); - final CustomerModel customerModel = new CustomerModel(); - final DiscountModel discountModel = new DiscountModel(); - final StaffModel staffModel = new StaffModel(); - final DeliveryAddressModel deliveryAddressModel = new DeliveryAddressModel(); - final PackageModel packageModel = new PackageModel(); - final MarketModel marketModel = new MarketModel(); - final DeliveryModel deliveryModel = new DeliveryModel(); - final CartonSizeModel cartonSizeModel = new CartonSizeModel(); - final ProcessingModel processingModel = new ProcessingModel(); - final PickupModel pickupModel = new PickupModel(); - final CartonSelectionModel cartonSelectionModel = new CartonSelectionModel(); - final PackageSelectionModel packageSelectionModel = - new PackageSelectionModel(); + final MainModel mainModel = MainModel(); + final ContactModel contactModel = ContactModel(); + final TermModel termModel = TermModel(); + final FAQModel faqModel = FAQModel(); + final PaymentMethodModel paymentMethodModel = PaymentMethodModel(); + final FcsShipmentModel fcsShipmentModel = FcsShipmentModel(); + final LanguageModel lanuguageModel = LanguageModel(); + final ShipmentRateModel shipmentRateModel = ShipmentRateModel(); + final CartonModel boxModel = CartonModel(); + final MessageModel messageModel = MessageModel(); + final InvoiceModel invoiceModel = InvoiceModel(); + final CustomerModel customerModel = CustomerModel(); + final DiscountModel discountModel = DiscountModel(); + final StaffModel staffModel = StaffModel(); + final DeliveryAddressModel deliveryAddressModel = DeliveryAddressModel(); + final PackageModel packageModel = PackageModel(); + final MarketModel marketModel = MarketModel(); + final DeliveryModel deliveryModel = DeliveryModel(); + final CartonSizeModel cartonSizeModel = CartonSizeModel(); + final ProcessingModel processingModel = ProcessingModel(); + final PickupModel pickupModel = PickupModel(); + final CartonSelectionModel cartonSelectionModel = CartonSelectionModel(); + final PackageSelectionModel packageSelectionModel = PackageSelectionModel(); final ConsigneeSelectionModel consigneeSelectionModel = - new ConsigneeSelectionModel(); - final SenderSelectionModel senderSelectionModel = new SenderSelectionModel(); + ConsigneeSelectionModel(); + final SenderSelectionModel senderSelectionModel = SenderSelectionModel(); final ShipmentSelectionModel shipmentSelectionModel = - new ShipmentSelectionModel(); + ShipmentSelectionModel(); late AppTranslationsDelegate _newLocaleDelegate; diff --git a/lib/domain/entities/cargo_type.dart b/lib/domain/entities/cargo_type.dart index 3b64cc2..d2562a6 100644 --- a/lib/domain/entities/cargo_type.dart +++ b/lib/domain/entities/cargo_type.dart @@ -11,6 +11,7 @@ class CargoType { double calWeight; int displayIndex; bool isDefault; + bool isMixCargo; double get calAmount => calRate * calWeight; @@ -26,7 +27,8 @@ class CargoType { this.isCutomDuty = false, this.customDutyFee = 0, this.displayIndex = 0, - this.isDefault = false}); + this.isDefault = false, + this.isMixCargo = false}); factory CargoType.fromMap(Map map, String id) { return CargoType( @@ -39,7 +41,8 @@ class CargoType { isCutomDuty: map['custom_duty'] ?? false, customDutyFee: (map['custom_duty_fee'] ?? 0).toDouble(), displayIndex: map['display_index'] ?? 0, - isDefault: map['is_defalut'] ?? false); + isDefault: map['is_defalut'] ?? false, + isMixCargo: map['is_mix_cargo'] ?? false); } factory CargoType.fromMapForCargo(Map map, String id) { @@ -62,18 +65,19 @@ class CargoType { "id": id, 'name': name, 'rate': rate, - 'weight': weight, - 'cal_weight': calWeight, - 'cal_rate': calRate, - 'custom_duty': isCutomDuty, - 'custom_duty_fee': customDutyFee, - 'qty': qty, + // 'weight': weight, + // 'cal_weight': calWeight, + // 'cal_rate': calRate, + // 'custom_duty': isCutomDuty, + // 'custom_duty_fee': customDutyFee, + // 'qty': qty, 'is_defalut': isDefault, - 'display_index': displayIndex + 'display_index': displayIndex, + 'is_mix_cargo': isMixCargo }; } - Map toMapForCargo() { + Map toMapForCarton() { return {"id": id, 'weight': weight}; } @@ -82,7 +86,7 @@ class CargoType { } CargoType clone() { - return CargoType.fromMap(toMap(), this.id!); + return CargoType.fromMap(toMap(), id!); } @override @@ -97,12 +101,16 @@ class CargoType { } bool isChangedForEdit(CargoType cargoType) { - return cargoType.name != this.name || cargoType.rate != this.rate; + return cargoType.name != name || + cargoType.rate != rate || + cargoType.displayIndex != displayIndex || + cargoType.isDefault != isDefault || + cargoType.isMixCargo != isMixCargo; } bool isChangedForEditCustomDuty(CargoType cargoType) { - return cargoType.name != this.name || - cargoType.customDutyFee != this.customDutyFee || - cargoType.rate != this.rate; + return cargoType.name != name || + cargoType.customDutyFee != customDutyFee || + cargoType.rate != rate; } } diff --git a/lib/domain/entities/carton.dart b/lib/domain/entities/carton.dart index 9afef6e..b0e21bd 100644 --- a/lib/domain/entities/carton.dart +++ b/lib/domain/entities/carton.dart @@ -166,7 +166,7 @@ class Carton { Map toMap() { var _types = cargoTypes.where((t) => t.weight != 0).toList(); - var _cargoTypes = _types.map((c) => c.toMapForCargo()).toList(); + var _cargoTypes = _types.map((c) => c.toMapForCarton()).toList(); var _packagesIds = packages.map((c) => c.id).toList(); diff --git a/lib/domain/vo/local_popupmenu.dart b/lib/domain/vo/local_popupmenu.dart index 4926898..1aa8394 100644 --- a/lib/domain/vo/local_popupmenu.dart +++ b/lib/domain/vo/local_popupmenu.dart @@ -24,3 +24,12 @@ List shipFiteringMenu = [ LocalPopupMenu(id: 7, text: "Delivered"), LocalPopupMenu(id: 6, text: "Canceled"), ]; + +List packageFiteringMenu = [ + LocalPopupMenu(id: 0, text: "All"), + LocalPopupMenu(id: 1, text: "Received"), + LocalPopupMenu(id: 2, text: "Processed"), + LocalPopupMenu(id: 3, text: "Packed"), + LocalPopupMenu(id: 4, text: "Shipped"), + LocalPopupMenu(id: 5, text: "Delivered"), +]; diff --git a/lib/pages/carton/carton_info.dart b/lib/pages/carton/carton_info.dart index 7e23e66..356d7e4 100644 --- a/lib/pages/carton/carton_info.dart +++ b/lib/pages/carton/carton_info.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:fcs/constants.dart'; import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/domain/entities/carton.dart'; @@ -24,12 +26,14 @@ import '../fcs_shipment/model/fcs_shipment_model.dart'; import '../widgets/local_button.dart'; import 'carton_package_editor.dart'; import 'mix_carton/mix_carton_editor.dart'; +import 'mix_carton_detail_list.dart'; import 'model/carton_model.dart'; +import 'package_detail_list.dart'; import 'print_qr_code_page.dart'; class CartonInfo extends StatefulWidget { final Carton carton; - CartonInfo({required this.carton}); + const CartonInfo({super.key, required this.carton}); @override _CartonInfoState createState() => _CartonInfoState(); @@ -176,14 +180,28 @@ class _CartonInfoState extends State { showLabelLink: true, subText: Text(numberFormatter.format(_packages.length)), labelTextKey: "box.package", - onTapLabel: () {}, + onTapLabel: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => PackageDetailList( + cartonNumber: _carton.cartonNumber ?? '', + packages: _packages))); + }, ); final mixCartonLengthBox = DisplayText( showLabelLink: true, subText: Text(numberFormatter.format(_mixCartons.length)), labelTextKey: "box.shipment.boxes", - onTapLabel: () {}, + onTapLabel: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => MixCartonDetailList( + cartonNumber: _carton.cartonNumber ?? '', + cartons: _mixCartons))); + }, ); final senderBox = userDisplayBox(context, @@ -315,18 +333,20 @@ class _CartonInfoState extends State { return Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Container( - color: e.key.isEven ? Colors.grey.shade300 : oddColor, + color: e.key.isEven ? Colors.grey.shade300 : oddColor, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( e.value.name ?? "", - style: TextStyle(color: Colors.black, fontSize: 15), + style: + TextStyle(color: Colors.black, fontSize: 15), ), - Text("${removeTrailingZeros((e.value.qty).toDouble())} pc", + Text( + "${removeTrailingZeros((e.value.qty).toDouble())} pc", textAlign: TextAlign.end, - style: - TextStyle(color: Colors.black, fontSize: 15)) + style: TextStyle( + color: Colors.black, fontSize: 15)) ], ), ), @@ -482,10 +502,16 @@ class _CartonInfoState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible(child: cartonSizeBox), - Flexible(child: packageLengthBox), + _packages.isEmpty + ? const SizedBox() + : Flexible(child: packageLengthBox), ], ), - fromPackage ? const SizedBox() : mixCartonLengthBox, + fromPackage + ? const SizedBox() + : _mixCartons.isEmpty + ? const SizedBox() + : mixCartonLengthBox, shipmentBox, // _packages.isEmpty // ? const SizedBox() @@ -541,9 +567,7 @@ class _CartonInfoState extends State { return list.map((p) { return Container( padding: EdgeInsets.only(top: 0), - child: Container( - child: Row(children: [new Text(p.trackingID ?? "")]), - )); + child: Row(children: [Text(p.trackingID ?? "")])); }).toList(); } @@ -551,9 +575,7 @@ class _CartonInfoState extends State { return list.map((c) { return Container( padding: EdgeInsets.only(top: 0), - child: Container( - child: Row(children: [new Text(c.cartonNumber ?? '')]), - )); + child: Row(children: [Text(c.cartonNumber ?? '')])); }).toList(); } diff --git a/lib/pages/carton/carton_list.dart b/lib/pages/carton/carton_list.dart index 71d3306..fb8a8a6 100644 --- a/lib/pages/carton/carton_list.dart +++ b/lib/pages/carton/carton_list.dart @@ -134,9 +134,9 @@ class _CartonListState extends State { FadeTransition( opacity: animation, child: SizeTransition( - child: child, sizeFactor: animation, axis: Axis.vertical, + child: child, ), ), child: _down @@ -289,36 +289,43 @@ class _CartonListState extends State { Widget _filterWidget(BuildContext context) { var model = Provider.of(context); - return IconButton( - icon: Stack( - alignment: Alignment.center, - children: [ - const Icon( - Icons.filter_list, - color: Colors.white, + return Padding( + padding: const EdgeInsets.only(right: 5), + child: IconButton( + icon: SizedBox( + width: 30, + height: 30, + child: Stack( + alignment: Alignment.center, + children: [ + const Icon( + Icons.filter_list, + color: Colors.white, + ), + model.filterByStatus != null || + model.filterBySender != null || + model.filterByConsingee != null || + model.shipment != null + ? Positioned( + bottom: 15, + right: 0, + child: Container( + width: 10, + height: 10, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Colors.red, + ), + ), + ) + : Container() + ], ), - model.filterByStatus != null || - model.filterBySender != null || - model.filterByConsingee != null || - model.shipment != null - ? Positioned( - bottom: 15, - right: 0, - child: Container( - width: 10, - height: 10, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: Colors.red, - ), - ), - ) - : Container() - ], - ), - onPressed: () { - _showFilter(); - }); + ), + onPressed: () { + _showFilter(); + }), + ); } _showFilter() async { diff --git a/lib/pages/carton/carton_package_editor.dart b/lib/pages/carton/carton_package_editor.dart index baeabee..c082be7 100644 --- a/lib/pages/carton/carton_package_editor.dart +++ b/lib/pages/carton/carton_package_editor.dart @@ -1,4 +1,4 @@ -// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use, use_build_context_synchronously import 'package:fcs/pages/carton/model/carton_model.dart'; import 'package:flutter/cupertino.dart'; @@ -26,7 +26,7 @@ import 'cargo_widget.dart'; import 'carton_size_widget.dart'; import 'carton_submit.dart'; import 'model/package_selection_model.dart'; -import 'package_selection_widget.dart'; +import 'packages_widget.dart'; class CartonPackageEditor extends StatefulWidget { final Carton carton; @@ -233,11 +233,10 @@ class _CartonPackageEditorState extends State { )); } else if (step.stepType == StepType.PACKAGES) { return Expanded( - child: PackageSelectionWidget( + child: PackagesWidget( sender: _sender!, consignee: _consignee!, shipment: _shipment!, - packages: _packages, onContinue: (packages) { setState(() { _packages = List.from(packages); diff --git a/lib/pages/carton/carton_package_form.dart b/lib/pages/carton/carton_package_form.dart index 26f520d..a4b1567 100644 --- a/lib/pages/carton/carton_package_form.dart +++ b/lib/pages/carton/carton_package_form.dart @@ -23,7 +23,7 @@ import 'carton_size_widget.dart'; import 'carton_submit.dart'; import 'model/carton_model.dart'; import 'model/package_selection_model.dart'; -import 'package_selection_widget.dart'; +import 'packages_widget.dart'; class CartonPackageForm extends StatefulWidget { final User sender; @@ -166,11 +166,10 @@ class _CartonPackageFormState extends State { )); } else if (step.stepType == StepType.PACKAGES) { return Expanded( - child: PackageSelectionWidget( + child: PackagesWidget( sender: widget.sender, consignee: widget.consignee, shipment: _shipment!, - packages: _packages, onContinue: (packages) { setState(() { _packages = List.from(packages); diff --git a/lib/pages/carton/carton_size_widget.dart b/lib/pages/carton/carton_size_widget.dart index 7898b42..0259522 100644 --- a/lib/pages/carton/carton_size_widget.dart +++ b/lib/pages/carton/carton_size_widget.dart @@ -522,7 +522,7 @@ class _CartonSizeWidgetState extends State { children: [ const SizedBox(height: 8), userRow, - LocalTitle(textKey: "box.bill_to", topPadding: 8), + LocalTitle(textKey: "box.bill_to", topPadding: 5), const SizedBox(height: 5), billRadioBox, const SizedBox(height: 8), diff --git a/lib/pages/carton/mix_carton_detail_list.dart b/lib/pages/carton/mix_carton_detail_list.dart new file mode 100644 index 0000000..9f4b94b --- /dev/null +++ b/lib/pages/carton/mix_carton_detail_list.dart @@ -0,0 +1,114 @@ +import 'package:fcs/domain/entities/carton.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/widgets/local_app_bar.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 '../widgets/local_text.dart'; +import 'carton_info.dart'; + +class MixCartonDetailList extends StatelessWidget { + final String cartonNumber; + final List cartons; + MixCartonDetailList( + {super.key, required this.cartonNumber, required this.cartons}); + + final NumberFormat numberFormatter = NumberFormat("#,###"); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: LocalAppBar( + backgroundColor: Colors.white, + arrowColor: primaryColor, + labelColor: primaryColor, + titleWidget: Column( + children: [ + LocalText( + context, + "box.cartion.count", + fontSize: 20, + color: primaryColor, + translationVariables: [numberFormatter.format(cartons.length)], + ), + Text(cartonNumber, + style: TextStyle(fontSize: 15, color: Colors.black)) + ], + ), + ), + body: ListView.separated( + separatorBuilder: (context, index) => + Divider(height: 1, color: dividerColor), + itemCount: cartons.length, + itemBuilder: (BuildContext context, int index) { + var carton = cartons[index]; + return InkWell( + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => CartonInfo(carton: carton)), + ); + }, + child: Container( + padding: EdgeInsets.only(left: 15, right: 15), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + children: [ + Icon(MaterialCommunityIcons.package, + color: primaryColor), + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 15), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + carton.cartonNumber == null + ? '' + : carton.cartonNumber!, + style: TextStyle( + fontSize: 15.0, + color: Colors.black), + ), + Padding( + padding: + const EdgeInsets.only(top: 5), + child: Text( + carton.consigneeName ?? '', + style: TextStyle( + fontSize: 15.0, + color: Colors.grey), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + Text( + "${carton.cartonWeight.toStringAsFixed(2)} lb", + style: TextStyle(fontSize: 14.0, color: Colors.grey), + ) + ], + ), + ], + ), + ), + ); + }, + )); + } +} diff --git a/lib/pages/carton/model/package_selection_model.dart b/lib/pages/carton/model/package_selection_model.dart index 5ac2bb2..de6d77a 100644 --- a/lib/pages/carton/model/package_selection_model.dart +++ b/lib/pages/carton/model/package_selection_model.dart @@ -145,4 +145,33 @@ class PackageSelectionModel extends BaseModel { } return list; } + + Future> getActivePackages( + {required String shipmentId, + required String senderId, + required String consigneeId}) async { + List list = []; + try { + String path = "/$packages_collection"; + + var snaps = await FirebaseFirestore.instance + .collection(path) + .where("status", + whereIn: [package_processed_status, package_packed_status]) + .where("sender_id", isEqualTo: senderId) + .where("user_id", isEqualTo: consigneeId) + // .where("fcs_shipment_id", isEqualTo: shipmentId) + .where("is_deleted", isEqualTo: false) + .orderBy("created_date", descending: true) + .get(const GetOptions(source: Source.server)); + list = snaps.docs + .map((documentSnapshot) => + Package.fromMap(documentSnapshot.data(), documentSnapshot.id)) + .toList(); + } catch (e) { + log.warning("Error!! $e"); + list = []; + } + return list; + } } diff --git a/lib/pages/carton/package_detail_list.dart b/lib/pages/carton/package_detail_list.dart new file mode 100644 index 0000000..4dd72f1 --- /dev/null +++ b/lib/pages/carton/package_detail_list.dart @@ -0,0 +1,111 @@ +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/package/package_info.dart'; +import 'package:fcs/pages/widgets/local_app_bar.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 '../widgets/local_text.dart'; + +class PackageDetailList extends StatelessWidget { + final String cartonNumber; + final List packages; + PackageDetailList( + {super.key, required this.cartonNumber, required this.packages}); + + final NumberFormat numberFormatter = NumberFormat("#,###"); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: LocalAppBar( + backgroundColor: Colors.white, + arrowColor: primaryColor, + labelColor: primaryColor, + titleWidget: Column( + children: [ + LocalText( + context, + "box.package.count", + fontSize: 20, + color: primaryColor, + translationVariables: [numberFormatter.format(packages.length)], + ), + Text(cartonNumber, + style: TextStyle(fontSize: 15, color: Colors.black)) + ], + ), + ), + body: ListView.separated( + separatorBuilder: (context, index) => + Divider(height: 1, color: dividerColor), + itemCount: packages.length, + itemBuilder: (BuildContext context, int index) { + var package = packages[index]; + return InkWell( + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => PackageInfo(package: package)), + ); + }, + child: Container( + padding: EdgeInsets.only(left: 15, right: 15), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + children: [ + Icon(Octicons.package, color: primaryColor), + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 15), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + package.id == null + ? '' + : package.trackingID!, + style: TextStyle( + fontSize: 15.0, + color: Colors.black), + ), + Padding( + padding: + const EdgeInsets.only(top: 5), + child: Text( + package.market == null + ? '' + : package.market!, + style: TextStyle( + fontSize: 15.0, + color: Colors.grey), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ], + ), + ], + ), + ), + ); + }, + )); + } +} diff --git a/lib/pages/carton/packages_widget.dart b/lib/pages/carton/packages_widget.dart new file mode 100644 index 0000000..a2abb2d --- /dev/null +++ b/lib/pages/carton/packages_widget.dart @@ -0,0 +1,211 @@ +import 'package:fcs/domain/entities/fcs_shipment.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart'; +import 'package:provider/provider.dart'; + +import '../../domain/entities/package.dart'; +import '../../domain/entities/user.dart'; +import '../main/util.dart'; +import '../widgets/continue_button.dart'; +import '../widgets/local_title.dart'; +import '../widgets/previous_button.dart'; +import 'model/package_selection_model.dart'; +import 'package_selection_result.dart'; + +typedef OnPrevious = Function(List packages); +typedef OnContinue = Function(List packages); + +class PackagesWidget extends StatefulWidget { + final User sender; + final User consignee; + final FcsShipment shipment; + final OnPrevious? onPrevious; + final OnContinue? onContinue; + + const PackagesWidget({ + super.key, + this.onPrevious, + this.onContinue, + required this.shipment, + required this.sender, + required this.consignee, + }); + + @override + State createState() => _PackagesWidgetState(); +} + +class _PackagesWidgetState extends State { + final _scrollController = ScrollController(); + bool _down = true; + List _packages = []; + + @override + void initState() { + _init(); + super.initState(); + _scrollController.addListener(() { + setState(() { + _down = _scrollController.position.userScrollDirection == + ScrollDirection.forward; + }); + }); + } + + _init() async { + _packages.clear(); + var packageModel = context.read(); + var list = await packageModel.getActivePackages( + shipmentId: widget.shipment.id!, + senderId: widget.sender.id!, + consigneeId: widget.consignee.id!); + _packages = List.from(list); + if (mounted) { + setState(() {}); + } + } + + @override + Widget build(BuildContext context) { + final senderBox = userDisplayBox(context, + lableKey: "box.sender.title", + icon: MaterialCommunityIcons.account_arrow_right, + showLink: false, + name: widget.sender.name ?? "", + fcsID: widget.sender.fcsID ?? ""); + + final consigneeBox = userDisplayBox(context, + showLink: false, + lableKey: "box.consignee.title", + icon: MaterialCommunityIcons.account_arrow_left, + name: widget.consignee.name, + fcsID: widget.consignee.fcsID); + + final userRow = Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded(flex: 2, child: consigneeBox), + Flexible(child: senderBox) + ], + ); + + final continueBtn = ContinueButton( + onTap: () { + if (widget.onContinue != null) { + widget.onContinue!(_packages); + } + }, + ); + + final previousBtn = PreviousButton(onTap: () { + if (widget.onPrevious != null) { + widget.onPrevious!(_packages); + } + }); + + return Column( + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Column( + children: [ + AnimatedSwitcher( + duration: const Duration(milliseconds: 300), + transitionBuilder: + (Widget child, Animation animation) => + FadeTransition( + opacity: animation, + child: SizeTransition( + sizeFactor: animation, + axis: Axis.vertical, + child: child, + ), + ), + child: _down + ? Column(children: [ + const SizedBox(height: 8), + userRow, + LocalTitle( + textKey: "box.select.package", topPadding: 5), + const SizedBox(height: 10), + ]) + : const SizedBox(), + ), + Expanded( + child: RefreshIndicator( + color: primaryColor, + onRefresh: () async { + _init(); + }, + child: ListView.builder( + padding: const EdgeInsets.only(top: 10), + controller: _scrollController, + shrinkWrap: true, + physics: const AlwaysScrollableScrollPhysics(), + itemBuilder: (context, index) { + Package package = _packages[index]; + return packageRow(context, package); + }, + itemCount: _packages.length)), + ), + ], + ), + ), + ), + widget.onContinue != null + ? Padding( + padding: const EdgeInsets.only(left: 15, right: 15, top: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + previousBtn, + continueBtn, + ], + ), + ) + : const SizedBox(), + const SizedBox(height: 20) + ], + ); + } + + Widget packageRow(BuildContext context, Package package) { + return Padding( + padding: const EdgeInsets.only(top: 5, bottom: 5), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(5)), + border: Border.all(color: Colors.grey.shade300)), + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(package.trackingID ?? "", + style: TextStyle(fontSize: 15.0, color: Colors.black)), + Text( + package.cartonIds.isEmpty + ? "-" + : "${numberFormatter.format(package.cartonIds.length)} Boxes", + style: TextStyle(fontSize: 15.0, color: Colors.grey), + ), + ], + ), + ), + ), + package.isChecked + ? Icon(Icons.check, color: primaryColor) + : const SizedBox() + ], + ), + ), + ); + } +} diff --git a/lib/pages/fcs_shipment/fcs_shipment_list.dart b/lib/pages/fcs_shipment/fcs_shipment_list.dart index 2bb9713..812049e 100644 --- a/lib/pages/fcs_shipment/fcs_shipment_list.dart +++ b/lib/pages/fcs_shipment/fcs_shipment_list.dart @@ -13,12 +13,14 @@ import 'fcs_shipment_editor.dart'; import 'fcs_shipment_list_row.dart'; class FcsShipmentList extends StatefulWidget { + const FcsShipmentList({super.key}); + @override _FcsShipmentListState createState() => _FcsShipmentListState(); } class _FcsShipmentListState extends State { - bool _isLoading = false; + bool isLoading = false; int _selectedIndex = 0; @override @@ -41,7 +43,7 @@ class _FcsShipmentListState extends State { var shipmentModel = Provider.of(context); return LocalProgress( - inAsyncCall: _isLoading, + inAsyncCall: isLoading, child: Scaffold( appBar: LocalAppBar(labelKey: "FCSshipment.list.title", actions: [ _menuFilteringWidget(context), @@ -66,63 +68,68 @@ class _FcsShipmentListState extends State { } Widget _menuFilteringWidget(BuildContext context) { - return PopupMenuButton( - splashRadius: 25, - padding: const EdgeInsets.only(right: 15), - elevation: 3.2, - tooltip: 'This is tooltip', - onSelected: (choice) async { - setState(() { - _selectedIndex = choice.id; - }); + return Padding( + padding: const EdgeInsets.only(right: 5), + child: PopupMenuButton( + elevation: 3.2, + tooltip: '', + onSelected: (choice) async { + setState(() { + _selectedIndex = choice.id; + }); - await context.read().onChanged(choice.id); - }, - icon: Stack( - alignment: Alignment.center, - children: [ - const Icon( - Icons.filter_list, - color: Colors.white, + await context.read().onChanged(choice.id); + }, + icon: SizedBox( + width: 30, + height: 30, + child: Stack( + alignment: Alignment.center, + children: [ + const Icon( + Icons.filter_list, + color: Colors.white, + ), + _selectedIndex != 0 + ? Positioned( + bottom: 15, + right: 0, + child: Container( + width: 10, + height: 10, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Colors.red, + ), + ), + ) + : Container() + ], ), - _selectedIndex != 0 - ? Positioned( - bottom: 15, - right: 0, - child: Container( + ), + itemBuilder: (BuildContext context) { + return shipFiteringMenu.map((LocalPopupMenu choice) { + return PopupMenuItem( + value: choice, + child: Row( + children: [ + Flexible( + child: Text("${choice.text}", + style: TextStyle(color: Colors.black))), + const SizedBox( width: 10, - height: 10, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: Colors.red, - ), ), - ) - : Container() - ], - ), - itemBuilder: (BuildContext context) { - return shipFiteringMenu.map((LocalPopupMenu choice) { - return PopupMenuItem( - value: choice, - child: Row( - children: [ - Flexible( - child: Text("${choice.text}", - style: TextStyle(color: Colors.black))), - const SizedBox( - width: 10, - ), - _selectedIndex == choice.id - ? const Icon( - Icons.check, - color: Colors.grey, - ) - : const SizedBox(), - ], - ), - ); - }).toList(); - }); + _selectedIndex == choice.id + ? const Icon( + Icons.check, + color: Colors.grey, + ) + : const SizedBox(), + ], + ), + ); + }).toList(); + }), + ); } } diff --git a/lib/pages/fcs_shipment/fcs_shipment_list_row.dart b/lib/pages/fcs_shipment/fcs_shipment_list_row.dart index 50ff32f..aac80ef 100644 --- a/lib/pages/fcs_shipment/fcs_shipment_list_row.dart +++ b/lib/pages/fcs_shipment/fcs_shipment_list_row.dart @@ -8,8 +8,8 @@ import 'fcs_shipment_info.dart'; class FcsShipmentListRow extends StatelessWidget { final FcsShipment shipment; - final dateFormatter = new DateFormat('dd MMM yyyy'); - FcsShipmentListRow({Key? key, required this.shipment}) : super(key: key); + final dateFormatter = DateFormat('dd MMM yyyy'); + FcsShipmentListRow({super.key, required this.shipment}); @override Widget build(BuildContext context) { @@ -23,31 +23,31 @@ class FcsShipmentListRow extends StatelessWidget { child: Row( children: [ Expanded( - child: new Padding( + child: Padding( padding: const EdgeInsets.symmetric(vertical: 13), - child: new Row( + child: Row( children: [ Icon( Ionicons.ios_airplane, color: primaryColor, size: 30, ), - new Expanded( + Expanded( child: Padding( padding: const EdgeInsets.only(left: 15), - child: new Column( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - new Text( + Text( shipment.shipmentNumber ?? '', - style: new TextStyle( + style: TextStyle( fontSize: 15.0, color: Colors.black), ), Padding( padding: const EdgeInsets.only(top: 5), - child: new Text( + child: Text( dateFormatter.format(shipment.cutoffDate!), - style: new TextStyle( + style: TextStyle( fontSize: 15.0, color: Colors.grey), ), ) diff --git a/lib/pages/package/model/package_model.dart b/lib/pages/package/model/package_model.dart index fed9bfc..7f4d84b 100644 --- a/lib/pages/package/model/package_model.dart +++ b/lib/pages/package/model/package_model.dart @@ -23,17 +23,20 @@ class PackageModel extends BaseModel { PaginatorListener? activePackages; bool isLoading = false; - int selectedIndex = 1; + int selectedIndexForCustomer = 1; + int selectedIndex = 0; - initData(int index, bool isCustomer) { - selectedIndex = index; - if (isCustomer) { - _loadPaginationCustomerPackages(selectedIndex == 2); - } else { - _loadPaginationPackages(selectedIndex == 2); - } + initDataForCustomer(int index) { + selectedIndexForCustomer = index; + _loadPaginationCustomerPackages(selectedIndexForCustomer == 2); } + initData(int index) { + selectedIndex = index; + _loadPaginationPackages(selectedIndex); + } + + @override void privilegeChanged() { if (user != null) { _loadPaginationActivePackages(); @@ -47,30 +50,57 @@ class PackageModel extends BaseModel { if (activePackages != null) activePackages!.close(); } - onChanged(int index, bool isCustomer) { - selectedIndex = index; - if (isCustomer) { - _loadPaginationCustomerPackages(selectedIndex == 2); - } else { - _loadPaginationPackages(selectedIndex == 2); - } + onChangedForCustomer(int index) { + selectedIndexForCustomer = index; + _loadPaginationCustomerPackages(selectedIndexForCustomer == 2); notifyListeners(); } - _loadPaginationPackages(bool isDelivered) { + _loadPaginationPackages(int index) { if (user == null) return; if (!((user!.hasPackages() || user!.hasReceiving() || - user!.hasProcessing()))) return; + user!.hasProcessing()))) { + return; + } String path = "/$packages_collection"; - Query col = FirebaseFirestore.instance - .collection(path) - .where("is_delivered", isEqualTo: isDelivered); - Query pageQuery = FirebaseFirestore.instance - .collection(path) - .where("is_delivered", isEqualTo: isDelivered) - .orderBy("update_time", descending: true); + Query col = FirebaseFirestore.instance.collection(path); + Query pageQuery = FirebaseFirestore.instance.collection(path); + + // received status + if (index == 1) { + col = col.where("status", isEqualTo: package_received_status); + pageQuery = pageQuery.where("status", isEqualTo: package_received_status); + } + + // processed status + if (index == 2) { + col = col.where("status", isEqualTo: package_processed_status); + pageQuery = + pageQuery.where("status", isEqualTo: package_processed_status); + } + + // packed status + if (index == 3) { + col = col.where("status", isEqualTo: package_packed_status); + pageQuery = pageQuery.where("status", isEqualTo: package_packed_status); + } + + // shipped status + if (index == 4) { + col = col.where("status", isEqualTo: package_shipped_status); + pageQuery = pageQuery.where("status", isEqualTo: package_shipped_status); + } + + // delivered status + if (index == 5) { + col = col.where("status", isEqualTo: package_delivered_status); + pageQuery = + pageQuery.where("status", isEqualTo: package_delivered_status); + } + + pageQuery = pageQuery.orderBy("update_time", descending: true); packages?.close(); packages = PaginatorListener( @@ -78,6 +108,12 @@ class PackageModel extends BaseModel { rowPerLoad: 30); } + onChanged(int index) { + selectedIndex = index; + _loadPaginationPackages(index); + notifyListeners(); + } + _loadPaginationCustomerPackages(bool isDelivered) { if (user == null) return; String path = "/$packages_collection"; @@ -102,7 +138,9 @@ class PackageModel extends BaseModel { if (user == null) return; if (!((user!.hasPackages() || user!.hasReceiving() || - user!.hasProcessing()))) return; + user!.hasProcessing()))) { + return; + } String path = "/$packages_collection"; Query col = FirebaseFirestore.instance @@ -142,7 +180,7 @@ class PackageModel extends BaseModel { String path = "/$packages_collection"; try { var snaps = await FirebaseFirestore.instance - .collection("$path") + .collection(path) .where("tracking_id", isEqualTo: trackingID) .where("is_deleted", isEqualTo: false) .get(const GetOptions(source: Source.server)); diff --git a/lib/pages/package/package_list.dart b/lib/pages/package/package_list.dart index 7de1f57..06a88a1 100644 --- a/lib/pages/package/package_list.dart +++ b/lib/pages/package/package_list.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/package/model/package_model.dart'; @@ -16,14 +18,15 @@ import 'package:provider/provider.dart'; class PackageList extends StatefulWidget { final bool forCustomer; - const PackageList({Key? key, this.forCustomer = true}) : super(key: key); + const PackageList({super.key, this.forCustomer = true}); @override _PackageListState createState() => _PackageListState(); } class _PackageListState extends State { - bool _isLoading = false; - int _selectedIndex = 1; + bool isLoading = false; + int _selectedIndexForCustomer = 1; + int _selectedIndex = 0; @override void initState() { @@ -33,8 +36,13 @@ class _PackageListState extends State { _init() { var model = context.read(); - _selectedIndex = model.selectedIndex; - model.initData(_selectedIndex, widget.forCustomer); + if (widget.forCustomer) { + _selectedIndexForCustomer = model.selectedIndexForCustomer; + model.initDataForCustomer(_selectedIndexForCustomer); + } else { + _selectedIndex = model.selectedIndex; + model.initData(_selectedIndex); + } if (mounted) { setState(() {}); @@ -53,23 +61,23 @@ class _PackageListState extends State { LocalPopupMenu( id: 1, textKey: "package.popupmenu.active", - selected: packageModel.selectedIndex == 1), + selected: packageModel.selectedIndexForCustomer == 1), LocalPopupMenu( id: 2, textKey: "package.popupmenu.delivered", - selected: packageModel.selectedIndex == 2) + selected: packageModel.selectedIndexForCustomer == 2) ], popupMenuCallback: (p) { - this.setState(() { - _selectedIndex = p.id; + setState(() { + _selectedIndexForCustomer = p.id; }); context .read() - .onChanged(_selectedIndex, widget.forCustomer); + .onChangedForCustomer(_selectedIndexForCustomer); }); return LocalProgress( - inAsyncCall: _isLoading, + inAsyncCall: isLoading, child: Scaffold( appBar: LocalAppBar( labelKey: 'package.title', @@ -84,7 +92,7 @@ class _PackageListState extends State { iconSize: 30, onPressed: () => searchPackage(context, callbackPackageSelect: _searchCallback)), - popupMenu + widget.forCustomer ? popupMenu : _menuFilteringWidget(context) ], ), body: PaginatorListView( @@ -98,11 +106,77 @@ class _PackageListState extends State { _searchCallback(Package package) async { var packageModel = Provider.of(context, listen: false); - Package? _package = await packageModel.getPackage(package.id!); - if (_package == null) return; + Package? package0 = await packageModel.getPackage(package.id!); + if (package0 == null) return; Navigator.push( context, - CupertinoPageRoute(builder: (context) => PackageInfo(package: _package)), + CupertinoPageRoute(builder: (context) => PackageInfo(package: package0)), + ); + } + + Widget _menuFilteringWidget(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(right: 5), + child: PopupMenuButton( + elevation: 3.2, + tooltip: '', + onSelected: (choice) async { + setState(() { + _selectedIndex = choice.id; + }); + + await context.read().onChanged(choice.id); + }, + icon: SizedBox( + width: 30, + height: 30, + child: Stack( + alignment: Alignment.center, + children: [ + const Icon( + Icons.filter_list, + color: Colors.white, + ), + _selectedIndex != 0 + ? Positioned( + bottom: 15, + right: 0, + child: Container( + width: 10, + height: 10, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: Colors.red, + ), + ), + ) + : Container() + ], + ), + ), + itemBuilder: (BuildContext context) { + return packageFiteringMenu.map((LocalPopupMenu choice) { + return PopupMenuItem( + value: choice, + child: Row( + children: [ + Flexible( + child: Text("${choice.text}", + style: TextStyle(color: Colors.black))), + const SizedBox( + width: 10, + ), + _selectedIndex == choice.id + ? const Icon( + Icons.check, + color: Colors.grey, + ) + : const SizedBox(), + ], + ), + ); + }).toList(); + }), ); } } diff --git a/lib/pages/package/package_list_row.dart b/lib/pages/package/package_list_row.dart index eee3313..7bfcd24 100644 --- a/lib/pages/package/package_list_row.dart +++ b/lib/pages/package/package_list_row.dart @@ -6,21 +6,20 @@ import 'package:flutter/material.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:intl/intl.dart'; -typedef CallbackPackageSelect(Package package); +typedef CallbackPackageSelect = Function(Package package); class PackageListRow extends StatelessWidget { final bool isCustomer; final Package package; final CallbackPackageSelect? callbackPackageSelect; final double dotSize = 15.0; - final DateFormat dateFormat = new DateFormat("dd MMM yyyy"); + final DateFormat dateFormat = DateFormat("dd MMM yyyy"); PackageListRow( - {Key? key, + {super.key, required this.package, this.callbackPackageSelect, - this.isCustomer = false}) - : super(key: key); + this.isCustomer = false}); @override Widget build(BuildContext context) { @@ -44,30 +43,30 @@ class PackageListRow extends StatelessWidget { Row( children: [ Expanded( - child: new Padding( + child: Padding( padding: const EdgeInsets.symmetric(vertical: 13), - child: new Row( + child: Row( children: [ Icon(Octicons.package, color: primaryColor), - new Expanded( + Expanded( child: Padding( padding: const EdgeInsets.only(left: 15), - child: new Column( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - new Text( + Text( package.id == null ? '' : package.trackingID!, - style: new TextStyle( + style: TextStyle( fontSize: 15.0, color: Colors.black), ), Padding( padding: const EdgeInsets.only(top: 5), - child: new Text( + child: Text( package.market == null ? '' : package.market!, - style: new TextStyle( - fontSize: 15.0, color: Colors.black), + style: TextStyle( + fontSize: 15.0, color: Colors.grey), ), ), ], @@ -88,12 +87,11 @@ class PackageListRow extends StatelessWidget { fontWeight: FontWeight.bold)), Padding( padding: const EdgeInsets.only(top: 5), - child: new Text( + child: Text( package.currentStatusDate != null ? dateFormat.format(package.currentStatusDate!) : '', - style: - new TextStyle(fontSize: 14.0, color: Colors.grey), + style: TextStyle(fontSize: 14.0, color: Colors.grey), ), ), ], diff --git a/lib/pages/processing/processing_list_row.dart b/lib/pages/processing/processing_list_row.dart index e308227..1ff6fdf 100644 --- a/lib/pages/processing/processing_list_row.dart +++ b/lib/pages/processing/processing_list_row.dart @@ -7,17 +7,16 @@ import 'package:intl/intl.dart'; import 'processing_info.dart'; -typedef CallbackPackageSelect(Package package); +typedef CallbackPackageSelect = Function(Package package); class ProcessingListRow extends StatelessWidget { final Package package; final CallbackPackageSelect? callbackPackageSelect; final double dotSize = 15.0; - final DateFormat dateFormat = new DateFormat("dd MMM yyyy"); + final DateFormat dateFormat = DateFormat("dd MMM yyyy"); ProcessingListRow( - {Key? key, required this.package, this.callbackPackageSelect}) - : super(key: key); + {super.key, required this.package, this.callbackPackageSelect}); @override Widget build(BuildContext context) { @@ -38,30 +37,30 @@ class ProcessingListRow extends StatelessWidget { child: Row( children: [ Expanded( - child: new Padding( + child: Padding( padding: const EdgeInsets.symmetric(vertical: 13.0), - child: new Row( + child: Row( children: [ Icon(FontAwesome.dropbox, color: primaryColor, size: 30), - new Expanded( + Expanded( child: Padding( padding: const EdgeInsets.only(left: 15), - child: new Column( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - new Text( + Text( package.trackingID == null ? '' : package.trackingID!, - style: new TextStyle( + style: TextStyle( fontSize: 15.0, color: Colors.black), ), Padding( padding: const EdgeInsets.only(top: 5.0), - child: new Text( + child: Text( package.market == null ? '' : package.market!, - style: new TextStyle( - fontSize: 15.0, color: Colors.black), + style: TextStyle( + fontSize: 15.0, color: Colors.grey), ), ), ], @@ -82,11 +81,11 @@ class ProcessingListRow extends StatelessWidget { fontWeight: FontWeight.bold)), Padding( padding: const EdgeInsets.only(top: 5), - child: new Text( + child: Text( package.currentStatusDate != null ? dateFormat.format(package.currentStatusDate!) : '', - style: new TextStyle(fontSize: 14.0, color: Colors.grey), + style: TextStyle(fontSize: 14.0, color: Colors.grey), ), ), ], diff --git a/lib/pages/profile/profile_page.dart b/lib/pages/profile/profile_page.dart index 50396ca..5c1b925 100644 --- a/lib/pages/profile/profile_page.dart +++ b/lib/pages/profile/profile_page.dart @@ -28,9 +28,11 @@ import 'account_delection_page.dart'; import 'add_recovery_email.dart'; import 'change_phone_number.dart'; -typedef void ProfileCallback(); +typedef ProfileCallback = void Function(); class Profile extends StatefulWidget { + const Profile({super.key}); + @override _ProfileState createState() => _ProfileState(); } @@ -52,9 +54,9 @@ class _ProfileState extends State { buildLanguage(LanguageModel languageModel) async { var lan = await languageModel.load(); - if (this.selectedLanguage != lan) { + if (selectedLanguage != lan) { setState(() { - this.selectedLanguage = lan; + selectedLanguage = lan; }); } } diff --git a/lib/pages/rates/cargo_editor.dart b/lib/pages/rates/cargo_editor.dart index 6645e4c..effc05c 100644 --- a/lib/pages/rates/cargo_editor.dart +++ b/lib/pages/rates/cargo_editor.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/main/util.dart'; @@ -6,6 +8,7 @@ import 'package:fcs/pages/widgets/local_app_bar.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:provider/provider.dart'; import '../widgets/local_text.dart'; @@ -13,32 +16,34 @@ import 'model/shipment_rate_model.dart'; class CargoEditor extends StatefulWidget { final CargoType? cargo; - CargoEditor({this.cargo}); + const CargoEditor({super.key, this.cargo}); @override _CargoEditorState createState() => _CargoEditorState(); } class _CargoEditorState extends State { - TextEditingController _descController = new TextEditingController(); - TextEditingController _rateController = new TextEditingController(); - TextEditingController _displayIndexController = new TextEditingController(); + TextEditingController descController = TextEditingController(); + TextEditingController rateController = TextEditingController(); + TextEditingController displayIndexController = TextEditingController(); bool _isLoading = false; late CargoType _cargo; bool _isNew = false; final _cargoFormKey = GlobalKey(); bool _isDefault = false; + bool _isMixCargo = false; @override void initState() { super.initState(); if (widget.cargo != null) { _cargo = widget.cargo!; - _descController.text = _cargo.name ?? ""; - _rateController.text = _cargo.rate.toStringAsFixed(2); - _displayIndexController.text = _cargo.displayIndex.toString(); + descController.text = _cargo.name ?? ""; + rateController.text = _cargo.rate.toStringAsFixed(2); + displayIndexController.text = _cargo.displayIndex.toString(); _isDefault = _cargo.isDefault; + _isMixCargo = _cargo.isMixCargo; } else { _isNew = true; } @@ -53,8 +58,8 @@ class _CargoEditorState extends State { Widget build(BuildContext context) { final typeBox = InputText( labelTextKey: 'cargo.type', - iconData: Icons.text_format, - controller: _descController, + iconData: Ionicons.text, + controller: descController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { @@ -66,8 +71,8 @@ class _CargoEditorState extends State { final rateBox = InputText( labelTextKey: 'cargo.rate', - iconData: Icons.attach_money, - controller: _rateController, + iconData: Fontisto.dollar, + controller: rateController, textInputType: TextInputType.number, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { @@ -80,8 +85,8 @@ class _CargoEditorState extends State { final displayIndexBox = InputText( labelTextKey: 'cargo.display_index', - iconData: Icons.numbers, - controller: _displayIndexController, + iconData: FontAwesome.sort_numeric_asc, + controller: displayIndexController, textInputType: TextInputType.number, autovalidateMode: AutovalidateMode.onUserInteraction, // validator: (value) { @@ -93,7 +98,7 @@ class _CargoEditorState extends State { ); final defaultBox = Padding( - padding: const EdgeInsets.symmetric(vertical: 20), + padding: const EdgeInsets.symmetric(vertical: 10), child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( child: Column( @@ -112,7 +117,7 @@ class _CargoEditorState extends State { scale: 0.7, alignment: Alignment.centerRight, child: CupertinoSwitch( - activeColor: primaryColor, + activeTrackColor: primaryColor, value: _isDefault, onChanged: (v) { setState(() { @@ -122,6 +127,34 @@ class _CargoEditorState extends State { ]), ); + final mixCargoBox = + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + LocalText( + context, + 'cargo.is_mix', + color: Colors.black54, + fontSize: 15, + ), + ], + ), + ), + Transform.scale( + scale: 0.7, + alignment: Alignment.centerRight, + child: CupertinoSwitch( + activeTrackColor: primaryColor, + value: _isMixCargo, + onChanged: (v) { + setState(() { + _isMixCargo = v; + }); + })) + ]); + return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( @@ -160,14 +193,16 @@ class _CargoEditorState extends State { typeBox, rateBox, displayIndexBox, + SizedBox(height: 10), defaultBox, + mixCargoBox, SizedBox(height: 30), ], ), ), fcsButton(context, getLocalString(context, "btn.save"), callack: _save), - SizedBox(height: 10) + SizedBox(height: 30) ], ), ), @@ -186,18 +221,19 @@ class _CargoEditorState extends State { try { var shipmentRateModel = Provider.of(context, listen: false); - CargoType _cargo = CargoType( - name: _descController.text, - rate: double.parse(_rateController.text), - displayIndex: _displayIndexController.text == '' + CargoType cargo = CargoType( + name: descController.text, + rate: double.parse(rateController.text), + displayIndex: displayIndexController.text == '' ? 0 - : int.parse(_displayIndexController.text), - isDefault: _isDefault); + : int.parse(displayIndexController.text), + isDefault: _isDefault, + isMixCargo: _isMixCargo); if (_isNew) { - await shipmentRateModel.addCargoType(_cargo); + await shipmentRateModel.addCargoType(cargo); } else { - _cargo.id = this._cargo.id; - await shipmentRateModel.updateCargoType(_cargo); + cargo.id = _cargo.id; + await shipmentRateModel.updateCargoType(cargo); } Navigator.pop(context); } catch (e) { @@ -220,7 +256,7 @@ class _CargoEditorState extends State { try { var shipmentRateModel = Provider.of(context, listen: false); - await shipmentRateModel.deleteCargoType(this._cargo.id!); + await shipmentRateModel.deleteCargoType(_cargo.id!); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); @@ -233,11 +269,19 @@ class _CargoEditorState extends State { isDataChanged() { if (_isNew) { - return _descController.text != "" || _rateController.text != ""; + return descController.text != "" || + rateController.text != "" || + displayIndexController.text != "" || + _isDefault != false || + _isMixCargo != false; } else { - CargoType _cargo = CargoType( - name: _descController.text, rate: double.parse(_rateController.text)); - return this._cargo.isChangedForEdit(_cargo); + CargoType cargo = CargoType( + name: descController.text, + rate: double.parse(rateController.text), + displayIndex: int.parse(displayIndexController.text), + isDefault: _isDefault, + isMixCargo: _isMixCargo); + return _cargo.isChangedForEdit(cargo); } } } diff --git a/lib/pages/rates/cargo_type_list.dart b/lib/pages/rates/cargo_type_list.dart index a9bfe53..a0d0689 100644 --- a/lib/pages/rates/cargo_type_list.dart +++ b/lib/pages/rates/cargo_type_list.dart @@ -11,13 +11,13 @@ import 'cargo_editor.dart'; import 'model/shipment_rate_model.dart'; class CargoTypeList extends StatefulWidget { - const CargoTypeList({Key? key}) : super(key: key); + const CargoTypeList({super.key}); @override _CargoTypeListState createState() => _CargoTypeListState(); } class _CargoTypeListState extends State { - bool _isLoading = false; + bool isLoading = false; @override void initState() { @@ -34,9 +34,9 @@ class _CargoTypeListState extends State { var shipmentRateModel = Provider.of(context); return LocalProgress( - inAsyncCall: _isLoading, + inAsyncCall: isLoading, child: Scaffold( - appBar: LocalAppBar(labelKey: "cargo.form.title"), + appBar: LocalAppBar(labelKey: "cargo.title"), floatingActionButton: FloatingActionButton.extended( onPressed: () { Navigator.of(context).push( @@ -44,8 +44,7 @@ class _CargoTypeListState extends State { }, icon: Icon(Icons.add, color: Colors.white), backgroundColor: primaryColor, - label: - LocalText(context, 'cargo.form.title', color: Colors.white)), + label: LocalText(context, 'cargo.new', color: Colors.white)), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView.separated( @@ -64,7 +63,7 @@ class _CargoTypeListState extends State { }, child: Container( child: _row(cargo.name ?? "", - "\$ " + cargo.rate.toStringAsFixed(2), 'per pound'), + "\$ ${cargo.rate.toStringAsFixed(2)}", 'per pound'), ), ); }), @@ -85,12 +84,12 @@ class _CargoTypeListState extends State { Padding( padding: const EdgeInsets.only(bottom: 3.0), child: Text( - '$price', + price, style: TextStyle(color: primaryColor, fontSize: 14), ), ), Text( - '$unit', + unit, style: TextStyle(color: Colors.grey, fontSize: 14), ), ], diff --git a/lib/pages/rates/custom_editor.dart b/lib/pages/rates/custom_editor.dart index 43d4dad..1fe909f 100644 --- a/lib/pages/rates/custom_editor.dart +++ b/lib/pages/rates/custom_editor.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/main/util.dart'; @@ -5,6 +7,7 @@ import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; @@ -12,19 +15,19 @@ import 'model/shipment_rate_model.dart'; class CustomEditor extends StatefulWidget { final CargoType? custom; - CustomEditor({this.custom}); + const CustomEditor({super.key, this.custom}); @override _CustomEditorState createState() => _CustomEditorState(); } class _CustomEditorState extends State { - TextEditingController _productController = new TextEditingController(); - TextEditingController _feeController = new TextEditingController(); - TextEditingController _shipmentRateController = new TextEditingController(); + TextEditingController productController = TextEditingController(); + TextEditingController feeController = TextEditingController(); + TextEditingController shipmentRateController = TextEditingController(); bool _isLoading = false; - CargoType _custom = new CargoType(); + CargoType _custom = CargoType(); bool _isNew = false; final _customFormKey = GlobalKey(); @@ -33,9 +36,9 @@ class _CustomEditorState extends State { super.initState(); if (widget.custom != null) { _custom = widget.custom!; - _productController.text = _custom.name ?? ""; - _feeController.text = _custom.customDutyFee.toStringAsFixed(2); - _shipmentRateController.text = _custom.rate.toStringAsFixed(2); + productController.text = _custom.name ?? ""; + feeController.text = _custom.customDutyFee.toStringAsFixed(2); + shipmentRateController.text = _custom.rate.toStringAsFixed(2); } else { _isNew = true; } @@ -49,20 +52,22 @@ class _CustomEditorState extends State { @override Widget build(BuildContext context) { final productBox = InputText( - labelTextKey: 'rate.cutom.product_type', - iconData: FontAwesomeIcons.weightHanging, - autovalidateMode: AutovalidateMode.onUserInteraction, - controller: _productController, - validator: (value){ - if(value==null || value.isEmpty){ - return "Please insert product type"; - } - return null; - },); + labelTextKey: 'rate.cutom.product_type', + iconData: FontAwesomeIcons.weightHanging, + autovalidateMode: AutovalidateMode.onUserInteraction, + controller: productController, + validator: (value) { + if (value == null || value.isEmpty) { + return "Please insert product type"; + } + return null; + }, + ); + final feeBox = InputText( labelTextKey: 'rate.custom.fee', - iconData: Icons.attach_money, - controller: _feeController, + iconData: Fontisto.dollar, + controller: feeController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { @@ -74,8 +79,8 @@ class _CustomEditorState extends State { final shipmentRateBox = InputText( labelTextKey: 'rate.custom.shipment_rate', - iconData: Icons.attach_money, - controller: _shipmentRateController, + iconData: Fontisto.dollar, + controller: shipmentRateController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { @@ -128,7 +133,7 @@ class _CustomEditorState extends State { ), fcsButton(context, getLocalString(context, "btn.save"), callack: _save), - SizedBox(height: 10) + SizedBox(height: 30) ], ), ), @@ -148,15 +153,15 @@ class _CustomEditorState extends State { try { var shipmentRateModel = Provider.of(context, listen: false); - CargoType _customduty = CargoType( - name: _productController.text, - customDutyFee: double.parse(_feeController.text), - rate: double.parse(_shipmentRateController.text)); + CargoType customduty = CargoType( + name: productController.text, + customDutyFee: double.parse(feeController.text), + rate: double.parse(shipmentRateController.text)); if (_isNew) { - await shipmentRateModel.addCustomDuty(_customduty); + await shipmentRateModel.addCustomDuty(customduty); } else { - _customduty.id = this._custom.id; - await shipmentRateModel.updateCustomDuty(_customduty); + customduty.id = _custom.id; + await shipmentRateModel.updateCustomDuty(customduty); } Navigator.pop(context); } catch (e) { @@ -180,7 +185,7 @@ class _CustomEditorState extends State { try { var shipmentRateModel = Provider.of(context, listen: false); - await shipmentRateModel.deleteCustomDuty(this._custom.id!); + await shipmentRateModel.deleteCustomDuty(_custom.id!); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); @@ -193,15 +198,15 @@ class _CustomEditorState extends State { isDataChanged() { if (_isNew) { - return _productController.text != "" || - _feeController.text != "" || - _shipmentRateController.text != ""; + return productController.text != "" || + feeController.text != "" || + shipmentRateController.text != ""; } else { - CargoType _customduty = CargoType( - name: _productController.text, - customDutyFee: double.parse(_feeController.text), - rate: double.parse(_shipmentRateController.text)); - return this._custom.isChangedForEditCustomDuty(_customduty); + CargoType customduty = CargoType( + name: productController.text, + customDutyFee: double.parse(feeController.text), + rate: double.parse(shipmentRateController.text)); + return _custom.isChangedForEditCustomDuty(customduty); } } } diff --git a/lib/pages/rates/custom_list.dart b/lib/pages/rates/custom_list.dart index 3d92211..f537cab 100644 --- a/lib/pages/rates/custom_list.dart +++ b/lib/pages/rates/custom_list.dart @@ -11,13 +11,13 @@ import 'model/shipment_rate_model.dart'; class CustomList extends StatefulWidget { final bool? selected; - const CustomList({Key? key, this.selected}) : super(key: key); + const CustomList({super.key, this.selected}); @override _CustomListState createState() => _CustomListState(); } class _CustomListState extends State { - bool _isLoading = false; + bool isLoading = false; bool _selected = false; @override @@ -38,7 +38,7 @@ class _CustomListState extends State { var shipmentRateModel = Provider.of(context); return LocalProgress( - inAsyncCall: _isLoading, + inAsyncCall: isLoading, child: Scaffold( appBar: LocalAppBar(labelKey: 'rate.custom_duty.title'), floatingActionButton: FloatingActionButton.extended( @@ -49,7 +49,7 @@ class _CustomListState extends State { icon: Icon(Icons.add, color: Colors.white), backgroundColor: primaryColor, label: - LocalText(context, 'rate.custom_duty', color: Colors.white)), + LocalText(context, 'rate.custom_new', color: Colors.white)), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView.separated( @@ -70,13 +70,11 @@ class _CustomListState extends State { child: Container( child: _row( custom.name ?? "", - "Custom Fee \$ " + - custom.customDutyFee.toStringAsFixed(2), + "Custom Fee \$ ${custom.customDutyFee.toStringAsFixed(2)}", // ignore: unnecessary_null_comparison custom.rate == null ? "" - : "Shipment rate \$ " + - custom.rate.toStringAsFixed(2)), + : "Shipment rate \$ ${custom.rate.toStringAsFixed(2)}"), ), ); }), @@ -97,7 +95,7 @@ class _CustomListState extends State { Padding( padding: const EdgeInsets.only(bottom: 3.0), child: Text( - '$fee', + fee, style: TextStyle(color: primaryColor, fontSize: 14), ), ), @@ -106,7 +104,7 @@ class _CustomListState extends State { : Padding( padding: const EdgeInsets.only(top: 3.0), child: Text( - "$shipmentRate", + shipmentRate, style: TextStyle(color: Colors.grey, fontSize: 14), ), ) diff --git a/lib/pages/rates/discount_by weight_list.dart b/lib/pages/rates/discount_by weight_list.dart index 5d22343..b4666b5 100644 --- a/lib/pages/rates/discount_by weight_list.dart +++ b/lib/pages/rates/discount_by weight_list.dart @@ -11,30 +11,20 @@ import 'package:provider/provider.dart'; import 'model/shipment_rate_model.dart'; class DiscountByWeightList extends StatefulWidget { - const DiscountByWeightList({Key? key}) : super(key: key); + const DiscountByWeightList({super.key}); @override _DiscountByWeightListState createState() => _DiscountByWeightListState(); } class _DiscountByWeightListState extends State { - bool _isLoading = false; - - @override - void initState() { - super.initState(); - } - - @override - void dispose() { - super.dispose(); - } + bool isLoading = false; @override Widget build(BuildContext context) { var shipmentRateModel = Provider.of(context); return LocalProgress( - inAsyncCall: _isLoading, + inAsyncCall: isLoading, child: Scaffold( appBar: LocalAppBar(labelKey: 'rate.discount_by_weight'), floatingActionButton: FloatingActionButton.extended( @@ -64,7 +54,7 @@ class _DiscountByWeightListState extends State { child: Container( child: _row( "${discountByWeight.weight.toStringAsFixed(2)} lb", - "\$ " + discountByWeight.discount.toString()), + "\$ ${discountByWeight.discount}"), ), ); }), @@ -85,7 +75,7 @@ class _DiscountByWeightListState extends State { Padding( padding: const EdgeInsets.only(bottom: 3.0), child: Text( - '$price', + price, style: TextStyle(color: primaryColor, fontSize: 14), ), ), diff --git a/lib/pages/rates/discount_by_weight_editor.dart b/lib/pages/rates/discount_by_weight_editor.dart index 5a6308f..bea935c 100644 --- a/lib/pages/rates/discount_by_weight_editor.dart +++ b/lib/pages/rates/discount_by_weight_editor.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:fcs/domain/entities/discount_by_weight.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/main/util.dart'; @@ -6,24 +8,25 @@ import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; class DiscountByWeightEditor extends StatefulWidget { final DiscountByWeight? discountByWeight; - DiscountByWeightEditor({this.discountByWeight}); + const DiscountByWeightEditor({super.key, this.discountByWeight}); @override _DiscountByWeightEditorState createState() => _DiscountByWeightEditorState(); } class _DiscountByWeightEditorState extends State { - TextEditingController _weightController = new TextEditingController(); - TextEditingController _discountController = new TextEditingController(); + TextEditingController weightController = TextEditingController(); + TextEditingController discountController = TextEditingController(); bool _isLoading = false; bool _isNew = false; - DiscountByWeight _discountByWeight = new DiscountByWeight(); + DiscountByWeight _discountByWeight = DiscountByWeight(); final _discountFormKey = GlobalKey(); @override @@ -31,8 +34,8 @@ class _DiscountByWeightEditorState extends State { super.initState(); if (widget.discountByWeight != null) { _discountByWeight = widget.discountByWeight!; - _weightController.text = _discountByWeight.weight.toStringAsFixed(2); - _discountController.text = _discountByWeight.discount.toString(); + weightController.text = _discountByWeight.weight.toStringAsFixed(2); + discountController.text = _discountByWeight.discount.toString(); _isNew = false; } else { _isNew = true; @@ -49,7 +52,7 @@ class _DiscountByWeightEditorState extends State { final weightBox = InputText( labelTextKey: 'rate.discount.weight', iconData: FontAwesomeIcons.weightHanging, - controller: _weightController, + controller: weightController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { @@ -60,8 +63,8 @@ class _DiscountByWeightEditorState extends State { ); final discountRateBox = InputText( labelTextKey: 'rate.discount.rate', - iconData: Icons.attach_money, - controller: _discountController, + iconData: Fontisto.dollar, + controller: discountController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { @@ -75,7 +78,7 @@ class _DiscountByWeightEditorState extends State { inAsyncCall: _isLoading, child: Scaffold( appBar: LocalAppBar( - labelKey: 'discount.new', + labelKey: 'discount.form', backgroundColor: Colors.white, labelColor: primaryColor, arrowColor: primaryColor, @@ -114,7 +117,7 @@ class _DiscountByWeightEditorState extends State { ), fcsButton(context, getLocalString(context, "btn.save"), callack: _save), - SizedBox(height: 10) + SizedBox(height: 30) ], ), ), @@ -134,14 +137,14 @@ class _DiscountByWeightEditorState extends State { try { var shipmentRateModel = Provider.of(context, listen: false); - DiscountByWeight _discount = DiscountByWeight( - weight: double.parse(_weightController.text), - discount: double.parse(_discountController.text)); + DiscountByWeight discount = DiscountByWeight( + weight: double.parse(weightController.text), + discount: double.parse(discountController.text)); if (_isNew) { - await shipmentRateModel.addDiscountByWeight(_discount); + await shipmentRateModel.addDiscountByWeight(discount); } else { - _discount.id = this._discountByWeight.id; - await shipmentRateModel.updateDiscountByWeight(_discount); + discount.id = _discountByWeight.id; + await shipmentRateModel.updateDiscountByWeight(discount); } Navigator.pop(context); } catch (e) { @@ -165,8 +168,7 @@ class _DiscountByWeightEditorState extends State { try { var shipmentRateModel = Provider.of(context, listen: false); - await shipmentRateModel - .deleteDiscountByWeight(this._discountByWeight.id!); + await shipmentRateModel.deleteDiscountByWeight(_discountByWeight.id!); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); @@ -179,12 +181,12 @@ class _DiscountByWeightEditorState extends State { isDataChanged() { if (_isNew) { - return _weightController.text != "" || _discountController.text != ""; + return weightController.text != "" || discountController.text != ""; } else { - DiscountByWeight _discount = DiscountByWeight( - weight: double.parse(_weightController.text), - discount: double.parse(_discountController.text)); - return this._discountByWeight.isChangedForEdit(_discount); + DiscountByWeight discount = DiscountByWeight( + weight: double.parse(weightController.text), + discount: double.parse(discountController.text)); + return _discountByWeight.isChangedForEdit(discount); } } } diff --git a/lib/pages/rates/shipment_rates_calculate.dart b/lib/pages/rates/shipment_rates_calculate.dart index 9fea9ce..5efb2a5 100644 --- a/lib/pages/rates/shipment_rates_calculate.dart +++ b/lib/pages/rates/shipment_rates_calculate.dart @@ -11,23 +11,24 @@ 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/material.dart'; -import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart'; +import 'package:flutter_vector_icons/flutter_vector_icons.dart'; + import 'package:provider/provider.dart'; class ShipmentRatesCal extends StatefulWidget { - ShipmentRatesCal(); + const ShipmentRatesCal({super.key}); @override _ShipmentRatesCalState createState() => _ShipmentRatesCalState(); } class _ShipmentRatesCalState extends State { - bool _isLoading = false; + bool isLoading = false; late CargoType _cargoType; - TextEditingController _widthController = new TextEditingController(); - TextEditingController _heightController = new TextEditingController(); - TextEditingController _lengthController = new TextEditingController(); - TextEditingController _actualWeightCtl = new TextEditingController(); + TextEditingController widthController = TextEditingController(); + TextEditingController heightController = TextEditingController(); + TextEditingController lengthController = TextEditingController(); + TextEditingController actualWeightCtl = TextEditingController(); double _shipmentWeight = 0; double _amount = 0; double _deliveryFee = 0; @@ -38,25 +39,25 @@ class _ShipmentRatesCalState extends State { //for shipment weight Rate rate = Provider.of(context, listen: false).rate; - _lengthController.addListener(_calShipmentWeight); - _widthController.addListener(_calShipmentWeight); - _heightController.addListener(_calShipmentWeight); - _actualWeightCtl.addListener(_calShipmentWeight); + lengthController.addListener(_calShipmentWeight); + widthController.addListener(_calShipmentWeight); + heightController.addListener(_calShipmentWeight); + actualWeightCtl.addListener(_calShipmentWeight); _cargoType = rate.defaultCargoType; - _lengthController.text = '12'; - _widthController.text = '12'; - _heightController.text = '12'; - _actualWeightCtl.text = "10.00"; + lengthController.text = '12'; + widthController.text = '12'; + heightController.text = '12'; + actualWeightCtl.text = "10.00"; _calShipmentWeight(); } _calShipmentWeight() { Rate rate = Provider.of(context, listen: false).rate; - double l = double.tryParse(_lengthController.text) ?? 0; - double w = double.tryParse(_widthController.text) ?? 0; - double h = double.tryParse(_heightController.text) ?? 0; - _cargoType.weight = double.tryParse(_actualWeightCtl.text) ?? 0; + double l = double.tryParse(lengthController.text) ?? 0; + double w = double.tryParse(widthController.text) ?? 0; + double h = double.tryParse(heightController.text) ?? 0; + _cargoType.weight = double.tryParse(actualWeightCtl.text) ?? 0; Carton box = Carton(cargoTypes: [_cargoType], length: l, width: w, height: h); var amount = box.calAmount(rate); @@ -83,15 +84,15 @@ class _ShipmentRatesCalState extends State { List cargos = shipmentRateModel.rate.cargoTypes; final lengthBox = LengthPicker( - controller: _lengthController, + controller: lengthController, lableKey: "box.length", ); final widthBox = LengthPicker( - controller: _widthController, + controller: widthController, lableKey: "box.width", ); final heightBox = LengthPicker( - controller: _heightController, + controller: heightController, lableKey: "box.height", ); @@ -102,9 +103,9 @@ class _ShipmentRatesCalState extends State { 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), + SizedBox(width: 80, child: lengthBox), + SizedBox(width: 80, child: widthBox), + SizedBox(width: 80, child: heightBox), ], ); @@ -115,7 +116,7 @@ class _ShipmentRatesCalState extends State { ); final actualWeightBox = InputText( - controller: _actualWeightCtl, + controller: actualWeightCtl, labelTextKey: "box.actual_weight", iconData: MaterialCommunityIcons.weight, textInputType: TextInputType.numberWithOptions(decimal: true), @@ -129,13 +130,13 @@ class _ShipmentRatesCalState extends State { }); }, labelKey: "cargo.type", - iconData: Icons.text_format, + iconData: Ionicons.text, selectedValue: _cargoType, values: cargos, ); return LocalProgress( - inAsyncCall: _isLoading, + inAsyncCall: isLoading, child: Scaffold( appBar: LocalAppBar( labelKey: "rate.cal.title", diff --git a/lib/pages/rates/shipment_rates_edit.dart b/lib/pages/rates/shipment_rates_edit.dart index e61f537..97a3e29 100644 --- a/lib/pages/rates/shipment_rates_edit.dart +++ b/lib/pages/rates/shipment_rates_edit.dart @@ -1,3 +1,5 @@ +// ignore_for_file: use_build_context_synchronously + import 'package:fcs/domain/entities/rate.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; @@ -5,13 +7,14 @@ import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import '../main/util.dart'; class ShipmentRatesEdit extends StatefulWidget { - ShipmentRatesEdit(); + const ShipmentRatesEdit({super.key}); @override _ShipmentRatesEditState createState() => _ShipmentRatesEditState(); @@ -19,11 +22,11 @@ class ShipmentRatesEdit extends StatefulWidget { class _ShipmentRatesEditState extends State { bool _isLoading = false; - TextEditingController _minWeight = new TextEditingController(); - TextEditingController _deliveryFee = new TextEditingController(); - TextEditingController _volumetricRatio = new TextEditingController(); - TextEditingController _diffDiscountWeight = new TextEditingController(); - TextEditingController _diffWeightRate = new TextEditingController(); + TextEditingController minWeight = TextEditingController(); + TextEditingController deliveryFee = TextEditingController(); + TextEditingController volumetricRatio = TextEditingController(); + TextEditingController diffDiscountWeight = TextEditingController(); + TextEditingController diffWeightRate = TextEditingController(); late Rate rate; @@ -34,11 +37,11 @@ class _ShipmentRatesEditState extends State { Provider.of(context, listen: false); rate = shipmentRateModel.rate; - _minWeight.text = rate.freeDeliveryWeight.toStringAsFixed(2); - _deliveryFee.text = rate.deliveryFee.toStringAsFixed(2); - _volumetricRatio.text = rate.volumetricRatio.toStringAsFixed(2); - _diffDiscountWeight.text = rate.diffDiscountWeight.toStringAsFixed(2); - _diffWeightRate.text = rate.diffWeightRate.toStringAsFixed(2); + minWeight.text = rate.freeDeliveryWeight.toStringAsFixed(2); + deliveryFee.text = rate.deliveryFee.toStringAsFixed(2); + volumetricRatio.text = rate.volumetricRatio.toStringAsFixed(2); + diffDiscountWeight.text = rate.diffDiscountWeight.toStringAsFixed(2); + diffWeightRate.text = rate.diffWeightRate.toStringAsFixed(2); } @override @@ -51,23 +54,27 @@ class _ShipmentRatesEditState extends State { final minWigBox = InputText( labelTextKey: 'rate.min_weight', iconData: FontAwesomeIcons.weightHanging, - controller: _minWeight); + controller: minWeight); + final feeBox = InputText( labelTextKey: 'rate.delivery_fee', - iconData: Icons.attach_money, - controller: _deliveryFee); + iconData: Fontisto.dollar, + controller: deliveryFee); + final ratioBox = InputText( labelTextKey: 'rate.volumetric_ratio', iconData: FontAwesomeIcons.weightHanging, - controller: _volumetricRatio); + controller: volumetricRatio); + final diffDiscountWeightBox = InputText( labelTextKey: 'rate.diff_discount_weight', iconData: FontAwesomeIcons.weightHanging, - controller: _diffDiscountWeight); + controller: diffDiscountWeight); + final diffWeightRateBox = InputText( labelTextKey: 'rate.diff_weight_rate', - iconData: Icons.attach_money, - controller: _diffWeightRate); + iconData: Fontisto.dollar, + controller: diffWeightRate); return LocalProgress( inAsyncCall: _isLoading, @@ -105,7 +112,7 @@ class _ShipmentRatesEditState extends State { ), fcsButton(context, getLocalString(context, "btn.save"), callack: _save), - SizedBox(height: 10) + SizedBox(height: 30) ], ), ), @@ -120,15 +127,14 @@ class _ShipmentRatesEditState extends State { try { var shipmentRateModel = Provider.of(context, listen: false); - Rate _rate = new Rate( - deliveryFee: double.parse(_deliveryFee.text), - freeDeliveryWeight: double.parse(_minWeight.text), - volumetricRatio: double.parse(_volumetricRatio.text), - diffDiscountWeight: double.parse(_diffDiscountWeight.text), - diffWeightRate: double.parse(_diffWeightRate.text)); - Rate r = new Rate(); - print('_rate =>$r'); - await shipmentRateModel.updateRate(_rate); + Rate rate = Rate( + deliveryFee: double.parse(deliveryFee.text), + freeDeliveryWeight: double.parse(minWeight.text), + volumetricRatio: double.parse(volumetricRatio.text), + diffDiscountWeight: double.parse(diffDiscountWeight.text), + diffWeightRate: double.parse(diffWeightRate.text)); + + await shipmentRateModel.updateRate(rate); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); @@ -140,13 +146,13 @@ class _ShipmentRatesEditState extends State { } isDataChanged() { - Rate _rate = new Rate( - deliveryFee: double.parse(_deliveryFee.text), - freeDeliveryWeight: double.parse(_minWeight.text), - volumetricRatio: double.parse(_volumetricRatio.text), - diffDiscountWeight: double.parse(_diffDiscountWeight.text), - diffWeightRate: double.parse(_diffWeightRate.text), + Rate rate = Rate( + deliveryFee: double.parse(deliveryFee.text), + freeDeliveryWeight: double.parse(minWeight.text), + volumetricRatio: double.parse(volumetricRatio.text), + diffDiscountWeight: double.parse(diffDiscountWeight.text), + diffWeightRate: double.parse(diffWeightRate.text), ); - return rate.isChangedForEdit(_rate); + return rate.isChangedForEdit(rate); } } diff --git a/lib/pages/receiving/receiving_list_row.dart b/lib/pages/receiving/receiving_list_row.dart index c863c33..ebc135d 100644 --- a/lib/pages/receiving/receiving_list_row.dart +++ b/lib/pages/receiving/receiving_list_row.dart @@ -7,17 +7,16 @@ import 'package:intl/intl.dart'; import 'receiving_info.dart'; -typedef CallbackPackageSelect(Package package); +typedef CallbackPackageSelect = Function(Package package); class ReceivingListRow extends StatelessWidget { final Package package; final CallbackPackageSelect? callbackPackageSelect; final double dotSize = 15.0; - final DateFormat dateFormat = new DateFormat("dd MMM yyyy"); + final DateFormat dateFormat = DateFormat("dd MMM yyyy"); ReceivingListRow( - {Key? key, required this.package, this.callbackPackageSelect}) - : super(key: key); + {super.key, required this.package, this.callbackPackageSelect}); @override Widget build(BuildContext context) { @@ -38,29 +37,29 @@ class ReceivingListRow extends StatelessWidget { child: Row( children: [ Expanded( - child: new Padding( + child: Padding( padding: const EdgeInsets.symmetric(vertical: 13.0), - child: new Row( + child: Row( children: [ Icon(MaterialCommunityIcons.inbox_arrow_down, color: primaryColor), - new Expanded( + Expanded( child: Padding( padding: const EdgeInsets.only(left: 15), - child: new Column( + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - new Text( + Text( package.id == null ? '' : package.trackingID!, - style: new TextStyle( + style: TextStyle( fontSize: 15.0, color: Colors.black), ), Padding( padding: const EdgeInsets.only(top: 5), - child: new Text( + child: Text( package.market == null ? '' : package.market!, - style: new TextStyle( - fontSize: 15.0, color: Colors.black), + style: TextStyle( + fontSize: 15.0, color: Colors.grey), ), ), ], @@ -81,11 +80,11 @@ class ReceivingListRow extends StatelessWidget { fontWeight: FontWeight.bold)), Padding( padding: const EdgeInsets.only(top: 5), - child: new Text( + child: Text( package.currentStatusDate != null ? dateFormat.format(package.currentStatusDate!) : '', - style: new TextStyle(fontSize: 14.0, color: Colors.grey), + style: TextStyle(fontSize: 14.0, color: Colors.grey), ), ), ], diff --git a/lib/pages/widgets/local_popup_menu_button.dart b/lib/pages/widgets/local_popup_menu_button.dart index 268f80e..6131883 100644 --- a/lib/pages/widgets/local_popup_menu_button.dart +++ b/lib/pages/widgets/local_popup_menu_button.dart @@ -15,14 +15,13 @@ class LocalPopupMenuButton extends StatefulWidget { final Color buttonColor; const LocalPopupMenuButton( - {Key? key, + {super.key, this.popupMenuCallback, this.popmenus, this.buttonIcon, this.selectable = true, this.multiSelect = false, - this.buttonColor = primaryColor}) - : super(key: key); + this.buttonColor = primaryColor}); @override _LocalPopupMenuButtonState createState() => _LocalPopupMenuButtonState(); @@ -46,30 +45,32 @@ class _LocalPopupMenuButtonState extends State { if (widget.selectable) { if (!widget.multiSelect) { setState(() { - popmenus.forEach((e) { - if (e.id != selected.id) + for (var e in popmenus) { + if (e.id != selected.id) { e.selected = false; - else + } else { e.selected = true; - }); + } + } }); selected.selected = true; } else { setState(() { - popmenus.forEach((e) { + for (var e in popmenus) { if (e.id == selected.id) e.selected = !e.selected; - }); + } }); selected.selected = !selected.selected; } } - if (selected.enabled && widget.popupMenuCallback != null) + if (selected.enabled && widget.popupMenuCallback != null) { widget.popupMenuCallback!(selected); + } }, icon: Container( width: 30, height: 30, - decoration: new BoxDecoration( + decoration: BoxDecoration( shape: BoxShape.circle, //color: Colors.white, ), @@ -87,7 +88,7 @@ class _LocalPopupMenuButtonState extends State { child: Container( width: 10, height: 10, - decoration: new BoxDecoration( + decoration: BoxDecoration( shape: BoxShape.circle, color: secondaryColor, ), @@ -109,7 +110,7 @@ class _LocalPopupMenuButtonState extends State { color: choice.enabled ? Colors.black : Colors.grey)) : LocalText(context, choice.textKey ?? "", - color: choice.enabled ? Colors.black : Colors.grey, + color: choice.enabled ? Colors.black : Colors.grey, fontSize: 14), SizedBox( width: 10, @@ -128,9 +129,9 @@ class _LocalPopupMenuButtonState extends State { } bool _needHighlight() { - popmenus.forEach((e) { - if (e.selected && e.highlight) return; - }); + for (var e in popmenus) { + if (e.selected && e.highlight) continue; + } return false; } }