From 17ca3e2a3fb7a498d9bd7b33f819a0f6694ebbd3 Mon Sep 17 00:00:00 2001 From: tzw Date: Wed, 26 Mar 2025 15:51:47 +0630 Subject: [PATCH] update cargo type input, add package count and carton count for shipment info --- assets/local/localization_en.json | 6 +- assets/local/localization_mu.json | 6 +- lib/helpers/pdf.dart | 4 +- lib/pages/carton/cargo_widget.dart | 67 ++++++++++------- lib/pages/carton/carton_package_editor.dart | 6 +- lib/pages/carton/carton_package_form.dart | 5 +- .../carton/model/package_selection_model.dart | 1 + lib/pages/carton/print_qr_code_page.dart | 4 +- lib/pages/fcs_shipment/fcs_shipment_info.dart | 74 +++++++++++++------ .../model/fcs_shipment_model.dart | 26 +++++++ lib/pages/main/home_page.dart | 10 +++ 11 files changed, 156 insertions(+), 53 deletions(-) diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index 348f83f..3acd6f8 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -709,5 +709,9 @@ "pickup.customer.remark":"Customer Remark", "pickup.reschedul.remark":"Reschedule Remark", "pickup.delivery.address":"Delivery address", - "Pickup End ===================================================================":"" + "Pickup End ===================================================================":"", + + "Setting Start ================================================================":"", + "setting.title":"Settings", + "Setting End ===================================================================":"" } \ No newline at end of file diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index 03a16c8..a58a44b 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -711,5 +711,9 @@ "pickup.customer.remark":"ဝယ်သူ မှတ်ချက်", "pickup.reschedul.remark":"Reschedule Remark", "pickup.delivery.address":"ပို့ဆောင်ရမည့်လိပ်စာ", - "Pickup End ===================================================================":"" + "Pickup End ===================================================================":"", + + "Setting Start ================================================================":"", + "setting.title":"Settings", + "Setting End ===================================================================":"" } \ No newline at end of file diff --git a/lib/helpers/pdf.dart b/lib/helpers/pdf.dart index 97f05c4..d699242 100644 --- a/lib/helpers/pdf.dart +++ b/lib/helpers/pdf.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:fcs/pages/main/util.dart'; import 'package:flutter/services.dart'; import 'package:open_file/open_file.dart'; import 'package:path_provider/path_provider.dart'; @@ -53,7 +54,8 @@ Future generateCartonPdf(Carton carton) async { fontSize: 10, )), pw.SizedBox(height: 3), - pw.Text("${carton.actualWeight} lb", + pw.Text( + "${twoDecimalFormatted(double.tryParse(removeTrailingZeros(carton.actualWeight)) ?? 0)} lb", style: pw.TextStyle( fontSize: 10, color: PdfColor.fromInt(0xFF757575))) diff --git a/lib/pages/carton/cargo_widget.dart b/lib/pages/carton/cargo_widget.dart index 33016d5..b6810b6 100644 --- a/lib/pages/carton/cargo_widget.dart +++ b/lib/pages/carton/cargo_widget.dart @@ -16,8 +16,8 @@ import 'cargo_type_addition_dialog.dart'; import 'mix_cargo_type_addition_dialog.dart'; import 'surcharge_item_addition.dart'; -typedef OnPrevious = Function( - List cargoTypes, List customDuties); +typedef OnPrevious = Function(List cargoTypes, + List customDuties, double totalWeight); typedef OnContinue = Function( List cargoTypes, List customDuties); @@ -28,16 +28,17 @@ class CargoWidget extends StatefulWidget { final List surchargeItems; final OnPrevious? onPrevious; final OnContinue? onContinue; + final double totalWeight; - const CargoWidget({ - super.key, - required this.cargoTypes, - required this.surchargeItems, - this.onPrevious, - this.onContinue, - required this.sender, - required this.consignee, - }); + const CargoWidget( + {super.key, + required this.cargoTypes, + required this.surchargeItems, + this.onPrevious, + this.onContinue, + required this.sender, + required this.consignee, + this.totalWeight = 0}); @override State createState() => _CargoWidgetState(); @@ -54,7 +55,7 @@ class _CargoWidgetState extends State { bool get hasValueTotalWeight => totalCtl.text.isNotEmpty && totalCtl.text != '0.00'; bool get hasValueCargoes => - _cargoTypes.isNotEmpty && _cargoTypes.every((e) => e.weight != 0.00); + _cargoTypes.isNotEmpty && _cargoTypes.every((e) => e.weight != 0); double get actualTotalWeight => _cargoTypes.fold(0, (sum, value) => sum + value.weight); @@ -67,6 +68,7 @@ class _CargoWidgetState extends State { } _init() { + totalCtl.clear(); // for cargo types if (widget.cargoTypes.isNotEmpty) { _cargoTypes = List.from(widget.cargoTypes); @@ -77,6 +79,9 @@ class _CargoWidgetState extends State { editor.addListener(inputChangeListener); cargoTypeControllers.add(editor); } + totalCtl.text = twoDecimalFormatted( + double.tryParse(removeTrailingZeros(widget.totalWeight)) ?? 0); + _onPopulate(); } else { WidgetsBinding.instance.addPostFrameCallback((_) { @@ -130,7 +135,7 @@ class _CargoWidgetState extends State { List emptyFields = []; for (int i = 0; i < cargoTypeControllers.length; i++) { if (cargoTypeControllers[i].text.trim().isEmpty || - cargoTypeControllers[i].text.trim() == "0") { + cargoTypeControllers[i].text.trim() == "0.00") { emptyFields.add(i); } } @@ -143,7 +148,6 @@ class _CargoWidgetState extends State { double.tryParse(removeTrailingZeros(actualTotalWeight)) ?? 0); error = null; } else { - // auto populate remaining value double totalWeight = (double.tryParse(totalCtl.text) ?? 0); if (actualTotalWeight > totalWeight) { @@ -156,6 +160,7 @@ class _CargoWidgetState extends State { List emptyFieldIndexes = getEmptyFields(); if (emptyFieldIndexes.isNotEmpty) { + // auto populate remaining value if (emptyFieldIndexes.length == 1) { _cargoTypes.asMap().entries.forEach((e) { if (e.value.weight == 0) { @@ -164,7 +169,11 @@ class _CargoWidgetState extends State { double.tryParse(removeTrailingZeros(e.value.weight)) ?? 0); } }); + } else { + _onCheckTotalWeight(twoDecimalFormatted(totalWeight)); } + } else { + _onCheckTotalWeight(twoDecimalFormatted(totalWeight)); } } } @@ -185,6 +194,18 @@ class _CargoWidgetState extends State { } } + @override + void dispose() { + for (var controller in cargoTypeControllers) { + controller.dispose(); + } + + for (var controller in surchargeControllers) { + controller.dispose(); + } + super.dispose(); + } + @override Widget build(BuildContext context) { final senderBox = userDisplayBox(context, @@ -281,11 +302,7 @@ class _CargoWidgetState extends State { child: inputTextFieldWidget(context, lableText: "Total", controller: totalCtl, onFieldSubmitted: (newValue) { - if (hasValueCargoes) { - _onCheckTotalWeight(newValue); - } else { - _onPopulate(); - } + _onCheckTotalWeight(newValue); }, suffixIcon: InkResponse( radius: 23, @@ -397,13 +414,9 @@ class _CargoWidgetState extends State { ); final previousBtn = PreviousButton(onTap: () { - if (error != null) { - showMsgDialog( - context, "Error", "Please add the right cargo type weight"); - return; - } if (widget.onPrevious != null) { - widget.onPrevious!(_cargoTypes, _surchareItems); + widget.onPrevious!( + _cargoTypes, _surchareItems, double.tryParse(totalCtl.text) ?? 0); } }); @@ -595,9 +608,11 @@ class _CargoWidgetState extends State { Function(String)? onChanged, Function(String)? onFieldSubmitted, bool readOnly = false, - Widget? suffixIcon}) { + Widget? suffixIcon, + FocusNode? focusNode}) { return TextFormField( controller: controller, + focusNode: focusNode, style: textStyle, cursorColor: primaryColor, keyboardType: TextInputType.number, diff --git a/lib/pages/carton/carton_package_editor.dart b/lib/pages/carton/carton_package_editor.dart index 7e561e7..15ba3fc 100644 --- a/lib/pages/carton/carton_package_editor.dart +++ b/lib/pages/carton/carton_package_editor.dart @@ -47,6 +47,7 @@ class _CartonPackageEditorState extends State { List _cargoTypes = []; List _surchareItems = []; + double _totalWeight = 0; int currentStep = 0; double _length = 0; @@ -89,6 +90,7 @@ class _CartonPackageEditorState extends State { widget.carton.cargoTypes.map((e) => e.cloneForCarton()).toList(); _surchareItems = widget.carton.surchareItems.map((e) => e.cloneForSurchage()).toList(); + _totalWeight = _cargoTypes.fold(0, (sum, value) => sum + value.weight); // check carton size type List cartonSizes = context.read().cartonSizes; @@ -252,6 +254,7 @@ class _CartonPackageEditorState extends State { consignee: _consignee!, cargoTypes: _cargoTypes, surchargeItems: _surchareItems, + totalWeight: _totalWeight, onContinue: (cargoTypes, customDuties) { setState(() { _cargoTypes = List.from(cargoTypes); @@ -259,8 +262,9 @@ class _CartonPackageEditorState extends State { currentStep += 1; }); }, - onPrevious: (cargoTypes, customDuties) { + onPrevious: (cargoTypes, customDuties, totalWeight) { setState(() { + _totalWeight = totalWeight; _cargoTypes = List.from(cargoTypes); _surchareItems = List.from(customDuties); currentStep -= 1; diff --git a/lib/pages/carton/carton_package_form.dart b/lib/pages/carton/carton_package_form.dart index 5f87927..7ae4785 100644 --- a/lib/pages/carton/carton_package_form.dart +++ b/lib/pages/carton/carton_package_form.dart @@ -50,6 +50,7 @@ class _CartonPackageFormState extends State { List _cargoTypes = []; List _surchareItems = []; + double _totalWeight = 0; int currentStep = 0; double _length = 0; @@ -188,6 +189,7 @@ class _CartonPackageFormState extends State { consignee: widget.consignee, cargoTypes: _cargoTypes, surchargeItems: _surchareItems, + totalWeight: _totalWeight, onContinue: (cargoTypes, customDuties) { setState(() { _cargoTypes = List.from(cargoTypes); @@ -195,8 +197,9 @@ class _CartonPackageFormState extends State { currentStep += 1; }); }, - onPrevious: (cargoTypes, customDuties) { + onPrevious: (cargoTypes, customDuties, totalWeight) { setState(() { + _totalWeight = totalWeight; _cargoTypes = List.from(cargoTypes); _surchareItems = List.from(customDuties); currentStep -= 1; diff --git a/lib/pages/carton/model/package_selection_model.dart b/lib/pages/carton/model/package_selection_model.dart index 3e91adc..fba9872 100644 --- a/lib/pages/carton/model/package_selection_model.dart +++ b/lib/pages/carton/model/package_selection_model.dart @@ -174,6 +174,7 @@ class PackageSelectionModel extends BaseModel { .where("sender_id", isEqualTo: senderId) .where("user_id", isEqualTo: consigneeId) .where("fcs_shipment_id", isEqualTo: shipmentId) + .where("delete_time", isEqualTo: 0) .count() .get(); diff --git a/lib/pages/carton/print_qr_code_page.dart b/lib/pages/carton/print_qr_code_page.dart index f751128..91f8511 100644 --- a/lib/pages/carton/print_qr_code_page.dart +++ b/lib/pages/carton/print_qr_code_page.dart @@ -1,5 +1,6 @@ import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/local_button.dart'; import 'package:flutter/material.dart'; @@ -42,7 +43,8 @@ class PrintQrCodePage extends StatelessWidget { TextStyle(fontSize: 16, fontFamily: "Roboto")), Padding( padding: const EdgeInsets.only(top: 3), - child: Text("${carton.actualWeight} lb", + child: Text( + "${twoDecimalFormatted(double.tryParse(removeTrailingZeros(carton.actualWeight)) ?? 0)} lb", style: TextStyle( fontSize: 16, color: labelColor, diff --git a/lib/pages/fcs_shipment/fcs_shipment_info.dart b/lib/pages/fcs_shipment/fcs_shipment_info.dart index 2952e5e..e58ceda 100644 --- a/lib/pages/fcs_shipment/fcs_shipment_info.dart +++ b/lib/pages/fcs_shipment/fcs_shipment_info.dart @@ -42,6 +42,8 @@ class _FcsShipmentInfoState extends State { TextEditingController portController = TextEditingController(); TextEditingController destinationController = TextEditingController(); TextEditingController statusController = TextEditingController(); + int _packageCount = 0; + int _cartonCount = 0; @override void initState() { @@ -50,25 +52,56 @@ class _FcsShipmentInfoState extends State { _load(); } - _load() { - shipmentNumberController.text = _fcsShipment.shipmentNumber ?? ""; - if (_fcsShipment.cutoffDate != null) { - cutoffDateController.text = - dateFormatter.format(_fcsShipment.cutoffDate!); - } - if (_fcsShipment.etaDate != null) { - arrivalDateController.text = dateFormatter.format(_fcsShipment.etaDate!); - } - if (_fcsShipment.departureDate != null) { - departureDateControler.text = - dateFormatter.format(_fcsShipment.departureDate!); - } + _load() async { + try { + _isLoading = true; + shipmentNumberController.text = _fcsShipment.shipmentNumber ?? ""; + if (_fcsShipment.cutoffDate != null) { + cutoffDateController.text = + dateFormatter.format(_fcsShipment.cutoffDate!); + } + if (_fcsShipment.etaDate != null) { + arrivalDateController.text = + dateFormatter.format(_fcsShipment.etaDate!); + } + if (_fcsShipment.departureDate != null) { + departureDateControler.text = + dateFormatter.format(_fcsShipment.departureDate!); + } - shipmentTypeControler.text = _fcsShipment.shipmentTypeName ?? ""; - consigneeController.text = _fcsShipment.consigneeName ?? ''; - portController.text = _fcsShipment.loadingPortName ?? ''; - destinationController.text = _fcsShipment.destinationPortName ?? ''; - statusController.text = _fcsShipment.status ?? ""; + shipmentTypeControler.text = _fcsShipment.shipmentTypeName ?? ""; + consigneeController.text = _fcsShipment.consigneeName ?? ''; + portController.text = _fcsShipment.loadingPortName ?? ''; + destinationController.text = _fcsShipment.destinationPortName ?? ''; + statusController.text = _fcsShipment.status ?? ""; + + await Future.wait([_loadPackageCount(), _loadCartonCount()]); + } finally { + _isLoading = false; + } + if (mounted) { + setState(() {}); + } + } + + Future _loadPackageCount() async { + int? count = await context + .read() + .getPackageCount(fcsShipmentId: _fcsShipment.id ?? ""); + _packageCount = count ?? 0; + if (mounted) { + setState(() {}); + } + } + + Future _loadCartonCount() async { + int? count = await context + .read() + .getCartonCount(fcsShipmentId: _fcsShipment.id ?? ""); + _cartonCount = count ?? 0; + if (mounted) { + setState(() {}); + } } @override @@ -90,13 +123,13 @@ class _FcsShipmentInfoState extends State { ); final cartonBox = DisplayText( - text: numberFormatter.format(_fcsShipment.cartonCount), + text: numberFormatter.format(_cartonCount), labelTextKey: "FCSshipment.carton", iconData: MaterialCommunityIcons.package, ); final packageBox = DisplayText( - text: numberFormatter.format(_fcsShipment.packageCount), + text: numberFormatter.format(_packageCount), labelTextKey: "FCSshipment.package", iconData: Octicons.package, ); @@ -196,7 +229,6 @@ class _FcsShipmentInfoState extends State { style: TextStyle(fontSize: 15, color: Colors.black)) ], ), - backgroundColor: Colors.white, labelColor: primaryColor, arrowColor: primaryColor, diff --git a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart index 72254b1..3d63f80 100644 --- a/lib/pages/fcs_shipment/model/fcs_shipment_model.dart +++ b/lib/pages/fcs_shipment/model/fcs_shipment_model.dart @@ -314,4 +314,30 @@ class FcsShipmentModel extends BaseModel { } return fcsShipments; } + + Future getPackageCount({required String fcsShipmentId}) async { + String path = "/$packages_collection"; + + AggregateQuerySnapshot query = await FirebaseFirestore.instance + .collection(path) + .where("fcs_shipment_id", isEqualTo: fcsShipmentId) + .where("delete_time", isEqualTo: 0) + .count() + .get(); + + return query.count; + } + + Future getCartonCount({required String fcsShipmentId}) async { + String path = "/$cartons_collection"; + + AggregateQuerySnapshot query = await FirebaseFirestore.instance + .collection(path) + .where("fcs_shipment_id", isEqualTo: fcsShipmentId) + .where("delete_time", isEqualTo: 0) + .count() + .get(); + + return query.count; + } } diff --git a/lib/pages/main/home_page.dart b/lib/pages/main/home_page.dart index cba4d63..894613e 100644 --- a/lib/pages/main/home_page.dart +++ b/lib/pages/main/home_page.dart @@ -350,6 +350,14 @@ class _HomePageState extends State { btnCallback: () => Navigator.of(context).push( CupertinoPageRoute(builder: (context) => DeliverList()))); + // final setttingBtn = TaskButton( + // "setting.title", + // icon: Ionicons.ios_settings_outline, + // btnCallback: () => Navigator.of(context).push(CupertinoPageRoute( + // builder: (context) => StaffList(), + // )), + // ); + List widgets = []; List widgetsFcs = []; widgets.add(notiBtn); @@ -372,8 +380,10 @@ class _HomePageState extends State { if (user.hasCustomers()) widgetsFcs.add(customersBtn); if (user.hasAdmin()) widgetsFcs.add(discountBtn); if (user.hasStaffs()) widgetsFcs.add(staffBtn); + // widgetsFcs.add(setttingBtn); } widgets.add(faqBtn); + // widgets.add(setttingBtn); final fcsToggle = ToggleButtons( selectedColor: Colors.white,