add structure
This commit is contained in:
386
lib/vo/do.dart
Normal file
386
lib/vo/do.dart
Normal file
@@ -0,0 +1,386 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import 'po.dart';
|
||||
import 'setting.dart';
|
||||
|
||||
class DOSubmission {
|
||||
final dateFormatter = new DateFormat('dd MMM yyyy hh:mm a');
|
||||
|
||||
String id;
|
||||
String poID;
|
||||
String doNumber;
|
||||
DateTime deliveryDate;
|
||||
DateTime doDate;
|
||||
String driverLicenseNumber;
|
||||
String driverName;
|
||||
String carNo;
|
||||
String status;
|
||||
String deliveryStatus;
|
||||
DateTime deliveryInitiatedTime;
|
||||
String comment;
|
||||
String userID;
|
||||
String userName;
|
||||
String type;
|
||||
String bizName;
|
||||
String driverImgUrl;
|
||||
String doReceiptUrl;
|
||||
int storageCharge = 0;
|
||||
String storageReceiptUrl;
|
||||
String driverLicenceUrl;
|
||||
int totalQty;
|
||||
|
||||
File driverImg;
|
||||
|
||||
List<DOLine> doLines = List();
|
||||
List<POSubmission> pos = List();
|
||||
List<DOPOLine> dopoLies = List();
|
||||
|
||||
get isApproved => status != null && status == "approved";
|
||||
get isClosed => status != null && status == "closed";
|
||||
get isPending => status == "pending";
|
||||
get getDeliveryStatus =>
|
||||
deliveryStatus == null ? "You can initiate delivery" : deliveryStatus;
|
||||
get deliveryInitTime => deliveryInitiatedTime == null
|
||||
? ""
|
||||
: dateFormatter.format(deliveryInitiatedTime);
|
||||
|
||||
bool hasStorageCharge() {
|
||||
return this.storageCharge != null && this.storageCharge > 0;
|
||||
}
|
||||
|
||||
DOSubmission(
|
||||
{this.id,
|
||||
this.doNumber,
|
||||
this.deliveryDate,
|
||||
this.doDate,
|
||||
this.driverLicenseNumber,
|
||||
this.driverName,
|
||||
this.carNo,
|
||||
this.status,
|
||||
this.comment,
|
||||
this.type,
|
||||
this.userName,
|
||||
this.bizName,
|
||||
this.deliveryStatus,
|
||||
this.driverImgUrl,
|
||||
this.deliveryInitiatedTime,
|
||||
this.poID,
|
||||
this.doReceiptUrl,
|
||||
this.storageCharge,
|
||||
this.storageReceiptUrl,
|
||||
this.driverLicenceUrl,
|
||||
this.totalQty});
|
||||
|
||||
void loadPOs() {
|
||||
this.doLines.clear();
|
||||
var isSingle = type == "single";
|
||||
pos.forEach((p) => p.poLines.forEach((l) {
|
||||
var dl = DOLine(
|
||||
productID: l.productID,
|
||||
productName: l.productName,
|
||||
qty: isSingle ? l.balanceQty : 0,
|
||||
poBalQty: l.balanceQty);
|
||||
if (this.doLines.contains(dl)) {
|
||||
this.doLines[this.doLines.indexOf(dl)].qty += dl.qty;
|
||||
this.doLines[this.doLines.indexOf(dl)].poBalQty += dl.poBalQty;
|
||||
} else {
|
||||
this.doLines.add(dl);
|
||||
}
|
||||
}));
|
||||
|
||||
dopoLies.clear();
|
||||
pos.forEach((p) => p.poLines.forEach((l) => dopoLies.add(DOPOLine(
|
||||
poID: p.id,
|
||||
productID: l.productID,
|
||||
productName: l.productName,
|
||||
poNumber: p.poNumber,
|
||||
poQty: l.qty,
|
||||
poBalQty: l.balanceQty,
|
||||
doQty: isSingle ? l.balanceQty : 0,
|
||||
poApproveDate: p.poApproveDate,
|
||||
))));
|
||||
dopoLies.sort((l1, l2) => l1.poNumber.compareTo(l2.poNumber));
|
||||
}
|
||||
|
||||
void updateDoline(String productID, int qty) {
|
||||
var _doLine = this.doLines.firstWhere((l) => l.productID == productID);
|
||||
|
||||
if (qty < 0) {
|
||||
throw Exception("invalid number, must be greater than or equal to zero");
|
||||
}
|
||||
|
||||
if (_doLine.poBalQty < qty) {
|
||||
throw Exception(
|
||||
"invalid number,must be less than or equal to PO balance qty");
|
||||
}
|
||||
if (_doLine != null && _doLine.poBalQty >= qty) {
|
||||
_doLine.qty = qty;
|
||||
|
||||
var _dopoLines = dopoLies.where((l) => l.productID == productID).toList();
|
||||
// clear
|
||||
_dopoLines.forEach((l) => l.doQty = 0);
|
||||
|
||||
// add
|
||||
var poBalQty = qty;
|
||||
_dopoLines.forEach((l) {
|
||||
if (poBalQty == 0) return;
|
||||
var _qty = poBalQty > l.poBalQty ? l.poBalQty : poBalQty;
|
||||
l.doQty = _qty;
|
||||
poBalQty -= _qty;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void updateStorageCharge(Setting setting) {
|
||||
if (deliveryDate == null) {
|
||||
storageCharge = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
var _deliveryDate =
|
||||
DateTime(deliveryDate.year, deliveryDate.month, deliveryDate.day);
|
||||
storageCharge = 0;
|
||||
dopoLies.forEach((l) {
|
||||
var _approveDate = DateTime(
|
||||
l.poApproveDate.year, l.poApproveDate.month, l.poApproveDate.day);
|
||||
int diff = _deliveryDate.difference(_approveDate).inDays;
|
||||
if (diff > setting.firstStorageChargeIn) {
|
||||
storageCharge += l.doQty * setting.firstStorageCharge;
|
||||
}
|
||||
if (diff > setting.secondStorageChargeIn) {
|
||||
storageCharge += l.doQty * setting.secondStorageCharge;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
List<String> getPOs() {
|
||||
return this.dopoLies.map((l) => l.poID).toList();
|
||||
}
|
||||
|
||||
void setDOPOLineBalance(String poID, List<POLine> poLines) {
|
||||
poLines.forEach((poLine) {
|
||||
this.dopoLies.forEach((l) {
|
||||
if (l.poID == poID && l.productID == poLine.productID) {
|
||||
l.poBalQty = poLine.balanceQty;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
List lines = doLines.map((l) => l.toMap()).toList();
|
||||
List doPOlines = dopoLies.map((l) => l.toMap()).toList();
|
||||
return {
|
||||
"id": id,
|
||||
'delivery_date': deliveryDate?.toUtc()?.toIso8601String(),
|
||||
'do_number': doNumber,
|
||||
'po_id': poID,
|
||||
'car_number': carNo,
|
||||
'driver_name': driverName,
|
||||
'driver_license_number': driverLicenseNumber,
|
||||
'do_lines': lines,
|
||||
'do_po_lines': doPOlines,
|
||||
'comment': comment,
|
||||
'user_id': userID,
|
||||
'user_name': userName,
|
||||
'type': type,
|
||||
'driver_img_url': driverImgUrl,
|
||||
'driver_sign_url': doReceiptUrl,
|
||||
'delivery_status': deliveryStatus,
|
||||
'storage_charge': storageCharge,
|
||||
'storage_receipt_url': storageReceiptUrl,
|
||||
'driver_license_url': driverLicenceUrl,
|
||||
};
|
||||
}
|
||||
|
||||
factory DOSubmission.fromMap(Map<String, dynamic> map, String id) {
|
||||
var ts = (map['delivery_date'] as Timestamp);
|
||||
var dt = (map['delivery_initiated_time'] as Timestamp);
|
||||
var dots = (map['do_date'] as Timestamp);
|
||||
return DOSubmission(
|
||||
id: id,
|
||||
deliveryDate: ts == null ? null : ts.toDate(),
|
||||
deliveryInitiatedTime: dt == null ? null : dt.toDate(),
|
||||
doDate: dots == null ? null : dots.toDate(),
|
||||
doNumber: map['do_number'],
|
||||
status: map['status'],
|
||||
comment: map["comment"],
|
||||
driverName: map["driver_name"],
|
||||
driverLicenseNumber: map["driver_license_number"],
|
||||
driverImgUrl: map["driver_img_url"],
|
||||
doReceiptUrl: map["driver_sign_url"],
|
||||
carNo: map["car_number"],
|
||||
type: map["type"],
|
||||
userName: map['user_name'],
|
||||
bizName: map['biz_name'],
|
||||
deliveryStatus: map['delivery_status'],
|
||||
poID: map['po_id'],
|
||||
storageCharge: map['storage_charge'],
|
||||
storageReceiptUrl: map['storage_receipt_url'],
|
||||
driverLicenceUrl: map['driver_license_url'],
|
||||
totalQty: map['total_qty']);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DOSubmission{id:$id, deliveryDate:$deliveryDate,driverLicenseNumber:$driverLicenseNumber,driverName:$driverName,carNo:$carNo,status:$status,doLines:$doLines}';
|
||||
}
|
||||
}
|
||||
|
||||
class DOLine {
|
||||
String id;
|
||||
String productID;
|
||||
String productName;
|
||||
int qty;
|
||||
int amount;
|
||||
int price;
|
||||
String storageID;
|
||||
String storageName;
|
||||
String action;
|
||||
int displayOrder;
|
||||
|
||||
int poBalQty; // only for UI
|
||||
|
||||
DOLine(
|
||||
{this.id,
|
||||
this.productID,
|
||||
this.productName,
|
||||
this.qty,
|
||||
this.amount,
|
||||
this.price,
|
||||
this.storageID,
|
||||
this.storageName,
|
||||
this.action,
|
||||
this.poBalQty,
|
||||
this.displayOrder});
|
||||
|
||||
factory DOLine.fromMap(Map<String, dynamic> map) {
|
||||
return DOLine(
|
||||
id: map['id'],
|
||||
productID: map['product_id'],
|
||||
productName: map['product_name'],
|
||||
qty: map['quantity'],
|
||||
amount: map['amount'],
|
||||
price: map['price'],
|
||||
storageID: map['storage_id'],
|
||||
storageName: map['storage_name'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'product_id': productID,
|
||||
'product_name': productName,
|
||||
'quantity': qty,
|
||||
'price': price,
|
||||
'amount': amount,
|
||||
'storage_id': storageID,
|
||||
'storage_name': storageName,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
return other.productID == this.productID;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
int result = 17;
|
||||
result = 37 * result + productID.hashCode;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DOLine{productID:$productID,productName:$productName,qty:$qty,amount:$amount,price:$price,storageID:$storageID,displayOrder:$displayOrder}';
|
||||
}
|
||||
}
|
||||
|
||||
class DOPOLine {
|
||||
String id;
|
||||
String poID;
|
||||
String poNumber;
|
||||
DateTime poApproveDate;
|
||||
String productID;
|
||||
String productName;
|
||||
int poQty;
|
||||
int poBalQty;
|
||||
int doQty;
|
||||
int poBalAtCreate;
|
||||
|
||||
DateTime poApprovedDate;
|
||||
int displayOrder;
|
||||
|
||||
get getPoBalanceQty => poBalQty - doQty;
|
||||
get getPoBalanceQtyAtCreate =>
|
||||
poBalAtCreate == null ? 0 : (poBalAtCreate - doQty);
|
||||
|
||||
DOPOLine(
|
||||
{this.id,
|
||||
this.poID,
|
||||
this.poNumber,
|
||||
this.productID,
|
||||
this.productName,
|
||||
this.poQty,
|
||||
this.poBalQty,
|
||||
this.doQty,
|
||||
this.poApproveDate,
|
||||
this.displayOrder,
|
||||
this.poBalAtCreate});
|
||||
|
||||
factory DOPOLine.fromMap(Map<String, dynamic> map) {
|
||||
return DOPOLine(
|
||||
id: map['id'],
|
||||
poID: map['po_id'],
|
||||
poNumber: map['po_number'],
|
||||
productID: map['product_id'],
|
||||
productName: map['product_name'],
|
||||
doQty: map['do_quantity'],
|
||||
poQty: map['po_quantity'],
|
||||
poBalQty: map['po_bal_quantity'],
|
||||
poBalAtCreate: map['po_balance_at_create']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'po_id': poID,
|
||||
'po_number': poNumber,
|
||||
'product_id': productID,
|
||||
'product_name': productName,
|
||||
'do_quantity': doQty,
|
||||
'po_quantity': poQty,
|
||||
'po_bal_quantity': poBalQty,
|
||||
'po_balance_at_create': poBalQty,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(other) {
|
||||
if (identical(this, other)) {
|
||||
return true;
|
||||
}
|
||||
return other.productID == this.productID && other.poID == this.poID;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
int result = 17;
|
||||
result = 37 * result + poID.hashCode;
|
||||
result = 37 * result + productID.hashCode;
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'DOLine{productID:$productID,productName:$productName,doQty:$doQty}';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user