import 'package:fcs/domain/entities/fcs_shipment.dart'; import 'package:fcs/domain/entities/shipment_consignee.dart'; import 'package:fcs/domain/entities/shipment_port.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/localization/app_translations.dart'; import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart'; import 'package:fcs/pages/main/model/language_model.dart'; import 'package:fcs/pages/widgets/input_date.dart'; import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/material.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import '../../domain/entities/shipment_type.dart'; import '../main/util.dart'; class FcsShipmentEditor extends StatefulWidget { final FcsShipment? shipment; FcsShipmentEditor({this.shipment}); @override _FcsShipmentEditorState createState() => _FcsShipmentEditorState(); } class _FcsShipmentEditorState extends State { final _formKey = GlobalKey(); var dateFormatter = new DateFormat('dd MMM yyyy'); TextEditingController _shipmentNumberController = new TextEditingController(); TextEditingController _cutoffDateController = new TextEditingController(); TextEditingController _etaDateController = new TextEditingController(); TextEditingController _statusController = new TextEditingController(); FcsShipment _shipment = new FcsShipment(); bool _isLoading = false; ShipmentType? _currentShipmentType; ShipmentConsignee? _currentConsignee; ShipmentPort? _currentLoadingPort; ShipmentPort? _currentDestination; bool _isNew = false; @override void initState() { super.initState(); _isNew = widget.shipment == null; var model = Provider.of(context, listen: false); if (widget.shipment != null) { _shipment = widget.shipment!; _shipmentNumberController.text = _shipment.shipmentNumber ?? ""; if (_shipment.cutoffDate != null) _cutoffDateController.text = dateFormatter.format(_shipment.cutoffDate!); if (_shipment.etaDate != null) _etaDateController.text = dateFormatter.format(_shipment.etaDate!); _statusController.text = _shipment.status ?? ""; List shipmentTypes = model.shipmentTypes .where((e) => e.id == _shipment.shipmentTypeId) .toList(); _currentShipmentType = shipmentTypes.isNotEmpty ? shipmentTypes.first : null; List shipmentConsingees = model.shipmentConsingees .where((e) => e.id == _shipment.consigneeId) .toList(); _currentConsignee = shipmentConsingees.isNotEmpty ? shipmentConsingees.first : null; List loadingPorts = model.shipmentPorts .where((e) => e.id == _shipment.loadingPortId) .toList(); _currentLoadingPort = loadingPorts.isNotEmpty ? loadingPorts.first : null; List loadingDestination = model.shipmentPorts .where((e) => e.id == _shipment.destinationPortId) .toList(); _currentDestination = loadingDestination.isNotEmpty ? loadingDestination.first : null; } else { _currentShipmentType = model.shipmentTypes.first; _currentConsignee = model.shipmentConsingees.first; _currentLoadingPort = model.shipmentPorts.first; _currentDestination = model.shipmentPorts.first; } } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { var languageModel = Provider.of(context); var shipmentModel = context.watch(); List shipmentTypes = shipmentModel.shipmentTypes; List shipmentConsingees = shipmentModel.shipmentConsingees; List shipmentPorts = shipmentModel.shipmentPorts; final shipmentTypeBox = DropdownButtonFormField( value: _currentShipmentType == "" ? null : _currentShipmentType, decoration: InputDecoration( contentPadding: EdgeInsets.zero, enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), fillColor: Colors.white, labelStyle: languageModel.isEng ? newLabelStyle(color: Colors.black54, fontSize: 20) : newLabelStyleMM(color: Colors.black54, fontSize: 20), labelText: AppTranslations.of(context)!.text('FCSshipment.shipment_type'), icon: Icon(Ionicons.ios_airplane, color: primaryColor)), items: shipmentTypes .map((e) => DropdownMenuItem(child: Text(e.name), value: e)) .toList(), onChanged: (selected) => { setState(() { _currentShipmentType = selected; }) }, ); final consigneeBox = DropdownButtonFormField( value: _currentConsignee == "" ? null : _currentConsignee, decoration: InputDecoration( contentPadding: EdgeInsets.zero, enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), fillColor: Colors.white, labelStyle: languageModel.isEng ? newLabelStyle(color: Colors.black54, fontSize: 20) : newLabelStyleMM(color: Colors.black54, fontSize: 20), labelText: AppTranslations.of(context)!.text('FCSshipment.consignee'), icon: Icon(Icons.work, color: primaryColor)), items: shipmentConsingees .map((e) => DropdownMenuItem(child: Text(e.name), value: e)) .toList(), onChanged: (selected) => { setState(() { _currentConsignee = selected; }) }, ); final loadingPortBox = DropdownButtonFormField( value: _currentLoadingPort == "" ? null : _currentLoadingPort, decoration: InputDecoration( contentPadding: EdgeInsets.zero, enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), fillColor: Colors.white, labelStyle: languageModel.isEng ? newLabelStyle(color: Colors.black54, fontSize: 20) : newLabelStyleMM(color: Colors.black54, fontSize: 20), labelText: AppTranslations.of(context)!.text('FCSshipment.port_of_loading'), icon: Icon(FontAwesomeIcons.ship, color: primaryColor)), items: shipmentPorts .map((e) => DropdownMenuItem(child: Text(e.name), value: e)) .toList(), onChanged: (selected) => { setState(() { _currentLoadingPort = selected; }) }, ); final destinationBox = DropdownButtonFormField( value: _currentDestination == "" ? null : _currentDestination, decoration: InputDecoration( contentPadding: EdgeInsets.zero, enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)), fillColor: Colors.white, labelStyle: languageModel.isEng ? newLabelStyle(color: Colors.black54, fontSize: 20) : newLabelStyleMM(color: Colors.black54, fontSize: 20), labelText: AppTranslations.of(context)! .text('FCSshipment.final_destination'), icon: Icon(MaterialCommunityIcons.location_enter, color: primaryColor)), items: shipmentPorts .map((e) => DropdownMenuItem(child: Text(e.name), value: e)) .toList(), onChanged: (selected) => { setState(() { _currentDestination = selected; }) }, ); final createBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( textKey: "FCSshipment.create", callBack: _create, ), ); final updateBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( textKey: "FCSshipment.update", callBack: _update, ), ); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: LocalAppBar( labelKey: _isNew ? "FCSshipment.add" : "FCSshipment.form.title", backgroundColor: Colors.white, labelColor: primaryColor, arrowColor: primaryColor, onBack: () { if (isDataChanged()) { showConfirmDialog(context, "back.button_confirm", () { Navigator.of(context).pop(); }); } else { Navigator.of(context).pop(); } }), body: Form( key: _formKey, child: ListView( padding: const EdgeInsets.only(left: 10, right: 10), children: [ InputText( labelTextKey: "FCSshipment.number", iconData: Ionicons.ios_airplane, controller: _shipmentNumberController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value!.isEmpty) { return "Enter shipment number"; } return null; }, ), InputDate( labelTextKey: "FCSshipment.cutoff_date", iconData: Icons.date_range, controller: _cutoffDateController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value!.isEmpty) { return "Select cutoff date"; } return null; }, ), InputDate( labelTextKey: "FCSshipment.ETA", iconData: Icons.date_range, controller: _etaDateController, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value!.isEmpty) { return "Select ETA date"; } return null; }, ), const SizedBox(height: 20), shipmentTypeBox, const SizedBox(height: 25), consigneeBox, const SizedBox(height: 25), loadingPortBox, const SizedBox(height: 25), destinationBox, SizedBox(height: 30), _isNew ? createBtn : updateBtn, SizedBox(height: 15) ]), ), ), ); } FcsShipment _getPayload() { FcsShipment fcsShipment = FcsShipment(); fcsShipment.id = _shipment.id; fcsShipment.shipmentNumber = _shipmentNumberController.text; fcsShipment.shipmentTypeId = _currentShipmentType?.id ?? ""; fcsShipment.consigneeId = _currentConsignee?.id ?? ""; fcsShipment.loadingPortId = _currentLoadingPort?.id ?? ""; fcsShipment.destinationPortId = _currentDestination?.id ?? ""; var cutoffDate = _cutoffDateController.text; var etaDate = _etaDateController.text; fcsShipment.cutoffDate = (cutoffDate == "" ? null : dateFormatter.parse(cutoffDate))!; fcsShipment.etaDate = (etaDate == "" ? null : dateFormatter.parse(etaDate)); return fcsShipment; } Future _create() async { if (!_formKey.currentState!.validate()) return; FcsShipment fcsShipment = _getPayload(); setState(() { _isLoading = true; }); try { await context.read().create(fcsShipment); Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } Future _update() async { if (!_formKey.currentState!.validate()) return; FcsShipment fcsShipment = _getPayload(); setState(() { _isLoading = true; }); try { await context.read().update(fcsShipment); Navigator.pop(context, true); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } isDataChanged() { if (_isNew) { var shipmentModel = Provider.of(context, listen: false); return _shipmentNumberController.text != "" || _cutoffDateController.text != "" || _etaDateController.text != "" || _currentConsignee != shipmentModel.shipmentConsingees.first || _currentShipmentType != shipmentModel.shipmentTypes.first || _currentLoadingPort != shipmentModel.shipmentPorts.first || _currentDestination != shipmentModel.shipmentPorts.first; } else { FcsShipment fcsShipment = _getPayload(); return widget.shipment!.isChangedForEdit(fcsShipment); } } }