import 'package:fcs/domain/constants.dart'; import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/domain/entities/shipment.dart'; import 'package:fcs/domain/vo/delivery_address.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/shipment/model/shipment_model.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_date.dart'; import 'package:fcs/pages/widgets/input_time.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:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import 'box_row.dart'; import 'shipment_box_editor.dart'; import 'widgets.dart'; class ShipmentEditor extends StatefulWidget { final Shipment shipment; ShipmentEditor({this.shipment}); @override _ShipmentEditorState createState() => _ShipmentEditorState(); } class _ShipmentEditorState extends State { var dateFormatter = new DateFormat('dd MMM yyyy'); var timeFormatter = new DateFormat('jm'); TextEditingController _fromTimeEditingController = new TextEditingController(); TextEditingController _toTimeEditingController = new TextEditingController(); TextEditingController _pickupDate = new TextEditingController(); Shipment _shipment; bool _isLoading = false; var now = new DateTime.now(); bool _isNew; String _selectedShipmentType; @override void initState() { super.initState(); if (widget.shipment != null) { _isNew = false; _shipment = widget.shipment; _selectedShipmentType = _shipment.shipmentType; _fromTimeEditingController.text = _shipment.pickupTimeStart; _toTimeEditingController.text = _shipment.pickupTimeEnd; _pickupDate.text = dateFormatter.format(_shipment.pickupDate ?? now); } else { _isNew = true; _selectedShipmentType = shipment_local_pickup; _pickupDate.text = dateFormatter.format(now); _fromTimeEditingController.text = "${timeFormatter.format(now)}"; _toTimeEditingController.text = "${timeFormatter.format(now)}"; _shipment = Shipment(boxes: []); var shipmentModel = Provider.of(context, listen: false); _shipment.pickupAddress = shipmentModel.defalutAddress; _pickupDate.text = dateFormatter.format(now); } } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { MainModel mainModel = Provider.of(context); ShipmentModel pickupModel = Provider.of(context); final shipmentNumberBox = getShipmentNumberStatus(context, _shipment); bool isLocalPickup = _selectedShipmentType == shipment_local_pickup; bool isCourierPickup = _selectedShipmentType == shipment_courier_pickup; bool isLocalDropoff = _selectedShipmentType == shipment_local_dropoff; bool isCourierDropoff = _selectedShipmentType == shipment_courier_dropoff; var deliveryAddressModel = Provider.of(context); final fromTimeBox = InputTime( labelTextKey: 'shipment.from', iconData: Icons.timer, controller: _fromTimeEditingController); final toTimeBox = Container( width: 150, child: InputTime( iconData: Icons.timer_off, labelTextKey: 'shipment.to', controller: _toTimeEditingController)); final pickupDateBox = InputDate( labelTextKey: "shipment.date", iconData: Icons.date_range, controller: _pickupDate, ); final curierDropoffAddress = Padding( padding: EdgeInsets.all(8), child: FloatingActionButton.extended( onPressed: _openCourierWebsite, icon: Icon(Icons.open_in_new, color: primaryColor), label: Text( 'Visit courier websie \nfor nearest drop-off', style: TextStyle(fontSize: 16, color: primaryColor), ), backgroundColor: Colors.white, )); final pickupAddressBox = DefaultDeliveryAddress( deliveryAddress: _shipment.pickupAddress, iconData: Icons.location_on, labelKey: "shipment.location", onTap: () async { DeliveryAddress address = await Navigator.push( context, CupertinoPageRoute( builder: (context) => DeliveryAddressSelection( deliveryAddress: _shipment.pickupAddress, user: mainModel.user)), ); if (address == null) return; setState(() { _shipment.pickupAddress = address; }); }, ); var localDropoffAddressBox = Row(children: [ FcsIDIcon(), Expanded( child: DisplayText( text: mainModel.setting.usaAddress, ), ) ]); final createBtn = LocalButton( textKey: "shipment.create", callBack: _save, ); final updateBtn = LocalButton( textKey: "shipment.update", callBack: _save, ); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: AppBar( centerTitle: true, leading: new IconButton( icon: new Icon( CupertinoIcons.back, color: primaryColor, ), 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, _isNew ? "shipment.new.title" : "shipment.edit.title", fontSize: 20, color: primaryColor, ), ), body: Padding( padding: const EdgeInsets.all(10.0), child: ListView( children: [ _isNew ? Container() : Center(child: shipmentNumberBox), LocalTitle(textKey: "shipment.type"), LocalRadioButtons( values: pickupModel.shipmentTypes, selectedValue: _selectedShipmentType, callback: (v) { setState(() { _selectedShipmentType = v; }); }), ...(isLocalDropoff ? [ LocalTitle(textKey: "shipment.location.dropoff"), localDropoffAddressBox ] : []), ...(isCourierDropoff ? [ LocalTitle(textKey: "shipment.courier.dropoff"), curierDropoffAddress ] : []), ...(isCourierPickup || isLocalPickup ? [ LocalTitle(textKey: "shipment.location"), pickupAddressBox, LocalTitle(textKey: "shipment.date.time"), pickupDateBox, fromTimeBox, toTimeBox, ] : []), LocalTitle( textKey: "boxes.name", trailing: IconButton( icon: Icon( Icons.add_circle, color: primaryColor, ), onPressed: () async { Carton box = await Navigator.push( context, CupertinoPageRoute( builder: (context) => ShipmentBoxEditor()), ); _addBox(box); }, ), ), Column( children: getBoxList(context, _shipment.boxes), ), _isNew ? createBtn : updateBtn, ], ), ), ), ); } List getBoxList(BuildContext context, List boxes) { return boxes.asMap().entries.map((_box) { return InkWell( onTap: () async { Carton box = await Navigator.of(context).push(CupertinoPageRoute( builder: (context) => ShipmentBoxEditor(box: _box.value))); _saveBox(box); }, child: Row( children: [ Expanded(child: BoxRow(box: _box.value)), InkWell( onTap: () => _removeBox(_box.value), child: Padding( padding: const EdgeInsets.all(8.0), child: Icon(Icons.remove_circle, color: primaryColor), ), ), ], ), ); }).toList(); } _addBox(Carton box) { if (box == null) return; box.cartonType = carton_from_shipments; _shipment.boxes.add(box); setState(() {}); } _saveBox(Carton box) { if (box == null) return; setState(() {}); } _removeBox(Carton box) { if (box == null) return; _shipment.boxes.remove(box); setState(() {}); } _save() async { _shipment.shipmentType = this._selectedShipmentType; _shipment.pickupDate = dateFormatter.parse(_pickupDate.text); _shipment.pickupTimeStart = _fromTimeEditingController.text; _shipment.pickupTimeEnd = _toTimeEditingController.text; setState(() { _isLoading = true; }); try { ShipmentModel shipmentModel = Provider.of(context, listen: false); if (_isNew) { await shipmentModel.createShipment(_shipment); } else { await shipmentModel.updateShipment(_shipment); } Navigator.pop(context, true); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } _openCourierWebsite() { MainModel mainModel = Provider.of(context, listen: false); launch("${mainModel.setting.courierWebsite}"); } isDataChanged() { return _shipment.boxes.isNotEmpty; } }