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'; import 'cargo_type.dart'; import 'package.dart'; class Carton { String? id; String? shipmentID; String? shipmentNumber; String? senderID; String? senderFCSID; String? senderName; String? boxNumber; String? status; String? cargoDesc; String? desc; double width; double height; double length; int? shipmentWeight; bool? isChecked; bool? isShipmentCarton; String? cartonType; String? fcsID; String? userName; String? userID; String? fcsShipmentID; String? fcsShipmentNumber; String? mixCartonID; String? mixCartonNumber; String? cartonSizeID; String? cartonSizeName; double? cartonWeight; int rate; int weight; String? packageType; String? pickUpID; List photos = []; String? remark; DateTime? arrivedDate; String? cartonNumber; List packageIDs; List packages; List cargoTypes = []; DeliveryAddress? deliveryAddress; Shipment? shipment; //for mix box String? mixBoxType; List mixCartons; List mixCartonIDs; int get amount => rate != null && weight != null ? (rate * weight) : 0; // String get packageNumber => // shipmentNumber + "-" + receiverNumber + " #" + boxNumber; double get actualWeight => cargoTypes == null ? 0 : cargoTypes.fold(0, (p, e) => e.weight + p); int getShipmentWeight(double volumetricRatio) { if (length == null || length <= 0 || width == null || width <= 0 || height == null || height <= 0 || volumetricRatio == null || volumetricRatio <= 0) return 0; return ((length * width * height) / volumetricRatio).round(); } /// getCargoTypeForCalWeight returns carton with shipment weight List getCargoTypeForCalWeight(double volumetricRatio) { // get shipment weight double volume = length * width * height; double sw = volume / volumetricRatio; // 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 int sw = getShipmentWeight(rate.volumetricRatio); // get actual weight double aw = cargoTypes.fold(0.0, (p, c) => p + c.weight); if (aw == 0 || sw == 0) return 0; double wd = sw - aw; wd = wd - rate.diffDiscountWeight; double wdAmount = wd > 0 ? wd * rate.diffWeightRate : 0; DiscountByWeight discountByWeight = rate.getDiscountByWeight(aw); double total = 0; cargoTypes.forEach((e) { double r = e.rate - (discountByWeight != null ? (discountByWeight.discount) : 0); double amount = e.weight * r; total += amount; }); return total + wdAmount; } List shipmentHistory; Carton( {this.id, this.shipmentID, this.shipmentNumber, this.senderID, this.senderFCSID, this.senderName, this.boxNumber, this.desc, this.width = 0, this.height = 0, this.length = 0, this.shipmentWeight, this.isChecked = false, this.cartonType, this.fcsID, this.userID, this.userName, this.rate = 0, this.weight = 0, this.packageType, this.pickUpID, this.remark, this.status, this.arrivedDate, this.cargoDesc, this.shipmentHistory = const [], this.packages = const [], this.cargoTypes = const [], this.cartonNumber, this.fcsShipmentID, this.fcsShipmentNumber, this.packageIDs = const [], this.mixCartonID, this.mixCartonNumber, this.isShipmentCarton = false, this.deliveryAddress, this.cartonSizeID, this.cartonSizeName, this.mixBoxType, this.mixCartons = const [], this.mixCartonIDs = const [], this.cartonWeight}); Map toMap() { List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList(); List _packages = packages.map((c) => c.toJson()).toList(); List _mixCartons = mixCartons.map((c) => c.toJson()).toList(); return { 'id': id, 'fcs_shipment_id': fcsShipmentID, 'user_id': userID, 'cargo_types': _cargoTypes, 'packages': _packages, 'length': length, 'width': width, 'height': height, 'delivery_address': deliveryAddress?.toMap(), 'carton_type': cartonType, 'mix_carton_id': mixCartonID, 'mix_box_type': mixBoxType, 'mix_cartons': _mixCartons, 'sender_id': senderID, 'sender_fcs_id': senderFCSID, 'sender_name': senderName }; } factory Carton.fromMap(Map map, String docID) { var _arrivedDate = (map['arrived_date'] as Timestamp); var da = map['delivery_address']; var _da = da != null ? DeliveryAddress.fromMap(da, da["id"]) : null; var cargoTypesMaps = List>.from(map['cargo_types'] ?? []); var cargoTypes = cargoTypesMaps.map((e) => CargoType.fromMap(e, e["id"])).toList(); var mixCartonsMaps = List>.from(map['mix_cartons'] ?? []); var _mixCartons = mixCartonsMaps.map((e) => Carton.fromMap(e, e["id"])).toList(); 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'], length: double.tryParse(map['length'].toString()) ?? 0, width: double.tryParse(map['width'].toString()) ?? 0, height: double.tryParse(map['height'].toString()) ?? 0, userName: map['user_name'], fcsID: map['fcs_id'], cartonType: map['carton_type'], cartonNumber: map['carton_number'], userID: map['user_id'], fcsShipmentID: map['fcs_shipment_id'], fcsShipmentNumber: map['fcs_shipment_number'], isShipmentCarton: map['is_shipment_carton'], mixCartonID: map['mix_carton_id'], mixCartonNumber: map['mix_carton_number'], status: map['status'], packageIDs: List.from(map['package_ids'] ?? []), deliveryAddress: _da, cargoTypes: cargoTypes, mixBoxType: map['mix_box_type'], mixCartons: _mixCartons, senderID: map['sender_id'], senderFCSID: map['sender_fcs_id'], senderName: map['sender_name'], mixCartonIDs: List.from(map['mix_carton_ids'] ?? []), cartonWeight: (map['carton_weight'] ?? 0).toDouble(), ); } Map toJson() { List _cargoTypes = cargoTypes.map((c) => c.toMap()).toList(); List _packages = packages.map((c) => c.toJson()).toList(); List _mixCartons = mixCartons.map((c) => c.toJson()).toList(); return { 'id': id, 'fcs_shipment_id': fcsShipmentID, 'user_id': userID, 'cargo_types': _cargoTypes, 'packages': _packages, 'length': length, 'width': width, 'height': height, 'delivery_address': deliveryAddress?.toMap(), 'carton_type': cartonType, 'mix_carton_id': mixCartonID, 'mix_box_type': mixBoxType, 'mix_cartons': _mixCartons, 'sender_id': senderID, 'sender_fcs_id': senderFCSID, 'sender_name': senderName }; } @override bool operator ==(Object other) => other is Carton && other.id == id; @override int get hashCode => id.hashCode; }