update boxes

This commit is contained in:
Thinzar Win
2020-10-14 16:53:16 +06:30
parent 6c871ea066
commit 4862f1123d
11 changed files with 894 additions and 264 deletions

View File

@@ -242,13 +242,13 @@
"box.package.desc":"Description", "box.package.desc":"Description",
"box.package.market":"Market", "box.package.market":"Market",
"box.add_package":"Add package", "box.add_package":"Add package",
"box.number":"Box number", "box.number":"Carton number",
"box.length":"Length", "box.length":"Length",
"box.width":"Width", "box.width":"Width",
"box.height":"Height", "box.height":"Height",
"box.shipment_info":"Shipment information", "box.shipment_info":"Shipment information",
"box.cargo_type":"Cargo types", "box.cargo_type":"Cargo types",
"box.dimension":"Carton dimension", "box.dimension":"Dimension",
"box.delivery_address":"Delivery address", "box.delivery_address":"Delivery address",
"box.fcs_shipment_num":"FCS shipment number", "box.fcs_shipment_num":"FCS shipment number",
"box.fcs.id":"FCS ID", "box.fcs.id":"FCS ID",
@@ -266,7 +266,13 @@
"box.tracking.id":"Tracking ID", "box.tracking.id":"Tracking ID",
"box.market":"Market", "box.market":"Market",
"box.cargo.save.btn":"Save", "box.cargo.save.btn":"Save",
"box.type.title":"Carton Types", "box.type.title":"Carton types",
"box.shipment.boxes":"Cartons",
"box.shipment_number":"Shipment number",
"box.shipment.desc":"Description",
"box.mix.number":"Carton number",
"box.mix.desc":"Description",
"box.info.title":"Carton",
"Boxes End ================================================================":"", "Boxes End ================================================================":"",
"Delivery Start ================================================================":"", "Delivery Start ================================================================":"",
@@ -305,7 +311,7 @@
"shipment.edit.title": "Edit Shipment", "shipment.edit.title": "Edit Shipment",
"shipment.type": "Pickup/drop-off", "shipment.type": "Pickup/drop-off",
"shipment.date": "Pickup date", "shipment.date": "Pickup date",
"shipment.date.time": "Pickup date/time", "shipment.date.time": "Pickup date/Time",
"shipment.time": "Pickup time", "shipment.time": "Pickup time",
"shipment.location": "Pickup address", "shipment.location": "Pickup address",
"shipment.location_time": "Pickup Location / Time", "shipment.location_time": "Pickup Location / Time",

View File

@@ -234,21 +234,21 @@
"Boxes Start ================================================================":"", "Boxes Start ================================================================":"",
"boxes.name":"သေတ္တာများ", "boxes.name":"သေတ္တာများ",
"boxes.title":"Boxes", "boxes.title":"သေတ္တာများ",
"boxes.new":"သေတ္တာ အသစ်", "boxes.new":"သေတ္တာ အသစ်",
"boxes.create.title":"သေတ္တာ အသစ်", "boxes.create.title":"သေတ္တာ အသစ်",
"box.edit.title":"သေတ္တာ ပြင်ဆင်ခြင်း", "box.edit.title":"သေတ္တာ ပြင်ဆင်ခြင်း",
"box.package.id":"Package ID", "box.package.id":"Package ID",
"box.package.desc":"Description", "box.package.desc":"ဖော်ပြချက်",
"box.package.market":"Market", "box.package.market":"Market",
"box.add_package":"Add Package", "box.add_package":"Add Package",
"box.number":"Box နံပါတ်", "box.number":"သေတ္တာ နံပါတ်",
"box.length":"အလျား", "box.length":"အလျား",
"box.width":"အနံ", "box.width":"အနံ",
"box.height":"အမြင့်", "box.height":"အမြင့်",
"box.shipment_info":"တင်ပို့သတင်းအချက်အလက်", "box.shipment_info":"တင်ပို့သတင်းအချက်အလက်",
"box.cargo_type":"ကုန်ပစ္စည်းအမျိုးအစားများ", "box.cargo_type":"ကုန်ပစ္စည်းအမျိုးအစားများ",
"box.dimension":"သေတ္တာအရွယ်အစား", "box.dimension":"အရွယ်အစား",
"box.delivery_address":"ပို့ဆောင်ရမည့်လိပ်စာ", "box.delivery_address":"ပို့ဆောင်ရမည့်လိပ်စာ",
"box.fcs_shipment_num":"FCS တင်ပို့နံပါတ်", "box.fcs_shipment_num":"FCS တင်ပို့နံပါတ်",
"box.fcs.id":"FCS ID", "box.fcs.id":"FCS ID",
@@ -267,6 +267,12 @@
"box.market":"အွန်လိုင်စျေးဆိုင်", "box.market":"အွန်လိုင်စျေးဆိုင်",
"box.cargo.save.btn":"သိမ်းဆည်းမည်", "box.cargo.save.btn":"သိမ်းဆည်းမည်",
"box.type.title":"သေတ္တာအမျိုးအစားများ", "box.type.title":"သေတ္တာအမျိုးအစားများ",
"box.shipment.boxes":"သေတ္တာများ",
"box.shipment_number":"ပို့ဆောင်နံပါတ်",
"box.shipment.desc":"ဖော်ပြချက်",
"box.mix.number":"သေတ္တာ နံပါတ်",
"box.mix.desc":"ဖော်ပြချက်",
"box.info.title":"သေတ္တာ",
"Boxes End ================================================================":"", "Boxes End ================================================================":"",
"Delivery Start ================================================================":"", "Delivery Start ================================================================":"",
@@ -305,23 +311,23 @@
"shipment.edit.title": "ပို့ဆောင်ခြင်း ပြင်ဆင်ခြင်း", "shipment.edit.title": "ပို့ဆောင်ခြင်း ပြင်ဆင်ခြင်း",
"shipment.type": "Pickup/Drop-off", "shipment.type": "Pickup/Drop-off",
"shipment.date": "Pickup date", "shipment.date": "Pickup date",
"shipment.date.time": "Pickup date/time", "shipment.date.time": "Pickup date/Time",
"shipment.time": "Pickup Time", "shipment.time": "Pickup time",
"shipment.location_time": "Pickup Location / Time", "shipment.location_time": "Pickup location / Time",
"shipment.location": "Pickup location", "shipment.location": "Pickup location",
"shipment.information": "Pickup informations", "shipment.information": "Pickup informations",
"shipment.recipient_information": "Recipient Informations", "shipment.recipient_information": "Recipient informations",
"shipment.from":"From", "shipment.from":"From",
"shipment.to":"To", "shipment.to":"To",
"shipment.box.delivery":"Delivery Address", "shipment.box.delivery":"Delivery address",
"shipment.handling.fee":"Handling Fee/Courier Fee", "shipment.handling.fee":"Handling fee/Courier fee",
"shipment.box.cargo.type":"Cargo Types", "shipment.box.cargo.type":"Cargo types",
"shipment.box.dimemsion":"Dimension", "shipment.box.dimemsion":"Dimension",
"shipment.box.shipment.weight":"Shipment weight", "shipment.box.shipment.weight":"Shipment weight",
"shipment.box.length":"Length", "shipment.box.length":"Length",
"shipment.box.width":"Width", "shipment.box.width":"Width",
"shipment.box.height":"Height", "shipment.box.height":"Height",
"shipment.box.add":"Add Box", "shipment.box.add":"Add carton",
"Shipment End ================================================================":"", "Shipment End ================================================================":"",
"Rate Start ================================================================":"", "Rate Start ================================================================":"",

View File

@@ -58,4 +58,4 @@ const shipment_courier_dropoff = "Courier drop-off";
//Carton types //Carton types
const carton_from_packages = "From packages"; const carton_from_packages = "From packages";
const carton_from_shipments = "From shipments"; const carton_from_shipments = "From shipments";
const carton_mix_box = "Mix box"; const carton_mix_box = "Mix carton";

View File

@@ -16,10 +16,15 @@ class Box {
String boxNumber; String boxNumber;
String status; String status;
String cargoDesc; String cargoDesc;
String desc;
int width; int width;
int height; int height;
int length; int length;
int shipmentWeight; int shipmentWeight;
bool isChecked;
String cartonType;
String fcsID;
String userName;
int rate; int rate;
int weight; int weight;
@@ -66,10 +71,15 @@ class Box {
this.receiverNumber, this.receiverNumber,
this.receiverAddress, this.receiverAddress,
this.boxNumber, this.boxNumber,
this.desc,
this.width, this.width,
this.height, this.height,
this.length, this.length,
this.shipmentWeight, this.shipmentWeight,
this.isChecked = false,
this.cartonType,
this.fcsID,
this.userName,
this.rate, this.rate,
this.weight, this.weight,
this.packageType, this.packageType,

View File

@@ -1,3 +1,4 @@
import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/box.dart'; import 'package:fcs/domain/entities/box.dart';
import 'package:fcs/domain/entities/cargo.dart'; import 'package:fcs/domain/entities/cargo.dart';
import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/domain/entities/package.dart';
@@ -5,7 +6,6 @@ import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/domain/vo/delivery_address.dart'; import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/localization/app_translations.dart'; import 'package:fcs/localization/app_translations.dart';
import 'package:fcs/pages/delivery_address/delivery_address_list.dart';
import 'package:fcs/pages/delivery_address/delivery_address_row.dart'; import 'package:fcs/pages/delivery_address/delivery_address_row.dart';
import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart';
import 'package:fcs/pages/main/model/language_model.dart'; import 'package:fcs/pages/main/model/language_model.dart';
@@ -18,21 +18,16 @@ import 'package:fcs/pages/widgets/defalut_delivery_address.dart';
import 'package:fcs/pages/widgets/delivery_address_selection.dart'; import 'package:fcs/pages/widgets/delivery_address_selection.dart';
import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/fcs_id_icon.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart';
import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/length_picker.dart';
import 'package:fcs/pages/widgets/local_button.dart';
import 'package:fcs/pages/widgets/local_radio_buttons.dart'; import 'package:fcs/pages/widgets/local_radio_buttons.dart';
import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/local_title.dart'; import 'package:fcs/pages/widgets/local_title.dart';
import 'package:fcs/pages/widgets/my_data_table.dart';
import 'package:fcs/pages/widgets/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:fcs/pages/widgets/title_with_add_button.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.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:provider/provider.dart';
import 'package:timeline_list/timeline.dart';
import 'package:timeline_list/timeline_model.dart';
import 'cargo_type_editor.dart'; import 'cargo_type_editor.dart';
import 'model/box_model.dart'; import 'model/box_model.dart';
@@ -52,19 +47,22 @@ class _BoxEditorState extends State<BoxEditor> {
Box _box; Box _box;
bool _isLoading = false; bool _isLoading = false;
bool isNew; bool isNew;
bool isMixBox = false;
DeliveryAddress _deliveryAddress = new DeliveryAddress(); DeliveryAddress _deliveryAddress = new DeliveryAddress();
User user; User user;
String _selectShipmentNumber; String _selectShipmentNumber;
String _selectedCartonType; String _selectedCartonType;
List<Package> _packages = []; List<Package> _packages = [];
List<Box> _shipmentBoxes = [];
List<Box> _mixBoxes = [];
List<Cargo> _cargoTypes = []; List<Cargo> _cargoTypes = [];
double volumetricRatio = 0; double volumetricRatio = 0;
double shipmentWeight = 0; double shipmentWeight = 0;
Box _selectedShipmentBox;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// for packages
var packageModel = Provider.of<PackageModel>(context, listen: false); var packageModel = Provider.of<PackageModel>(context, listen: false);
_packages = [ _packages = [
packageModel.packages[0], packageModel.packages[0],
@@ -73,6 +71,18 @@ class _BoxEditorState extends State<BoxEditor> {
_packages.forEach((p) { _packages.forEach((p) {
p.isChecked = false; p.isChecked = false;
}); });
//for shipment boxes
var boxModel = Provider.of<BoxModel>(context, listen: false);
_shipmentBoxes = [boxModel.boxes[0], boxModel.boxes[1], boxModel.boxes[2]];
//for mix boxes
_mixBoxes = [boxModel.boxes[0], boxModel.boxes[1], boxModel.boxes[2]];
_mixBoxes.forEach((b) {
b.isChecked = false;
});
//for shipment weight
volumetricRatio = volumetricRatio =
Provider.of<MainModel>(context, listen: false).setting.volumetricRatio; Provider.of<MainModel>(context, listen: false).setting.volumetricRatio;
_lengthController.addListener(_calShipmentWeight); _lengthController.addListener(_calShipmentWeight);
@@ -87,6 +97,7 @@ class _BoxEditorState extends State<BoxEditor> {
_widthController.text = _box.width.toString(); _widthController.text = _box.width.toString();
_heightController.text = _box.height.toString(); _heightController.text = _box.height.toString();
_lengthController.text = _box.length.toString(); _lengthController.text = _box.length.toString();
_selectedCartonType = _box.cartonType;
isNew = false; isNew = false;
} else { } else {
_cargoTypes = [ _cargoTypes = [
@@ -99,6 +110,7 @@ class _BoxEditorState extends State<BoxEditor> {
Provider.of<DeliveryAddressModel>(context, listen: false); Provider.of<DeliveryAddressModel>(context, listen: false);
_deliveryAddress = shipmentModel.defalutAddress; _deliveryAddress = shipmentModel.defalutAddress;
isNew = true; isNew = true;
_selectedCartonType = carton_from_packages;
} }
} }
@@ -116,46 +128,6 @@ class _BoxEditorState extends State<BoxEditor> {
super.dispose(); super.dispose();
} }
final DateFormat dateFormat = DateFormat("d MMM yyyy");
List<TimelineModel> _models() {
// return [];
return _box.shipmentHistory
.map((e) => TimelineModel(
Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(e.status,
style: TextStyle(
color: e.done ? primaryColor : Colors.grey,
fontSize: 16,
fontWeight: FontWeight.bold)),
e.status == "Processed"
? Text("(Waiting for payment)",
style: TextStyle(
color: e.done ? primaryColor : Colors.grey,
fontSize: 14,
fontWeight: FontWeight.bold))
: Container(),
Text(dateFormat.format(e.date)),
],
),
),
iconBackground: e.done ? primaryColor : Colors.grey,
icon: Icon(
e.status == "Shipped"
? Ionicons.ios_airplane
: e.status == "Delivered"
? MaterialCommunityIcons.truck_fast
: e.status == "Processed"
? MaterialIcons.check
: Octicons.package,
color: Colors.white,
)))
.toList();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var languageModel = Provider.of<LanguageModel>(context); var languageModel = Provider.of<LanguageModel>(context);
@@ -174,7 +146,7 @@ class _BoxEditorState extends State<BoxEditor> {
Ionicons.ios_airplane, Ionicons.ios_airplane,
color: primaryColor, color: primaryColor,
)), )),
items: ["A102", "A103", "A201", "A202"] items: ["A204", "A203", "A201", "A202"]
.map((e) => DropdownMenuItem( .map((e) => DropdownMenuItem(
child: Text( child: Text(
e, e,
@@ -189,33 +161,6 @@ class _BoxEditorState extends State<BoxEditor> {
}, },
)); ));
final mixBox = Container(
child: new Row(
children: <Widget>[
new Checkbox(
value: isMixBox,
activeColor: primaryColor,
onChanged: (bool value) {
setState(() {
isMixBox = value;
});
}),
SizedBox(
width: 5,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(
"Mix Box",
style: TextStyle(fontSize: 15.0),
),
],
),
],
),
);
final fcsIDBox = Row( final fcsIDBox = Row(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
@@ -251,12 +196,12 @@ class _BoxEditorState extends State<BoxEditor> {
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Container( Container(
width: 40, width: 30,
), ),
Expanded( Expanded(
child: LocalText(context, 'box.tracking.id', color: Colors.grey), child: LocalText(context, 'box.tracking.id', color: Colors.grey),
), ),
LocalText(context, 'box.market', color: Colors.grey), LocalText(context, 'box.package.desc', color: Colors.grey),
], ],
), ),
); );
@@ -294,11 +239,138 @@ class _BoxEditorState extends State<BoxEditor> {
p.value.trackingID, p.value.trackingID,
style: textStyle, style: textStyle,
)), )),
new Column(
children: [
new Text( new Text(
p.value.market == null ? "" : p.value.market, p.value.desc == null ? "" : p.value.desc,
style: textStyle,
),
new Text(
"(${p.value.market == null ? "" : p.value.market})",
style: textStyle, style: textStyle,
) )
], ],
)
],
),
),
);
}).toList();
}
final shipmentBoxTitle = Container(
padding: EdgeInsets.only(right: 10.0, top: 20),
child: Row(
children: <Widget>[
Container(
width: 30,
),
Expanded(
child:
LocalText(context, 'box.shipment_number', color: Colors.grey),
),
LocalText(context, 'box.shipment.desc', color: Colors.grey),
],
),
);
List<Widget> getshipmentBoxRowList() {
return _shipmentBoxes.asMap().entries.map((s) {
return Container(
color: Colors.grey[50].withOpacity(0.2),
child: Container(
padding:
EdgeInsets.only(left: 0.0, right: 10.0, top: 3.0, bottom: 3.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: s.key == _shipmentBoxes.length - 1
? Colors.white
: Colors.grey[350],
width: 1),
),
),
child: Row(
children: <Widget>[
Radio(
activeColor: primaryColor,
groupValue: _selectedShipmentBox,
value: s.value,
onChanged: (value) {
setState(() {
_selectedShipmentBox = value;
});
},
),
Expanded(
child: new Text(
s.value.shipmentNumber,
style: textStyle,
)),
new Text(
s.value.desc == null ? "" : s.value.desc,
style: textStyle,
),
],
),
),
);
}).toList();
}
final mixBoxTitle = Container(
padding: EdgeInsets.only(right: 10.0, top: 20),
child: Row(
children: <Widget>[
Container(
width: 30,
),
Expanded(
child: LocalText(context, 'box.mix.number', color: Colors.grey),
),
LocalText(context, 'box.mix.desc', color: Colors.grey),
],
),
);
List<Widget> getMixBoxRowList() {
return _mixBoxes.asMap().entries.map((b) {
return Container(
color: b.value.isChecked
? Colors.grey.withOpacity(0.2)
: Colors.grey[50].withOpacity(0.2),
child: Container(
padding:
EdgeInsets.only(left: 0.0, right: 10.0, top: 3.0, bottom: 3.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: b.key == _mixBoxes.length - 1
? Colors.white
: Colors.grey[350],
width: 1),
),
),
child: Row(
children: <Widget>[
Checkbox(
value: b.value.isChecked,
activeColor: primaryColor,
onChanged: (bool check) {
setState(() {
b.value.isChecked = check;
});
}),
Expanded(
child: new Text(
b.value.packageNumber,
style: textStyle,
)),
new Text(
b.value.desc == null ? "" : b.value.desc,
style: textStyle,
),
],
), ),
), ),
); );
@@ -328,11 +400,13 @@ class _BoxEditorState extends State<BoxEditor> {
var rows = _cargoTypes.asMap().entries.map((c) { var rows = _cargoTypes.asMap().entries.map((c) {
total += c.value.weight; total += c.value.weight;
return InkWell( return InkWell(
onTap: () { onTap: () async {
Navigator.push( Cargo cargo = await Navigator.push<Cargo>(
context, context,
BottomUpPageRoute(CargoTypeEditor(cargo: c.value)), BottomUpPageRoute(CargoTypeEditor(
); cargo: c.value,
)));
_addCargo(cargo);
}, },
child: Container( child: Container(
color: Colors.grey[50].withOpacity(0.2), color: Colors.grey[50].withOpacity(0.2),
@@ -411,58 +485,49 @@ class _BoxEditorState extends State<BoxEditor> {
return rows; return rows;
} }
final shipmentWeightBox = Container( final lengthBox = LengthPicker(
padding: EdgeInsets.only(left: 10), controller: _lengthController,
child: DisplayText( lableKey: "box.length",
);
final widthBox = LengthPicker(
controller: _widthController,
lableKey: "box.width",
);
final heightBox = LengthPicker(
controller: _heightController,
lableKey: "box.height",
);
final dimBox = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(FontAwesome.arrow_circle_right, color: primaryColor),
),
SizedBox(child: lengthBox, width: 80),
SizedBox(child: widthBox, width: 80),
SizedBox(child: heightBox, width: 80),
],
);
final shipmentWeightBox = DisplayText(
text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "",
labelTextKey: "box.shipment_weight", labelTextKey: "box.shipment_weight",
iconData: MaterialCommunityIcons.weight, iconData: MaterialCommunityIcons.weight,
)); );
final widthBox = Container( final createBtn = LocalButton(
padding: EdgeInsets.only(left: 10, right: 10), textKey: "box.create.btn",
child: InputText( );
labelTextKey: 'box.width',
iconData: FontAwesomeIcons.arrowCircleRight,
controller: _widthController));
final heightBox = Container( final completeBtn = LocalButton(
padding: EdgeInsets.only(left: 10, right: 10), textKey: "box.complete.btn",
child: InputText( );
labelTextKey: 'box.height',
iconData: FontAwesomeIcons.arrowAltCircleUp,
controller: _heightController));
final lengthBox = Container( final deliveryBtn = LocalButton(
padding: EdgeInsets.only(left: 10, right: 10), textKey: "box.deliver.btn",
child: InputText( );
labelTextKey: 'box.length',
iconData: FontAwesomeIcons.arrowCircleUp,
controller: _lengthController));
final createBtn = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: fcsButton(
context,
getLocalString(context, 'box.create.btn'),
callack: () {},
));
final completeBtn = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: fcsButton(
context,
getLocalString(context, 'box.complete.btn'),
callack: () {},
));
final deliveryBtn = Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: fcsButton(
context,
getLocalString(context, 'box.deliver.btn'),
callack: () {},
));
return LocalProgress( return LocalProgress(
inAsyncCall: _isLoading, inAsyncCall: _isLoading,
@@ -470,7 +535,7 @@ class _BoxEditorState extends State<BoxEditor> {
appBar: AppBar( appBar: AppBar(
centerTitle: true, centerTitle: true,
leading: new IconButton( leading: new IconButton(
icon: new Icon(Icons.close, color: primaryColor, size: 30), icon: new Icon(CupertinoIcons.back, color: primaryColor, size: 30),
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
), ),
shadowColor: Colors.transparent, shadowColor: Colors.transparent,
@@ -517,10 +582,10 @@ class _BoxEditorState extends State<BoxEditor> {
), ),
fcsIDBox, fcsIDBox,
namebox, namebox,
LocalTitle(textKey: "box.packages"), _selectedCartonType == "From packages"
? Column(
Column(
children: [ children: [
LocalTitle(textKey: "box.packages"),
packageTitle, packageTitle,
Divider( Divider(
color: Colors.grey[400], color: Colors.grey[400],
@@ -528,29 +593,48 @@ class _BoxEditorState extends State<BoxEditor> {
Column( Column(
children: getPackageRowList(), children: getPackageRowList(),
), ),
SizedBox(height: 10),
], ],
)
: _selectedCartonType == "From shipments"
? Column(
children: [
LocalTitle(textKey: "box.shipment.boxes"),
shipmentBoxTitle,
Divider(
color: Colors.grey[400],
), ),
Divider(), Column(
Container( children: getshipmentBoxRowList(),
padding: EdgeInsets.only(left: 10), ),
child: TitleWithAddButton( ],
iconData: MaterialCommunityIcons.briefcase_check, )
titleKey: "box.cargo_type", : _selectedCartonType == "Mix carton"
onTap: () async { ? Column(
children: [
LocalTitle(textKey: "box.shipment.boxes"),
mixBoxTitle,
Divider(
color: Colors.grey[400],
),
Column(
children: getMixBoxRowList(),
)
],
)
: Container(),
LocalTitle(
textKey: "box.cargo_type",
trailing: IconButton(
icon: Icon(
Icons.add_circle,
color: primaryColor,
),
onPressed: () async {
Cargo cargo = await Navigator.push<Cargo>( Cargo cargo = await Navigator.push<Cargo>(
context, BottomUpPageRoute(CargoTypeEditor())); context, BottomUpPageRoute(CargoTypeEditor()));
if (cargo != null) { _addCargo(cargo);
setState(() {
_box.cargoTypes.add(cargo);
});
}
}), }),
), ),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: Column(
children: [
cargoTitle, cargoTitle,
Divider( Divider(
color: Colors.grey[400], color: Colors.grey[400],
@@ -558,26 +642,11 @@ class _BoxEditorState extends State<BoxEditor> {
Column( Column(
children: getCargoRowList(), children: getCargoRowList(),
), ),
SizedBox(height: 10), LocalTitle(textKey: "box.dimension"),
], dimBox,
),
),
Divider(),
SizedBox(
height: 10,
),
TitleWithAddButton(
titleKey: "box.dimension",
),
shipmentWeightBox, shipmentWeightBox,
widthBox, LocalTitle(textKey: "box.delivery_address"),
heightBox, DefaultDeliveryAddress(
lengthBox,
SizedBox(height: 25),
Divider(),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
child: DefaultDeliveryAddress(
deliveryAddress: _deliveryAddress, deliveryAddress: _deliveryAddress,
labelKey: "box.delivery_address", labelKey: "box.delivery_address",
onTap: () async { onTap: () async {
@@ -592,31 +661,6 @@ class _BoxEditorState extends State<BoxEditor> {
this._deliveryAddress = d; this._deliveryAddress = d;
}); });
}), }),
),
SizedBox(height: 15),
Divider(),
isNew
? Container()
: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 10),
child: TitleWithAddButton(
titleKey: "box.status",
),
),
Container(
height: 230,
padding: EdgeInsets.only(left: 10),
child: isNew
? Container()
: Timeline(
children: _models(),
position: TimelinePosition.Left),
),
],
),
isNew ? Container() : Divider(),
SizedBox( SizedBox(
height: 10, height: 10,
), ),
@@ -650,4 +694,12 @@ class _BoxEditorState extends State<BoxEditor> {
); );
}).toList(); }).toList();
} }
_addCargo(Cargo cargo) {
if (cargo == null) return;
setState(() {
_cargoTypes.remove(cargo);
_cargoTypes.add(cargo);
});
}
} }

551
lib/pages/box/box_info.dart Normal file
View File

@@ -0,0 +1,551 @@
import 'package:fcs/domain/constants.dart';
import 'package:fcs/domain/entities/box.dart';
import 'package:fcs/domain/entities/cargo.dart';
import 'package:fcs/domain/entities/package.dart';
import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/model/main_model.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/package/model/package_model.dart';
import 'package:fcs/pages/widgets/bottom_up_page_route.dart';
import 'package:fcs/pages/widgets/defalut_delivery_address.dart';
import 'package:fcs/pages/widgets/display_text.dart';
import 'package:fcs/pages/widgets/fcs_id_icon.dart';
import 'package:fcs/pages/widgets/length_picker.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/multi_img_controller.dart';
import 'package:fcs/pages/widgets/multi_img_file.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:fcs/pages/widgets/status_tree.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:timeline_list/timeline.dart';
import 'package:timeline_list/timeline_model.dart';
import 'box_editor.dart';
import 'model/box_model.dart';
final DateFormat dateFormat = DateFormat("d MMM yyyy");
class BoxInfo extends StatefulWidget {
final Box box;
BoxInfo({this.box});
@override
_BoxInfoState createState() => _BoxInfoState();
}
class _BoxInfoState extends State<BoxInfo> {
bool _isLoading = false;
Box _box;
String _selectedCartonType;
String _shipmentNumber;
List<Package> _packages = [];
List<Box> _mixBoxes = [];
Box _selectedShipmentBox;
List<Cargo> _cargoTypes = [];
DeliveryAddress _deliveryAddress = new DeliveryAddress();
TextEditingController _widthController = new TextEditingController();
TextEditingController _heightController = new TextEditingController();
TextEditingController _lengthController = new TextEditingController();
double volumetricRatio = 0;
double shipmentWeight = 0;
@override
void initState() {
super.initState();
_box = widget.box;
_shipmentNumber = _box.shipmentNumber;
_selectedCartonType = _box.cartonType;
// for packages
var packageModel = Provider.of<PackageModel>(context, listen: false);
_packages = [
packageModel.packages[0],
packageModel.packages[1],
];
_packages.forEach((p) {
p.isChecked = false;
});
//for shipment boxes
var boxModel = Provider.of<BoxModel>(context, listen: false);
_selectedShipmentBox = boxModel.boxes[0];
//for mix boxes
_mixBoxes = [boxModel.boxes[0], boxModel.boxes[1], boxModel.boxes[2]];
_mixBoxes.forEach((b) {
b.isChecked = false;
});
//for shipment weight
volumetricRatio =
Provider.of<MainModel>(context, listen: false).setting.volumetricRatio;
_lengthController.addListener(_calShipmentWeight);
_widthController.addListener(_calShipmentWeight);
_heightController.addListener(_calShipmentWeight);
_widthController.text = _box.width.toString();
_heightController.text = _box.height.toString();
_lengthController.text = _box.length.toString();
_cargoTypes = _box.cargoTypes;
_deliveryAddress = _box.shippingAddress;
}
_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();
}
final DateFormat dateFormat = DateFormat("d MMM yyyy");
List<TimelineModel> _models() {
// return [];
return _box.shipmentHistory
.map((e) => TimelineModel(
Padding(
padding: const EdgeInsets.all(18.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(e.status,
style: TextStyle(
color: e.done ? primaryColor : Colors.grey,
fontSize: 16,
fontWeight: FontWeight.bold)),
e.status == "Processed"
? Text("(Waiting for payment)",
style: TextStyle(
color: e.done ? primaryColor : Colors.grey,
fontSize: 14,
fontWeight: FontWeight.bold))
: Container(),
Text(dateFormat.format(e.date)),
],
),
),
iconBackground: e.done ? primaryColor : Colors.grey,
icon: Icon(
e.status == "Shipped"
? Ionicons.ios_airplane
: e.status == "Delivered"
? MaterialCommunityIcons.truck_fast
: e.status == "Processed"
? MaterialIcons.check
: Octicons.package,
color: Colors.white,
)))
.toList();
}
@override
Widget build(BuildContext context) {
var boxModel = Provider.of<BoxModel>(context);
final shipmentBox = DisplayText(
text: _shipmentNumber == null ? "" : _shipmentNumber,
labelTextKey: "box.fcs_shipment_num",
iconData: Ionicons.ios_airplane,
);
final fcsIDBox = DisplayText(
text: _box.fcsID == null ? "" : _box.fcsID,
labelTextKey: "box.fcs.id",
icon: FcsIDIcon(),
);
final customerNameBox = DisplayText(
text: _box.userName == null ? "" : _box.userName,
labelTextKey: "box.name",
iconData: Icons.person,
);
final packageTitle = Container(
padding: EdgeInsets.only(left: 15, right: 10.0, top: 20),
child: Row(
children: <Widget>[
Expanded(
child: LocalText(context, 'box.tracking.id', color: Colors.grey),
),
LocalText(context, 'box.package.desc', color: Colors.grey),
],
),
);
List<Widget> getPackageRowList() {
return _packages.asMap().entries.map((p) {
return Container(
color: Colors.grey[50].withOpacity(0.2),
child: Container(
padding:
EdgeInsets.only(left: 15.0, right: 10.0, top: 5.0, bottom: 5.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: p.key == _packages.length - 1
? Colors.white
: Colors.grey[350],
width: 1),
),
),
child: Row(
children: <Widget>[
Expanded(
child: new Text(
p.value.trackingID,
style: textStyle,
)),
new Column(
children: [
new Text(
p.value.desc == null ? "" : p.value.desc,
style: textStyle,
),
new Text(
"(${p.value.market == null ? "" : p.value.market})",
style: textStyle,
)
],
)
],
),
),
);
}).toList();
}
final shipmentBoxTitle = Container(
padding: EdgeInsets.only(left: 15, right: 10.0, top: 20),
child: Row(
children: <Widget>[
Expanded(
child:
LocalText(context, 'box.shipment_number', color: Colors.grey),
),
LocalText(context, 'box.shipment.desc', color: Colors.grey),
],
),
);
final shipmentBoxRow = Container(
padding: EdgeInsets.only(left: 15.0, right: 10.0, top: 5.0, bottom: 5.0),
child: Row(
children: <Widget>[
Expanded(
child: new Text(
_selectedShipmentBox.shipmentNumber == null
? ""
: _selectedShipmentBox.shipmentNumber,
style: textStyle,
)),
new Text(
_selectedShipmentBox.desc == null ? "" : _selectedShipmentBox.desc,
style: textStyle,
),
],
),
);
final mixBoxTitle = Container(
padding: EdgeInsets.only(left: 15, right: 10.0, top: 20),
child: Row(
children: <Widget>[
Expanded(
child: LocalText(context, 'box.mix.number', color: Colors.grey),
),
LocalText(context, 'box.mix.desc', color: Colors.grey),
],
),
);
List<Widget> getMixBoxRowList() {
return _mixBoxes.asMap().entries.map((b) {
return Container(
color: Colors.grey[50].withOpacity(0.2),
child: Container(
padding: EdgeInsets.only(
left: 15.0, right: 10.0, top: 13.0, bottom: 13.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: b.key == _mixBoxes.length - 1
? Colors.white
: Colors.grey[350],
width: 1),
),
),
child: Row(
children: <Widget>[
Expanded(
child: new Text(
b.value.packageNumber,
style: textStyle,
)),
new Text(
b.value.desc == null ? "" : b.value.desc,
style: textStyle,
),
],
),
),
);
}).toList();
}
final cargoTitle = Container(
padding: EdgeInsets.only(left: 15, right: 0.0, top: 20),
child: Row(
children: <Widget>[
Expanded(
child: LocalText(context, 'cargo.type', color: Colors.grey),
),
Container(
padding: EdgeInsets.only(right: 10),
child: LocalText(context, 'cargo.weight', color: Colors.grey)),
],
),
);
List<Widget> getCargoRowList() {
if (_cargoTypes == null) {
return [];
}
int total = 0;
var rows = _cargoTypes.asMap().entries.map((c) {
total += c.value.weight;
return InkWell(
onTap: () {},
child: Container(
color: Colors.grey[50].withOpacity(0.2),
child: Container(
padding: EdgeInsets.only(
left: 15.0, right: 10.0, top: 13.0, bottom: 13.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[350], width: 1),
),
),
child: Row(
children: <Widget>[
Expanded(
child: new Text(
c.value.type,
style: textStyle,
)),
Container(
padding: EdgeInsets.only(right: 10),
child: new Text(
c.value.weight == null ? "0" : c.value.weight.toString(),
style: textStyle,
),
)
],
),
),
),
);
}).toList();
var totalRow = InkWell(
child: Container(
color: Colors.grey[50].withOpacity(0.2),
child: Container(
padding:
EdgeInsets.only(left: 15.0, right: 10.0, top: 15.0, bottom: 15.0),
child: Row(
children: <Widget>[
Expanded(
child: new Text(
"Total Weight",
style: TextStyle(fontWeight: FontWeight.bold),
)),
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Align(
alignment: Alignment.centerRight,
child: new Text(
total.toString(),
style: TextStyle(fontWeight: FontWeight.bold),
),
),
)
],
),
),
));
rows.add(totalRow);
return rows;
}
final lengthBox = LengthPicker(
controller: _lengthController,
lableKey: "box.length",
isReadOnly: true,
);
final widthBox = LengthPicker(
controller: _widthController,
lableKey: "box.width",
isReadOnly: true,
);
final heightBox = LengthPicker(
controller: _heightController,
lableKey: "box.height",
isReadOnly: true,
);
final dimBox = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Icon(FontAwesome.arrow_circle_right, color: primaryColor),
),
SizedBox(child: lengthBox, width: 80),
SizedBox(child: widthBox, width: 80),
SizedBox(child: heightBox, width: 80),
],
);
final shipmentWeightBox = DisplayText(
text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "",
labelTextKey: "box.shipment_weight",
iconData: MaterialCommunityIcons.weight,
);
return LocalProgress(
inAsyncCall: _isLoading,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
leading: new IconButton(
icon: new Icon(CupertinoIcons.back, color: primaryColor, size: 30),
onPressed: () => Navigator.of(context).pop(),
),
shadowColor: Colors.transparent,
backgroundColor: Colors.white,
title: LocalText(
context,
"box.info.title",
fontSize: 20,
color: primaryColor,
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.edit, color: primaryColor),
onPressed: _gotoEditor,
),
],
),
body: Card(
child: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: ListView(children: <Widget>[
Center(child: nameWidget(_box.packageNumber)),
SizedBox(
height: 10,
),
LocalTitle(textKey: "box.type.title"),
LocalRadioButtons(
values: boxModel.cartonTypes,
selectedValue: _selectedCartonType,
callback: (v) {}),
LocalTitle(textKey: "box.shipment_info"),
shipmentBox,
fcsIDBox,
customerNameBox,
_selectedCartonType == "From packages"
? Column(
children: [
LocalTitle(textKey: "box.packages"),
packageTitle,
Divider(
color: Colors.grey[400],
),
Column(
children: getPackageRowList(),
),
],
)
: _selectedCartonType == "From shipments"
? Column(
children: [
LocalTitle(textKey: "box.shipment.boxes"),
shipmentBoxTitle,
Divider(
color: Colors.grey[400],
),
shipmentBoxRow
],
)
: _selectedCartonType == "Mix carton"
? Column(
children: [
LocalTitle(textKey: "box.shipment.boxes"),
mixBoxTitle,
Divider(
color: Colors.grey[400],
),
Column(
children: getMixBoxRowList(),
)
],
)
: Container(),
LocalTitle(textKey: "box.cargo_type"),
cargoTitle,
Divider(
color: Colors.grey[400],
),
Column(
children: getCargoRowList(),
),
LocalTitle(textKey: "box.dimension"),
dimBox,
shipmentWeightBox,
LocalTitle(textKey: "box.delivery_address"),
DefaultDeliveryAddress(
deliveryAddress: _deliveryAddress,
labelKey: "box.delivery_address",
),
LocalTitle(textKey: "box.status"),
Container(
height: 230,
child: Timeline(
children: _models(), position: TimelinePosition.Left),
),
SizedBox(
height: 20,
)
]),
)),
],
),
),
),
);
}
_gotoEditor() async {
Navigator.push(
context,
BottomUpPageRoute(BoxEditor(box: widget.box)),
);
}
}

View File

@@ -51,7 +51,7 @@ class _BoxListState extends State<BoxList> {
Icons.search, Icons.search,
color: Colors.white, color: Colors.white,
), ),
iconSize: 30, iconSize: 30, onPressed: () {},
// onPressed: () => showPlacesSearch(context), // onPressed: () => showPlacesSearch(context),
), ),
], ],

View File

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'box_editor.dart'; import 'box_editor.dart';
import 'box_info.dart';
class BoxListRow extends StatefulWidget { class BoxListRow extends StatefulWidget {
final bool isReadOnly; final bool isReadOnly;
@@ -32,17 +33,10 @@ class _BoxListRowState extends State<BoxListRow> {
padding: EdgeInsets.only(left: 15, right: 15), padding: EdgeInsets.only(left: 15, right: 15),
child: InkWell( child: InkWell(
onTap: () { onTap: () {
if (widget.isReadOnly) {
// Navigator.push(
// context,
// BottomUpPageRoute(PackageInfo(package: _box)),
// );
} else {
Navigator.push( Navigator.push(
context, context,
BottomUpPageRoute(BoxEditor(box: _box)), BottomUpPageRoute(BoxInfo(box: _box)),
); );
}
}, },
child: Row( child: Row(
children: <Widget>[ children: <Widget>[

View File

@@ -38,6 +38,8 @@ class BoxModel extends BaseModel {
status: "Packed", status: "Packed",
receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon', receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon',
cargoDesc: "Clothes", cargoDesc: "Clothes",
desc: "Desc 1",
cartonType: carton_from_packages,
arrivedDate: DateTime(2020, 6, 1), arrivedDate: DateTime(2020, 6, 1),
width: 10, width: 10,
height: 10, height: 10,
@@ -58,7 +60,7 @@ class BoxModel extends BaseModel {
Cargo(type: 'Dangerous', weight: 30) Cargo(type: 'Dangerous', weight: 30)
]), ]),
Box( Box(
shipmentNumber: "A202", shipmentNumber: "A203",
receiverNumber: "3", receiverNumber: "3",
receiverName: "Ko Myo Min", receiverName: "Ko Myo Min",
boxNumber: "2", boxNumber: "2",
@@ -67,6 +69,7 @@ class BoxModel extends BaseModel {
weight: 75, weight: 75,
status: "Packed", status: "Packed",
cargoDesc: "Clothes", cargoDesc: "Clothes",
desc: "Desc 2",
arrivedDate: DateTime(2020, 6, 1), arrivedDate: DateTime(2020, 6, 1),
width: 10, width: 10,
height: 20, height: 20,
@@ -75,6 +78,7 @@ class BoxModel extends BaseModel {
shipmentHistory: statusHistory, shipmentHistory: statusHistory,
packages: packages, packages: packages,
receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon', receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon',
cartonType: carton_from_shipments,
shippingAddress: DeliveryAddress( shippingAddress: DeliveryAddress(
fullName: 'Mg Myo', fullName: 'Mg Myo',
addressLine1: '153-154 5th Thitsar.', addressLine1: '153-154 5th Thitsar.',
@@ -88,7 +92,7 @@ class BoxModel extends BaseModel {
Cargo(type: 'Dangerous', weight: 30) Cargo(type: 'Dangerous', weight: 30)
]), ]),
Box( Box(
shipmentNumber: "A202", shipmentNumber: "A204",
receiverNumber: "3", receiverNumber: "3",
receiverName: "Ko Myo Min", receiverName: "Ko Myo Min",
boxNumber: "3", boxNumber: "3",
@@ -97,6 +101,8 @@ class BoxModel extends BaseModel {
weight: 75, weight: 75,
cargoDesc: "Shoes", cargoDesc: "Shoes",
status: "Packed", status: "Packed",
desc: "Desc 3",
cartonType: carton_mix_box,
arrivedDate: DateTime(2020, 6, 1), arrivedDate: DateTime(2020, 6, 1),
width: 10, width: 10,
height: 10, height: 10,
@@ -127,6 +133,7 @@ class BoxModel extends BaseModel {
weight: 75, weight: 75,
status: "Packed", status: "Packed",
cargoDesc: "Dietary supplement", cargoDesc: "Dietary supplement",
desc: "Desc 4",
arrivedDate: DateTime(2020, 6, 1), arrivedDate: DateTime(2020, 6, 1),
width: 10, width: 10,
height: 10, height: 10,

View File

@@ -178,6 +178,7 @@ class _ShipmentBoxEditorState extends State<ShipmentBoxEditor> {
LocalTitle(textKey: "shipment.box.delivery"), LocalTitle(textKey: "shipment.box.delivery"),
DefaultDeliveryAddress( DefaultDeliveryAddress(
deliveryAddress: _deliveryAddress, deliveryAddress: _deliveryAddress,
labelKey: "shipment.box.delivery",
onTap: () async { onTap: () async {
DeliveryAddress d = await Navigator.push<DeliveryAddress>( DeliveryAddress d = await Navigator.push<DeliveryAddress>(
context, context,

View File

@@ -8,8 +8,9 @@ import 'input_text.dart';
class LengthPicker extends StatefulWidget { class LengthPicker extends StatefulWidget {
final TextEditingController controller; final TextEditingController controller;
final String lableKey; final String lableKey;
final bool isReadOnly;
const LengthPicker({Key key, this.controller, this.lableKey}) const LengthPicker({Key key, this.controller, this.lableKey, this.isReadOnly})
: super(key: key); : super(key: key);
@override @override
@@ -40,7 +41,9 @@ class _LengthPickerState extends State<LengthPicker> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return InkWell( return InkWell(
onTap: () => _showDialog(context), onTap: () => widget.isReadOnly == null
? _showDialog(context)
: widget.isReadOnly ? null : _showDialog(context),
child: Padding( child: Padding(
padding: EdgeInsets.only(left: 8, right: 8), padding: EdgeInsets.only(left: 8, right: 8),
child: InputText( child: InputText(