update carton and add staff name

This commit is contained in:
Thinzar Win
2020-12-10 20:06:15 +06:30
parent d540bfbd30
commit d1261a33c1
19 changed files with 1030 additions and 330 deletions

View File

@@ -296,6 +296,9 @@
"box.new_carton_btn":"Create new carton",
"box.select.cargo.title":"Select cargos",
"box.complete.packaging":"Complete Packaging",
"box.mix_caton_title":"Mix cartons",
"box.min_caton.form.title":"Mix Carton",
"box.mix_carton_btn":"Create mix carton",
"Boxes End ================================================================":"",
"Delivery Start ================================================================":"",

View File

@@ -296,6 +296,9 @@
"box.new_carton_btn":"သေတ္တာ အသစ်ပြုလုပ်မည်",
"box.select.cargo.title":"Sကုန်ပစ္စည်းများ ရွေးခြင်း",
"box.complete.packaging":"ထုပ်ပိုးခြင်း ပြီးဆုံးမည်",
"box.mix_caton_title":"Mix cartons",
"box.min_caton.form.title":"Mix Carton",
"box.mix_carton_btn":"Create mix carton",
"Boxes End ================================================================":"",
"Delivery Start ================================================================":"",

View File

@@ -79,8 +79,13 @@ const shipment_courier_dropoff = "Courier drop off";
//Carton types
const carton_from_packages = "From packages";
const carton_from_shipments = "From shipments";
const carton_mix_box = "Mix carton";
const carton_mix_carton = "Mix carton";
const carton_small_bag = "Small bag";
const carton_mix_box = "Mix box";
//Mix types
const mix_delivery = "Mix Delivery";
const mix_pickup = "Mix Pickup";
//Carton status
const carton_packed_status = "packed";

View File

@@ -4,14 +4,18 @@ class ShipmentStatus {
String status;
DateTime date;
bool done;
ShipmentStatus({this.status, this.date, this.done});
String staffId;
String staffName;
ShipmentStatus(
{this.status, this.date, this.done, this.staffId, this.staffName});
factory ShipmentStatus.fromMap(Map<String, dynamic> map) {
var _date = (map['date'] as Timestamp);
return ShipmentStatus(
status: map['status'],
date: _date == null ? null : _date.toDate(),
done: map['done'],
);
status: map['status'],
date: _date == null ? null : _date.toDate(),
done: map['done'],
staffId: map['staff_id'],
staffName: map['staff_name']);
}
}

View File

@@ -0,0 +1,97 @@
import 'package:fcs/domain/entities/cargo_type.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/my_data_table.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CargoTable extends StatefulWidget {
final List<CargoType> cargoTypes;
const CargoTable({
Key key,
this.cargoTypes,
}) : super(key: key);
@override
_CargoTableState createState() => _CargoTableState();
}
class _CargoTableState extends State<CargoTable> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: MyDataTable(
headingRowHeight: 40,
columnSpacing: 140,
columns: [
MyDataColumn(
label: LocalText(
context,
"cargo.type",
color: Colors.grey,
),
),
MyDataColumn(
label: LocalText(
context,
"cargo.weight",
color: Colors.grey,
),
),
],
rows: getCargoRows(context),
),
);
}
List<MyDataRow> getCargoRows(BuildContext context) {
if (widget.cargoTypes == null) {
return [];
}
double total = 0;
var rows = widget.cargoTypes.map((c) {
total += c.weight;
return MyDataRow(
onSelectChanged: (bool selected) async {},
cells: [
MyDataCell(new Text(
c.name == null ? "" : c.name,
style: textStyle,
)),
MyDataCell(
Text(c.weight == null ? "0" : c.weight.toStringAsFixed(2),
style: textStyle),
),
],
);
}).toList();
var totalRow = MyDataRow(
onSelectChanged: (bool selected) {},
cells: [
MyDataCell(Align(
alignment: Alignment.centerRight,
child: LocalText(
context,
"shipment.cargo.total",
color: Colors.black87,
fontWeight: FontWeight.bold,
),
)),
MyDataCell(
Padding(
padding: const EdgeInsets.only(right: 48.0),
child: Align(
alignment: Alignment.centerRight,
child: Text(total.toStringAsFixed(2),
style: TextStyle(fontWeight: FontWeight.bold))),
),
),
],
);
rows.add(totalRow);
return rows;
}
}

View File

@@ -76,6 +76,46 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
);
List<Widget> getCargoRowList() {
return cargos.map((c) {
return Container(
child: Container(
padding:
EdgeInsets.only(left: 10.0, right: 5.0, top: 3.0, bottom: 3.0),
child: Row(
children: <Widget>[
Checkbox(
value: c.isChecked,
activeColor: primaryColor,
onChanged: (bool check) {
setState(() {
c.isChecked = check;
});
}),
new Text(c.name, style: textStyle),
c.isCutomDuty
? Padding(
padding: const EdgeInsets.only(left: 15),
child: IconButton(
onPressed: () {
setState(() {
cargos.removeWhere((t) => t.name == c.name);
});
},
icon: Icon(
Icons.remove_circle,
color: Colors.black45,
),
),
)
: Container(),
],
),
),
);
}).toList();
}
List<Widget> _getCargoRowList() {
return cargos.map((c) {
return Container(
child: Container(
@@ -206,10 +246,10 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
_addCustom(customDuty);
}),
),
cargoTableTitleBox,
Divider(
color: Colors.grey[400],
),
// cargoTableTitleBox,
// Divider(
// color: Colors.grey[400],
// ),
Column(
children: getCargoRowList(),
),
@@ -229,7 +269,8 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
if (cargos.any((c) => c.name == customDuty.productType)) return;
setState(() {
cargos.add(CargoType(name: customDuty.productType, isCutomDuty: true));
cargos.add(
CargoType(name: customDuty.productType, isCutomDuty: true, qty: 1));
});
}
}

View File

@@ -1,13 +1,13 @@
import 'package:fcs/domain/entities/cargo_type.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/dialog_input.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/my_data_table.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'cargo_type_editor.dart';
import 'total_weight_edit.dart';
typedef OnAdd(CargoType cargoType);
typedef OnRemove(CargoType cargoType);
@@ -28,6 +28,8 @@ class _CargoTableState extends State<CargoTable> {
double totalWeight = 0;
List<CargoType> _cargos = [];
double remainingWeight = 0;
List<String> _list = [];
List<String> _types = [];
@override
Widget build(BuildContext context) {
@@ -35,25 +37,36 @@ class _CargoTableState extends State<CargoTable> {
widget.cargoTypes.length == 0 ? this.totalWeight : remainingWeight;
this._cargos = widget.cargoTypes.length == 0 ? [] : this._cargos;
return MyDataTable(
headingRowHeight: 40,
columns: [
MyDataColumn(
label: LocalText(
context,
"cargo.type",
color: Colors.grey,
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: MyDataTable(
headingRowHeight: 40,
columnSpacing: 40,
columns: [
MyDataColumn(
label: LocalText(
context,
"cargo.type",
color: Colors.grey,
),
),
),
MyDataColumn(
label: LocalText(
context,
"cargo.weight",
color: Colors.grey,
MyDataColumn(
label: LocalText(
context,
"cargo.qty",
color: Colors.grey,
),
),
),
],
rows: getCargoRows(context),
MyDataColumn(
label: LocalText(
context,
"cargo.weight",
color: Colors.grey,
),
),
],
rows: getCargoRows(context),
),
);
}
@@ -61,49 +74,51 @@ class _CargoTableState extends State<CargoTable> {
if (widget.cargoTypes == null) {
return [];
}
List<String> _list = [];
List<String> _types = [];
CargoType cargo;
print("copy remainingWeight>>>${this.remainingWeight}");
var rows = widget.cargoTypes.map((c) {
return MyDataRow(
onSelectChanged: (bool selected) async {
if (this.totalWeight <= 0) {
showMsgDialog(context, "Error", "Please insert total weight");
return;
}
// if (this.totalWeight <= 0) {
// showMsgDialog(context, "Error", "Please insert total weight");
// return;
// }
if (c.isCutomDuty) return;
CargoType cargo = await Navigator.push<CargoType>(
context,
CupertinoPageRoute(
builder: (context) => CargoTypeEditor(
cargo: c,
)));
if (widget.onAdd != null) widget.onAdd(cargo);
if (cargo == null) return;
// if (c.isCutomDuty) return;
// CargoType cargo = await Navigator.push<CargoType>(
// context,
// CupertinoPageRoute(
// builder: (context) => CargoTypeEditor(
// cargo: c,
// )));
// if (widget.onAdd != null) widget.onAdd(cargo);
// if (cargo == null) return;
this._cargos.add(cargo);
if (this.remainingWeight <= 0) return;
this.remainingWeight -= cargo.weight;
// this._cargos.add(cargo);
// if (this.remainingWeight <= 0) return;
// this.remainingWeight -= cargo.weight;
this._cargos.forEach((c) {
_list.add(c.name);
});
widget.cargoTypes.forEach((c) {
_types.add(c.name);
});
// this._cargos.forEach((c) {
// _list.add(c.name);
// });
// widget.cargoTypes.forEach((c) {
// _types.add(c.name);
// });
if (this._cargos.length == widget.cargoTypes.length - 1) {
_types.forEach((t) {
if (!_list.contains(t)) {
widget.cargoTypes.forEach((c) {
if (c.name == t) {
c.weight = this.remainingWeight;
}
});
}
});
}
// if (this._cargos.length == widget.cargoTypes.length - 1) {
// _types.forEach((t) {
// if (!_list.contains(t)) {
// widget.cargoTypes.forEach((c) {
// if (c.name == t) {
// c.weight = this.remainingWeight;
// }
// });
// }
// });
// }
},
cells: [
MyDataCell(Row(
@@ -118,12 +133,106 @@ class _CargoTableState extends State<CargoTable> {
),
],
)),
MyDataCell(
c.isCutomDuty
? InkWell(
onTap: () async {
String _t = await showDialog(
context: context,
builder: (_) => DialogInput(
label: "cargo.qty", value: c.qty.toString()));
if (_t == null) return;
setState(() {
c.qty = int.parse(_t);
});
},
child: Center(
child: Container(
width: 40,
padding: const EdgeInsets.all(7.0),
decoration: BoxDecoration(
border: Border.all(color: primaryColor),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
child: new Text(
c.qty == null ? "" : c.qty.toString(),
style: textStyle,
textAlign: TextAlign.center,
),
),
),
)
: Center(
child: new Text(
"-",
style: textStyle,
),
),
),
MyDataCell(
Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(c.weight == null ? "0.00" : c.weight.toStringAsFixed(2),
style: textStyle),
GestureDetector(
onTap: () async {
if (this.totalWeight <= 0) {
showMsgDialog(
context, "Error", "Please insert total weight");
return;
}
String _t = await showDialog(
context: context,
builder: (_) => DialogInput(
label: "cargo.weight",
value: c.weight.toStringAsFixed(2)));
if (_t == null) return;
setState(() {
c.weight = double.parse(_t);
});
cargo = c;
this._cargos.add(cargo);
if (this.remainingWeight <= 0) return;
this.remainingWeight -= cargo.weight;
this._cargos.forEach((c) {
_list.add(c.name);
});
widget.cargoTypes.forEach((c) {
_types.add(c.name);
});
if (this._cargos.length == widget.cargoTypes.length - 1) {
_types.forEach((t) {
if (!_list.contains(t)) {
widget.cargoTypes.forEach((c) {
if (c.name == t) {
c.weight = this.remainingWeight;
setState(() {
this._cargos = [];
});
}
});
}
});
this.remainingWeight = this.totalWeight;
}
},
child: Container(
padding: const EdgeInsets.all(7.0),
decoration: BoxDecoration(
border: Border.all(color: primaryColor),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
child: Text(
c.weight == null ? "0.00" : c.weight.toStringAsFixed(2),
style: textStyle),
),
),
widget.onRemove == null
? SizedBox(
width: 50,
@@ -155,20 +264,23 @@ class _CargoTableState extends State<CargoTable> {
fontWeight: FontWeight.bold,
),
)),
MyDataCell(Text("")),
MyDataCell(
Padding(
padding: const EdgeInsets.only(right: 40.0),
padding: const EdgeInsets.only(right: 48.0),
child: Align(
alignment: Alignment.centerRight,
child: InkWell(
onTap: () async {
double _t = await Navigator.of(context).push<double>(
CupertinoPageRoute(
builder: (context) =>
TotalWeightEdit(totalWeight: totalWeight)));
String _t = await showDialog(
context: context,
builder: (_) => DialogInput(
label: "shipment.cargo.total",
value: totalWeight.toStringAsFixed(2)));
if (_t == null) return;
setState(() {
totalWeight = _t;
totalWeight = double.parse(_t);
remainingWeight = totalWeight;
});
},
@@ -190,11 +302,6 @@ class _CargoTableState extends State<CargoTable> {
return rows;
}
double getRemainBalance(double total) {
double _r = this.totalWeight < total ? 0 : this.totalWeight - total;
return _r;
}
List<MyDataRow> _getCargoRows(BuildContext context) {
if (widget.cargoTypes == null) {
return [];

View File

@@ -79,7 +79,7 @@ class _CargoTableState extends State<CargoTable> {
style: textStyle,
),
new Text(
c.qty == null ? "" : " x ${c.qty.toString()}",
c.qty == null || c.qty == 0 ? "" : " x ${c.qty.toString()}",
style: TextStyle(color: Colors.grey),
),
],

View File

@@ -7,20 +7,16 @@ import 'package:fcs/domain/entities/package.dart';
import 'package:fcs/domain/entities/user.dart';
import 'package:fcs/domain/vo/delivery_address.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/carton/carton_cargo_table.dart';
import 'package:fcs/pages/carton/carton_package_table.dart';
import 'package:fcs/pages/carton_search/carton_search.dart';
import 'package:fcs/pages/carton_size/carton_size_list.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/fcs_shipment/model/fcs_shipment_model.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/package/model/package_model.dart';
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
import 'package:fcs/pages/user_search/user_serach.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_button.dart';
import 'package:fcs/pages/widgets/local_dropdown.dart';
import 'package:fcs/pages/widgets/local_radio_buttons.dart';
@@ -31,8 +27,9 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:provider/provider.dart';
import 'cargo_type_addtion.dart';
import 'cargo_type_editor.dart';
import 'carton_list_row.dart';
import 'carton_row.dart';
import 'mix_carton_editor.dart';
import 'model/carton_model.dart';
import '../carton_size/model/carton_size_model.dart';
import 'package_carton_editor.dart';
@@ -57,14 +54,14 @@ class _CartonEditorState extends State<CartonEditor> {
DeliveryAddress _deliveryAddress = new DeliveryAddress();
User _user;
String _selectedCartonType;
String _selectedMixType;
double volumetricRatio = 0;
double shipmentWeight = 0;
FcsShipment _fcsShipment;
List<FcsShipment> _fcsShipments;
Carton _mixCarton;
List<Carton> _mixCartons;
List<Carton> _cartons = [];
List<Carton> _mixCartons = [];
@override
void initState() {
@@ -98,12 +95,14 @@ class _CartonEditorState extends State<CartonEditor> {
_heightController.text = "";
_isNew = true;
_selectedCartonType = carton_from_packages;
_selectedMixType = mix_delivery;
_loadFcsShipments();
// _cartons = [
// Carton(cartonNumber: "A100B-1#1"),
// Carton(cartonNumber: "A100B-1#2"),
// Carton(cartonNumber: "A100B-1#3")
// ];
_cartons = [Carton(cartonNumber: "A100B-1#3", userName: "Seven 7")];
_mixCartons = [
Carton(cartonNumber: "A100B-1#1", userName: "Seven 7"),
Carton(cartonNumber: "A100B-1#2", userName: "Seven 7"),
];
}
}
@@ -167,18 +166,6 @@ class _CartonEditorState extends State<CartonEditor> {
});
}
_loadMixCartons() async {
if (_fcsShipment == null || _fcsShipment.id == null) return;
if (_selectedCartonType != carton_small_bag) return;
CartonModel cartonModel = Provider.of<CartonModel>(context, listen: false);
List<Carton> cartons =
await cartonModel.getMixCartonsByFcsShipment(_fcsShipment.id);
setState(() {
_mixCartons = cartons;
});
}
_calShipmentWeight() {
double l = double.parse(_lengthController.text, (s) => 0);
double w = double.parse(_widthController.text, (s) => 0);
@@ -197,17 +184,13 @@ class _CartonEditorState extends State<CartonEditor> {
Widget build(BuildContext context) {
var boxModel = Provider.of<CartonModel>(context);
bool isMixBox = _selectedCartonType == carton_mix_box;
bool isSmallBag = _selectedCartonType == carton_small_bag;
final shipmentBox = DisplayText(
text: _carton.fcsShipmentNumber,
labelTextKey: "box.fcs_shipment_num",
iconData: Ionicons.ios_airplane,
);
final mixCartonNumberBox = DisplayText(
text: _carton.mixCartonNumber,
labelTextKey: "box.mix.carton",
iconData: MaterialCommunityIcons.package,
);
var fcsShipmentsBox = Container(
padding: EdgeInsets.only(top: 10),
child: LocalDropdown<FcsShipment>(
@@ -215,7 +198,6 @@ class _CartonEditorState extends State<CartonEditor> {
setState(() {
_fcsShipment = v;
});
_loadMixCartons();
},
labelKey: "shipment.pack.fcs.shipment",
iconData: Ionicons.ios_airplane,
@@ -224,21 +206,6 @@ class _CartonEditorState extends State<CartonEditor> {
values: _fcsShipments,
));
var mixCartonsBox = Container(
padding: EdgeInsets.only(top: 10),
child: LocalDropdown<Carton>(
callback: (v) {
setState(() {
_mixCarton = v;
});
},
labelKey: "box.mix.carton",
iconData: MaterialCommunityIcons.package,
display: (u) => u.cartonNumber,
selectedValue: _mixCarton,
values: _mixCartons,
));
final fcsIDBox = Container(
padding: EdgeInsets.only(top: 10),
child: Row(
@@ -269,41 +236,6 @@ class _CartonEditorState extends State<CartonEditor> {
iconData: Icons.person,
);
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(2) : "",
labelTextKey: "box.shipment_weight",
iconData: MaterialCommunityIcons.weight,
);
final createBtn = LocalButton(
textKey: "box.complete.packaging",
callBack: _save,
@@ -324,35 +256,7 @@ class _CartonEditorState extends State<CartonEditor> {
});
});
final cargoTableTitleBox = LocalTitle(
textKey: "box.cargo.type",
trailing: IconButton(
icon: Icon(
Icons.add_circle,
color: primaryColor,
),
onPressed: () async {
// CargoType cargo = await Navigator.push<CargoType>(context,
// CupertinoPageRoute(builder: (context) => CargoTypeEditor()));
// _addCargo(cargo);
List<CargoType> cargos = await Navigator.push<List<CargoType>>(
context,
CupertinoPageRoute(builder: (context) => CargoTypeAddition()));
if (cargos == null) return;
setState(() {
_carton.cargoTypes.clear();
_carton.cargoTypes.addAll(cargos);
});
}),
);
final cargoTableBox = CargoTable(
cargoTypes: _carton.cargoTypes,
onAdd: (c) => _addCargo(c),
onRemove: (c) => _removeCargo(c),
);
final cartonTitleBox = Container(
final _cartonTitleBox = Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
@@ -374,6 +278,54 @@ class _CartonEditorState extends State<CartonEditor> {
),
);
final cartonTitleBox = Container(
child: LocalTitle(
textKey: "boxes.title",
trailing: IconButton(
icon: Icon(
Icons.add_circle,
color: primaryColor,
),
onPressed: () async {
Carton _carton = await Navigator.push(
context,
CupertinoPageRoute(builder: (context) => PackageCartonEditor()),
);
_addCarton(_carton);
}),
),
);
final mixTypeBox = Container(
padding: EdgeInsets.only(top: 10),
child: LocalRadioButtons(
readOnly: !_isNew,
values: boxModel.mixTypes,
selectedValue: _selectedMixType,
callback: (v) {
setState(() {
_selectedMixType = v;
});
}));
final mixcartonTitleBox = Container(
child: LocalTitle(
textKey: "box.mix_caton_title",
trailing: IconButton(
icon: Icon(
Icons.add_circle,
color: primaryColor,
),
onPressed: () async {
Carton _carton = await Navigator.push(
context,
CupertinoPageRoute(builder: (context) => MixCartonEditor()),
);
},
),
),
);
return LocalProgress(
inAsyncCall: _isLoading,
child: Scaffold(
@@ -399,19 +351,6 @@ class _CartonEditorState extends State<CartonEditor> {
fontSize: 20,
color: primaryColor,
),
// title: _isNew
// ? LocalText(
// context,
// "boxes.create.title",
// fontSize: 20,
// color: primaryColor,
// )
// : LocalText(
// context,
// "box.edit.title",
// fontSize: 20,
// color: primaryColor,
// ),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
@@ -425,21 +364,15 @@ class _CartonEditorState extends State<CartonEditor> {
cartonTypeBox,
LocalTitle(textKey: "box.shipment_info"),
_isNew ? fcsShipmentsBox : shipmentBox,
isSmallBag
? _isNew
? mixCartonsBox
: mixCartonNumberBox
: Container(),
isMixBox ? mixTypeBox : Container(),
...(isMixBox
? [
// CartonMixTable(
// cartons: _carton.cartons,
// onSelect: (c, check) {
// setState(() {
// c.isChecked = check;
// });
// },
// )
mixcartonTitleBox,
Column(
children: _getMixCartons(
context,
this._mixCartons,
)),
]
: [
fcsIDBox,
@@ -464,31 +397,6 @@ class _CartonEditorState extends State<CartonEditor> {
context,
this._cartons,
)),
// cargoTableTitleBox,
// cargoTableBox,
// isSmallBag
// ? Container()
// : LocalTitle(textKey: "box.dimension"),
// isSmallBag ? Container() : cartonSizeDropdown(),
// isSmallBag ? Container() : dimBox,
// isSmallBag ? Container() : shipmentWeightBox,
// LocalTitle(textKey: "box.delivery_address"),
// DefaultDeliveryAddress(
// deliveryAddress: _deliveryAddress,
// labelKey: "box.delivery_address",
// onTap: () async {
// DeliveryAddress _address = await Navigator.push(
// context,
// CupertinoPageRoute(
// builder: (context) => DeliveryAddressList(
// isAdminCreation: true,
// deliveryAddress: _deliveryAddress)));
// if (_address == null) return;
// setState(() {
// _deliveryAddress = _address;
// });
// },
// ),
]),
SizedBox(
height: 20,
@@ -512,52 +420,23 @@ class _CartonEditorState extends State<CartonEditor> {
List<Widget> _getCartons(BuildContext context, List<Carton> cartons) {
return cartons.map((c) {
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[300]),
),
return InkWell(
onTap: () {},
child: CartonRow(
key: ValueKey(c.id),
box: c,
),
child: InkWell(
onTap: () {},
child: Row(
children: <Widget>[
Expanded(
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: new Row(
children: <Widget>[
new Padding(
padding:
new EdgeInsets.symmetric(horizontal: 15.0 - 5 / 2),
child: Stack(
alignment: AlignmentDirectional.bottomEnd,
children: [
Icon(
MaterialCommunityIcons.package,
color: primaryColor,
size: 30,
),
],
),
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(
c.cartonNumber == null ? "" : c.cartonNumber,
style: new TextStyle(fontSize: 15.0),
),
],
),
),
],
),
),
),
],
),
);
}).toList();
}
List<Widget> _getMixCartons(BuildContext context, List<Carton> cartons) {
return cartons.map((c) {
return InkWell(
onTap: () {},
child: CartonRow(
key: ValueKey(c.id),
box: c,
),
);
}).toList();
@@ -642,30 +521,6 @@ class _CartonEditorState extends State<CartonEditor> {
);
}
List<Widget> getAddressList(
BuildContext context, List<DeliveryAddress> addresses) {
return addresses.asMap().entries.map((s) {
return InkWell(
onTap: () {},
child: DeliveryAddressRow(deliveryAddress: s.value),
);
}).toList();
}
_addCargo(CargoType cargo) {
if (cargo == null) return;
setState(() {
_carton.cargoTypes.remove(cargo);
_carton.cargoTypes.add(cargo);
});
}
_removeCargo(CargoType cargo) {
setState(() {
_carton.cargoTypes.remove(cargo);
});
}
_save() async {
bool isFromShipment = _selectedCartonType == carton_from_shipments;
bool isSmallBag = _selectedCartonType == carton_small_bag;
@@ -733,7 +588,10 @@ class _CartonEditorState extends State<CartonEditor> {
isDataChanged() {
if (_isNew) {
return _fcsShipment != null || _user != null || _cartons.isNotEmpty;
return _fcsShipment != null ||
_user != null ||
_cartons.isNotEmpty ||
this._mixCartons.isNotEmpty;
} else {
return true;
}

View File

@@ -20,7 +20,7 @@ import 'package:flutter_icons/flutter_icons.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'carton_cargo_table.dart';
import 'cargo_table.dart';
import 'carton_editor.dart';
import 'carton_package_table.dart';
import 'model/carton_model.dart';

View File

@@ -0,0 +1,100 @@
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:intl/intl.dart';
typedef OnRemove(Carton carton);
class CartonRow extends StatelessWidget {
final Carton box;
final OnRemove onRemove;
CartonRow({Key key, this.box, this.onRemove}) : super(key: key);
final double dotSize = 15.0;
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[300]),
),
),
child: Row(
children: <Widget>[
Expanded(
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 13.0),
child: new Row(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 5, right: 10),
child: Icon(
MaterialCommunityIcons.package,
color: primaryColor,
size: 30,
),
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text(
box.cartonNumber ?? "",
style: new TextStyle(
fontSize: 15.0, color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 10),
child: new Text(
box.userName ?? "",
style: new TextStyle(
fontSize: 15.0, color: Colors.grey),
),
)
],
),
),
],
),
),
),
Column(
children: <Widget>[
onRemove == null
? Container()
: IconButton(
icon: Icon(
Icons.remove_circle,
color: primaryColor,
),
onPressed: () {
if (onRemove != null) onRemove(box);
}),
box.actualWeight == 0
? Container()
: Padding(
padding: const EdgeInsets.only(left: 8.0, bottom: 5),
child: Row(
children: <Widget>[
new Text(
"${box.actualWeight?.toStringAsFixed(2) ?? ''} lb",
style: new TextStyle(
fontSize: 15.0, color: Colors.grey),
),
],
),
),
],
),
],
),
);
}
}

View File

@@ -0,0 +1,128 @@
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/carton_search/carton_search.dart';
import 'package:fcs/pages/widgets/local_button.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 'carton_row.dart';
class MixCartonEditor extends StatefulWidget {
final Carton box;
MixCartonEditor({this.box});
@override
_MixCartonEditorState createState() => _MixCartonEditorState();
}
class _MixCartonEditorState extends State<MixCartonEditor> {
Carton _box;
bool _isLoading = false;
bool _isNew;
List<Carton> _cartons = [];
@override
void initState() {
super.initState();
if (widget.box != null) {
_box = widget.box;
_isNew = false;
} else {
_isNew = true;
_box = Carton(cargoTypes: []);
}
}
@override
Widget build(BuildContext context) {
final createBtn = LocalButton(
textKey: "box.mix_carton_btn",
callBack: _creatCarton,
);
final cargoTableTitleBox = LocalTitle(
textKey: "boxes.title",
trailing: IconButton(
icon: Icon(
Icons.add_circle,
color: primaryColor,
),
onPressed: () => searchCarton(context, callbackCartonSelect: (c) {
_addMixCarton(c);
}),
),
);
return LocalProgress(
inAsyncCall: _isLoading,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
leading: new IconButton(
icon: new Icon(
CupertinoIcons.back,
color: primaryColor,
),
onPressed: () => Navigator.of(context).pop(),
),
shadowColor: Colors.transparent,
backgroundColor: Colors.white,
title: LocalText(
context,
"box.min_caton.form.title",
fontSize: 20,
color: primaryColor,
),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
cargoTableTitleBox,
Column(
children: _getCartons(
context,
this._cartons,
)),
SizedBox(
height: 20,
),
createBtn
],
),
),
),
);
}
List<Widget> _getCartons(BuildContext context, List<Carton> cartons) {
return cartons.map((c) {
return CartonRow(
key: ValueKey(c.id),
box: c,
onRemove: (carton) {
_removeMixCarton(carton);
},
);
}).toList();
}
_addMixCarton(Carton carton) {
if (carton == null) return;
if (this._cartons.any((c) => c.cartonNumber == carton.cartonNumber)) return;
setState(() {
this._cartons.add(carton);
});
}
_removeMixCarton(Carton carton) {
setState(() {
this._cartons.remove(carton);
});
}
_creatCarton() {}
}

View File

@@ -3,6 +3,7 @@ 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/cargo_type.dart';
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/domain/vo/message.dart';
import 'package:fcs/domain/vo/shipment_status.dart';
@@ -55,11 +56,8 @@ class CartonModel extends BaseModel {
});
}
List<String> cartonTypes = [
carton_from_packages,
carton_mix_box,
carton_small_bag
];
List<String> cartonTypes = [carton_from_packages, carton_mix_box];
List<String> mixTypes = [mix_delivery, mix_pickup];
List<String> cartonTypesInfo = [
carton_from_packages,
carton_mix_box,
@@ -220,4 +218,40 @@ class CartonModel extends BaseModel {
Future<void> deleteCarton(Carton carton) {
return Services.instance.cartonService.deleteCarton(carton);
}
Future<List<Carton>> searchCarton(String term) async {
if (term == null || term == '') return List();
List<Carton> _cartons = [];
try {
_cartons = [
Carton(
cartonNumber: "A100B-1#1",
cargoTypes: [CargoType(name: "General", weight: 12)],
userName: "Seven 7"),
Carton(
cartonNumber: "A100B-1#2",
cargoTypes: [CargoType(name: "General", weight: 12)],
userName: "Seven 7"),
Carton(
cartonNumber: "A100B-1#3",
cargoTypes: [CargoType(name: "General", weight: 12)],
userName: "Seven 7"),
Carton(
cartonNumber: "A100B-1#4",
cargoTypes: [CargoType(name: "General", weight: 12)],
userName: "Seven 7"),
Carton(
cartonNumber: "A100B-1#5",
cargoTypes: [CargoType(name: "General", weight: 12)],
userName: "Seven 7"),
];
} catch (e) {
// permission error
log.warning("user error:" + e.toString());
return null;
}
return _cartons;
}
}

View File

@@ -86,12 +86,6 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
@override
Widget build(BuildContext context) {
final shipmentWeightBox = DisplayText(
labelTextKey: "box.shipment_weight",
text: shipmentWeight == null ? "" : shipmentWeight.toStringAsFixed(0),
iconData: MaterialCommunityIcons.weight,
);
final lengthBox = LengthPicker(
controller: _lengthCtl,
lableKey: "box.length",
@@ -179,7 +173,6 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
LocalTitle(textKey: "box.dimension"),
cartonSizeDropdown(),
dimBox,
shipmentWeightBox,
LocalTitle(textKey: "box.delivery_address"),
DefaultDeliveryAddress(
deliveryAddress: _box.deliveryAddress,

View File

@@ -0,0 +1,101 @@
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'carton_search.dart';
class CartonListRow extends StatefulWidget {
final CallbackCartonSelect callbackCartonSelect;
final Carton carton;
const CartonListRow({this.carton, this.callbackCartonSelect});
@override
_CartonListRowState createState() => _CartonListRowState();
}
class _CartonListRowState extends State<CartonListRow> {
final double dotSize = 15.0;
Carton _carton;
@override
void initState() {
super.initState();
this._carton = widget.carton;
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[300]),
),
),
child: InkWell(
onTap: () {
Navigator.pop(context);
if (widget.callbackCartonSelect != null)
widget.callbackCartonSelect(widget.carton);
},
child: Row(
children: <Widget>[
Expanded(
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 13.0),
child: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.symmetric(
horizontal: 25.0 - dotSize / 2),
child: Icon(
MaterialCommunityIcons.package,
color: primaryColor,
size: 30,
),
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text(
_carton.cartonNumber ?? "",
style: new TextStyle(
fontSize: 15.0, color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 10),
child: new Text(
_carton.userName ?? "",
style: new TextStyle(
fontSize: 15.0, color: Colors.grey),
),
)
],
),
),
Padding(
padding: const EdgeInsets.only(
left: 8.0, bottom: 5, right: 10),
child: Row(
children: <Widget>[
new Text(
"${_carton.actualWeight?.toStringAsFixed(2) ?? ''} lb",
style: new TextStyle(
fontSize: 15.0, color: Colors.grey),
),
],
),
),
],
),
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,122 @@
import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/carton/model/carton_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:provider/provider.dart';
import 'carton_list_row.dart';
typedef CallbackCartonSelect(Carton carton);
Future<Carton> searchCarton(BuildContext context,
{CallbackCartonSelect callbackCartonSelect}) async =>
await showSearch<Carton>(
context: context,
delegate: PartSearchDelegate(callbackCartonSelect: callbackCartonSelect),
);
class PartSearchDelegate extends SearchDelegate<Carton> {
final CallbackCartonSelect callbackCartonSelect;
PartSearchDelegate({this.callbackCartonSelect});
@override
String get searchFieldLabel => 'Search by Carton Number/Customer Name';
@override
ThemeData appBarTheme(BuildContext context) {
final ThemeData theme = Theme.of(context);
return theme.copyWith(
inputDecorationTheme: InputDecorationTheme(
hintStyle: TextStyle(
color: theme.primaryTextTheme.caption.color, fontSize: 14)),
textTheme: theme.textTheme.copyWith(
title: theme.textTheme.title.copyWith(
color: theme.primaryTextTheme.title.color, fontSize: 16)),
primaryColor: primaryColor,
);
}
@override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () => query = '',
),
];
}
@override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () => close(context, null),
);
}
@override
Widget buildResults(BuildContext context) {
final cartonModel = Provider.of<CartonModel>(context);
return FutureBuilder(
future: cartonModel.searchCarton(query),
builder: (context, AsyncSnapshot<List<Carton>> snapshot) {
if (snapshot.hasData) {
if (snapshot.data.length == 0) {
return Container(
child: Center(
child: Text(
"No result found",
textAlign: TextAlign.center,
),
),
);
}
return Container(
padding: EdgeInsets.only(top: 15),
child: ListView(
children: snapshot.data
.map((u) => CartonListRow(
carton: u,
callbackCartonSelect: callbackCartonSelect,
))
.toList(),
),
);
} else if (snapshot.hasError) {
return Container(
child: Center(
child: Text(
'${snapshot.error}',
textAlign: TextAlign.center,
),
),
);
} else {
return Container(
child: Center(
child: CircularProgressIndicator(
valueColor:
new AlwaysStoppedAnimation<Color>(primaryColor)),
),
);
}
});
}
@override
Widget buildSuggestions(BuildContext context) {
return Container(
child: Center(
child: Opacity(
opacity: 0.2,
child: Icon(
MaterialCommunityIcons.package,
color: primaryColor,
size: 200,
),
),
),
);
}
}

View File

@@ -10,8 +10,6 @@ import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'custom_row.dart';
import 'model/shipment_rate_model.dart';
class CustomList extends StatefulWidget {
@@ -88,7 +86,11 @@ class _CustomListState extends State<CustomList> {
},
child: Container(
child: _row(
custom.productType, "\$ " + custom.fee.toStringAsFixed(2)),
custom.productType,
"\$ " + custom.fee.toStringAsFixed(2),
custom.shipmentRate == null
? ""
: "\$ " + custom.shipmentRate.toStringAsFixed(2)),
),
);
}),
@@ -96,7 +98,7 @@ class _CustomListState extends State<CustomList> {
);
}
_row(String desc, String price) {
_row(String desc, String fee, String shipmentRate) {
return Container(
padding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
child: Row(
@@ -109,10 +111,19 @@ class _CustomListState extends State<CustomList> {
Padding(
padding: const EdgeInsets.only(bottom: 3.0),
child: Text(
'$price',
'$fee',
style: TextStyle(color: primaryColor, fontSize: 14),
),
),
shipmentRate == ""
? Container()
: Padding(
padding: const EdgeInsets.only(top: 3.0),
child: Text(
"\$ " + "$shipmentRate",
style: TextStyle(color: Colors.grey, fontSize: 14),
),
)
],
),
SizedBox(

View File

@@ -0,0 +1,92 @@
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/material.dart';
import 'local_text.dart';
class DialogInput extends StatefulWidget {
final String value;
final String label;
const DialogInput({Key key, this.label, this.value}) : super(key: key);
@override
_DialogInputState createState() => _DialogInputState();
}
class _DialogInputState extends State<DialogInput> {
final _formKey = GlobalKey<FormState>();
TextEditingController _controller = new TextEditingController();
bool _isLoading = false;
@override
void initState() {
super.initState();
if (widget.value != null) {
_controller.text = widget.value;
}
}
@override
Widget build(BuildContext context) {
return LocalProgress(
inAsyncCall: _isLoading,
child: AlertDialog(
title: LocalText(
context,
widget.label,
fontSize: 20,
color: primaryColor,
),
content: Form(
key: _formKey,
child: TextField(
controller: _controller,
keyboardType: TextInputType.number,
decoration: new InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: primaryColor, width: 1.0))),
),
),
actions: <Widget>[
FlatButton(
child: LocalText(
context,
'btn.cancel',
color: labelColor,
),
onPressed: () {
_controller.clear();
Navigator.of(context).pop();
}),
FlatButton(
color: primaryColor,
child: LocalText(
context,
'btn.ok',
color: Colors.white,
fontWeight: FontWeight.bold,
),
onPressed: () async {
if (!_formKey.currentState.validate()) return;
_save();
})
],
),
);
}
_save() {
setState(() {
_isLoading = true;
});
try {
Navigator.pop<String>(context, _controller.text);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
}

View File

@@ -54,6 +54,7 @@ class StatusTree extends StatelessWidget {
e.done || isPacked
? Text(dateFormatter.format(e.date))
: Container(),
e.staffName == null ? Container() : Text(e.staffName)
],
),
),