import 'package:fcs/domain/entities/cargo_type.dart'; 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/rate.dart'; import 'package.dart'; import 'receipt.dart'; class Invoice { String id; String invoiceNumber; DateTime invoiceDate; String customerName; String customerPhoneNumber; double amount; String status; String paymentAttachment; double handlingFee; double deliveryFee; double paidAmount; List packages; List receipts; List receiptPhotos; List customDuties; List cartons; Discount discount; List getCargoTypes(Rate rate) { List 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; }); DiscountByWeight discountByWeight = rate.getDiscountByWeight( shipmentWeight > actualWeight ? shipmentWeight : actualWeight); 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; e.calRate = r; e.calWeight = cargoWeight; e.amount = amount; }); return cargoTypes; } double getTotal(Rate rate) { List cargoTypes = getCargoTypes(rate); var total = cargoTypes.fold(0.0, (p, c) => c.amount + p); return total; } double getNetAmount(Rate rate) { List cargoTypes = getCargoTypes(rate); var total = cargoTypes.fold(0.0, (p, c) => c.amount + p); total += getCustomFee(); total += getDeliveryFee(); total += getHandlingFee(); total -= getDiscount(); return total; } double getTotalBalance(Rate rate) { return getNetAmount(rate) - (paidAmount ?? 0); } double getCustomFee() { 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); factory Invoice.fromMap(Map map, String docID) { return Invoice( id: docID, invoiceNumber: map['invoice_number'], invoiceDate: map['invoice_date'], customerName: map['customer_name'], customerPhoneNumber: 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'], ); } }