import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/domain/entities/carton_size.dart'; import 'package:fcs/domain/entities/fcs_shipment.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/pages/carton/carton_package_table.dart'; import 'package:fcs/pages/carton_search/carton_search.dart'; import 'package:fcs/pages/carton_size/carton_size_list.dart'; import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_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/display_text.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart'; import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/local_dropdown.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 'carton_list_row.dart'; import 'carton_row.dart'; import 'mix_carton_editor.dart'; import 'model/carton_model.dart'; import '../carton_size/model/carton_size_model.dart'; import 'package_carton_editor.dart'; import 'widgets.dart'; class CartonEditor extends StatefulWidget { final Carton box; CartonEditor({this.box}); @override _CartonEditorState createState() => _CartonEditorState(); } class _CartonEditorState extends State { TextEditingController _widthController = new TextEditingController(); TextEditingController _heightController = new TextEditingController(); TextEditingController _lengthController = new TextEditingController(); Carton _carton; bool _isLoading = false; bool _isNew; DeliveryAddress _deliveryAddress = new DeliveryAddress(); User _user; String _selectedCartonType; String _selectedMixType; double volumetricRatio = 0; double shipmentWeight = 0; FcsShipment _fcsShipment; List _fcsShipments; Carton _mixCarton; List _cartons = []; List _mixCartons = []; @override void initState() { super.initState(); //for shipment weight volumetricRatio = Provider.of(context, listen: false) .rate .volumetricRatio; _lengthController.addListener(_calShipmentWeight); _widthController.addListener(_calShipmentWeight); _heightController.addListener(_calShipmentWeight); if (widget.box != null) { _carton = widget.box; _deliveryAddress = _carton.deliveryAddress; _widthController.text = _carton.width.toString(); _heightController.text = _carton.height.toString(); _lengthController.text = _carton.length.toString(); _selectedCartonType = _carton.cartonType; _isNew = false; _user = User(fcsID: _carton.fcsID, name: _carton.userName); _loadPackages(); } else { _carton = Carton( cargoTypes: [], packages: [], ); _lengthController.text = "0"; _widthController.text = "0"; _heightController.text = "0"; _isNew = true; _selectedCartonType = carton_from_packages; _selectedMixType = mix_delivery; _loadFcsShipments(); _cartons = [Carton(cartonNumber: "A100B-1#3", userName: "Seven 7")]; _mixCartons = [ Carton(cartonNumber: "A100B-1#1", userName: "Seven 7"), Carton(cartonNumber: "A100B-1#2", userName: "Seven 7"), ]; } } _loadFcsShipments() async { FcsShipmentModel fcsShipmentModel = Provider.of(context, listen: false); var fcsShipments = await fcsShipmentModel.getActiveFcsShipments(); var fcsShipment = fcsShipments .firstWhere((e) => e.id == _carton.fcsShipmentID, orElse: () => null); setState(() { _fcsShipments = fcsShipments; _fcsShipment = fcsShipment; }); } _loadPackages() async { if (_user == null) return; PackageModel packageModel = Provider.of(context, listen: false); List packages = await packageModel.getPackages( _user.id, [package_processed_status, package_packed_status]); if (_isNew) { String prevCompare; packages.forEach((p) { String compare = (p.deliveryAddress?.fullName ?? "") + (p.deliveryAddress?.phoneNumber ?? ""); if (prevCompare != null && compare == prevCompare) { p.isChecked = true; } else { p.isChecked = false; } if (prevCompare == null) { p.isChecked = true; prevCompare = compare; } }); } else { packages.forEach((p) { if (_carton.packages.contains(p)) { p.isChecked = _carton.packages.firstWhere((cp) => cp == p).isChecked; } else { p.isChecked = false; } }); } setState(() { _carton.packages = packages; }); _populateDeliveryAddress(); } _populateDeliveryAddress() { if (_carton.packages == null) return; var d = _carton.packages .firstWhere((p) => p.isChecked && p.deliveryAddress != null, orElse: () => null) ?.deliveryAddress; setState(() { _deliveryAddress = d; }); } _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 boxModel = Provider.of(context); bool isMixBox = _selectedCartonType == carton_mix_box; final shipmentBox = DisplayText( text: _carton.fcsShipmentNumber, labelTextKey: "box.fcs_shipment_num", iconData: Ionicons.ios_airplane, ); var fcsShipmentsBox = Container( padding: EdgeInsets.only(top: 10), child: LocalDropdown( callback: (v) { setState(() { _fcsShipment = v; }); }, labelKey: "shipment.pack.fcs.shipment", iconData: Ionicons.ios_airplane, display: (u) => u.shipmentNumber, selectedValue: _fcsShipment, values: _fcsShipments, )); final fcsIDBox = Container( padding: EdgeInsets.only(top: 10), child: Row( children: [ Expanded( child: DisplayText( text: _user?.fcsID ?? "", labelTextKey: "box.fcs.id", icon: FcsIDIcon(), )), _isNew ? IconButton( icon: Icon(Icons.search, color: primaryColor), onPressed: () => searchUser(context, callbackUserSelect: (u) { setState(() { this._user = u; _loadPackages(); }); })) : Container(), ], )); final namebox = DisplayText( text: _user?.name ?? "", labelTextKey: "box.name", iconData: Icons.person, ); final createBtn = LocalButton( textKey: "box.complete.packaging", callBack: _save, ); final saveBtn = LocalButton( textKey: "box.cargo.save.btn", callBack: _save, ); final cartonTypeBox = LocalRadioButtons( readOnly: !_isNew, values: boxModel.cartonTypes, selectedValue: _selectedCartonType, callback: (v) { setState(() { _selectedCartonType = v; }); }); final cartonTitleBox = Container( child: LocalTitle( textKey: "boxes.title", trailing: IconButton( icon: Icon( Icons.add_circle, color: primaryColor, ), onPressed: () async { bool isFromPackages = _selectedCartonType == carton_from_packages; if (_user == null && isFromPackages) { showMsgDialog(context, "Error", "Please select customer"); return; } if (_fcsShipment == null && _isNew) { showMsgDialog(context, "Error", "Please select FCS shipment"); return; } double l = double.parse(_lengthController.text, (s) => 0); double w = double.parse(_widthController.text, (s) => 0); double h = double.parse(_heightController.text, (s) => 0); Carton carton = Carton(); carton.id = _carton.id; carton.cartonType = _selectedCartonType; carton.fcsShipmentID = _isNew ? _fcsShipment.id : _carton.fcsShipmentID; carton.userID = _user?.id; carton.packages = _carton.packages.where((e) => e.isChecked).toList(); carton.cargoTypes = _carton.cargoTypes; carton.length = l; carton.width = w; carton.height = h; carton.deliveryAddress = _carton.deliveryAddress; setState(() { _isLoading = true; }); try { Navigator.push( context, CupertinoPageRoute( builder: (context) => PackageCartonEditor(carton: carton, isNew: _isNew)), ); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } }), ), ); final mixTypeBox = Container( padding: EdgeInsets.only(top: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.only(left: 5), child: LocalText( context, "box.mix_type", color: primaryColor, fontSize: 15, fontWeight: FontWeight.bold, )), Row( children: boxModel.mixTypes.map((e) { return Row( children: [ Radio( value: e, groupValue: _selectedMixType, activeColor: primaryColor, onChanged: (v) { setState(() { _selectedMixType = v; }); }, ), Text(e), ], ); }).toList(), ), ], ), ); final mixcartonTitleBox = Container( child: LocalTitle( textKey: "box.mix_caton_title", trailing: IconButton( icon: Icon( Icons.add_circle, color: primaryColor, ), onPressed: () { Navigator.push( context, CupertinoPageRoute(builder: (context) => MixCartonEditor()), ); }, ), ), ); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: AppBar( centerTitle: true, leading: new IconButton( icon: new Icon(CupertinoIcons.back, color: primaryColor, size: 30), onPressed: () { if (isDataChanged()) { showConfirmDialog(context, "back.button_confirm", () { Navigator.of(context).pop(); }); } else { Navigator.of(context).pop(); } }, ), shadowColor: Colors.transparent, backgroundColor: Colors.white, title: LocalText( context, "box.info.title", fontSize: 20, color: primaryColor, ), ), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView( shrinkWrap: true, children: [ _isNew ? Container() : Center(child: getCartonNumberStatus(context, _carton)), LocalTitle(textKey: "box.type.title"), cartonTypeBox, LocalTitle(textKey: "box.shipment_info"), _isNew ? fcsShipmentsBox : shipmentBox, isMixBox ? mixTypeBox : Container(), ...(isMixBox ? [ mixcartonTitleBox, Column( children: _getMixCartons( context, this._mixCartons, )), ] : [ fcsIDBox, namebox, CartonPackageTable( packages: _carton.packages, onSelect: (p, checked) { if (checked && _deliveryAddress != null && p.deliveryAddress?.id != _deliveryAddress.id) { return; } setState(() { p.isChecked = checked; }); _populateDeliveryAddress(); }, ), cartonTitleBox, Column( children: _getCartons( context, this._cartons, )), ]), SizedBox( height: 20, ), createBtn, SizedBox( height: 20, ), ], ), ), ), ); } _addCarton(Carton carton) { if (carton == null) return; this._cartons.add(carton); setState(() {}); } List _getCartons(BuildContext context, List cartons) { return cartons.map((c) { return InkWell( onTap: () {}, child: CartonRow( key: ValueKey(c.id), box: c, ), ); }).toList(); } List _getMixCartons(BuildContext context, List cartons) { return cartons.map((c) { return InkWell( onTap: () {}, child: CartonRow( key: ValueKey(c.id), box: c, ), ); }).toList(); } CartonSize selectedCatonSize; Widget cartonSizeDropdown() { List _cartonSizes = Provider.of(context).getCartonSizes; return Padding( padding: const EdgeInsets.only(top: 10), child: Row( children: [ Padding( padding: const EdgeInsets.only(left: 0, right: 10), child: Icon(AntDesign.CodeSandbox, color: primaryColor), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(right: 18.0), child: LocalText( context, "box.carton_size", color: Colors.black54, fontSize: 16, ), ), DropdownButton( isDense: true, value: selectedCatonSize, style: TextStyle(color: Colors.black, fontSize: 14), underline: Container( height: 1, color: Colors.grey, ), onChanged: (CartonSize newValue) { setState(() { if (newValue.name == MANAGE_CARTONSIZE) { selectedCatonSize = null; _manageCartonSize(); return; } selectedCatonSize = newValue; _widthController.text = selectedCatonSize.width.toString(); _heightController.text = selectedCatonSize.height.toString(); _lengthController.text = selectedCatonSize.length.toString(); }); }, isExpanded: true, items: _cartonSizes .map>((CartonSize value) { return DropdownMenuItem( value: value, child: Text(value.name ?? "", overflow: TextOverflow.ellipsis, style: TextStyle( color: value.name == MANAGE_CARTONSIZE ? secondaryColor : primaryColor)), ); }).toList(), ), ], ), ), ], ), ); } _manageCartonSize() { Navigator.push( context, CupertinoPageRoute(builder: (context) => CartonSizeList()), ); } _save() async { // bool isFromShipment = _selectedCartonType == carton_from_shipments; // bool isSmallBag = _selectedCartonType == carton_small_bag; // if (_user == null && (isFromShipment || isSmallBag)) { // showMsgDialog(context, "Error", "Please select customer"); // return; // } // if (_fcsShipment == null && _isNew) { // showMsgDialog(context, "Error", "Please select FCS shipment"); // return; // } // if ((_carton.cargoTypes?.length ?? 0) == 0 && // (isFromShipment || isSmallBag)) { // showMsgDialog(context, "Error", "Expect at least one cargo type"); // return; // } // double l = double.parse(_lengthController.text, (s) => 0); // double w = double.parse(_widthController.text, (s) => 0); // double h = double.parse(_heightController.text, (s) => 0); // if ((l <= 0 || w <= 0 || h <= 0) && isFromShipment) { // showMsgDialog(context, "Error", "Invalid dimension"); // return; // } // if (_deliveryAddress == null && (isFromShipment || isSmallBag)) { // showMsgDialog(context, "Error", "Invalid delivery address"); // return; // } // if (isSmallBag && _mixCarton == null && _isNew) { // showMsgDialog(context, "Error", "Invalid mix carton"); // return; // } // Carton carton = Carton(); // carton.id = _carton.id; // carton.cartonType = _selectedCartonType; // carton.fcsShipmentID = _isNew ? _fcsShipment.id : _carton.fcsShipmentID; // carton.userID = _user?.id; // carton.cargoTypes = _carton.cargoTypes; // carton.packages = _carton.packages.where((e) => e.isChecked).toList(); // carton.mixCartonID = _mixCarton?.id; // carton.length = l; // carton.width = w; // carton.height = h; // carton.deliveryAddress = _deliveryAddress; // setState(() { // _isLoading = true; // }); // try { // CartonModel cartonModel = // Provider.of(context, listen: false); // if (_isNew) { // await cartonModel.createCarton(carton); // } else { // await cartonModel.updateCarton(carton); // } // Navigator.pop(context, true); // } catch (e) { // showMsgDialog(context, "Error", e.toString()); // } finally { // setState(() { // _isLoading = false; // }); // } Navigator.pop(context, true); } isDataChanged() { if (_isNew) { return false; // return _fcsShipment != null || _user != null; } else { return false; } } }