add fcs shipment apis

This commit is contained in:
Sai Naw Wun
2020-10-08 03:32:52 +06:30
parent ad1999f5c9
commit 6105b45cb8
23 changed files with 442 additions and 531 deletions

View File

@@ -5,18 +5,17 @@ import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
import 'package:fcs/pages/main/model/language_model.dart';
import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/input_date.dart';
import 'package:fcs/pages/widgets/input_text.dart';
import 'package:fcs/pages/widgets/label_widgets.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/popupmenu.dart';
import 'package:fcs/pages/widgets/progress.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:flutter/material.dart';
import '../main/util.dart';
class FcsShipmentEditor extends StatefulWidget {
@@ -37,22 +36,28 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
TextEditingController _portController = new TextEditingController();
TextEditingController _destinationController = new TextEditingController();
TextEditingController _statusController = new TextEditingController();
TextEditingController _remarkController = new TextEditingController();
FcsShipment _shipment = new FcsShipment();
bool _isLoading = false;
String _currentShipment;
String _currentShipmentType;
bool _isNew = false;
@override
void initState() {
super.initState();
_isNew = widget.shipment == null;
if (widget.shipment != null) {
_shipment = widget.shipment;
_shipmentNumberController.text = _shipment.shipmentNumber;
_cutoffDateController.text = dateFormatter.format(_shipment.cutoffDate);
_arrivalDateController.text = dateFormatter.format(_shipment.arrivalDate);
_departureDateControler.text =
dateFormatter.format(_shipment.departureDate);
_statusController.text = _shipment.status;
_currentShipmentType = _shipment.shipType;
_consigneeController.text = _shipment.consignee;
_portController.text = _shipment.port;
_destinationController.text = _shipment.destination;
}
}
@@ -61,76 +66,21 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
super.dispose();
}
Widget showShipmentNumber(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 10),
child: Row(
children: <Widget>[
Icon(Icons.text_rotation_none),
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: labeledText(
context, _shipmentNumberController.text, "shipment.number"),
),
],
),
);
}
Widget showShipmentTypes(
BuildContext context, FcsShipmentModel shipmentModel) {
return Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Icon(MaterialCommunityIcons.box_shadow),
SizedBox(
width: 10,
),
new Flexible(
child: Container(
width: 200.0,
child: DropdownButton<String>(
value: _currentShipment,
isExpanded: true,
hint: Text(
'Select shipment type',
),
onChanged: changedDropDown,
items: shipmentModel.shipmentType
.map<DropdownMenuItem<String>>((String shipment) {
return new DropdownMenuItem<String>(
value: shipment,
child: new Text(shipment,
style:
new TextStyle(color: Colors.black87, fontSize: 17)),
);
}).toList(),
),
),
),
],
);
}
void changedDropDown(selected) {
setState(() {
_currentShipment = selected;
});
}
@override
Widget build(BuildContext context) {
var shipmentModel = Provider.of<FcsShipmentModel>(context);
var languageModel = Provider.of<LanguageModel>(context);
var mainModel = Provider.of<MainModel>(context);
final createBtn = fcsButton(
context,
getLocalString(context, "FCSshipment.create"),
callack: _create,
);
final updateBtn = fcsButton(
context,
getLocalString(context, "FCSshipment.update"),
callack: _update,
);
return LocalProgress(
@@ -150,111 +100,74 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
color: primaryColor,
fontSize: 18,
),
actions: [menuPopWidget(context)],
actions: _isNew ? [] : [menuPopWidget(context)],
),
body: Card(
child: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView(children: <Widget>[
// _showCustomerData(mainModel.customer),
widget.shipment == null
? InputText(
labelTextKey: "FCSshipment.number",
iconData: Ionicons.ios_airplane,
controller: _shipmentNumberController,
)
: DisplayText(
iconData: Ionicons.ios_airplane,
labelText: "FCSshipment.number",
text: _shipmentNumberController.text),
widget.shipment == null
? InputText(
labelTextKey: "FCSshipment.cutoff_date",
iconData: Icons.date_range,
controller: _cutoffDateController,
)
: Container(),
InputText(
labelTextKey: "FCSshipment.ETA",
iconData: Icons.date_range,
controller: _arrivalDateController,
),
InputText(
labelTextKey: "FCSshipment.departure_date",
iconData: Icons.date_range,
controller: _departureDateControler,
),
widget.shipment == null
? DropdownButtonFormField(
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: primaryColor)),
fillColor: Colors.white,
labelStyle: languageModel.isEng
? labelStyle
: labelStyleMM,
labelText: AppTranslations.of(context)
.text('FCSshipment.shipment_type'),
icon: Icon(Ionicons.ios_airplane,
color: primaryColor)),
items: shipmentModel.shipmentType
.map((e) =>
DropdownMenuItem(child: Text(e), value: e))
.toList(),
onChanged: (selected) => {
setState(() {
_currentShipment = selected;
})
},
)
: Container(),
widget.shipment == null
? InputText(
labelTextKey: 'FCSshipment.consignee',
iconData: Icons.work,
controller: _consigneeController)
: Container(),
widget.shipment == null
? InputText(
labelTextKey: 'FCSshipment.port_of_loading',
iconData: FontAwesomeIcons.ship,
controller: _portController)
: Container(),
widget.shipment == null
? InputText(
labelTextKey: 'FCSshipment.final_destination',
iconData: MaterialCommunityIcons.location_enter,
controller: _destinationController)
: Container(),
widget.shipment == null
? Container()
: Container(
padding: EdgeInsets.only(top: 5),
child: DisplayText(
text: _statusController.text,
iconData: Icons.av_timer,
labelText: 'FCSshipment.status',
)),
widget.shipment == null
? Container()
: InputText(
labelTextKey: 'FCSshipment.remark',
iconData: MaterialCommunityIcons.note,
controller: _remarkController),
]),
)),
widget.shipment == null ? createBtn : updateBtn,
SizedBox(height: 15)
],
),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView(children: <Widget>[
InputText(
labelTextKey: "FCSshipment.number",
iconData: Ionicons.ios_airplane,
controller: _shipmentNumberController,
),
InputDate(
labelTextKey: "FCSshipment.cutoff_date",
iconData: Icons.date_range,
controller: _cutoffDateController,
),
InputDate(
labelTextKey: "FCSshipment.ETA",
iconData: Icons.date_range,
controller: _arrivalDateController,
),
InputDate(
labelTextKey: "FCSshipment.departure_date",
iconData: Icons.date_range,
controller: _departureDateControler,
),
DropdownButtonFormField(
value: _currentShipmentType == "" ? null : _currentShipmentType,
decoration: InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: primaryColor)),
fillColor: Colors.white,
labelStyle: languageModel.isEng ? labelStyle : labelStyleMM,
labelText: AppTranslations.of(context)
.text('FCSshipment.shipment_type'),
icon: Icon(Ionicons.ios_airplane, color: primaryColor)),
items: mainModel.setting.shipmentTypes
.map((e) => DropdownMenuItem(child: Text(e), value: e))
.toList(),
onChanged: (selected) => {
setState(() {
_currentShipmentType = selected;
})
},
),
InputText(
labelTextKey: 'FCSshipment.consignee',
iconData: Icons.work,
controller: _consigneeController),
InputText(
labelTextKey: 'FCSshipment.port_of_loading',
iconData: FontAwesomeIcons.ship,
controller: _portController),
InputText(
labelTextKey: 'FCSshipment.final_destination',
iconData: MaterialCommunityIcons.location_enter,
controller: _destinationController),
_isNew
? Container()
: Container(
padding: EdgeInsets.only(top: 5),
child: DisplayText(
text: _statusController.text,
iconData: Icons.av_timer,
labelTextKey: 'FCSshipment.status',
)),
_isNew ? createBtn : updateBtn,
SizedBox(height: 15)
]),
),
),
);
@@ -312,4 +225,96 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
}).toList();
});
}
FcsShipment _getPayload() {
FcsShipment fcsShipment = FcsShipment();
fcsShipment.id = _shipment.id;
fcsShipment.shipmentNumber = _shipmentNumberController.text;
fcsShipment.shipType = _currentShipmentType;
fcsShipment.consignee = _consigneeController.text;
fcsShipment.port = _portController.text;
fcsShipment.destination = _destinationController.text;
try {
var cutoffDate = _cutoffDateController.text;
var arrivalDate = _arrivalDateController.text;
var depDate = _departureDateControler.text;
fcsShipment.cutoffDate =
cutoffDate == "" ? null : dateFormatter.parse(cutoffDate);
fcsShipment.arrivalDate =
arrivalDate == "" ? null : dateFormatter.parse(arrivalDate);
fcsShipment.departureDate =
depDate == "" ? null : dateFormatter.parse(depDate);
} catch (e) {
showMsgDialog(context, "Error", e.toString()); // shold never happen
}
return fcsShipment;
}
Future<bool> _validate(FcsShipment fcsShipment) async {
if (fcsShipment.shipmentNumber == "") {
await showMsgDialog(context, "Error", "Invalid shipment number!");
return false;
}
if (fcsShipment.shipType == null) {
await showMsgDialog(context, "Error", "Invalid shipment type!");
return false;
}
if (fcsShipment.cutoffDate == null) {
await showMsgDialog(context, "Error", "Invalid cutoff date!");
return false;
}
if (fcsShipment.arrivalDate == null) {
await showMsgDialog(context, "Error", "Invalid ETA date!");
return false;
}
if (fcsShipment.departureDate == null) {
await showMsgDialog(context, "Error", "Invalid departure date!");
return false;
}
return true;
}
Future<void> _create() async {
FcsShipment fcsShipment = _getPayload();
bool valid = await _validate(fcsShipment);
if (!valid) {
return;
}
setState(() {
_isLoading = true;
});
var shipmentModel = Provider.of<FcsShipmentModel>(context, listen: false);
try {
await shipmentModel.create(fcsShipment);
Navigator.pop(context);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
Future<void> _update() async {
FcsShipment fcsShipment = _getPayload();
bool valid = await _validate(fcsShipment);
if (!valid) {
return;
}
setState(() {
_isLoading = true;
});
var shipmentModel = Provider.of<FcsShipmentModel>(context, listen: false);
try {
await shipmentModel.update(fcsShipment);
Navigator.pop(context);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
}

View File

@@ -4,6 +4,7 @@ import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
import 'package:fcs/pages/widgets/bottom_up_page_route.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
@@ -39,22 +40,12 @@ class _FcsShipmentListState extends State<FcsShipmentList> {
appBar: AppBar(
centerTitle: true,
leading: new IconButton(
icon: new Icon(Icons.close),
icon: new Icon(CupertinoIcons.back),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
title: LocalText(context, 'FCSshipment.list.title',
color: Colors.white, fontSize: 20),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
iconSize: 30,
// onPressed: () => showPlacesSearch(context),
),
],
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
@@ -74,10 +65,11 @@ class _FcsShipmentListState extends State<FcsShipmentList> {
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(top: 15),
shrinkWrap: true,
itemCount: shipmentModel.shipments.length,
itemCount: shipmentModel.fcsShipments.length,
itemBuilder: (BuildContext context, int index) {
return FcsShipmentListRow(
shipment: shipmentModel.shipments[index]);
key: ValueKey(shipmentModel.fcsShipments[index].id),
shipment: shipmentModel.fcsShipments[index]);
}),
),
],

View File

@@ -8,27 +8,10 @@ import 'package:intl/intl.dart';
import 'fcs_shipment_editor.dart';
class FcsShipmentListRow extends StatefulWidget {
class FcsShipmentListRow extends StatelessWidget {
final FcsShipment shipment;
const FcsShipmentListRow({this.shipment});
@override
_FcsShipmentListRowState createState() => _FcsShipmentListRowState();
}
class _FcsShipmentListRowState extends State<FcsShipmentListRow> {
var dateFormatter = new DateFormat('dd MMM yyyy');
final double dotSize = 15.0;
FcsShipment _shipment = new FcsShipment();
@override
void initState() {
super.initState();
if (widget.shipment != null) {
_shipment = widget.shipment;
}
}
final dateFormatter = new DateFormat('dd MMM yyyy');
FcsShipmentListRow({Key key, this.shipment}) : super(key: key);
@override
Widget build(BuildContext context) {
@@ -37,7 +20,7 @@ class _FcsShipmentListRowState extends State<FcsShipmentListRow> {
child: InkWell(
onTap: () {
Navigator.of(context)
.push(BottomUpPageRoute(FcsShipmentEditor(shipment: _shipment)));
.push(BottomUpPageRoute(FcsShipmentEditor(shipment: shipment)));
},
child: Row(
children: <Widget>[
@@ -61,9 +44,9 @@ class _FcsShipmentListRowState extends State<FcsShipmentListRow> {
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text(
_shipment.shipmentNumber == null
shipment.shipmentNumber == null
? ''
: _shipment.shipmentNumber,
: shipment.shipmentNumber,
style: new TextStyle(
fontSize: 15.0, color: Colors.black),
),
@@ -71,7 +54,7 @@ class _FcsShipmentListRowState extends State<FcsShipmentListRow> {
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 10),
child: new Text(
dateFormatter.format(_shipment.shipDate),
dateFormatter.format(shipment.cutoffDate),
style: new TextStyle(
fontSize: 15.0, color: Colors.grey),
),
@@ -85,7 +68,7 @@ class _FcsShipmentListRowState extends State<FcsShipmentListRow> {
),
Padding(
padding: const EdgeInsets.all(0),
child: getStatus(_shipment.status),
child: getStatus(shipment.status),
),
],
),

View File

@@ -1,78 +1,45 @@
import 'dart:async';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fcs/data/services/services.dart';
import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/fcs_shipment.dart';
import 'package:fcs/pages/main/model/base_model.dart';
import 'package:logging/logging.dart';
class FcsShipmentModel extends BaseModel {
List<String> shipmentType = ['Air', 'Ship', 'Cargo Truck'];
List<FcsShipment> shipments = [
FcsShipment(
shipDate: DateTime(2020, 4, 23),
shipmentNumber: 'A103B',
status: 'In Progress',
arrivalDate: DateTime(2020, 4, 30),
departureDate: DateTime(2020, 4, 23)),
FcsShipment(
shipDate: DateTime(2020, 4, 2),
shipmentNumber: 'A100A',
status: 'Ready to ship',
arrivalDate: DateTime(2020, 4, 28),
departureDate: DateTime(2020, 4, 15)),
FcsShipment(
shipDate: DateTime(2020, 4, 2),
shipmentNumber: 'A100B',
status: 'Arrived',
arrivalDate: DateTime(2020, 4, 28),
departureDate: DateTime(2020, 4, 15)),
FcsShipment(
shipDate: DateTime(2020, 4, 10),
shipmentNumber: 'A102B',
status: 'Canceled',
arrivalDate: DateTime(2020, 4, 20),
departureDate: DateTime(2020, 4, 10)),
FcsShipment(
shipDate: DateTime(2020, 4, 2),
shipmentNumber: 'A100B',
status: 'Canceled',
arrivalDate: DateTime(2020, 4, 20),
departureDate: DateTime(2020, 4, 23)),
FcsShipment(
shipDate: DateTime(2020, 4, 10),
shipmentNumber: 'A102B',
status: 'Arrived',
arrivalDate: DateTime(2020, 4, 30),
departureDate: DateTime(2020, 4, 20),
)
];
final log = Logger('FcsShipmentModel');
List<FcsShipment> get canceled {
List<FcsShipment> _p =
shipments.where((e) => e.status == "Canceled").toList()
..sort((e1, e2) {
return e1.shipDate.compareTo(e2.shipDate);
});
return _p;
StreamSubscription<QuerySnapshot> listener;
List<FcsShipment> fcsShipments = [];
@override
void privilegeChanged() {
super.privilegeChanged();
_loadFcsShipments();
}
List<FcsShipment> get completed {
return shipments.where((e) => e.status == "Arrived").toList()
..sort((e1, e2) {
return e1.shipDate.compareTo(e2.shipDate);
Future<void> _loadFcsShipments() async {
if (user == null) return;
String path = "/$fcs_shipment_collection/";
if (listener != null) listener.cancel();
fcsShipments = [];
try {
listener = Firestore.instance
.collection("$path")
.snapshots()
.listen((QuerySnapshot snapshot) {
fcsShipments.clear();
fcsShipments = snapshot.documents.map((documentSnapshot) {
var s = FcsShipment.fromMap(
documentSnapshot.data, documentSnapshot.documentID);
return s;
}).toList();
notifyListeners();
});
}
List<FcsShipment> get upcoming {
List<FcsShipment> _shipments = shipments
.where((e) =>
e.status == "In Progress" ||
e.status == "Ready to ship" ||
e.status == "Processed" ||
e.status == "Rescheduled")
.toList();
_shipments.sort((e1, e2) {
return e1.shipDate.compareTo(e2.shipDate);
});
return _shipments;
} catch (e) {
log.warning("Error!! $e");
}
}
void initUser(user) {
@@ -81,6 +48,14 @@ class FcsShipmentModel extends BaseModel {
@override
logout() async {
shipments = [];
fcsShipments = [];
}
Future<void> create(FcsShipment fcsShipment) {
return Services.instance.fcsShipmentService.createFcsShipment(fcsShipment);
}
Future<void> update(FcsShipment fcsShipment) {
return Services.instance.fcsShipmentService.updateFcsShipment(fcsShipment);
}
}