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/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'; 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/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/input_text.dart'; import 'package:fcs/pages/widgets/local_text.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/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'; 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; bool isMixBox = false; DeliveryAddress _deliveryAddress = new DeliveryAddress(); User user; String selectShipmentNumber; List _packages = []; List _cargoTypes = []; double volumetricRatio = 0; double shipmentWeight = 0; @override void initState() { super.initState(); var packageModel = Provider.of(context, listen: false); _packages = [ packageModel.packages[0], packageModel.packages[1], ]; _packages.forEach((p) { p.isChecked = false; }); volumetricRatio = Provider.of(context, listen: false).setting.volumetricRatio; _lengthController.addListener(_calShipmentWeight); _widthController.addListener(_calShipmentWeight); _heightController.addListener(_calShipmentWeight); if (widget.box != null) { _box = widget.box; _deliveryAddress = _box.shippingAddress; _cargoTypes = _box.cargoTypes; selectShipmentNumber = _box.shipmentNumber; _widthController.text = _box.width.toString(); _heightController.text = _box.height.toString(); _lengthController.text = _box.length.toString(); isNew = false; } else { _cargoTypes = [ Cargo(type: 'General', weight: 25), Cargo(type: 'Medicine', weight: 20), Cargo(type: 'Dangerous', weight: 30) ]; var shipmentModel = Provider.of(context, listen: false); _deliveryAddress = shipmentModel.defalutAddress; isNew = true; } } _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 languageModel = Provider.of(context); var shipmentBox = Container( child: Padding( padding: const EdgeInsets.only(left: 10.0, right: 10), 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: ["A102", "A103", "A201", "A202"] .map((e) => DropdownMenuItem( child: Text( e, style: TextStyle(color: primaryColor), ), value: e)) .toList(), onChanged: (value) { setState(() { selectShipmentNumber = value; }); }, ))); 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 = Container( padding: EdgeInsets.only(left: 10), child: 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 = Container( padding: EdgeInsets.only(left: 10), child: DisplayText( text: user != null ? user.phoneNumber : "", labelTextKey: "box.phone", iconData: Icons.phone, )); final namebox = Container( padding: EdgeInsets.only(left: 10), child: 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: 40, ), Expanded( child: LocalText(context, 'box.tracking.id', color: Colors.grey), ), LocalText(context, 'box.market', 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 Text( p.value.market == null ? "" : p.value.market, 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 []; } int total = 0; var rows = _cargoTypes.asMap().entries.map((c) { total += c.value.weight; return InkWell( onTap: () { Navigator.push( context, BottomUpPageRoute(CargoTypeEditor(cargo: c.value)), ); }, 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.type, 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: new Text( "Total Weight", style: TextStyle(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 shipmentWeightBox = Container( padding: EdgeInsets.only(left: 10), child: DisplayText( text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", labelTextKey: "box.shipment_weight", iconData: MaterialCommunityIcons.weight, )); final widthBox = Container( padding: EdgeInsets.only(left: 10, right: 10), child: InputText( labelTextKey: 'box.width', iconData: FontAwesomeIcons.arrowCircleRight, controller: _widthController)); final heightBox = Container( padding: EdgeInsets.only(left: 10, right: 10), child: InputText( labelTextKey: 'box.height', iconData: FontAwesomeIcons.arrowAltCircleUp, controller: _heightController)); final lengthBox = Container( padding: EdgeInsets.only(left: 10, right: 10), child: InputText( labelTextKey: 'box.length', iconData: FontAwesomeIcons.arrowCircleUp, controller: _lengthController)); final createBtn = Container( padding: EdgeInsets.only(left: 10, right: 10), child: fcsButton( context, getLocalString(context, 'box.create.btn'), callack: () {}, )); 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: () {}, )); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: AppBar( centerTitle: true, leading: new IconButton( icon: new Icon(Icons.close, color: primaryColor, size: 30), onPressed: () => Navigator.of(context).pop(), ), shadowColor: Colors.transparent, backgroundColor: Colors.white, title: widget.box == null ? LocalText( context, "boxes.new", fontSize: 20, color: primaryColor, ) : LocalText( context, "box.edit.title", fontSize: 20, color: primaryColor, ), ), body: ListView( shrinkWrap: true, children: [ widget.box == null ? Container() : Center(child: nameWidget(_box.packageNumber)), SizedBox( height: 10, ), TitleWithAddButton( titleKey: "box.shipment_info", ), shipmentBox, SizedBox( height: 10, ), fcsIDBox, phoneNumberBox, namebox, mixBox, SizedBox( height: 10, ), Divider(), Container( padding: EdgeInsets.only(top: 10, left: 10), child: TitleWithAddButton( iconData: Octicons.package, titleKey: "box.packages", ), ), Container( padding: EdgeInsets.only(left: 10, right: 10), child: 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, 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( children: [ Padding( padding: EdgeInsets.only(top: 10), child: TitleWithAddButton( titleKey: "box.status", ), ), Container( height: 230, padding: EdgeInsets.only(left: 10), child: isNew ? Container() : Timeline( children: _models(), position: TimelinePosition.Left), ), ], ), isNew ? Container() : Divider(), 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(); } }