fix rates

This commit is contained in:
2021-01-04 17:19:01 +06:30
parent 3fdcb851ed
commit ee586e8f41
10 changed files with 103 additions and 63 deletions

View File

@@ -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",

View File

@@ -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":"အခကြေးငွေ",

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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}';
} }
} }

View File

@@ -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,
), ),

View File

@@ -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,
)),
],
));
}
} }

View File

@@ -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);
} }

View File

@@ -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
View 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));
});
}