update carton from packages

This commit is contained in:
2021-01-08 17:13:51 +06:30
parent f0662ff1d0
commit 32b8c5ae93
17 changed files with 321 additions and 371 deletions

View File

@@ -36,6 +36,7 @@ class RateDataProvider {
.collection(config_collection) .collection(config_collection)
.document(rate_doc_id) .document(rate_doc_id)
.collection(cargo_types_collection) .collection(cargo_types_collection)
.where("custom_duty", isEqualTo: false)
.snapshots(); .snapshots();
await for (var snaps in snapshots) { await for (var snaps in snapshots) {
@@ -48,18 +49,19 @@ class RateDataProvider {
} }
} }
Stream<List<CustomDuty>> _customDutiesStream() async* { Stream<List<CargoType>> _customDutiesStream() async* {
List<CustomDuty> customDuries = []; List<CargoType> customDuries = [];
Stream<QuerySnapshot> snapshots = Firestore.instance Stream<QuerySnapshot> snapshots = Firestore.instance
.collection(config_collection) .collection(config_collection)
.document(rate_doc_id) .document(rate_doc_id)
.collection(custom_duties_collection) .collection(cargo_types_collection)
.where("custom_duty", isEqualTo: true)
.snapshots(); .snapshots();
await for (var snaps in snapshots) { await for (var snaps in snapshots) {
customDuries = []; customDuries = [];
customDuries = snaps.documents.map((snap) { customDuries = snaps.documents.map((snap) {
return CustomDuty.fromMap(snap.data, snap.documentID); return CargoType.fromMap(snap.data, snap.documentID);
}).toList(); }).toList();
yield customDuries; yield customDuries;
} }
@@ -84,7 +86,7 @@ class RateDataProvider {
StreamSubscription<Rate> rateListener; StreamSubscription<Rate> rateListener;
StreamSubscription<List<CargoType>> cargoListener; StreamSubscription<List<CargoType>> cargoListener;
StreamSubscription<List<CustomDuty>> customListener; StreamSubscription<List<CargoType>> customListener;
StreamSubscription<List<DiscountByWeight>> discountListener; StreamSubscription<List<DiscountByWeight>> discountListener;
Stream<Rate> rate() { Stream<Rate> rate() {
Future<void> _start() async { Future<void> _start() async {

View File

@@ -5,23 +5,13 @@ class CargoType {
double weight; double weight;
bool isChecked; bool isChecked;
int qty; int qty;
bool isCutomDuty = false; bool isCutomDuty;
double customDutyFee;
double get calAmount => (calRate ?? 0) * (calWeight ?? 0); double get calAmount => (calRate ?? 0) * (calWeight ?? 0);
double calRate; double calRate;
double calWeight; double calWeight;
factory CargoType.fromMap(Map<String, dynamic> map, String id) {
return CargoType(
id: id,
name: map['name'],
rate: map['rate']?.toDouble() ?? 0,
weight: map['weight']?.toDouble() ?? 0,
calWeight: map['cal_weight']?.toDouble() ?? 0,
calRate: map['cal_rate']?.toDouble() ?? 0,
);
}
CargoType( CargoType(
{this.id, {this.id,
this.name, this.name,
@@ -31,7 +21,21 @@ class CargoType {
this.calRate, this.calRate,
this.isChecked = false, this.isChecked = false,
this.qty = 0, this.qty = 0,
this.isCutomDuty = false}); this.isCutomDuty,
this.customDutyFee});
factory CargoType.fromMap(Map<String, dynamic> map, String id) {
return CargoType(
id: id,
name: map['name'],
rate: map['rate']?.toDouble() ?? 0,
weight: map['weight']?.toDouble() ?? 0,
calWeight: map['cal_weight']?.toDouble() ?? 0,
calRate: map['cal_rate']?.toDouble() ?? 0,
isCutomDuty: map['custom_duty'] ?? false,
customDutyFee: (map['custom_duty_fee'] ?? 0).toDouble(),
qty: (map['qty'] ?? 0).toInt());
}
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
@@ -41,6 +45,9 @@ class CargoType {
'weight': weight, 'weight': weight,
'cal_weight': calWeight, 'cal_weight': calWeight,
'cal_rate': calRate, 'cal_rate': calRate,
'custom_duty': isCutomDuty,
'custom_duty_fee': customDutyFee,
'qty': qty
}; };
} }
@@ -62,4 +69,10 @@ class CargoType {
bool isChangedForEdit(CargoType cargoType) { bool isChangedForEdit(CargoType cargoType) {
return cargoType.name != this.name || cargoType.rate != this.rate; return cargoType.name != this.name || cargoType.rate != this.rate;
} }
bool isChangedForEditCustomDuty(CargoType cargoType) {
return cargoType.name != this.name ||
cargoType.customDutyFee != this.customDutyFee ||
cargoType.rate != this.rate;
}
} }

View File

@@ -26,6 +26,21 @@ class CartonSize {
); );
} }
@override
bool operator ==(other) {
if (identical(this, other)) {
return true;
}
return other.id == this.id;
}
@override
int get hashCode {
int result = 17;
result = 37 * result + id.hashCode;
return result;
}
bool isChangedForEdit(CartonSize cartonSize) { bool isChangedForEdit(CartonSize cartonSize) {
return cartonSize.name != this.name || return cartonSize.name != this.name ||
cartonSize.length != this.length || cartonSize.length != this.length ||

View File

@@ -1,4 +1,4 @@
import 'package:fcs/domain/entities/custom_duty.dart';
import 'package:fcs/domain/entities/discount_by_weight.dart'; import 'package:fcs/domain/entities/discount_by_weight.dart';
import 'cargo_type.dart'; import 'cargo_type.dart';
@@ -12,7 +12,7 @@ class Rate {
double diffWeightRate; double diffWeightRate;
List<CargoType> cargoTypes; List<CargoType> cargoTypes;
List<CustomDuty> customDuties; List<CargoType> customDuties;
List<DiscountByWeight> discountByWeights; List<DiscountByWeight> discountByWeights;
DiscountByWeight getDiscountByWeight(double weight) { DiscountByWeight getDiscountByWeight(double weight) {

View File

@@ -123,7 +123,7 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
color: primaryColor, color: primaryColor,
), ),
onPressed: () async { onPressed: () async {
CustomDuty customDuty = await Navigator.of(context).push( CargoType customDuty = await Navigator.of(context).push(
CupertinoPageRoute( CupertinoPageRoute(
builder: (context) => builder: (context) =>
CustomList(selected: true))); CustomList(selected: true)));
@@ -143,14 +143,20 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
); );
} }
_addCustom(CustomDuty customDuty) { _addCustom(CargoType customDuty) {
if (customDuty == null) return; if (customDuty == null) return;
if (cargos.any((c) => c.name == customDuty.productType)) return; if (cargos.any((c) => c.name == customDuty.name)) return;
// setState(() {
// cargos.add(CargoType(
// name: customDuty.productType, isCutomDuty: true, qty: 1, weight: 0));
// });
setState(() { setState(() {
cargos.add(CargoType( customDuty.qty = 1;
name: customDuty.productType, isCutomDuty: true, qty: 1, weight: 0)); customDuty.isChecked = false;
cargos.add(customDuty);
}); });
} }
} }

View File

@@ -105,7 +105,9 @@ class _CargoTableState extends State<CargoTable> {
String _t = await showDialog( String _t = await showDialog(
context: context, context: context,
builder: (_) => DialogInput( builder: (_) => DialogInput(
label: "cargo.qty", value: c.qty.toString())); label: "cargo.qty",
value: c.qty.toString(),
isQty: true));
if (_t == null) return; if (_t == null) return;
setState(() { setState(() {
@@ -238,10 +240,11 @@ class _CargoTableState extends State<CargoTable> {
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
String _t = await showDialog( String _t = await showDialog(
context: context, context: context,
builder: (_) => DialogInput( builder: (_) => DialogInput(
label: "shipment.cargo.total", label: "shipment.cargo.total",
value: totalWeight.toStringAsFixed(2))); value: totalWeight.toStringAsFixed(2)),
);
if (_t == null) return; if (_t == null) return;
setState(() { setState(() {

View File

@@ -54,19 +54,19 @@ class _CartonEditorState extends State<CartonEditor> {
TextEditingController _heightController = new TextEditingController(); TextEditingController _heightController = new TextEditingController();
TextEditingController _lengthController = new TextEditingController(); TextEditingController _lengthController = new TextEditingController();
List<DeliveryAddress> _deliveryAddresses = []; List<DeliveryAddress> _deliveryAddresses = [];
DeliveryAddress _deliveryAddress = new DeliveryAddress();
List<CargoType> _cargoTypes = [];
Carton _carton; Carton _carton;
bool _isLoading = false; bool _isLoading = false;
bool _isNew; bool _isNew;
DeliveryAddress _deliveryAddress = new DeliveryAddress();
User _user; User _user;
String _selectedCartonType; String _selectedCartonType;
String _selectedMixType; String _selectedMixBoxType;
double volumetricRatio = 0; double volumetricRatio = 0;
double shipmentWeight = 0; double shipmentWeight = 0;
FcsShipment _fcsShipment; FcsShipment _fcsShipment;
List<FcsShipment> _fcsShipments; List<FcsShipment> _fcsShipments;
Carton _mixCarton;
List<Carton> _cartons = []; List<Carton> _cartons = [];
List<Carton> _mixCartons = []; List<Carton> _mixCartons = [];
CartonSize selectedCatonSize; CartonSize selectedCatonSize;
@@ -90,11 +90,12 @@ class _CartonEditorState extends State<CartonEditor> {
_heightController.text = _carton.height.toString(); _heightController.text = _carton.height.toString();
_lengthController.text = _carton.length.toString(); _lengthController.text = _carton.length.toString();
_selectedCartonType = _carton.cartonType; _selectedCartonType = _carton.cartonType;
_cargoTypes = List.from(_carton.cargoTypes);
_isNew = false; _isNew = false;
_user = User(fcsID: _carton.fcsID, name: _carton.userName); _user = User(fcsID: _carton.fcsID, name: _carton.userName);
_loadPackages(); _loadPackages();
_getDeliverAddresses(); _getDeliverAddresses();
getCartonSize(); _getCartonSize();
} else { } else {
_carton = Carton( _carton = Carton(
cargoTypes: [], cargoTypes: [],
@@ -105,9 +106,8 @@ class _CartonEditorState extends State<CartonEditor> {
_heightController.text = "0"; _heightController.text = "0";
_isNew = true; _isNew = true;
_selectedCartonType = carton_from_packages; _selectedCartonType = carton_from_packages;
_selectedMixType = mix_delivery; _selectedMixBoxType = mix_delivery;
_loadFcsShipments(); _loadFcsShipments();
// _cartons = [Carton(cartonNumber: "A100B-1#3", userName: "Seven 7")];
// _mixCartons = [ // _mixCartons = [
// Carton(cartonNumber: "A100B-1#1", userName: "Seven 7"), // Carton(cartonNumber: "A100B-1#1", userName: "Seven 7"),
@@ -192,21 +192,18 @@ class _CartonEditorState extends State<CartonEditor> {
await addressModel.getDeliveryAddresses(_carton.userID); await addressModel.getDeliveryAddresses(_carton.userID);
} }
getCartonSize() { _getCartonSize() {
var cartonSizeModel = Provider.of<CartonSizeModel>(context, listen: false); var cartonSizeModel = Provider.of<CartonSizeModel>(context, listen: false);
cartonSizeModel.cartonSizes.forEach((c) { cartonSizeModel.cartonSizes.forEach((c) {
if (c.length == _carton.length && if (c.length == _carton.length &&
c.width == _carton.width && c.width == _carton.width &&
c.height == _carton.height) { c.height == _carton.height) {
print(c.name); selectedCatonSize = CartonSize(
// setState(() { id: c.id,
// // selectedCatonSize = CartonSize( name: c.name,
// // id: c.id, length: c.length,
// // name: c.name, width: c.width,
// // length: c.length, height: c.height);
// // width: c.width,
// // height: c.height);
// });
} }
}); });
} }
@@ -274,7 +271,9 @@ class _CartonEditorState extends State<CartonEditor> {
final createBtn = LocalButton( final createBtn = LocalButton(
textKey: "box.complete.packaging", textKey: "box.complete.packaging",
callBack: _save, callBack: () {
Navigator.pop(context);
},
); );
final saveBtn = LocalButton( final saveBtn = LocalButton(
@@ -300,62 +299,7 @@ class _CartonEditorState extends State<CartonEditor> {
Icons.add_circle, Icons.add_circle,
color: primaryColor, color: primaryColor,
), ),
onPressed: () async { onPressed: _addCarton),
bool isFromPackages = _selectedCartonType == carton_from_packages;
if (_user == null && isFromPackages) {
showMsgDialog(context, "Error", "Please select FCS ID");
return;
}
if (_fcsShipment == null && _isNew) {
showMsgDialog(context, "Error", "Please select FCS shipment");
return;
}
double l = double.parse(_lengthController.text, (s) => 0);
double w = double.parse(_widthController.text, (s) => 0);
double h = double.parse(_heightController.text, (s) => 0);
Carton carton = Carton();
carton.id = _carton.id;
carton.cartonType = _selectedCartonType;
carton.fcsShipmentID =
_isNew ? _fcsShipment.id : _carton.fcsShipmentID;
carton.userID = _user?.id;
carton.fcsID = _user?.fcsID;
carton.userName = _user?.name;
carton.packages =
_carton.packages.where((e) => e.isChecked).toList();
carton.cargoTypes = _carton.cargoTypes;
carton.length = l;
carton.width = w;
carton.height = h;
carton.deliveryAddress = _carton.deliveryAddress;
setState(() {
_isLoading = true;
});
try {
Carton _c = await Navigator.push(
context,
CupertinoPageRoute(
builder: (context) =>
PackageCartonEditor(carton: carton, isNew: _isNew)),
);
if (_c == null) return;
var cartonModel =
Provider.of<CartonModel>(context, listen: false);
Carton _carton = await cartonModel.getCarton(_c.id);
_cartons.add(_carton);
setState(() {});
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}),
), ),
); );
@@ -374,16 +318,16 @@ class _CartonEditorState extends State<CartonEditor> {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
)), )),
Row( Row(
children: boxModel.mixTypes.map((e) { children: boxModel.mixBoxTypes.map((e) {
return Row( return Row(
children: [ children: [
Radio( Radio(
value: e, value: e,
groupValue: _selectedMixType, groupValue: _selectedMixBoxType,
activeColor: primaryColor, activeColor: primaryColor,
onChanged: (v) { onChanged: (v) {
setState(() { setState(() {
_selectedMixType = v; _selectedMixBoxType = v;
}); });
}, },
), ),
@@ -404,12 +348,7 @@ class _CartonEditorState extends State<CartonEditor> {
Icons.add_circle, Icons.add_circle,
color: primaryColor, color: primaryColor,
), ),
onPressed: () { onPressed: _addMixCarton,
Navigator.push(
context,
CupertinoPageRoute(builder: (context) => MixCartonEditor()),
);
},
), ),
), ),
); );
@@ -426,15 +365,15 @@ class _CartonEditorState extends State<CartonEditor> {
CupertinoPageRoute(builder: (context) => CargoTypeAddition())); CupertinoPageRoute(builder: (context) => CargoTypeAddition()));
if (cargos == null) return; if (cargos == null) return;
setState(() { setState(() {
_carton.cargoTypes.clear(); _cargoTypes.clear();
_carton.cargoTypes.addAll(cargos); _cargoTypes.addAll(cargos);
}); });
}), }),
); );
final cargoTableBox = CargoTable( final cargoTableBox = CargoTable(
isNew: _isNew, isNew: _isNew,
cargoTypes: _carton.cargoTypes, cargoTypes: _cargoTypes,
onAdd: (c) => _addCargo(c), onAdd: (c) => _addCargo(c),
onRemove: (c) => _removeCargo(c), onRemove: (c) => _removeCargo(c),
); );
@@ -487,7 +426,7 @@ class _CartonEditorState extends State<CartonEditor> {
backgroundColor: Colors.white, backgroundColor: Colors.white,
title: LocalText( title: LocalText(
context, context,
"box.info.title", _isNew ? "box.info.title" : "box.edit.title",
fontSize: 20, fontSize: 20,
color: primaryColor, color: primaryColor,
), ),
@@ -509,10 +448,7 @@ class _CartonEditorState extends State<CartonEditor> {
? [ ? [
mixcartonTitleBox, mixcartonTitleBox,
Column( Column(
children: _getMixCartons( children: _getMixCartons(context, this._mixCartons)),
context,
this._mixCartons,
)),
] ]
: [ : [
fcsIDBox, fcsIDBox,
@@ -585,19 +521,26 @@ class _CartonEditorState extends State<CartonEditor> {
); );
} }
_addCarton(Carton carton) {
if (carton == null) return;
this._cartons.add(carton);
setState(() {});
}
List<Widget> _getCartons(BuildContext context, List<Carton> cartons) { List<Widget> _getCartons(BuildContext context, List<Carton> cartons) {
return cartons.map((c) { return cartons.asMap().entries.map((c) {
return InkWell( return InkWell(
onTap: () {}, onTap: () async {
_loadPackages();
c.value.packages = _carton.packages;
Carton _c = await Navigator.push(
context,
CupertinoPageRoute(
builder: (context) =>
PackageCartonEditor(carton: c.value, isNew: false)),
);
if (_c == null) return;
cartons.removeWhere((item) => item.id == _c.id);
cartons.insert(c.key, _c);
setState(() {});
},
child: CartonRow( child: CartonRow(
key: ValueKey(c.id), key: ValueKey(c.value.id),
box: c, box: c.value,
), ),
); );
}).toList(); }).toList();
@@ -696,81 +639,126 @@ class _CartonEditorState extends State<CartonEditor> {
_addCargo(CargoType cargo) { _addCargo(CargoType cargo) {
if (cargo == null) return; if (cargo == null) return;
setState(() { setState(() {
_carton.cargoTypes.remove(cargo); _cargoTypes.remove(cargo);
_carton.cargoTypes.add(cargo); _cargoTypes.add(cargo);
}); });
} }
_removeCargo(CargoType cargo) { _removeCargo(CargoType cargo) {
setState(() { setState(() {
_carton.cargoTypes.remove(cargo); _cargoTypes.remove(cargo);
}); });
} }
_save() async { _addCarton() async {
// bool isFromShipment = _selectedCartonType == carton_from_shipments; bool isFromPackages = _selectedCartonType == carton_from_packages;
// bool isSmallBag = _selectedCartonType == carton_small_bag; if (_user == null && isFromPackages) {
// if (_user == null && (isFromShipment || isSmallBag)) { showMsgDialog(context, "Error", "Please select FCS ID");
// showMsgDialog(context, "Error", "Please select customer"); return;
// return; }
// } if (_fcsShipment == null && _isNew) {
// if (_fcsShipment == null && _isNew) { showMsgDialog(context, "Error", "Please select FCS shipment");
// showMsgDialog(context, "Error", "Please select FCS shipment"); return;
// return; }
// }
// if ((_carton.cargoTypes?.length ?? 0) == 0 &&
// (isFromShipment || isSmallBag)) {
// showMsgDialog(context, "Error", "Expect at least one cargo type");
// return;
// }
// double l = double.parse(_lengthController.text, (s) => 0);
// double w = double.parse(_widthController.text, (s) => 0);
// double h = double.parse(_heightController.text, (s) => 0);
// if ((l <= 0 || w <= 0 || h <= 0) && isFromShipment) {
// showMsgDialog(context, "Error", "Invalid dimension");
// return;
// }
// if (_deliveryAddress == null && (isFromShipment || isSmallBag)) {
// showMsgDialog(context, "Error", "Invalid delivery address");
// return;
// }
// if (isSmallBag && _mixCarton == null && _isNew) {
// showMsgDialog(context, "Error", "Invalid mix carton");
// return;
// }
// Carton carton = Carton(); double l = double.parse(_lengthController.text, (s) => 0);
// carton.id = _carton.id; double w = double.parse(_widthController.text, (s) => 0);
// carton.cartonType = _selectedCartonType; double h = double.parse(_heightController.text, (s) => 0);
// carton.fcsShipmentID = _isNew ? _fcsShipment.id : _carton.fcsShipmentID;
// carton.userID = _user?.id; Carton carton = Carton();
// carton.cargoTypes = _carton.cargoTypes; carton.id = _carton.id;
// carton.packages = _carton.packages.where((e) => e.isChecked).toList(); carton.cartonType = _selectedCartonType;
// carton.mixCartonID = _mixCarton?.id; carton.fcsShipmentID = _isNew ? _fcsShipment.id : _carton.fcsShipmentID;
// carton.length = l; carton.userID = _user?.id;
// carton.width = w; carton.fcsID = _user?.fcsID;
// carton.height = h; carton.userName = _user?.name;
// carton.deliveryAddress = _deliveryAddress; carton.packages = _carton.packages.where((e) => e.isChecked).toList();
// setState(() {
// _isLoading = true; carton.cargoTypes = _carton.cargoTypes;
// }); carton.length = l;
// try { carton.width = w;
// CartonModel cartonModel = carton.height = h;
// Provider.of<CartonModel>(context, listen: false);
// if (_isNew) { carton.deliveryAddress = _carton.deliveryAddress;
// await cartonModel.createCarton(carton);
// } else { try {
// await cartonModel.updateCarton(carton); Carton _c = await Navigator.push(
// } context,
// Navigator.pop(context, true); CupertinoPageRoute(
// } catch (e) { builder: (context) =>
// showMsgDialog(context, "Error", e.toString()); PackageCartonEditor(carton: carton, isNew: _isNew)),
// } finally { );
// setState(() { if (_c == null) return;
// _isLoading = false; var cartonModel = Provider.of<CartonModel>(context, listen: false);
// }); Carton _carton = await cartonModel.getCarton(_c.id);
// } _cartons.add(_carton);
Navigator.pop(context, true); setState(() {});
} catch (e) {
showMsgDialog(context, "Error", e.toString());
}
}
_addMixCarton() async {
if (_fcsShipment == null && _isNew) {
showMsgDialog(context, "Error", "Please select FCS shipment");
return;
}
Carton carton = Carton();
carton.id = _carton.id;
carton.cartonType = _selectedCartonType;
carton.fcsShipmentID = _isNew ? _fcsShipment.id : _carton.fcsShipmentID;
carton.mixBoxType = _selectedMixBoxType;
await Navigator.push(
context,
CupertinoPageRoute(builder: (context) => MixCartonEditor(box: carton)),
);
}
_save() async {
bool isFromPackages = _selectedCartonType == carton_from_packages;
if ((_cargoTypes?.length ?? 0) == 0 && (isFromPackages)) {
showMsgDialog(context, "Error", "Expect at least one cargo type");
return;
}
double l = double.parse(_lengthController.text, (s) => 0);
double w = double.parse(_widthController.text, (s) => 0);
double h = double.parse(_heightController.text, (s) => 0);
if ((l <= 0 || w <= 0 || h <= 0) && isFromPackages) {
showMsgDialog(context, "Error", "Invalid dimension");
return;
}
if (_deliveryAddress == null && (isFromPackages)) {
showMsgDialog(context, "Error", "Invalid delivery address");
return;
}
Carton carton = Carton();
carton.id = _carton.id;
carton.cartonType = _selectedCartonType;
carton.fcsShipmentID = _isNew ? _fcsShipment.id : _carton.fcsShipmentID;
carton.userID = _user?.id;
carton.packages = _carton.packages.where((e) => e.isChecked).toList();
carton.cargoTypes = _cargoTypes;
carton.length = l;
carton.width = w;
carton.height = h;
carton.deliveryAddress = _deliveryAddress;
setState(() {
_isLoading = true;
});
try {
CartonModel cartonModel =
Provider.of<CartonModel>(context, listen: false);
await cartonModel.updateCarton(carton);
Navigator.pop(context, true);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
} }
isDataChanged() { isDataChanged() {

View File

@@ -109,7 +109,6 @@ class _CartonInfoState extends State<CartonInfo> {
if (c.length == _box.length && if (c.length == _box.length &&
c.width == _box.width && c.width == _box.width &&
c.height == _box.height) { c.height == _box.height) {
print(c.name);
setState(() { setState(() {
_cartonSizeController.text = c.name; _cartonSizeController.text = c.name;
}); });

View File

@@ -1,12 +1,15 @@
import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/domain/entities/carton.dart';
import 'package:fcs/helpers/theme.dart'; import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/carton/model/carton_model.dart';
import 'package:fcs/pages/carton_search/carton_search.dart'; import 'package:fcs/pages/carton_search/carton_search.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/local_button.dart'; import 'package:fcs/pages/widgets/local_button.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/progress.dart'; import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'carton_row.dart'; import 'carton_row.dart';
class MixCartonEditor extends StatefulWidget { class MixCartonEditor extends StatefulWidget {
@@ -26,14 +29,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_box = widget.box;
if (widget.box != null) {
_box = widget.box;
_isNew = false;
} else {
_isNew = true;
_box = Carton(cargoTypes: []);
}
} }
@override @override
@@ -124,5 +120,26 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
}); });
} }
_creatCarton() {} _creatCarton() {
if ((this._cartons?.length ?? 0) == 0) {
showMsgDialog(context, "Error", "Expect at least one carton");
return;
}
Carton carton = Carton();
carton.id = _box.id;
carton.cartonType = _box.cartonType;
setState(() {
_isLoading = true;
});
try {
CartonModel cartonModel =
Provider.of<CartonModel>(context, listen: false);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
} }

View File

@@ -57,7 +57,7 @@ class CartonModel extends BaseModel {
} }
List<String> cartonTypes = [carton_from_packages, carton_mix_box]; List<String> cartonTypes = [carton_from_packages, carton_mix_box];
List<String> mixTypes = [mix_delivery, mix_pickup]; List<String> mixBoxTypes = [mix_delivery, mix_pickup];
List<String> cartonTypesInfo = [ List<String> cartonTypesInfo = [
carton_from_packages, carton_from_packages,
carton_mix_box, carton_mix_box,
@@ -212,7 +212,6 @@ class CartonModel extends BaseModel {
} }
Future<void> updateCarton(Carton carton) { Future<void> updateCarton(Carton carton) {
print(carton.id);
return Services.instance.cartonService.updateCarton(carton); return Services.instance.cartonService.updateCarton(carton);
} }

View File

@@ -45,6 +45,7 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
DeliveryAddress _deliveryAddress = new DeliveryAddress(); DeliveryAddress _deliveryAddress = new DeliveryAddress();
List<DeliveryAddress> _deliveryAddresses = []; List<DeliveryAddress> _deliveryAddresses = [];
List<CargoType> _cargoTypes = []; List<CargoType> _cargoTypes = [];
CartonSize selectedCatonSize;
@override @override
void initState() { void initState() {
@@ -65,6 +66,7 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
_widthCtl.text = _carton.width.toString(); _widthCtl.text = _carton.width.toString();
_heightCtl.text = _carton.height.toString(); _heightCtl.text = _carton.height.toString();
_deliveryAddress = _carton.deliveryAddress; _deliveryAddress = _carton.deliveryAddress;
_getCartonSize();
} }
} }
@@ -75,6 +77,22 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
await addressModel.getDeliveryAddresses(_carton.userID); await addressModel.getDeliveryAddresses(_carton.userID);
} }
_getCartonSize() {
var cartonSizeModel = Provider.of<CartonSizeModel>(context, listen: false);
cartonSizeModel.cartonSizes.forEach((c) {
if (c.length == _carton.length &&
c.width == _carton.width &&
c.height == _carton.height) {
selectedCatonSize = CartonSize(
id: c.id,
name: c.name,
length: c.length,
width: c.width,
height: c.height);
}
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final lengthBox = LengthPicker( final lengthBox = LengthPicker(
@@ -105,7 +123,7 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
], ],
); );
final createBtn = LocalButton( final createBtn = LocalButton(
textKey: "box.new_carton_btn", textKey: widget.isNew ? "box.new_carton_btn" : "box.cargo.save.btn",
callBack: _creatCarton, callBack: _creatCarton,
); );
@@ -193,7 +211,6 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
); );
} }
CartonSize selectedCatonSize;
Widget cartonSizeDropdown() { Widget cartonSizeDropdown() {
List<CartonSize> _cartonSizes = List<CartonSize> _cartonSizes =
Provider.of<CartonSizeModel>(context).getCartonSizes; Provider.of<CartonSizeModel>(context).getCartonSizes;
@@ -307,7 +324,6 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
carton.userID = _carton.userID; carton.userID = _carton.userID;
carton.cargoTypes = _cargoTypes; carton.cargoTypes = _cargoTypes;
carton.packages = _carton.packages.where((e) => e.isChecked).toList(); carton.packages = _carton.packages.where((e) => e.isChecked).toList();
// carton.cartonSizeID = selectedCatonSize?.id;
carton.length = l; carton.length = l;
carton.width = w; carton.width = w;
carton.height = h; carton.height = h;
@@ -323,7 +339,8 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
Navigator.pop(context, _c); Navigator.pop(context, _c);
} else { } else {
await cartonModel.updateCarton(carton); await cartonModel.updateCarton(carton);
Navigator.pop(context, carton); Carton _c = await cartonModel.getCarton(_carton.id);
Navigator.pop(context, _c);
} }
} catch (e) { } catch (e) {
showMsgDialog(context, "Error", e.toString()); showMsgDialog(context, "Error", e.toString());

View File

@@ -1,4 +1,4 @@
import 'package:fcs/domain/entities/custom_duty.dart'; import 'package:fcs/domain/entities/cargo_type.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/main/util.dart'; import 'package:fcs/pages/main/util.dart';
@@ -12,7 +12,7 @@ import 'package:provider/provider.dart';
import 'model/shipment_rate_model.dart'; import 'model/shipment_rate_model.dart';
class CustomEditor extends StatefulWidget { class CustomEditor extends StatefulWidget {
final CustomDuty custom; final CargoType custom;
CustomEditor({this.custom}); CustomEditor({this.custom});
@override @override
@@ -25,7 +25,7 @@ class _CustomEditorState extends State<CustomEditor> {
TextEditingController _shipmentRateController = new TextEditingController(); TextEditingController _shipmentRateController = new TextEditingController();
bool _isLoading = false; bool _isLoading = false;
CustomDuty _custom = new CustomDuty(); CargoType _custom = new CargoType();
bool _isNew = false; bool _isNew = false;
@override @override
@@ -33,11 +33,10 @@ class _CustomEditorState extends State<CustomEditor> {
super.initState(); super.initState();
if (widget.custom != null) { if (widget.custom != null) {
_custom = widget.custom; _custom = widget.custom;
_productController.text = _custom.productType; _productController.text = _custom.name;
_feeController.text = _custom.fee.toStringAsFixed(2); _feeController.text = _custom.customDutyFee.toStringAsFixed(2);
_shipmentRateController.text = _custom.shipmentRate == null _shipmentRateController.text =
? "" _custom.rate == null ? "" : _custom.rate.toStringAsFixed(2);
: _custom.shipmentRate.toStringAsFixed(2);
} else { } else {
_isNew = true; _isNew = true;
} }
@@ -123,11 +122,10 @@ class _CustomEditorState extends State<CustomEditor> {
try { try {
var shipmentRateModel = var shipmentRateModel =
Provider.of<ShipmentRateModel>(context, listen: false); Provider.of<ShipmentRateModel>(context, listen: false);
CustomDuty _customduty = CustomDuty( CargoType _customduty = CargoType(
productType: _productController.text, name: _productController.text,
fee: double.parse(_feeController.text), customDutyFee: double.parse(_feeController.text),
shipmentRate: double.parse(_shipmentRateController.text)); rate: double.parse(_shipmentRateController.text));
print('_customduty => $_customduty');
if (_isNew) { if (_isNew) {
await shipmentRateModel.addCustomDuty(_customduty); await shipmentRateModel.addCustomDuty(_customduty);
} else { } else {
@@ -173,12 +171,11 @@ class _CustomEditorState extends State<CustomEditor> {
_feeController.text != "" || _feeController.text != "" ||
_shipmentRateController.text != ""; _shipmentRateController.text != "";
} else { } else {
CustomDuty _customduty = CustomDuty( CargoType _customduty = CargoType(
productType: _productController.text, name: _productController.text,
fee: double.parse(_feeController.text), customDutyFee: double.parse(_feeController.text),
// shipmentRate: double.parse(_shipmentRateController.text) rate: double.parse(_shipmentRateController.text));
); return widget.custom.isChangedForEditCustomDuty(_customduty);
return widget.custom.isChangedForEdit(_customduty);
} }
} }
} }

View File

@@ -1,3 +1,4 @@
import 'package:fcs/domain/entities/cargo_type.dart';
import 'package:fcs/domain/entities/custom_duty.dart'; import 'package:fcs/domain/entities/custom_duty.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';
@@ -74,8 +75,7 @@ class _CustomListState extends State<CustomList> {
), ),
itemCount: shipmentRateModel.rate.customDuties.length, itemCount: shipmentRateModel.rate.customDuties.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
CustomDuty custom = CargoType custom = shipmentRateModel.rate.customDuties[index];
shipmentRateModel.rate.customDuties[index];
return InkWell( return InkWell(
onTap: () { onTap: () {
_selected _selected
@@ -86,11 +86,11 @@ class _CustomListState extends State<CustomList> {
}, },
child: Container( child: Container(
child: _row( child: _row(
custom.productType, custom.name,
"\$ " + custom.fee.toStringAsFixed(2), "Custom Fee \$ " + custom.customDutyFee.toStringAsFixed(2),
custom.shipmentRate == null custom.rate == null
? "" ? ""
: "\$ " + custom.shipmentRate.toStringAsFixed(2)), : "Shipment rate \$ " + custom.rate.toStringAsFixed(2)),
), ),
); );
}), }),
@@ -120,7 +120,7 @@ class _CustomListState extends State<CustomList> {
: Padding( : Padding(
padding: const EdgeInsets.only(top: 3.0), padding: const EdgeInsets.only(top: 3.0),
child: Text( child: Text(
"\$ " + "$shipmentRate", "$shipmentRate",
style: TextStyle(color: Colors.grey, fontSize: 14), style: TextStyle(color: Colors.grey, fontSize: 14),
), ),
) )

View File

@@ -50,16 +50,18 @@ class ShipmentRateModel extends BaseModel {
//CustomDuty //CustomDuty
Future<void> addCustomDuty(CustomDuty customDuty) { Future<void> addCustomDuty(CargoType customDuty) {
return Services.instance.rateService.createCustomDuty(customDuty); customDuty.isCutomDuty=true;
return Services.instance.rateService.createCargoType(customDuty);
} }
Future<void> updateCustomDuty(CustomDuty customDuty) { Future<void> updateCustomDuty(CargoType customDuty) {
return Services.instance.rateService.updateCustomDuty(customDuty); customDuty.isCutomDuty=true;
return Services.instance.rateService.updateCargoType(customDuty);
} }
Future<void> deleteCustomDuty(String id) { Future<void> deleteCustomDuty(String id) {
return Services.instance.rateService.deleteCustomDuty(id); return Services.instance.rateService.deleteCargoType(id);
} }
//Discount by weight //Discount by weight

View File

@@ -145,14 +145,10 @@ class _ShipmentRatesState extends State<ShipmentRates> {
"Volumetric Ratio", "Volumetric Ratio",
"${rate.volumetricRatio.toStringAsFixed(2)}", "${rate.volumetricRatio.toStringAsFixed(2)}",
"in3 per pound"), "in3 per pound"),
_row( _row("Weight difference discount",
"Weight difference discount", "${rate.diffDiscountWeight.toStringAsFixed(2)}", "pounds"),
"${rate.diffDiscountWeight.toStringAsFixed(2)}", _row("Weight difference rate",
"pounds"), "\$ ${rate.diffWeightRate.toStringAsFixed(2)}", ""),
_row(
"Weight difference rate",
"\$ ${rate.diffWeightRate.toStringAsFixed(2)}",
""),
Divider( Divider(
color: Colors.grey, color: Colors.grey,
), ),
@@ -195,10 +191,10 @@ class _ShipmentRatesState extends State<ShipmentRates> {
}).toList(); }).toList();
} }
List<Widget> getCustonWidget(List<CustomDuty> customs) { List<Widget> getCustonWidget(List<CargoType> customs) {
return customs.map((c) { return customs.map((c) {
return Container( return Container(
child: _row(c.productType, "\$ " + c.fee.toStringAsFixed(2), ''), child: _row(c.name, "\$ " + c.customDutyFee.toStringAsFixed(2), ''),
); );
}).toList(); }).toList();
} }

View File

@@ -44,7 +44,8 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
_minWeight.text = rate.freeDeliveryWeight?.toStringAsFixed(2) ?? ""; _minWeight.text = rate.freeDeliveryWeight?.toStringAsFixed(2) ?? "";
_deliveryFee.text = rate.deliveryFee?.toStringAsFixed(2) ?? ""; _deliveryFee.text = rate.deliveryFee?.toStringAsFixed(2) ?? "";
_volumetricRatio.text = rate.volumetricRatio?.toStringAsFixed(2) ?? ""; _volumetricRatio.text = rate.volumetricRatio?.toStringAsFixed(2) ?? "";
_diffDiscountWeight.text = rate.diffDiscountWeight?.toStringAsFixed(2) ?? ""; _diffDiscountWeight.text =
rate.diffDiscountWeight?.toStringAsFixed(2) ?? "";
_diffWeightRate.text = rate.diffWeightRate?.toStringAsFixed(2) ?? ""; _diffWeightRate.text = rate.diffWeightRate?.toStringAsFixed(2) ?? "";
} }
@@ -162,120 +163,4 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
); );
return rate.isChangedForEdit(_rate); return rate.isChangedForEdit(_rate);
} }
List<MyDataRow> getCargoRows(List<CargoType> cargos) {
return cargos.map((r) {
return MyDataRow(
onSelectChanged: (selected) {
Navigator.push(
context,
CupertinoPageRoute(builder: (context) => CargoEditor(cargo: r)),
);
},
cells: [
MyDataCell(
new Text(
r.name,
style: textStyle,
),
),
MyDataCell(
new Text(
r.rate.toString(),
style: textStyle,
),
),
MyDataCell(IconButton(icon: Icon(Icons.delete), onPressed: null)),
],
);
}).toList();
}
List<MyDataRow> getCustomsRows(List<CustomDuty> customs) {
return customs.map((c) {
return MyDataRow(
onSelectChanged: (selected) {
Navigator.push(
context,
CupertinoPageRoute(builder: (context) => CustomEditor(custom: c)),
);
},
cells: [
MyDataCell(
new Text(
c.productType,
style: textStyle,
),
),
MyDataCell(
new Text(
c.fee.toString(),
style: textStyle,
),
),
MyDataCell(IconButton(icon: Icon(Icons.delete), onPressed: null)),
],
);
}).toList();
}
List<MyDataRow> getDiscounts(List<DiscountByWeight> discounts) {
return discounts.map((d) {
return MyDataRow(
onSelectChanged: (selected) {
// Navigator.push(
// context,
// CupertinoPageRoute(builder: (context) => CargoEditor(rate: r)),
// );
},
cells: [
MyDataCell(
new Text(
"${d.weight} lb",
style: textStyle,
),
),
MyDataCell(
Center(
child: new Text(
d.discount.toString(),
style: textStyle,
),
),
),
MyDataCell(IconButton(icon: Icon(Icons.delete), onPressed: null)),
],
);
}).toList();
}
_row(String desc, String price, String unit) {
return Container(
padding: EdgeInsets.only(left: 25, top: 5, bottom: 5),
child: Row(
children: <Widget>[
Text('$desc ', style: TextStyle(fontSize: 15)),
Spacer(),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 3.0),
child: Text(
'$price',
style: TextStyle(color: primaryColor, fontSize: 14),
),
),
Text(
'$unit',
style: TextStyle(color: Colors.grey, fontSize: 14),
),
],
),
SizedBox(
width: 50,
),
],
));
}
} }

View File

@@ -7,7 +7,9 @@ import 'local_text.dart';
class DialogInput extends StatefulWidget { class DialogInput extends StatefulWidget {
final String value; final String value;
final String label; final String label;
const DialogInput({Key key, this.label, this.value}) : super(key: key); final bool isQty;
const DialogInput({Key key, this.label, this.value, this.isQty = false})
: super(key: key);
@override @override
_DialogInputState createState() => _DialogInputState(); _DialogInputState createState() => _DialogInputState();
} }
@@ -15,6 +17,7 @@ class DialogInput extends StatefulWidget {
class _DialogInputState extends State<DialogInput> { class _DialogInputState extends State<DialogInput> {
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
TextEditingController _controller = new TextEditingController(); TextEditingController _controller = new TextEditingController();
final _focusNode = FocusNode();
bool _isLoading = false; bool _isLoading = false;
@@ -23,6 +26,12 @@ class _DialogInputState extends State<DialogInput> {
super.initState(); super.initState();
if (widget.value != null) { if (widget.value != null) {
_controller.text = widget.value; _controller.text = widget.value;
_focusNode.addListener(() {
if (_focusNode.hasFocus) {
_controller.selection = TextSelection(
baseOffset: 0, extentOffset: _controller.text.length);
}
});
} }
} }
@@ -41,6 +50,8 @@ class _DialogInputState extends State<DialogInput> {
key: _formKey, key: _formKey,
child: TextField( child: TextField(
controller: _controller, controller: _controller,
focusNode: widget.isQty ? _focusNode : FocusNode(),
autofocus: true,
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
decoration: new InputDecoration( decoration: new InputDecoration(
focusedBorder: UnderlineInputBorder( focusedBorder: UnderlineInputBorder(