update carton and cargo type

This commit is contained in:
tzw
2025-03-12 17:49:27 +06:30
parent 05e912ea68
commit e208734dfa
32 changed files with 1141 additions and 462 deletions

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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"),
];

View File

@@ -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();
}

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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),

View 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),
)
],
),
],
),
),
);
},
));
}
}

View File

@@ -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;
}
}

View 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),
),
),
],
),
),
),
],
),
),
),
],
),
],
),
),
);
},
));
}
}

View 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()
],
),
),
);
}
}

View File

@@ -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();
}),
);
}
}

View File

@@ -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),
),
)

View File

@@ -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));

View File

@@ -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();
}),
);
}
}

View File

@@ -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),
),
),
],

View File

@@ -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),
),
),
],

View File

@@ -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;
});
}
}

View File

@@ -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);
}
}
}

View File

@@ -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),
),
],

View File

@@ -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);
}
}
}

View File

@@ -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),
),
)

View File

@@ -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),
),
),

View File

@@ -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);
}
}
}

View File

@@ -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",

View File

@@ -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);
}
}

View File

@@ -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),
),
),
],

View File

@@ -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;
}
}