fix rates
This commit is contained in:
@@ -405,6 +405,8 @@
|
|||||||
"rate.delivery_fee":"Delivery fees",
|
"rate.delivery_fee":"Delivery fees",
|
||||||
"rate.total_estimated_amount":"Total estimated amount",
|
"rate.total_estimated_amount":"Total estimated amount",
|
||||||
"rate.volumetric_ratio":"Volumetric ratio",
|
"rate.volumetric_ratio":"Volumetric ratio",
|
||||||
|
"rate.diff_discount_weight":"Weight difference discount (lb)",
|
||||||
|
"rate.diff_weight_rate":"Weight difference rate",
|
||||||
"rate.custom.form.title":"Custom",
|
"rate.custom.form.title":"Custom",
|
||||||
"rate.cutom.product_type":"Product type",
|
"rate.cutom.product_type":"Product type",
|
||||||
"rate.custom.fee":"Fee",
|
"rate.custom.fee":"Fee",
|
||||||
|
|||||||
@@ -405,6 +405,8 @@
|
|||||||
"rate.delivery_fee":"ပို့ဆောင်ခ",
|
"rate.delivery_fee":"ပို့ဆောင်ခ",
|
||||||
"rate.total_estimated_amount":"စုစုပေါင်းခန့်မှန်းပမာဏ",
|
"rate.total_estimated_amount":"စုစုပေါင်းခန့်မှန်းပမာဏ",
|
||||||
"rate.volumetric_ratio":"Volumetric Ratio",
|
"rate.volumetric_ratio":"Volumetric Ratio",
|
||||||
|
"rate.diff_discount_weight":"Weight difference discount (lb)",
|
||||||
|
"rate.diff_weight_rate":"Weight difference rate",
|
||||||
"rate.custom.form.title":"အကောက်ခွန်",
|
"rate.custom.form.title":"အကောက်ခွန်",
|
||||||
"rate.cutom.product_type":"ကုန်ပစ္စည်းအမျိုးအစား",
|
"rate.cutom.product_type":"ကုန်ပစ္စည်းအမျိုးအစား",
|
||||||
"rate.custom.fee":"အခကြေးငွေ",
|
"rate.custom.fee":"အခကြေးငွေ",
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ class RateDataProvider {
|
|||||||
_rate.deliveryFee = rate.deliveryFee;
|
_rate.deliveryFee = rate.deliveryFee;
|
||||||
_rate.freeDeliveryWeight = rate.freeDeliveryWeight;
|
_rate.freeDeliveryWeight = rate.freeDeliveryWeight;
|
||||||
_rate.volumetricRatio = rate.volumetricRatio;
|
_rate.volumetricRatio = rate.volumetricRatio;
|
||||||
|
_rate.diffDiscountWeight = rate.diffDiscountWeight;
|
||||||
|
_rate.diffWeightRate = rate.diffWeightRate;
|
||||||
controller.add(_rate);
|
controller.add(_rate);
|
||||||
});
|
});
|
||||||
cargoListener = _cargoTypeStream().listen((cargoTypes) {
|
cargoListener = _cargoTypeStream().listen((cargoTypes) {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class Carton {
|
|||||||
double get actualWeight =>
|
double get actualWeight =>
|
||||||
cargoTypes == null ? 0 : cargoTypes.fold(0, (p, e) => e.weight + p);
|
cargoTypes == null ? 0 : cargoTypes.fold(0, (p, e) => e.weight + p);
|
||||||
|
|
||||||
double getShipmentWeight(double volumetricRatio) {
|
int getShipmentWeight(double volumetricRatio) {
|
||||||
if (length == null ||
|
if (length == null ||
|
||||||
length <= 0 ||
|
length <= 0 ||
|
||||||
width == null ||
|
width == null ||
|
||||||
@@ -72,7 +72,7 @@ class Carton {
|
|||||||
volumetricRatio == null ||
|
volumetricRatio == null ||
|
||||||
volumetricRatio <= 0) return 0;
|
volumetricRatio <= 0) return 0;
|
||||||
|
|
||||||
return (length * width * height) / volumetricRatio;
|
return ((length * width * height) / volumetricRatio).round();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getCargoTypeForCalWeight returns carton with shipment weight
|
/// getCargoTypeForCalWeight returns carton with shipment weight
|
||||||
@@ -95,25 +95,26 @@ class Carton {
|
|||||||
/// calAmount returns total amount
|
/// calAmount returns total amount
|
||||||
double calAmount(Rate rate) {
|
double calAmount(Rate rate) {
|
||||||
// get shipment weight
|
// get shipment weight
|
||||||
double volume = (length ?? 0) * (width ?? 0) * (height ?? 0);
|
int sw = getShipmentWeight(rate.volumetricRatio);
|
||||||
double sw = volume / rate.volumetricRatio ?? 0;
|
|
||||||
|
|
||||||
// get actual weight
|
// get actual weight
|
||||||
double aw = cargoTypes.fold(0.0, (p, c) => p + c.weight);
|
double aw = cargoTypes.fold(0.0, (p, c) => p + c.weight);
|
||||||
if (aw == 0 || sw == 0) return 0;
|
if (aw == 0 || sw == 0) return 0;
|
||||||
|
|
||||||
DiscountByWeight discountByWeight =
|
double wd = sw - aw;
|
||||||
rate.getDiscountByWeight(sw > aw ? sw : aw);
|
wd = wd - rate.diffDiscountWeight;
|
||||||
|
double wdAmount = wd > 0 ? wd * rate.diffWeightRate : 0;
|
||||||
|
|
||||||
|
DiscountByWeight discountByWeight = rate.getDiscountByWeight(aw);
|
||||||
|
|
||||||
double total = 0;
|
double total = 0;
|
||||||
cargoTypes.forEach((e) {
|
cargoTypes.forEach((e) {
|
||||||
double cargoWeight = aw > sw ? e.weight : e.weight / aw * sw;
|
|
||||||
double r =
|
double r =
|
||||||
e.rate - (discountByWeight != null ? discountByWeight.discount : 0);
|
e.rate - (discountByWeight != null ? discountByWeight.discount : 0);
|
||||||
double amount = cargoWeight * r;
|
double amount = e.weight * r;
|
||||||
total += amount;
|
total += amount;
|
||||||
});
|
});
|
||||||
return total;
|
return total + wdAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ShipmentStatus> shipmentHistory;
|
List<ShipmentStatus> shipmentHistory;
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ class Rate {
|
|||||||
double freeDeliveryWeight;
|
double freeDeliveryWeight;
|
||||||
double volumetricRatio;
|
double volumetricRatio;
|
||||||
|
|
||||||
|
double diffDiscountWeight;
|
||||||
|
double diffWeightRate;
|
||||||
|
|
||||||
List<CargoType> cargoTypes;
|
List<CargoType> cargoTypes;
|
||||||
List<CustomDuty> customDuties;
|
List<CustomDuty> customDuties;
|
||||||
List<DiscountByWeight> discountByWeights;
|
List<DiscountByWeight> discountByWeights;
|
||||||
@@ -22,17 +25,20 @@ class Rate {
|
|||||||
? null
|
? null
|
||||||
: cargoTypes.firstWhere((e) => e.name == "General");
|
: cargoTypes.firstWhere((e) => e.name == "General");
|
||||||
|
|
||||||
Rate({
|
Rate(
|
||||||
this.deliveryFee,
|
{this.deliveryFee,
|
||||||
this.freeDeliveryWeight,
|
this.freeDeliveryWeight,
|
||||||
this.volumetricRatio,
|
this.volumetricRatio,
|
||||||
});
|
this.diffDiscountWeight,
|
||||||
|
this.diffWeightRate});
|
||||||
|
|
||||||
factory Rate.fromMap(Map<String, dynamic> map) {
|
factory Rate.fromMap(Map<String, dynamic> map) {
|
||||||
return Rate(
|
return Rate(
|
||||||
deliveryFee: (map['delivery_fee'] ?? 0).toDouble(),
|
deliveryFee: (map['delivery_fee'] ?? 0).toDouble(),
|
||||||
freeDeliveryWeight: (map['free_delivery_weight'] ?? 0).toDouble(),
|
freeDeliveryWeight: (map['free_delivery_weight'] ?? 0).toDouble(),
|
||||||
volumetricRatio: (map['volumetric_ratio'] ?? 0).toDouble(),
|
volumetricRatio: (map['volumetric_ratio'] ?? 0).toDouble(),
|
||||||
|
diffDiscountWeight: (map['diff_discount_weight'] ?? 0).toDouble(),
|
||||||
|
diffWeightRate: (map['diff_weight_rate'] ?? 0).toDouble(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,17 +47,21 @@ class Rate {
|
|||||||
"delivery_fee": deliveryFee,
|
"delivery_fee": deliveryFee,
|
||||||
'free_delivery_weight': freeDeliveryWeight,
|
'free_delivery_weight': freeDeliveryWeight,
|
||||||
'volumetric_ratio': volumetricRatio,
|
'volumetric_ratio': volumetricRatio,
|
||||||
|
'diff_discount_weight': diffDiscountWeight,
|
||||||
|
'diff_weight_rate': diffWeightRate,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isChangedForEdit(Rate rate) {
|
bool isChangedForEdit(Rate rate) {
|
||||||
return rate.freeDeliveryWeight != this.freeDeliveryWeight ||
|
return rate.freeDeliveryWeight != this.freeDeliveryWeight ||
|
||||||
rate.deliveryFee != this.deliveryFee ||
|
rate.deliveryFee != this.deliveryFee ||
|
||||||
rate.volumetricRatio != this.volumetricRatio;
|
rate.volumetricRatio != this.volumetricRatio ||
|
||||||
|
rate.diffDiscountWeight != this.diffDiscountWeight ||
|
||||||
|
rate.diffWeightRate != this.diffWeightRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Rate{deliveryFee:$deliveryFee,freeDeliveryWeight:$freeDeliveryWeight,volumetricRatio:$volumetricRatio}';
|
return 'Rate{deliveryFee:$deliveryFee,freeDeliveryWeight:$freeDeliveryWeight,volumetricRatio:$volumetricRatio,diffDiscountWeight:$diffDiscountWeight,diffWeightRate:$diffWeightRate}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,14 @@ class _ShipmentRatesState extends State<ShipmentRates> {
|
|||||||
"Volumetric Ratio",
|
"Volumetric Ratio",
|
||||||
"${rate.volumetricRatio.toStringAsFixed(2)}",
|
"${rate.volumetricRatio.toStringAsFixed(2)}",
|
||||||
"in3 per pound"),
|
"in3 per pound"),
|
||||||
|
_row(
|
||||||
|
"Weight difference discount",
|
||||||
|
"${rate.diffDiscountWeight.toStringAsFixed(2)}",
|
||||||
|
"pounds"),
|
||||||
|
_row(
|
||||||
|
"Weight difference rate",
|
||||||
|
"\$ ${rate.diffWeightRate.toStringAsFixed(2)}",
|
||||||
|
""),
|
||||||
Divider(
|
Divider(
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
|||||||
_deliveryFee =
|
_deliveryFee =
|
||||||
effectiveWeight > rate.freeDeliveryWeight ? 0 : rate.deliveryFee;
|
effectiveWeight > rate.freeDeliveryWeight ? 0 : rate.deliveryFee;
|
||||||
_amount = amount == null ? 0 : amount + _deliveryFee;
|
_amount = amount == null ? 0 : amount + _deliveryFee;
|
||||||
_shipmentWeight = shipmentWeight;
|
_shipmentWeight = shipmentWeight.toDouble();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,9 +143,7 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
|||||||
leading: new IconButton(
|
leading: new IconButton(
|
||||||
icon: new Icon(CupertinoIcons.back, color: primaryColor),
|
icon: new Icon(CupertinoIcons.back, color: primaryColor),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showConfirmDialog(context, "back.button_confirm", () {
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
});
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
@@ -197,41 +195,4 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_row(String desc, String price, String unit, String value, {bool input}) {
|
|
||||||
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),
|
|
||||||
),
|
|
||||||
// TextFormField(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 50,
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 50,
|
|
||||||
child: TextFormField(
|
|
||||||
initialValue: value,
|
|
||||||
textAlign: TextAlign.end,
|
|
||||||
)),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
|||||||
TextEditingController _minWeight = new TextEditingController();
|
TextEditingController _minWeight = new TextEditingController();
|
||||||
TextEditingController _deliveryFee = new TextEditingController();
|
TextEditingController _deliveryFee = new TextEditingController();
|
||||||
TextEditingController _volumetricRatio = new TextEditingController();
|
TextEditingController _volumetricRatio = new TextEditingController();
|
||||||
|
TextEditingController _diffDiscountWeight = new TextEditingController();
|
||||||
|
TextEditingController _diffWeightRate = new TextEditingController();
|
||||||
|
|
||||||
Rate rate;
|
Rate rate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -41,6 +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) ?? "";
|
||||||
|
_diffWeightRate.text = rate.diffWeightRate?.toStringAsFixed(2) ?? "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -62,8 +67,16 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
|||||||
controller: _deliveryFee);
|
controller: _deliveryFee);
|
||||||
final ratioBox = InputText(
|
final ratioBox = InputText(
|
||||||
labelTextKey: 'rate.volumetric_ratio',
|
labelTextKey: 'rate.volumetric_ratio',
|
||||||
iconData: Icons.attach_money,
|
iconData: FontAwesomeIcons.weightHanging,
|
||||||
controller: _volumetricRatio);
|
controller: _volumetricRatio);
|
||||||
|
final diffDiscountWeightBox = InputText(
|
||||||
|
labelTextKey: 'rate.diff_discount_weight',
|
||||||
|
iconData: FontAwesomeIcons.weightHanging,
|
||||||
|
controller: _diffDiscountWeight);
|
||||||
|
final diffWeightRateBox = InputText(
|
||||||
|
labelTextKey: 'rate.diff_weight_rate',
|
||||||
|
iconData: Icons.attach_money,
|
||||||
|
controller: _diffWeightRate);
|
||||||
|
|
||||||
return LocalProgress(
|
return LocalProgress(
|
||||||
inAsyncCall: _isLoading,
|
inAsyncCall: _isLoading,
|
||||||
@@ -97,6 +110,8 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
|||||||
minWigBox,
|
minWigBox,
|
||||||
feeBox,
|
feeBox,
|
||||||
ratioBox,
|
ratioBox,
|
||||||
|
diffDiscountWeightBox,
|
||||||
|
diffWeightRateBox,
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -121,7 +136,9 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
|||||||
Rate _rate = new Rate(
|
Rate _rate = new Rate(
|
||||||
deliveryFee: double.parse(_deliveryFee.text),
|
deliveryFee: double.parse(_deliveryFee.text),
|
||||||
freeDeliveryWeight: double.parse(_minWeight.text),
|
freeDeliveryWeight: double.parse(_minWeight.text),
|
||||||
volumetricRatio: double.parse(_volumetricRatio.text));
|
volumetricRatio: double.parse(_volumetricRatio.text),
|
||||||
|
diffDiscountWeight: double.parse(_diffDiscountWeight.text),
|
||||||
|
diffWeightRate: double.parse(_diffWeightRate.text));
|
||||||
Rate r = new Rate();
|
Rate r = new Rate();
|
||||||
print('_rate =>$r');
|
print('_rate =>$r');
|
||||||
await shipmentRateModel.updateRate(_rate);
|
await shipmentRateModel.updateRate(_rate);
|
||||||
@@ -139,7 +156,10 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
|||||||
Rate _rate = new Rate(
|
Rate _rate = new Rate(
|
||||||
deliveryFee: double.parse(_deliveryFee.text),
|
deliveryFee: double.parse(_deliveryFee.text),
|
||||||
freeDeliveryWeight: double.parse(_minWeight.text),
|
freeDeliveryWeight: double.parse(_minWeight.text),
|
||||||
volumetricRatio: double.parse(_volumetricRatio.text));
|
volumetricRatio: double.parse(_volumetricRatio.text),
|
||||||
|
diffDiscountWeight: double.parse(_diffDiscountWeight.text),
|
||||||
|
diffWeightRate: double.parse(_diffWeightRate.text),
|
||||||
|
);
|
||||||
return rate.isChangedForEdit(_rate);
|
return rate.isChangedForEdit(_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ dependencies:
|
|||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
test: ^1.15.7
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|||||||
33
test/rate_test.dart
Normal file
33
test/rate_test.dart
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||||
|
import 'package:fcs/domain/entities/carton.dart';
|
||||||
|
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
||||||
|
import 'package:fcs/domain/entities/rate.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
@TestOn('vm')
|
||||||
|
void main() {
|
||||||
|
var rate = Rate();
|
||||||
|
rate.discountByWeights = [
|
||||||
|
DiscountByWeight(weight: 25, discount: 0.25),
|
||||||
|
DiscountByWeight(weight: 50, discount: 0.5),
|
||||||
|
];
|
||||||
|
rate.volumetricRatio = 166.36;
|
||||||
|
rate.diffDiscountWeight = 5;
|
||||||
|
rate.diffWeightRate = 1.5;
|
||||||
|
|
||||||
|
test('Calculate carton price 1', () {
|
||||||
|
var ct = CargoType(name: "General", weight: 10, rate: 6);
|
||||||
|
var carton = Carton(cargoTypes: [ct], length: 15, width: 15, height: 15);
|
||||||
|
expect(carton.calAmount(rate), equals(67.50));
|
||||||
|
});
|
||||||
|
test('Calculate carton price 2', () {
|
||||||
|
var ct = CargoType(name: "General", weight: 10, rate: 6);
|
||||||
|
var carton = Carton(cargoTypes: [ct], length: 10, width: 10, height: 10);
|
||||||
|
expect(carton.calAmount(rate), equals(60));
|
||||||
|
});
|
||||||
|
test('Calculate carton price 3', () {
|
||||||
|
var ct = CargoType(name: "General", weight: 10, rate: 6);
|
||||||
|
var carton = Carton(cargoTypes: [ct], length: 15, width: 15, height: 10);
|
||||||
|
expect(carton.calAmount(rate), equals(60));
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user