From 4862f1123d1ef569684c19b0669554da02d2e3c9 Mon Sep 17 00:00:00 2001 From: Thinzar Win Date: Wed, 14 Oct 2020 16:53:16 +0630 Subject: [PATCH] update boxes --- assets/local/localization_en.json | 14 +- assets/local/localization_mu.json | 30 +- lib/domain/constants.dart | 2 +- lib/domain/entities/box.dart | 10 + lib/pages/box/box_editor.dart | 514 ++++++++++-------- lib/pages/box/box_info.dart | 551 ++++++++++++++++++++ lib/pages/box/box_list.dart | 2 +- lib/pages/box/box_list_row.dart | 16 +- lib/pages/box/model/box_model.dart | 11 +- lib/pages/shipment/shipment_box_editor.dart | 1 + lib/pages/widgets/length_picker.dart | 7 +- 11 files changed, 894 insertions(+), 264 deletions(-) create mode 100644 lib/pages/box/box_info.dart diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index 597a403..b6bf53a 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -242,13 +242,13 @@ "box.package.desc":"Description", "box.package.market":"Market", "box.add_package":"Add package", - "box.number":"Box number", + "box.number":"Carton number", "box.length":"Length", "box.width":"Width", "box.height":"Height", "box.shipment_info":"Shipment information", "box.cargo_type":"Cargo types", - "box.dimension":"Carton dimension", + "box.dimension":"Dimension", "box.delivery_address":"Delivery address", "box.fcs_shipment_num":"FCS shipment number", "box.fcs.id":"FCS ID", @@ -266,7 +266,13 @@ "box.tracking.id":"Tracking ID", "box.market":"Market", "box.cargo.save.btn":"Save", - "box.type.title":"Carton Types", + "box.type.title":"Carton types", + "box.shipment.boxes":"Cartons", + "box.shipment_number":"Shipment number", + "box.shipment.desc":"Description", + "box.mix.number":"Carton number", + "box.mix.desc":"Description", + "box.info.title":"Carton", "Boxes End ================================================================":"", "Delivery Start ================================================================":"", @@ -305,7 +311,7 @@ "shipment.edit.title": "Edit Shipment", "shipment.type": "Pickup/drop-off", "shipment.date": "Pickup date", - "shipment.date.time": "Pickup date/time", + "shipment.date.time": "Pickup date/Time", "shipment.time": "Pickup time", "shipment.location": "Pickup address", "shipment.location_time": "Pickup Location / Time", diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index f0c8617..36f5bf5 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -234,21 +234,21 @@ "Boxes Start ================================================================":"", "boxes.name":"သေတ္တာများ", - "boxes.title":"Boxes", + "boxes.title":"သေတ္တာများ", "boxes.new":"သေတ္တာ အသစ်", "boxes.create.title":"သေတ္တာ အသစ်", "box.edit.title":"သေတ္တာ ပြင်ဆင်ခြင်း", "box.package.id":"Package ID", - "box.package.desc":"Description", + "box.package.desc":"ဖော်ပြချက်", "box.package.market":"Market", "box.add_package":"Add Package", - "box.number":"Box နံပါတ်", + "box.number":"သေတ္တာ နံပါတ်", "box.length":"အလျား", "box.width":"အနံ", "box.height":"အမြင့်", "box.shipment_info":"တင်ပို့သတင်းအချက်အလက်", "box.cargo_type":"ကုန်ပစ္စည်းအမျိုးအစားများ", - "box.dimension":"သေတ္တာအရွယ်အစား", + "box.dimension":"အရွယ်အစား", "box.delivery_address":"ပို့ဆောင်ရမည့်လိပ်စာ", "box.fcs_shipment_num":"FCS တင်ပို့နံပါတ်", "box.fcs.id":"FCS ID", @@ -267,6 +267,12 @@ "box.market":"အွန်လိုင်စျေးဆိုင်", "box.cargo.save.btn":"သိမ်းဆည်းမည်", "box.type.title":"သေတ္တာအမျိုးအစားများ", + "box.shipment.boxes":"သေတ္တာများ", + "box.shipment_number":"ပို့ဆောင်နံပါတ်", + "box.shipment.desc":"ဖော်ပြချက်", + "box.mix.number":"သေတ္တာ နံပါတ်", + "box.mix.desc":"ဖော်ပြချက်", + "box.info.title":"သေတ္တာ", "Boxes End ================================================================":"", "Delivery Start ================================================================":"", @@ -305,23 +311,23 @@ "shipment.edit.title": "ပို့ဆောင်ခြင်း ပြင်ဆင်ခြင်း", "shipment.type": "Pickup/Drop-off", "shipment.date": "Pickup date", - "shipment.date.time": "Pickup date/time", - "shipment.time": "Pickup Time", - "shipment.location_time": "Pickup Location / Time", + "shipment.date.time": "Pickup date/Time", + "shipment.time": "Pickup time", + "shipment.location_time": "Pickup location / Time", "shipment.location": "Pickup location", "shipment.information": "Pickup informations", - "shipment.recipient_information": "Recipient Informations", + "shipment.recipient_information": "Recipient informations", "shipment.from":"From", "shipment.to":"To", - "shipment.box.delivery":"Delivery Address", - "shipment.handling.fee":"Handling Fee/Courier Fee", - "shipment.box.cargo.type":"Cargo Types", + "shipment.box.delivery":"Delivery address", + "shipment.handling.fee":"Handling fee/Courier fee", + "shipment.box.cargo.type":"Cargo types", "shipment.box.dimemsion":"Dimension", "shipment.box.shipment.weight":"Shipment weight", "shipment.box.length":"Length", "shipment.box.width":"Width", "shipment.box.height":"Height", - "shipment.box.add":"Add Box", + "shipment.box.add":"Add carton", "Shipment End ================================================================":"", "Rate Start ================================================================":"", diff --git a/lib/domain/constants.dart b/lib/domain/constants.dart index 185d202..88db0a9 100644 --- a/lib/domain/constants.dart +++ b/lib/domain/constants.dart @@ -58,4 +58,4 @@ const shipment_courier_dropoff = "Courier drop-off"; //Carton types const carton_from_packages = "From packages"; const carton_from_shipments = "From shipments"; -const carton_mix_box = "Mix box"; +const carton_mix_box = "Mix carton"; diff --git a/lib/domain/entities/box.dart b/lib/domain/entities/box.dart index 161336a..51dae8b 100644 --- a/lib/domain/entities/box.dart +++ b/lib/domain/entities/box.dart @@ -16,10 +16,15 @@ class Box { String boxNumber; String status; String cargoDesc; + String desc; int width; int height; int length; int shipmentWeight; + bool isChecked; + String cartonType; + String fcsID; + String userName; int rate; int weight; @@ -66,10 +71,15 @@ class Box { this.receiverNumber, this.receiverAddress, this.boxNumber, + this.desc, this.width, this.height, this.length, this.shipmentWeight, + this.isChecked = false, + this.cartonType, + this.fcsID, + this.userName, this.rate, this.weight, this.packageType, diff --git a/lib/pages/box/box_editor.dart b/lib/pages/box/box_editor.dart index 1f652a4..b283184 100644 --- a/lib/pages/box/box_editor.dart +++ b/lib/pages/box/box_editor.dart @@ -1,3 +1,4 @@ +import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/entities/box.dart'; import 'package:fcs/domain/entities/cargo.dart'; import 'package:fcs/domain/entities/package.dart'; @@ -5,7 +6,6 @@ import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/domain/vo/delivery_address.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/localization/app_translations.dart'; -import 'package:fcs/pages/delivery_address/delivery_address_list.dart'; import 'package:fcs/pages/delivery_address/delivery_address_row.dart'; import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; import 'package:fcs/pages/main/model/language_model.dart'; @@ -18,21 +18,16 @@ import 'package:fcs/pages/widgets/defalut_delivery_address.dart'; import 'package:fcs/pages/widgets/delivery_address_selection.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart'; -import 'package:fcs/pages/widgets/input_text.dart'; +import 'package:fcs/pages/widgets/length_picker.dart'; +import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/local_radio_buttons.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_title.dart'; -import 'package:fcs/pages/widgets/my_data_table.dart'; import 'package:fcs/pages/widgets/progress.dart'; -import 'package:fcs/pages/widgets/title_with_add_button.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_icons/flutter_icons.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import 'package:timeline_list/timeline.dart'; -import 'package:timeline_list/timeline_model.dart'; - import 'cargo_type_editor.dart'; import 'model/box_model.dart'; @@ -52,19 +47,22 @@ class _BoxEditorState extends State { Box _box; bool _isLoading = false; bool isNew; - bool isMixBox = false; DeliveryAddress _deliveryAddress = new DeliveryAddress(); User user; String _selectShipmentNumber; String _selectedCartonType; List _packages = []; + List _shipmentBoxes = []; + List _mixBoxes = []; List _cargoTypes = []; double volumetricRatio = 0; double shipmentWeight = 0; + Box _selectedShipmentBox; @override void initState() { super.initState(); + // for packages var packageModel = Provider.of(context, listen: false); _packages = [ packageModel.packages[0], @@ -73,6 +71,18 @@ class _BoxEditorState extends State { _packages.forEach((p) { p.isChecked = false; }); + + //for shipment boxes + var boxModel = Provider.of(context, listen: false); + _shipmentBoxes = [boxModel.boxes[0], boxModel.boxes[1], boxModel.boxes[2]]; + + //for mix boxes + _mixBoxes = [boxModel.boxes[0], boxModel.boxes[1], boxModel.boxes[2]]; + _mixBoxes.forEach((b) { + b.isChecked = false; + }); + + //for shipment weight volumetricRatio = Provider.of(context, listen: false).setting.volumetricRatio; _lengthController.addListener(_calShipmentWeight); @@ -87,6 +97,7 @@ class _BoxEditorState extends State { _widthController.text = _box.width.toString(); _heightController.text = _box.height.toString(); _lengthController.text = _box.length.toString(); + _selectedCartonType = _box.cartonType; isNew = false; } else { _cargoTypes = [ @@ -99,6 +110,7 @@ class _BoxEditorState extends State { Provider.of(context, listen: false); _deliveryAddress = shipmentModel.defalutAddress; isNew = true; + _selectedCartonType = carton_from_packages; } } @@ -116,46 +128,6 @@ class _BoxEditorState extends State { super.dispose(); } - final DateFormat dateFormat = DateFormat("d MMM yyyy"); - List _models() { - // return []; - return _box.shipmentHistory - .map((e) => TimelineModel( - Padding( - padding: const EdgeInsets.all(18.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(e.status, - style: TextStyle( - color: e.done ? primaryColor : Colors.grey, - fontSize: 16, - fontWeight: FontWeight.bold)), - e.status == "Processed" - ? Text("(Waiting for payment)", - style: TextStyle( - color: e.done ? primaryColor : Colors.grey, - fontSize: 14, - fontWeight: FontWeight.bold)) - : Container(), - Text(dateFormat.format(e.date)), - ], - ), - ), - iconBackground: e.done ? primaryColor : Colors.grey, - icon: Icon( - e.status == "Shipped" - ? Ionicons.ios_airplane - : e.status == "Delivered" - ? MaterialCommunityIcons.truck_fast - : e.status == "Processed" - ? MaterialIcons.check - : Octicons.package, - color: Colors.white, - ))) - .toList(); - } - @override Widget build(BuildContext context) { var languageModel = Provider.of(context); @@ -174,7 +146,7 @@ class _BoxEditorState extends State { Ionicons.ios_airplane, color: primaryColor, )), - items: ["A102", "A103", "A201", "A202"] + items: ["A204", "A203", "A201", "A202"] .map((e) => DropdownMenuItem( child: Text( e, @@ -189,33 +161,6 @@ class _BoxEditorState extends State { }, )); - final mixBox = Container( - child: new Row( - children: [ - new Checkbox( - value: isMixBox, - activeColor: primaryColor, - onChanged: (bool value) { - setState(() { - isMixBox = value; - }); - }), - SizedBox( - width: 5, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - new Text( - "Mix Box", - style: TextStyle(fontSize: 15.0), - ), - ], - ), - ], - ), - ); - final fcsIDBox = Row( children: [ Expanded( @@ -251,12 +196,12 @@ class _BoxEditorState extends State { child: Row( children: [ Container( - width: 40, + width: 30, ), Expanded( child: LocalText(context, 'box.tracking.id', color: Colors.grey), ), - LocalText(context, 'box.market', color: Colors.grey), + LocalText(context, 'box.package.desc', color: Colors.grey), ], ), ); @@ -294,9 +239,17 @@ class _BoxEditorState extends State { p.value.trackingID, style: textStyle, )), - new Text( - p.value.market == null ? "" : p.value.market, - style: textStyle, + new Column( + children: [ + new Text( + p.value.desc == null ? "" : p.value.desc, + style: textStyle, + ), + new Text( + "(${p.value.market == null ? "" : p.value.market})", + style: textStyle, + ) + ], ) ], ), @@ -305,6 +258,125 @@ class _BoxEditorState extends State { }).toList(); } + final shipmentBoxTitle = Container( + padding: EdgeInsets.only(right: 10.0, top: 20), + child: Row( + children: [ + Container( + width: 30, + ), + Expanded( + child: + LocalText(context, 'box.shipment_number', color: Colors.grey), + ), + LocalText(context, 'box.shipment.desc', color: Colors.grey), + ], + ), + ); + + List getshipmentBoxRowList() { + return _shipmentBoxes.asMap().entries.map((s) { + return Container( + color: Colors.grey[50].withOpacity(0.2), + child: Container( + padding: + EdgeInsets.only(left: 0.0, right: 10.0, top: 3.0, bottom: 3.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: s.key == _shipmentBoxes.length - 1 + ? Colors.white + : Colors.grey[350], + width: 1), + ), + ), + child: Row( + children: [ + Radio( + activeColor: primaryColor, + groupValue: _selectedShipmentBox, + value: s.value, + onChanged: (value) { + setState(() { + _selectedShipmentBox = value; + }); + }, + ), + Expanded( + child: new Text( + s.value.shipmentNumber, + style: textStyle, + )), + new Text( + s.value.desc == null ? "" : s.value.desc, + style: textStyle, + ), + ], + ), + ), + ); + }).toList(); + } + + final mixBoxTitle = Container( + padding: EdgeInsets.only(right: 10.0, top: 20), + child: Row( + children: [ + Container( + width: 30, + ), + Expanded( + child: LocalText(context, 'box.mix.number', color: Colors.grey), + ), + LocalText(context, 'box.mix.desc', color: Colors.grey), + ], + ), + ); + + List getMixBoxRowList() { + return _mixBoxes.asMap().entries.map((b) { + return Container( + color: b.value.isChecked + ? Colors.grey.withOpacity(0.2) + : Colors.grey[50].withOpacity(0.2), + child: Container( + padding: + EdgeInsets.only(left: 0.0, right: 10.0, top: 3.0, bottom: 3.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: b.key == _mixBoxes.length - 1 + ? Colors.white + : Colors.grey[350], + width: 1), + ), + ), + child: Row( + children: [ + Checkbox( + value: b.value.isChecked, + activeColor: primaryColor, + onChanged: (bool check) { + setState(() { + b.value.isChecked = check; + }); + }), + Expanded( + child: new Text( + b.value.packageNumber, + style: textStyle, + )), + new Text( + b.value.desc == null ? "" : b.value.desc, + style: textStyle, + ), + ], + ), + ), + ); + }).toList(); + } + final cargoTitle = Container( padding: EdgeInsets.only(left: 15, right: 0.0, top: 20), child: Row( @@ -328,11 +400,13 @@ class _BoxEditorState extends State { var rows = _cargoTypes.asMap().entries.map((c) { total += c.value.weight; return InkWell( - onTap: () { - Navigator.push( - context, - BottomUpPageRoute(CargoTypeEditor(cargo: c.value)), - ); + onTap: () async { + Cargo cargo = await Navigator.push( + context, + BottomUpPageRoute(CargoTypeEditor( + cargo: c.value, + ))); + _addCargo(cargo); }, child: Container( color: Colors.grey[50].withOpacity(0.2), @@ -411,58 +485,49 @@ class _BoxEditorState extends State { return rows; } - final shipmentWeightBox = Container( - padding: EdgeInsets.only(left: 10), - child: DisplayText( - text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", - labelTextKey: "box.shipment_weight", - iconData: MaterialCommunityIcons.weight, - )); + final lengthBox = LengthPicker( + controller: _lengthController, + lableKey: "box.length", + ); + final widthBox = LengthPicker( + controller: _widthController, + lableKey: "box.width", + ); + final heightBox = LengthPicker( + controller: _heightController, + lableKey: "box.height", + ); - final widthBox = Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: InputText( - labelTextKey: 'box.width', - iconData: FontAwesomeIcons.arrowCircleRight, - controller: _widthController)); + final dimBox = Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Icon(FontAwesome.arrow_circle_right, color: primaryColor), + ), + SizedBox(child: lengthBox, width: 80), + SizedBox(child: widthBox, width: 80), + SizedBox(child: heightBox, width: 80), + ], + ); - final heightBox = Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: InputText( - labelTextKey: 'box.height', - iconData: FontAwesomeIcons.arrowAltCircleUp, - controller: _heightController)); + final shipmentWeightBox = DisplayText( + text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", + labelTextKey: "box.shipment_weight", + iconData: MaterialCommunityIcons.weight, + ); - final lengthBox = Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: InputText( - labelTextKey: 'box.length', - iconData: FontAwesomeIcons.arrowCircleUp, - controller: _lengthController)); + final createBtn = LocalButton( + textKey: "box.create.btn", + ); - final createBtn = Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: fcsButton( - context, - getLocalString(context, 'box.create.btn'), - callack: () {}, - )); + final completeBtn = LocalButton( + textKey: "box.complete.btn", + ); - final completeBtn = Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: fcsButton( - context, - getLocalString(context, 'box.complete.btn'), - callack: () {}, - )); - - final deliveryBtn = Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: fcsButton( - context, - getLocalString(context, 'box.deliver.btn'), - callack: () {}, - )); + final deliveryBtn = LocalButton( + textKey: "box.deliver.btn", + ); return LocalProgress( inAsyncCall: _isLoading, @@ -470,7 +535,7 @@ class _BoxEditorState extends State { appBar: AppBar( centerTitle: true, leading: new IconButton( - icon: new Icon(Icons.close, color: primaryColor, size: 30), + icon: new Icon(CupertinoIcons.back, color: primaryColor, size: 30), onPressed: () => Navigator.of(context).pop(), ), shadowColor: Colors.transparent, @@ -517,106 +582,85 @@ class _BoxEditorState extends State { ), fcsIDBox, namebox, - LocalTitle(textKey: "box.packages"), - - Column( - children: [ - packageTitle, - Divider( - color: Colors.grey[400], - ), - Column( - children: getPackageRowList(), - ), - SizedBox(height: 10), - ], - ), - Divider(), - Container( - padding: EdgeInsets.only(left: 10), - child: TitleWithAddButton( - iconData: MaterialCommunityIcons.briefcase_check, - titleKey: "box.cargo_type", - onTap: () async { - Cargo cargo = await Navigator.push( - context, BottomUpPageRoute(CargoTypeEditor())); - if (cargo != null) { - setState(() { - _box.cargoTypes.add(cargo); - }); - } - }), - ), - Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: Column( - children: [ - cargoTitle, - Divider( - color: Colors.grey[400], - ), - Column( - children: getCargoRowList(), - ), - SizedBox(height: 10), - ], - ), - ), - Divider(), - SizedBox( - height: 10, - ), - TitleWithAddButton( - titleKey: "box.dimension", - ), - shipmentWeightBox, - widthBox, - heightBox, - lengthBox, - SizedBox(height: 25), - Divider(), - Container( - padding: EdgeInsets.only(left: 10, right: 10), - child: DefaultDeliveryAddress( - deliveryAddress: _deliveryAddress, - labelKey: "box.delivery_address", - onTap: () async { - DeliveryAddress d = await Navigator.push( - context, - BottomUpPageRoute(DeliveryAddressSelection( - deliveryAddress: _deliveryAddress, - )), - ); - if (d == null) return; - setState(() { - this._deliveryAddress = d; - }); - }), - ), - SizedBox(height: 15), - Divider(), - isNew - ? Container() - : Column( + _selectedCartonType == "From packages" + ? Column( children: [ - Padding( - padding: EdgeInsets.only(top: 10), - child: TitleWithAddButton( - titleKey: "box.status", - ), + LocalTitle(textKey: "box.packages"), + packageTitle, + Divider( + color: Colors.grey[400], ), - Container( - height: 230, - padding: EdgeInsets.only(left: 10), - child: isNew - ? Container() - : Timeline( - children: _models(), - position: TimelinePosition.Left), + Column( + children: getPackageRowList(), ), ], + ) + : _selectedCartonType == "From shipments" + ? Column( + children: [ + LocalTitle(textKey: "box.shipment.boxes"), + shipmentBoxTitle, + Divider( + color: Colors.grey[400], + ), + Column( + children: getshipmentBoxRowList(), + ), + ], + ) + : _selectedCartonType == "Mix carton" + ? Column( + children: [ + LocalTitle(textKey: "box.shipment.boxes"), + mixBoxTitle, + Divider( + color: Colors.grey[400], + ), + Column( + children: getMixBoxRowList(), + ) + ], + ) + : Container(), + LocalTitle( + textKey: "box.cargo_type", + trailing: IconButton( + icon: Icon( + Icons.add_circle, + color: primaryColor, ), - isNew ? Container() : Divider(), + onPressed: () async { + Cargo cargo = await Navigator.push( + context, BottomUpPageRoute(CargoTypeEditor())); + _addCargo(cargo); + }), + ), + cargoTitle, + Divider( + color: Colors.grey[400], + ), + Column( + children: getCargoRowList(), + ), + LocalTitle(textKey: "box.dimension"), + dimBox, + shipmentWeightBox, + LocalTitle(textKey: "box.delivery_address"), + DefaultDeliveryAddress( + deliveryAddress: _deliveryAddress, + labelKey: "box.delivery_address", + onTap: () async { + DeliveryAddress d = await Navigator.push( + context, + BottomUpPageRoute(DeliveryAddressSelection( + deliveryAddress: _deliveryAddress, + )), + ); + if (d == null) return; + setState(() { + this._deliveryAddress = d; + }); + }), SizedBox( height: 10, ), @@ -650,4 +694,12 @@ class _BoxEditorState extends State { ); }).toList(); } + + _addCargo(Cargo cargo) { + if (cargo == null) return; + setState(() { + _cargoTypes.remove(cargo); + _cargoTypes.add(cargo); + }); + } } diff --git a/lib/pages/box/box_info.dart b/lib/pages/box/box_info.dart new file mode 100644 index 0000000..63607d7 --- /dev/null +++ b/lib/pages/box/box_info.dart @@ -0,0 +1,551 @@ +import 'package:fcs/domain/constants.dart'; +import 'package:fcs/domain/entities/box.dart'; +import 'package:fcs/domain/entities/cargo.dart'; +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/domain/vo/delivery_address.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/main/model/main_model.dart'; +import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/package/model/package_model.dart'; +import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; +import 'package:fcs/pages/widgets/defalut_delivery_address.dart'; +import 'package:fcs/pages/widgets/display_text.dart'; +import 'package:fcs/pages/widgets/fcs_id_icon.dart'; +import 'package:fcs/pages/widgets/length_picker.dart'; +import 'package:fcs/pages/widgets/local_radio_buttons.dart'; +import 'package:fcs/pages/widgets/local_text.dart'; +import 'package:fcs/pages/widgets/local_title.dart'; +import 'package:fcs/pages/widgets/multi_img_controller.dart'; +import 'package:fcs/pages/widgets/multi_img_file.dart'; +import 'package:fcs/pages/widgets/progress.dart'; +import 'package:fcs/pages/widgets/status_tree.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_icons/flutter_icons.dart'; +import 'package:intl/intl.dart'; +import 'package:provider/provider.dart'; +import 'package:timeline_list/timeline.dart'; +import 'package:timeline_list/timeline_model.dart'; + +import 'box_editor.dart'; +import 'model/box_model.dart'; + +final DateFormat dateFormat = DateFormat("d MMM yyyy"); + +class BoxInfo extends StatefulWidget { + final Box box; + BoxInfo({this.box}); + + @override + _BoxInfoState createState() => _BoxInfoState(); +} + +class _BoxInfoState extends State { + bool _isLoading = false; + Box _box; + String _selectedCartonType; + String _shipmentNumber; + List _packages = []; + List _mixBoxes = []; + Box _selectedShipmentBox; + List _cargoTypes = []; + DeliveryAddress _deliveryAddress = new DeliveryAddress(); + TextEditingController _widthController = new TextEditingController(); + TextEditingController _heightController = new TextEditingController(); + TextEditingController _lengthController = new TextEditingController(); + double volumetricRatio = 0; + double shipmentWeight = 0; + + @override + void initState() { + super.initState(); + _box = widget.box; + _shipmentNumber = _box.shipmentNumber; + _selectedCartonType = _box.cartonType; + // for packages + var packageModel = Provider.of(context, listen: false); + _packages = [ + packageModel.packages[0], + packageModel.packages[1], + ]; + _packages.forEach((p) { + p.isChecked = false; + }); + + //for shipment boxes + var boxModel = Provider.of(context, listen: false); + _selectedShipmentBox = boxModel.boxes[0]; + + //for mix boxes + _mixBoxes = [boxModel.boxes[0], boxModel.boxes[1], boxModel.boxes[2]]; + _mixBoxes.forEach((b) { + b.isChecked = false; + }); + + //for shipment weight + volumetricRatio = + Provider.of(context, listen: false).setting.volumetricRatio; + _lengthController.addListener(_calShipmentWeight); + _widthController.addListener(_calShipmentWeight); + _heightController.addListener(_calShipmentWeight); + + _widthController.text = _box.width.toString(); + _heightController.text = _box.height.toString(); + _lengthController.text = _box.length.toString(); + + _cargoTypes = _box.cargoTypes; + _deliveryAddress = _box.shippingAddress; + } + + _calShipmentWeight() { + double l = double.parse(_lengthController.text, (s) => 0); + double w = double.parse(_widthController.text, (s) => 0); + double h = double.parse(_heightController.text, (s) => 0); + setState(() { + shipmentWeight = l * w * h / volumetricRatio; + }); + } + + @override + void dispose() { + super.dispose(); + } + + final DateFormat dateFormat = DateFormat("d MMM yyyy"); + List _models() { + // return []; + return _box.shipmentHistory + .map((e) => TimelineModel( + Padding( + padding: const EdgeInsets.all(18.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(e.status, + style: TextStyle( + color: e.done ? primaryColor : Colors.grey, + fontSize: 16, + fontWeight: FontWeight.bold)), + e.status == "Processed" + ? Text("(Waiting for payment)", + style: TextStyle( + color: e.done ? primaryColor : Colors.grey, + fontSize: 14, + fontWeight: FontWeight.bold)) + : Container(), + Text(dateFormat.format(e.date)), + ], + ), + ), + iconBackground: e.done ? primaryColor : Colors.grey, + icon: Icon( + e.status == "Shipped" + ? Ionicons.ios_airplane + : e.status == "Delivered" + ? MaterialCommunityIcons.truck_fast + : e.status == "Processed" + ? MaterialIcons.check + : Octicons.package, + color: Colors.white, + ))) + .toList(); + } + + @override + Widget build(BuildContext context) { + var boxModel = Provider.of(context); + + final shipmentBox = DisplayText( + text: _shipmentNumber == null ? "" : _shipmentNumber, + labelTextKey: "box.fcs_shipment_num", + iconData: Ionicons.ios_airplane, + ); + final fcsIDBox = DisplayText( + text: _box.fcsID == null ? "" : _box.fcsID, + labelTextKey: "box.fcs.id", + icon: FcsIDIcon(), + ); + + final customerNameBox = DisplayText( + text: _box.userName == null ? "" : _box.userName, + labelTextKey: "box.name", + iconData: Icons.person, + ); + + final packageTitle = Container( + padding: EdgeInsets.only(left: 15, right: 10.0, top: 20), + child: Row( + children: [ + Expanded( + child: LocalText(context, 'box.tracking.id', color: Colors.grey), + ), + LocalText(context, 'box.package.desc', color: Colors.grey), + ], + ), + ); + + List getPackageRowList() { + return _packages.asMap().entries.map((p) { + return Container( + color: Colors.grey[50].withOpacity(0.2), + child: Container( + padding: + EdgeInsets.only(left: 15.0, right: 10.0, top: 5.0, bottom: 5.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: p.key == _packages.length - 1 + ? Colors.white + : Colors.grey[350], + width: 1), + ), + ), + child: Row( + children: [ + Expanded( + child: new Text( + p.value.trackingID, + style: textStyle, + )), + new Column( + children: [ + new Text( + p.value.desc == null ? "" : p.value.desc, + style: textStyle, + ), + new Text( + "(${p.value.market == null ? "" : p.value.market})", + style: textStyle, + ) + ], + ) + ], + ), + ), + ); + }).toList(); + } + + final shipmentBoxTitle = Container( + padding: EdgeInsets.only(left: 15, right: 10.0, top: 20), + child: Row( + children: [ + Expanded( + child: + LocalText(context, 'box.shipment_number', color: Colors.grey), + ), + LocalText(context, 'box.shipment.desc', color: Colors.grey), + ], + ), + ); + + final shipmentBoxRow = Container( + padding: EdgeInsets.only(left: 15.0, right: 10.0, top: 5.0, bottom: 5.0), + child: Row( + children: [ + Expanded( + child: new Text( + _selectedShipmentBox.shipmentNumber == null + ? "" + : _selectedShipmentBox.shipmentNumber, + style: textStyle, + )), + new Text( + _selectedShipmentBox.desc == null ? "" : _selectedShipmentBox.desc, + style: textStyle, + ), + ], + ), + ); + + final mixBoxTitle = Container( + padding: EdgeInsets.only(left: 15, right: 10.0, top: 20), + child: Row( + children: [ + Expanded( + child: LocalText(context, 'box.mix.number', color: Colors.grey), + ), + LocalText(context, 'box.mix.desc', color: Colors.grey), + ], + ), + ); + + List getMixBoxRowList() { + return _mixBoxes.asMap().entries.map((b) { + return Container( + color: Colors.grey[50].withOpacity(0.2), + child: Container( + padding: EdgeInsets.only( + left: 15.0, right: 10.0, top: 13.0, bottom: 13.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: b.key == _mixBoxes.length - 1 + ? Colors.white + : Colors.grey[350], + width: 1), + ), + ), + child: Row( + children: [ + Expanded( + child: new Text( + b.value.packageNumber, + style: textStyle, + )), + new Text( + b.value.desc == null ? "" : b.value.desc, + style: textStyle, + ), + ], + ), + ), + ); + }).toList(); + } + + final cargoTitle = Container( + padding: EdgeInsets.only(left: 15, right: 0.0, top: 20), + child: Row( + children: [ + Expanded( + child: LocalText(context, 'cargo.type', color: Colors.grey), + ), + Container( + padding: EdgeInsets.only(right: 10), + child: LocalText(context, 'cargo.weight', color: Colors.grey)), + ], + ), + ); + + List getCargoRowList() { + if (_cargoTypes == null) { + return []; + } + int total = 0; + + var rows = _cargoTypes.asMap().entries.map((c) { + total += c.value.weight; + return InkWell( + onTap: () {}, + child: Container( + color: Colors.grey[50].withOpacity(0.2), + child: Container( + padding: EdgeInsets.only( + left: 15.0, right: 10.0, top: 13.0, bottom: 13.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: Colors.grey[350], width: 1), + ), + ), + child: Row( + children: [ + Expanded( + child: new Text( + c.value.type, + style: textStyle, + )), + Container( + padding: EdgeInsets.only(right: 10), + child: new Text( + c.value.weight == null ? "0" : c.value.weight.toString(), + style: textStyle, + ), + ) + ], + ), + ), + ), + ); + }).toList(); + + var totalRow = InkWell( + child: Container( + color: Colors.grey[50].withOpacity(0.2), + child: Container( + padding: + EdgeInsets.only(left: 15.0, right: 10.0, top: 15.0, bottom: 15.0), + child: Row( + children: [ + Expanded( + child: new Text( + "Total Weight", + style: TextStyle(fontWeight: FontWeight.bold), + )), + Padding( + padding: const EdgeInsets.only(right: 10.0), + child: Align( + alignment: Alignment.centerRight, + child: new Text( + total.toString(), + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + ) + ], + ), + ), + )); + + rows.add(totalRow); + return rows; + } + + final lengthBox = LengthPicker( + controller: _lengthController, + lableKey: "box.length", + isReadOnly: true, + ); + final widthBox = LengthPicker( + controller: _widthController, + lableKey: "box.width", + isReadOnly: true, + ); + final heightBox = LengthPicker( + controller: _heightController, + lableKey: "box.height", + isReadOnly: true, + ); + + final dimBox = Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: Icon(FontAwesome.arrow_circle_right, color: primaryColor), + ), + SizedBox(child: lengthBox, width: 80), + SizedBox(child: widthBox, width: 80), + SizedBox(child: heightBox, width: 80), + ], + ); + + final shipmentWeightBox = DisplayText( + text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", + labelTextKey: "box.shipment_weight", + iconData: MaterialCommunityIcons.weight, + ); + + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: new Icon(CupertinoIcons.back, color: primaryColor, size: 30), + onPressed: () => Navigator.of(context).pop(), + ), + shadowColor: Colors.transparent, + backgroundColor: Colors.white, + title: LocalText( + context, + "box.info.title", + fontSize: 20, + color: primaryColor, + ), + actions: [ + IconButton( + icon: Icon(Icons.edit, color: primaryColor), + onPressed: _gotoEditor, + ), + ], + ), + body: Card( + child: Column( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(10.0), + child: ListView(children: [ + Center(child: nameWidget(_box.packageNumber)), + SizedBox( + height: 10, + ), + LocalTitle(textKey: "box.type.title"), + LocalRadioButtons( + values: boxModel.cartonTypes, + selectedValue: _selectedCartonType, + callback: (v) {}), + LocalTitle(textKey: "box.shipment_info"), + shipmentBox, + fcsIDBox, + customerNameBox, + _selectedCartonType == "From packages" + ? Column( + children: [ + LocalTitle(textKey: "box.packages"), + packageTitle, + Divider( + color: Colors.grey[400], + ), + Column( + children: getPackageRowList(), + ), + ], + ) + : _selectedCartonType == "From shipments" + ? Column( + children: [ + LocalTitle(textKey: "box.shipment.boxes"), + shipmentBoxTitle, + Divider( + color: Colors.grey[400], + ), + shipmentBoxRow + ], + ) + : _selectedCartonType == "Mix carton" + ? Column( + children: [ + LocalTitle(textKey: "box.shipment.boxes"), + mixBoxTitle, + Divider( + color: Colors.grey[400], + ), + Column( + children: getMixBoxRowList(), + ) + ], + ) + : Container(), + LocalTitle(textKey: "box.cargo_type"), + cargoTitle, + Divider( + color: Colors.grey[400], + ), + Column( + children: getCargoRowList(), + ), + LocalTitle(textKey: "box.dimension"), + dimBox, + shipmentWeightBox, + LocalTitle(textKey: "box.delivery_address"), + DefaultDeliveryAddress( + deliveryAddress: _deliveryAddress, + labelKey: "box.delivery_address", + ), + LocalTitle(textKey: "box.status"), + Container( + height: 230, + child: Timeline( + children: _models(), position: TimelinePosition.Left), + ), + SizedBox( + height: 20, + ) + ]), + )), + ], + ), + ), + ), + ); + } + + _gotoEditor() async { + Navigator.push( + context, + BottomUpPageRoute(BoxEditor(box: widget.box)), + ); + } +} diff --git a/lib/pages/box/box_list.dart b/lib/pages/box/box_list.dart index 3447982..2672313 100644 --- a/lib/pages/box/box_list.dart +++ b/lib/pages/box/box_list.dart @@ -51,7 +51,7 @@ class _BoxListState extends State { Icons.search, color: Colors.white, ), - iconSize: 30, + iconSize: 30, onPressed: () {}, // onPressed: () => showPlacesSearch(context), ), ], diff --git a/lib/pages/box/box_list_row.dart b/lib/pages/box/box_list_row.dart index 5b4d7a1..6e08f8d 100644 --- a/lib/pages/box/box_list_row.dart +++ b/lib/pages/box/box_list_row.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'box_editor.dart'; +import 'box_info.dart'; class BoxListRow extends StatefulWidget { final bool isReadOnly; @@ -32,17 +33,10 @@ class _BoxListRowState extends State { padding: EdgeInsets.only(left: 15, right: 15), child: InkWell( onTap: () { - if (widget.isReadOnly) { - // Navigator.push( - // context, - // BottomUpPageRoute(PackageInfo(package: _box)), - // ); - } else { - Navigator.push( - context, - BottomUpPageRoute(BoxEditor(box: _box)), - ); - } + Navigator.push( + context, + BottomUpPageRoute(BoxInfo(box: _box)), + ); }, child: Row( children: [ diff --git a/lib/pages/box/model/box_model.dart b/lib/pages/box/model/box_model.dart index 524625b..41ba64c 100644 --- a/lib/pages/box/model/box_model.dart +++ b/lib/pages/box/model/box_model.dart @@ -38,6 +38,8 @@ class BoxModel extends BaseModel { status: "Packed", receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon', cargoDesc: "Clothes", + desc: "Desc 1", + cartonType: carton_from_packages, arrivedDate: DateTime(2020, 6, 1), width: 10, height: 10, @@ -58,7 +60,7 @@ class BoxModel extends BaseModel { Cargo(type: 'Dangerous', weight: 30) ]), Box( - shipmentNumber: "A202", + shipmentNumber: "A203", receiverNumber: "3", receiverName: "Ko Myo Min", boxNumber: "2", @@ -67,6 +69,7 @@ class BoxModel extends BaseModel { weight: 75, status: "Packed", cargoDesc: "Clothes", + desc: "Desc 2", arrivedDate: DateTime(2020, 6, 1), width: 10, height: 20, @@ -75,6 +78,7 @@ class BoxModel extends BaseModel { shipmentHistory: statusHistory, packages: packages, receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon', + cartonType: carton_from_shipments, shippingAddress: DeliveryAddress( fullName: 'Mg Myo', addressLine1: '153-154 5th Thitsar.', @@ -88,7 +92,7 @@ class BoxModel extends BaseModel { Cargo(type: 'Dangerous', weight: 30) ]), Box( - shipmentNumber: "A202", + shipmentNumber: "A204", receiverNumber: "3", receiverName: "Ko Myo Min", boxNumber: "3", @@ -97,6 +101,8 @@ class BoxModel extends BaseModel { weight: 75, cargoDesc: "Shoes", status: "Packed", + desc: "Desc 3", + cartonType: carton_mix_box, arrivedDate: DateTime(2020, 6, 1), width: 10, height: 10, @@ -127,6 +133,7 @@ class BoxModel extends BaseModel { weight: 75, status: "Packed", cargoDesc: "Dietary supplement", + desc: "Desc 4", arrivedDate: DateTime(2020, 6, 1), width: 10, height: 10, diff --git a/lib/pages/shipment/shipment_box_editor.dart b/lib/pages/shipment/shipment_box_editor.dart index af72644..5116a4c 100644 --- a/lib/pages/shipment/shipment_box_editor.dart +++ b/lib/pages/shipment/shipment_box_editor.dart @@ -178,6 +178,7 @@ class _ShipmentBoxEditorState extends State { LocalTitle(textKey: "shipment.box.delivery"), DefaultDeliveryAddress( deliveryAddress: _deliveryAddress, + labelKey: "shipment.box.delivery", onTap: () async { DeliveryAddress d = await Navigator.push( context, diff --git a/lib/pages/widgets/length_picker.dart b/lib/pages/widgets/length_picker.dart index c738e32..386e90d 100644 --- a/lib/pages/widgets/length_picker.dart +++ b/lib/pages/widgets/length_picker.dart @@ -8,8 +8,9 @@ import 'input_text.dart'; class LengthPicker extends StatefulWidget { final TextEditingController controller; final String lableKey; + final bool isReadOnly; - const LengthPicker({Key key, this.controller, this.lableKey}) + const LengthPicker({Key key, this.controller, this.lableKey, this.isReadOnly}) : super(key: key); @override @@ -40,7 +41,9 @@ class _LengthPickerState extends State { @override Widget build(BuildContext context) { return InkWell( - onTap: () => _showDialog(context), + onTap: () => widget.isReadOnly == null + ? _showDialog(context) + : widget.isReadOnly ? null : _showDialog(context), child: Padding( padding: EdgeInsets.only(left: 8, right: 8), child: InputText(