update invoice page
This commit is contained in:
@@ -4,7 +4,6 @@ class CargoType {
|
||||
double rate;
|
||||
double weight;
|
||||
|
||||
int shipmentWeight;
|
||||
double amount;
|
||||
|
||||
double calRate;
|
||||
@@ -16,9 +15,10 @@ class CargoType {
|
||||
name: map['name'],
|
||||
rate: map['rate']?.toDouble() ?? 0,
|
||||
weight: map['weight']?.toDouble() ?? 0,
|
||||
calWeight: map['cal_weight']?.toDouble() ?? 0,
|
||||
);
|
||||
}
|
||||
CargoType({this.id, this.name, this.rate, this.weight});
|
||||
CargoType({this.id, this.name, this.rate, this.weight, this.calWeight});
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
@@ -26,6 +26,7 @@ class CargoType {
|
||||
'name': name,
|
||||
'rate': rate,
|
||||
'weight': weight,
|
||||
'cal_weight': calWeight,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
||||
import 'package:fcs/domain/entities/rate.dart';
|
||||
import 'package:fcs/domain/entities/shipment.dart';
|
||||
import 'package:fcs/domain/vo/shipment_status.dart';
|
||||
import 'package:fcs/domain/vo/delivery_address.dart';
|
||||
|
||||
@@ -9,6 +10,7 @@ import 'package.dart';
|
||||
|
||||
class Carton {
|
||||
String id;
|
||||
String shipmentID;
|
||||
String shipmentNumber;
|
||||
String senderFCSID;
|
||||
String senderName;
|
||||
@@ -47,9 +49,9 @@ class Carton {
|
||||
List<String> packageIDs;
|
||||
List<Package> packages;
|
||||
List<CargoType> cargoTypes;
|
||||
List<Carton> cartons;
|
||||
|
||||
DeliveryAddress deliveryAddress;
|
||||
Shipment shipment;
|
||||
|
||||
int get amount => rate != null && weight != null ? rate * weight : 0;
|
||||
|
||||
@@ -73,6 +75,23 @@ class Carton {
|
||||
return (length * width * height) / volumetricRatio;
|
||||
}
|
||||
|
||||
/// getCargoTypeForCalWeight returns carton with shipment weight
|
||||
List<CargoType> getCargoTypeForCalWeight(double volumetricRatio) {
|
||||
// get shipment weight
|
||||
double volume = (length ?? 0) * (width ?? 0) * (height ?? 0);
|
||||
double sw = volume / volumetricRatio ?? 0;
|
||||
|
||||
// get actual weight
|
||||
double aw = cargoTypes.fold(0.0, (p, c) => p + c.weight);
|
||||
if (aw == 0 || sw == 0) return [];
|
||||
|
||||
cargoTypes.forEach((e) {
|
||||
double calWeight = aw > sw ? e.weight : e.weight / aw * sw;
|
||||
e.calWeight = calWeight;
|
||||
});
|
||||
return cargoTypes;
|
||||
}
|
||||
|
||||
/// calAmount returns total amount
|
||||
double calAmount(Rate rate) {
|
||||
// get shipment weight
|
||||
@@ -101,6 +120,7 @@ class Carton {
|
||||
|
||||
Carton(
|
||||
{this.id,
|
||||
this.shipmentID,
|
||||
this.shipmentNumber,
|
||||
this.senderFCSID,
|
||||
this.senderName,
|
||||
@@ -133,7 +153,6 @@ class Carton {
|
||||
this.cartonNumber,
|
||||
this.fcsShipmentID,
|
||||
this.fcsShipmentNumber,
|
||||
this.cartons,
|
||||
this.packageIDs,
|
||||
this.mixCartonID,
|
||||
this.mixCartonNumber,
|
||||
@@ -143,7 +162,6 @@ class Carton {
|
||||
Map<String, dynamic> toMap() {
|
||||
List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
|
||||
List _packages = packages?.map((c) => c.toJson())?.toList();
|
||||
List _cartons = cartons?.map((c) => c.toMap())?.toList() ?? [];
|
||||
return {
|
||||
"id": id,
|
||||
'fcs_shipment_id': fcsShipmentID,
|
||||
@@ -155,8 +173,7 @@ class Carton {
|
||||
'height': height,
|
||||
'delivery_address': deliveryAddress.toMap(),
|
||||
'carton_type': cartonType,
|
||||
'cartons': _cartons,
|
||||
'mix_carton_id': mixCartonID
|
||||
'mix_carton_id': mixCartonID,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -171,6 +188,7 @@ class Carton {
|
||||
return Carton(
|
||||
id: docID,
|
||||
arrivedDate: _arrivedDate != null ? _arrivedDate.toDate() : null,
|
||||
shipmentID: map['shipment_id'],
|
||||
shipmentNumber: map['shipment_number'],
|
||||
receiverNumber: map['receiver_number'],
|
||||
boxNumber: map['box_number'],
|
||||
|
||||
@@ -3,63 +3,59 @@ import 'package:fcs/domain/entities/carton.dart';
|
||||
import 'package:fcs/domain/entities/custom_duty.dart';
|
||||
import 'package:fcs/domain/entities/discount.dart';
|
||||
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
||||
import 'package:fcs/domain/entities/payment_method.dart';
|
||||
import 'package:fcs/domain/entities/rate.dart';
|
||||
|
||||
import 'package.dart';
|
||||
import 'receipt.dart';
|
||||
import 'package:fcs/domain/entities/shipment.dart';
|
||||
|
||||
class Invoice {
|
||||
String id;
|
||||
String invoiceNumber;
|
||||
DateTime invoiceDate;
|
||||
String customerName;
|
||||
String customerPhoneNumber;
|
||||
double amount;
|
||||
String fcsShipmentID;
|
||||
String userID;
|
||||
String userName;
|
||||
String phoneNumber;
|
||||
String status;
|
||||
String paymentAttachment;
|
||||
|
||||
double handlingFee;
|
||||
double deliveryFee;
|
||||
double paidAmount;
|
||||
double amount;
|
||||
|
||||
List<Package> packages;
|
||||
List<Receipt> receipts;
|
||||
List<String> receiptPhotos;
|
||||
List<CustomDuty> customDuties;
|
||||
List<Carton> cartons;
|
||||
List<CargoType> cargoTypes;
|
||||
List<Shipment> shipments;
|
||||
Discount discount;
|
||||
PaymentMethod paymentMethod;
|
||||
|
||||
List<CargoType> getCargoTypes(Rate rate) {
|
||||
List<CargoType> cargoTypes = [];
|
||||
double actualWeight = 0;
|
||||
double shipmentWeight = 0;
|
||||
cartons.forEach((c) {
|
||||
c.cargoTypes.forEach((tc) {
|
||||
if (cargoTypes.contains(tc)) {
|
||||
CargoType existing = cargoTypes.firstWhere((wc) => wc.id == tc.id);
|
||||
existing.weight += tc.weight;
|
||||
} else {
|
||||
cargoTypes.add(tc.clone());
|
||||
}
|
||||
actualWeight += tc.weight;
|
||||
});
|
||||
double volume = (c.length ?? 0) * (c.width ?? 0) * (c.height ?? 0);
|
||||
double sw = volume / rate.volumetricRatio ?? 0;
|
||||
shipmentWeight += sw;
|
||||
double totalCalWeight = 0;
|
||||
cartons.forEach((carton) {
|
||||
if (carton.isChecked) {
|
||||
var _cartonsTypes =
|
||||
carton.getCargoTypeForCalWeight(rate.volumetricRatio);
|
||||
_cartonsTypes.forEach((ct) {
|
||||
if (cargoTypes.contains(ct)) {
|
||||
CargoType existing = cargoTypes.firstWhere((wc) => wc.id == ct.id);
|
||||
existing.calWeight += ct.calWeight;
|
||||
} else {
|
||||
cargoTypes.add(ct.clone());
|
||||
}
|
||||
totalCalWeight += ct.calWeight;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
DiscountByWeight discountByWeight = rate.getDiscountByWeight(
|
||||
shipmentWeight > actualWeight ? shipmentWeight : actualWeight);
|
||||
DiscountByWeight discountByWeight =
|
||||
rate.getDiscountByWeight(totalCalWeight);
|
||||
|
||||
cargoTypes.forEach((e) {
|
||||
print(actualWeight > shipmentWeight);
|
||||
double cargoWeight = actualWeight > shipmentWeight
|
||||
? e.weight
|
||||
: e.weight / actualWeight * shipmentWeight;
|
||||
double r =
|
||||
e.rate - (discountByWeight != null ? discountByWeight.discount : 0);
|
||||
double amount = cargoWeight * r;
|
||||
double amount = e.calWeight * r;
|
||||
e.calRate = r;
|
||||
e.calWeight = cargoWeight;
|
||||
e.amount = amount;
|
||||
});
|
||||
return cargoTypes;
|
||||
@@ -81,6 +77,12 @@ class Invoice {
|
||||
return total;
|
||||
}
|
||||
|
||||
double getHandlingFee() {
|
||||
return shipments?.where((sh) => sh.isSelected)?.fold(0, (p, s) {
|
||||
return p + (s?.handlingFee ?? 0) - (s?.paidHandlingFee ?? 0);
|
||||
});
|
||||
}
|
||||
|
||||
double getTotalBalance(Rate rate) {
|
||||
return getNetAmount(rate) - (paidAmount ?? 0);
|
||||
}
|
||||
@@ -89,49 +91,57 @@ class Invoice {
|
||||
return customDuties == null ? 0 : customDuties.fold(0, (p, d) => p + d.fee);
|
||||
}
|
||||
|
||||
double getHandlingFee() {
|
||||
return handlingFee == null ? 0 : handlingFee;
|
||||
}
|
||||
|
||||
double getDeliveryFee() {
|
||||
return deliveryFee == null ? 0 : deliveryFee;
|
||||
}
|
||||
|
||||
double getDiscount() => discount == null ? 0 : discount.amount;
|
||||
|
||||
Invoice(
|
||||
{this.id,
|
||||
this.invoiceNumber,
|
||||
this.invoiceDate,
|
||||
this.customerName,
|
||||
this.customerPhoneNumber,
|
||||
this.amount,
|
||||
this.discount,
|
||||
this.status,
|
||||
this.paymentAttachment,
|
||||
this.packages,
|
||||
this.receiptPhotos,
|
||||
this.customDuties,
|
||||
this.cartons,
|
||||
this.handlingFee,
|
||||
this.receipts});
|
||||
|
||||
double get getAmount => packages.fold(0, (p, e) => (e.rate * e.weight) + p);
|
||||
Invoice({
|
||||
this.id,
|
||||
this.invoiceNumber,
|
||||
this.invoiceDate,
|
||||
this.userName,
|
||||
this.phoneNumber,
|
||||
this.amount,
|
||||
this.discount,
|
||||
this.status,
|
||||
this.customDuties,
|
||||
this.cartons,
|
||||
this.cargoTypes,
|
||||
this.handlingFee,
|
||||
this.fcsShipmentID,
|
||||
this.shipments,
|
||||
});
|
||||
|
||||
factory Invoice.fromMap(Map<String, dynamic> map, String docID) {
|
||||
return Invoice(
|
||||
id: docID,
|
||||
invoiceNumber: map['invoice_number'],
|
||||
invoiceDate: map['invoice_date'],
|
||||
customerName: map['customer_name'],
|
||||
customerPhoneNumber: map['phone_number'],
|
||||
userName: map['user_name'],
|
||||
phoneNumber: map['phone_number'],
|
||||
amount: map['amount'],
|
||||
status: map['status'],
|
||||
discount: map['discount'],
|
||||
paymentAttachment: map['payment_attachment'],
|
||||
packages: map['packages'],
|
||||
receiptPhotos: map['receiptPhotos'],
|
||||
receipts: map['receipts'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList();
|
||||
List _customDuties = customDuties?.map((c) => c.toMap())?.toList();
|
||||
List _cartons = cartons?.map((c) => c.toMap())?.toList() ?? [];
|
||||
return {
|
||||
"id": id,
|
||||
"invoice_date": invoiceDate,
|
||||
"user_id": userID,
|
||||
'fcs_shipment_id': fcsShipmentID,
|
||||
'cargo_types': _cargoTypes,
|
||||
'custom_duties': _customDuties,
|
||||
'cartons': _cartons,
|
||||
'discount': discount?.toMap(),
|
||||
'handling_fee': handlingFee,
|
||||
'delivery_fee': deliveryFee,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
|
||||
class Receipt {
|
||||
String id;
|
||||
int amount;
|
||||
|
||||
@@ -18,6 +18,7 @@ class Shipment {
|
||||
int numberOfPackage;
|
||||
int weight;
|
||||
double handlingFee;
|
||||
double paidHandlingFee;
|
||||
String address;
|
||||
String status;
|
||||
bool isCourier;
|
||||
@@ -31,6 +32,7 @@ class Shipment {
|
||||
String fcsShipmentID;
|
||||
String fcsShipmentNumber;
|
||||
String shipmentLabelUrl;
|
||||
bool isSelected;
|
||||
|
||||
Shipment(
|
||||
{this.id,
|
||||
@@ -44,6 +46,7 @@ class Shipment {
|
||||
this.numberOfPackage,
|
||||
this.weight,
|
||||
this.handlingFee,
|
||||
this.paidHandlingFee,
|
||||
this.address,
|
||||
this.status,
|
||||
this.pickupDate,
|
||||
@@ -89,6 +92,7 @@ class Shipment {
|
||||
pickupUserName: map['pickup_user_name'],
|
||||
pickupUserPhoneNumber: map['pickup_user_phone_number'],
|
||||
handlingFee: map['handling_fee'],
|
||||
paidHandlingFee: map['paid_handling_fee'],
|
||||
fcsShipmentID: map['fcs_shipment_id'],
|
||||
fcsShipmentNumber: map['fcs_shipment_number'],
|
||||
shipmentLabelUrl: map['shipment_label_url'],
|
||||
@@ -116,6 +120,12 @@ class Shipment {
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => other is Shipment && other.id == id;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PickUp{id:$id, userName:$userName,phoneNumber:$phoneNumber,numberOfPackage:$numberOfPackage,weight:$weight,status:$status}';
|
||||
|
||||
Reference in New Issue
Block a user