Files
fcs/lib/pages/fcs_shipment/fcs_shipment_editor.dart

379 lines
14 KiB
Dart

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<FcsShipmentEditor> {
final _formKey = GlobalKey<FormState>();
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<FcsShipmentModel>(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<ShipmentType> shipmentTypes = model.shipmentTypes
.where((e) => e.id == _shipment.shipmentTypeId)
.toList();
_currentShipmentType =
shipmentTypes.isNotEmpty ? shipmentTypes.first : null;
List<ShipmentConsignee> shipmentConsingees = model.shipmentConsingees
.where((e) => e.id == _shipment.consigneeId)
.toList();
_currentConsignee =
shipmentConsingees.isNotEmpty ? shipmentConsingees.first : null;
List<ShipmentPort> loadingPorts = model.shipmentPorts
.where((e) => e.id == _shipment.loadingPortId)
.toList();
_currentLoadingPort = loadingPorts.isNotEmpty ? loadingPorts.first : null;
List<ShipmentPort> loadingDestination = model.shipmentPorts
.where((e) => e.id == _shipment.destinationPortId)
.toList();
_currentDestination =
loadingDestination.isNotEmpty ? loadingDestination.first : null;
} else {
_currentShipmentType =
model.shipmentTypes.isNotEmpty ? model.shipmentTypes.first : null;
_currentConsignee = model.shipmentConsingees.isNotEmpty
? model.shipmentConsingees.first
: null;
_currentLoadingPort =
model.shipmentPorts.isNotEmpty ? model.shipmentPorts.first : null;
_currentDestination =
model.shipmentPorts.isNotEmpty ? model.shipmentPorts.first : null;
}
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
var languageModel = Provider.of<LanguageModel>(context);
var shipmentModel = context.watch<FcsShipmentModel>();
List<ShipmentType> shipmentTypes = shipmentModel.shipmentTypes;
List<ShipmentConsignee> shipmentConsingees =
shipmentModel.shipmentConsingees;
List<ShipmentPort> 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: <Widget>[
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<void> _create() async {
if (!_formKey.currentState!.validate()) return;
FcsShipment fcsShipment = _getPayload();
setState(() {
_isLoading = true;
});
try {
await context.read<FcsShipmentModel>().create(fcsShipment);
Navigator.pop(context);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> _update() async {
if (!_formKey.currentState!.validate()) return;
FcsShipment fcsShipment = _getPayload();
setState(() {
_isLoading = true;
});
try {
await context.read<FcsShipmentModel>().update(fcsShipment);
Navigator.pop(context, true);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
isDataChanged() {
if (_isNew) {
var shipmentModel = Provider.of<FcsShipmentModel>(context, listen: false);
return _shipmentNumberController.text != "" ||
_cutoffDateController.text != "" ||
_etaDateController.text != "" ||
(shipmentModel.shipmentConsingees.isNotEmpty &&
_currentConsignee != shipmentModel.shipmentConsingees.first) ||
(shipmentModel.shipmentTypes.isNotEmpty &&
_currentShipmentType != shipmentModel.shipmentTypes.first) ||
(shipmentModel.shipmentPorts.isNotEmpty &&
_currentLoadingPort != shipmentModel.shipmentPorts.first) ||
(shipmentModel.shipmentPorts.isNotEmpty &&
_currentDestination != shipmentModel.shipmentPorts.first);
} else {
FcsShipment fcsShipment = _getPayload();
return widget.shipment!.isChangedForEdit(fcsShipment);
}
}
}