import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/entities/box.dart'; import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/domain/entities/package.dart'; 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_row.dart'; import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; import 'package:fcs/pages/main/model/language_model.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/rates/model/shipment_rate_model.dart'; import 'package:fcs/pages/user_search/user_serach.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/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/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/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_icons/flutter_icons.dart'; import 'package:provider/provider.dart'; import 'cargo_type_editor.dart'; import 'model/box_model.dart'; class BoxEditor extends StatefulWidget { final Box box; BoxEditor({this.box}); @override _BoxEditorState createState() => _BoxEditorState(); } class _BoxEditorState extends State { TextEditingController _widthController = new TextEditingController(); TextEditingController _heightController = new TextEditingController(); TextEditingController _lengthController = new TextEditingController(); Box _box; bool _isLoading = false; bool isNew; 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], packageModel.packages[1], ]; _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) .rate .volumetricRatio; _lengthController.addListener(_calShipmentWeight); _widthController.addListener(_calShipmentWeight); _heightController.addListener(_calShipmentWeight); if (widget.box != null) { _box = widget.box; _deliveryAddress = _box.deliveryAddress; _cargoTypes = _box.cargoTypes; _selectShipmentNumber = _box.shipmentNumber; _widthController.text = _box.width.toString(); _heightController.text = _box.height.toString(); _lengthController.text = _box.length.toString(); _selectedCartonType = _box.cartonType; isNew = false; } else { _cargoTypes = [ CargoType(id: "1", name: 'General', weight: 25), CargoType(id: "2", name: 'Medicine', weight: 20), CargoType(id: "3", name: 'Dangerous', weight: 30) ]; var shipmentModel = Provider.of(context, listen: false); _deliveryAddress = shipmentModel.defalutAddress; isNew = true; _selectedCartonType = carton_from_packages; } } _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(); } @override Widget build(BuildContext context) { var languageModel = Provider.of(context); var boxModel = Provider.of(context); var shipmentBox = Container( child: DropdownButtonFormField( value: _selectShipmentNumber, decoration: InputDecoration( fillColor: Colors.white, labelText: AppTranslations.of(context).text("box.fcs_shipment_num"), labelStyle: languageModel.isEng ? TextStyle(fontWeight: FontWeight.w500) : TextStyle(fontWeight: FontWeight.w500, fontFamily: "Myanmar3"), icon: Icon( Ionicons.ios_airplane, color: primaryColor, )), items: ["A204", "A203", "A201", "A202"] .map((e) => DropdownMenuItem( child: Text( e, style: TextStyle(color: primaryColor), ), value: e)) .toList(), onChanged: (value) { setState(() { _selectShipmentNumber = value; }); }, )); final fcsIDBox = Row( children: [ Expanded( child: DisplayText( text: user != null ? user.fcsID : "", labelTextKey: "box.fcs.id", icon: FcsIDIcon(), )), IconButton( icon: Icon(Icons.search, color: primaryColor), onPressed: () => searchUser(context, callbackUserSelect: (u) { setState(() { this.user = u; }); })), ], ); final phoneNumberBox = DisplayText( text: user != null ? user.phoneNumber : "", labelTextKey: "box.phone", iconData: Icons.phone, ); final namebox = DisplayText( text: user != null ? user.name : "", labelTextKey: "box.name", iconData: Icons.person, ); final packageTitle = Container( padding: EdgeInsets.only(right: 10.0, top: 20), child: Row( children: [ Container( width: 30, ), 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: p.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: p.key == _packages.length - 1 ? Colors.white : Colors.grey[350], width: 1), ), ), child: Row( children: [ Checkbox( value: p.value.isChecked, activeColor: primaryColor, onChanged: (bool check) { setState(() { p.value.isChecked = check; }); }), 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(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( children: [ Expanded( child: LocalText(context, 'cargo.type', color: Colors.grey), ), Container( padding: EdgeInsets.only(right: 20), child: LocalText(context, 'cargo.weight', color: Colors.grey)), ], ), ); List getCargoRowList() { if (_cargoTypes == null) { return []; } double total = 0; var rows = _cargoTypes.asMap().entries.map((c) { total += c.value.weight; return InkWell( onTap: () async { CargoType cargo = await Navigator.push( context, CupertinoPageRoute( builder: (context) => CargoTypeEditor(cargo: c.value)), ); _addCargo(cargo); }, child: Container( color: Colors.grey[50].withOpacity(0.2), child: Container( padding: EdgeInsets.only( left: 15.0, right: 0.0, top: 0.0, bottom: 0.0), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.grey[350], width: 1), ), ), child: Row( children: [ Expanded( child: new Text( c.value.name, style: textStyle, )), Row( children: [ new Text( c.value.weight == null ? "0" : c.value.weight.toString(), style: textStyle, ), IconButton( icon: Icon( Icons.remove_circle, color: primaryColor, ), onPressed: () { setState(() { _cargoTypes.remove(c.value); }); }, ) ], ) ], ), ), ), ); }).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: LocalText(context, "box.cargo.total", color: Colors.black87, fontWeight: FontWeight.bold), ), Padding( padding: const EdgeInsets.only(right: 40.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", ); final widthBox = LengthPicker( controller: _widthController, lableKey: "box.width", ); final heightBox = LengthPicker( controller: _heightController, lableKey: "box.height", ); final dimBox = Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(right: 8.0), child: Icon(FontAwesome.arrow_circle_right, color: primaryColor), ), SizedBox(child: lengthBox, width: 80), SizedBox(child: widthBox, width: 80), SizedBox(child: heightBox, width: 80), ], ); final shipmentWeightBox = DisplayText( text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", labelTextKey: "box.shipment_weight", iconData: MaterialCommunityIcons.weight, ); final createBtn = LocalButton( textKey: "box.create.btn", ); final completeBtn = LocalButton( textKey: "box.complete.btn", ); final deliveryBtn = LocalButton( textKey: "box.deliver.btn", ); 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: widget.box == null ? LocalText( context, "boxes.create.title", fontSize: 20, color: primaryColor, ) : LocalText( context, "box.edit.title", fontSize: 20, color: primaryColor, ), ), body: Padding( padding: const EdgeInsets.all(10.0), child: ListView( shrinkWrap: true, children: [ widget.box == null ? Container() : Center(child: nameWidget(_box.packageNumber)), SizedBox( height: 10, ), LocalTitle(textKey: "box.type.title"), LocalRadioButtons( values: boxModel.cartonTypes, selectedValue: _selectedCartonType, callback: (v) { print(v); setState(() { _selectedCartonType = v; }); }), LocalTitle(textKey: "box.shipment_info"), shipmentBox, SizedBox( height: 10, ), fcsIDBox, namebox, _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], ), 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, ), onPressed: () async { CargoType cargo = await Navigator.push( context, CupertinoPageRoute( builder: (context) => 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, CupertinoPageRoute( builder: (context) => DeliveryAddressSelection( deliveryAddress: _deliveryAddress, )), ); if (d == null) return; setState(() { this._deliveryAddress = d; }); }), SizedBox( height: 10, ), widget.box == null ? createBtn : Container( child: Column( children: [ completeBtn, widget.box.status == 'Arrived' ? deliveryBtn : Container(), ], )), SizedBox( height: 20, ), ], ), ), ), ); } List getAddressList( BuildContext context, List addresses) { return addresses.asMap().entries.map((s) { return InkWell( onTap: () {}, child: DeliveryAddressRow(deliveryAddress: s.value), ); }).toList(); } _addCargo(CargoType cargo) { if (cargo == null) return; setState(() { _cargoTypes.remove(cargo); _cargoTypes.add(cargo); }); } }