Merge branch 'master' of tzw/fcs into master
This commit is contained in:
@@ -266,7 +266,7 @@
|
|||||||
"box.delivery_type":"Delivery type",
|
"box.delivery_type":"Delivery type",
|
||||||
"box.fcs_shipment_num":"Shipment",
|
"box.fcs_shipment_num":"Shipment",
|
||||||
"box.fcs.id":"FCS ID",
|
"box.fcs.id":"FCS ID",
|
||||||
"box.name":"Customer name",
|
"box.name":"Sender",
|
||||||
"box.phone":"Phone number",
|
"box.phone":"Phone number",
|
||||||
"box.actual_weight":"Actual weight",
|
"box.actual_weight":"Actual weight",
|
||||||
"box.add_cargo":"Add cargo",
|
"box.add_cargo":"Add cargo",
|
||||||
@@ -326,6 +326,14 @@
|
|||||||
"box.package_size":"Package",
|
"box.package_size":"Package",
|
||||||
"box.select.cartion":"Select cartons",
|
"box.select.cartion":"Select cartons",
|
||||||
"box.no_carton":"There is no cartons in this shipment.",
|
"box.no_carton":"There is no cartons in this shipment.",
|
||||||
|
"box.crete.carton":"Create carton",
|
||||||
|
"box.carton.type":"Carton Type",
|
||||||
|
"box.select.delivery":"Select delivery type",
|
||||||
|
"box.select.package":"Select packages",
|
||||||
|
"box.no_package":"There is no packages.",
|
||||||
|
"box.input_cargo_weight":"Input cargo weight (lb)",
|
||||||
|
"box.input_surcharge_item":"Input surcharge items",
|
||||||
|
"box.select.cargo_type":"Select surcharge item",
|
||||||
"Boxes End ================================================================":"",
|
"Boxes End ================================================================":"",
|
||||||
|
|
||||||
"Delivery Start ================================================================":"",
|
"Delivery Start ================================================================":"",
|
||||||
@@ -592,7 +600,7 @@
|
|||||||
"processing.new":"New Processing",
|
"processing.new":"New Processing",
|
||||||
"processing.create":"New Processing",
|
"processing.create":"New Processing",
|
||||||
"processing.update":"Update Processing",
|
"processing.update":"Update Processing",
|
||||||
"processing.consignee.name":"Consignee name",
|
"processing.consignee.name":"Consignee",
|
||||||
"processing.shipper.name":"Sender name",
|
"processing.shipper.name":"Sender name",
|
||||||
"processing.package.select.btn":"Select",
|
"processing.package.select.btn":"Select",
|
||||||
"processing.package.create":"New Package",
|
"processing.package.create":"New Package",
|
||||||
|
|||||||
@@ -266,7 +266,7 @@
|
|||||||
"box.delivery_type":"ပို့ဆောင်ရမည့်အမျိုးအစား",
|
"box.delivery_type":"ပို့ဆောင်ရမည့်အမျိုးအစား",
|
||||||
"box.fcs_shipment_num":"တင်ပို့နံပါတ်",
|
"box.fcs_shipment_num":"တင်ပို့နံပါတ်",
|
||||||
"box.fcs.id":"FCS ID",
|
"box.fcs.id":"FCS ID",
|
||||||
"box.name":"နာမည်",
|
"box.name":"ပေးပို့သူ",
|
||||||
"box.package":"အထုပ်များ",
|
"box.package":"အထုပ်များ",
|
||||||
"box.phone":"ဖုန်းနံပါတ်",
|
"box.phone":"ဖုန်းနံပါတ်",
|
||||||
"box.actual_weight":"အမှန်အလေးချိန်",
|
"box.actual_weight":"အမှန်အလေးချိန်",
|
||||||
@@ -325,6 +325,14 @@
|
|||||||
"box.package_size":"Package",
|
"box.package_size":"Package",
|
||||||
"box.select.cartion":"Select cartons",
|
"box.select.cartion":"Select cartons",
|
||||||
"box.no_carton":"There is no cartons in this shipment.",
|
"box.no_carton":"There is no cartons in this shipment.",
|
||||||
|
"box.crete.carton":"Create carton",
|
||||||
|
"box.carton.type":"Carton Type",
|
||||||
|
"box.select.delivery":"Select delivery type",
|
||||||
|
"box.select.package":"Select packages",
|
||||||
|
"box.no_package":"There is no packages.",
|
||||||
|
"box.input_cargo_weight":"Input cargo weight (lb)",
|
||||||
|
"box.input_surcharge_item":"Input surcharge items",
|
||||||
|
"box.select.cargo_type":"Select surcharge item",
|
||||||
"Boxes End ================================================================":"",
|
"Boxes End ================================================================":"",
|
||||||
|
|
||||||
"Delivery Start ================================================================":"",
|
"Delivery Start ================================================================":"",
|
||||||
@@ -595,7 +603,7 @@
|
|||||||
"processing.new":"လုပ်ဆောင်ခြင်း အသစ်",
|
"processing.new":"လုပ်ဆောင်ခြင်း အသစ်",
|
||||||
"processing.create":"လုပ်ဆောင်ခြင်း အသစ်",
|
"processing.create":"လုပ်ဆောင်ခြင်း အသစ်",
|
||||||
"processing.update":"လုပ်ဆောင်ခြင်း ပြင်ဆင်ခြင်း",
|
"processing.update":"လုပ်ဆောင်ခြင်း ပြင်ဆင်ခြင်း",
|
||||||
"processing.consignee.name":"လက်ခံသူ အမည်",
|
"processing.consignee.name":"လက်ခံသူ",
|
||||||
"processing.shipper.name":"တင်ပို့သူ အမည်",
|
"processing.shipper.name":"တင်ပို့သူ အမည်",
|
||||||
"processing.package.select.btn":"ရွေးချယ်မည်",
|
"processing.package.select.btn":"ရွေးချယ်မည်",
|
||||||
"processing.package.create":"အထုပ် အသစ်",
|
"processing.package.create":"အထုပ် အသစ်",
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'pages/carton/model/carton_selection_model.dart';
|
import 'pages/carton/model/carton_selection_model.dart';
|
||||||
|
import 'pages/carton/model/package_selection_model.dart';
|
||||||
import 'pages/delivery/model/delivery_model.dart';
|
import 'pages/delivery/model/delivery_model.dart';
|
||||||
|
|
||||||
class App extends StatefulWidget {
|
class App extends StatefulWidget {
|
||||||
@@ -64,6 +65,7 @@ class _AppState extends State<App> {
|
|||||||
final ProcessingModel processingModel = new ProcessingModel();
|
final ProcessingModel processingModel = new ProcessingModel();
|
||||||
final PickupModel pickupModel = new PickupModel();
|
final PickupModel pickupModel = new PickupModel();
|
||||||
final CartonSelectionModel cartonSelectionModel = new CartonSelectionModel();
|
final CartonSelectionModel cartonSelectionModel = new CartonSelectionModel();
|
||||||
|
final PackageSelectionModel packageSelectionModel = new PackageSelectionModel();
|
||||||
|
|
||||||
late AppTranslationsDelegate _newLocaleDelegate;
|
late AppTranslationsDelegate _newLocaleDelegate;
|
||||||
|
|
||||||
@@ -87,7 +89,8 @@ class _AppState extends State<App> {
|
|||||||
..addModel(cartonSizeModel)
|
..addModel(cartonSizeModel)
|
||||||
..addModel(processingModel)
|
..addModel(processingModel)
|
||||||
..addModel(pickupModel)
|
..addModel(pickupModel)
|
||||||
..addModel(cartonSelectionModel);
|
..addModel(cartonSelectionModel)
|
||||||
|
..addModel(packageSelectionModel);
|
||||||
|
|
||||||
_newLocaleDelegate = AppTranslationsDelegate(
|
_newLocaleDelegate = AppTranslationsDelegate(
|
||||||
newLocale: Translation().supportedLocales().first);
|
newLocale: Translation().supportedLocales().first);
|
||||||
@@ -137,6 +140,7 @@ class _AppState extends State<App> {
|
|||||||
ChangeNotifierProvider.value(value: processingModel),
|
ChangeNotifierProvider.value(value: processingModel),
|
||||||
ChangeNotifierProvider.value(value: pickupModel),
|
ChangeNotifierProvider.value(value: pickupModel),
|
||||||
ChangeNotifierProvider.value(value: cartonSelectionModel),
|
ChangeNotifierProvider.value(value: cartonSelectionModel),
|
||||||
|
ChangeNotifierProvider.value(value: packageSelectionModel),
|
||||||
],
|
],
|
||||||
child: Consumer<LanguageModel>(
|
child: Consumer<LanguageModel>(
|
||||||
builder: (context, value, child) {
|
builder: (context, value, child) {
|
||||||
|
|||||||
@@ -133,3 +133,7 @@ const invoice_paid_status = "paid";
|
|||||||
const payment_pending_status = "pending";
|
const payment_pending_status = "pending";
|
||||||
const payment_confirmed_status = "confirmed";
|
const payment_confirmed_status = "confirmed";
|
||||||
const payment_canceled_status = "canceled";
|
const payment_canceled_status = "canceled";
|
||||||
|
|
||||||
|
//Delivery types
|
||||||
|
const delivery_caton = "Delivery carton";
|
||||||
|
const pickup_carton = "Pick-up carton";
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class CargoType {
|
|||||||
double weight;
|
double weight;
|
||||||
bool isChecked;
|
bool isChecked;
|
||||||
int qty;
|
int qty;
|
||||||
bool? isCutomDuty;
|
bool isCutomDuty;
|
||||||
double customDutyFee;
|
double customDutyFee;
|
||||||
double calRate;
|
double calRate;
|
||||||
double calWeight;
|
double calWeight;
|
||||||
@@ -21,7 +21,7 @@ class CargoType {
|
|||||||
this.calRate = 0,
|
this.calRate = 0,
|
||||||
this.isChecked = false,
|
this.isChecked = false,
|
||||||
this.qty = 0,
|
this.qty = 0,
|
||||||
this.isCutomDuty,
|
this.isCutomDuty = false,
|
||||||
this.customDutyFee = 0});
|
this.customDutyFee = 0});
|
||||||
|
|
||||||
factory CargoType.fromMap(Map<String, dynamic> map, String id) {
|
factory CargoType.fromMap(Map<String, dynamic> map, String id) {
|
||||||
@@ -33,8 +33,8 @@ class CargoType {
|
|||||||
calWeight: map['cal_weight']?.toDouble() ?? 0,
|
calWeight: map['cal_weight']?.toDouble() ?? 0,
|
||||||
calRate: map['cal_rate']?.toDouble() ?? 0,
|
calRate: map['cal_rate']?.toDouble() ?? 0,
|
||||||
isCutomDuty: map['custom_duty'] ?? false,
|
isCutomDuty: map['custom_duty'] ?? false,
|
||||||
customDutyFee: (map['custom_duty_fee'] ?? 0).toDouble(),
|
customDutyFee: (map['custom_duty_fee'] ?? 0).toDouble());
|
||||||
qty: (map['qty'] ?? 0).toInt());
|
//qty: (map['qty'] ?? 0).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class Package {
|
|||||||
DateTime? currentStatusDate;
|
DateTime? currentStatusDate;
|
||||||
List<String> photoUrls;
|
List<String> photoUrls;
|
||||||
List<ShipmentStatus> shipmentHistory;
|
List<ShipmentStatus> shipmentHistory;
|
||||||
|
List<String> cartonIds;
|
||||||
String? desc;
|
String? desc;
|
||||||
|
|
||||||
String? status;
|
String? status;
|
||||||
@@ -69,7 +70,8 @@ class Package {
|
|||||||
this.deliveryAddress,
|
this.deliveryAddress,
|
||||||
this.isChecked = false,
|
this.isChecked = false,
|
||||||
this.photoFiles = const [],
|
this.photoFiles = const [],
|
||||||
this.senderPhoneNumber});
|
this.senderPhoneNumber,
|
||||||
|
this.cartonIds = const []});
|
||||||
|
|
||||||
factory Package.fromMap(Map<String, dynamic> map, String docID) {
|
factory Package.fromMap(Map<String, dynamic> map, String docID) {
|
||||||
var _currentStatusDate = (map['status_date'] as Timestamp);
|
var _currentStatusDate = (map['status_date'] as Timestamp);
|
||||||
@@ -82,6 +84,9 @@ class Package {
|
|||||||
var da = map['delivery_address'];
|
var da = map['delivery_address'];
|
||||||
var _da = da != null ? DeliveryAddress.fromMap(da, da["id"]) : null;
|
var _da = da != null ? DeliveryAddress.fromMap(da, da["id"]) : null;
|
||||||
|
|
||||||
|
List<String> cartonIds =
|
||||||
|
map['carton_ids'] == null ? [] : List.from(map['carton_ids']);
|
||||||
|
|
||||||
return Package(
|
return Package(
|
||||||
id: docID,
|
id: docID,
|
||||||
userID: map['user_id'],
|
userID: map['user_id'],
|
||||||
@@ -99,7 +104,8 @@ class Package {
|
|||||||
deliveryAddress: _da,
|
deliveryAddress: _da,
|
||||||
currentStatusDate: _currentStatusDate.toDate().toLocal(),
|
currentStatusDate: _currentStatusDate.toDate().toLocal(),
|
||||||
photoUrls: _photoUrls,
|
photoUrls: _photoUrls,
|
||||||
shipmentHistory: _shipmentStatus);
|
shipmentHistory: _shipmentStatus,
|
||||||
|
cartonIds: cartonIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
padding: const EdgeInsets.only(right: 48.0),
|
padding: const EdgeInsets.only(right: 48.0),
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
child: Text(total.toStringAsFixed(2),
|
child: Text(total.toStringAsFixed(2)+" lb",
|
||||||
style: TextStyle(fontWeight: FontWeight.bold))),
|
style: TextStyle(fontWeight: FontWeight.bold))),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
356
lib/pages/carton/cargo_widget.dart
Normal file
356
lib/pages/carton/cargo_widget.dart
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
import 'package:fcs/helpers/theme.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../domain/entities/cargo_type.dart';
|
||||||
|
import '../../domain/entities/user.dart';
|
||||||
|
import '../rates/model/shipment_rate_model.dart';
|
||||||
|
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';
|
||||||
|
|
||||||
|
typedef OnPrevious = Function(
|
||||||
|
List<CargoType> cargoTypes, List<CargoType> customDuties);
|
||||||
|
typedef OnContinue = Function(
|
||||||
|
List<CargoType> cargoTypes, List<CargoType> customDuties);
|
||||||
|
|
||||||
|
class CargoWidget extends StatefulWidget {
|
||||||
|
final User sender;
|
||||||
|
final User consignee;
|
||||||
|
final List<CargoType> cargoTypes;
|
||||||
|
final List<CargoType> customDuties;
|
||||||
|
final OnPrevious? onPrevious;
|
||||||
|
final OnContinue? onContinue;
|
||||||
|
|
||||||
|
const CargoWidget({
|
||||||
|
Key? key,
|
||||||
|
required this.cargoTypes,
|
||||||
|
required this.customDuties,
|
||||||
|
this.onPrevious,
|
||||||
|
this.onContinue,
|
||||||
|
required this.sender,
|
||||||
|
required this.consignee,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CargoWidget> createState() => _CargoWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CargoWidgetState extends State<CargoWidget> {
|
||||||
|
List<CargoType> _cargoTypes = [];
|
||||||
|
List<CargoType> _customDuties = [];
|
||||||
|
TextEditingController _totalCtl = TextEditingController();
|
||||||
|
List<TextEditingController> _cargoTypeControllers = [];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
var model = context.read<ShipmentRateModel>();
|
||||||
|
_cargoTypes = model.rate.cargoTypes.map((e) => e.clone()).toList();
|
||||||
|
|
||||||
|
if (widget.cargoTypes.isNotEmpty) {
|
||||||
|
} else {
|
||||||
|
_cargoTypes.forEach((e) {
|
||||||
|
var editor = new TextEditingController();
|
||||||
|
editor.text = '';
|
||||||
|
editor.addListener(inputChangeListener);
|
||||||
|
_cargoTypeControllers.add(editor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFieldEmpty(int index) {
|
||||||
|
return _cargoTypeControllers[index].text.isEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int> getEmptyFields() {
|
||||||
|
List<int> emptyFields = [];
|
||||||
|
for (int i = 0; i < _cargoTypeControllers.length; i++) {
|
||||||
|
if (isFieldEmpty(i)) {
|
||||||
|
emptyFields.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return emptyFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
inputChangeListener() {
|
||||||
|
List<int> emptyFields = getEmptyFields();
|
||||||
|
print("emptyFields:$emptyFields");
|
||||||
|
|
||||||
|
// if (emptyFields.isNotEmpty && emptyFields.length == 1) {
|
||||||
|
// // _cargoTypeControllers[emptyFields.first].text =
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (emptyFields.isEmpty) {
|
||||||
|
_cargoTypes.asMap().entries.forEach((e) {
|
||||||
|
_cargoTypes[e.key].weight =
|
||||||
|
double.tryParse(_cargoTypeControllers[e.key].text) ?? 0;
|
||||||
|
});
|
||||||
|
double total = _cargoTypes.fold(0, (sum, value) => sum + value.weight);
|
||||||
|
setState(() {
|
||||||
|
_totalCtl.text = total.toString();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// if (emptyFields.length == 1) {
|
||||||
|
// print("_totalCtl.text:${_totalCtl.text}");
|
||||||
|
|
||||||
|
// if (_totalCtl.text.isNotEmpty) {
|
||||||
|
// double t = double.tryParse(_totalCtl.text) ?? 0;
|
||||||
|
|
||||||
|
// _cargoTypes.asMap().entries.forEach((e) {
|
||||||
|
// _cargoTypes[e.key].weight =
|
||||||
|
// double.tryParse(_cargoTypeControllers[e.key].text) ?? 0;
|
||||||
|
// });
|
||||||
|
// double result =
|
||||||
|
// _cargoTypes.fold(0, (sum, value) => sum + value.weight);
|
||||||
|
|
||||||
|
// double remaining = t - result;
|
||||||
|
// setState(() {
|
||||||
|
// _cargoTypeControllers[emptyFields.first].text =
|
||||||
|
// remaining.toString();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final senderBox = DisplayText(
|
||||||
|
text: widget.sender.name,
|
||||||
|
labelTextKey: "box.sender.title",
|
||||||
|
iconData: MaterialCommunityIcons.account_arrow_right,
|
||||||
|
subText: Text(widget.sender.fcsID!,
|
||||||
|
style: TextStyle(fontSize: 13, color: labelColor)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final consigneeBox = DisplayText(
|
||||||
|
text: widget.consignee.name,
|
||||||
|
labelTextKey: "box.consignee.title",
|
||||||
|
iconData: MaterialCommunityIcons.account_arrow_left,
|
||||||
|
subText: Text(widget.consignee.fcsID!,
|
||||||
|
style: TextStyle(fontSize: 13, color: labelColor)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final userRow = Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: senderBox,
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
Flexible(child: consigneeBox)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final cargosBox = Wrap(
|
||||||
|
alignment: WrapAlignment.spaceBetween,
|
||||||
|
runSpacing: 15,
|
||||||
|
children: _cargoTypes.asMap().entries.map((e) {
|
||||||
|
var key = e.key;
|
||||||
|
var c = e.value;
|
||||||
|
return SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width / 2.3,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
InkResponse(
|
||||||
|
radius: 25,
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_cargoTypeControllers[key].clear();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Icon(MaterialIcons.clear)),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Flexible(
|
||||||
|
child: inputTextFieldWidget(context,
|
||||||
|
lableText: c.name ?? "",
|
||||||
|
controller: _cargoTypeControllers[key]
|
||||||
|
// onChanged: (newValue) {
|
||||||
|
// setState(() {
|
||||||
|
// _cargoTypes[key].weight = double.tryParse(newValue) ?? 0;
|
||||||
|
// });
|
||||||
|
// double total =
|
||||||
|
// _cargoTypes.fold(0, (sum, value) => sum + value.weight);
|
||||||
|
// setState(() {
|
||||||
|
// _totalCtl.text = total.toString();
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList());
|
||||||
|
|
||||||
|
final totalBox = Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width / 2.3,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
InkResponse(
|
||||||
|
radius: 25,
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_totalCtl.clear();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Icon(MaterialIcons.clear)),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Flexible(
|
||||||
|
child: inputTextFieldWidget(context,
|
||||||
|
lableText: "Total", controller: _totalCtl),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final subchargeItemTitleBox = LocalTitle(
|
||||||
|
textKey: "box.input_surcharge_item",
|
||||||
|
trailing: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.add_circle,
|
||||||
|
color: primaryColor,
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
List<CargoType>? customList = await Navigator.push<List<CargoType>>(
|
||||||
|
context,
|
||||||
|
CupertinoPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
CustomDutyAddition(customDuties: _customDuties)));
|
||||||
|
if (customList == null) return;
|
||||||
|
|
||||||
|
_customDuties = List.from(customList);
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
final subChargeItemsBox = Wrap(
|
||||||
|
alignment: WrapAlignment.spaceBetween,
|
||||||
|
runSpacing: 15,
|
||||||
|
children: _customDuties.asMap().entries.map((e) {
|
||||||
|
var key = e.key;
|
||||||
|
var c = e.value;
|
||||||
|
return SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width / 2.3,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
InkResponse(
|
||||||
|
radius: 25,
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_customDuties.removeAt(key);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Icon(Feather.minus_circle)),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Flexible(
|
||||||
|
child: inputTextFieldWidget(
|
||||||
|
context,
|
||||||
|
lableText: c.name ?? "",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList());
|
||||||
|
|
||||||
|
final continueBtn = ContinueButton(
|
||||||
|
onTap: () {
|
||||||
|
// if (selectedPackageList.isEmpty || searchResults.isEmpty) {
|
||||||
|
// showMsgDialog(context, 'Error', "Please select the packages");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (widget.onContinue != null) {
|
||||||
|
// widget.onContinue!(selectedPackageList);
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final previousBtn = PreviousButton(onTap: () {
|
||||||
|
if (widget.onPrevious != null) {
|
||||||
|
widget.onPrevious!(_cargoTypes, _customDuties);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: ListView(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
userRow,
|
||||||
|
LocalTitle(textKey: "box.input_cargo_weight", topPadding: 10),
|
||||||
|
cargosBox,
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
Divider(),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
totalBox,
|
||||||
|
subchargeItemTitleBox,
|
||||||
|
subChargeItemsBox,
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
widget.onContinue != null
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 15, right: 15, top: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
previousBtn,
|
||||||
|
continueBtn,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
const SizedBox(height: 20)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget inputTextFieldWidget(BuildContext context,
|
||||||
|
{required String lableText,
|
||||||
|
TextEditingController? controller,
|
||||||
|
Function(String)? onChanged}) {
|
||||||
|
return TextFormField(
|
||||||
|
controller: controller,
|
||||||
|
style: textStyle,
|
||||||
|
cursorColor: primaryColor,
|
||||||
|
keyboardType: TextInputType.number,
|
||||||
|
onChanged: onChanged,
|
||||||
|
decoration: new InputDecoration(
|
||||||
|
contentPadding: EdgeInsets.all(0),
|
||||||
|
labelText: lableText,
|
||||||
|
labelStyle: newLabelStyle(color: Colors.black54, fontSize: 17),
|
||||||
|
enabledBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: primaryColor, width: 1.0)),
|
||||||
|
focusedBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: primaryColor, width: 1.0)),
|
||||||
|
disabledBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: primaryColor, width: 1.0)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,7 +90,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
DataCell(
|
DataCell(
|
||||||
c.isCutomDuty!
|
c.isCutomDuty
|
||||||
? GestureDetector(
|
? GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
String? _t = await showDialog(
|
String? _t = await showDialog(
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import 'package:fcs/pages/widgets/progress.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||||
import 'mix_cation/mix_cartion_editor.dart';
|
import '../main/util.dart';
|
||||||
|
import 'carton_editor_for_package.dart';
|
||||||
|
import 'mix_carton/mix_carton_editor.dart';
|
||||||
import 'carton_row.dart';
|
import 'carton_row.dart';
|
||||||
|
|
||||||
class CartonEditor extends StatefulWidget {
|
class CartonEditor extends StatefulWidget {
|
||||||
@@ -26,7 +28,7 @@ class CartonEditor extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CartonEditorState extends State<CartonEditor> {
|
class _CartonEditorState extends State<CartonEditor> {
|
||||||
List<String> cartonTypes = [carton_from_packages, carton_mix_carton];
|
List<String> _cartonTypes = [carton_from_packages, carton_mix_carton];
|
||||||
List<Carton> _cartons = [];
|
List<Carton> _cartons = [];
|
||||||
|
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
@@ -34,23 +36,26 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
int _billToValue = 1;
|
int _billToValue = 1;
|
||||||
String? _selectedCartonType;
|
String? _selectedCartonType;
|
||||||
|
|
||||||
User? consignee;
|
User? _consignee;
|
||||||
User? sender;
|
User? _sender;
|
||||||
Carton? _carton;
|
Carton? _carton;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
_init();
|
||||||
super.initState();
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
if (widget.carton != null) {
|
if (widget.carton != null) {
|
||||||
_carton = widget.carton;
|
_carton = widget.carton;
|
||||||
_selectedCartonType = _carton!.cartonType;
|
_selectedCartonType = _carton!.cartonType;
|
||||||
|
|
||||||
_isNew = false;
|
_isNew = false;
|
||||||
|
|
||||||
consignee = User(
|
_consignee = User(
|
||||||
id: _carton!.userID, fcsID: _carton!.fcsID, name: _carton!.userName);
|
id: _carton!.userID, fcsID: _carton!.fcsID, name: _carton!.userName);
|
||||||
sender = User(
|
_sender = User(
|
||||||
id: _carton!.senderID,
|
id: _carton!.senderID,
|
||||||
fcsID: _carton!.senderFCSID,
|
fcsID: _carton!.senderFCSID,
|
||||||
name: _carton!.senderName);
|
name: _carton!.senderName);
|
||||||
@@ -62,6 +67,20 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
Carton(cartonNumber: "A177(A)-3#2", cartonWeight: 35.5),
|
Carton(cartonNumber: "A177(A)-3#2", cartonWeight: 35.5),
|
||||||
Carton(cartonNumber: "A177(A)-3#1", cartonWeight: 25.5)
|
Carton(cartonNumber: "A177(A)-3#1", cartonWeight: 25.5)
|
||||||
];
|
];
|
||||||
|
_sender = User(
|
||||||
|
name: "ptd-phyo44 kaelone",
|
||||||
|
fcsID: "FCS-8X6V",
|
||||||
|
phoneNumber: "+959444444444",
|
||||||
|
id: "48u_4s-HiQeW-HwSqeRd9TSMWh3mLZfSk5rpaUEh_zw");
|
||||||
|
|
||||||
|
_consignee = User(
|
||||||
|
id: "HsIwG88K-0_HSazgEy5QR27kcjkOvfv7_Sr1JP18Q1A",
|
||||||
|
name: "One One",
|
||||||
|
phoneNumber: "+959111111111",
|
||||||
|
fcsID: "FCS-EFRF");
|
||||||
|
}
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +126,7 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
|
|
||||||
final cartonTypeBox = LocalRadioButtons(
|
final cartonTypeBox = LocalRadioButtons(
|
||||||
readOnly: !_isNew,
|
readOnly: !_isNew,
|
||||||
values: cartonTypes,
|
values: _cartonTypes,
|
||||||
selectedValue: _selectedCartonType,
|
selectedValue: _selectedCartonType,
|
||||||
callback: (String? v) {
|
callback: (String? v) {
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -125,6 +144,22 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
onTap: () {
|
onTap: () {
|
||||||
//for packages
|
//for packages
|
||||||
if (isFromPackages) {
|
if (isFromPackages) {
|
||||||
|
if (_sender == null) {
|
||||||
|
showMsgDialog(
|
||||||
|
context, "Error", "Please select sender's FCS ID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_consignee == null) {
|
||||||
|
showMsgDialog(
|
||||||
|
context, "Error", "Please select consignee's FCS ID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
CupertinoPageRoute(
|
||||||
|
builder: (context) => CartonEditorForPackage(
|
||||||
|
sender: _sender!, consignee: _consignee!)));
|
||||||
}
|
}
|
||||||
// for mix cartion
|
// for mix cartion
|
||||||
else {
|
else {
|
||||||
@@ -153,25 +188,25 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
icon: Icon(Icons.search, color: Colors.black),
|
icon: Icon(Icons.search, color: Colors.black),
|
||||||
onPressed: () => searchUser(context, onUserSelect: (u) {
|
onPressed: () => searchUser(context, onUserSelect: (u) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.consignee = u;
|
this._consignee = u;
|
||||||
});
|
});
|
||||||
}, popPage: true)),
|
}, popPage: true)),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
final consigneefcsIDBox = DisplayText(
|
final consigneefcsIDBox = DisplayText(
|
||||||
text: consignee != null ? consignee!.fcsID : "",
|
text: _consignee != null ? _consignee!.fcsID : "",
|
||||||
labelTextKey: "processing.fcs.id",
|
labelTextKey: "processing.fcs.id",
|
||||||
icon: FcsIDIcon(),
|
icon: FcsIDIcon(),
|
||||||
);
|
);
|
||||||
|
|
||||||
final consigneePhoneBox = DisplayText(
|
final consigneePhoneBox = DisplayText(
|
||||||
text: consignee != null ? consignee!.phoneNumber : "",
|
text: _consignee != null ? _consignee!.phoneNumber : "",
|
||||||
labelTextKey: "processing.phone",
|
labelTextKey: "processing.phone",
|
||||||
iconData: MaterialCommunityIcons.phone);
|
iconData: MaterialCommunityIcons.phone);
|
||||||
|
|
||||||
final consigneeNameBox = DisplayText(
|
final consigneeNameBox = DisplayText(
|
||||||
text: consignee != null ? consignee!.name : "",
|
text: _consignee != null ? _consignee!.name : "",
|
||||||
labelTextKey: "processing.consignee.name",
|
labelTextKey: "processing.consignee.name",
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
iconData: MaterialCommunityIcons.account_arrow_left);
|
iconData: MaterialCommunityIcons.account_arrow_left);
|
||||||
@@ -199,25 +234,25 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
icon: Icon(Icons.search, color: Colors.black),
|
icon: Icon(Icons.search, color: Colors.black),
|
||||||
onPressed: () => searchUser(context, onUserSelect: (u) {
|
onPressed: () => searchUser(context, onUserSelect: (u) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.sender = u;
|
this._sender = u;
|
||||||
});
|
});
|
||||||
}, popPage: true)),
|
}, popPage: true)),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
final senderIDBox = DisplayText(
|
final senderIDBox = DisplayText(
|
||||||
text: sender != null ? sender!.fcsID : "",
|
text: _sender != null ? _sender!.fcsID : "",
|
||||||
labelTextKey: "processing.fcs.id",
|
labelTextKey: "processing.fcs.id",
|
||||||
icon: FcsIDIcon());
|
icon: FcsIDIcon());
|
||||||
|
|
||||||
final senderPhoneBox = DisplayText(
|
final senderPhoneBox = DisplayText(
|
||||||
text: sender != null ? sender!.phoneNumber : "",
|
text: _sender != null ? _sender!.phoneNumber : "",
|
||||||
labelTextKey: "processing.phone",
|
labelTextKey: "processing.phone",
|
||||||
iconData: MaterialCommunityIcons.phone,
|
iconData: MaterialCommunityIcons.phone,
|
||||||
);
|
);
|
||||||
|
|
||||||
final senderNameBox = DisplayText(
|
final senderNameBox = DisplayText(
|
||||||
text: sender != null ? sender!.name : "",
|
text: _sender != null ? _sender!.name : "",
|
||||||
labelTextKey: "processing.shipper.name",
|
labelTextKey: "processing.shipper.name",
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
iconData: MaterialCommunityIcons.account_arrow_right);
|
iconData: MaterialCommunityIcons.account_arrow_right);
|
||||||
|
|||||||
239
lib/pages/carton/carton_editor_for_package.dart
Normal file
239
lib/pages/carton/carton_editor_for_package.dart
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
// ignore_for_file: deprecated_member_use
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../../domain/constants.dart';
|
||||||
|
import '../../../domain/entities/carton_size.dart';
|
||||||
|
import '../../../domain/entities/fcs_shipment.dart';
|
||||||
|
import '../../../domain/vo/local_step.dart';
|
||||||
|
import '../../../helpers/theme.dart';
|
||||||
|
import '../../domain/entities/cargo_type.dart';
|
||||||
|
import '../../domain/entities/package.dart';
|
||||||
|
import '../../domain/entities/user.dart';
|
||||||
|
import '../main/util.dart';
|
||||||
|
import '../widgets/local_text.dart';
|
||||||
|
import '../widgets/progress.dart';
|
||||||
|
import '../widgets/step_widget.dart';
|
||||||
|
import 'cargo_widget.dart';
|
||||||
|
import 'carton_size_widget.dart';
|
||||||
|
import 'model/package_selection_model.dart';
|
||||||
|
import 'package_selection_widget.dart';
|
||||||
|
|
||||||
|
class CartonEditorForPackage extends StatefulWidget {
|
||||||
|
final User sender;
|
||||||
|
final User consignee;
|
||||||
|
const CartonEditorForPackage(
|
||||||
|
{Key? key, required this.sender, required this.consignee})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CartonEditorForPackage> createState() => _CartonEditorForPackageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CartonEditorForPackageState extends State<CartonEditorForPackage> {
|
||||||
|
var dateFormatter = DateFormat('dd MMM yyyy');
|
||||||
|
final NumberFormat numberFormatter = NumberFormat("#,###");
|
||||||
|
List<LocalStep> steps = [
|
||||||
|
LocalStep(lable: 'Size', stepType: StepType.SIZE),
|
||||||
|
LocalStep(lable: 'Packages', stepType: StepType.PACKAGES),
|
||||||
|
LocalStep(lable: 'Cargos', stepType: StepType.CARGOS),
|
||||||
|
LocalStep(lable: 'Submit', stepType: StepType.SUBMIT)
|
||||||
|
];
|
||||||
|
List<Package> _packages = [];
|
||||||
|
List<CargoType> _cargoTypes = [];
|
||||||
|
List<CargoType> _customDuties = [];
|
||||||
|
|
||||||
|
int currentStep = 0;
|
||||||
|
double _length = 0;
|
||||||
|
double _width = 0;
|
||||||
|
double _height = 0;
|
||||||
|
|
||||||
|
String _selectedDeliveryType = delivery_caton;
|
||||||
|
FcsShipment? _shipment;
|
||||||
|
String _cartonSizeType = standardCarton;
|
||||||
|
CartonSize? _standardSize;
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
context.read<PackageSelectionModel>().clearSelection();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return WillPopScope(
|
||||||
|
onWillPop: () {
|
||||||
|
if (currentStep == 0) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
if (currentStep > 0) {
|
||||||
|
setState(() {
|
||||||
|
currentStep -= 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Future.value(false);
|
||||||
|
},
|
||||||
|
child: LocalProgress(
|
||||||
|
inAsyncCall: _isLoading,
|
||||||
|
child: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
elevation: 0,
|
||||||
|
centerTitle: true,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(CupertinoIcons.back,
|
||||||
|
color: primaryColor, size: 25),
|
||||||
|
onPressed: () {
|
||||||
|
if (currentStep == 0) {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
if (currentStep > 0) {
|
||||||
|
setState(() {
|
||||||
|
currentStep -= 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
title: LocalText(context, 'boxes.new',
|
||||||
|
color: primaryColor, fontSize: 20),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
StepperWidget(
|
||||||
|
labels: steps.map((e) => e.lable).toList(),
|
||||||
|
currentStep: currentStep,
|
||||||
|
eachStepWidth: MediaQuery.of(context).size.width / 4,
|
||||||
|
onChange: (index) {
|
||||||
|
if (index > currentStep) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
currentStep = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
getContent(currentStep)
|
||||||
|
],
|
||||||
|
))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget getContent(int index) {
|
||||||
|
var step = steps[index];
|
||||||
|
if (step.stepType == StepType.SIZE) {
|
||||||
|
return Expanded(
|
||||||
|
child: CartonSizeWidget(
|
||||||
|
deliveryType: _selectedDeliveryType,
|
||||||
|
sender: widget.sender,
|
||||||
|
consignee: widget.consignee,
|
||||||
|
shipment: _shipment,
|
||||||
|
cartonSizeType: _cartonSizeType,
|
||||||
|
standardSize: _standardSize,
|
||||||
|
length: _length,
|
||||||
|
width: _width,
|
||||||
|
height: _height,
|
||||||
|
onPrevious: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
onContinue: (deliveryType, shipment, cartonSizeType,
|
||||||
|
{standardSize, length, width, height}) {
|
||||||
|
setState(() {
|
||||||
|
_selectedDeliveryType = deliveryType;
|
||||||
|
_shipment = shipment;
|
||||||
|
_cartonSizeType = cartonSizeType;
|
||||||
|
_standardSize = standardSize;
|
||||||
|
_length = length ?? 0;
|
||||||
|
_width = width ?? 0;
|
||||||
|
_height = height ?? 0;
|
||||||
|
currentStep += 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
));
|
||||||
|
} else if (step.stepType == StepType.PACKAGES) {
|
||||||
|
return Expanded(
|
||||||
|
child: PackageSelectionWidget(
|
||||||
|
sender: widget.sender,
|
||||||
|
consignee: widget.consignee,
|
||||||
|
shipment: _shipment!,
|
||||||
|
packages: _packages,
|
||||||
|
onContinue: (packages) {
|
||||||
|
setState(() {
|
||||||
|
_packages = List.from(packages);
|
||||||
|
currentStep += 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onPrevious: (packages) {
|
||||||
|
setState(() {
|
||||||
|
_packages = List.from(packages);
|
||||||
|
currentStep -= 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (step.stepType == StepType.CARGOS) {
|
||||||
|
return Expanded(
|
||||||
|
child: CargoWidget(
|
||||||
|
sender: widget.sender,
|
||||||
|
consignee: widget.consignee,
|
||||||
|
cargoTypes: _cargoTypes,
|
||||||
|
customDuties: _customDuties,
|
||||||
|
onContinue: (cargoTypes, customDuties) {
|
||||||
|
setState(() {
|
||||||
|
_cargoTypes = List.from(cargoTypes);
|
||||||
|
_customDuties = List.from(customDuties);
|
||||||
|
currentStep += 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onPrevious: (cargoTypes, customDuties) {
|
||||||
|
setState(() {
|
||||||
|
_cargoTypes = List.from(cargoTypes);
|
||||||
|
_customDuties = List.from(customDuties);
|
||||||
|
currentStep -= 1;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Expanded(
|
||||||
|
child: Text("Submit"),
|
||||||
|
// child: MixCartonSubmit(
|
||||||
|
// cartonSizeType: _cartonSizeType,
|
||||||
|
// standardSize: _standardSize,
|
||||||
|
// length: _length,
|
||||||
|
// width: _width,
|
||||||
|
// height: _height,
|
||||||
|
// shipment: _shipment!,
|
||||||
|
// cartons: _packages,
|
||||||
|
// onCreate: () {
|
||||||
|
// _create();
|
||||||
|
// },
|
||||||
|
// onPrevious: () {
|
||||||
|
// setState(() {
|
||||||
|
// currentStep -= 1;
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_create() async {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
} catch (e) {
|
||||||
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'package:fcs/domain/constants.dart';
|
import 'package:fcs/domain/constants.dart';
|
||||||
|
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||||
import 'package:fcs/domain/entities/carton.dart';
|
import 'package:fcs/domain/entities/carton.dart';
|
||||||
import 'package:fcs/domain/entities/package.dart';
|
import 'package:fcs/domain/entities/package.dart';
|
||||||
|
import 'package:fcs/domain/entities/pickup.dart';
|
||||||
import 'package:fcs/domain/vo/delivery_address.dart';
|
import 'package:fcs/domain/vo/delivery_address.dart';
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/carton_size/model/carton_size_model.dart';
|
import 'package:fcs/pages/carton_size/model/carton_size_model.dart';
|
||||||
@@ -15,7 +17,10 @@ import 'package:fcs/pages/widgets/local_app_bar.dart';
|
|||||||
import 'package:fcs/pages/widgets/local_radio_buttons.dart';
|
import 'package:fcs/pages/widgets/local_radio_buttons.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
import 'package:fcs/pages/widgets/local_title.dart';
|
import 'package:fcs/pages/widgets/local_title.dart';
|
||||||
|
import 'package:fcs/pages/widgets/multi_img_controller.dart';
|
||||||
|
import 'package:fcs/pages/widgets/multi_img_file.dart';
|
||||||
import 'package:fcs/pages/widgets/progress.dart';
|
import 'package:fcs/pages/widgets/progress.dart';
|
||||||
|
import 'package:fcs/pages/widgets/status_tree.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||||
@@ -32,8 +37,10 @@ import 'widgets.dart';
|
|||||||
final DateFormat dateFormat = DateFormat("d MMM yyyy");
|
final DateFormat dateFormat = DateFormat("d MMM yyyy");
|
||||||
|
|
||||||
class CartonInfo extends StatefulWidget {
|
class CartonInfo extends StatefulWidget {
|
||||||
final Carton? box;
|
final Package? package;
|
||||||
CartonInfo({this.box});
|
final Carton? box;
|
||||||
|
|
||||||
|
CartonInfo({this.box,this.package});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_CartonInfoState createState() => _CartonInfoState();
|
_CartonInfoState createState() => _CartonInfoState();
|
||||||
@@ -42,7 +49,12 @@ class CartonInfo extends StatefulWidget {
|
|||||||
class _CartonInfoState extends State<CartonInfo> {
|
class _CartonInfoState extends State<CartonInfo> {
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
Carton? _box;
|
Carton? _box;
|
||||||
|
|
||||||
|
List<CargoType>? cargoTypes;
|
||||||
|
List<String> pickups=['203PVH','Fh290','HH211'];
|
||||||
|
Map<String,dynamic> cargos={"General":150,"Electronics":15};
|
||||||
DeliveryAddress? _deliveryAddress = new DeliveryAddress();
|
DeliveryAddress? _deliveryAddress = new DeliveryAddress();
|
||||||
|
MultiImgController multiImgController = MultiImgController();
|
||||||
TextEditingController _widthController = new TextEditingController();
|
TextEditingController _widthController = new TextEditingController();
|
||||||
TextEditingController _heightController = new TextEditingController();
|
TextEditingController _heightController = new TextEditingController();
|
||||||
TextEditingController _lengthController = new TextEditingController();
|
TextEditingController _lengthController = new TextEditingController();
|
||||||
@@ -57,11 +69,13 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
bool isSmallBag = false;
|
bool isSmallBag = false;
|
||||||
bool isFromCartons = false;
|
bool isFromCartons = false;
|
||||||
bool isEdiable = false;
|
bool isEdiable = false;
|
||||||
|
Package? _package;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_box = widget.box;
|
_box = widget.box;
|
||||||
|
initPackage(widget.package);
|
||||||
//for shipment weight
|
//for shipment weight
|
||||||
volumetricRatio = Provider.of<ShipmentRateModel>(context, listen: false)
|
volumetricRatio = Provider.of<ShipmentRateModel>(context, listen: false)
|
||||||
.rate
|
.rate
|
||||||
@@ -74,6 +88,14 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
_loadPackages();
|
_loadPackages();
|
||||||
_loadMixCartons();
|
_loadMixCartons();
|
||||||
}
|
}
|
||||||
|
initPackage(Package? package) {
|
||||||
|
|
||||||
|
if (package == null) return;
|
||||||
|
multiImgController.setImageUrls = package.photoUrls;
|
||||||
|
setState(() {
|
||||||
|
_package = package;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_updateBoxData() {
|
_updateBoxData() {
|
||||||
_widthController.text = _box!.width.toString();
|
_widthController.text = _box!.width.toString();
|
||||||
@@ -176,14 +198,14 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
//iconData: Ionicons.ios_airplane,
|
//iconData: Ionicons.ios_airplane,
|
||||||
);
|
);
|
||||||
final cartonQrBox = DisplayText(
|
final cartonQrBox = DisplayText(
|
||||||
// text: _box!.,
|
// text: _box!.,
|
||||||
//labelTextKey: "box.number",
|
//labelTextKey: "box.number",
|
||||||
iconData: AntDesign.qrcode,
|
iconData: AntDesign.qrcode,
|
||||||
);
|
);
|
||||||
final shipmentBox = DisplayText(
|
final shipmentBox = DisplayText(
|
||||||
text: _box!.fcsShipmentNumber,
|
text: _box!.fcsShipmentNumber,
|
||||||
labelTextKey: "box.fcs_shipment_num",
|
labelTextKey: "box.fcs_shipment_num",
|
||||||
// iconData: Ionicons.ios_airplane,
|
// iconData: Ionicons.ios_airplane,
|
||||||
);
|
);
|
||||||
final deliveryBox = DisplayText(
|
final deliveryBox = DisplayText(
|
||||||
text: "Delivery Carton",
|
text: "Delivery Carton",
|
||||||
@@ -199,8 +221,9 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
|
|
||||||
final customerNameBox = DisplayText(
|
final customerNameBox = DisplayText(
|
||||||
text: _box!.userName == null ? "" : _box!.userName,
|
text: _box!.userName == null ? "" : _box!.userName,
|
||||||
text1: _box!.fcsID == null ? "" : _box!.fcsID,
|
subText: Text(_box!.fcsID ?? "", style: textStyle),
|
||||||
labelTextKey: "box.name",
|
labelTextKey: "box.name",
|
||||||
|
|
||||||
//iconData: Icons.person,
|
//iconData: Icons.person,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -211,18 +234,22 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final consigneeNameBox = DisplayText(
|
final consigneeNameBox = DisplayText(
|
||||||
text: _box!.userName != null ? _box!.userName : "",
|
text: _box!.senderName != null ? _box!.senderName : "",
|
||||||
text1: _box!.fcsID != null ? _box!.fcsID : "",
|
subText: Text(_box!.senderFCSID ?? "", style: textStyle),
|
||||||
|
|
||||||
labelTextKey: "processing.consignee.name",
|
labelTextKey: "processing.consignee.name",
|
||||||
//maxLines: 2,
|
//maxLines: 2,
|
||||||
//iconData: Ionicons.document_text_outline,
|
// iconData: Ionicons.document_text_outline,
|
||||||
);
|
);
|
||||||
|
|
||||||
final consigneeBox = Container(
|
final consigneeBox = Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
consigneefcsIDBox,
|
|
||||||
consigneeNameBox,
|
consigneeNameBox,
|
||||||
|
IconButton(icon:Icon(Ionicons.document_text_outline),
|
||||||
|
onPressed:() {},),
|
||||||
|
Text("Bill to",style:TextStyle(color:Color.fromARGB(255, 57, 80, 233)))
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -282,11 +309,22 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
SizedBox(child: heightBox, width: 80),
|
SizedBox(child: heightBox, width: 80),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
final packageBox = DisplayText(
|
final packageBox = DisplayText(
|
||||||
text: "203FVH",
|
//text: "203FVH",
|
||||||
labelTextKey: "box.package",
|
labelTextKey: "box.package",
|
||||||
//iconData: AntDesign.CodeSandbox,
|
|
||||||
);
|
);
|
||||||
|
final img = MultiImageFile(
|
||||||
|
enabled: false,
|
||||||
|
controller: multiImgController,
|
||||||
|
title: "Receipt File",
|
||||||
|
);
|
||||||
|
final cargoBox = DisplayText(
|
||||||
|
//text: "203FVH",
|
||||||
|
labelTextKey: "box.cargo.type",
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
final cartonSizeBox = DisplayText(
|
final cartonSizeBox = DisplayText(
|
||||||
text: _cartonSizeController.text,
|
text: _cartonSizeController.text,
|
||||||
@@ -353,63 +391,128 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
]
|
]
|
||||||
: [],
|
: [],
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Container(
|
||||||
padding: const EdgeInsets.all(10.0),
|
padding: const EdgeInsets.all(10.0),
|
||||||
child: ListView(shrinkWrap: true, children: <Widget>[
|
child: Row( children: <Widget>[
|
||||||
// Container(child: Row(children: [
|
// Container(child: Row(children: [
|
||||||
// Column(children: [
|
// Column(children: [
|
||||||
// LocalTitle(textKey: "box.type.title"),
|
// LocalTitle(textKey: "box.type.title"),
|
||||||
// Align(
|
// Align(
|
||||||
// alignment: Alignment(-0.1,0.1),
|
// alignment: Alignment(-0.1,0.1),
|
||||||
// child: getCartonNumberStatus(context, _box!)),
|
// child: getCartonNumberStatus(context, _box!)),
|
||||||
|
|
||||||
// ],)
|
// ],)
|
||||||
// ]),),
|
// ]),),
|
||||||
Padding(padding: EdgeInsets.only(left: 30),
|
Padding(
|
||||||
child:
|
padding: EdgeInsets.only(left: 10),
|
||||||
Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [Expanded(child: cartonTypeBox,
|
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
Flexible(
|
|
||||||
child: cartonQrBox,
|
|
||||||
),
|
|
||||||
],)),
|
|
||||||
|
|
||||||
|
|
||||||
Padding(padding: EdgeInsets.only(left: 30),
|
|
||||||
child:
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
children: [Expanded(child: shipmentBox,
|
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
Flexible(
|
|
||||||
child: deliveryBox,
|
|
||||||
),
|
|
||||||
],)),
|
|
||||||
Padding(padding: EdgeInsets.only(left: 30),
|
|
||||||
child:
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Flexible(child: customerNameBox,
|
|
||||||
),
|
|
||||||
|
|
||||||
Flexible(
|
|
||||||
child: consigneeNameBox,
|
|
||||||
),
|
|
||||||
Flexible(child:
|
|
||||||
Column(
|
|
||||||
children: [
|
children: [
|
||||||
Icon(Ionicons.document_text_outline),
|
Expanded(
|
||||||
Text("Bill to",style:TextStyle(color:Colors.blue))
|
child: cartonTypeBox,
|
||||||
]
|
flex: 1,
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: IconButton(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
iconSize: 30,
|
||||||
|
icon: const Icon( AntDesign.qrcode),
|
||||||
|
onPressed: () {
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
)),
|
)),
|
||||||
],)),
|
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: shipmentBox,
|
||||||
|
flex: 1,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: deliveryBox,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: customerNameBox,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: consigneeNameBox,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Column(children: [
|
||||||
|
Icon(Ionicons.document_text_outline),
|
||||||
|
Text("Bill to", style: TextStyle(color: Colors.blue))
|
||||||
|
])),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Padding(padding: EdgeInsets.only(left:10),
|
||||||
|
child: Flexible(child: packageBox)),
|
||||||
|
for(int pack=0;pack<pickups.length;pack++)
|
||||||
|
|
||||||
|
Padding(padding: EdgeInsets.only(left: 10.0),
|
||||||
|
child:
|
||||||
|
Text(pickups[pack],style:TextStyle(fontSize: 15,color: Colors.black))
|
||||||
|
),
|
||||||
|
Padding(padding: EdgeInsets.only(left: 10),
|
||||||
|
child: cargoBox,),
|
||||||
|
// ListView.builder(
|
||||||
|
// itemCount: cargos.length,
|
||||||
|
// itemBuilder: (BuildContext context, int index) {
|
||||||
|
// return ListTile(
|
||||||
|
// title: Text(cargos[index].key));
|
||||||
|
|
||||||
|
// }),
|
||||||
|
|
||||||
|
Expanded(child:
|
||||||
|
Padding(padding: EdgeInsets.only(left: 200.0,right: 8.0),
|
||||||
|
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Color(0xff272262),
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5.0)),
|
||||||
|
minimumSize: Size(100, 35), //////// HERE
|
||||||
|
),
|
||||||
|
onPressed: (){},
|
||||||
|
child: const Text('Upload Images'),
|
||||||
|
),)),
|
||||||
|
Center(child: ElevatedButton(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Color.fromARGB(255, 196, 39, 52),
|
||||||
|
elevation: 3,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5.0)),
|
||||||
|
minimumSize: Size(300, 45), //////// HERE
|
||||||
|
),
|
||||||
|
onPressed: (){},
|
||||||
|
child: const Text('Delete Carton',style:TextStyle(fontSize: 20)),
|
||||||
|
),),
|
||||||
|
|
||||||
|
//_package!.photoUrls.length == 0 || _package!.photoUrls.isEmpty ? Container() : img,
|
||||||
|
|
||||||
|
// Padding(padding: EdgeInsets.only(left: 10.0),
|
||||||
|
// child: Column(children: [
|
||||||
|
// cargos.isEmpty?Container():
|
||||||
|
// Text(cargos[cargo].key),
|
||||||
|
// Text(cargos[cargo].value),
|
||||||
|
// ]),),
|
||||||
|
|
||||||
|
//_packageList,
|
||||||
|
|
||||||
//LocalTitle(textKey: "box.shipment_info"),
|
//LocalTitle(textKey: "box.shipment_info"),
|
||||||
// shipmentBox,
|
// shipmentBox,
|
||||||
// isSmallBag ? mixCartonNumberBox : Container(),
|
// isSmallBag ? mixCartonNumberBox : Container(),
|
||||||
// isMixBox
|
// isMixBox
|
||||||
// ? Container()
|
// ? Container()
|
||||||
@@ -429,40 +532,49 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
// ],
|
// ],
|
||||||
// )
|
// )
|
||||||
// : Container(),
|
// : Container(),
|
||||||
Padding(padding: EdgeInsets.only(left: 30),
|
// Padding(padding: EdgeInsets.only(left: 10),
|
||||||
child:
|
// child: Row(children:[
|
||||||
packageBox),
|
|
||||||
isMixBox ? mixTypeBox : Container(),
|
// ListView.builder(
|
||||||
isMixBox ? LocalTitle(textKey: "box.mix_caton_title") : Container(),
|
// itemCount: pickups.length,
|
||||||
isMixBox
|
// itemBuilder: (context, index) {
|
||||||
? Column(children: _getCartons(context, _box!.mixCartons))
|
// return ListTile(
|
||||||
: Container(),
|
// title: Text(pickups[index]),
|
||||||
isFromPackages || isSmallBag
|
// );
|
||||||
? CartonPackageTable(
|
// },)
|
||||||
packages: _box!.packages,
|
|
||||||
)
|
// ])),
|
||||||
: Container(),
|
// // isMixBox ? mixTypeBox : Container(),
|
||||||
// isMixBox ? Container() : LocalTitle(textKey: "box.cargo.type"),
|
// isMixBox ? LocalTitle(textKey: "box.mix_caton_title") : Container(),
|
||||||
isMixBox ? Container() : cargoTableBox,
|
// isMixBox
|
||||||
...(isFromPackages || isFromCartons
|
// ? Column(children: _getCartons(context, _box!.mixCartons))
|
||||||
? [
|
// : Container(),
|
||||||
LocalTitle(textKey: "box.dimension"),
|
// isFromPackages || isSmallBag
|
||||||
cartonSizeBox,
|
// ? CartonPackageTable(
|
||||||
dimBox,
|
// packages: _box!.packages,
|
||||||
]
|
// )
|
||||||
: []),
|
// : Container(),
|
||||||
isMixBox
|
// isMixBox ? Container() : LocalTitle(textKey: "box.cargo.type"),
|
||||||
? Container()
|
// isMixBox ? Container() : cargoTableBox,
|
||||||
: LocalTitle(textKey: "box.delivery_address"),
|
// ...(isFromPackages || isFromCartons
|
||||||
isMixBox
|
// ? [
|
||||||
? Container()
|
// LocalTitle(textKey: "box.dimension"),
|
||||||
: DefaultDeliveryAddress(
|
// cartonSizeBox,
|
||||||
deliveryAddress: _deliveryAddress,
|
// dimBox,
|
||||||
labelKey: "box.delivery_address",
|
// ]
|
||||||
),
|
// : []),
|
||||||
SizedBox(
|
// isMixBox
|
||||||
height: 20,
|
// ? Container()
|
||||||
)
|
// : LocalTitle(textKey: "box.delivery_address"),
|
||||||
|
// isMixBox
|
||||||
|
// ? Container()
|
||||||
|
// : DefaultDeliveryAddress(
|
||||||
|
// deliveryAddress: _deliveryAddress,
|
||||||
|
// labelKey: "box.delivery_address",
|
||||||
|
// ),
|
||||||
|
// SizedBox(
|
||||||
|
// height: 20,
|
||||||
|
// )
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -515,4 +627,18 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Widget _packageList(BuildContext context) {
|
||||||
|
return ListView.builder(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
itemCount: pickups.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return Container(
|
||||||
|
height: 50,
|
||||||
|
//color: Colors.amber[pickups[index]],
|
||||||
|
child: Center(child: Text('Entry ${pickups[index]}')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
//separatorBuilder: (BuildContext context, int index) => const Divider(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
400
lib/pages/carton/carton_size_widget.dart
Normal file
400
lib/pages/carton/carton_size_widget.dart
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
import 'package:fcs/pages/widgets/local_radio.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import '../../../domain/constants.dart';
|
||||||
|
import '../../../domain/entities/carton_size.dart';
|
||||||
|
import '../../../domain/entities/fcs_shipment.dart';
|
||||||
|
import '../../../helpers/theme.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 '../widgets/box_size_picker.dart';
|
||||||
|
import '../widgets/continue_button.dart';
|
||||||
|
import '../widgets/display_text.dart';
|
||||||
|
import '../widgets/local_dropdown.dart';
|
||||||
|
import '../widgets/local_radio_buttons.dart';
|
||||||
|
import '../widgets/local_text.dart';
|
||||||
|
import '../widgets/local_title.dart';
|
||||||
|
import '../widgets/previous_button.dart';
|
||||||
|
|
||||||
|
typedef OnPrevious = Function();
|
||||||
|
|
||||||
|
typedef OnContinue = Function(String deliveryType,FcsShipment shipment, String cartonSizeType,
|
||||||
|
{CartonSize? standardSize, double? length, double? width, double? height});
|
||||||
|
|
||||||
|
class CartonSizeWidget extends StatefulWidget {
|
||||||
|
final OnPrevious? onPrevious;
|
||||||
|
final OnContinue? onContinue;
|
||||||
|
final User sender;
|
||||||
|
final User consignee;
|
||||||
|
final String deliveryType;
|
||||||
|
final FcsShipment? shipment;
|
||||||
|
final String cartonSizeType;
|
||||||
|
final CartonSize? standardSize;
|
||||||
|
final double? length;
|
||||||
|
final double? width;
|
||||||
|
final double? height;
|
||||||
|
|
||||||
|
const CartonSizeWidget(
|
||||||
|
{Key? key,
|
||||||
|
this.onPrevious,
|
||||||
|
this.onContinue,
|
||||||
|
this.shipment,
|
||||||
|
required this.cartonSizeType,
|
||||||
|
this.standardSize,
|
||||||
|
this.length,
|
||||||
|
this.width,
|
||||||
|
this.height,
|
||||||
|
required this.sender,
|
||||||
|
required this.consignee,
|
||||||
|
required this.deliveryType})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CartonSizeWidget> createState() => _CartonSizeWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||||
|
List<String> _deliveryTypes = [delivery_caton, pickup_carton];
|
||||||
|
|
||||||
|
FcsShipment? _shipment;
|
||||||
|
String _cartionSizeType = standardCarton;
|
||||||
|
|
||||||
|
List<FcsShipment> _shipments = [];
|
||||||
|
CartonSize? _selectStandardSize;
|
||||||
|
late String _selectedDeliveryType;
|
||||||
|
|
||||||
|
TextEditingController _widthController = new TextEditingController();
|
||||||
|
TextEditingController _heightController = new TextEditingController();
|
||||||
|
TextEditingController _lengthController = new TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() async {
|
||||||
|
_selectedDeliveryType = widget.deliveryType;
|
||||||
|
_shipment = widget.shipment;
|
||||||
|
_cartionSizeType = widget.cartonSizeType;
|
||||||
|
|
||||||
|
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
|
||||||
|
_selectStandardSize = widget.standardSize ?? cartonSizes.first;
|
||||||
|
|
||||||
|
_lengthController.text =
|
||||||
|
widget.length == null ? "0" : widget.length.toString();
|
||||||
|
_widthController.text =
|
||||||
|
widget.width == null ? "0" : widget.width.toString();
|
||||||
|
_heightController.text =
|
||||||
|
widget.height == null ? "0" : widget.height.toString();
|
||||||
|
|
||||||
|
var fcsShipments =
|
||||||
|
await context.read<FcsShipmentModel>().getActiveFcsShipments();
|
||||||
|
_shipments = fcsShipments;
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
List<CartonSize> cartonSizes = context.watch<CartonSizeModel>().cartonSizes;
|
||||||
|
bool isStandardSize = _cartionSizeType == standardCarton;
|
||||||
|
bool isCustomSize = _cartionSizeType == customCarton;
|
||||||
|
bool isNoneDefinedSize = _cartionSizeType == packageCartion;
|
||||||
|
|
||||||
|
final senderBox = DisplayText(
|
||||||
|
text: widget.sender.name,
|
||||||
|
labelTextKey: "box.sender.title",
|
||||||
|
iconData: MaterialCommunityIcons.account_arrow_right,
|
||||||
|
subText: Text(widget.sender.fcsID!,
|
||||||
|
style: TextStyle(fontSize: 13, color: labelColor)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final consigneeBox = DisplayText(
|
||||||
|
text: widget.consignee.name,
|
||||||
|
labelTextKey: "box.consignee.title",
|
||||||
|
iconData: MaterialCommunityIcons.account_arrow_left,
|
||||||
|
subText: Text(widget.consignee.fcsID!,
|
||||||
|
style: TextStyle(fontSize: 13, color: labelColor)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final userRow = Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: senderBox,
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
Flexible(child: consigneeBox)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final deliveryTypeBox = LocalRadioButtons(
|
||||||
|
values: _deliveryTypes,
|
||||||
|
selectedValue: _selectedDeliveryType,
|
||||||
|
callback: (String? v) {
|
||||||
|
setState(() {
|
||||||
|
_selectedDeliveryType = v!;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
final continueBtn = ContinueButton(onTap: () {
|
||||||
|
double l = double.tryParse(_lengthController.text) ?? 0;
|
||||||
|
double w = double.tryParse(_widthController.text) ?? 0;
|
||||||
|
double h = double.tryParse(_heightController.text) ?? 0;
|
||||||
|
|
||||||
|
if (_shipment == null) {
|
||||||
|
showMsgDialog(context, "Error", "Please select shipment");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStandardSize &&
|
||||||
|
_selectStandardSize == null &&
|
||||||
|
!isCustomSize &&
|
||||||
|
!isNoneDefinedSize) {
|
||||||
|
showMsgDialog(
|
||||||
|
context, "Error", "Please select the standard carton size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCustomSize &&
|
||||||
|
!isStandardSize &&
|
||||||
|
!isNoneDefinedSize &&
|
||||||
|
(l == 0 || w == 0 || h == 0)) {
|
||||||
|
showMsgDialog(context, "Error", "Please add the carton size");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widget.onContinue != null) {
|
||||||
|
widget.onContinue!(_selectedDeliveryType,_shipment!, _cartionSizeType,
|
||||||
|
standardSize: _selectStandardSize, length: l, width: w, height: h);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final previousBtn = PreviousButton(onTap: () {
|
||||||
|
if (widget.onPrevious != null) {
|
||||||
|
widget.onPrevious!();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final standardSizeBox = Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 34.0, top: 8),
|
||||||
|
child: IgnorePointer(
|
||||||
|
ignoring: !isStandardSize,
|
||||||
|
child: DropdownButton<CartonSize>(
|
||||||
|
isDense: true,
|
||||||
|
value: _selectStandardSize,
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 14),
|
||||||
|
underline: Container(height: 1, color: Colors.grey),
|
||||||
|
onChanged: (newValue) {
|
||||||
|
setState(() {
|
||||||
|
_selectStandardSize = newValue!;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
isExpanded: true,
|
||||||
|
items:
|
||||||
|
cartonSizes.map<DropdownMenuItem<CartonSize>>((CartonSize value) {
|
||||||
|
return DropdownMenuItem<CartonSize>(
|
||||||
|
value: value,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text("${value.name} - ",
|
||||||
|
style: TextStyle(
|
||||||
|
color: isStandardSize ? Colors.black : labelColor)),
|
||||||
|
Text(
|
||||||
|
"${value.length.toInt()}”x${value.width.toInt()}”x${value.height.toInt()}”",
|
||||||
|
style: TextStyle(color: labelColor)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final lengthBox = BoxSizePicker(
|
||||||
|
lableKey: 'box.length',
|
||||||
|
controller: _lengthController,
|
||||||
|
enable: isCustomSize);
|
||||||
|
|
||||||
|
final widthBox = BoxSizePicker(
|
||||||
|
lableKey: 'box.width',
|
||||||
|
controller: _widthController,
|
||||||
|
enable: isCustomSize);
|
||||||
|
|
||||||
|
final heightBox = BoxSizePicker(
|
||||||
|
lableKey: 'box.height',
|
||||||
|
controller: _heightController,
|
||||||
|
enable: isCustomSize);
|
||||||
|
|
||||||
|
final customSizeBox = Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 34.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Flexible(child: lengthBox),
|
||||||
|
Flexible(child: widthBox),
|
||||||
|
Flexible(child: heightBox)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final cartonSizedBox = Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// standard carton size
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_cartionSizeType = standardCarton;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Row(children: <Widget>[
|
||||||
|
LocalRadio(
|
||||||
|
value: standardCarton,
|
||||||
|
groupValue: _cartionSizeType,
|
||||||
|
onChanged: (p0) {
|
||||||
|
setState(() {
|
||||||
|
_cartionSizeType = standardCarton;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: LocalText(context, 'box.standard_carton_size',
|
||||||
|
fontSize: 15,
|
||||||
|
color: isStandardSize ? primaryColor : labelColor),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
standardSizeBox,
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
// custom size
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_cartionSizeType = customCarton;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Row(children: <Widget>[
|
||||||
|
LocalRadio(
|
||||||
|
value: customCarton,
|
||||||
|
groupValue: _cartionSizeType,
|
||||||
|
onChanged: (p0) {
|
||||||
|
setState(() {
|
||||||
|
_cartionSizeType = customCarton;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: LocalText(context, 'box.custom_size',
|
||||||
|
fontSize: 15,
|
||||||
|
color: isCustomSize ? primaryColor : Colors.black54),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
customSizeBox,
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
// not defined size
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
_cartionSizeType = packageCartion;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Row(children: <Widget>[
|
||||||
|
LocalRadio(
|
||||||
|
value: packageCartion,
|
||||||
|
groupValue: _cartionSizeType,
|
||||||
|
onChanged: (p0) {
|
||||||
|
setState(() {
|
||||||
|
_cartionSizeType = packageCartion;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: LocalText(context, 'box.package_size',
|
||||||
|
fontSize: 15,
|
||||||
|
color: isNoneDefinedSize ? primaryColor : Colors.black54),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 34.0),
|
||||||
|
child: Text(
|
||||||
|
"No defined size",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: isNoneDefinedSize ? Colors.black : labelColor),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final fcsShipmentsBox = Container(
|
||||||
|
padding: EdgeInsets.only(top: 10),
|
||||||
|
child: LocalDropdown<FcsShipment>(
|
||||||
|
callback: (v) {
|
||||||
|
setState(() {
|
||||||
|
_shipment = v;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
labelKey: "box.shipment",
|
||||||
|
iconData: Ionicons.ios_airplane,
|
||||||
|
display: (u) => u.shipmentNumber,
|
||||||
|
selectedValue: _shipment,
|
||||||
|
values: _shipments,
|
||||||
|
));
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ListView(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
userRow,
|
||||||
|
LocalTitle(textKey: "box.select.delivery", topPadding: 10),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
deliveryTypeBox,
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
LocalTitle(textKey: "box.select_carton_size"),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
cartonSizedBox,
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
LocalTitle(textKey: "box.select_shipment"),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
fcsShipmentsBox,
|
||||||
|
const SizedBox(height: 30)
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
widget.onPrevious == null ? const SizedBox() : previousBtn,
|
||||||
|
continueBtn
|
||||||
|
// warehouse != null ? continueBtn : const SizedBox(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
127
lib/pages/carton/custom_duty_addition.dart
Normal file
127
lib/pages/carton/custom_duty_addition.dart
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
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/local_title.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) {
|
||||||
|
if (widget.customDuties.any((e) => e.id == p.id)) {
|
||||||
|
p.isChecked = true;
|
||||||
|
} else {
|
||||||
|
p.isChecked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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>[
|
||||||
|
LocalTitle(
|
||||||
|
textKey: "box.select.cargo.title",
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: getCargoRowList(customDuties),
|
||||||
|
),
|
||||||
|
SizedBox(height: 30),
|
||||||
|
saveBtn,
|
||||||
|
SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ class CartonSelectionResult extends StatelessWidget {
|
|||||||
var model = context.watch<CartonSelectionModel>();
|
var model = context.watch<CartonSelectionModel>();
|
||||||
List<Carton> searchResults = model.cartons;
|
List<Carton> searchResults = model.cartons;
|
||||||
|
|
||||||
return searchResults.isEmpty
|
return searchResults.isEmpty && !model.isLoading
|
||||||
? Center(
|
? Center(
|
||||||
child: LocalText(context, 'box.no_carton',
|
child: LocalText(context, 'box.no_carton',
|
||||||
color: Colors.black, fontSize: 15))
|
color: Colors.black, fontSize: 15))
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/carton/mix_cation/carton_selection_result.dart';
|
import 'package:fcs/pages/carton/mix_carton/carton_selection_result.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
@@ -11,11 +11,13 @@ import '../../../domain/entities/carton_size.dart';
|
|||||||
import '../../../domain/entities/fcs_shipment.dart';
|
import '../../../domain/entities/fcs_shipment.dart';
|
||||||
import '../../../domain/vo/local_step.dart';
|
import '../../../domain/vo/local_step.dart';
|
||||||
import '../../../helpers/theme.dart';
|
import '../../../helpers/theme.dart';
|
||||||
|
import '../../main/util.dart';
|
||||||
import '../../widgets/local_text.dart';
|
import '../../widgets/local_text.dart';
|
||||||
import '../../widgets/progress.dart';
|
import '../../widgets/progress.dart';
|
||||||
import '../../widgets/step_widget.dart';
|
import '../../widgets/step_widget.dart';
|
||||||
import '../model/carton_selection_model.dart';
|
import '../model/carton_selection_model.dart';
|
||||||
import 'carton_selection_widget.dart';
|
import 'carton_selection_widget.dart';
|
||||||
|
import 'mix_carton_submit.dart';
|
||||||
import 'type_widget.dart';
|
import 'type_widget.dart';
|
||||||
|
|
||||||
class MixCartonEditor extends StatefulWidget {
|
class MixCartonEditor extends StatefulWidget {
|
||||||
@@ -35,7 +37,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
|||||||
LocalStep(lable: 'Cartons', stepType: StepType.CARTONS),
|
LocalStep(lable: 'Cartons', stepType: StepType.CARTONS),
|
||||||
LocalStep(lable: 'Submit', stepType: StepType.SUBMIT)
|
LocalStep(lable: 'Submit', stepType: StepType.SUBMIT)
|
||||||
];
|
];
|
||||||
List<Carton> _cartions = [];
|
List<Carton> _cartons = [];
|
||||||
|
|
||||||
int currentStep = 0;
|
int currentStep = 0;
|
||||||
double _length = 0;
|
double _length = 0;
|
||||||
@@ -43,7 +45,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
|||||||
double _height = 0;
|
double _height = 0;
|
||||||
|
|
||||||
FcsShipment? _shipment;
|
FcsShipment? _shipment;
|
||||||
String _cartionSizeType = standardCarton;
|
String _cartonSizeType = standardCarton;
|
||||||
CartonSize? _standardSize;
|
CartonSize? _standardSize;
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
|
|
||||||
@@ -97,7 +99,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
|||||||
StepperWidget(
|
StepperWidget(
|
||||||
labels: steps.map((e) => e.lable).toList(),
|
labels: steps.map((e) => e.lable).toList(),
|
||||||
currentStep: currentStep,
|
currentStep: currentStep,
|
||||||
eachStepWidth: 120,
|
eachStepWidth: MediaQuery.of(context).size.width / 3,
|
||||||
onChange: (index) {
|
onChange: (index) {
|
||||||
if (index > currentStep) {
|
if (index > currentStep) {
|
||||||
return;
|
return;
|
||||||
@@ -119,7 +121,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
|||||||
return Expanded(
|
return Expanded(
|
||||||
child: TypeWidget(
|
child: TypeWidget(
|
||||||
shipment: _shipment,
|
shipment: _shipment,
|
||||||
cartonSizeType: _cartionSizeType,
|
cartonSizeType: _cartonSizeType,
|
||||||
standardSize: _standardSize,
|
standardSize: _standardSize,
|
||||||
length: _length,
|
length: _length,
|
||||||
width: _width,
|
width: _width,
|
||||||
@@ -131,7 +133,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
|||||||
{standardSize, length, width, height}) {
|
{standardSize, length, width, height}) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_shipment = shipment;
|
_shipment = shipment;
|
||||||
_cartionSizeType = cartonSizeType;
|
_cartonSizeType = cartonSizeType;
|
||||||
_standardSize = standardSize;
|
_standardSize = standardSize;
|
||||||
_length = length ?? 0;
|
_length = length ?? 0;
|
||||||
_width = width ?? 0;
|
_width = width ?? 0;
|
||||||
@@ -144,16 +146,16 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
|||||||
return Expanded(
|
return Expanded(
|
||||||
child: CartonSelectionWidget(
|
child: CartonSelectionWidget(
|
||||||
shipment: _shipment!,
|
shipment: _shipment!,
|
||||||
cartons: _cartions,
|
cartons: _cartons,
|
||||||
onContinue: (cartons) {
|
onContinue: (cartons) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_cartions = List.from(cartons);
|
_cartons = List.from(cartons);
|
||||||
currentStep += 1;
|
currentStep += 1;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onPrevious: (cartons) {
|
onPrevious: (cartons) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_cartions = List.from(cartons);
|
_cartons = List.from(cartons);
|
||||||
currentStep -= 1;
|
currentStep -= 1;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -161,27 +163,39 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: Text("Submit"),
|
child: MixCartonSubmit(
|
||||||
// child: StockAdjustmentSubmit(
|
cartonSizeType: _cartonSizeType,
|
||||||
// warehouse: _warehouse?.name,
|
standardSize: _standardSize,
|
||||||
// products: products,
|
length: _length,
|
||||||
// onCreate: () {
|
width: _width,
|
||||||
// if (user != null && user.hasInventoryCreate()) {
|
height: _height,
|
||||||
// showConfirmDialog(context, 'stock_adjustment_confirm', _create);
|
shipment: _shipment!,
|
||||||
// } else {
|
cartons: _cartons,
|
||||||
// showDialog(
|
onCreate: () {
|
||||||
// context: context,
|
_create();
|
||||||
// builder: (BuildContext context) => const AuthorizedDialog(
|
},
|
||||||
// uiFunction: funcInventoriesCreate));
|
onPrevious: () {
|
||||||
// }
|
setState(() {
|
||||||
// },
|
currentStep -= 1;
|
||||||
// onPrevious: () {
|
});
|
||||||
// setState(() {
|
},
|
||||||
// currentStep -= 1;
|
),
|
||||||
// });
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_create() async {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
Navigator.pop(context, true);
|
||||||
|
} catch (e) {
|
||||||
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
} finally {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
289
lib/pages/carton/mix_carton/mix_carton_submit.dart
Normal file
289
lib/pages/carton/mix_carton/mix_carton_submit.dart
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
import '../../../domain/constants.dart';
|
||||||
|
import '../../../domain/entities/cargo_type.dart';
|
||||||
|
import '../../../domain/entities/carton.dart';
|
||||||
|
import '../../../domain/entities/carton_size.dart';
|
||||||
|
import '../../../domain/entities/fcs_shipment.dart';
|
||||||
|
import '../../../helpers/theme.dart';
|
||||||
|
import '../../widgets/local_text.dart';
|
||||||
|
import '../../widgets/previous_button.dart';
|
||||||
|
import '../../widgets/submit_text_widget.dart';
|
||||||
|
import "package:collection/collection.dart";
|
||||||
|
|
||||||
|
typedef OnCreateMixCarton = Function();
|
||||||
|
typedef OnPrevious = Function();
|
||||||
|
|
||||||
|
class MixCartonSubmit extends StatefulWidget {
|
||||||
|
final FcsShipment shipment;
|
||||||
|
final List<Carton> cartons;
|
||||||
|
final String cartonSizeType;
|
||||||
|
final CartonSize? standardSize;
|
||||||
|
final double length;
|
||||||
|
final double width;
|
||||||
|
final double height;
|
||||||
|
final OnCreateMixCarton? onCreate;
|
||||||
|
final OnPrevious? onPrevious;
|
||||||
|
const MixCartonSubmit(
|
||||||
|
{Key? key,
|
||||||
|
this.onCreate,
|
||||||
|
this.onPrevious,
|
||||||
|
required this.shipment,
|
||||||
|
this.cartons = const [],
|
||||||
|
this.standardSize,
|
||||||
|
required this.cartonSizeType,
|
||||||
|
this.length = 0,
|
||||||
|
this.width = 0,
|
||||||
|
this.height = 0})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MixCartonSubmit> createState() => _MixCartonSubmitState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MixCartonSubmitState extends State<MixCartonSubmit> {
|
||||||
|
final NumberFormat numberFormatter = NumberFormat("#,###");
|
||||||
|
Map<String?, double> _mapCargosByWeight = {};
|
||||||
|
Map<String?, double> _mapCargosByCustomDutyFee = {};
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
List<CargoType> _cargoTypes = [];
|
||||||
|
for (var c in widget.cartons) {
|
||||||
|
_cargoTypes.addAll(c.cargoTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get cargos by weight
|
||||||
|
Map<String?, List<CargoType>> _cargosByWeight =
|
||||||
|
groupCargos(_cargoTypes.where((e) => !e.isCutomDuty).toList());
|
||||||
|
|
||||||
|
_cargosByWeight.forEach((key, value) {
|
||||||
|
double total = value.fold(0, (sum, item) => sum + item.weight);
|
||||||
|
_mapCargosByWeight[key] = total;
|
||||||
|
});
|
||||||
|
|
||||||
|
// get cargos by custom duty fee
|
||||||
|
Map<String?, List<CargoType>> _cargosByCustomDutyFee =
|
||||||
|
groupCargos(_cargoTypes.where((e) => e.isCutomDuty).toList());
|
||||||
|
|
||||||
|
_cargosByCustomDutyFee.forEach((key, value) {
|
||||||
|
double total = value.fold(0, (sum, item) => sum + item.qty);
|
||||||
|
_mapCargosByCustomDutyFee[key] = total;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String?, List<CargoType>> groupCargos(List<CargoType> cargos) {
|
||||||
|
var groups = groupBy(cargos, (CargoType e) {
|
||||||
|
String? _categoryName = e.name;
|
||||||
|
return _categoryName;
|
||||||
|
});
|
||||||
|
|
||||||
|
return groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
String? boxDimension = widget.cartonSizeType == standardCarton
|
||||||
|
? "${widget.standardSize?.name} - ${widget.standardSize?.length.toInt()}”x${widget.standardSize?.width.toInt()}”x${widget.standardSize?.height.toInt()}”"
|
||||||
|
: widget.cartonSizeType == customCarton
|
||||||
|
? "${widget.length.toInt()}”x${widget.width.toInt()}”x${widget.height.toInt()}”"
|
||||||
|
: null;
|
||||||
|
|
||||||
|
final cartonType = Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: SubmitTextWidget(
|
||||||
|
labelKey: 'box.carton.type',
|
||||||
|
text: 'Mix Carton',
|
||||||
|
subText: boxDimension,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final shipmentBox = Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: SubmitTextWidget(
|
||||||
|
labelKey: 'box.shipment',
|
||||||
|
text: widget.shipment.shipmentNumber ?? '',
|
||||||
|
subText: widget.shipment.status ?? "",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final cartonsBox = Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 5, bottom: 5),
|
||||||
|
child: LocalText(context, 'box.cartion.count',
|
||||||
|
translationVariables: [widget.cartons.length.toString()],
|
||||||
|
color: primaryColor,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: primaryColor),
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 15,
|
||||||
|
children: widget.cartons.map((e) {
|
||||||
|
return SizedBox(
|
||||||
|
width: MediaQuery.of(context).size.width / 2.5,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||||
|
child: Text(
|
||||||
|
e.cartonNumber ?? "",
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 15),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList()),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final cargosBox = Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 5, bottom: 5),
|
||||||
|
child: LocalText(context, 'box.cargo.type',
|
||||||
|
color: primaryColor, fontSize: 16, fontWeight: FontWeight.normal),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: primaryColor),
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: _mapCargosByWeight.entries.map((e) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
e.key ?? "",
|
||||||
|
style:
|
||||||
|
TextStyle(color: Colors.black, fontSize: 15),
|
||||||
|
),
|
||||||
|
Text("${numberFormatter.format(e.value)} lb",
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.black, fontSize: 15))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList()),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: _mapCargosByCustomDutyFee.entries.map((e) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
e.key ?? "",
|
||||||
|
style: TextStyle(color: labelColor, fontSize: 15),
|
||||||
|
),
|
||||||
|
Text("${numberFormatter.format(e.value)} pc",
|
||||||
|
style:
|
||||||
|
TextStyle(color: labelColor, fontSize: 15))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
final createBtn = InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (widget.onCreate != null) {
|
||||||
|
widget.onCreate!();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.bottomRight,
|
||||||
|
height: 45,
|
||||||
|
width: 150,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: primaryColor,
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: TextButton(
|
||||||
|
onPressed: null,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Flexible(
|
||||||
|
child: LocalText(context, 'box.crete.carton',
|
||||||
|
color: Colors.white, fontSize: 15),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 5),
|
||||||
|
const Icon(
|
||||||
|
MaterialCommunityIcons.check_circle_outline,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
final previousBtn = PreviousButton(onTap: () {
|
||||||
|
if (widget.onPrevious != null) {
|
||||||
|
widget.onPrevious!();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: ListView(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
children: [
|
||||||
|
cartonType,
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
shipmentBox,
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
widget.cartons.isNotEmpty ? cartonsBox : const SizedBox(),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
cargosBox,
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [previousBtn, createBtn],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -109,7 +109,7 @@ class _TypeWidgetState extends State<TypeWidget> {
|
|||||||
!isCustomSize &&
|
!isCustomSize &&
|
||||||
!isNoneDefinedSize) {
|
!isNoneDefinedSize) {
|
||||||
showMsgDialog(
|
showMsgDialog(
|
||||||
context, "Error", "Please select the standard cartion size");
|
context, "Error", "Please select the standard carton size");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ class _TypeWidgetState extends State<TypeWidget> {
|
|||||||
!isStandardSize &&
|
!isStandardSize &&
|
||||||
!isNoneDefinedSize &&
|
!isNoneDefinedSize &&
|
||||||
(l == 0 || w == 0 || h == 0)) {
|
(l == 0 || w == 0 || h == 0)) {
|
||||||
showMsgDialog(context, "Error", "Please add the cartion size");
|
showMsgDialog(context, "Error", "Please add the carton size");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,6 +15,8 @@ class CartonSelectionModel extends BaseModel {
|
|||||||
bool reachEnd = false;
|
bool reachEnd = false;
|
||||||
List<Carton> cartons = [];
|
List<Carton> cartons = [];
|
||||||
|
|
||||||
|
bool isLoading = false;
|
||||||
|
|
||||||
// for default carton
|
// for default carton
|
||||||
DocumentSnapshot? _lastDocument;
|
DocumentSnapshot? _lastDocument;
|
||||||
bool ended = false;
|
bool ended = false;
|
||||||
@@ -96,10 +98,11 @@ class CartonSelectionModel extends BaseModel {
|
|||||||
int rowPerPage = 20;
|
int rowPerPage = 20;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
isLoading = true;
|
||||||
String path = "/$cartons_collection";
|
String path = "/$cartons_collection";
|
||||||
Query query = FirebaseFirestore.instance
|
Query query = FirebaseFirestore.instance
|
||||||
.collection(path)
|
.collection(path)
|
||||||
.where("fcs_shipment_id", isEqualTo: shipmentId)
|
// .where("fcs_shipment_id", isEqualTo: shipmentId)
|
||||||
// .where("status", isEqualTo: carton_processing_status)
|
// .where("status", isEqualTo: carton_processing_status)
|
||||||
// .where("carton_type", isEqualTo: carton_mix_box)
|
// .where("carton_type", isEqualTo: carton_mix_box)
|
||||||
.where("is_deleted", isEqualTo: false)
|
.where("is_deleted", isEqualTo: false)
|
||||||
@@ -131,6 +134,8 @@ class CartonSelectionModel extends BaseModel {
|
|||||||
notifyListeners();
|
notifyListeners();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.warning("error:$e");
|
log.warning("error:$e");
|
||||||
|
} finally {
|
||||||
|
isLoading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
170
lib/pages/carton/model/package_selection_model.dart
Normal file
170
lib/pages/carton/model/package_selection_model.dart
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
|
||||||
|
import '../../../domain/constants.dart';
|
||||||
|
import '../../../domain/entities/package.dart';
|
||||||
|
import '../../main/model/base_model.dart';
|
||||||
|
|
||||||
|
class PackageSelectionModel extends BaseModel {
|
||||||
|
final log = Logger("PackageSelectionModel");
|
||||||
|
// for search
|
||||||
|
String query = "";
|
||||||
|
int offset = 0;
|
||||||
|
bool reachEnd = false;
|
||||||
|
List<Package> packages = [];
|
||||||
|
|
||||||
|
bool isLoading = false;
|
||||||
|
|
||||||
|
// for default package
|
||||||
|
DocumentSnapshot? _lastDocument;
|
||||||
|
bool ended = false;
|
||||||
|
|
||||||
|
List<Package> selectedPackageList = [];
|
||||||
|
|
||||||
|
Timer? t;
|
||||||
|
search(String term,
|
||||||
|
{bool imm = false,
|
||||||
|
required String shipmentId,
|
||||||
|
required String senderId,
|
||||||
|
required String consigneeId}) async {
|
||||||
|
query = term;
|
||||||
|
packages.clear();
|
||||||
|
offset = 0;
|
||||||
|
reachEnd = false;
|
||||||
|
t?.cancel();
|
||||||
|
t = Timer(Duration(milliseconds: imm ? 0 : 800), () async {
|
||||||
|
await loadMoreSearch(
|
||||||
|
term: term,
|
||||||
|
shipmentId: shipmentId,
|
||||||
|
consigneeId: consigneeId,
|
||||||
|
senderId: senderId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadMoreSearch(
|
||||||
|
{required String term,
|
||||||
|
required String shipmentId,
|
||||||
|
required String senderId,
|
||||||
|
required String consigneeId}) async {
|
||||||
|
if (term == "") {
|
||||||
|
await _refresh(
|
||||||
|
shipmentId: shipmentId, senderId: senderId, consigneeId: consigneeId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// int rowPerPage = 21;
|
||||||
|
// List<Carton> list = [];
|
||||||
|
// SearchPara searchPara = SearchPara(filters: [], term: term);
|
||||||
|
// isLoading = true;
|
||||||
|
|
||||||
|
// var path =
|
||||||
|
// "/search/$cartons_collection/${searchPara.escapeTerm}/$rowPerPage/$offset/${searchPara.escapeFilters}";
|
||||||
|
|
||||||
|
// var result = await requestAPI(path, "GET",
|
||||||
|
// token: await getToken(), url: Config.instance.searchURL);
|
||||||
|
|
||||||
|
// if (result != null) {
|
||||||
|
// for (var row in result) {
|
||||||
|
// var item = ArtistExt.fromMapForSearch(row);
|
||||||
|
// list.add(item);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (var p in list) {
|
||||||
|
// selectedArtistList.contains(p)
|
||||||
|
// ? p.isSelected = true
|
||||||
|
// : p.isSelected = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// artists.addAll(list);
|
||||||
|
// offset += rowPerPage;
|
||||||
|
// if (list.length < rowPerPage) {
|
||||||
|
// reachEnd = true;
|
||||||
|
// }
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
addDefaultPackages(
|
||||||
|
{required String shipmentId,
|
||||||
|
required String senderId,
|
||||||
|
required String consigneeId}) async {
|
||||||
|
packages.clear();
|
||||||
|
await _refresh(
|
||||||
|
shipmentId: shipmentId, senderId: senderId, consigneeId: consigneeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectPackage(Package a) {
|
||||||
|
if (a.isChecked) {
|
||||||
|
selectedPackageList.add(a);
|
||||||
|
} else {
|
||||||
|
selectedPackageList.remove(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _refresh(
|
||||||
|
{required String shipmentId,
|
||||||
|
required String senderId,
|
||||||
|
required String consigneeId}) async {
|
||||||
|
packages.clear();
|
||||||
|
_lastDocument = null;
|
||||||
|
ended = false;
|
||||||
|
await loadMoreData(
|
||||||
|
shipmentId: shipmentId, senderId: senderId, consigneeId: consigneeId);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> loadMoreData(
|
||||||
|
{required String shipmentId,
|
||||||
|
required String senderId,
|
||||||
|
required String consigneeId}) async {
|
||||||
|
int rowPerPage = 20;
|
||||||
|
|
||||||
|
try {
|
||||||
|
isLoading = true;
|
||||||
|
String path = "/$packages_collection";
|
||||||
|
Query query = FirebaseFirestore.instance
|
||||||
|
.collection(path)
|
||||||
|
// .where("fcs_shipment_id", isEqualTo: shipmentId)
|
||||||
|
// .where("status", isEqualTo: package_processed_status)
|
||||||
|
.where("user_id", whereIn: [senderId, consigneeId])
|
||||||
|
.where("is_deleted", isEqualTo: false)
|
||||||
|
.orderBy("created_date", descending: true);
|
||||||
|
|
||||||
|
if (_lastDocument != null) {
|
||||||
|
query = query.startAfterDocument(_lastDocument!);
|
||||||
|
}
|
||||||
|
|
||||||
|
QuerySnapshot querySnap = await query.limit(rowPerPage).get();
|
||||||
|
|
||||||
|
if (querySnap.docs.isEmpty) return;
|
||||||
|
_lastDocument = querySnap.docs[querySnap.docs.length - 1];
|
||||||
|
|
||||||
|
List<Package> list = querySnap.docs.map((documentSnapshot) {
|
||||||
|
var p = Package.fromMap(documentSnapshot.data() as Map<String, dynamic>,
|
||||||
|
documentSnapshot.id);
|
||||||
|
return p;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
for (var p in list) {
|
||||||
|
selectedPackageList.contains(p)
|
||||||
|
? p.isChecked = true
|
||||||
|
: p.isChecked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
packages.addAll(list);
|
||||||
|
if (list.length < rowPerPage) ended = true;
|
||||||
|
notifyListeners();
|
||||||
|
} catch (e) {
|
||||||
|
log.warning("error:$e");
|
||||||
|
} finally {
|
||||||
|
isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearSelection() {
|
||||||
|
selectedPackageList.clear();
|
||||||
|
packages.clear();
|
||||||
|
query = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
120
lib/pages/carton/package_selection_result.dart
Normal file
120
lib/pages/carton/package_selection_result.dart
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../../helpers/theme.dart';
|
||||||
|
import '../../domain/entities/package.dart';
|
||||||
|
import 'model/package_selection_model.dart';
|
||||||
|
|
||||||
|
typedef OnAction = Future<void> Function();
|
||||||
|
final NumberFormat numberFormatter = NumberFormat("#,###");
|
||||||
|
|
||||||
|
class PackageSelectionResult extends StatelessWidget {
|
||||||
|
final bool isLoadingMore;
|
||||||
|
final OnAction onLoadMore;
|
||||||
|
final OnAction onRefresh;
|
||||||
|
final Function(Package)? onTap;
|
||||||
|
final ScrollController controller;
|
||||||
|
|
||||||
|
const PackageSelectionResult(
|
||||||
|
{super.key,
|
||||||
|
required this.isLoadingMore,
|
||||||
|
required this.onLoadMore,
|
||||||
|
required this.onRefresh,
|
||||||
|
this.onTap,
|
||||||
|
required this.controller});
|
||||||
|
|
||||||
|
bool _scrollNotification(ScrollNotification scrollInfo) {
|
||||||
|
if (!isLoadingMore &&
|
||||||
|
scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
|
||||||
|
onLoadMore();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var model = context.watch<PackageSelectionModel>();
|
||||||
|
List<Package> searchResults = model.packages;
|
||||||
|
|
||||||
|
return searchResults.isEmpty && !model.isLoading
|
||||||
|
? Center(
|
||||||
|
child: LocalText(context, 'box.no_package',
|
||||||
|
color: Colors.black, fontSize: 15))
|
||||||
|
: Column(children: [
|
||||||
|
Expanded(
|
||||||
|
child: NotificationListener<ScrollNotification>(
|
||||||
|
onNotification: _scrollNotification,
|
||||||
|
child: RefreshIndicator(
|
||||||
|
color: primaryColor,
|
||||||
|
onRefresh: () => onRefresh(),
|
||||||
|
child: ListView.builder(
|
||||||
|
controller: controller,
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
Package package = searchResults[index];
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 5, bottom: 5),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (onTap != null) {
|
||||||
|
onTap!(package);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.all(Radius.circular(5)),
|
||||||
|
border:
|
||||||
|
Border.all(color: Colors.grey.shade300)),
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Row(
|
||||||
|
children: <Widget>[
|
||||||
|
Expanded(
|
||||||
|
child: new Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 8.0),
|
||||||
|
child: new Column(
|
||||||
|
crossAxisAlignment:
|
||||||
|
CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
new Text(package.trackingID ?? "",
|
||||||
|
style: new TextStyle(
|
||||||
|
fontSize: 15.0,
|
||||||
|
color: Colors.black)),
|
||||||
|
new Text(
|
||||||
|
package.cartonIds.isEmpty
|
||||||
|
? "-"
|
||||||
|
: "${numberFormatter.format(package.cartonIds.length)} Boxes",
|
||||||
|
style: new TextStyle(
|
||||||
|
fontSize: 15.0,
|
||||||
|
color: Colors.grey),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
package.isChecked
|
||||||
|
? Icon(Icons.check, color: primaryColor)
|
||||||
|
: const SizedBox()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: searchResults.length)),
|
||||||
|
)),
|
||||||
|
Container(
|
||||||
|
height: isLoadingMore ? 50.0 : 0,
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: const Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
valueColor: AlwaysStoppedAnimation<Color>(primaryColor)),
|
||||||
|
)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
289
lib/pages/carton/package_selection_widget.dart
Normal file
289
lib/pages/carton/package_selection_widget.dart
Normal file
@@ -0,0 +1,289 @@
|
|||||||
|
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
||||||
|
import 'package:fcs/helpers/theme.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../domain/entities/package.dart';
|
||||||
|
import '../../domain/entities/user.dart';
|
||||||
|
import '../main/util.dart';
|
||||||
|
import '../widgets/barcode_scanner.dart';
|
||||||
|
import '../widgets/continue_button.dart';
|
||||||
|
import '../widgets/display_text.dart';
|
||||||
|
import '../widgets/local_title.dart';
|
||||||
|
import '../widgets/previous_button.dart';
|
||||||
|
import 'model/carton_selection_model.dart';
|
||||||
|
import 'model/package_selection_model.dart';
|
||||||
|
import 'package_selection_result.dart';
|
||||||
|
|
||||||
|
typedef OnPrevious = Function(List<Package> packages);
|
||||||
|
typedef OnContinue = Function(List<Package> packages);
|
||||||
|
|
||||||
|
class PackageSelectionWidget extends StatefulWidget {
|
||||||
|
final User sender;
|
||||||
|
final User consignee;
|
||||||
|
final FcsShipment shipment;
|
||||||
|
final List<Package> packages;
|
||||||
|
final OnPrevious? onPrevious;
|
||||||
|
final OnContinue? onContinue;
|
||||||
|
|
||||||
|
const PackageSelectionWidget({
|
||||||
|
Key? key,
|
||||||
|
required this.packages,
|
||||||
|
this.onPrevious,
|
||||||
|
this.onContinue,
|
||||||
|
required this.shipment,
|
||||||
|
required this.sender,
|
||||||
|
required this.consignee,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PackageSelectionWidget> createState() => _PackageSelectionWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PackageSelectionWidgetState extends State<PackageSelectionWidget> {
|
||||||
|
final TextEditingController _controller = TextEditingController();
|
||||||
|
String _query = "";
|
||||||
|
bool _isLoadMore = false;
|
||||||
|
final _scrollController = ScrollController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
var searchModel = context.read<PackageSelectionModel>();
|
||||||
|
searchModel.addDefaultPackages(
|
||||||
|
shipmentId: widget.shipment.id!,
|
||||||
|
consigneeId: widget.consignee.id!,
|
||||||
|
senderId: widget.sender.id!);
|
||||||
|
|
||||||
|
_controller.text = searchModel.query;
|
||||||
|
_query = searchModel.query;
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant PackageSelectionWidget oldWidget) {
|
||||||
|
_init();
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadMoreData() async {
|
||||||
|
if (_isLoadMore) return;
|
||||||
|
var model = context.read<PackageSelectionModel>();
|
||||||
|
if (model.reachEnd || model.ended) return;
|
||||||
|
setState(() {
|
||||||
|
_isLoadMore = true;
|
||||||
|
});
|
||||||
|
if (_query != "") {
|
||||||
|
await model.loadMoreSearch(
|
||||||
|
term: _query,
|
||||||
|
shipmentId: widget.shipment.id!,
|
||||||
|
consigneeId: widget.consignee.id!,
|
||||||
|
senderId: widget.sender.id!);
|
||||||
|
} else {
|
||||||
|
await model.loadMoreData(
|
||||||
|
shipmentId: widget.shipment.id!,
|
||||||
|
consigneeId: widget.consignee.id!,
|
||||||
|
senderId: widget.sender.id!);
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_isLoadMore = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var model = context.watch<PackageSelectionModel>();
|
||||||
|
List<Package> searchResults = model.packages;
|
||||||
|
List<Package> selectedPackageList = model.selectedPackageList;
|
||||||
|
|
||||||
|
final senderBox = DisplayText(
|
||||||
|
text: widget.sender.name,
|
||||||
|
labelTextKey: "box.sender.title",
|
||||||
|
iconData: MaterialCommunityIcons.account_arrow_right,
|
||||||
|
subText: Text(widget.sender.fcsID!,
|
||||||
|
style: TextStyle(fontSize: 13, color: labelColor)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final consigneeBox = DisplayText(
|
||||||
|
text: widget.consignee.name,
|
||||||
|
labelTextKey: "box.consignee.title",
|
||||||
|
iconData: MaterialCommunityIcons.account_arrow_left,
|
||||||
|
subText: Text(widget.consignee.fcsID!,
|
||||||
|
style: TextStyle(fontSize: 13, color: labelColor)),
|
||||||
|
);
|
||||||
|
|
||||||
|
final userRow = Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: senderBox,
|
||||||
|
flex: 2,
|
||||||
|
),
|
||||||
|
Flexible(child: consigneeBox)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
final continueBtn = ContinueButton(
|
||||||
|
onTap: () {
|
||||||
|
if (selectedPackageList.isEmpty || searchResults.isEmpty) {
|
||||||
|
showMsgDialog(context, 'Error', "Please select the packages");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (widget.onContinue != null) {
|
||||||
|
widget.onContinue!(selectedPackageList);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
final previousBtn = PreviousButton(onTap: () {
|
||||||
|
if (widget.onPrevious != null) {
|
||||||
|
widget.onPrevious!(selectedPackageList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final searchBox = SizedBox(
|
||||||
|
height: 40,
|
||||||
|
child: TextField(
|
||||||
|
controller: _controller,
|
||||||
|
cursorColor: primaryColor,
|
||||||
|
onSubmitted: (value) {
|
||||||
|
setState(() {
|
||||||
|
_query = value;
|
||||||
|
});
|
||||||
|
_search(imm: true);
|
||||||
|
},
|
||||||
|
onChanged: (v) {
|
||||||
|
setState(() {
|
||||||
|
_query = v;
|
||||||
|
});
|
||||||
|
_search();
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
enabledBorder: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: labelColor),
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
|
borderSide:
|
||||||
|
BorderSide(color: labelColor.withOpacity(0.3), width: 0)),
|
||||||
|
focusedBorder: const OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||||
|
borderSide: BorderSide(color: labelColor),
|
||||||
|
),
|
||||||
|
hintText: "Search by tracking number",
|
||||||
|
hintStyle: const TextStyle(
|
||||||
|
color: Colors.grey,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.normal),
|
||||||
|
suffixIcon: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
InkResponse(
|
||||||
|
radius: 20,
|
||||||
|
onTap: () {
|
||||||
|
_scan(context);
|
||||||
|
},
|
||||||
|
child: const Icon(Icons.qr_code_scanner,
|
||||||
|
color: Colors.black87)),
|
||||||
|
IconButton(
|
||||||
|
splashRadius: 20,
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_controller.clear();
|
||||||
|
_query = "";
|
||||||
|
});
|
||||||
|
_search();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.close, color: Colors.black87)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
contentPadding: const EdgeInsets.all(10),
|
||||||
|
filled: true),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(left: 10, right: 10),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
userRow,
|
||||||
|
LocalTitle(textKey: "box.select.package", topPadding: 10),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
searchBox,
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: PackageSelectionResult(
|
||||||
|
controller: _scrollController,
|
||||||
|
isLoadingMore: _isLoadMore,
|
||||||
|
onLoadMore: _loadMoreData,
|
||||||
|
onRefresh: () async {
|
||||||
|
_init();
|
||||||
|
},
|
||||||
|
onTap: (a) async {
|
||||||
|
setState(() {
|
||||||
|
a.isChecked = !a.isChecked;
|
||||||
|
});
|
||||||
|
context.read<PackageSelectionModel>().selectPackage(a);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
widget.onContinue != null
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 15, right: 15, top: 10),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
previousBtn,
|
||||||
|
continueBtn,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: const SizedBox(),
|
||||||
|
const SizedBox(height: 20)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scan(BuildContext context) async {
|
||||||
|
try {
|
||||||
|
String? barcode = await scanBarcode();
|
||||||
|
if (barcode != null) {
|
||||||
|
setState(() {
|
||||||
|
_controller.text = barcode;
|
||||||
|
_query = barcode;
|
||||||
|
});
|
||||||
|
await _search();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showMsgDialog(context, 'Error', e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_search({bool imm = false}) async {
|
||||||
|
try {
|
||||||
|
await context
|
||||||
|
.read<CartonSelectionModel>()
|
||||||
|
.search(_query, imm: imm, shipmentId: widget.shipment.id!);
|
||||||
|
} catch (e) {
|
||||||
|
showMsgDialog(context, 'Error', e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
|
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
|
||||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||||
import 'package:fcs/pages/widgets/local_popup_menu_button.dart';
|
|
||||||
import 'package:fcs/pages/widgets/local_popupmenu.dart';
|
import 'package:fcs/pages/widgets/local_popupmenu.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
import 'package:fcs/pages/widgets/progress.dart';
|
import 'package:fcs/pages/widgets/progress.dart';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
|
|||||||
|
|
||||||
class DisplayText extends StatelessWidget {
|
class DisplayText extends StatelessWidget {
|
||||||
final String? text;
|
final String? text;
|
||||||
final String? text1;
|
final Widget? subText;
|
||||||
final String? labelTextKey;
|
final String? labelTextKey;
|
||||||
final IconData? iconData;
|
final IconData? iconData;
|
||||||
final int? maxLines;
|
final int? maxLines;
|
||||||
@@ -14,11 +14,10 @@ class DisplayText extends StatelessWidget {
|
|||||||
final Color? borderColor;
|
final Color? borderColor;
|
||||||
final Widget? icon;
|
final Widget? icon;
|
||||||
|
|
||||||
|
|
||||||
const DisplayText({
|
const DisplayText({
|
||||||
Key? key,
|
Key? key,
|
||||||
this.text,
|
this.text,
|
||||||
this.text1,
|
this.subText,
|
||||||
this.labelTextKey,
|
this.labelTextKey,
|
||||||
this.iconData,
|
this.iconData,
|
||||||
this.maxLines = 1,
|
this.maxLines = 1,
|
||||||
@@ -72,12 +71,9 @@ class DisplayText extends StatelessWidget {
|
|||||||
text!,
|
text!,
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
text1 == null
|
subText == null
|
||||||
? Container()
|
? Container()
|
||||||
: Text(
|
: subText!,
|
||||||
text1!,
|
|
||||||
style: textStyle,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import 'package:flutter/material.dart';
|
|||||||
class LocalTitle extends StatelessWidget {
|
class LocalTitle extends StatelessWidget {
|
||||||
final String? textKey;
|
final String? textKey;
|
||||||
final Widget? trailing;
|
final Widget? trailing;
|
||||||
|
final double topPadding;
|
||||||
final List<String>? translationVariables;
|
final List<String>? translationVariables;
|
||||||
|
|
||||||
const LocalTitle(
|
const LocalTitle(
|
||||||
{Key? key, this.textKey, this.trailing, this.translationVariables})
|
{Key? key, this.textKey, this.trailing, this.translationVariables,this.topPadding = 18})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -17,7 +18,7 @@ class LocalTitle extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.only(top: 18),
|
padding: EdgeInsets.only(top: topPadding),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
LocalText(context, textKey!,
|
LocalText(context, textKey!,
|
||||||
|
|||||||
45
lib/pages/widgets/submit_text_widget.dart
Normal file
45
lib/pages/widgets/submit_text_widget.dart
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../helpers/theme.dart';
|
||||||
|
import 'local_text.dart';
|
||||||
|
|
||||||
|
class SubmitTextWidget extends StatelessWidget {
|
||||||
|
final String labelKey;
|
||||||
|
final String text;
|
||||||
|
final String? subText;
|
||||||
|
|
||||||
|
const SubmitTextWidget(
|
||||||
|
{Key? key, required this.labelKey, required this.text, this.subText})
|
||||||
|
: super(key: key);
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 5, bottom: 5),
|
||||||
|
child: LocalText(context, labelKey,
|
||||||
|
color: primaryColor, fontSize: 16, fontWeight: FontWeight.normal),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: primaryColor),
|
||||||
|
borderRadius: BorderRadius.circular(5),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(text,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16.0, fontWeight: FontWeight.w500)),
|
||||||
|
subText == null
|
||||||
|
? const SizedBox()
|
||||||
|
: Text(subText!,
|
||||||
|
style:
|
||||||
|
const TextStyle(fontSize: 14.0, color: Colors.grey)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user