update cargo type form from rate, update carton info and form
This commit is contained in:
@@ -351,7 +351,7 @@
|
||||
"box.no_package":"There is no packages.",
|
||||
"box.input_cargo_weight":"Cargo type (lb)",
|
||||
"box.input_surcharge_item":"Surcharge items",
|
||||
"box.select.cargo_type":"Select surcharge item",
|
||||
"box.select.cargo_type":"Add surcharge item",
|
||||
"box.surcharge.item":"Surcharge items",
|
||||
"box.package.count":"Packages ({0})",
|
||||
"box.bill_to":"Bill to",
|
||||
@@ -370,6 +370,7 @@
|
||||
"box.print.btn":"Print",
|
||||
"box.delivery":"Delivery",
|
||||
"box.pickup":"Pick-up",
|
||||
"box.add.cargo_type":"Add cargo type",
|
||||
"Boxes End ================================================================":"",
|
||||
|
||||
"Delivery Start ================================================================":"",
|
||||
@@ -393,8 +394,8 @@
|
||||
"FCSshipment.departure_date":"Departure date",
|
||||
"FCSshipment.shipment_type":"Shipment type",
|
||||
"FCSshipment.consignee":"Consignee",
|
||||
"FCSshipment.port_of_loading":"Port of loading",
|
||||
"FCSshipment.final_destination":"Final destination",
|
||||
"FCSshipment.port_of_loading":"Loading port",
|
||||
"FCSshipment.final_destination":"Destination port",
|
||||
"FCSshipment.status":"Status",
|
||||
"FCSshipment.remark":"Remark",
|
||||
"FCSshipment.commercial_invoice":"Download commercial invoice",
|
||||
@@ -415,6 +416,7 @@
|
||||
"FCSshipment.process.confirm":"Process this shipment?",
|
||||
"FCSshipment.arrive.confirm":"Arrive this shipment?",
|
||||
"FCSshipment.invoice.confirm":"Invoice this shipment?",
|
||||
"FCSshipment.delete.confirm":"Delete this shipment?",
|
||||
"FCS Shipment End ================================================================":"",
|
||||
|
||||
"Shipment Start ================================================================":"",
|
||||
@@ -509,6 +511,8 @@
|
||||
"cargo.qty":"Quantity",
|
||||
"cargo.amount":"Amount",
|
||||
"cargo.edit.delete.confirm":"Delete this cargo type?",
|
||||
"cargo.display_index":"Display index",
|
||||
"cargo.is_default":"Default Cargo",
|
||||
"Cargo End ================================================================":"",
|
||||
|
||||
"Invoices Start ================================================================":"",
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
"box.no_package":"There is no packages.",
|
||||
"box.input_cargo_weight":"Cargo type (lb)",
|
||||
"box.input_surcharge_item":"Surcharge items",
|
||||
"box.select.cargo_type":"Select surcharge item",
|
||||
"box.select.cargo_type":"Add surcharge item",
|
||||
"box.surcharge.item":"Surcharge items",
|
||||
"box.package.count":"Packages ({0})",
|
||||
"box.bill_to":"Bill to",
|
||||
@@ -370,6 +370,7 @@
|
||||
"box.print.btn":"ပရင့်ထုတ်မည်",
|
||||
"box.delivery":"Delivery",
|
||||
"box.pickup":"Pick-up",
|
||||
"box.add.cargo_type":"Add cargo type",
|
||||
"Boxes End ================================================================":"",
|
||||
|
||||
"Delivery Start ================================================================":"",
|
||||
@@ -418,6 +419,7 @@
|
||||
"FCSshipment.process.confirm":"လုပ်ငန်းစဉ်ကို အတည်ပြုပါ ?",
|
||||
"FCSshipment.arrive.confirm":"ရောက်ရှိကြောင်း အတည်ပြုပါ ?",
|
||||
"FCSshipment.invoice.confirm":"Invoice this shipment ?",
|
||||
"FCSshipment.delete.confirm":"တင်ပို့ခြင်းကို ဖျက်မလား?",
|
||||
"FCS Shipment End ================================================================":"",
|
||||
|
||||
"Shipment Start ================================================================":"",
|
||||
@@ -512,6 +514,8 @@
|
||||
"cargo.qty":"အရေအတွက်",
|
||||
"cargo.amount":"ပမာဏ",
|
||||
"cargo.edit.delete.confirm":"ကုန်ပစ္စည်းကို ဖျက်မလား?",
|
||||
"cargo.display_index":"Display index",
|
||||
"cargo.is_default":"Default Cargo",
|
||||
"Cargo End ================================================================":"",
|
||||
|
||||
"Invoices Start ================================================================":"",
|
||||
|
||||
@@ -9,6 +9,8 @@ const privilege_collection = "privileges";
|
||||
const markets_collection = "markets";
|
||||
const carton_sizes_collection = "carton_sizes";
|
||||
const shipment_type_collection = "shipment_types";
|
||||
const shipment_consignee_collection = "shipment_consignees";
|
||||
const shipment_port_collection = "ports";
|
||||
|
||||
const packages_collection = "packages";
|
||||
const messages_collection = "messages";
|
||||
@@ -91,6 +93,7 @@ const shipment_courier_dropoff = "Courier drop off";
|
||||
//Carton types
|
||||
const carton_from_packages = "For packages";
|
||||
const carton_mix_carton = "For cartons (Mix carton)";
|
||||
const mix_carton = "Mix carton";
|
||||
|
||||
const carton_from_cartons = "From cartons";
|
||||
const carton_from_shipments = "From shipments";
|
||||
@@ -100,7 +103,7 @@ const carton_mix_box = "Mix box";
|
||||
// carton Size
|
||||
const standardCarton = "Standard carton size";
|
||||
const customCarton = "Custom size";
|
||||
const packageCartion = "Package";
|
||||
const packageCarton = "Package";
|
||||
|
||||
//Mix types
|
||||
const mix_delivery = "Mix Delivery";
|
||||
@@ -140,9 +143,9 @@ const payment_confirmed_status = "confirmed";
|
||||
const payment_canceled_status = "canceled";
|
||||
|
||||
//Delivery types
|
||||
const delivery_caton = "Delivery";
|
||||
const pickup_carton = "Pick-up";
|
||||
const delivery_caton = "delivery";
|
||||
const pickup_carton = "pickup";
|
||||
|
||||
// bill
|
||||
const billToSender = "Bill to sender";
|
||||
const billToConsignee = "Bill to consignee";
|
||||
const billToSender = "sender";
|
||||
const billToConsignee = "consignee";
|
||||
|
||||
@@ -15,6 +15,7 @@ class CartonDataProvider {
|
||||
Future<Carton> createCarton(Carton carton) async {
|
||||
var data = await requestAPI("/cartons", "POST",
|
||||
payload: carton.toMap(), token: await getToken());
|
||||
print("carton data:${data}");
|
||||
return Carton.fromMap(data, data['id']);
|
||||
}
|
||||
|
||||
@@ -25,7 +26,25 @@ class CartonDataProvider {
|
||||
|
||||
Future<void> deleteCarton(Carton carton) async {
|
||||
return await requestAPI("/cartons", "DELETE",
|
||||
payload: carton.toMap(), token: await getToken());
|
||||
payload: {'id': carton.id}, token: await getToken());
|
||||
}
|
||||
|
||||
Future<Carton> createMixCarton(Carton carton) async {
|
||||
var data = await requestAPI("/cartons", "POST",
|
||||
payload: carton.toMapForMix(), token: await getToken());
|
||||
print("carton mix data:${data}");
|
||||
return Carton.fromMap(data, data['id']);
|
||||
}
|
||||
|
||||
Future<void> updateMixCarton(Carton carton) async {
|
||||
return await requestAPI("/cartons", "PUT",
|
||||
payload: carton.toMapForMix(), token: await getToken());
|
||||
}
|
||||
|
||||
Future<void> uploadCartonImages(Carton carton) async {
|
||||
return await requestAPI("/cartons/upload_images", "PUT",
|
||||
payload: {'id': carton.id, "photo_urls": carton.photoUrls},
|
||||
token: await getToken());
|
||||
}
|
||||
|
||||
Future<void> deliver(Carton carton) async {
|
||||
@@ -47,7 +66,7 @@ class CartonDataProvider {
|
||||
.collection(path)
|
||||
.where("carton_number", isEqualTo: term)
|
||||
.where("is_deleted", isEqualTo: false)
|
||||
.orderBy("created_at", descending: true)
|
||||
.orderBy("update_time", descending: true)
|
||||
.get();
|
||||
return querySnap.docs.map((e) => Carton.fromMap(e.data(), e.id)).toList();
|
||||
} catch (e) {
|
||||
|
||||
@@ -38,6 +38,7 @@ class RateDataProvider {
|
||||
.doc(rate_doc_id)
|
||||
.collection(cargo_types_collection)
|
||||
.where("custom_duty", isEqualTo: false)
|
||||
.orderBy("display_index", descending: false)
|
||||
.snapshots();
|
||||
|
||||
await for (var snaps in snapshots) {
|
||||
|
||||
@@ -37,4 +37,19 @@ class CartonServiceImp implements CartonService {
|
||||
Future<List<Carton>> searchCarton(String term) {
|
||||
return cartonDataProvider.searchCarton(term);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Carton> createMixCarton(Carton carton) {
|
||||
return cartonDataProvider.createMixCarton(carton);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> updateMixCarton(Carton carton) {
|
||||
return cartonDataProvider.updateMixCarton(carton);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> uploadCartonImages(Carton carton) {
|
||||
return cartonDataProvider.uploadCartonImages(carton);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,7 @@ abstract class CartonService {
|
||||
Future<void> deleteCarton(Carton carton);
|
||||
Future<void> deliver(Carton carton);
|
||||
Future<List<Carton>> searchCarton(String term);
|
||||
Future<Carton> createMixCarton(Carton carton);
|
||||
Future<void> updateMixCarton(Carton carton);
|
||||
Future<void> uploadCartonImages(Carton carton);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ class CargoType {
|
||||
double customDutyFee;
|
||||
double calRate;
|
||||
double calWeight;
|
||||
int displayIndex;
|
||||
bool isDefault;
|
||||
|
||||
double get calAmount => calRate * calWeight;
|
||||
|
||||
@@ -22,7 +24,9 @@ class CargoType {
|
||||
this.isChecked = false,
|
||||
this.qty = 0,
|
||||
this.isCutomDuty = false,
|
||||
this.customDutyFee = 0});
|
||||
this.customDutyFee = 0,
|
||||
this.displayIndex = 0,
|
||||
this.isDefault = false});
|
||||
|
||||
factory CargoType.fromMap(Map<String, dynamic> map, String id) {
|
||||
return CargoType(
|
||||
@@ -33,8 +37,21 @@ class CargoType {
|
||||
calWeight: map['cal_weight']?.toDouble() ?? 0,
|
||||
calRate: map['cal_rate']?.toDouble() ?? 0,
|
||||
isCutomDuty: map['custom_duty'] ?? false,
|
||||
customDutyFee: (map['custom_duty_fee'] ?? 0).toDouble());
|
||||
//qty: (map['qty'] ?? 0).toInt());
|
||||
customDutyFee: (map['custom_duty_fee'] ?? 0).toDouble(),
|
||||
displayIndex: map['display_index'] ?? 0,
|
||||
isDefault: map['is_defalut'] ?? false);
|
||||
}
|
||||
|
||||
factory CargoType.fromMapForCargo(Map<String, dynamic> map, String id) {
|
||||
return CargoType(
|
||||
id: id, name: map['name'], weight: map['weight']?.toDouble() ?? 0);
|
||||
}
|
||||
|
||||
factory CargoType.fromMapForsurcharge(Map<String, dynamic> map, String id) {
|
||||
return CargoType(
|
||||
id: id,
|
||||
name: map['name'],
|
||||
qty: map['qty'] == null ? 0 : int.tryParse(map['qty'].toString()) ?? 0);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
@@ -47,10 +64,20 @@ class CargoType {
|
||||
'cal_rate': calRate,
|
||||
'custom_duty': isCutomDuty,
|
||||
'custom_duty_fee': customDutyFee,
|
||||
'qty': qty
|
||||
'qty': qty,
|
||||
'is_defalut': isDefault,
|
||||
'display_index': displayIndex
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMapForCargo() {
|
||||
return {"id": id, 'weight': weight};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMapForSurcharge() {
|
||||
return {"id": id, 'qty': qty};
|
||||
}
|
||||
|
||||
CargoType clone() {
|
||||
return CargoType.fromMap(toMap(), this.id!);
|
||||
}
|
||||
|
||||
@@ -10,33 +10,34 @@ import 'package.dart';
|
||||
|
||||
class Carton {
|
||||
String? id;
|
||||
String? shipmentID;
|
||||
String? shipmentNumber;
|
||||
String? cartonNumber;
|
||||
String? fcsShipmentID;
|
||||
String? fcsShipmentNumber;
|
||||
|
||||
String? senderID;
|
||||
String? senderFCSID;
|
||||
String? senderName;
|
||||
|
||||
String? boxNumber;
|
||||
String? status;
|
||||
String? cargoDesc;
|
||||
String? desc;
|
||||
String? consigneeFCSID;
|
||||
String? consigneeName;
|
||||
String? consigneeID;
|
||||
|
||||
double width;
|
||||
double height;
|
||||
double length;
|
||||
|
||||
String? status;
|
||||
String? cargoDesc;
|
||||
String? desc;
|
||||
|
||||
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;
|
||||
String? deliveryType;
|
||||
|
||||
String? lastMile;
|
||||
String? cartonSizeType;
|
||||
|
||||
double cartonWeight;
|
||||
@@ -50,19 +51,18 @@ class Carton {
|
||||
List<String> photoUrls;
|
||||
String? remark;
|
||||
DateTime? arrivedDate;
|
||||
String? cartonNumber;
|
||||
|
||||
List<String> packageIDs;
|
||||
List<Package> packages;
|
||||
List<CargoType> cargoTypes = [];
|
||||
List<CargoType> surchareItems = [];
|
||||
|
||||
DeliveryAddress? deliveryAddress;
|
||||
Shipment? shipment;
|
||||
|
||||
//for mix box
|
||||
String? mixBoxType;
|
||||
List<Carton> mixCartons;
|
||||
List<String> mixCartonIDs;
|
||||
//for mix carton
|
||||
List<Carton> cartons;
|
||||
List<String> cartonIDs;
|
||||
|
||||
int get amount => (rate * weight);
|
||||
|
||||
@@ -123,12 +123,9 @@ class Carton {
|
||||
|
||||
Carton(
|
||||
{this.id,
|
||||
this.shipmentID,
|
||||
this.shipmentNumber,
|
||||
this.senderID,
|
||||
this.senderFCSID,
|
||||
this.senderName,
|
||||
this.boxNumber,
|
||||
this.desc,
|
||||
this.width = 0,
|
||||
this.height = 0,
|
||||
@@ -136,9 +133,9 @@ class Carton {
|
||||
this.shipmentWeight,
|
||||
this.isChecked = false,
|
||||
this.cartonType,
|
||||
this.fcsID,
|
||||
this.userID,
|
||||
this.userName,
|
||||
this.consigneeFCSID,
|
||||
this.consigneeID,
|
||||
this.consigneeName,
|
||||
this.rate = 0,
|
||||
this.weight = 0,
|
||||
this.packageType,
|
||||
@@ -150,47 +147,60 @@ class Carton {
|
||||
this.shipmentHistory = const [],
|
||||
this.packages = const [],
|
||||
this.cargoTypes = const [],
|
||||
this.surchareItems = const [],
|
||||
this.cartonNumber,
|
||||
this.billTo,
|
||||
this.fcsShipmentID,
|
||||
this.fcsShipmentNumber,
|
||||
this.packageIDs = const [],
|
||||
this.mixCartonID,
|
||||
this.mixCartonNumber,
|
||||
this.isShipmentCarton = false,
|
||||
this.deliveryAddress,
|
||||
this.cartonSizeID,
|
||||
this.cartonSizeName,
|
||||
this.cartonSizeType,
|
||||
this.deliveryType,
|
||||
this.mixBoxType,
|
||||
this.mixCartons = const [],
|
||||
this.mixCartonIDs = const [],
|
||||
this.lastMile,
|
||||
this.cartons = const [],
|
||||
this.cartonIDs = const [],
|
||||
this.cartonWeight = 0,
|
||||
this.photoUrls = const [],
|
||||
this.isSelected = false});
|
||||
|
||||
Map<String, dynamic> 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();
|
||||
var _types = cargoTypes.where((t) => t.weight != 0).toList();
|
||||
var _cargoTypes = _types.map((c) => c.toMapForCargo()).toList();
|
||||
|
||||
var _packagesIds = packages.map((c) => c.id).toList();
|
||||
|
||||
var _surchareItems =
|
||||
surchareItems.map((c) => c.toMapForSurcharge()).toList();
|
||||
|
||||
return {
|
||||
'id': id,
|
||||
'carton_type': cartonType,
|
||||
'fcs_shipment_id': fcsShipmentID,
|
||||
'user_id': userID,
|
||||
'cargo_types': _cargoTypes,
|
||||
'packages': _packages,
|
||||
'sender_user_id': senderID,
|
||||
'consignee_user_id': consigneeID,
|
||||
'bill_to': billTo,
|
||||
'last_mile': lastMile,
|
||||
'length': length,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'delivery_address': deliveryAddress?.toMap(),
|
||||
'package_ids': _packagesIds,
|
||||
'cargo_types': _cargoTypes,
|
||||
'surcharge_items': _surchareItems,
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMapForMix() {
|
||||
var _cartonIds = cartons.map((c) => c.id).toList();
|
||||
|
||||
return {
|
||||
'id': id,
|
||||
'carton_type': cartonType,
|
||||
'mix_carton_id': mixCartonID,
|
||||
'mix_box_type': mixBoxType,
|
||||
'mix_cartons': _mixCartons,
|
||||
'sender_id': senderID,
|
||||
'sender_fcs_id': senderFCSID,
|
||||
'sender_name': senderName
|
||||
'fcs_shipment_id': fcsShipmentID,
|
||||
'length': length,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'carton_ids': _cartonIds,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -199,75 +209,48 @@ class Carton {
|
||||
map['arrived_date'] == null ? null : (map['arrived_date'] as Timestamp);
|
||||
var da = map['delivery_address'];
|
||||
var _da = da != null ? DeliveryAddress.fromMap(da, da["id"]) : null;
|
||||
|
||||
var cargoTypesMaps =
|
||||
List<Map<String, dynamic>>.from(map['cargo_types'] ?? []);
|
||||
var cargoTypes =
|
||||
cargoTypesMaps.map((e) => CargoType.fromMap(e, e["id"])).toList();
|
||||
var mixCartonsMaps =
|
||||
List<Map<String, dynamic>>.from(map['mix_cartons'] ?? []);
|
||||
var _mixCartons =
|
||||
mixCartonsMaps.map((e) => Carton.fromMap(e, e["id"])).toList();
|
||||
var cargoTypes = cargoTypesMaps
|
||||
.map((e) => CargoType.fromMapForCargo(e, e["id"]))
|
||||
.toList();
|
||||
|
||||
var surchargeItemMaps =
|
||||
List<Map<String, dynamic>>.from(map['surcharge_items'] ?? []);
|
||||
var surchageItems = surchargeItemMaps
|
||||
.map((e) => CargoType.fromMapForsurcharge(e, e["id"]))
|
||||
.toList();
|
||||
|
||||
List<String> _photoUrls =
|
||||
map['photo_urls'] == null ? [] : List.from(map['photo_urls']);
|
||||
|
||||
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<String>.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<String>.from(map['mix_carton_ids'] ?? []),
|
||||
cartonWeight: (map['carton_weight'] ?? 0).toDouble(),
|
||||
photoUrls: _photoUrls,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> 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,
|
||||
"photo_urls": photoUrls
|
||||
};
|
||||
id: docID,
|
||||
arrivedDate: _arrivedDate != null ? _arrivedDate.toDate() : null,
|
||||
length: double.tryParse(map['length'].toString()) ?? 0,
|
||||
width: double.tryParse(map['width'].toString()) ?? 0,
|
||||
height: double.tryParse(map['height'].toString()) ?? 0,
|
||||
cartonType: map['carton_type'],
|
||||
cartonNumber: map['carton_number'],
|
||||
fcsShipmentID: map['fcs_shipment_id'],
|
||||
fcsShipmentNumber: map['fcs_shipment_number'],
|
||||
status: map['status'],
|
||||
packageIDs: List<String>.from(map['package_ids'] ?? []),
|
||||
deliveryAddress: _da,
|
||||
cargoTypes: cargoTypes,
|
||||
surchareItems: surchageItems,
|
||||
senderID: map['sender_user_id'],
|
||||
senderFCSID: map['sender_fcs_id'],
|
||||
senderName: map['sender_user_name'],
|
||||
consigneeID: map['consignee_user_id'],
|
||||
consigneeName: map['consignee_user_name'],
|
||||
consigneeFCSID: map['consignee_fcs_id'],
|
||||
cartonIDs: List<String>.from(map['carton_ids'] ?? []),
|
||||
cartonWeight: (map['carton_weight'] ?? 0).toDouble(),
|
||||
photoUrls: _photoUrls,
|
||||
billTo: map['bill_to'] ?? '',
|
||||
lastMile: map['last_mile'] ?? "");
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -4,13 +4,16 @@ class FcsShipment {
|
||||
String? id;
|
||||
String? shipmentNumber;
|
||||
DateTime? cutoffDate;
|
||||
DateTime? etaDate;
|
||||
String? shipmentTypeId;
|
||||
String? shipTypeName;
|
||||
DateTime? arrivalDate;
|
||||
String? shipmentTypeName;
|
||||
DateTime? departureDate;
|
||||
String? consignee;
|
||||
String? port;
|
||||
String? destination;
|
||||
String? consigneeId;
|
||||
String? consigneeName;
|
||||
String? loadingPortId;
|
||||
String? loadingPortName;
|
||||
String? destinationPortId;
|
||||
String? destinationPortName;
|
||||
String? status;
|
||||
String? reportName;
|
||||
|
||||
@@ -19,13 +22,16 @@ class FcsShipment {
|
||||
this.shipmentNumber,
|
||||
this.cutoffDate,
|
||||
this.shipmentTypeId,
|
||||
this.shipTypeName,
|
||||
this.shipmentTypeName,
|
||||
this.status,
|
||||
this.arrivalDate,
|
||||
this.etaDate,
|
||||
this.departureDate,
|
||||
this.consignee,
|
||||
this.port,
|
||||
this.destination,
|
||||
this.consigneeId,
|
||||
this.consigneeName,
|
||||
this.loadingPortId,
|
||||
this.loadingPortName,
|
||||
this.destinationPortId,
|
||||
this.destinationPortName,
|
||||
this.reportName,
|
||||
});
|
||||
|
||||
@@ -33,45 +39,45 @@ class FcsShipment {
|
||||
var _cutoffDate =
|
||||
map['cutoff_date'] == null ? null : (map['cutoff_date'] as Timestamp);
|
||||
var _arrivalDate =
|
||||
map['arrival_date'] == null ? null : (map['arrival_date'] as Timestamp);
|
||||
map['eta_date'] == null ? null : (map['eta_date'] as Timestamp);
|
||||
|
||||
return FcsShipment(
|
||||
id: docID,
|
||||
cutoffDate: _cutoffDate != null ? _cutoffDate.toDate() : null,
|
||||
arrivalDate: _arrivalDate != null ? _arrivalDate.toDate() : null,
|
||||
shipmentNumber: map['shipment_number'],
|
||||
shipTypeName: map['shipment_type_name'],
|
||||
shipmentTypeId: map['shipment_type_id'] ?? "",
|
||||
status: map['status'],
|
||||
consignee: map['consignee'],
|
||||
port: map['port'],
|
||||
destination: map['destination'],
|
||||
);
|
||||
id: docID,
|
||||
cutoffDate: _cutoffDate != null ? _cutoffDate.toDate() : null,
|
||||
etaDate: _arrivalDate != null ? _arrivalDate.toDate() : null,
|
||||
shipmentNumber: map['shipment_number'],
|
||||
shipmentTypeId: map['shipment_type_id'] ?? "",
|
||||
shipmentTypeName: map['shipment_type_name'],
|
||||
status: map['status'],
|
||||
consigneeId: map['shipment_consignee_id'],
|
||||
consigneeName: map['shipment_consignee_name'],
|
||||
loadingPortId: map['loading_port_id'],
|
||||
loadingPortName: map['loading_port_name'],
|
||||
destinationPortId: map['destination_port_id'],
|
||||
destinationPortName: map['destination_port_name']);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'shipment_number': shipmentNumber,
|
||||
'shipment_type_id': shipmentTypeId,
|
||||
'cutoff_date': cutoffDate?.toUtc().toIso8601String(),
|
||||
'arrival_date': arrivalDate?.toUtc().toIso8601String(),
|
||||
'consignee': consignee,
|
||||
'port': port,
|
||||
'destination': destination,
|
||||
// 'status': status,
|
||||
// 'report_name': reportName,
|
||||
'eta_date': etaDate?.toUtc().toIso8601String(),
|
||||
'shipment_type_id': shipmentTypeId,
|
||||
'shipment_consignee_id': consigneeId,
|
||||
'loading_port_id': loadingPortId,
|
||||
'destination_port_id': destinationPortId
|
||||
};
|
||||
}
|
||||
|
||||
bool isChangedForEdit(FcsShipment fcsShipment) {
|
||||
return fcsShipment.shipmentNumber != this.shipmentNumber ||
|
||||
fcsShipment.cutoffDate != this.cutoffDate ||
|
||||
fcsShipment.arrivalDate != this.arrivalDate ||
|
||||
fcsShipment.etaDate != this.etaDate ||
|
||||
fcsShipment.shipmentTypeId != this.shipmentTypeId ||
|
||||
fcsShipment.consignee != this.consignee ||
|
||||
fcsShipment.port != this.port ||
|
||||
fcsShipment.destination != this.destination;
|
||||
fcsShipment.consigneeId != this.consigneeId ||
|
||||
fcsShipment.loadingPortId != this.loadingPortId ||
|
||||
fcsShipment.destinationPortId != this.destinationPortId;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
17
lib/domain/entities/shipment_consignee.dart
Normal file
17
lib/domain/entities/shipment_consignee.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
class ShipmentConsignee {
|
||||
String id;
|
||||
String name;
|
||||
|
||||
ShipmentConsignee({required this.id, required this.name});
|
||||
|
||||
factory ShipmentConsignee.fromMap(Map<String, dynamic> map, String id) {
|
||||
return ShipmentConsignee(id: id, name: map['name'] ?? "");
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is ShipmentConsignee && other.id == id;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
17
lib/domain/entities/shipment_port.dart
Normal file
17
lib/domain/entities/shipment_port.dart
Normal file
@@ -0,0 +1,17 @@
|
||||
class ShipmentPort {
|
||||
String id;
|
||||
String name;
|
||||
|
||||
ShipmentPort({required this.id, required this.name});
|
||||
|
||||
factory ShipmentPort.fromMap(Map<String, dynamic> map, String id) {
|
||||
return ShipmentPort(id: id, name: map['name'] ?? "");
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
other is ShipmentPort && other.id == id;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
@@ -7,4 +7,10 @@ class ShipmentType {
|
||||
factory ShipmentType.fromMap(Map<String, dynamic> map, String id) {
|
||||
return ShipmentType(id: id, name: map['name'] ?? "");
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => other is ShipmentType && other.id == id;
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class LocalPopupMenu {
|
||||
List<LocalPopupMenu> shipFiteringMenu = <LocalPopupMenu>[
|
||||
LocalPopupMenu(id: 0, text :"All"),
|
||||
LocalPopupMenu(id: 1, text: "Pending"),
|
||||
LocalPopupMenu(id: 2, text: "Processing"),
|
||||
LocalPopupMenu(id: 2, text: "Processed"),
|
||||
LocalPopupMenu(id: 3, text: "Shipped"),
|
||||
LocalPopupMenu(id: 4, text: "Arrived"),
|
||||
LocalPopupMenu(id: 5, text: "Invoiced"),
|
||||
|
||||
@@ -51,7 +51,7 @@ Future<dynamic> requestAPI(String path, method,
|
||||
});
|
||||
|
||||
String curlPath =
|
||||
"curl -X $method ${list.join("")}${payload != null ? '-d $payload ' : ''}${options.baseUrl}$path";
|
||||
"curl -X $method ${list.join("")}${payload != null ? '-d \'${jsonEncode(payload)}\' ' : ''}${options.baseUrl}$path";
|
||||
|
||||
log.log(curlPath);
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ Future<void> generateCartonPdf(Carton carton) async {
|
||||
style: pw.TextStyle(
|
||||
fontSize: 12,
|
||||
)),
|
||||
pw.Text(carton.userName!,
|
||||
pw.Text(carton.consigneeName!,
|
||||
style: pw.TextStyle(
|
||||
fontSize: 10,
|
||||
)),
|
||||
|
||||
@@ -19,7 +19,8 @@ Future<void> main() async {
|
||||
Config(
|
||||
flavor: Flavor.DEV,
|
||||
color: Colors.blue,
|
||||
apiURL: "https://asia-northeast1-fcs-dev1.cloudfunctions.net/API13",
|
||||
apiURL:"http://192.168.100.150:9090",
|
||||
// apiURL: "https://asia-northeast1-fcs-dev1.cloudfunctions.net/API13",
|
||||
reportURL: "http://petrok.mokkon.com:7071",
|
||||
reportProjectID: "fcs-dev",
|
||||
bucketName: "gs://fcs-dev1-us",
|
||||
|
||||
114
lib/pages/carton/cargo_type_addition.dart
Normal file
114
lib/pages/carton/cargo_type_addition.dart
Normal file
@@ -0,0 +1,114 @@
|
||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../main/util.dart';
|
||||
|
||||
class CargoTypeAddition extends StatefulWidget {
|
||||
final List<CargoType> cargoTypes;
|
||||
const CargoTypeAddition({super.key, required this.cargoTypes});
|
||||
@override
|
||||
_CargoTypeAdditionState createState() => _CargoTypeAdditionState();
|
||||
}
|
||||
|
||||
class _CargoTypeAdditionState extends State<CargoTypeAddition> {
|
||||
bool _isLoading = false;
|
||||
List<CargoType> cargoTypes = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_init();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
_init() {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
cargoTypes =
|
||||
shipmentRateModel.rate.cargoTypes.map((e) => e.clone()).toList();
|
||||
|
||||
for (var p in cargoTypes) {
|
||||
p.qty = 0;
|
||||
if (widget.cargoTypes.any((e) => e.id == p.id)) {
|
||||
p.isChecked = true;
|
||||
} else {
|
||||
p.isChecked = false;
|
||||
}
|
||||
|
||||
widget.cargoTypes.forEach((vp) {
|
||||
if (p.id == vp.id) {
|
||||
p.qty = vp.qty;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
_onTap(CargoType cargo) {
|
||||
if (cargo.isChecked) {
|
||||
showMsgDialog(context, "Error", "Already exit!");
|
||||
return;
|
||||
}
|
||||
Navigator.pop(context, cargo);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> getCargoRowList(List<CargoType> _c) {
|
||||
return _c.map((c) {
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
_onTap(c);
|
||||
},
|
||||
title: new Text(c.name ?? '', style: textStyle),
|
||||
trailing: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: primaryColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
minimumSize: Size(80, 35)),
|
||||
onPressed: c.isChecked
|
||||
? null
|
||||
: () {
|
||||
_onTap(c);
|
||||
},
|
||||
child: Text(
|
||||
"Add",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
),
|
||||
));
|
||||
}).toList();
|
||||
}
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
labelKey: 'box.add.cargo_type',
|
||||
backgroundColor: Colors.white,
|
||||
labelColor: primaryColor,
|
||||
arrowColor: primaryColor),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
children: getCargoRowList(cargoTypes),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,8 @@ import '../widgets/continue_button.dart';
|
||||
import '../widgets/display_text.dart';
|
||||
import '../widgets/local_title.dart';
|
||||
import '../widgets/previous_button.dart';
|
||||
import 'custom_duty_addition.dart';
|
||||
import 'cargo_type_addition.dart';
|
||||
import 'surcharge_item_addition.dart';
|
||||
|
||||
typedef OnPrevious = Function(
|
||||
List<CargoType> cargoTypes, List<CargoType> customDuties);
|
||||
@@ -56,28 +57,20 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
|
||||
_init() {
|
||||
// for cargo types
|
||||
var model = context.read<ShipmentRateModel>();
|
||||
_cargoTypes = model.rate.cargoTypes.map((e) => e.clone()).toList();
|
||||
|
||||
if (widget.cargoTypes.isNotEmpty) {
|
||||
_cargoTypes.forEach((mp) {
|
||||
mp.weight = 0;
|
||||
widget.cargoTypes.forEach((vp) {
|
||||
if (mp.id == vp.id) {
|
||||
mp.weight = vp.weight;
|
||||
}
|
||||
});
|
||||
});
|
||||
_cargoTypes = List.from(widget.cargoTypes);
|
||||
_cargoTypes.forEach((e) {
|
||||
var editor = new TextEditingController();
|
||||
editor.text = removeTrailingZeros(e.weight);
|
||||
editor.addListener(inputChangeListener);
|
||||
_cargoTypeControllers.add(editor);
|
||||
});
|
||||
|
||||
double total = _cargoTypes.fold(0, (sum, value) => sum + value.weight);
|
||||
_totalCtl.text = removeTrailingZeros(total);
|
||||
_calculateTotalWeght();
|
||||
} else {
|
||||
var model = context.read<ShipmentRateModel>();
|
||||
var cargoes = model.rate.cargoTypes.map((e) => e.clone()).toList();
|
||||
|
||||
_cargoTypes = cargoes.where((e) => e.isDefault).toList();
|
||||
_cargoTypes.forEach((e) {
|
||||
var editor = new TextEditingController();
|
||||
editor.text = '';
|
||||
@@ -103,6 +96,11 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
_calculateTotalWeght() {
|
||||
double total = _cargoTypes.fold(0, (sum, value) => sum + value.weight);
|
||||
_totalCtl.text = removeTrailingZeros(total);
|
||||
}
|
||||
|
||||
bool isFieldEmpty(int index) {
|
||||
return _cargoTypeControllers[index].text.isEmpty;
|
||||
}
|
||||
@@ -158,6 +156,39 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
],
|
||||
);
|
||||
|
||||
final cargoTitle = LocalTitle(
|
||||
textKey: "box.input_cargo_weight",
|
||||
topPadding: 0,
|
||||
trailing: IconButton(
|
||||
icon: Icon(
|
||||
Icons.add_circle,
|
||||
color: primaryColor,
|
||||
),
|
||||
onPressed: () async {
|
||||
CargoType? cargoType = await Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
CargoTypeAddition(cargoTypes: _cargoTypes)));
|
||||
if (cargoType == null) return;
|
||||
_cargoTypes.add(cargoType);
|
||||
|
||||
_cargoTypeControllers.clear();
|
||||
|
||||
_cargoTypes.forEach((e) {
|
||||
var editor = new TextEditingController();
|
||||
editor.text = removeTrailingZeros(e.weight);
|
||||
editor.addListener(inputChangeListener);
|
||||
_cargoTypeControllers.add(editor);
|
||||
});
|
||||
|
||||
_calculateTotalWeght();
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
final cargosBox = Wrap(
|
||||
alignment: WrapAlignment.spaceBetween,
|
||||
runSpacing: 15,
|
||||
@@ -171,6 +202,8 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
InkResponse(
|
||||
radius: 25,
|
||||
onTap: () {
|
||||
_cargoTypes.removeAt(key);
|
||||
|
||||
double totalWeight = double.tryParse(_totalCtl.text) ?? 0;
|
||||
double removeWeight =
|
||||
(double.tryParse(_cargoTypeControllers[key].text) ??
|
||||
@@ -182,11 +215,12 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
}
|
||||
|
||||
_cargoTypeControllers[key].clear();
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
child: Icon(MaterialIcons.clear, color: labelColor)),
|
||||
child: Icon(Feather.minus_circle, color: labelColor)),
|
||||
const SizedBox(width: 10),
|
||||
Flexible(
|
||||
child: inputTextFieldWidget(context,
|
||||
@@ -254,14 +288,14 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
color: primaryColor,
|
||||
),
|
||||
onPressed: () async {
|
||||
List<CargoType>? customList = await Navigator.push<List<CargoType>>(
|
||||
CargoType? surchargeItem = await Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
CustomDutyAddition(customDuties: _surchareItems)));
|
||||
if (customList == null) return;
|
||||
SurchargeItemAddition(items: _surchareItems)));
|
||||
if (surchargeItem == null) return;
|
||||
|
||||
_surchareItems = List.from(customList);
|
||||
_surchareItems.add(surchargeItem);
|
||||
|
||||
_surchargeControllers.clear();
|
||||
_surchareItems.asMap().entries.forEach((e) {
|
||||
@@ -315,10 +349,11 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
final continueBtn = ContinueButton(
|
||||
onTap: () {
|
||||
if (widget.onContinue != null) {
|
||||
|
||||
if(_surchareItems.isNotEmpty && _surchareItems.any((item)=> item.qty == 0)){
|
||||
showMsgDialog(context, "Error", "Please insert surcharge item quantity");
|
||||
return;
|
||||
if (_surchareItems.isNotEmpty &&
|
||||
_surchareItems.any((item) => item.qty == 0)) {
|
||||
showMsgDialog(
|
||||
context, "Error", "Please insert surcharge item quantity");
|
||||
return;
|
||||
}
|
||||
|
||||
widget.onContinue!(_cargoTypes, _surchareItems);
|
||||
@@ -341,7 +376,7 @@ class _CargoWidgetState extends State<CargoWidget> {
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
userRow,
|
||||
LocalTitle(textKey: "box.input_cargo_weight", topPadding: 5),
|
||||
cargoTitle,
|
||||
cargosBox,
|
||||
const SizedBox(height: 15),
|
||||
Divider(),
|
||||
|
||||
@@ -56,7 +56,9 @@ class _CartonEditorState extends State<CartonEditor> {
|
||||
_isNew = false;
|
||||
|
||||
_consignee = User(
|
||||
id: _carton!.userID, fcsID: _carton!.fcsID, name: _carton!.userName);
|
||||
id: _carton!.consigneeID,
|
||||
fcsID: _carton!.consigneeFCSID,
|
||||
name: _carton!.consigneeName);
|
||||
_sender = User(
|
||||
id: _carton!.senderID,
|
||||
fcsID: _carton!.senderFCSID,
|
||||
@@ -129,7 +131,7 @@ class _CartonEditorState extends State<CartonEditor> {
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: InkResponse(
|
||||
radius: 30,
|
||||
onTap: () {
|
||||
onTap: () async {
|
||||
//for packages
|
||||
if (isFromPackages) {
|
||||
if (_sender == null) {
|
||||
@@ -149,20 +151,32 @@ class _CartonEditorState extends State<CartonEditor> {
|
||||
return;
|
||||
}
|
||||
|
||||
Navigator.push(
|
||||
Carton? carton = await Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => CartonPackageForm(
|
||||
sender: _sender!,
|
||||
consignee: _consignee!,
|
||||
)));
|
||||
|
||||
if (carton != null) {
|
||||
setState(() {
|
||||
_cartons.add(carton);
|
||||
});
|
||||
}
|
||||
}
|
||||
// for mix cartion
|
||||
else {
|
||||
Navigator.push(
|
||||
Carton? carton = await Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => const MixCartonForm()));
|
||||
|
||||
if (carton != null) {
|
||||
setState(() {
|
||||
_cartons.add(carton);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Icon(Icons.add_circle, color: primaryColor),
|
||||
|
||||
@@ -18,6 +18,7 @@ import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../domain/entities/carton_size.dart';
|
||||
import '../carton_size/model/carton_size_model.dart';
|
||||
import '../widgets/local_button.dart';
|
||||
import 'carton_package_editor.dart';
|
||||
import 'mix_carton/mix_carton_editor.dart';
|
||||
@@ -56,27 +57,41 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
_init() async {
|
||||
try {
|
||||
_isLoading = true;
|
||||
_carton.cartonType = carton_from_packages;
|
||||
_carton.billTo = billToConsignee;
|
||||
_carton.cartonSizeType = customCarton;
|
||||
_multiImgController.setImageUrls = _carton.photoUrls;
|
||||
_cargoTypes = _carton.cargoTypes.where((e) => !e.isCutomDuty).toList();
|
||||
_surchareItems = _carton.cargoTypes.where((e) => e.isCutomDuty).toList();
|
||||
_cargoTypes = _carton.cargoTypes;
|
||||
_surchareItems = _carton.surchareItems;
|
||||
|
||||
// check carton size type
|
||||
List<CartonSize> cartonSizes =
|
||||
context.read<CartonSizeModel>().cartonSizes;
|
||||
var sameLength = cartonSizes.any((size) => size.length == _carton.length);
|
||||
var sameWidth = cartonSizes.any((size) => size.width == _carton.width);
|
||||
var sameHeight = cartonSizes.any((size) => size.height == _carton.height);
|
||||
bool isStandartSize = sameLength && sameWidth && sameHeight;
|
||||
if (isStandartSize) {
|
||||
_carton.cartonSizeType = standardCarton;
|
||||
standardSize = cartonSizes.firstWhere((size) =>
|
||||
size.length == _carton.length &&
|
||||
size.width == _carton.width &&
|
||||
size.height == _carton.height);
|
||||
} else if (_carton.length == 0 &&
|
||||
_carton.width == 0 &&
|
||||
_carton.height == 0) {
|
||||
_carton.cartonSizeType = packageCarton;
|
||||
} else {
|
||||
_carton.cartonSizeType = customCarton;
|
||||
}
|
||||
|
||||
if (_carton.cartonType == carton_from_packages) {
|
||||
_carton.deliveryType = delivery_caton;
|
||||
_packages = await context
|
||||
.read<PackageModel>()
|
||||
.getPackagesByIds(_carton.packageIDs);
|
||||
}
|
||||
|
||||
if (_carton.cartonType == carton_mix_carton) {
|
||||
if (_carton.cartonType == mix_carton) {
|
||||
_mixCartons = await context
|
||||
.read<CartonModel>()
|
||||
.getCartonsByIds(_carton.mixCartonIDs);
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
.getCartonsByIds(_carton.cartonIDs);
|
||||
}
|
||||
|
||||
totalWeight =
|
||||
@@ -86,17 +101,23 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String? boxDimension = _carton.cartonSizeType == standardCarton
|
||||
var fromPackage = _carton.cartonType == carton_from_packages;
|
||||
|
||||
String? boxDimension = _carton.cartonSizeType == standardCarton
|
||||
? "${standardSize?.name} - ${standardSize?.length.toInt()}”x${standardSize?.width.toInt()}”x${standardSize?.height.toInt()}”"
|
||||
: _carton.cartonSizeType == customCarton
|
||||
? "${_carton.length.toInt()}”x${_carton.width.toInt()}”x${_carton.height.toInt()}”"
|
||||
: null;
|
||||
|
||||
final cartonTypeBox = DisplayText(
|
||||
final cartonNumberBox = DisplayText(
|
||||
text: _carton.cartonNumber,
|
||||
labelTextKey: "box.number",
|
||||
);
|
||||
@@ -111,10 +132,12 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
},
|
||||
icon: Icon(AntDesign.qrcode, color: Colors.black));
|
||||
|
||||
final cartonSubTypeBox = DisplayText(
|
||||
final cartonTypeBox = DisplayText(
|
||||
text: _carton.cartonType == carton_from_packages
|
||||
? "For packages"
|
||||
: "Mix carton",
|
||||
: _carton.cartonType == mix_carton
|
||||
? carton_mix_carton
|
||||
: '',
|
||||
labelTextKey: "box.carton.type",
|
||||
);
|
||||
|
||||
@@ -132,13 +155,13 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
labelTextKey: "box.fcs_shipment_num",
|
||||
);
|
||||
|
||||
final deliveryBox = DisplayText(
|
||||
text: _carton.deliveryType,
|
||||
final lastMileBox = DisplayText(
|
||||
text: _carton.lastMile == delivery_caton ? 'Delivery' : 'Pick-up',
|
||||
labelTextKey: "box.delivery_type",
|
||||
);
|
||||
|
||||
final cartonSizeBox = DisplayText(
|
||||
subText: boxDimension == null ? null : Text("$boxDimension"),
|
||||
subText: Text("${boxDimension ?? 'No defined size'}"),
|
||||
labelTextKey: "box.carton_size",
|
||||
);
|
||||
|
||||
@@ -149,8 +172,8 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
);
|
||||
|
||||
final consigneeNameBox = DisplayText(
|
||||
text: _carton.userName != null ? _carton.userName : "",
|
||||
subText: Text(_carton.fcsID ?? "", style: textStyle),
|
||||
text: _carton.consigneeName != null ? _carton.consigneeName : "",
|
||||
subText: Text(_carton.consigneeFCSID ?? "", style: textStyle),
|
||||
labelTextKey: "processing.consignee.name",
|
||||
);
|
||||
|
||||
@@ -367,30 +390,29 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
padding: const EdgeInsets.only(left: 20, right: 20),
|
||||
child: ListView(children: <Widget>[
|
||||
Row(children: [
|
||||
Flexible(child: cartonTypeBox,flex: 1),
|
||||
Flexible(child: cartonNumberBox, flex: 1),
|
||||
Flexible(
|
||||
child: cartonQrBox,
|
||||
),
|
||||
|
||||
]),
|
||||
Row(
|
||||
children: [
|
||||
Flexible(child: cartonSubTypeBox),
|
||||
Flexible(child: cartonTypeBox),
|
||||
],
|
||||
),
|
||||
_mixCartons.isEmpty ? userRowBox : const SizedBox(),
|
||||
fromPackage ? userRowBox : const SizedBox(),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(child: billInfoBox),
|
||||
fromPackage ? Flexible(child: billInfoBox) : SizedBox(),
|
||||
Flexible(child: shipmentBox),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_mixCartons.isEmpty
|
||||
? Flexible(child: deliveryBox)
|
||||
fromPackage
|
||||
? Flexible(child: lastMileBox)
|
||||
: const SizedBox(),
|
||||
Flexible(child: cartonSizeBox),
|
||||
],
|
||||
@@ -430,7 +452,9 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
uploadImageBtn,
|
||||
const SizedBox(height: 30),
|
||||
img,
|
||||
const SizedBox(height: 40),
|
||||
_carton.photoUrls.isNotEmpty
|
||||
? const SizedBox(height: 40)
|
||||
: const SizedBox(),
|
||||
deleteBtn,
|
||||
const SizedBox(height: 20)
|
||||
]))));
|
||||
@@ -457,17 +481,22 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
}
|
||||
|
||||
_gotoEditor() async {
|
||||
bool? updated = _carton.cartonType == carton_mix_carton
|
||||
? await Navigator.push<bool>(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => MixCartonEditor(carton: _carton)),
|
||||
)
|
||||
: await Navigator.push<bool>(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => CartonPackageEditor(carton: _carton)),
|
||||
);
|
||||
bool? updated = false;
|
||||
if (_carton.cartonType == mix_carton) {
|
||||
updated = await Navigator.push<bool>(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => MixCartonEditor(carton: _carton)),
|
||||
);
|
||||
}
|
||||
|
||||
if (_carton.cartonType == carton_from_packages) {
|
||||
updated = await Navigator.push<bool>(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => CartonPackageEditor(carton: _carton)),
|
||||
);
|
||||
}
|
||||
|
||||
if (updated ?? false) {
|
||||
Carton? c =
|
||||
@@ -489,9 +518,8 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
// var cartonModel = Provider.of<CartonModel>(context, listen: false);
|
||||
// await cartonModel.deleteCarton(widget.carton);
|
||||
// Navigator.pop(context, true);
|
||||
await context.read<CartonModel>().deleteCarton(widget.carton);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
} finally {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:fcs/pages/carton/model/carton_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@@ -14,6 +15,7 @@ import '../../domain/entities/cargo_type.dart';
|
||||
import '../../domain/entities/carton.dart';
|
||||
import '../../domain/entities/package.dart';
|
||||
import '../../domain/entities/user.dart';
|
||||
import '../carton_size/model/carton_size_model.dart';
|
||||
import '../fcs_shipment/model/fcs_shipment_model.dart';
|
||||
import '../main/util.dart';
|
||||
import '../package/model/package_model.dart';
|
||||
@@ -53,7 +55,7 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
double _width = 0;
|
||||
double _height = 0;
|
||||
|
||||
String _selectedDeliveryType = delivery_caton;
|
||||
String _selectedLastMile = delivery_caton;
|
||||
String _billToValue = billToSender;
|
||||
|
||||
FcsShipment? _shipment;
|
||||
@@ -78,20 +80,14 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
id: widget.carton.senderID);
|
||||
|
||||
_consignee = User(
|
||||
id: widget.carton.userID,
|
||||
name: widget.carton.userName,
|
||||
fcsID: widget.carton.fcsID);
|
||||
id: widget.carton.consigneeID,
|
||||
name: widget.carton.consigneeName,
|
||||
fcsID: widget.carton.consigneeFCSID);
|
||||
|
||||
_billToValue = widget.carton.billTo ?? billToSender;
|
||||
_selectedDeliveryType = widget.carton.deliveryType ?? delivery_caton;
|
||||
_cartonSizeType = widget.carton.cartonSizeType ?? customCarton;
|
||||
_length = widget.carton.length;
|
||||
_width = widget.carton.width;
|
||||
_height = widget.carton.height;
|
||||
_cargoTypes =
|
||||
widget.carton.cargoTypes.where((e) => !e.isCutomDuty).toList();
|
||||
_surchareItems =
|
||||
widget.carton.cargoTypes.where((e) => e.isCutomDuty).toList();
|
||||
_selectedLastMile = widget.carton.lastMile ?? delivery_caton;
|
||||
_cargoTypes = widget.carton.cargoTypes;
|
||||
_surchareItems = widget.carton.surchareItems;
|
||||
|
||||
var s = await context
|
||||
.read<FcsShipmentModel>()
|
||||
@@ -102,6 +98,30 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
.read<PackageModel>()
|
||||
.getPackagesByIds(widget.carton.packageIDs);
|
||||
|
||||
// check carton size type
|
||||
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
|
||||
|
||||
var sameLength =
|
||||
cartonSizes.any((size) => size.length == widget.carton.length);
|
||||
var sameWidth =
|
||||
cartonSizes.any((size) => size.width == widget.carton.width);
|
||||
var sameHeight =
|
||||
cartonSizes.any((size) => size.height == widget.carton.height);
|
||||
bool isStandartSize = sameLength && sameWidth && sameHeight;
|
||||
if (isStandartSize) {
|
||||
_cartonSizeType = standardCarton;
|
||||
_standardSize = cartonSizes.firstWhere((size) =>
|
||||
size.length == widget.carton.length &&
|
||||
size.width == widget.carton.width &&
|
||||
size.height == widget.carton.height);
|
||||
} else if (widget.carton.length == 0 &&
|
||||
widget.carton.width == 0 &&
|
||||
widget.carton.height == 0) {
|
||||
_cartonSizeType = packageCarton;
|
||||
} else {
|
||||
_cartonSizeType = customCarton;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
@@ -143,8 +163,16 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
},
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
title: LocalText(context, 'box.update_title',
|
||||
color: primaryColor, fontSize: 20),
|
||||
title: Column(
|
||||
children: [
|
||||
LocalText(context, 'box.update_title',
|
||||
color: primaryColor, fontSize: 20),
|
||||
Text(
|
||||
widget.carton.cartonNumber ?? '',
|
||||
style: TextStyle(color: primaryColor, fontSize: 14),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
@@ -172,7 +200,7 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
if (step.stepType == StepType.SIZE) {
|
||||
return Expanded(
|
||||
child: CartonSizeWidget(
|
||||
deliveryType: _selectedDeliveryType,
|
||||
lastMile: _selectedLastMile,
|
||||
billType: _billToValue,
|
||||
sender: _sender!,
|
||||
consignee: _consignee!,
|
||||
@@ -188,7 +216,7 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
onContinue: (deliveryType, billType, shipment, cartonSizeType,
|
||||
{standardSize, length, width, height}) {
|
||||
setState(() {
|
||||
_selectedDeliveryType = deliveryType;
|
||||
_selectedLastMile = deliveryType;
|
||||
_billToValue = billType;
|
||||
_shipment = shipment;
|
||||
_cartonSizeType = cartonSizeType;
|
||||
@@ -256,7 +284,7 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
length: _length,
|
||||
width: _width,
|
||||
height: _height,
|
||||
deliveryType: _selectedDeliveryType,
|
||||
lastMile: _selectedLastMile,
|
||||
shipment: _shipment!,
|
||||
packages: _packages,
|
||||
cargoTypes: _cargoTypes,
|
||||
@@ -279,6 +307,40 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
double length = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
|
||||
if (_cartonSizeType == standardCarton) {
|
||||
if (_standardSize != null) {
|
||||
length = _standardSize!.length;
|
||||
width = _standardSize!.width;
|
||||
height = _standardSize!.height;
|
||||
}
|
||||
} else if (_cartonSizeType == customCarton) {
|
||||
length = _length;
|
||||
width = _width;
|
||||
height = _height;
|
||||
} else {
|
||||
length = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
var carton = Carton(
|
||||
cartonType: carton_from_packages,
|
||||
billTo: _billToValue,
|
||||
lastMile: _selectedLastMile,
|
||||
fcsShipmentID: _shipment?.id,
|
||||
length: length,
|
||||
width: width,
|
||||
height: height,
|
||||
packages: _packages,
|
||||
cargoTypes: _cargoTypes,
|
||||
surchareItems: _surchareItems);
|
||||
|
||||
await context.read<CartonModel>().updateCarton(carton);
|
||||
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:fcs/domain/entities/carton.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@@ -20,6 +21,7 @@ import '../widgets/step_widget.dart';
|
||||
import 'cargo_widget.dart';
|
||||
import 'carton_size_widget.dart';
|
||||
import 'carton_submit.dart';
|
||||
import 'model/carton_model.dart';
|
||||
import 'model/package_selection_model.dart';
|
||||
import 'package_selection_widget.dart';
|
||||
|
||||
@@ -55,7 +57,7 @@ class _CartonPackageFormState extends State<CartonPackageForm> {
|
||||
double _width = 0;
|
||||
double _height = 0;
|
||||
|
||||
String _selectedDeliveryType = delivery_caton;
|
||||
String _selectedLastMile = delivery_caton;
|
||||
String _billToValue = billToSender;
|
||||
|
||||
FcsShipment? _shipment;
|
||||
@@ -134,7 +136,7 @@ class _CartonPackageFormState extends State<CartonPackageForm> {
|
||||
if (step.stepType == StepType.SIZE) {
|
||||
return Expanded(
|
||||
child: CartonSizeWidget(
|
||||
deliveryType: _selectedDeliveryType,
|
||||
lastMile: _selectedLastMile,
|
||||
billType: _billToValue,
|
||||
sender: widget.sender,
|
||||
consignee: widget.consignee,
|
||||
@@ -147,10 +149,10 @@ class _CartonPackageFormState extends State<CartonPackageForm> {
|
||||
onPrevious: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onContinue: (deliveryType, billType, shipment, cartonSizeType,
|
||||
onContinue: (lastMile, billType, shipment, cartonSizeType,
|
||||
{standardSize, length, width, height}) {
|
||||
setState(() {
|
||||
_selectedDeliveryType = deliveryType;
|
||||
_selectedLastMile = lastMile;
|
||||
_billToValue = billType;
|
||||
_shipment = shipment;
|
||||
_cartonSizeType = cartonSizeType;
|
||||
@@ -217,7 +219,7 @@ class _CartonPackageFormState extends State<CartonPackageForm> {
|
||||
length: _length,
|
||||
width: _width,
|
||||
height: _height,
|
||||
deliveryType: _selectedDeliveryType,
|
||||
lastMile: _selectedLastMile,
|
||||
shipment: _shipment!,
|
||||
packages: _packages,
|
||||
cargoTypes: _cargoTypes,
|
||||
@@ -240,7 +242,41 @@ class _CartonPackageFormState extends State<CartonPackageForm> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
Navigator.pop(context, true);
|
||||
double length = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
|
||||
if (_cartonSizeType == standardCarton) {
|
||||
if (_standardSize != null) {
|
||||
length = _standardSize!.length;
|
||||
width = _standardSize!.width;
|
||||
height = _standardSize!.height;
|
||||
}
|
||||
} else if (_cartonSizeType == customCarton) {
|
||||
length = _length;
|
||||
width = _width;
|
||||
height = _height;
|
||||
} else {
|
||||
length = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
var carton = Carton(
|
||||
cartonType: carton_from_packages,
|
||||
senderID: widget.sender.id,
|
||||
consigneeID: widget.consignee.id,
|
||||
billTo: _billToValue,
|
||||
lastMile: _selectedLastMile,
|
||||
fcsShipmentID: _shipment?.id,
|
||||
length: length,
|
||||
width: width,
|
||||
height: height,
|
||||
packages: _packages,
|
||||
cargoTypes: _cargoTypes,
|
||||
surchareItems: _surchareItems);
|
||||
var c = await context.read<CartonModel>().createCarton(carton);
|
||||
Navigator.pop(context, c);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
} finally {
|
||||
|
||||
@@ -31,7 +31,7 @@ class CartonSizeWidget extends StatefulWidget {
|
||||
final OnContinue? onContinue;
|
||||
final User sender;
|
||||
final User consignee;
|
||||
final String deliveryType;
|
||||
final String lastMile;
|
||||
final String billType;
|
||||
final FcsShipment? shipment;
|
||||
final String cartonSizeType;
|
||||
@@ -52,7 +52,7 @@ class CartonSizeWidget extends StatefulWidget {
|
||||
this.height,
|
||||
required this.sender,
|
||||
required this.consignee,
|
||||
required this.deliveryType,
|
||||
required this.lastMile,
|
||||
required this.billType})
|
||||
: super(key: key);
|
||||
|
||||
@@ -68,7 +68,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
|
||||
List<FcsShipment> _shipments = [];
|
||||
CartonSize? _selectStandardSize;
|
||||
late String _selectedDeliveryType;
|
||||
late String _selectedLastmile;
|
||||
late String _billToValue;
|
||||
|
||||
TextEditingController _widthController = new TextEditingController();
|
||||
@@ -82,13 +82,10 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
}
|
||||
|
||||
_init() async {
|
||||
_selectedDeliveryType = widget.deliveryType;
|
||||
_selectedLastmile = widget.lastMile;
|
||||
_billToValue = widget.billType;
|
||||
_cartonSizeType = widget.cartonSizeType;
|
||||
|
||||
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
|
||||
_selectStandardSize = widget.standardSize ?? cartonSizes.first;
|
||||
|
||||
_lengthController.text =
|
||||
widget.length == null ? "0" : removeTrailingZeros(widget.length ?? 0);
|
||||
_widthController.text =
|
||||
@@ -96,6 +93,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
_heightController.text =
|
||||
widget.height == null ? "0" : removeTrailingZeros(widget.height ?? 0);
|
||||
|
||||
_getStandardCartonSize();
|
||||
_loadShipment();
|
||||
|
||||
if (mounted) {
|
||||
@@ -103,11 +101,24 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
_getStandardCartonSize() {
|
||||
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
|
||||
_selectStandardSize = widget.standardSize ?? cartonSizes.first;
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
_loadShipment() async {
|
||||
var fcsShipments =
|
||||
await context.read<FcsShipmentModel>().getActiveFcsShipments();
|
||||
_shipments = fcsShipments;
|
||||
_shipment = widget.shipment;
|
||||
if (_shipments.contains(widget.shipment)) {
|
||||
_shipment = widget.shipment;
|
||||
} else {
|
||||
_shipment = null;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
@@ -116,6 +127,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
@override
|
||||
void didUpdateWidget(covariant CartonSizeWidget oldWidget) {
|
||||
_loadShipment();
|
||||
_getStandardCartonSize();
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@@ -125,7 +137,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
context.watch<CartonSizeModel>().getCartonSizes;
|
||||
bool isStandardSize = _cartonSizeType == standardCarton;
|
||||
bool isCustomSize = _cartonSizeType == customCarton;
|
||||
bool isNoneDefinedSize = _cartonSizeType == packageCartion;
|
||||
bool isNoneDefinedSize = _cartonSizeType == packageCarton;
|
||||
|
||||
final senderBox = DisplayText(
|
||||
text: widget.sender.name,
|
||||
@@ -139,7 +151,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
text: widget.consignee.name,
|
||||
labelTextKey: "box.consignee.title",
|
||||
iconData: MaterialCommunityIcons.account_arrow_left,
|
||||
subText: Text(widget.consignee.fcsID!,
|
||||
subText: Text(widget.consignee.fcsID ?? '',
|
||||
style: TextStyle(fontSize: 13, color: labelColor)),
|
||||
);
|
||||
|
||||
@@ -161,16 +173,16 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_selectedDeliveryType = delivery_caton;
|
||||
_selectedLastmile = delivery_caton;
|
||||
});
|
||||
},
|
||||
child: Row(children: <Widget>[
|
||||
LocalRadio(
|
||||
value: delivery_caton,
|
||||
groupValue: _selectedDeliveryType,
|
||||
groupValue: _selectedLastmile,
|
||||
onChanged: (p0) {
|
||||
setState(() {
|
||||
_selectedDeliveryType = delivery_caton;
|
||||
_selectedLastmile = delivery_caton;
|
||||
});
|
||||
},
|
||||
),
|
||||
@@ -179,7 +191,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: LocalText(context, 'box.delivery',
|
||||
fontSize: 15,
|
||||
color: _selectedDeliveryType == delivery_caton
|
||||
color: _selectedLastmile == delivery_caton
|
||||
? primaryColor
|
||||
: Colors.black),
|
||||
),
|
||||
@@ -190,16 +202,16 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_selectedDeliveryType = pickup_carton;
|
||||
_selectedLastmile = pickup_carton;
|
||||
});
|
||||
},
|
||||
child: Row(children: <Widget>[
|
||||
LocalRadio(
|
||||
value: pickup_carton,
|
||||
groupValue: _selectedDeliveryType,
|
||||
groupValue: _selectedLastmile,
|
||||
onChanged: (p0) {
|
||||
setState(() {
|
||||
_selectedDeliveryType = pickup_carton;
|
||||
_selectedLastmile = pickup_carton;
|
||||
});
|
||||
},
|
||||
),
|
||||
@@ -208,7 +220,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: LocalText(context, 'box.pickup',
|
||||
fontSize: 15,
|
||||
color: _selectedDeliveryType == pickup_carton
|
||||
color: _selectedLastmile == pickup_carton
|
||||
? primaryColor
|
||||
: Colors.black),
|
||||
),
|
||||
@@ -315,7 +327,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
|
||||
if (widget.onContinue != null) {
|
||||
widget.onContinue!(
|
||||
_selectedDeliveryType, _billToValue, _shipment!, _cartonSizeType,
|
||||
_selectedLastmile, _billToValue, _shipment!, _cartonSizeType,
|
||||
standardSize: _selectStandardSize, length: l, width: w, height: h);
|
||||
}
|
||||
});
|
||||
@@ -463,16 +475,16 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_cartonSizeType = packageCartion;
|
||||
_cartonSizeType = packageCarton;
|
||||
});
|
||||
},
|
||||
child: Row(children: <Widget>[
|
||||
LocalRadio(
|
||||
value: packageCartion,
|
||||
value: packageCarton,
|
||||
groupValue: _cartonSizeType,
|
||||
onChanged: (p0) {
|
||||
setState(() {
|
||||
_cartonSizeType = packageCartion;
|
||||
_cartonSizeType = packageCarton;
|
||||
});
|
||||
},
|
||||
),
|
||||
|
||||
@@ -30,7 +30,7 @@ class CartonSubmit extends StatelessWidget {
|
||||
final double length;
|
||||
final double width;
|
||||
final double height;
|
||||
final String deliveryType;
|
||||
final String lastMile;
|
||||
final List<CargoType> cargoTypes;
|
||||
final List<CargoType> surchareItems;
|
||||
final OnCreateCarton? onCreate;
|
||||
@@ -47,7 +47,7 @@ class CartonSubmit extends StatelessWidget {
|
||||
this.packages = const [],
|
||||
this.standardSize,
|
||||
required this.cartonSizeType,
|
||||
required this.deliveryType,
|
||||
required this.lastMile,
|
||||
this.length = 0,
|
||||
this.width = 0,
|
||||
this.height = 0,
|
||||
@@ -69,10 +69,7 @@ class CartonSubmit extends StatelessWidget {
|
||||
final cartonType = Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: SubmitTextWidget(
|
||||
labelKey: 'box.carton.type',
|
||||
text: carton_from_packages,
|
||||
// subText: boxDimension
|
||||
),
|
||||
labelKey: 'box.carton.type', text: carton_from_packages),
|
||||
);
|
||||
|
||||
final shipmentBox = Padding(
|
||||
@@ -187,7 +184,7 @@ class CartonSubmit extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: SubmitTextWidget(
|
||||
labelKey: 'box.select.delivery',
|
||||
text: deliveryType,
|
||||
text: lastMile == delivery_caton ? 'Delivery' : 'Pick-up',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -195,7 +192,7 @@ class CartonSubmit extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: SubmitTextWidget(
|
||||
labelKey: 'box.carton_size',
|
||||
text: boxDimension??'',
|
||||
text: boxDimension ?? 'No defined size',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/main/util.dart';
|
||||
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../widgets/local_button.dart';
|
||||
|
||||
class CustomDutyAddition extends StatefulWidget {
|
||||
final List<CargoType> customDuties;
|
||||
|
||||
const CustomDutyAddition({super.key, required this.customDuties});
|
||||
@override
|
||||
_CustomDutyAdditionState createState() => _CustomDutyAdditionState();
|
||||
}
|
||||
|
||||
class _CustomDutyAdditionState extends State<CustomDutyAddition> {
|
||||
bool _isLoading = false;
|
||||
List<CargoType> customDuties = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_init();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
_init() {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
customDuties =
|
||||
shipmentRateModel.rate.customDuties.map((e) => e.clone()).toList();
|
||||
|
||||
for (var p in customDuties) {
|
||||
p.qty = 0;
|
||||
if (widget.customDuties.any((e) => e.id == p.id)) {
|
||||
p.isChecked = true;
|
||||
} else {
|
||||
p.isChecked = false;
|
||||
}
|
||||
|
||||
widget.customDuties.forEach((vp) {
|
||||
if (p.id == vp.id) {
|
||||
p.qty = vp.qty;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> getCargoRowList(List<CargoType> _c) {
|
||||
return _c.map((c) {
|
||||
return Container(
|
||||
child: Container(
|
||||
padding:
|
||||
EdgeInsets.only(left: 10.0, right: 5.0, top: 3.0, bottom: 3.0),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
c.isChecked = !c.isChecked;
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Checkbox(
|
||||
value: c.isChecked,
|
||||
activeColor: primaryColor,
|
||||
onChanged: (bool? check) {
|
||||
setState(() {
|
||||
c.isChecked = check ?? false;
|
||||
});
|
||||
}),
|
||||
new Text(c.name ?? '', style: textStyle),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
final saveBtn = Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||
child: LocalButton(
|
||||
textKey: "box.cargo.select.btn",
|
||||
callBack: () {
|
||||
List<CargoType> _cargos =
|
||||
customDuties.where((c) => c.isChecked).toList();
|
||||
|
||||
if (_cargos.isEmpty) {
|
||||
showMsgDialog(context, 'Error', "Please select the cargo type");
|
||||
return;
|
||||
}
|
||||
Navigator.pop(context, _cargos);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
labelKey: 'box.select.cargo_type',
|
||||
backgroundColor: Colors.white,
|
||||
labelColor: primaryColor,
|
||||
arrowColor: primaryColor),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
children: getCargoRowList(customDuties),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
saveBtn,
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import '../../../domain/entities/carton_size.dart';
|
||||
import '../../../domain/entities/fcs_shipment.dart';
|
||||
import '../../../domain/vo/local_step.dart';
|
||||
import '../../../helpers/theme.dart';
|
||||
import '../../carton_size/model/carton_size_model.dart';
|
||||
import '../../main/util.dart';
|
||||
import '../../widgets/local_text.dart';
|
||||
import '../../widgets/progress.dart';
|
||||
@@ -58,10 +59,30 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
||||
|
||||
_init() async {
|
||||
context.read<CartonSelectionModel>().clearSelection();
|
||||
_cartonSizeType = customCarton;
|
||||
_length = widget.carton.length;
|
||||
_width = widget.carton.width;
|
||||
_height = widget.carton.height;
|
||||
|
||||
// check carton size type
|
||||
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
|
||||
|
||||
var sameLength =
|
||||
cartonSizes.any((size) => size.length == widget.carton.length);
|
||||
var sameWidth =
|
||||
cartonSizes.any((size) => size.width == widget.carton.width);
|
||||
var sameHeight =
|
||||
cartonSizes.any((size) => size.height == widget.carton.height);
|
||||
bool isStandartSize = sameLength && sameWidth && sameHeight;
|
||||
if (isStandartSize) {
|
||||
_cartonSizeType = standardCarton;
|
||||
_standardSize = cartonSizes.firstWhere((size) =>
|
||||
size.length == widget.carton.length &&
|
||||
size.width == widget.carton.width &&
|
||||
size.height == widget.carton.height);
|
||||
} else if (widget.carton.length == 0 &&
|
||||
widget.carton.width == 0 &&
|
||||
widget.carton.height == 0) {
|
||||
_cartonSizeType = packageCarton;
|
||||
} else {
|
||||
_cartonSizeType = customCarton;
|
||||
}
|
||||
|
||||
var s = await context
|
||||
.read<FcsShipmentModel>()
|
||||
@@ -70,7 +91,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
||||
|
||||
_cartons = await context
|
||||
.read<CartonModel>()
|
||||
.getCartonsByIds(widget.carton.mixCartonIDs);
|
||||
.getCartonsByIds(widget.carton.cartonIDs);
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
@@ -113,8 +134,16 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
||||
},
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
title: LocalText(context, 'box.update_title',
|
||||
color: primaryColor, fontSize: 20),
|
||||
title: Column(
|
||||
children: [
|
||||
LocalText(context, 'box.update_title',
|
||||
color: primaryColor, fontSize: 20),
|
||||
Text(
|
||||
widget.carton.cartonNumber ?? '',
|
||||
style: TextStyle(color: primaryColor, fontSize: 14),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
@@ -212,6 +241,35 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
double length = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
|
||||
if (_cartonSizeType == standardCarton) {
|
||||
if (_standardSize != null) {
|
||||
length = _standardSize!.length;
|
||||
width = _standardSize!.width;
|
||||
height = _standardSize!.height;
|
||||
}
|
||||
} else if (_cartonSizeType == customCarton) {
|
||||
length = _length;
|
||||
width = _width;
|
||||
height = _height;
|
||||
} else {
|
||||
length = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
var carton = Carton(
|
||||
id: widget.carton.id,
|
||||
cartonType: mix_carton,
|
||||
fcsShipmentID: _shipment?.id,
|
||||
length: length,
|
||||
width: width,
|
||||
height: height,
|
||||
cartons: _cartons);
|
||||
await context.read<CartonModel>().updateCarton(carton);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// ignore_for_file: deprecated_member_use
|
||||
|
||||
import 'package:fcs/pages/carton/model/carton_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@@ -187,7 +188,35 @@ class _MixCartonFormState extends State<MixCartonForm> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
Navigator.pop(context, true);
|
||||
double length = 0;
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
|
||||
if (_cartonSizeType == standardCarton) {
|
||||
if (_standardSize != null) {
|
||||
length = _standardSize!.length;
|
||||
width = _standardSize!.width;
|
||||
height = _standardSize!.height;
|
||||
}
|
||||
} else if (_cartonSizeType == customCarton) {
|
||||
length = _length;
|
||||
width = _width;
|
||||
height = _height;
|
||||
} else {
|
||||
length = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
var carton = Carton(
|
||||
cartonType: mix_carton,
|
||||
fcsShipmentID: _shipment?.id,
|
||||
length: length,
|
||||
width: width,
|
||||
height: height,
|
||||
cartons: _cartons);
|
||||
var c = await context.read<CartonModel>().createMixCarton(carton);
|
||||
Navigator.pop(context, c);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
} finally {
|
||||
|
||||
@@ -110,17 +110,14 @@ class _MixCartonSubmitState extends State<MixCartonSubmit> {
|
||||
final cartonType = Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: SubmitTextWidget(
|
||||
labelKey: 'box.carton.type',
|
||||
text: carton_mix_carton,
|
||||
// subText: boxDimension,
|
||||
),
|
||||
labelKey: 'box.carton.type', text: carton_mix_carton),
|
||||
);
|
||||
|
||||
final cartonSizeBox = Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: SubmitTextWidget(
|
||||
labelKey: 'box.carton_size',
|
||||
text: boxDimension ?? '',
|
||||
text: boxDimension ?? 'No defined size',
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -68,8 +68,6 @@ class _TypeWidgetState extends State<TypeWidget> {
|
||||
}
|
||||
|
||||
_init() async {
|
||||
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
|
||||
_selectStandardSize = widget.standardSize ?? cartonSizes.first;
|
||||
_cartionSizeType = widget.cartonSizeType;
|
||||
|
||||
_lengthController.text =
|
||||
@@ -79,6 +77,8 @@ class _TypeWidgetState extends State<TypeWidget> {
|
||||
_heightController.text =
|
||||
widget.height == null ? "0" : removeTrailingZeros(widget.height ?? 0);
|
||||
|
||||
_getStandardCartonSize();
|
||||
|
||||
_loadShipment();
|
||||
|
||||
if (mounted) {
|
||||
@@ -86,11 +86,24 @@ class _TypeWidgetState extends State<TypeWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
_getStandardCartonSize() {
|
||||
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
|
||||
_selectStandardSize = widget.standardSize ?? cartonSizes.first;
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
_loadShipment() async {
|
||||
var fcsShipments =
|
||||
await context.read<FcsShipmentModel>().getActiveFcsShipments();
|
||||
_shipments = fcsShipments;
|
||||
_shipment = widget.shipment;
|
||||
if (_shipments.contains(widget.shipment)) {
|
||||
_shipment = widget.shipment;
|
||||
} else {
|
||||
_shipment = null;
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
@@ -99,6 +112,7 @@ class _TypeWidgetState extends State<TypeWidget> {
|
||||
@override
|
||||
void didUpdateWidget(covariant TypeWidget oldWidget) {
|
||||
_loadShipment();
|
||||
_getStandardCartonSize();
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@@ -109,7 +123,7 @@ class _TypeWidgetState extends State<TypeWidget> {
|
||||
|
||||
bool isStandardSize = _cartionSizeType == standardCarton;
|
||||
bool isCustomSize = _cartionSizeType == customCarton;
|
||||
bool isNoneDefinedSize = _cartionSizeType == packageCartion;
|
||||
bool isNoneDefinedSize = _cartionSizeType == packageCarton;
|
||||
|
||||
final continueBtn = ContinueButton(onTap: () {
|
||||
double l = double.tryParse(_lengthController.text) ?? 0;
|
||||
@@ -287,16 +301,16 @@ class _TypeWidgetState extends State<TypeWidget> {
|
||||
InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_cartionSizeType = packageCartion;
|
||||
_cartionSizeType = packageCarton;
|
||||
});
|
||||
},
|
||||
child: Row(children: <Widget>[
|
||||
LocalRadio(
|
||||
value: packageCartion,
|
||||
value: packageCarton,
|
||||
groupValue: _cartionSizeType,
|
||||
onChanged: (p0) {
|
||||
setState(() {
|
||||
_cartionSizeType = packageCartion;
|
||||
_cartionSizeType = packageCarton;
|
||||
});
|
||||
},
|
||||
),
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:fcs/data/services/services.dart';
|
||||
import 'package:fcs/constants.dart';
|
||||
import 'package:fcs/domain/entities/carton.dart';
|
||||
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
||||
import 'package:fcs/helpers/shared_pref.dart';
|
||||
import 'package:fcs/pages/main/model/base_model.dart';
|
||||
import 'package:fcs/pagination/paginator_listener.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@@ -18,8 +19,6 @@ class CartonModel extends BaseModel {
|
||||
final log = Logger('CartonModel');
|
||||
|
||||
var defaultShipment = FcsShipment(shipmentNumber: "All shipments", id: all);
|
||||
|
||||
PaginatorListener<Carton>? cartonsByFilter;
|
||||
PaginatorListener<Carton>? getBoxes;
|
||||
|
||||
String? filterByStatus;
|
||||
@@ -49,13 +48,10 @@ class CartonModel extends BaseModel {
|
||||
@override
|
||||
logout() async {
|
||||
getBoxes?.close();
|
||||
cartonsByFilter?.close();
|
||||
}
|
||||
|
||||
Future<void> _initData() async {
|
||||
logout();
|
||||
|
||||
_loadPaginationCartons();
|
||||
}
|
||||
|
||||
filterCarton(FcsShipment? fcsShipment, User? consignee, User? sender,
|
||||
@@ -140,7 +136,7 @@ class CartonModel extends BaseModel {
|
||||
pageQuery = pageQuery.where("fcs_shipment_id", isEqualTo: shipment!.id);
|
||||
}
|
||||
|
||||
pageQuery = pageQuery.orderBy("created_at", descending: true);
|
||||
pageQuery = pageQuery.orderBy("update_time", descending: true);
|
||||
|
||||
getBoxes?.close();
|
||||
getBoxes = PaginatorListener<Carton>(
|
||||
@@ -148,30 +144,6 @@ class CartonModel extends BaseModel {
|
||||
rowPerLoad: 30);
|
||||
}
|
||||
|
||||
_loadPaginationCartons() {
|
||||
if (user == null || !user!.hasCarton()) return null;
|
||||
String path = "/$cartons_collection";
|
||||
|
||||
Query col = FirebaseFirestore.instance.collection(path);
|
||||
// .where("carton_type",
|
||||
// whereIn: [
|
||||
// carton_from_packages,
|
||||
// carton_from_cartons
|
||||
// ]).where("status", isEqualTo: carton_packed_status)
|
||||
// ;
|
||||
Query pageQuery = FirebaseFirestore.instance
|
||||
.collection(path)
|
||||
// .where("carton_type",
|
||||
// whereIn: [carton_from_packages, carton_from_cartons])
|
||||
// .where("status", isEqualTo: carton_packed_status)
|
||||
.orderBy("created_at", descending: true);
|
||||
|
||||
cartonsByFilter?.close();
|
||||
cartonsByFilter = PaginatorListener<Carton>(
|
||||
col, pageQuery, (data, id) => Carton.fromMap(data, id),
|
||||
rowPerLoad: 30);
|
||||
}
|
||||
|
||||
Future<List<Carton>> getCartons(String shipmentID) async {
|
||||
String path = "/$cartons_collection";
|
||||
var querySnap = await FirebaseFirestore.instance
|
||||
@@ -235,8 +207,18 @@ class CartonModel extends BaseModel {
|
||||
return Services.instance.cartonService.deleteCarton(carton);
|
||||
}
|
||||
|
||||
Future<List<Carton>> searchCarton(String term) async {
|
||||
Future<Carton> createMixCarton(Carton carton) {
|
||||
return Services.instance.cartonService.createCarton(carton);
|
||||
}
|
||||
|
||||
Future<void> updateMixCarton(Carton carton) {
|
||||
return Services.instance.cartonService.updateMixCarton(carton);
|
||||
}
|
||||
|
||||
Future<List<Carton>> searchCarton(String term) async {
|
||||
if (term != '') {
|
||||
await SharedPref.saveRecentSearch('carton_search', term);
|
||||
}
|
||||
return Services.instance.cartonService.searchCarton(term);
|
||||
}
|
||||
|
||||
@@ -277,9 +259,11 @@ class CartonModel extends BaseModel {
|
||||
uploadedURL.forEach((url) {
|
||||
carton.photoUrls.add(url);
|
||||
});
|
||||
|
||||
carton.photoUrls.removeWhere((e) => deletedUrls.contains(e));
|
||||
}
|
||||
try {
|
||||
// await Services.instance.packageService.updateReceiving(package);
|
||||
await Services.instance.cartonService.uploadCartonImages(carton);
|
||||
} catch (e) {
|
||||
// delete newly uploaded photos if fails
|
||||
try {
|
||||
|
||||
@@ -54,7 +54,7 @@ class CartonSelectionModel extends BaseModel {
|
||||
query = query.where("carton_number", isEqualTo: term);
|
||||
}
|
||||
|
||||
query = query.orderBy("created_at", descending: true);
|
||||
query = query.orderBy("update_time", descending: true);
|
||||
|
||||
if (_lastDocument != null) {
|
||||
query = query.startAfterDocument(_lastDocument!);
|
||||
|
||||
@@ -35,8 +35,11 @@ class PrintQrCodePage extends StatelessWidget {
|
||||
children: [
|
||||
Text(carton.cartonNumber ?? "",
|
||||
style: TextStyle(fontSize: 18, fontFamily: "Roboto")),
|
||||
Text(carton.userName!,
|
||||
style: TextStyle(fontSize: 16, fontFamily: "Roboto")),
|
||||
carton.consigneeName == null || carton.consigneeName == ''
|
||||
? const SizedBox()
|
||||
: Text(carton.consigneeName!,
|
||||
style:
|
||||
TextStyle(fontSize: 16, fontFamily: "Roboto")),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 3),
|
||||
child: Text("${carton.actualWeight} lb",
|
||||
|
||||
114
lib/pages/carton/surcharge_item_addition.dart
Normal file
114
lib/pages/carton/surcharge_item_addition.dart
Normal file
@@ -0,0 +1,114 @@
|
||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../main/util.dart';
|
||||
|
||||
class SurchargeItemAddition extends StatefulWidget {
|
||||
final List<CargoType> items;
|
||||
const SurchargeItemAddition({super.key, required this.items});
|
||||
@override
|
||||
_SurchargeItemAdditionState createState() => _SurchargeItemAdditionState();
|
||||
}
|
||||
|
||||
class _SurchargeItemAdditionState extends State<SurchargeItemAddition> {
|
||||
bool _isLoading = false;
|
||||
List<CargoType> surchargeItems = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_init();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
_init() {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
surchargeItems =
|
||||
shipmentRateModel.rate.customDuties.map((e) => e.clone()).toList();
|
||||
|
||||
for (var p in surchargeItems) {
|
||||
p.qty = 0;
|
||||
if (widget.items.any((e) => e.id == p.id)) {
|
||||
p.isChecked = true;
|
||||
} else {
|
||||
p.isChecked = false;
|
||||
}
|
||||
|
||||
widget.items.forEach((vp) {
|
||||
if (p.id == vp.id) {
|
||||
p.qty = vp.qty;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
_onTap(CargoType cargo) {
|
||||
if (cargo.isChecked) {
|
||||
showMsgDialog(context, "Error", "Already exit!");
|
||||
return;
|
||||
}
|
||||
Navigator.pop(context, cargo);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> getCargoRowList(List<CargoType> _c) {
|
||||
return _c.map((c) {
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
_onTap(c);
|
||||
},
|
||||
title: new Text(c.name ?? '', style: textStyle),
|
||||
trailing: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: primaryColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
minimumSize: Size(80, 35)),
|
||||
onPressed: c.isChecked
|
||||
? null
|
||||
: () {
|
||||
_onTap(c);
|
||||
},
|
||||
child: Text(
|
||||
"Add",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
),
|
||||
));
|
||||
}).toList();
|
||||
}
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
labelKey: 'box.select.cargo_type',
|
||||
backgroundColor: Colors.white,
|
||||
labelColor: primaryColor,
|
||||
arrowColor: primaryColor),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: <Widget>[
|
||||
Column(
|
||||
children: getCargoRowList(surchargeItems),
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ class CartonListRow extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
box.userName ?? "",
|
||||
box.consigneeName ?? "",
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
|
||||
@@ -62,7 +62,7 @@ class CartonListRow extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
carton.userName ?? "",
|
||||
carton.consigneeName ?? "",
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
|
||||
@@ -7,6 +7,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../helpers/shared_pref.dart';
|
||||
import '../widgets/suggest_list.dart';
|
||||
import 'carton_list_row.dart';
|
||||
|
||||
typedef CallbackCartonSelect(Carton carton);
|
||||
@@ -32,7 +34,7 @@ class PartSearchDelegate extends SearchDelegate<Carton> {
|
||||
appBarTheme: AppBarTheme(color: primaryColor),
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
iconColor: MaterialStateProperty.all<Color>(Colors.white))),
|
||||
iconColor: WidgetStateProperty.all<Color>(Colors.white))),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
border: InputBorder.none,
|
||||
hintStyle: TextStyle(color: Colors.grey, fontSize: 14)),
|
||||
@@ -120,13 +122,27 @@ class PartSearchDelegate extends SearchDelegate<Carton> {
|
||||
|
||||
@override
|
||||
Widget buildSuggestions(BuildContext context) {
|
||||
return Container(
|
||||
child: Center(
|
||||
child: Opacity(
|
||||
opacity: 0.2,
|
||||
child: Icon(MaterialCommunityIcons.package,
|
||||
size: 200, color: primaryColor)),
|
||||
),
|
||||
return FutureBuilder<List<String>?>(
|
||||
future: SharedPref.getRecentSearch('carton_search', query),
|
||||
builder: (context, snapshot) {
|
||||
List<String> _oldFilters = snapshot.data ?? [];
|
||||
if (_oldFilters.isEmpty) {
|
||||
return const Center(
|
||||
child: Opacity(
|
||||
opacity: 0.2,
|
||||
child: Icon(MaterialCommunityIcons.package,
|
||||
color: primaryColor, size: 200),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SuggestList(
|
||||
recentSearchList: _oldFilters,
|
||||
onTap: (String s) {
|
||||
query = s;
|
||||
showResults(context);
|
||||
},
|
||||
prefKey: 'carton_search');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +86,10 @@ class _DeliveryInfoState extends State<DeliveryInfo> {
|
||||
_loadPackages() async {
|
||||
if (!isFromPackages && !isSmallBag) return;
|
||||
|
||||
if (_box.cartonType == carton_from_packages && _box.userID == null) return;
|
||||
if (_box.cartonType == carton_from_packages && _box.consigneeID == null) return;
|
||||
PackageModel packageModel =
|
||||
Provider.of<PackageModel>(context, listen: false);
|
||||
List<Package> packages = await packageModel.getPackages(_box.userID!, [
|
||||
List<Package> packages = await packageModel.getPackages(_box.consigneeID!, [
|
||||
package_processed_status,
|
||||
package_packed_status,
|
||||
package_shipped_status,
|
||||
@@ -137,13 +137,13 @@ class _DeliveryInfoState extends State<DeliveryInfo> {
|
||||
iconData: Ionicons.ios_airplane,
|
||||
);
|
||||
final fcsIDBox = DisplayText(
|
||||
text: _box.fcsID,
|
||||
text: _box.consigneeFCSID,
|
||||
labelTextKey: "box.fcs.id",
|
||||
icon: FcsIDIcon(),
|
||||
);
|
||||
|
||||
final customerNameBox = DisplayText(
|
||||
text: _box.userName,
|
||||
text: _box.consigneeName,
|
||||
labelTextKey: "box.name",
|
||||
iconData: Icons.person,
|
||||
);
|
||||
|
||||
@@ -48,7 +48,7 @@ class DeliveryListRow extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
box.userName ?? "",
|
||||
box.consigneeName ?? "",
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
||||
import 'package:fcs/domain/entities/shipment_consignee.dart';
|
||||
import 'package:fcs/domain/entities/shipment_port.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/localization/app_translations.dart';
|
||||
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
|
||||
@@ -30,16 +32,16 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
|
||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
||||
TextEditingController _shipmentNumberController = new TextEditingController();
|
||||
TextEditingController _cutoffDateController = new TextEditingController();
|
||||
TextEditingController _arrivalDateController = new TextEditingController();
|
||||
TextEditingController _departureDateControler = new TextEditingController();
|
||||
TextEditingController _consigneeController = new TextEditingController();
|
||||
TextEditingController _portController = new TextEditingController();
|
||||
TextEditingController _destinationController = new TextEditingController();
|
||||
TextEditingController _etaDateController = new TextEditingController();
|
||||
|
||||
TextEditingController _statusController = new TextEditingController();
|
||||
|
||||
FcsShipment _shipment = new FcsShipment();
|
||||
bool _isLoading = false;
|
||||
ShipmentType? _currentShipmentType;
|
||||
ShipmentConsignee? _currentConsignee;
|
||||
ShipmentPort? _currentLoadingPort;
|
||||
ShipmentPort? _currentDestination;
|
||||
bool _isNew = false;
|
||||
|
||||
@override
|
||||
@@ -53,24 +55,38 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
|
||||
if (_shipment.cutoffDate != null)
|
||||
_cutoffDateController.text =
|
||||
dateFormatter.format(_shipment.cutoffDate!);
|
||||
if (_shipment.arrivalDate != null)
|
||||
_arrivalDateController.text =
|
||||
dateFormatter.format(_shipment.arrivalDate!);
|
||||
if (_shipment.departureDate != null)
|
||||
_departureDateControler.text =
|
||||
dateFormatter.format(_shipment.departureDate!);
|
||||
_statusController.text = _shipment.status ?? "";
|
||||
_consigneeController.text = _shipment.consignee ?? "";
|
||||
_portController.text = _shipment.port ?? "";
|
||||
_destinationController.text = _shipment.destination ?? "";
|
||||
if (_shipment.etaDate != null)
|
||||
_etaDateController.text = dateFormatter.format(_shipment.etaDate!);
|
||||
|
||||
List<ShipmentType> list = model.shipmentTypes
|
||||
_statusController.text = _shipment.status ?? "";
|
||||
|
||||
List<ShipmentType> shipmentTypes = model.shipmentTypes
|
||||
.where((e) => e.id == _shipment.shipmentTypeId)
|
||||
.toList();
|
||||
_currentShipmentType =
|
||||
shipmentTypes.isNotEmpty ? shipmentTypes.first : null;
|
||||
|
||||
_currentShipmentType = list.isNotEmpty ? list.first : null;
|
||||
List<ShipmentConsignee> shipmentConsingees = model.shipmentConsingees
|
||||
.where((e) => e.id == _shipment.consigneeId)
|
||||
.toList();
|
||||
_currentConsignee =
|
||||
shipmentConsingees.isNotEmpty ? shipmentConsingees.first : null;
|
||||
|
||||
List<ShipmentPort> loadingPorts = model.shipmentPorts
|
||||
.where((e) => e.id == _shipment.loadingPortId)
|
||||
.toList();
|
||||
_currentLoadingPort = loadingPorts.isNotEmpty ? loadingPorts.first : null;
|
||||
|
||||
List<ShipmentPort> loadingDestination = model.shipmentPorts
|
||||
.where((e) => e.id == _shipment.destinationPortId)
|
||||
.toList();
|
||||
_currentDestination =
|
||||
loadingDestination.isNotEmpty ? loadingDestination.first : null;
|
||||
} else {
|
||||
_currentShipmentType = model.shipmentTypes[0];
|
||||
_currentShipmentType = model.shipmentTypes.first;
|
||||
_currentConsignee = model.shipmentConsingees.first;
|
||||
_currentLoadingPort = model.shipmentPorts.first;
|
||||
_currentDestination = model.shipmentPorts.first;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,8 +98,111 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var languageModel = Provider.of<LanguageModel>(context);
|
||||
List<ShipmentType> shipmentTypes =
|
||||
context.watch<FcsShipmentModel>().shipmentTypes;
|
||||
var shipmentModel = context.watch<FcsShipmentModel>();
|
||||
List<ShipmentType> shipmentTypes = shipmentModel.shipmentTypes;
|
||||
List<ShipmentConsignee> shipmentConsingees =
|
||||
shipmentModel.shipmentConsingees;
|
||||
List<ShipmentPort> shipmentPorts = shipmentModel.shipmentPorts;
|
||||
|
||||
final shipmentTypeBox = DropdownButtonFormField(
|
||||
value: _currentShipmentType == "" ? null : _currentShipmentType,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
enabledBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
focusedBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
fillColor: Colors.white,
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(color: Colors.black54, fontSize: 20),
|
||||
labelText:
|
||||
AppTranslations.of(context)!.text('FCSshipment.shipment_type'),
|
||||
icon: Icon(Ionicons.ios_airplane, color: primaryColor)),
|
||||
items: shipmentTypes
|
||||
.map((e) => DropdownMenuItem(child: Text(e.name), value: e))
|
||||
.toList(),
|
||||
onChanged: (selected) => {
|
||||
setState(() {
|
||||
_currentShipmentType = selected;
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
final consigneeBox = DropdownButtonFormField(
|
||||
value: _currentConsignee == "" ? null : _currentConsignee,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
enabledBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
focusedBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
fillColor: Colors.white,
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(color: Colors.black54, fontSize: 20),
|
||||
labelText: AppTranslations.of(context)!.text('FCSshipment.consignee'),
|
||||
icon: Icon(Icons.work, color: primaryColor)),
|
||||
items: shipmentConsingees
|
||||
.map((e) => DropdownMenuItem(child: Text(e.name), value: e))
|
||||
.toList(),
|
||||
onChanged: (selected) => {
|
||||
setState(() {
|
||||
_currentConsignee = selected;
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
final loadingPortBox = DropdownButtonFormField(
|
||||
value: _currentLoadingPort == "" ? null : _currentLoadingPort,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
enabledBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
focusedBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
fillColor: Colors.white,
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(color: Colors.black54, fontSize: 20),
|
||||
labelText:
|
||||
AppTranslations.of(context)!.text('FCSshipment.port_of_loading'),
|
||||
icon: Icon(FontAwesomeIcons.ship, color: primaryColor)),
|
||||
items: shipmentPorts
|
||||
.map((e) => DropdownMenuItem(child: Text(e.name), value: e))
|
||||
.toList(),
|
||||
onChanged: (selected) => {
|
||||
setState(() {
|
||||
_currentLoadingPort = selected;
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
final destinationBox = DropdownButtonFormField(
|
||||
value: _currentDestination == "" ? null : _currentDestination,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
enabledBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
focusedBorder:
|
||||
UnderlineInputBorder(borderSide: BorderSide(color: primaryColor)),
|
||||
fillColor: Colors.white,
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(color: Colors.black54, fontSize: 20),
|
||||
labelText: AppTranslations.of(context)!
|
||||
.text('FCSshipment.final_destination'),
|
||||
icon:
|
||||
Icon(MaterialCommunityIcons.location_enter, color: primaryColor)),
|
||||
items: shipmentPorts
|
||||
.map((e) => DropdownMenuItem(child: Text(e.name), value: e))
|
||||
.toList(),
|
||||
onChanged: (selected) => {
|
||||
setState(() {
|
||||
_currentDestination = selected;
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
final createBtn = Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 30),
|
||||
@@ -150,7 +269,7 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
|
||||
InputDate(
|
||||
labelTextKey: "FCSshipment.ETA",
|
||||
iconData: Icons.date_range,
|
||||
controller: _arrivalDateController,
|
||||
controller: _etaDateController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value!.isEmpty) {
|
||||
@@ -160,47 +279,14 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
DropdownButtonFormField(
|
||||
value:
|
||||
_currentShipmentType == "" ? null : _currentShipmentType,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: primaryColor)),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: primaryColor)),
|
||||
fillColor: Colors.white,
|
||||
labelStyle: languageModel.isEng
|
||||
? newLabelStyle(color: Colors.black54, fontSize: 20)
|
||||
: newLabelStyleMM(
|
||||
color: Colors.black54, fontSize: 20),
|
||||
labelText: AppTranslations.of(context)!
|
||||
.text('FCSshipment.shipment_type'),
|
||||
icon: Icon(Ionicons.ios_airplane, color: primaryColor)),
|
||||
items: shipmentTypes
|
||||
.map((e) =>
|
||||
DropdownMenuItem(child: Text(e.name), value: e))
|
||||
.toList(),
|
||||
onChanged: (selected) => {
|
||||
setState(() {
|
||||
_currentShipmentType = selected;
|
||||
})
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
InputText(
|
||||
labelTextKey: 'FCSshipment.consignee',
|
||||
iconData: Icons.work,
|
||||
controller: _consigneeController),
|
||||
InputText(
|
||||
labelTextKey: 'FCSshipment.port_of_loading',
|
||||
iconData: FontAwesomeIcons.ship,
|
||||
controller: _portController),
|
||||
InputText(
|
||||
labelTextKey: 'FCSshipment.final_destination',
|
||||
iconData: MaterialCommunityIcons.location_enter,
|
||||
controller: _destinationController),
|
||||
SizedBox(height: 20),
|
||||
shipmentTypeBox,
|
||||
const SizedBox(height: 25),
|
||||
consigneeBox,
|
||||
const SizedBox(height: 25),
|
||||
loadingPortBox,
|
||||
const SizedBox(height: 25),
|
||||
destinationBox,
|
||||
SizedBox(height: 30),
|
||||
_isNew ? createBtn : updateBtn,
|
||||
SizedBox(height: 15)
|
||||
]),
|
||||
@@ -214,16 +300,15 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
|
||||
fcsShipment.id = _shipment.id;
|
||||
fcsShipment.shipmentNumber = _shipmentNumberController.text;
|
||||
fcsShipment.shipmentTypeId = _currentShipmentType?.id ?? "";
|
||||
fcsShipment.consignee = _consigneeController.text;
|
||||
fcsShipment.port = _portController.text;
|
||||
fcsShipment.destination = _destinationController.text;
|
||||
fcsShipment.consigneeId = _currentConsignee?.id ?? "";
|
||||
fcsShipment.loadingPortId = _currentLoadingPort?.id ?? "";
|
||||
fcsShipment.destinationPortId = _currentDestination?.id ?? "";
|
||||
|
||||
var cutoffDate = _cutoffDateController.text;
|
||||
var arrivalDate = _arrivalDateController.text;
|
||||
var etaDate = _etaDateController.text;
|
||||
fcsShipment.cutoffDate =
|
||||
(cutoffDate == "" ? null : dateFormatter.parse(cutoffDate))!;
|
||||
fcsShipment.arrivalDate =
|
||||
(arrivalDate == "" ? null : dateFormatter.parse(arrivalDate))!;
|
||||
fcsShipment.etaDate = (etaDate == "" ? null : dateFormatter.parse(etaDate));
|
||||
return fcsShipment;
|
||||
}
|
||||
|
||||
@@ -271,11 +356,11 @@ class _FcsShipmentEditorState extends State<FcsShipmentEditor> {
|
||||
var shipmentModel = Provider.of<FcsShipmentModel>(context, listen: false);
|
||||
return _shipmentNumberController.text != "" ||
|
||||
_cutoffDateController.text != "" ||
|
||||
_arrivalDateController.text != "" ||
|
||||
_consigneeController.text != "" ||
|
||||
_portController.text != "" ||
|
||||
_destinationController.text != "" ||
|
||||
_currentShipmentType != shipmentModel.shipmentTypes[0];
|
||||
_etaDateController.text != "" ||
|
||||
_currentConsignee != shipmentModel.shipmentConsingees.first ||
|
||||
_currentShipmentType != shipmentModel.shipmentTypes.first ||
|
||||
_currentLoadingPort != shipmentModel.shipmentPorts.first ||
|
||||
_currentDestination != shipmentModel.shipmentPorts.first;
|
||||
} else {
|
||||
FcsShipment fcsShipment = _getPayload();
|
||||
return widget.shipment!.isChangedForEdit(fcsShipment);
|
||||
|
||||
@@ -20,8 +20,8 @@ import 'package:provider/provider.dart';
|
||||
import 'fcs_shipment_editor.dart';
|
||||
|
||||
class FcsShipmentInfo extends StatefulWidget {
|
||||
final FcsShipment? fcsShipment;
|
||||
FcsShipmentInfo({this.fcsShipment});
|
||||
final FcsShipment fcsShipment;
|
||||
FcsShipmentInfo({required this.fcsShipment});
|
||||
|
||||
@override
|
||||
_FcsShipmentInfoState createState() => _FcsShipmentInfoState();
|
||||
@@ -29,7 +29,7 @@ class FcsShipmentInfo extends StatefulWidget {
|
||||
|
||||
class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
var dateFormatter = new DateFormat('dd MMM yyyy');
|
||||
FcsShipment? _fcsShipment;
|
||||
late FcsShipment _fcsShipment;
|
||||
bool _isLoading = false;
|
||||
TextEditingController _shipmentNumberController = new TextEditingController();
|
||||
TextEditingController _cutoffDateController = new TextEditingController();
|
||||
@@ -49,21 +49,21 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
}
|
||||
|
||||
_load() {
|
||||
_shipmentNumberController.text = _fcsShipment?.shipmentNumber ?? "";
|
||||
if (_fcsShipment?.cutoffDate != null)
|
||||
_shipmentNumberController.text = _fcsShipment.shipmentNumber ?? "";
|
||||
if (_fcsShipment.cutoffDate != null)
|
||||
_cutoffDateController.text =
|
||||
dateFormatter.format(_fcsShipment!.cutoffDate!);
|
||||
if (_fcsShipment?.arrivalDate != null)
|
||||
_arrivalDateController.text =
|
||||
dateFormatter.format(_fcsShipment!.arrivalDate!);
|
||||
if (_fcsShipment?.departureDate != null)
|
||||
dateFormatter.format(_fcsShipment.cutoffDate!);
|
||||
if (_fcsShipment.etaDate != null)
|
||||
_arrivalDateController.text = dateFormatter.format(_fcsShipment.etaDate!);
|
||||
if (_fcsShipment.departureDate != null)
|
||||
_departureDateControler.text =
|
||||
dateFormatter.format(_fcsShipment!.departureDate!);
|
||||
_shipmentTypeControler.text = _fcsShipment!.shipTypeName ?? "";
|
||||
_consigneeController.text = _fcsShipment!.consignee ?? "";
|
||||
_portController.text = _fcsShipment!.port ?? "";
|
||||
_destinationController.text = _fcsShipment!.destination ?? "";
|
||||
_statusController.text = _fcsShipment!.status ?? "";
|
||||
dateFormatter.format(_fcsShipment.departureDate!);
|
||||
|
||||
_shipmentTypeControler.text = _fcsShipment.shipmentTypeName ?? "";
|
||||
_consigneeController.text = _fcsShipment.consigneeName ?? '';
|
||||
_portController.text = _fcsShipment.loadingPortName ?? '';
|
||||
_destinationController.text = _fcsShipment.destinationPortName ?? '';
|
||||
_statusController.text = _fcsShipment.status ?? "";
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -176,7 +176,7 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
labelColor: primaryColor,
|
||||
arrowColor: primaryColor,
|
||||
actions: [
|
||||
_fcsShipment?.status == fcs_shipment_pending_status
|
||||
_fcsShipment.status == fcs_shipment_pending_status
|
||||
? IconButton(
|
||||
icon: Icon(Icons.edit, color: primaryColor),
|
||||
onPressed: _edit,
|
||||
@@ -212,20 +212,20 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
portBox,
|
||||
destinationBox,
|
||||
const SizedBox(height: 30),
|
||||
_fcsShipment?.status == fcs_shipment_pending_status
|
||||
_fcsShipment.status == fcs_shipment_pending_status
|
||||
? processBtn
|
||||
: Container(),
|
||||
_fcsShipment?.status == fcs_shipment_pending_status
|
||||
_fcsShipment.status == fcs_shipment_pending_status
|
||||
? Container(
|
||||
padding: EdgeInsets.only(top: 3), child: cancelBtn)
|
||||
: Container(),
|
||||
_fcsShipment?.status == fcs_shipment_processed_status
|
||||
_fcsShipment.status == fcs_shipment_processed_status
|
||||
? shipBtn
|
||||
: Container(),
|
||||
_fcsShipment?.status == fcs_shipment_shipped_status
|
||||
_fcsShipment.status == fcs_shipment_shipped_status
|
||||
? arriveBtn
|
||||
: Container(),
|
||||
_fcsShipment?.status == fcs_shipment_arrived_status
|
||||
_fcsShipment.status == fcs_shipment_arrived_status
|
||||
? invoiceBtn
|
||||
: Container(),
|
||||
SizedBox(height: 20)
|
||||
@@ -244,8 +244,8 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
);
|
||||
if (updated ?? false) {
|
||||
var shipmentModel = Provider.of<FcsShipmentModel>(context, listen: false);
|
||||
if (_fcsShipment != null && _fcsShipment!.id != null) {
|
||||
FcsShipment? f = await shipmentModel.getFcsShipment(_fcsShipment!.id!);
|
||||
if (_fcsShipment.id != null) {
|
||||
FcsShipment? f = await shipmentModel.getFcsShipment(_fcsShipment.id!);
|
||||
if (f == null) return;
|
||||
setState(() {
|
||||
_fcsShipment = f;
|
||||
@@ -294,7 +294,7 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
await context.read<FcsShipmentModel>().process(_fcsShipment!.id!);
|
||||
await context.read<FcsShipmentModel>().process(_fcsShipment.id!);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -316,7 +316,7 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
await context.read<FcsShipmentModel>().ship(_fcsShipment!.id!);
|
||||
await context.read<FcsShipmentModel>().ship(_fcsShipment.id!);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -338,7 +338,7 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
await context.read<FcsShipmentModel>().arrive(_fcsShipment!.id!);
|
||||
await context.read<FcsShipmentModel>().arrive(_fcsShipment.id!);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -360,7 +360,7 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
await context.read<FcsShipmentModel>().invoice(_fcsShipment!.id!);
|
||||
await context.read<FcsShipmentModel>().invoice(_fcsShipment.id!);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -376,7 +376,7 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
await context.read<FcsShipmentModel>().cancel(_fcsShipment!.id!);
|
||||
await context.read<FcsShipmentModel>().cancel(_fcsShipment.id!);
|
||||
Navigator.pop(context, true);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -402,11 +402,11 @@ class _FcsShipmentInfoState extends State<FcsShipmentInfo> {
|
||||
} else if (id == 4) {
|
||||
reportName = "manifest";
|
||||
}
|
||||
_fcsShipment!.reportName = reportName;
|
||||
_fcsShipment.reportName = reportName;
|
||||
|
||||
FcsShipmentModel fcsShipmentModel =
|
||||
Provider.of<FcsShipmentModel>(context, listen: false);
|
||||
String url = await fcsShipmentModel.report(_fcsShipment!);
|
||||
String url = await fcsShipmentModel.report(_fcsShipment);
|
||||
Navigator.of(context).push(CupertinoPageRoute(
|
||||
builder: (context) => PDFScreen(
|
||||
title: "",
|
||||
|
||||
@@ -43,21 +43,21 @@ class _FcsShipmentListState extends State<FcsShipmentList> {
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(labelKey: "FCSshipment.list.title", actions: [
|
||||
_menuFilteringWidget(context),
|
||||
]),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
_newShipment();
|
||||
},
|
||||
icon: Icon(Icons.add),
|
||||
label:
|
||||
LocalText(context, "FCSshipment.add", color: Colors.white),
|
||||
backgroundColor: primaryColor),
|
||||
body: PaginatorListView<FcsShipment>(
|
||||
paginatorListener: shipmentModel.fcsShipments!,
|
||||
rowBuilder: (p) => FcsShipmentListRow(shipment: p),
|
||||
color: primaryColor)));
|
||||
appBar: LocalAppBar(labelKey: "FCSshipment.list.title", actions: [
|
||||
_menuFilteringWidget(context),
|
||||
]),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
_newShipment();
|
||||
},
|
||||
icon: Icon(Icons.add),
|
||||
label: LocalText(context, "FCSshipment.add", color: Colors.white),
|
||||
backgroundColor: primaryColor),
|
||||
body: PaginatorListView<FcsShipment>(
|
||||
paginatorListener: shipmentModel.fcsShipments!,
|
||||
rowBuilder: (p) => FcsShipmentListRow(shipment: p),
|
||||
color: primaryColor),
|
||||
));
|
||||
}
|
||||
|
||||
_newShipment() {
|
||||
@@ -107,7 +107,9 @@ class _FcsShipmentListState extends State<FcsShipmentList> {
|
||||
value: choice,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(child: Text("${choice.text}",style: TextStyle(color: Colors.black))),
|
||||
Flexible(
|
||||
child: Text("${choice.text}",
|
||||
style: TextStyle(color: Colors.black))),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
|
||||
@@ -4,9 +4,11 @@ import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:fcs/data/services/services.dart';
|
||||
import 'package:fcs/constants.dart';
|
||||
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
||||
import 'package:fcs/domain/entities/shipment_port.dart';
|
||||
import 'package:fcs/pages/main/model/base_model.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import '../../../domain/entities/shipment_consignee.dart';
|
||||
import '../../../domain/entities/shipment_type.dart';
|
||||
import '../../../pagination/paginator_listener.dart';
|
||||
|
||||
@@ -17,7 +19,26 @@ class FcsShipmentModel extends BaseModel {
|
||||
int selectedIndex = 0;
|
||||
|
||||
List<ShipmentType> shipmentTypes = [];
|
||||
List<ShipmentConsignee> shipmentConsingees = [];
|
||||
List<ShipmentPort> shipmentPorts = [];
|
||||
StreamSubscription<QuerySnapshot>? _shipmentTypeListener;
|
||||
StreamSubscription<QuerySnapshot>? _shipmentConsigneeListener;
|
||||
StreamSubscription<QuerySnapshot>? _shipmentPortListener;
|
||||
|
||||
ShipmentType? getShipmentType(id) {
|
||||
var list = shipmentTypes.where((e) => e.id == id).toList();
|
||||
return list.isNotEmpty ? list.first : null;
|
||||
}
|
||||
|
||||
ShipmentConsignee? getShipmentConsignee(id) {
|
||||
var list = shipmentConsingees.where((e) => e.id == id).toList();
|
||||
return list.isNotEmpty ? list.first : null;
|
||||
}
|
||||
|
||||
ShipmentPort? getShipmentPort(id) {
|
||||
var list = shipmentPorts.where((e) => e.id == id).toList();
|
||||
return list.isNotEmpty ? list.first : null;
|
||||
}
|
||||
|
||||
onChanged(int index) {
|
||||
selectedIndex = index;
|
||||
@@ -39,7 +60,7 @@ class FcsShipmentModel extends BaseModel {
|
||||
pageQuery.where("status", isEqualTo: fcs_shipment_pending_status);
|
||||
}
|
||||
|
||||
// processing status
|
||||
// processed status
|
||||
if (index == 2) {
|
||||
col = col.where("status", isEqualTo: fcs_shipment_processed_status);
|
||||
pageQuery =
|
||||
@@ -74,7 +95,7 @@ class FcsShipmentModel extends BaseModel {
|
||||
pageQuery.where("status", isEqualTo: fcs_shipment_canceled_status);
|
||||
}
|
||||
|
||||
pageQuery = pageQuery.orderBy("shipment_number", descending: true);
|
||||
pageQuery = pageQuery.orderBy("update_time", descending: true);
|
||||
|
||||
fcsShipments?.close();
|
||||
fcsShipments = PaginatorListener<FcsShipment>(
|
||||
@@ -87,7 +108,7 @@ class FcsShipmentModel extends BaseModel {
|
||||
try {
|
||||
var snaps = await FirebaseFirestore.instance
|
||||
.collection("/$fcs_shipment_collection")
|
||||
// .where("status", isEqualTo: fcs_shipment_processed_status)
|
||||
.where("status", isEqualTo: fcs_shipment_processed_status)
|
||||
.get(const GetOptions(source: Source.server));
|
||||
fcsShipments = snaps.docs.map((documentSnapshot) {
|
||||
var fcs =
|
||||
@@ -137,13 +158,19 @@ class FcsShipmentModel extends BaseModel {
|
||||
void initUser(user) {
|
||||
super.initUser(user);
|
||||
_loadShipmentTypes();
|
||||
_loadShipmentConsignees();
|
||||
_loadShipmentPorts();
|
||||
}
|
||||
|
||||
@override
|
||||
logout() async {
|
||||
fcsShipments?.close();
|
||||
_shipmentTypeListener?.cancel();
|
||||
_shipmentConsigneeListener?.cancel();
|
||||
_shipmentPortListener?.cancel();
|
||||
shipmentTypes.clear();
|
||||
shipmentConsingees.clear();
|
||||
shipmentPorts.clear();
|
||||
}
|
||||
|
||||
Future<void> _loadShipmentTypes() async {
|
||||
@@ -155,10 +182,52 @@ class FcsShipmentModel extends BaseModel {
|
||||
.listen((QuerySnapshot snapshot) {
|
||||
shipmentTypes.clear();
|
||||
shipmentTypes = snapshot.docs.map((documentSnapshot) {
|
||||
var privilege = ShipmentType.fromMap(
|
||||
var type = ShipmentType.fromMap(
|
||||
documentSnapshot.data() as Map<String, dynamic>,
|
||||
documentSnapshot.id);
|
||||
return privilege;
|
||||
return type;
|
||||
}).toList();
|
||||
notifyListeners();
|
||||
});
|
||||
} catch (e) {
|
||||
log.warning("Error!! $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadShipmentConsignees() async {
|
||||
try {
|
||||
_shipmentConsigneeListener = FirebaseFirestore.instance
|
||||
.collection(
|
||||
"/$config_collection/$setting_doc_id/$shipment_consignee_collection")
|
||||
.snapshots()
|
||||
.listen((QuerySnapshot snapshot) {
|
||||
shipmentConsingees.clear();
|
||||
shipmentConsingees = snapshot.docs.map((documentSnapshot) {
|
||||
var consignee = ShipmentConsignee.fromMap(
|
||||
documentSnapshot.data() as Map<String, dynamic>,
|
||||
documentSnapshot.id);
|
||||
return consignee;
|
||||
}).toList();
|
||||
notifyListeners();
|
||||
});
|
||||
} catch (e) {
|
||||
log.warning("Error!! $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadShipmentPorts() async {
|
||||
try {
|
||||
_shipmentPortListener = FirebaseFirestore.instance
|
||||
.collection(
|
||||
"/$config_collection/$setting_doc_id/$shipment_port_collection")
|
||||
.snapshots()
|
||||
.listen((QuerySnapshot snapshot) {
|
||||
shipmentPorts.clear();
|
||||
shipmentPorts = snapshot.docs.map((documentSnapshot) {
|
||||
var port = ShipmentPort.fromMap(
|
||||
documentSnapshot.data() as Map<String, dynamic>,
|
||||
documentSnapshot.id);
|
||||
return port;
|
||||
}).toList();
|
||||
notifyListeners();
|
||||
});
|
||||
@@ -192,7 +261,7 @@ class FcsShipmentModel extends BaseModel {
|
||||
|
||||
Future<void> invoice(String id) {
|
||||
return Services.instance.fcsShipmentService
|
||||
.updateFcsShipmentStatus(id, fcs_shipment_shipped_status);
|
||||
.updateFcsShipmentStatus(id, fcs_shipment_invoiced_status);
|
||||
}
|
||||
|
||||
Future<void> cancel(String id) {
|
||||
|
||||
@@ -224,6 +224,9 @@ class PackageModel extends BaseModel {
|
||||
}
|
||||
|
||||
Future<List<Package>> searchPackage(String term) async {
|
||||
if (term != '') {
|
||||
await SharedPref.saveRecentSearch('package_search', term);
|
||||
}
|
||||
Future<List<Package>> packages =
|
||||
Services.instance.packageService.searchPackage(term);
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../helpers/shared_pref.dart';
|
||||
import '../widgets/suggest_list.dart';
|
||||
|
||||
Future<Package?> searchPackage(BuildContext context,
|
||||
{CallbackPackageSelect? callbackPackageSelect}) async =>
|
||||
await showSearch<Package>(
|
||||
@@ -22,7 +25,7 @@ class PackageSearchDelegate extends SearchDelegate<Package> {
|
||||
PackageSearchDelegate({this.callbackPackageSelect});
|
||||
|
||||
@override
|
||||
String get searchFieldLabel => 'Search by Tracking ID/Customer Name';
|
||||
String get searchFieldLabel => 'Search by Tracking ID/Customer name';
|
||||
|
||||
@override
|
||||
ThemeData appBarTheme(BuildContext context) {
|
||||
@@ -31,7 +34,7 @@ class PackageSearchDelegate extends SearchDelegate<Package> {
|
||||
appBarTheme: AppBarTheme(color: primaryColor),
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
iconColor: MaterialStateProperty.all<Color>(Colors.white))),
|
||||
iconColor: WidgetStateProperty.all<Color>(Colors.white))),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
border: InputBorder.none,
|
||||
hintStyle: TextStyle(color: Colors.grey, fontSize: 14)),
|
||||
@@ -123,12 +126,27 @@ class PackageSearchDelegate extends SearchDelegate<Package> {
|
||||
|
||||
@override
|
||||
Widget buildSuggestions(BuildContext context) {
|
||||
return Container(
|
||||
child: Center(
|
||||
child: Opacity(
|
||||
opacity: 0.2,
|
||||
child: Icon(Octicons.package, size: 200, color: primaryColor)),
|
||||
),
|
||||
return FutureBuilder<List<String>?>(
|
||||
future: SharedPref.getRecentSearch('package_search', query),
|
||||
builder: (context, snapshot) {
|
||||
List<String> _oldFilters = snapshot.data ?? [];
|
||||
if (_oldFilters.isEmpty) {
|
||||
return const Center(
|
||||
child: Opacity(
|
||||
opacity: 0.2,
|
||||
child: Icon(Octicons.package,
|
||||
color: primaryColor, size: 200),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SuggestList(
|
||||
recentSearchList: _oldFilters,
|
||||
onTap: (String s) {
|
||||
query = s;
|
||||
showResults(context);
|
||||
},
|
||||
prefKey: 'package_search');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ import 'package:fcs/pagination/paginator_listener.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' as Path;
|
||||
|
||||
import '../../../helpers/shared_pref.dart';
|
||||
|
||||
class PickupModel extends BaseModel {
|
||||
final log = Logger('PickupModel');
|
||||
PaginatorListener<Pickup>? pickups;
|
||||
@@ -86,6 +88,9 @@ class PickupModel extends BaseModel {
|
||||
}
|
||||
|
||||
Future<List<Pickup>> searchPickup(String term) async {
|
||||
if (term != '') {
|
||||
await SharedPref.saveRecentSearch('pickup_search', term);
|
||||
}
|
||||
Future<List<Pickup>> pickups =
|
||||
Services.instance.pickupService.searchPickup(term);
|
||||
return pickups;
|
||||
|
||||
@@ -9,6 +9,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../helpers/shared_pref.dart';
|
||||
import '../widgets/suggest_list.dart';
|
||||
|
||||
Future<Pickup?> searchPickup(BuildContext context,
|
||||
{CallbackPickupSelect? callbackPickupSelect}) async =>
|
||||
await showSearch<Pickup>(
|
||||
@@ -32,7 +35,7 @@ class PackageSearchDelegate extends SearchDelegate<Pickup> {
|
||||
appBarTheme: AppBarTheme(color: primaryColor),
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
iconColor: MaterialStateProperty.all<Color>(Colors.white))),
|
||||
iconColor: WidgetStateProperty.all<Color>(Colors.white))),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
border: InputBorder.none,
|
||||
hintStyle: TextStyle(color: Colors.grey, fontSize: 14)),
|
||||
@@ -124,13 +127,27 @@ class PackageSearchDelegate extends SearchDelegate<Pickup> {
|
||||
|
||||
@override
|
||||
Widget buildSuggestions(BuildContext context) {
|
||||
return Container(
|
||||
child: Center(
|
||||
child: Opacity(
|
||||
opacity: 0.2,
|
||||
child: Icon(SimpleLineIcons.direction,
|
||||
size: 200, color: primaryColor)),
|
||||
),
|
||||
return FutureBuilder<List<String>?>(
|
||||
future: SharedPref.getRecentSearch('pickup_search', query),
|
||||
builder: (context, snapshot) {
|
||||
List<String> _oldFilters = snapshot.data ?? [];
|
||||
if (_oldFilters.isEmpty) {
|
||||
return const Center(
|
||||
child: Opacity(
|
||||
opacity: 0.2,
|
||||
child: Icon(SimpleLineIcons.direction,
|
||||
color: primaryColor, size: 200),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SuggestList(
|
||||
recentSearchList: _oldFilters,
|
||||
onTap: (String s) {
|
||||
query = s;
|
||||
showResults(context);
|
||||
},
|
||||
prefKey: 'pickup_search');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ import 'package:fcs/pages/main/util.dart';
|
||||
import 'package:fcs/pages/widgets/input_text.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../widgets/local_text.dart';
|
||||
import 'model/shipment_rate_model.dart';
|
||||
|
||||
class CargoEditor extends StatefulWidget {
|
||||
@@ -20,11 +22,13 @@ class CargoEditor extends StatefulWidget {
|
||||
class _CargoEditorState extends State<CargoEditor> {
|
||||
TextEditingController _descController = new TextEditingController();
|
||||
TextEditingController _rateController = new TextEditingController();
|
||||
TextEditingController _displayIndexController = new TextEditingController();
|
||||
|
||||
bool _isLoading = false;
|
||||
late CargoType _cargo;
|
||||
bool _isNew = false;
|
||||
final _cargoFormKey = GlobalKey<FormState>();
|
||||
bool _isDefault = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -33,6 +37,8 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
_cargo = widget.cargo!;
|
||||
_descController.text = _cargo.name ?? "";
|
||||
_rateController.text = _cargo.rate.toStringAsFixed(2);
|
||||
_displayIndexController.text = _cargo.displayIndex.toString();
|
||||
_isDefault = _cargo.isDefault;
|
||||
} else {
|
||||
_isNew = true;
|
||||
}
|
||||
@@ -46,20 +52,23 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final typeBox = InputText(
|
||||
labelTextKey: 'cargo.type',
|
||||
iconData: Icons.text_format,
|
||||
controller: _descController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value){
|
||||
if(value==null || value.isEmpty){
|
||||
return "Please insert cargo type";
|
||||
}
|
||||
return null;
|
||||
},);
|
||||
labelTextKey: 'cargo.type',
|
||||
iconData: Icons.text_format,
|
||||
controller: _descController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Please insert cargo type";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
final rateBox = InputText(
|
||||
labelTextKey: 'cargo.rate',
|
||||
iconData: Icons.attach_money,
|
||||
controller: _rateController,
|
||||
textInputType: TextInputType.number,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
@@ -68,6 +77,51 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
final displayIndexBox = InputText(
|
||||
labelTextKey: 'cargo.display_index',
|
||||
iconData: Icons.numbers,
|
||||
controller: _displayIndexController,
|
||||
textInputType: TextInputType.number,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Please insert display index";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
final defaultBox = Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocalText(
|
||||
context,
|
||||
'cargo.is_default',
|
||||
color: Colors.black54,
|
||||
fontSize: 15,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Transform.scale(
|
||||
scale: 0.7,
|
||||
alignment: Alignment.centerRight,
|
||||
child: CupertinoSwitch(
|
||||
activeColor: primaryColor,
|
||||
value: _isDefault,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_isDefault = v;
|
||||
});
|
||||
}))
|
||||
]),
|
||||
);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
@@ -105,6 +159,8 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
children: <Widget>[
|
||||
typeBox,
|
||||
rateBox,
|
||||
displayIndexBox,
|
||||
defaultBox,
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
@@ -131,7 +187,10 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
CargoType _cargo = CargoType(
|
||||
name: _descController.text, rate: double.parse(_rateController.text));
|
||||
name: _descController.text,
|
||||
rate: double.parse(_rateController.text),
|
||||
displayIndex: int.parse(_displayIndexController.text),
|
||||
isDefault: _isDefault);
|
||||
if (_isNew) {
|
||||
await shipmentRateModel.addCargoType(_cargo);
|
||||
} else {
|
||||
|
||||
@@ -37,7 +37,7 @@ class UserSearchDelegate extends SearchDelegate<User> {
|
||||
appBarTheme: AppBarTheme(color: primaryColor),
|
||||
iconButtonTheme: IconButtonThemeData(
|
||||
style: ButtonStyle(
|
||||
iconColor: MaterialStateProperty.all<Color>(Colors.white))),
|
||||
iconColor: WidgetStateProperty.all<Color>(Colors.white))),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
border: InputBorder.none,
|
||||
hintStyle: TextStyle(color: Colors.grey, fontSize: 14)),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
|
||||
import '../helpers/theme.dart';
|
||||
import 'paginator_listener.dart';
|
||||
@@ -99,7 +100,23 @@ class _PaginatorListViewState<T> extends State<PaginatorListView<T>> {
|
||||
);
|
||||
}
|
||||
T t = _paginatorListener.data[index];
|
||||
return widget.rowBuilder(t);
|
||||
return Slidable(
|
||||
enabled: widget.onRemove != null ? true : false,
|
||||
endActionPane: ActionPane(
|
||||
extentRatio: 0.25,
|
||||
motion: const ScrollMotion(),
|
||||
children: widget.onRemove != null
|
||||
? [
|
||||
SlidableAction(
|
||||
onPressed: ((context) => widget.onRemove!(t)),
|
||||
backgroundColor: Colors.red,
|
||||
icon: Icons.delete,
|
||||
label: 'Delete',
|
||||
),
|
||||
]
|
||||
: [],
|
||||
),
|
||||
child: widget.rowBuilder(t));
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -58,6 +58,7 @@ dependencies:
|
||||
pdf: ^3.10.8
|
||||
qr_flutter: ^4.1.0
|
||||
flutter_markdown: ^0.6.20+1
|
||||
flutter_slidable: ^3.1.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user