Merge branch 'master' of tzw/fcs into master
This commit is contained in:
@@ -371,7 +371,7 @@
|
||||
"box.crete.carton":"Create carton",
|
||||
"box.carton.type":"Carton type",
|
||||
"box.select.delivery":"Last mile",
|
||||
"box.select.package":"Select packages",
|
||||
"box.select.package":"Packages",
|
||||
"box.no_package":"There is no packages.",
|
||||
"box.input_cargo_weight":"Cargo type (lb)",
|
||||
"box.input_surcharge_item":"Surcharge items",
|
||||
@@ -523,6 +523,7 @@
|
||||
"rate.discount.rate":"Discount rate",
|
||||
"rate.custom_duty.title":"Custom Fee",
|
||||
"rate.custom_duty":"Custom Fee",
|
||||
"rate.custom_new":"New custom fee",
|
||||
"rate.cargo.type":"Cargo Types",
|
||||
"rate.discount_by_weight":"Discounts by weight",
|
||||
"rate.discount_by_weight.edit.delete.confirm":"Delete this discount by weight?",
|
||||
@@ -530,6 +531,8 @@
|
||||
"Rate End ================================================================":"",
|
||||
|
||||
"Cargo Start ================================================================":"",
|
||||
"cargo.title":"Cargoes",
|
||||
"cargo.new":"New cargo",
|
||||
"cargo.form.title":"Cargo",
|
||||
"cargo.type":"Cargo type",
|
||||
"cargo.weight":"Weight",
|
||||
@@ -539,6 +542,7 @@
|
||||
"cargo.edit.delete.confirm":"Delete this cargo type?",
|
||||
"cargo.display_index":"Display index",
|
||||
"cargo.is_default":"Default Cargo",
|
||||
"cargo.is_mix":"Mix cargo",
|
||||
"Cargo End ================================================================":"",
|
||||
|
||||
"Invoices Start ================================================================":"",
|
||||
|
||||
@@ -371,7 +371,7 @@
|
||||
"box.crete.carton":"Create carton",
|
||||
"box.carton.type":"ပုံး အမျိုးအစား",
|
||||
"box.select.delivery":"Last mile",
|
||||
"box.select.package":"Select packages",
|
||||
"box.select.package":"Packages",
|
||||
"box.no_package":"There is no packages.",
|
||||
"box.input_cargo_weight":"Cargo type (lb)",
|
||||
"box.input_surcharge_item":"Surcharge items",
|
||||
@@ -526,6 +526,7 @@
|
||||
"rate.discount.rate":"လျှော့စျေးနှုန်း",
|
||||
"rate.custom_duty.title":"အကောက်ခွန်များ",
|
||||
"rate.custom_duty":"အကောက်ခွန်",
|
||||
"rate.custom_new":"အကောက်ခွန်အသစ်",
|
||||
"rate.cargo.type":"ကုန်ပစ္စည်းအမျိုးအစား",
|
||||
"rate.discount_by_weight":"အထူးလျှော့စျေး",
|
||||
"rate.discount_by_weight.edit.delete.confirm":"လျှော့စျေးနှုန်းကို ဖျက်မလား?",
|
||||
@@ -533,6 +534,8 @@
|
||||
"Rate End ================================================================":"",
|
||||
|
||||
"Cargo Start ================================================================":"",
|
||||
"cargo.title":"ကုန်ပစ္စည်းများ",
|
||||
"cargo.new":"ကုန်ပစ္စည်းအသစ်",
|
||||
"cargo.form.title":"ကုန်ပစ္စည်း",
|
||||
"cargo.type":"ကုန်ပစ္စည်းအမျိုးအစား",
|
||||
"cargo.weight":"အလေးချိန်",
|
||||
@@ -542,6 +545,7 @@
|
||||
"cargo.edit.delete.confirm":"ကုန်ပစ္စည်းကို ဖျက်မလား?",
|
||||
"cargo.display_index":"Display index",
|
||||
"cargo.is_default":"Default Cargo",
|
||||
"cargo.is_mix":"Mix cargo",
|
||||
"Cargo End ================================================================":"",
|
||||
|
||||
"Invoices Start ================================================================":"",
|
||||
|
||||
53
lib/app.dart
53
lib/app.dart
@@ -46,35 +46,34 @@ class App extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _AppState extends State<App> {
|
||||
final MainModel mainModel = new MainModel();
|
||||
final ContactModel contactModel = new ContactModel();
|
||||
final TermModel termModel = new TermModel();
|
||||
final FAQModel faqModel = new FAQModel();
|
||||
final PaymentMethodModel paymentMethodModel = new PaymentMethodModel();
|
||||
final FcsShipmentModel fcsShipmentModel = new FcsShipmentModel();
|
||||
final LanguageModel lanuguageModel = new LanguageModel();
|
||||
final ShipmentRateModel shipmentRateModel = new ShipmentRateModel();
|
||||
final CartonModel boxModel = new CartonModel();
|
||||
final MessageModel messageModel = new MessageModel();
|
||||
final InvoiceModel invoiceModel = new InvoiceModel();
|
||||
final CustomerModel customerModel = new CustomerModel();
|
||||
final DiscountModel discountModel = new DiscountModel();
|
||||
final StaffModel staffModel = new StaffModel();
|
||||
final DeliveryAddressModel deliveryAddressModel = new DeliveryAddressModel();
|
||||
final PackageModel packageModel = new PackageModel();
|
||||
final MarketModel marketModel = new MarketModel();
|
||||
final DeliveryModel deliveryModel = new DeliveryModel();
|
||||
final CartonSizeModel cartonSizeModel = new CartonSizeModel();
|
||||
final ProcessingModel processingModel = new ProcessingModel();
|
||||
final PickupModel pickupModel = new PickupModel();
|
||||
final CartonSelectionModel cartonSelectionModel = new CartonSelectionModel();
|
||||
final PackageSelectionModel packageSelectionModel =
|
||||
new PackageSelectionModel();
|
||||
final MainModel mainModel = MainModel();
|
||||
final ContactModel contactModel = ContactModel();
|
||||
final TermModel termModel = TermModel();
|
||||
final FAQModel faqModel = FAQModel();
|
||||
final PaymentMethodModel paymentMethodModel = PaymentMethodModel();
|
||||
final FcsShipmentModel fcsShipmentModel = FcsShipmentModel();
|
||||
final LanguageModel lanuguageModel = LanguageModel();
|
||||
final ShipmentRateModel shipmentRateModel = ShipmentRateModel();
|
||||
final CartonModel boxModel = CartonModel();
|
||||
final MessageModel messageModel = MessageModel();
|
||||
final InvoiceModel invoiceModel = InvoiceModel();
|
||||
final CustomerModel customerModel = CustomerModel();
|
||||
final DiscountModel discountModel = DiscountModel();
|
||||
final StaffModel staffModel = StaffModel();
|
||||
final DeliveryAddressModel deliveryAddressModel = DeliveryAddressModel();
|
||||
final PackageModel packageModel = PackageModel();
|
||||
final MarketModel marketModel = MarketModel();
|
||||
final DeliveryModel deliveryModel = DeliveryModel();
|
||||
final CartonSizeModel cartonSizeModel = CartonSizeModel();
|
||||
final ProcessingModel processingModel = ProcessingModel();
|
||||
final PickupModel pickupModel = PickupModel();
|
||||
final CartonSelectionModel cartonSelectionModel = CartonSelectionModel();
|
||||
final PackageSelectionModel packageSelectionModel = PackageSelectionModel();
|
||||
final ConsigneeSelectionModel consigneeSelectionModel =
|
||||
new ConsigneeSelectionModel();
|
||||
final SenderSelectionModel senderSelectionModel = new SenderSelectionModel();
|
||||
ConsigneeSelectionModel();
|
||||
final SenderSelectionModel senderSelectionModel = SenderSelectionModel();
|
||||
final ShipmentSelectionModel shipmentSelectionModel =
|
||||
new ShipmentSelectionModel();
|
||||
ShipmentSelectionModel();
|
||||
|
||||
late AppTranslationsDelegate _newLocaleDelegate;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class CargoType {
|
||||
double calWeight;
|
||||
int displayIndex;
|
||||
bool isDefault;
|
||||
bool isMixCargo;
|
||||
|
||||
double get calAmount => calRate * calWeight;
|
||||
|
||||
@@ -26,7 +27,8 @@ class CargoType {
|
||||
this.isCutomDuty = false,
|
||||
this.customDutyFee = 0,
|
||||
this.displayIndex = 0,
|
||||
this.isDefault = false});
|
||||
this.isDefault = false,
|
||||
this.isMixCargo = false});
|
||||
|
||||
factory CargoType.fromMap(Map<String, dynamic> map, String id) {
|
||||
return CargoType(
|
||||
@@ -39,7 +41,8 @@ class CargoType {
|
||||
isCutomDuty: map['custom_duty'] ?? false,
|
||||
customDutyFee: (map['custom_duty_fee'] ?? 0).toDouble(),
|
||||
displayIndex: map['display_index'] ?? 0,
|
||||
isDefault: map['is_defalut'] ?? false);
|
||||
isDefault: map['is_defalut'] ?? false,
|
||||
isMixCargo: map['is_mix_cargo'] ?? false);
|
||||
}
|
||||
|
||||
factory CargoType.fromMapForCargo(Map<String, dynamic> map, String id) {
|
||||
@@ -62,18 +65,19 @@ class CargoType {
|
||||
"id": id,
|
||||
'name': name,
|
||||
'rate': rate,
|
||||
'weight': weight,
|
||||
'cal_weight': calWeight,
|
||||
'cal_rate': calRate,
|
||||
'custom_duty': isCutomDuty,
|
||||
'custom_duty_fee': customDutyFee,
|
||||
'qty': qty,
|
||||
// 'weight': weight,
|
||||
// 'cal_weight': calWeight,
|
||||
// 'cal_rate': calRate,
|
||||
// 'custom_duty': isCutomDuty,
|
||||
// 'custom_duty_fee': customDutyFee,
|
||||
// 'qty': qty,
|
||||
'is_defalut': isDefault,
|
||||
'display_index': displayIndex
|
||||
'display_index': displayIndex,
|
||||
'is_mix_cargo': isMixCargo
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMapForCargo() {
|
||||
Map<String, dynamic> toMapForCarton() {
|
||||
return {"id": id, 'weight': weight};
|
||||
}
|
||||
|
||||
@@ -82,7 +86,7 @@ class CargoType {
|
||||
}
|
||||
|
||||
CargoType clone() {
|
||||
return CargoType.fromMap(toMap(), this.id!);
|
||||
return CargoType.fromMap(toMap(), id!);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -97,12 +101,16 @@ class CargoType {
|
||||
}
|
||||
|
||||
bool isChangedForEdit(CargoType cargoType) {
|
||||
return cargoType.name != this.name || cargoType.rate != this.rate;
|
||||
return cargoType.name != name ||
|
||||
cargoType.rate != rate ||
|
||||
cargoType.displayIndex != displayIndex ||
|
||||
cargoType.isDefault != isDefault ||
|
||||
cargoType.isMixCargo != isMixCargo;
|
||||
}
|
||||
|
||||
bool isChangedForEditCustomDuty(CargoType cargoType) {
|
||||
return cargoType.name != this.name ||
|
||||
cargoType.customDutyFee != this.customDutyFee ||
|
||||
cargoType.rate != this.rate;
|
||||
return cargoType.name != name ||
|
||||
cargoType.customDutyFee != customDutyFee ||
|
||||
cargoType.rate != rate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ class Carton {
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
var _types = cargoTypes.where((t) => t.weight != 0).toList();
|
||||
var _cargoTypes = _types.map((c) => c.toMapForCargo()).toList();
|
||||
var _cargoTypes = _types.map((c) => c.toMapForCarton()).toList();
|
||||
|
||||
var _packagesIds = packages.map((c) => c.id).toList();
|
||||
|
||||
|
||||
@@ -24,3 +24,12 @@ List<LocalPopupMenu> shipFiteringMenu = <LocalPopupMenu>[
|
||||
LocalPopupMenu(id: 7, text: "Delivered"),
|
||||
LocalPopupMenu(id: 6, text: "Canceled"),
|
||||
];
|
||||
|
||||
List<LocalPopupMenu> packageFiteringMenu = <LocalPopupMenu>[
|
||||
LocalPopupMenu(id: 0, text: "All"),
|
||||
LocalPopupMenu(id: 1, text: "Received"),
|
||||
LocalPopupMenu(id: 2, text: "Processed"),
|
||||
LocalPopupMenu(id: 3, text: "Packed"),
|
||||
LocalPopupMenu(id: 4, text: "Shipped"),
|
||||
LocalPopupMenu(id: 5, text: "Delivered"),
|
||||
];
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:fcs/constants.dart';
|
||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||
import 'package:fcs/domain/entities/carton.dart';
|
||||
@@ -24,12 +26,14 @@ import '../fcs_shipment/model/fcs_shipment_model.dart';
|
||||
import '../widgets/local_button.dart';
|
||||
import 'carton_package_editor.dart';
|
||||
import 'mix_carton/mix_carton_editor.dart';
|
||||
import 'mix_carton_detail_list.dart';
|
||||
import 'model/carton_model.dart';
|
||||
import 'package_detail_list.dart';
|
||||
import 'print_qr_code_page.dart';
|
||||
|
||||
class CartonInfo extends StatefulWidget {
|
||||
final Carton carton;
|
||||
CartonInfo({required this.carton});
|
||||
const CartonInfo({super.key, required this.carton});
|
||||
|
||||
@override
|
||||
_CartonInfoState createState() => _CartonInfoState();
|
||||
@@ -176,14 +180,28 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
showLabelLink: true,
|
||||
subText: Text(numberFormatter.format(_packages.length)),
|
||||
labelTextKey: "box.package",
|
||||
onTapLabel: () {},
|
||||
onTapLabel: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => PackageDetailList(
|
||||
cartonNumber: _carton.cartonNumber ?? '',
|
||||
packages: _packages)));
|
||||
},
|
||||
);
|
||||
|
||||
final mixCartonLengthBox = DisplayText(
|
||||
showLabelLink: true,
|
||||
subText: Text(numberFormatter.format(_mixCartons.length)),
|
||||
labelTextKey: "box.shipment.boxes",
|
||||
onTapLabel: () {},
|
||||
onTapLabel: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => MixCartonDetailList(
|
||||
cartonNumber: _carton.cartonNumber ?? '',
|
||||
cartons: _mixCartons)));
|
||||
},
|
||||
);
|
||||
|
||||
final senderBox = userDisplayBox(context,
|
||||
@@ -315,18 +333,20 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 2),
|
||||
child: Container(
|
||||
color: e.key.isEven ? Colors.grey.shade300 : oddColor,
|
||||
color: e.key.isEven ? Colors.grey.shade300 : oddColor,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
e.value.name ?? "",
|
||||
style: TextStyle(color: Colors.black, fontSize: 15),
|
||||
style:
|
||||
TextStyle(color: Colors.black, fontSize: 15),
|
||||
),
|
||||
Text("${removeTrailingZeros((e.value.qty).toDouble())} pc",
|
||||
Text(
|
||||
"${removeTrailingZeros((e.value.qty).toDouble())} pc",
|
||||
textAlign: TextAlign.end,
|
||||
style:
|
||||
TextStyle(color: Colors.black, fontSize: 15))
|
||||
style: TextStyle(
|
||||
color: Colors.black, fontSize: 15))
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -482,10 +502,16 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(child: cartonSizeBox),
|
||||
Flexible(child: packageLengthBox),
|
||||
_packages.isEmpty
|
||||
? const SizedBox()
|
||||
: Flexible(child: packageLengthBox),
|
||||
],
|
||||
),
|
||||
fromPackage ? const SizedBox() : mixCartonLengthBox,
|
||||
fromPackage
|
||||
? const SizedBox()
|
||||
: _mixCartons.isEmpty
|
||||
? const SizedBox()
|
||||
: mixCartonLengthBox,
|
||||
shipmentBox,
|
||||
// _packages.isEmpty
|
||||
// ? const SizedBox()
|
||||
@@ -541,9 +567,7 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
return list.map((p) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
child: Container(
|
||||
child: Row(children: <Widget>[new Text(p.trackingID ?? "")]),
|
||||
));
|
||||
child: Row(children: <Widget>[Text(p.trackingID ?? "")]));
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@@ -551,9 +575,7 @@ class _CartonInfoState extends State<CartonInfo> {
|
||||
return list.map((c) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
child: Container(
|
||||
child: Row(children: <Widget>[new Text(c.cartonNumber ?? '')]),
|
||||
));
|
||||
child: Row(children: <Widget>[Text(c.cartonNumber ?? '')]));
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
||||
@@ -134,9 +134,9 @@ class _CartonListState extends State<CartonList> {
|
||||
FadeTransition(
|
||||
opacity: animation,
|
||||
child: SizeTransition(
|
||||
child: child,
|
||||
sizeFactor: animation,
|
||||
axis: Axis.vertical,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
child: _down
|
||||
@@ -289,36 +289,43 @@ class _CartonListState extends State<CartonList> {
|
||||
|
||||
Widget _filterWidget(BuildContext context) {
|
||||
var model = Provider.of<CartonModel>(context);
|
||||
return IconButton(
|
||||
icon: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
const Icon(
|
||||
Icons.filter_list,
|
||||
color: Colors.white,
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: IconButton(
|
||||
icon: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
const Icon(
|
||||
Icons.filter_list,
|
||||
color: Colors.white,
|
||||
),
|
||||
model.filterByStatus != null ||
|
||||
model.filterBySender != null ||
|
||||
model.filterByConsingee != null ||
|
||||
model.shipment != null
|
||||
? Positioned(
|
||||
bottom: 15,
|
||||
right: 0,
|
||||
child: Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
model.filterByStatus != null ||
|
||||
model.filterBySender != null ||
|
||||
model.filterByConsingee != null ||
|
||||
model.shipment != null
|
||||
? Positioned(
|
||||
bottom: 15,
|
||||
right: 0,
|
||||
child: Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
_showFilter();
|
||||
});
|
||||
),
|
||||
onPressed: () {
|
||||
_showFilter();
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
_showFilter() async {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use, use_build_context_synchronously
|
||||
|
||||
import 'package:fcs/pages/carton/model/carton_model.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -26,7 +26,7 @@ import 'cargo_widget.dart';
|
||||
import 'carton_size_widget.dart';
|
||||
import 'carton_submit.dart';
|
||||
import 'model/package_selection_model.dart';
|
||||
import 'package_selection_widget.dart';
|
||||
import 'packages_widget.dart';
|
||||
|
||||
class CartonPackageEditor extends StatefulWidget {
|
||||
final Carton carton;
|
||||
@@ -233,11 +233,10 @@ class _CartonPackageEditorState extends State<CartonPackageEditor> {
|
||||
));
|
||||
} else if (step.stepType == StepType.PACKAGES) {
|
||||
return Expanded(
|
||||
child: PackageSelectionWidget(
|
||||
child: PackagesWidget(
|
||||
sender: _sender!,
|
||||
consignee: _consignee!,
|
||||
shipment: _shipment!,
|
||||
packages: _packages,
|
||||
onContinue: (packages) {
|
||||
setState(() {
|
||||
_packages = List.from(packages);
|
||||
|
||||
@@ -23,7 +23,7 @@ import 'carton_size_widget.dart';
|
||||
import 'carton_submit.dart';
|
||||
import 'model/carton_model.dart';
|
||||
import 'model/package_selection_model.dart';
|
||||
import 'package_selection_widget.dart';
|
||||
import 'packages_widget.dart';
|
||||
|
||||
class CartonPackageForm extends StatefulWidget {
|
||||
final User sender;
|
||||
@@ -166,11 +166,10 @@ class _CartonPackageFormState extends State<CartonPackageForm> {
|
||||
));
|
||||
} else if (step.stepType == StepType.PACKAGES) {
|
||||
return Expanded(
|
||||
child: PackageSelectionWidget(
|
||||
child: PackagesWidget(
|
||||
sender: widget.sender,
|
||||
consignee: widget.consignee,
|
||||
shipment: _shipment!,
|
||||
packages: _packages,
|
||||
onContinue: (packages) {
|
||||
setState(() {
|
||||
_packages = List.from(packages);
|
||||
|
||||
@@ -522,7 +522,7 @@ class _CartonSizeWidgetState extends State<CartonSizeWidget> {
|
||||
children: [
|
||||
const SizedBox(height: 8),
|
||||
userRow,
|
||||
LocalTitle(textKey: "box.bill_to", topPadding: 8),
|
||||
LocalTitle(textKey: "box.bill_to", topPadding: 5),
|
||||
const SizedBox(height: 5),
|
||||
billRadioBox,
|
||||
const SizedBox(height: 8),
|
||||
|
||||
114
lib/pages/carton/mix_carton_detail_list.dart
Normal file
114
lib/pages/carton/mix_carton_detail_list.dart
Normal file
@@ -0,0 +1,114 @@
|
||||
import 'package:fcs/domain/entities/carton.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../widgets/local_text.dart';
|
||||
import 'carton_info.dart';
|
||||
|
||||
class MixCartonDetailList extends StatelessWidget {
|
||||
final String cartonNumber;
|
||||
final List<Carton> cartons;
|
||||
MixCartonDetailList(
|
||||
{super.key, required this.cartonNumber, required this.cartons});
|
||||
|
||||
final NumberFormat numberFormatter = NumberFormat("#,###");
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
backgroundColor: Colors.white,
|
||||
arrowColor: primaryColor,
|
||||
labelColor: primaryColor,
|
||||
titleWidget: Column(
|
||||
children: [
|
||||
LocalText(
|
||||
context,
|
||||
"box.cartion.count",
|
||||
fontSize: 20,
|
||||
color: primaryColor,
|
||||
translationVariables: [numberFormatter.format(cartons.length)],
|
||||
),
|
||||
Text(cartonNumber,
|
||||
style: TextStyle(fontSize: 15, color: Colors.black))
|
||||
],
|
||||
),
|
||||
),
|
||||
body: ListView.separated(
|
||||
separatorBuilder: (context, index) =>
|
||||
Divider(height: 1, color: dividerColor),
|
||||
itemCount: cartons.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var carton = cartons[index];
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => CartonInfo(carton: carton)),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 15, right: 15),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(MaterialCommunityIcons.package,
|
||||
color: primaryColor),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
carton.cartonNumber == null
|
||||
? ''
|
||||
: carton.cartonNumber!,
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.black),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
carton.consigneeName ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"${carton.cartonWeight.toStringAsFixed(2)} lb",
|
||||
style: TextStyle(fontSize: 14.0, color: Colors.grey),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -145,4 +145,33 @@ class PackageSelectionModel extends BaseModel {
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Future<List<Package>> getActivePackages(
|
||||
{required String shipmentId,
|
||||
required String senderId,
|
||||
required String consigneeId}) async {
|
||||
List<Package> list = [];
|
||||
try {
|
||||
String path = "/$packages_collection";
|
||||
|
||||
var snaps = await FirebaseFirestore.instance
|
||||
.collection(path)
|
||||
.where("status",
|
||||
whereIn: [package_processed_status, package_packed_status])
|
||||
.where("sender_id", isEqualTo: senderId)
|
||||
.where("user_id", isEqualTo: consigneeId)
|
||||
// .where("fcs_shipment_id", isEqualTo: shipmentId)
|
||||
.where("is_deleted", isEqualTo: false)
|
||||
.orderBy("created_date", descending: true)
|
||||
.get(const GetOptions(source: Source.server));
|
||||
list = snaps.docs
|
||||
.map((documentSnapshot) =>
|
||||
Package.fromMap(documentSnapshot.data(), documentSnapshot.id))
|
||||
.toList();
|
||||
} catch (e) {
|
||||
log.warning("Error!! $e");
|
||||
list = [];
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
111
lib/pages/carton/package_detail_list.dart
Normal file
111
lib/pages/carton/package_detail_list.dart
Normal file
@@ -0,0 +1,111 @@
|
||||
import 'package:fcs/domain/entities/package.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/package/package_info.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../widgets/local_text.dart';
|
||||
|
||||
class PackageDetailList extends StatelessWidget {
|
||||
final String cartonNumber;
|
||||
final List<Package> packages;
|
||||
PackageDetailList(
|
||||
{super.key, required this.cartonNumber, required this.packages});
|
||||
|
||||
final NumberFormat numberFormatter = NumberFormat("#,###");
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
backgroundColor: Colors.white,
|
||||
arrowColor: primaryColor,
|
||||
labelColor: primaryColor,
|
||||
titleWidget: Column(
|
||||
children: [
|
||||
LocalText(
|
||||
context,
|
||||
"box.package.count",
|
||||
fontSize: 20,
|
||||
color: primaryColor,
|
||||
translationVariables: [numberFormatter.format(packages.length)],
|
||||
),
|
||||
Text(cartonNumber,
|
||||
style: TextStyle(fontSize: 15, color: Colors.black))
|
||||
],
|
||||
),
|
||||
),
|
||||
body: ListView.separated(
|
||||
separatorBuilder: (context, index) =>
|
||||
Divider(height: 1, color: dividerColor),
|
||||
itemCount: packages.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
var package = packages[index];
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(
|
||||
builder: (context) => PackageInfo(package: package)),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 15, right: 15),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(Octicons.package, color: primaryColor),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
package.id == null
|
||||
? ''
|
||||
: package.trackingID!,
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.black),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
package.market == null
|
||||
? ''
|
||||
: package.market!,
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
211
lib/pages/carton/packages_widget.dart
Normal file
211
lib/pages/carton/packages_widget.dart
Normal file
@@ -0,0 +1,211 @@
|
||||
import 'package:fcs/domain/entities/fcs_shipment.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.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/continue_button.dart';
|
||||
import '../widgets/local_title.dart';
|
||||
import '../widgets/previous_button.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 PackagesWidget extends StatefulWidget {
|
||||
final User sender;
|
||||
final User consignee;
|
||||
final FcsShipment shipment;
|
||||
final OnPrevious? onPrevious;
|
||||
final OnContinue? onContinue;
|
||||
|
||||
const PackagesWidget({
|
||||
super.key,
|
||||
this.onPrevious,
|
||||
this.onContinue,
|
||||
required this.shipment,
|
||||
required this.sender,
|
||||
required this.consignee,
|
||||
});
|
||||
|
||||
@override
|
||||
State<PackagesWidget> createState() => _PackagesWidgetState();
|
||||
}
|
||||
|
||||
class _PackagesWidgetState extends State<PackagesWidget> {
|
||||
final _scrollController = ScrollController();
|
||||
bool _down = true;
|
||||
List<Package> _packages = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_init();
|
||||
super.initState();
|
||||
_scrollController.addListener(() {
|
||||
setState(() {
|
||||
_down = _scrollController.position.userScrollDirection ==
|
||||
ScrollDirection.forward;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_init() async {
|
||||
_packages.clear();
|
||||
var packageModel = context.read<PackageSelectionModel>();
|
||||
var list = await packageModel.getActivePackages(
|
||||
shipmentId: widget.shipment.id!,
|
||||
senderId: widget.sender.id!,
|
||||
consigneeId: widget.consignee.id!);
|
||||
_packages = List.from(list);
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final senderBox = userDisplayBox(context,
|
||||
lableKey: "box.sender.title",
|
||||
icon: MaterialCommunityIcons.account_arrow_right,
|
||||
showLink: false,
|
||||
name: widget.sender.name ?? "",
|
||||
fcsID: widget.sender.fcsID ?? "");
|
||||
|
||||
final consigneeBox = userDisplayBox(context,
|
||||
showLink: false,
|
||||
lableKey: "box.consignee.title",
|
||||
icon: MaterialCommunityIcons.account_arrow_left,
|
||||
name: widget.consignee.name,
|
||||
fcsID: widget.consignee.fcsID);
|
||||
|
||||
final userRow = Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(flex: 2, child: consigneeBox),
|
||||
Flexible(child: senderBox)
|
||||
],
|
||||
);
|
||||
|
||||
final continueBtn = ContinueButton(
|
||||
onTap: () {
|
||||
if (widget.onContinue != null) {
|
||||
widget.onContinue!(_packages);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
final previousBtn = PreviousButton(onTap: () {
|
||||
if (widget.onPrevious != null) {
|
||||
widget.onPrevious!(_packages);
|
||||
}
|
||||
});
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
transitionBuilder:
|
||||
(Widget child, Animation<double> animation) =>
|
||||
FadeTransition(
|
||||
opacity: animation,
|
||||
child: SizeTransition(
|
||||
sizeFactor: animation,
|
||||
axis: Axis.vertical,
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
child: _down
|
||||
? Column(children: [
|
||||
const SizedBox(height: 8),
|
||||
userRow,
|
||||
LocalTitle(
|
||||
textKey: "box.select.package", topPadding: 5),
|
||||
const SizedBox(height: 10),
|
||||
])
|
||||
: const SizedBox(),
|
||||
),
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
color: primaryColor,
|
||||
onRefresh: () async {
|
||||
_init();
|
||||
},
|
||||
child: ListView.builder(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
controller: _scrollController,
|
||||
shrinkWrap: true,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
Package package = _packages[index];
|
||||
return packageRow(context, package);
|
||||
},
|
||||
itemCount: _packages.length)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
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 packageRow(BuildContext context, Package package) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 5),
|
||||
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: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(package.trackingID ?? "",
|
||||
style: TextStyle(fontSize: 15.0, color: Colors.black)),
|
||||
Text(
|
||||
package.cartonIds.isEmpty
|
||||
? "-"
|
||||
: "${numberFormatter.format(package.cartonIds.length)} Boxes",
|
||||
style: TextStyle(fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
package.isChecked
|
||||
? Icon(Icons.check, color: primaryColor)
|
||||
: const SizedBox()
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,14 @@ import 'fcs_shipment_editor.dart';
|
||||
import 'fcs_shipment_list_row.dart';
|
||||
|
||||
class FcsShipmentList extends StatefulWidget {
|
||||
const FcsShipmentList({super.key});
|
||||
|
||||
@override
|
||||
_FcsShipmentListState createState() => _FcsShipmentListState();
|
||||
}
|
||||
|
||||
class _FcsShipmentListState extends State<FcsShipmentList> {
|
||||
bool _isLoading = false;
|
||||
bool isLoading = false;
|
||||
int _selectedIndex = 0;
|
||||
|
||||
@override
|
||||
@@ -41,7 +43,7 @@ class _FcsShipmentListState extends State<FcsShipmentList> {
|
||||
var shipmentModel = Provider.of<FcsShipmentModel>(context);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
inAsyncCall: isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(labelKey: "FCSshipment.list.title", actions: [
|
||||
_menuFilteringWidget(context),
|
||||
@@ -66,63 +68,68 @@ class _FcsShipmentListState extends State<FcsShipmentList> {
|
||||
}
|
||||
|
||||
Widget _menuFilteringWidget(BuildContext context) {
|
||||
return PopupMenuButton<LocalPopupMenu>(
|
||||
splashRadius: 25,
|
||||
padding: const EdgeInsets.only(right: 15),
|
||||
elevation: 3.2,
|
||||
tooltip: 'This is tooltip',
|
||||
onSelected: (choice) async {
|
||||
setState(() {
|
||||
_selectedIndex = choice.id;
|
||||
});
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: PopupMenuButton<LocalPopupMenu>(
|
||||
elevation: 3.2,
|
||||
tooltip: '',
|
||||
onSelected: (choice) async {
|
||||
setState(() {
|
||||
_selectedIndex = choice.id;
|
||||
});
|
||||
|
||||
await context.read<FcsShipmentModel>().onChanged(choice.id);
|
||||
},
|
||||
icon: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
const Icon(
|
||||
Icons.filter_list,
|
||||
color: Colors.white,
|
||||
await context.read<FcsShipmentModel>().onChanged(choice.id);
|
||||
},
|
||||
icon: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
const Icon(
|
||||
Icons.filter_list,
|
||||
color: Colors.white,
|
||||
),
|
||||
_selectedIndex != 0
|
||||
? Positioned(
|
||||
bottom: 15,
|
||||
right: 0,
|
||||
child: Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
_selectedIndex != 0
|
||||
? Positioned(
|
||||
bottom: 15,
|
||||
right: 0,
|
||||
child: Container(
|
||||
),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return shipFiteringMenu.map((LocalPopupMenu choice) {
|
||||
return PopupMenuItem<LocalPopupMenu>(
|
||||
value: choice,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Text("${choice.text}",
|
||||
style: TextStyle(color: Colors.black))),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return shipFiteringMenu.map((LocalPopupMenu choice) {
|
||||
return PopupMenuItem<LocalPopupMenu>(
|
||||
value: choice,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Text("${choice.text}",
|
||||
style: TextStyle(color: Colors.black))),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
_selectedIndex == choice.id
|
||||
? const Icon(
|
||||
Icons.check,
|
||||
color: Colors.grey,
|
||||
)
|
||||
: const SizedBox(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
});
|
||||
_selectedIndex == choice.id
|
||||
? const Icon(
|
||||
Icons.check,
|
||||
color: Colors.grey,
|
||||
)
|
||||
: const SizedBox(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import 'fcs_shipment_info.dart';
|
||||
|
||||
class FcsShipmentListRow extends StatelessWidget {
|
||||
final FcsShipment shipment;
|
||||
final dateFormatter = new DateFormat('dd MMM yyyy');
|
||||
FcsShipmentListRow({Key? key, required this.shipment}) : super(key: key);
|
||||
final dateFormatter = DateFormat('dd MMM yyyy');
|
||||
FcsShipmentListRow({super.key, required this.shipment});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -23,31 +23,31 @@ class FcsShipmentListRow extends StatelessWidget {
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new Padding(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 13),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Ionicons.ios_airplane,
|
||||
color: primaryColor,
|
||||
size: 30,
|
||||
),
|
||||
new Expanded(
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: new Column(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text(
|
||||
Text(
|
||||
shipment.shipmentNumber ?? '',
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.black),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
dateFormatter.format(shipment.cutoffDate!),
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -23,17 +23,20 @@ class PackageModel extends BaseModel {
|
||||
PaginatorListener<Package>? activePackages;
|
||||
|
||||
bool isLoading = false;
|
||||
int selectedIndex = 1;
|
||||
int selectedIndexForCustomer = 1;
|
||||
int selectedIndex = 0;
|
||||
|
||||
initData(int index, bool isCustomer) {
|
||||
selectedIndex = index;
|
||||
if (isCustomer) {
|
||||
_loadPaginationCustomerPackages(selectedIndex == 2);
|
||||
} else {
|
||||
_loadPaginationPackages(selectedIndex == 2);
|
||||
}
|
||||
initDataForCustomer(int index) {
|
||||
selectedIndexForCustomer = index;
|
||||
_loadPaginationCustomerPackages(selectedIndexForCustomer == 2);
|
||||
}
|
||||
|
||||
initData(int index) {
|
||||
selectedIndex = index;
|
||||
_loadPaginationPackages(selectedIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
void privilegeChanged() {
|
||||
if (user != null) {
|
||||
_loadPaginationActivePackages();
|
||||
@@ -47,30 +50,57 @@ class PackageModel extends BaseModel {
|
||||
if (activePackages != null) activePackages!.close();
|
||||
}
|
||||
|
||||
onChanged(int index, bool isCustomer) {
|
||||
selectedIndex = index;
|
||||
if (isCustomer) {
|
||||
_loadPaginationCustomerPackages(selectedIndex == 2);
|
||||
} else {
|
||||
_loadPaginationPackages(selectedIndex == 2);
|
||||
}
|
||||
onChangedForCustomer(int index) {
|
||||
selectedIndexForCustomer = index;
|
||||
_loadPaginationCustomerPackages(selectedIndexForCustomer == 2);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
_loadPaginationPackages(bool isDelivered) {
|
||||
_loadPaginationPackages(int index) {
|
||||
if (user == null) return;
|
||||
if (!((user!.hasPackages() ||
|
||||
user!.hasReceiving() ||
|
||||
user!.hasProcessing()))) return;
|
||||
user!.hasProcessing()))) {
|
||||
return;
|
||||
}
|
||||
String path = "/$packages_collection";
|
||||
|
||||
Query col = FirebaseFirestore.instance
|
||||
.collection(path)
|
||||
.where("is_delivered", isEqualTo: isDelivered);
|
||||
Query pageQuery = FirebaseFirestore.instance
|
||||
.collection(path)
|
||||
.where("is_delivered", isEqualTo: isDelivered)
|
||||
.orderBy("update_time", descending: true);
|
||||
Query col = FirebaseFirestore.instance.collection(path);
|
||||
Query pageQuery = FirebaseFirestore.instance.collection(path);
|
||||
|
||||
// received status
|
||||
if (index == 1) {
|
||||
col = col.where("status", isEqualTo: package_received_status);
|
||||
pageQuery = pageQuery.where("status", isEqualTo: package_received_status);
|
||||
}
|
||||
|
||||
// processed status
|
||||
if (index == 2) {
|
||||
col = col.where("status", isEqualTo: package_processed_status);
|
||||
pageQuery =
|
||||
pageQuery.where("status", isEqualTo: package_processed_status);
|
||||
}
|
||||
|
||||
// packed status
|
||||
if (index == 3) {
|
||||
col = col.where("status", isEqualTo: package_packed_status);
|
||||
pageQuery = pageQuery.where("status", isEqualTo: package_packed_status);
|
||||
}
|
||||
|
||||
// shipped status
|
||||
if (index == 4) {
|
||||
col = col.where("status", isEqualTo: package_shipped_status);
|
||||
pageQuery = pageQuery.where("status", isEqualTo: package_shipped_status);
|
||||
}
|
||||
|
||||
// delivered status
|
||||
if (index == 5) {
|
||||
col = col.where("status", isEqualTo: package_delivered_status);
|
||||
pageQuery =
|
||||
pageQuery.where("status", isEqualTo: package_delivered_status);
|
||||
}
|
||||
|
||||
pageQuery = pageQuery.orderBy("update_time", descending: true);
|
||||
|
||||
packages?.close();
|
||||
packages = PaginatorListener<Package>(
|
||||
@@ -78,6 +108,12 @@ class PackageModel extends BaseModel {
|
||||
rowPerLoad: 30);
|
||||
}
|
||||
|
||||
onChanged(int index) {
|
||||
selectedIndex = index;
|
||||
_loadPaginationPackages(index);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
_loadPaginationCustomerPackages(bool isDelivered) {
|
||||
if (user == null) return;
|
||||
String path = "/$packages_collection";
|
||||
@@ -102,7 +138,9 @@ class PackageModel extends BaseModel {
|
||||
if (user == null) return;
|
||||
if (!((user!.hasPackages() ||
|
||||
user!.hasReceiving() ||
|
||||
user!.hasProcessing()))) return;
|
||||
user!.hasProcessing()))) {
|
||||
return;
|
||||
}
|
||||
String path = "/$packages_collection";
|
||||
|
||||
Query col = FirebaseFirestore.instance
|
||||
@@ -142,7 +180,7 @@ class PackageModel extends BaseModel {
|
||||
String path = "/$packages_collection";
|
||||
try {
|
||||
var snaps = await FirebaseFirestore.instance
|
||||
.collection("$path")
|
||||
.collection(path)
|
||||
.where("tracking_id", isEqualTo: trackingID)
|
||||
.where("is_deleted", isEqualTo: false)
|
||||
.get(const GetOptions(source: Source.server));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:fcs/domain/entities/package.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/package/model/package_model.dart';
|
||||
@@ -16,14 +18,15 @@ import 'package:provider/provider.dart';
|
||||
class PackageList extends StatefulWidget {
|
||||
final bool forCustomer;
|
||||
|
||||
const PackageList({Key? key, this.forCustomer = true}) : super(key: key);
|
||||
const PackageList({super.key, this.forCustomer = true});
|
||||
@override
|
||||
_PackageListState createState() => _PackageListState();
|
||||
}
|
||||
|
||||
class _PackageListState extends State<PackageList> {
|
||||
bool _isLoading = false;
|
||||
int _selectedIndex = 1;
|
||||
bool isLoading = false;
|
||||
int _selectedIndexForCustomer = 1;
|
||||
int _selectedIndex = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -33,8 +36,13 @@ class _PackageListState extends State<PackageList> {
|
||||
|
||||
_init() {
|
||||
var model = context.read<PackageModel>();
|
||||
_selectedIndex = model.selectedIndex;
|
||||
model.initData(_selectedIndex, widget.forCustomer);
|
||||
if (widget.forCustomer) {
|
||||
_selectedIndexForCustomer = model.selectedIndexForCustomer;
|
||||
model.initDataForCustomer(_selectedIndexForCustomer);
|
||||
} else {
|
||||
_selectedIndex = model.selectedIndex;
|
||||
model.initData(_selectedIndex);
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
setState(() {});
|
||||
@@ -53,23 +61,23 @@ class _PackageListState extends State<PackageList> {
|
||||
LocalPopupMenu(
|
||||
id: 1,
|
||||
textKey: "package.popupmenu.active",
|
||||
selected: packageModel.selectedIndex == 1),
|
||||
selected: packageModel.selectedIndexForCustomer == 1),
|
||||
LocalPopupMenu(
|
||||
id: 2,
|
||||
textKey: "package.popupmenu.delivered",
|
||||
selected: packageModel.selectedIndex == 2)
|
||||
selected: packageModel.selectedIndexForCustomer == 2)
|
||||
],
|
||||
popupMenuCallback: (p) {
|
||||
this.setState(() {
|
||||
_selectedIndex = p.id;
|
||||
setState(() {
|
||||
_selectedIndexForCustomer = p.id;
|
||||
});
|
||||
context
|
||||
.read<PackageModel>()
|
||||
.onChanged(_selectedIndex, widget.forCustomer);
|
||||
.onChangedForCustomer(_selectedIndexForCustomer);
|
||||
});
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
inAsyncCall: isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
labelKey: 'package.title',
|
||||
@@ -84,7 +92,7 @@ class _PackageListState extends State<PackageList> {
|
||||
iconSize: 30,
|
||||
onPressed: () => searchPackage(context,
|
||||
callbackPackageSelect: _searchCallback)),
|
||||
popupMenu
|
||||
widget.forCustomer ? popupMenu : _menuFilteringWidget(context)
|
||||
],
|
||||
),
|
||||
body: PaginatorListView<Package>(
|
||||
@@ -98,11 +106,77 @@ class _PackageListState extends State<PackageList> {
|
||||
|
||||
_searchCallback(Package package) async {
|
||||
var packageModel = Provider.of<PackageModel>(context, listen: false);
|
||||
Package? _package = await packageModel.getPackage(package.id!);
|
||||
if (_package == null) return;
|
||||
Package? package0 = await packageModel.getPackage(package.id!);
|
||||
if (package0 == null) return;
|
||||
Navigator.push(
|
||||
context,
|
||||
CupertinoPageRoute(builder: (context) => PackageInfo(package: _package)),
|
||||
CupertinoPageRoute(builder: (context) => PackageInfo(package: package0)),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _menuFilteringWidget(BuildContext context) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(right: 5),
|
||||
child: PopupMenuButton<LocalPopupMenu>(
|
||||
elevation: 3.2,
|
||||
tooltip: '',
|
||||
onSelected: (choice) async {
|
||||
setState(() {
|
||||
_selectedIndex = choice.id;
|
||||
});
|
||||
|
||||
await context.read<PackageModel>().onChanged(choice.id);
|
||||
},
|
||||
icon: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
const Icon(
|
||||
Icons.filter_list,
|
||||
color: Colors.white,
|
||||
),
|
||||
_selectedIndex != 0
|
||||
? Positioned(
|
||||
bottom: 15,
|
||||
right: 0,
|
||||
child: Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: const BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container()
|
||||
],
|
||||
),
|
||||
),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return packageFiteringMenu.map((LocalPopupMenu choice) {
|
||||
return PopupMenuItem<LocalPopupMenu>(
|
||||
value: choice,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Text("${choice.text}",
|
||||
style: TextStyle(color: Colors.black))),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
_selectedIndex == choice.id
|
||||
? const Icon(
|
||||
Icons.check,
|
||||
color: Colors.grey,
|
||||
)
|
||||
: const SizedBox(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,20 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
typedef CallbackPackageSelect(Package package);
|
||||
typedef CallbackPackageSelect = Function(Package package);
|
||||
|
||||
class PackageListRow extends StatelessWidget {
|
||||
final bool isCustomer;
|
||||
final Package package;
|
||||
final CallbackPackageSelect? callbackPackageSelect;
|
||||
final double dotSize = 15.0;
|
||||
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
|
||||
final DateFormat dateFormat = DateFormat("dd MMM yyyy");
|
||||
|
||||
PackageListRow(
|
||||
{Key? key,
|
||||
{super.key,
|
||||
required this.package,
|
||||
this.callbackPackageSelect,
|
||||
this.isCustomer = false})
|
||||
: super(key: key);
|
||||
this.isCustomer = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -44,30 +43,30 @@ class PackageListRow extends StatelessWidget {
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new Padding(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 13),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(Octicons.package, color: primaryColor),
|
||||
new Expanded(
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: new Column(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text(
|
||||
Text(
|
||||
package.id == null ? '' : package.trackingID!,
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.black),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
package.market == null
|
||||
? ''
|
||||
: package.market!,
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0, color: Colors.black),
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -88,12 +87,11 @@ class PackageListRow extends StatelessWidget {
|
||||
fontWeight: FontWeight.bold)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
package.currentStatusDate != null
|
||||
? dateFormat.format(package.currentStatusDate!)
|
||||
: '',
|
||||
style:
|
||||
new TextStyle(fontSize: 14.0, color: Colors.grey),
|
||||
style: TextStyle(fontSize: 14.0, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -7,17 +7,16 @@ import 'package:intl/intl.dart';
|
||||
|
||||
import 'processing_info.dart';
|
||||
|
||||
typedef CallbackPackageSelect(Package package);
|
||||
typedef CallbackPackageSelect = Function(Package package);
|
||||
|
||||
class ProcessingListRow extends StatelessWidget {
|
||||
final Package package;
|
||||
final CallbackPackageSelect? callbackPackageSelect;
|
||||
final double dotSize = 15.0;
|
||||
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
|
||||
final DateFormat dateFormat = DateFormat("dd MMM yyyy");
|
||||
|
||||
ProcessingListRow(
|
||||
{Key? key, required this.package, this.callbackPackageSelect})
|
||||
: super(key: key);
|
||||
{super.key, required this.package, this.callbackPackageSelect});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -38,30 +37,30 @@ class ProcessingListRow extends StatelessWidget {
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new Padding(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 13.0),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(FontAwesome.dropbox, color: primaryColor, size: 30),
|
||||
new Expanded(
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: new Column(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text(
|
||||
Text(
|
||||
package.trackingID == null
|
||||
? ''
|
||||
: package.trackingID!,
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.black),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5.0),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
package.market == null ? '' : package.market!,
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0, color: Colors.black),
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -82,11 +81,11 @@ class ProcessingListRow extends StatelessWidget {
|
||||
fontWeight: FontWeight.bold)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
package.currentStatusDate != null
|
||||
? dateFormat.format(package.currentStatusDate!)
|
||||
: '',
|
||||
style: new TextStyle(fontSize: 14.0, color: Colors.grey),
|
||||
style: TextStyle(fontSize: 14.0, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -28,9 +28,11 @@ import 'account_delection_page.dart';
|
||||
import 'add_recovery_email.dart';
|
||||
import 'change_phone_number.dart';
|
||||
|
||||
typedef void ProfileCallback();
|
||||
typedef ProfileCallback = void Function();
|
||||
|
||||
class Profile extends StatefulWidget {
|
||||
const Profile({super.key});
|
||||
|
||||
@override
|
||||
_ProfileState createState() => _ProfileState();
|
||||
}
|
||||
@@ -52,9 +54,9 @@ class _ProfileState extends State<Profile> {
|
||||
|
||||
buildLanguage(LanguageModel languageModel) async {
|
||||
var lan = await languageModel.load();
|
||||
if (this.selectedLanguage != lan) {
|
||||
if (selectedLanguage != lan) {
|
||||
setState(() {
|
||||
this.selectedLanguage = lan;
|
||||
selectedLanguage = lan;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/main/util.dart';
|
||||
@@ -6,6 +8,7 @@ import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../widgets/local_text.dart';
|
||||
@@ -13,32 +16,34 @@ import 'model/shipment_rate_model.dart';
|
||||
|
||||
class CargoEditor extends StatefulWidget {
|
||||
final CargoType? cargo;
|
||||
CargoEditor({this.cargo});
|
||||
const CargoEditor({super.key, this.cargo});
|
||||
|
||||
@override
|
||||
_CargoEditorState createState() => _CargoEditorState();
|
||||
}
|
||||
|
||||
class _CargoEditorState extends State<CargoEditor> {
|
||||
TextEditingController _descController = new TextEditingController();
|
||||
TextEditingController _rateController = new TextEditingController();
|
||||
TextEditingController _displayIndexController = new TextEditingController();
|
||||
TextEditingController descController = TextEditingController();
|
||||
TextEditingController rateController = TextEditingController();
|
||||
TextEditingController displayIndexController = TextEditingController();
|
||||
|
||||
bool _isLoading = false;
|
||||
late CargoType _cargo;
|
||||
bool _isNew = false;
|
||||
final _cargoFormKey = GlobalKey<FormState>();
|
||||
bool _isDefault = false;
|
||||
bool _isMixCargo = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.cargo != null) {
|
||||
_cargo = widget.cargo!;
|
||||
_descController.text = _cargo.name ?? "";
|
||||
_rateController.text = _cargo.rate.toStringAsFixed(2);
|
||||
_displayIndexController.text = _cargo.displayIndex.toString();
|
||||
descController.text = _cargo.name ?? "";
|
||||
rateController.text = _cargo.rate.toStringAsFixed(2);
|
||||
displayIndexController.text = _cargo.displayIndex.toString();
|
||||
_isDefault = _cargo.isDefault;
|
||||
_isMixCargo = _cargo.isMixCargo;
|
||||
} else {
|
||||
_isNew = true;
|
||||
}
|
||||
@@ -53,8 +58,8 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
Widget build(BuildContext context) {
|
||||
final typeBox = InputText(
|
||||
labelTextKey: 'cargo.type',
|
||||
iconData: Icons.text_format,
|
||||
controller: _descController,
|
||||
iconData: Ionicons.text,
|
||||
controller: descController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
@@ -66,8 +71,8 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
|
||||
final rateBox = InputText(
|
||||
labelTextKey: 'cargo.rate',
|
||||
iconData: Icons.attach_money,
|
||||
controller: _rateController,
|
||||
iconData: Fontisto.dollar,
|
||||
controller: rateController,
|
||||
textInputType: TextInputType.number,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
@@ -80,8 +85,8 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
|
||||
final displayIndexBox = InputText(
|
||||
labelTextKey: 'cargo.display_index',
|
||||
iconData: Icons.numbers,
|
||||
controller: _displayIndexController,
|
||||
iconData: FontAwesome.sort_numeric_asc,
|
||||
controller: displayIndexController,
|
||||
textInputType: TextInputType.number,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
// validator: (value) {
|
||||
@@ -93,7 +98,7 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
);
|
||||
|
||||
final defaultBox = Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 20),
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Flexible(
|
||||
child: Column(
|
||||
@@ -112,7 +117,7 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
scale: 0.7,
|
||||
alignment: Alignment.centerRight,
|
||||
child: CupertinoSwitch(
|
||||
activeColor: primaryColor,
|
||||
activeTrackColor: primaryColor,
|
||||
value: _isDefault,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
@@ -122,6 +127,34 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
]),
|
||||
);
|
||||
|
||||
final mixCargoBox =
|
||||
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
LocalText(
|
||||
context,
|
||||
'cargo.is_mix',
|
||||
color: Colors.black54,
|
||||
fontSize: 15,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Transform.scale(
|
||||
scale: 0.7,
|
||||
alignment: Alignment.centerRight,
|
||||
child: CupertinoSwitch(
|
||||
activeTrackColor: primaryColor,
|
||||
value: _isMixCargo,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
_isMixCargo = v;
|
||||
});
|
||||
}))
|
||||
]);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
@@ -160,14 +193,16 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
typeBox,
|
||||
rateBox,
|
||||
displayIndexBox,
|
||||
SizedBox(height: 10),
|
||||
defaultBox,
|
||||
mixCargoBox,
|
||||
SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
),
|
||||
fcsButton(context, getLocalString(context, "btn.save"),
|
||||
callack: _save),
|
||||
SizedBox(height: 10)
|
||||
SizedBox(height: 30)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -186,18 +221,19 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
try {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
CargoType _cargo = CargoType(
|
||||
name: _descController.text,
|
||||
rate: double.parse(_rateController.text),
|
||||
displayIndex: _displayIndexController.text == ''
|
||||
CargoType cargo = CargoType(
|
||||
name: descController.text,
|
||||
rate: double.parse(rateController.text),
|
||||
displayIndex: displayIndexController.text == ''
|
||||
? 0
|
||||
: int.parse(_displayIndexController.text),
|
||||
isDefault: _isDefault);
|
||||
: int.parse(displayIndexController.text),
|
||||
isDefault: _isDefault,
|
||||
isMixCargo: _isMixCargo);
|
||||
if (_isNew) {
|
||||
await shipmentRateModel.addCargoType(_cargo);
|
||||
await shipmentRateModel.addCargoType(cargo);
|
||||
} else {
|
||||
_cargo.id = this._cargo.id;
|
||||
await shipmentRateModel.updateCargoType(_cargo);
|
||||
cargo.id = _cargo.id;
|
||||
await shipmentRateModel.updateCargoType(cargo);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
@@ -220,7 +256,7 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
try {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
await shipmentRateModel.deleteCargoType(this._cargo.id!);
|
||||
await shipmentRateModel.deleteCargoType(_cargo.id!);
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -233,11 +269,19 @@ class _CargoEditorState extends State<CargoEditor> {
|
||||
|
||||
isDataChanged() {
|
||||
if (_isNew) {
|
||||
return _descController.text != "" || _rateController.text != "";
|
||||
return descController.text != "" ||
|
||||
rateController.text != "" ||
|
||||
displayIndexController.text != "" ||
|
||||
_isDefault != false ||
|
||||
_isMixCargo != false;
|
||||
} else {
|
||||
CargoType _cargo = CargoType(
|
||||
name: _descController.text, rate: double.parse(_rateController.text));
|
||||
return this._cargo.isChangedForEdit(_cargo);
|
||||
CargoType cargo = CargoType(
|
||||
name: descController.text,
|
||||
rate: double.parse(rateController.text),
|
||||
displayIndex: int.parse(displayIndexController.text),
|
||||
isDefault: _isDefault,
|
||||
isMixCargo: _isMixCargo);
|
||||
return _cargo.isChangedForEdit(cargo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import 'cargo_editor.dart';
|
||||
import 'model/shipment_rate_model.dart';
|
||||
|
||||
class CargoTypeList extends StatefulWidget {
|
||||
const CargoTypeList({Key? key}) : super(key: key);
|
||||
const CargoTypeList({super.key});
|
||||
@override
|
||||
_CargoTypeListState createState() => _CargoTypeListState();
|
||||
}
|
||||
|
||||
class _CargoTypeListState extends State<CargoTypeList> {
|
||||
bool _isLoading = false;
|
||||
bool isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -34,9 +34,9 @@ class _CargoTypeListState extends State<CargoTypeList> {
|
||||
var shipmentRateModel = Provider.of<ShipmentRateModel>(context);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
inAsyncCall: isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(labelKey: "cargo.form.title"),
|
||||
appBar: LocalAppBar(labelKey: "cargo.title"),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(
|
||||
@@ -44,8 +44,7 @@ class _CargoTypeListState extends State<CargoTypeList> {
|
||||
},
|
||||
icon: Icon(Icons.add, color: Colors.white),
|
||||
backgroundColor: primaryColor,
|
||||
label:
|
||||
LocalText(context, 'cargo.form.title', color: Colors.white)),
|
||||
label: LocalText(context, 'cargo.new', color: Colors.white)),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ListView.separated(
|
||||
@@ -64,7 +63,7 @@ class _CargoTypeListState extends State<CargoTypeList> {
|
||||
},
|
||||
child: Container(
|
||||
child: _row(cargo.name ?? "",
|
||||
"\$ " + cargo.rate.toStringAsFixed(2), 'per pound'),
|
||||
"\$ ${cargo.rate.toStringAsFixed(2)}", 'per pound'),
|
||||
),
|
||||
);
|
||||
}),
|
||||
@@ -85,12 +84,12 @@ class _CargoTypeListState extends State<CargoTypeList> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 3.0),
|
||||
child: Text(
|
||||
'$price',
|
||||
price,
|
||||
style: TextStyle(color: primaryColor, fontSize: 14),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'$unit',
|
||||
unit,
|
||||
style: TextStyle(color: Colors.grey, fontSize: 14),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/main/util.dart';
|
||||
@@ -5,6 +7,7 @@ import 'package:fcs/pages/widgets/input_text.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
@@ -12,19 +15,19 @@ import 'model/shipment_rate_model.dart';
|
||||
|
||||
class CustomEditor extends StatefulWidget {
|
||||
final CargoType? custom;
|
||||
CustomEditor({this.custom});
|
||||
const CustomEditor({super.key, this.custom});
|
||||
|
||||
@override
|
||||
_CustomEditorState createState() => _CustomEditorState();
|
||||
}
|
||||
|
||||
class _CustomEditorState extends State<CustomEditor> {
|
||||
TextEditingController _productController = new TextEditingController();
|
||||
TextEditingController _feeController = new TextEditingController();
|
||||
TextEditingController _shipmentRateController = new TextEditingController();
|
||||
TextEditingController productController = TextEditingController();
|
||||
TextEditingController feeController = TextEditingController();
|
||||
TextEditingController shipmentRateController = TextEditingController();
|
||||
|
||||
bool _isLoading = false;
|
||||
CargoType _custom = new CargoType();
|
||||
CargoType _custom = CargoType();
|
||||
bool _isNew = false;
|
||||
final _customFormKey = GlobalKey<FormState>();
|
||||
|
||||
@@ -33,9 +36,9 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
super.initState();
|
||||
if (widget.custom != null) {
|
||||
_custom = widget.custom!;
|
||||
_productController.text = _custom.name ?? "";
|
||||
_feeController.text = _custom.customDutyFee.toStringAsFixed(2);
|
||||
_shipmentRateController.text = _custom.rate.toStringAsFixed(2);
|
||||
productController.text = _custom.name ?? "";
|
||||
feeController.text = _custom.customDutyFee.toStringAsFixed(2);
|
||||
shipmentRateController.text = _custom.rate.toStringAsFixed(2);
|
||||
} else {
|
||||
_isNew = true;
|
||||
}
|
||||
@@ -49,20 +52,22 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final productBox = InputText(
|
||||
labelTextKey: 'rate.cutom.product_type',
|
||||
iconData: FontAwesomeIcons.weightHanging,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
controller: _productController,
|
||||
validator: (value){
|
||||
if(value==null || value.isEmpty){
|
||||
return "Please insert product type";
|
||||
}
|
||||
return null;
|
||||
},);
|
||||
labelTextKey: 'rate.cutom.product_type',
|
||||
iconData: FontAwesomeIcons.weightHanging,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
controller: productController,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Please insert product type";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
final feeBox = InputText(
|
||||
labelTextKey: 'rate.custom.fee',
|
||||
iconData: Icons.attach_money,
|
||||
controller: _feeController,
|
||||
iconData: Fontisto.dollar,
|
||||
controller: feeController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
@@ -74,8 +79,8 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
|
||||
final shipmentRateBox = InputText(
|
||||
labelTextKey: 'rate.custom.shipment_rate',
|
||||
iconData: Icons.attach_money,
|
||||
controller: _shipmentRateController,
|
||||
iconData: Fontisto.dollar,
|
||||
controller: shipmentRateController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
@@ -128,7 +133,7 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
),
|
||||
fcsButton(context, getLocalString(context, "btn.save"),
|
||||
callack: _save),
|
||||
SizedBox(height: 10)
|
||||
SizedBox(height: 30)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -148,15 +153,15 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
try {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
CargoType _customduty = CargoType(
|
||||
name: _productController.text,
|
||||
customDutyFee: double.parse(_feeController.text),
|
||||
rate: double.parse(_shipmentRateController.text));
|
||||
CargoType customduty = CargoType(
|
||||
name: productController.text,
|
||||
customDutyFee: double.parse(feeController.text),
|
||||
rate: double.parse(shipmentRateController.text));
|
||||
if (_isNew) {
|
||||
await shipmentRateModel.addCustomDuty(_customduty);
|
||||
await shipmentRateModel.addCustomDuty(customduty);
|
||||
} else {
|
||||
_customduty.id = this._custom.id;
|
||||
await shipmentRateModel.updateCustomDuty(_customduty);
|
||||
customduty.id = _custom.id;
|
||||
await shipmentRateModel.updateCustomDuty(customduty);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
@@ -180,7 +185,7 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
try {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
await shipmentRateModel.deleteCustomDuty(this._custom.id!);
|
||||
await shipmentRateModel.deleteCustomDuty(_custom.id!);
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -193,15 +198,15 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
|
||||
isDataChanged() {
|
||||
if (_isNew) {
|
||||
return _productController.text != "" ||
|
||||
_feeController.text != "" ||
|
||||
_shipmentRateController.text != "";
|
||||
return productController.text != "" ||
|
||||
feeController.text != "" ||
|
||||
shipmentRateController.text != "";
|
||||
} else {
|
||||
CargoType _customduty = CargoType(
|
||||
name: _productController.text,
|
||||
customDutyFee: double.parse(_feeController.text),
|
||||
rate: double.parse(_shipmentRateController.text));
|
||||
return this._custom.isChangedForEditCustomDuty(_customduty);
|
||||
CargoType customduty = CargoType(
|
||||
name: productController.text,
|
||||
customDutyFee: double.parse(feeController.text),
|
||||
rate: double.parse(shipmentRateController.text));
|
||||
return _custom.isChangedForEditCustomDuty(customduty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import 'model/shipment_rate_model.dart';
|
||||
|
||||
class CustomList extends StatefulWidget {
|
||||
final bool? selected;
|
||||
const CustomList({Key? key, this.selected}) : super(key: key);
|
||||
const CustomList({super.key, this.selected});
|
||||
@override
|
||||
_CustomListState createState() => _CustomListState();
|
||||
}
|
||||
|
||||
class _CustomListState extends State<CustomList> {
|
||||
bool _isLoading = false;
|
||||
bool isLoading = false;
|
||||
bool _selected = false;
|
||||
|
||||
@override
|
||||
@@ -38,7 +38,7 @@ class _CustomListState extends State<CustomList> {
|
||||
var shipmentRateModel = Provider.of<ShipmentRateModel>(context);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
inAsyncCall: isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(labelKey: 'rate.custom_duty.title'),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
@@ -49,7 +49,7 @@ class _CustomListState extends State<CustomList> {
|
||||
icon: Icon(Icons.add, color: Colors.white),
|
||||
backgroundColor: primaryColor,
|
||||
label:
|
||||
LocalText(context, 'rate.custom_duty', color: Colors.white)),
|
||||
LocalText(context, 'rate.custom_new', color: Colors.white)),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: ListView.separated(
|
||||
@@ -70,13 +70,11 @@ class _CustomListState extends State<CustomList> {
|
||||
child: Container(
|
||||
child: _row(
|
||||
custom.name ?? "",
|
||||
"Custom Fee \$ " +
|
||||
custom.customDutyFee.toStringAsFixed(2),
|
||||
"Custom Fee \$ ${custom.customDutyFee.toStringAsFixed(2)}",
|
||||
// ignore: unnecessary_null_comparison
|
||||
custom.rate == null
|
||||
? ""
|
||||
: "Shipment rate \$ " +
|
||||
custom.rate.toStringAsFixed(2)),
|
||||
: "Shipment rate \$ ${custom.rate.toStringAsFixed(2)}"),
|
||||
),
|
||||
);
|
||||
}),
|
||||
@@ -97,7 +95,7 @@ class _CustomListState extends State<CustomList> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 3.0),
|
||||
child: Text(
|
||||
'$fee',
|
||||
fee,
|
||||
style: TextStyle(color: primaryColor, fontSize: 14),
|
||||
),
|
||||
),
|
||||
@@ -106,7 +104,7 @@ class _CustomListState extends State<CustomList> {
|
||||
: Padding(
|
||||
padding: const EdgeInsets.only(top: 3.0),
|
||||
child: Text(
|
||||
"$shipmentRate",
|
||||
shipmentRate,
|
||||
style: TextStyle(color: Colors.grey, fontSize: 14),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -11,30 +11,20 @@ import 'package:provider/provider.dart';
|
||||
import 'model/shipment_rate_model.dart';
|
||||
|
||||
class DiscountByWeightList extends StatefulWidget {
|
||||
const DiscountByWeightList({Key? key}) : super(key: key);
|
||||
const DiscountByWeightList({super.key});
|
||||
@override
|
||||
_DiscountByWeightListState createState() => _DiscountByWeightListState();
|
||||
}
|
||||
|
||||
class _DiscountByWeightListState extends State<DiscountByWeightList> {
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
bool isLoading = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var shipmentRateModel = Provider.of<ShipmentRateModel>(context);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
inAsyncCall: isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(labelKey: 'rate.discount_by_weight'),
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
@@ -64,7 +54,7 @@ class _DiscountByWeightListState extends State<DiscountByWeightList> {
|
||||
child: Container(
|
||||
child: _row(
|
||||
"${discountByWeight.weight.toStringAsFixed(2)} lb",
|
||||
"\$ " + discountByWeight.discount.toString()),
|
||||
"\$ ${discountByWeight.discount}"),
|
||||
),
|
||||
);
|
||||
}),
|
||||
@@ -85,7 +75,7 @@ class _DiscountByWeightListState extends State<DiscountByWeightList> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 3.0),
|
||||
child: Text(
|
||||
'$price',
|
||||
price,
|
||||
style: TextStyle(color: primaryColor, fontSize: 14),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/main/util.dart';
|
||||
@@ -6,24 +8,25 @@ import 'package:fcs/pages/widgets/input_text.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class DiscountByWeightEditor extends StatefulWidget {
|
||||
final DiscountByWeight? discountByWeight;
|
||||
DiscountByWeightEditor({this.discountByWeight});
|
||||
const DiscountByWeightEditor({super.key, this.discountByWeight});
|
||||
|
||||
@override
|
||||
_DiscountByWeightEditorState createState() => _DiscountByWeightEditorState();
|
||||
}
|
||||
|
||||
class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
TextEditingController _weightController = new TextEditingController();
|
||||
TextEditingController _discountController = new TextEditingController();
|
||||
TextEditingController weightController = TextEditingController();
|
||||
TextEditingController discountController = TextEditingController();
|
||||
|
||||
bool _isLoading = false;
|
||||
bool _isNew = false;
|
||||
DiscountByWeight _discountByWeight = new DiscountByWeight();
|
||||
DiscountByWeight _discountByWeight = DiscountByWeight();
|
||||
final _discountFormKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
@@ -31,8 +34,8 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
super.initState();
|
||||
if (widget.discountByWeight != null) {
|
||||
_discountByWeight = widget.discountByWeight!;
|
||||
_weightController.text = _discountByWeight.weight.toStringAsFixed(2);
|
||||
_discountController.text = _discountByWeight.discount.toString();
|
||||
weightController.text = _discountByWeight.weight.toStringAsFixed(2);
|
||||
discountController.text = _discountByWeight.discount.toString();
|
||||
_isNew = false;
|
||||
} else {
|
||||
_isNew = true;
|
||||
@@ -49,7 +52,7 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
final weightBox = InputText(
|
||||
labelTextKey: 'rate.discount.weight',
|
||||
iconData: FontAwesomeIcons.weightHanging,
|
||||
controller: _weightController,
|
||||
controller: weightController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
@@ -60,8 +63,8 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
);
|
||||
final discountRateBox = InputText(
|
||||
labelTextKey: 'rate.discount.rate',
|
||||
iconData: Icons.attach_money,
|
||||
controller: _discountController,
|
||||
iconData: Fontisto.dollar,
|
||||
controller: discountController,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
@@ -75,7 +78,7 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
inAsyncCall: _isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
labelKey: 'discount.new',
|
||||
labelKey: 'discount.form',
|
||||
backgroundColor: Colors.white,
|
||||
labelColor: primaryColor,
|
||||
arrowColor: primaryColor,
|
||||
@@ -114,7 +117,7 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
),
|
||||
fcsButton(context, getLocalString(context, "btn.save"),
|
||||
callack: _save),
|
||||
SizedBox(height: 10)
|
||||
SizedBox(height: 30)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -134,14 +137,14 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
try {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
DiscountByWeight _discount = DiscountByWeight(
|
||||
weight: double.parse(_weightController.text),
|
||||
discount: double.parse(_discountController.text));
|
||||
DiscountByWeight discount = DiscountByWeight(
|
||||
weight: double.parse(weightController.text),
|
||||
discount: double.parse(discountController.text));
|
||||
if (_isNew) {
|
||||
await shipmentRateModel.addDiscountByWeight(_discount);
|
||||
await shipmentRateModel.addDiscountByWeight(discount);
|
||||
} else {
|
||||
_discount.id = this._discountByWeight.id;
|
||||
await shipmentRateModel.updateDiscountByWeight(_discount);
|
||||
discount.id = _discountByWeight.id;
|
||||
await shipmentRateModel.updateDiscountByWeight(discount);
|
||||
}
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
@@ -165,8 +168,7 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
try {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
await shipmentRateModel
|
||||
.deleteDiscountByWeight(this._discountByWeight.id!);
|
||||
await shipmentRateModel.deleteDiscountByWeight(_discountByWeight.id!);
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -179,12 +181,12 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
||||
|
||||
isDataChanged() {
|
||||
if (_isNew) {
|
||||
return _weightController.text != "" || _discountController.text != "";
|
||||
return weightController.text != "" || discountController.text != "";
|
||||
} else {
|
||||
DiscountByWeight _discount = DiscountByWeight(
|
||||
weight: double.parse(_weightController.text),
|
||||
discount: double.parse(_discountController.text));
|
||||
return this._discountByWeight.isChangedForEdit(_discount);
|
||||
DiscountByWeight discount = DiscountByWeight(
|
||||
weight: double.parse(weightController.text),
|
||||
discount: double.parse(discountController.text));
|
||||
return _discountByWeight.isChangedForEdit(discount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,23 +11,24 @@ import 'package:fcs/pages/widgets/local_dropdown.dart';
|
||||
import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class ShipmentRatesCal extends StatefulWidget {
|
||||
ShipmentRatesCal();
|
||||
const ShipmentRatesCal({super.key});
|
||||
|
||||
@override
|
||||
_ShipmentRatesCalState createState() => _ShipmentRatesCalState();
|
||||
}
|
||||
|
||||
class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
||||
bool _isLoading = false;
|
||||
bool isLoading = false;
|
||||
late CargoType _cargoType;
|
||||
TextEditingController _widthController = new TextEditingController();
|
||||
TextEditingController _heightController = new TextEditingController();
|
||||
TextEditingController _lengthController = new TextEditingController();
|
||||
TextEditingController _actualWeightCtl = new TextEditingController();
|
||||
TextEditingController widthController = TextEditingController();
|
||||
TextEditingController heightController = TextEditingController();
|
||||
TextEditingController lengthController = TextEditingController();
|
||||
TextEditingController actualWeightCtl = TextEditingController();
|
||||
double _shipmentWeight = 0;
|
||||
double _amount = 0;
|
||||
double _deliveryFee = 0;
|
||||
@@ -38,25 +39,25 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
||||
|
||||
//for shipment weight
|
||||
Rate rate = Provider.of<ShipmentRateModel>(context, listen: false).rate;
|
||||
_lengthController.addListener(_calShipmentWeight);
|
||||
_widthController.addListener(_calShipmentWeight);
|
||||
_heightController.addListener(_calShipmentWeight);
|
||||
_actualWeightCtl.addListener(_calShipmentWeight);
|
||||
lengthController.addListener(_calShipmentWeight);
|
||||
widthController.addListener(_calShipmentWeight);
|
||||
heightController.addListener(_calShipmentWeight);
|
||||
actualWeightCtl.addListener(_calShipmentWeight);
|
||||
_cargoType = rate.defaultCargoType;
|
||||
_lengthController.text = '12';
|
||||
_widthController.text = '12';
|
||||
_heightController.text = '12';
|
||||
_actualWeightCtl.text = "10.00";
|
||||
lengthController.text = '12';
|
||||
widthController.text = '12';
|
||||
heightController.text = '12';
|
||||
actualWeightCtl.text = "10.00";
|
||||
_calShipmentWeight();
|
||||
}
|
||||
|
||||
_calShipmentWeight() {
|
||||
Rate rate = Provider.of<ShipmentRateModel>(context, listen: false).rate;
|
||||
|
||||
double l = double.tryParse(_lengthController.text) ?? 0;
|
||||
double w = double.tryParse(_widthController.text) ?? 0;
|
||||
double h = double.tryParse(_heightController.text) ?? 0;
|
||||
_cargoType.weight = double.tryParse(_actualWeightCtl.text) ?? 0;
|
||||
double l = double.tryParse(lengthController.text) ?? 0;
|
||||
double w = double.tryParse(widthController.text) ?? 0;
|
||||
double h = double.tryParse(heightController.text) ?? 0;
|
||||
_cargoType.weight = double.tryParse(actualWeightCtl.text) ?? 0;
|
||||
Carton box =
|
||||
Carton(cargoTypes: [_cargoType], length: l, width: w, height: h);
|
||||
var amount = box.calAmount(rate);
|
||||
@@ -83,15 +84,15 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
||||
List<CargoType> cargos = shipmentRateModel.rate.cargoTypes;
|
||||
|
||||
final lengthBox = LengthPicker(
|
||||
controller: _lengthController,
|
||||
controller: lengthController,
|
||||
lableKey: "box.length",
|
||||
);
|
||||
final widthBox = LengthPicker(
|
||||
controller: _widthController,
|
||||
controller: widthController,
|
||||
lableKey: "box.width",
|
||||
);
|
||||
final heightBox = LengthPicker(
|
||||
controller: _heightController,
|
||||
controller: heightController,
|
||||
lableKey: "box.height",
|
||||
);
|
||||
|
||||
@@ -102,9 +103,9 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: Icon(FontAwesome.arrow_circle_right, color: primaryColor),
|
||||
),
|
||||
SizedBox(child: lengthBox, width: 80),
|
||||
SizedBox(child: widthBox, width: 80),
|
||||
SizedBox(child: heightBox, width: 80),
|
||||
SizedBox(width: 80, child: lengthBox),
|
||||
SizedBox(width: 80, child: widthBox),
|
||||
SizedBox(width: 80, child: heightBox),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -115,7 +116,7 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
||||
);
|
||||
|
||||
final actualWeightBox = InputText(
|
||||
controller: _actualWeightCtl,
|
||||
controller: actualWeightCtl,
|
||||
labelTextKey: "box.actual_weight",
|
||||
iconData: MaterialCommunityIcons.weight,
|
||||
textInputType: TextInputType.numberWithOptions(decimal: true),
|
||||
@@ -129,13 +130,13 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
||||
});
|
||||
},
|
||||
labelKey: "cargo.type",
|
||||
iconData: Icons.text_format,
|
||||
iconData: Ionicons.text,
|
||||
selectedValue: _cargoType,
|
||||
values: cargos,
|
||||
);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
inAsyncCall: isLoading,
|
||||
child: Scaffold(
|
||||
appBar: LocalAppBar(
|
||||
labelKey: "rate.cal.title",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:fcs/domain/entities/rate.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
|
||||
@@ -5,13 +7,14 @@ import 'package:fcs/pages/widgets/input_text.dart';
|
||||
import 'package:fcs/pages/widgets/local_app_bar.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../main/util.dart';
|
||||
|
||||
class ShipmentRatesEdit extends StatefulWidget {
|
||||
ShipmentRatesEdit();
|
||||
const ShipmentRatesEdit({super.key});
|
||||
|
||||
@override
|
||||
_ShipmentRatesEditState createState() => _ShipmentRatesEditState();
|
||||
@@ -19,11 +22,11 @@ class ShipmentRatesEdit extends StatefulWidget {
|
||||
|
||||
class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
||||
bool _isLoading = false;
|
||||
TextEditingController _minWeight = new TextEditingController();
|
||||
TextEditingController _deliveryFee = new TextEditingController();
|
||||
TextEditingController _volumetricRatio = new TextEditingController();
|
||||
TextEditingController _diffDiscountWeight = new TextEditingController();
|
||||
TextEditingController _diffWeightRate = new TextEditingController();
|
||||
TextEditingController minWeight = TextEditingController();
|
||||
TextEditingController deliveryFee = TextEditingController();
|
||||
TextEditingController volumetricRatio = TextEditingController();
|
||||
TextEditingController diffDiscountWeight = TextEditingController();
|
||||
TextEditingController diffWeightRate = TextEditingController();
|
||||
|
||||
late Rate rate;
|
||||
|
||||
@@ -34,11 +37,11 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
rate = shipmentRateModel.rate;
|
||||
|
||||
_minWeight.text = rate.freeDeliveryWeight.toStringAsFixed(2);
|
||||
_deliveryFee.text = rate.deliveryFee.toStringAsFixed(2);
|
||||
_volumetricRatio.text = rate.volumetricRatio.toStringAsFixed(2);
|
||||
_diffDiscountWeight.text = rate.diffDiscountWeight.toStringAsFixed(2);
|
||||
_diffWeightRate.text = rate.diffWeightRate.toStringAsFixed(2);
|
||||
minWeight.text = rate.freeDeliveryWeight.toStringAsFixed(2);
|
||||
deliveryFee.text = rate.deliveryFee.toStringAsFixed(2);
|
||||
volumetricRatio.text = rate.volumetricRatio.toStringAsFixed(2);
|
||||
diffDiscountWeight.text = rate.diffDiscountWeight.toStringAsFixed(2);
|
||||
diffWeightRate.text = rate.diffWeightRate.toStringAsFixed(2);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -51,23 +54,27 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
||||
final minWigBox = InputText(
|
||||
labelTextKey: 'rate.min_weight',
|
||||
iconData: FontAwesomeIcons.weightHanging,
|
||||
controller: _minWeight);
|
||||
controller: minWeight);
|
||||
|
||||
final feeBox = InputText(
|
||||
labelTextKey: 'rate.delivery_fee',
|
||||
iconData: Icons.attach_money,
|
||||
controller: _deliveryFee);
|
||||
iconData: Fontisto.dollar,
|
||||
controller: deliveryFee);
|
||||
|
||||
final ratioBox = InputText(
|
||||
labelTextKey: 'rate.volumetric_ratio',
|
||||
iconData: FontAwesomeIcons.weightHanging,
|
||||
controller: _volumetricRatio);
|
||||
controller: volumetricRatio);
|
||||
|
||||
final diffDiscountWeightBox = InputText(
|
||||
labelTextKey: 'rate.diff_discount_weight',
|
||||
iconData: FontAwesomeIcons.weightHanging,
|
||||
controller: _diffDiscountWeight);
|
||||
controller: diffDiscountWeight);
|
||||
|
||||
final diffWeightRateBox = InputText(
|
||||
labelTextKey: 'rate.diff_weight_rate',
|
||||
iconData: Icons.attach_money,
|
||||
controller: _diffWeightRate);
|
||||
iconData: Fontisto.dollar,
|
||||
controller: diffWeightRate);
|
||||
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
@@ -105,7 +112,7 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
||||
),
|
||||
fcsButton(context, getLocalString(context, "btn.save"),
|
||||
callack: _save),
|
||||
SizedBox(height: 10)
|
||||
SizedBox(height: 30)
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -120,15 +127,14 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
||||
try {
|
||||
var shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
Rate _rate = new Rate(
|
||||
deliveryFee: double.parse(_deliveryFee.text),
|
||||
freeDeliveryWeight: double.parse(_minWeight.text),
|
||||
volumetricRatio: double.parse(_volumetricRatio.text),
|
||||
diffDiscountWeight: double.parse(_diffDiscountWeight.text),
|
||||
diffWeightRate: double.parse(_diffWeightRate.text));
|
||||
Rate r = new Rate();
|
||||
print('_rate =>$r');
|
||||
await shipmentRateModel.updateRate(_rate);
|
||||
Rate rate = Rate(
|
||||
deliveryFee: double.parse(deliveryFee.text),
|
||||
freeDeliveryWeight: double.parse(minWeight.text),
|
||||
volumetricRatio: double.parse(volumetricRatio.text),
|
||||
diffDiscountWeight: double.parse(diffDiscountWeight.text),
|
||||
diffWeightRate: double.parse(diffWeightRate.text));
|
||||
|
||||
await shipmentRateModel.updateRate(rate);
|
||||
Navigator.pop(context);
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
@@ -140,13 +146,13 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
||||
}
|
||||
|
||||
isDataChanged() {
|
||||
Rate _rate = new Rate(
|
||||
deliveryFee: double.parse(_deliveryFee.text),
|
||||
freeDeliveryWeight: double.parse(_minWeight.text),
|
||||
volumetricRatio: double.parse(_volumetricRatio.text),
|
||||
diffDiscountWeight: double.parse(_diffDiscountWeight.text),
|
||||
diffWeightRate: double.parse(_diffWeightRate.text),
|
||||
Rate rate = Rate(
|
||||
deliveryFee: double.parse(deliveryFee.text),
|
||||
freeDeliveryWeight: double.parse(minWeight.text),
|
||||
volumetricRatio: double.parse(volumetricRatio.text),
|
||||
diffDiscountWeight: double.parse(diffDiscountWeight.text),
|
||||
diffWeightRate: double.parse(diffWeightRate.text),
|
||||
);
|
||||
return rate.isChangedForEdit(_rate);
|
||||
return rate.isChangedForEdit(rate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,17 +7,16 @@ import 'package:intl/intl.dart';
|
||||
|
||||
import 'receiving_info.dart';
|
||||
|
||||
typedef CallbackPackageSelect(Package package);
|
||||
typedef CallbackPackageSelect = Function(Package package);
|
||||
|
||||
class ReceivingListRow extends StatelessWidget {
|
||||
final Package package;
|
||||
final CallbackPackageSelect? callbackPackageSelect;
|
||||
final double dotSize = 15.0;
|
||||
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
|
||||
final DateFormat dateFormat = DateFormat("dd MMM yyyy");
|
||||
|
||||
ReceivingListRow(
|
||||
{Key? key, required this.package, this.callbackPackageSelect})
|
||||
: super(key: key);
|
||||
{super.key, required this.package, this.callbackPackageSelect});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -38,29 +37,29 @@ class ReceivingListRow extends StatelessWidget {
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: new Padding(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 13.0),
|
||||
child: new Row(
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(MaterialCommunityIcons.inbox_arrow_down,
|
||||
color: primaryColor),
|
||||
new Expanded(
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 15),
|
||||
child: new Column(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
new Text(
|
||||
Text(
|
||||
package.id == null ? '' : package.trackingID!,
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.black),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
package.market == null ? '' : package.market!,
|
||||
style: new TextStyle(
|
||||
fontSize: 15.0, color: Colors.black),
|
||||
style: TextStyle(
|
||||
fontSize: 15.0, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -81,11 +80,11 @@ class ReceivingListRow extends StatelessWidget {
|
||||
fontWeight: FontWeight.bold)),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 5),
|
||||
child: new Text(
|
||||
child: Text(
|
||||
package.currentStatusDate != null
|
||||
? dateFormat.format(package.currentStatusDate!)
|
||||
: '',
|
||||
style: new TextStyle(fontSize: 14.0, color: Colors.grey),
|
||||
style: TextStyle(fontSize: 14.0, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -15,14 +15,13 @@ class LocalPopupMenuButton extends StatefulWidget {
|
||||
final Color buttonColor;
|
||||
|
||||
const LocalPopupMenuButton(
|
||||
{Key? key,
|
||||
{super.key,
|
||||
this.popupMenuCallback,
|
||||
this.popmenus,
|
||||
this.buttonIcon,
|
||||
this.selectable = true,
|
||||
this.multiSelect = false,
|
||||
this.buttonColor = primaryColor})
|
||||
: super(key: key);
|
||||
this.buttonColor = primaryColor});
|
||||
|
||||
@override
|
||||
_LocalPopupMenuButtonState createState() => _LocalPopupMenuButtonState();
|
||||
@@ -46,30 +45,32 @@ class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
|
||||
if (widget.selectable) {
|
||||
if (!widget.multiSelect) {
|
||||
setState(() {
|
||||
popmenus.forEach((e) {
|
||||
if (e.id != selected.id)
|
||||
for (var e in popmenus) {
|
||||
if (e.id != selected.id) {
|
||||
e.selected = false;
|
||||
else
|
||||
} else {
|
||||
e.selected = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
selected.selected = true;
|
||||
} else {
|
||||
setState(() {
|
||||
popmenus.forEach((e) {
|
||||
for (var e in popmenus) {
|
||||
if (e.id == selected.id) e.selected = !e.selected;
|
||||
});
|
||||
}
|
||||
});
|
||||
selected.selected = !selected.selected;
|
||||
}
|
||||
}
|
||||
if (selected.enabled && widget.popupMenuCallback != null)
|
||||
if (selected.enabled && widget.popupMenuCallback != null) {
|
||||
widget.popupMenuCallback!(selected);
|
||||
}
|
||||
},
|
||||
icon: Container(
|
||||
width: 30,
|
||||
height: 30,
|
||||
decoration: new BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
//color: Colors.white,
|
||||
),
|
||||
@@ -87,7 +88,7 @@ class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
|
||||
child: Container(
|
||||
width: 10,
|
||||
height: 10,
|
||||
decoration: new BoxDecoration(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: secondaryColor,
|
||||
),
|
||||
@@ -109,7 +110,7 @@ class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
|
||||
color:
|
||||
choice.enabled ? Colors.black : Colors.grey))
|
||||
: LocalText(context, choice.textKey ?? "",
|
||||
color: choice.enabled ? Colors.black : Colors.grey,
|
||||
color: choice.enabled ? Colors.black : Colors.grey,
|
||||
fontSize: 14),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
@@ -128,9 +129,9 @@ class _LocalPopupMenuButtonState extends State<LocalPopupMenuButton> {
|
||||
}
|
||||
|
||||
bool _needHighlight() {
|
||||
popmenus.forEach((e) {
|
||||
if (e.selected && e.highlight) return;
|
||||
});
|
||||
for (var e in popmenus) {
|
||||
if (e.selected && e.highlight) continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user