Files
fcs/lib/pages/carton/carton_info.dart

655 lines
23 KiB
Dart
Raw Normal View History

2025-03-12 17:49:27 +06:30
// ignore_for_file: use_build_context_synchronously
2024-09-22 16:49:59 +06:30
import 'package:fcs/constants.dart';
2024-02-05 17:28:53 +06:30
import 'package:fcs/domain/entities/cargo_type.dart';
2020-10-20 06:19:10 +06:30
import 'package:fcs/domain/entities/carton.dart';
2020-10-14 16:53:16 +06:30
import 'package:fcs/domain/entities/package.dart';
import 'package:fcs/helpers/theme.dart';
2024-02-09 13:49:18 +06:30
import 'package:fcs/pages/carton/carton_image_upload_editor.dart';
2020-10-14 16:53:16 +06:30
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/package/model/package_model.dart';
import 'package:fcs/pages/widgets/display_text.dart';
2024-01-25 17:40:35 +06:30
import 'package:fcs/pages/widgets/local_app_bar.dart';
2020-10-14 16:53:16 +06:30
import 'package:fcs/pages/widgets/local_text.dart';
2024-02-05 17:28:53 +06:30
import 'package:fcs/pages/widgets/multi_img_controller.dart';
import 'package:fcs/pages/widgets/multi_img_file.dart';
2020-10-14 16:53:16 +06:30
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
2021-09-10 12:00:08 +06:30
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
2020-10-14 16:53:16 +06:30
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
2024-02-09 17:40:51 +06:30
import '../../domain/entities/carton_size.dart';
2025-03-07 17:41:09 +06:30
import '../../domain/entities/fcs_shipment.dart';
import '../carton_size/model/carton_size_model.dart';
2025-03-07 17:41:09 +06:30
import '../fcs_shipment/model/fcs_shipment_model.dart';
2024-02-09 13:35:32 +06:30
import '../widgets/local_button.dart';
2024-02-09 13:49:18 +06:30
import 'carton_package_editor.dart';
2024-02-09 13:35:32 +06:30
import 'mix_carton/mix_carton_editor.dart';
2025-03-12 17:49:27 +06:30
import 'mix_carton_detail_list.dart';
2020-10-18 02:38:46 +06:30
import 'model/carton_model.dart';
2025-03-12 17:49:27 +06:30
import 'package_detail_list.dart';
2024-02-26 17:26:25 +06:30
import 'print_qr_code_page.dart';
2020-10-14 16:53:16 +06:30
2020-10-19 05:13:49 +06:30
class CartonInfo extends StatefulWidget {
2024-02-09 13:35:32 +06:30
final Carton carton;
2025-03-12 17:49:27 +06:30
const CartonInfo({super.key, required this.carton});
2020-10-14 16:53:16 +06:30
@override
2020-10-19 05:13:49 +06:30
_CartonInfoState createState() => _CartonInfoState();
2020-10-14 16:53:16 +06:30
}
2020-10-19 05:13:49 +06:30
class _CartonInfoState extends State<CartonInfo> {
2025-03-07 17:41:09 +06:30
var dateFormatter = DateFormat('dd MMM yyyy');
2024-02-09 13:35:32 +06:30
final NumberFormat numberFormatter = NumberFormat("#,###");
2025-03-07 17:41:09 +06:30
MultiImgController multiImgController = MultiImgController();
2024-02-09 13:35:32 +06:30
bool _isLoading = false;
late Carton _carton;
List<CargoType> _cargoTypes = [];
List<CargoType> _surchareItems = [];
List<Carton> _mixCartons = [];
List<Package> _packages = [];
2024-02-09 17:40:51 +06:30
double totalWeight = 0.0;
double totalSurchargeCount = 0.0;
CartonSize? standardSize;
2025-03-07 17:41:09 +06:30
FcsShipment? _shipment;
2024-02-08 17:09:01 +06:30
2020-10-14 16:53:16 +06:30
@override
void initState() {
2024-02-09 13:35:32 +06:30
_carton = widget.carton;
_init();
2020-10-14 16:53:16 +06:30
super.initState();
}
2024-02-09 13:35:32 +06:30
_init() async {
2024-02-13 11:02:46 +06:30
try {
_isLoading = true;
2025-03-07 17:41:09 +06:30
multiImgController.setImageUrls = _carton.photoUrls;
_cargoTypes = _carton.cargoTypes;
_surchareItems = _carton.surchareItems;
// check carton size type
List<CartonSize> cartonSizes =
context.read<CartonSizeModel>().cartonSizes;
var sameLength = cartonSizes.any((size) => size.length == _carton.length);
var sameWidth = cartonSizes.any((size) => size.width == _carton.width);
var sameHeight = cartonSizes.any((size) => size.height == _carton.height);
bool isStandartSize = sameLength && sameWidth && sameHeight;
if (isStandartSize) {
_carton.cartonSizeType = standardCarton;
standardSize = cartonSizes.firstWhere((size) =>
size.length == _carton.length &&
size.width == _carton.width &&
size.height == _carton.height);
} else if (_carton.length == 0 &&
_carton.width == 0 &&
_carton.height == 0) {
_carton.cartonSizeType = packageCarton;
} else {
_carton.cartonSizeType = customCarton;
}
2025-03-07 17:41:09 +06:30
if (widget.carton.fcsShipmentID != null &&
widget.carton.fcsShipmentID != '') {
var s = await context
.read<FcsShipmentModel>()
.getFcsShipment(widget.carton.fcsShipmentID!);
_shipment = s;
}
2024-02-13 11:02:46 +06:30
if (_carton.cartonType == carton_from_packages) {
_packages = await context
.read<PackageModel>()
.getPackagesByIds(_carton.packageIDs);
}
2021-01-10 15:56:27 +06:30
if (_carton.cartonType == mix_carton) {
2024-02-13 11:02:46 +06:30
_mixCartons = await context
.read<CartonModel>()
.getCartonsByIds(_carton.cartonIDs);
2024-10-01 18:15:53 +06:30
_cargoTypes.sort((a, b) => a.name!.compareTo(b.name!));
_surchareItems.sort((a, b) => a.name!.compareTo(b.name!));
2024-02-13 11:02:46 +06:30
}
2024-02-13 11:02:46 +06:30
totalWeight =
_carton.cargoTypes.fold(0, (sum, value) => sum + value.weight);
totalSurchargeCount =
_surchareItems.fold(0, (sum, value) => sum + value.qty);
} finally {
_isLoading = false;
2024-02-09 13:35:32 +06:30
}
if (mounted) {
setState(() {});
}
2020-10-14 16:53:16 +06:30
}
@override
Widget build(BuildContext context) {
var fromPackage = _carton.cartonType == carton_from_packages;
String? boxDimension = _carton.cartonSizeType == standardCarton
2024-02-09 17:40:51 +06:30
? "${standardSize?.name} - ${standardSize?.length.toInt()}”x${standardSize?.width.toInt()}”x${standardSize?.height.toInt()}"
: _carton.cartonSizeType == customCarton
? "${_carton.length.toInt()}”x${_carton.width.toInt()}”x${_carton.height.toInt()}"
: null;
2024-02-26 17:26:25 +06:30
final cartonQrBox = IconButton(
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => PrintQrCodePage(carton: _carton)),
);
},
2025-03-07 17:41:09 +06:30
icon: Icon(AntDesign.qrcode, color: primaryColor));
2024-02-26 17:26:25 +06:30
final cartonTypeBox = DisplayText(
2024-02-09 17:40:51 +06:30
text: _carton.cartonType == carton_from_packages
2024-09-23 18:37:21 +06:30
? "For packages"
: _carton.cartonType == mix_carton
? carton_mix_carton
: '',
2024-02-09 17:09:05 +06:30
labelTextKey: "box.carton.type",
);
2024-02-09 13:35:32 +06:30
2024-09-23 18:37:21 +06:30
final billInfoBox = DisplayText(
text: _carton.billTo == billToSender
? "Sender"
: _carton.billTo == billToConsignee
? "Consignee"
: null,
labelTextKey: "box.bill_to",
);
final lastMileBox = DisplayText(
2024-10-01 18:15:53 +06:30
text: _carton.lastMile == delivery_caton
? 'Delivery'
: _carton.lastMile == pickup_carton
? 'Pick-up'
: '',
labelTextKey: "box.delivery_type",
2020-10-14 16:53:16 +06:30
);
2024-09-23 18:37:21 +06:30
final cartonSizeBox = DisplayText(
2025-03-07 17:41:09 +06:30
subText: Text(boxDimension ?? 'No defined size'),
2024-10-01 18:15:53 +06:30
labelTextKey: "box.select_carton_size",
2024-09-23 18:37:21 +06:30
);
2025-03-07 17:41:09 +06:30
final packageLengthBox = DisplayText(
showLabelLink: true,
subText: Text(numberFormatter.format(_packages.length)),
labelTextKey: "box.package",
2025-03-12 17:49:27 +06:30
onTapLabel: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => PackageDetailList(
cartonNumber: _carton.cartonNumber ?? '',
packages: _packages)));
},
2020-10-14 16:53:16 +06:30
);
2025-03-07 17:41:09 +06:30
final mixCartonLengthBox = DisplayText(
showLabelLink: true,
subText: Text(numberFormatter.format(_mixCartons.length)),
labelTextKey: "box.shipment.boxes",
2025-03-12 17:49:27 +06:30
onTapLabel: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => MixCartonDetailList(
cartonNumber: _carton.cartonNumber ?? '',
cartons: _mixCartons)));
},
2020-10-14 16:53:16 +06:30
);
2025-03-07 17:41:09 +06:30
final senderBox = userDisplayBox(context,
lableKey: "box.sender.title",
name: _carton.senderName,
fcsID: _carton.senderFCSID);
final consigneeNameBox = userDisplayBox(context,
lableKey: "box.consignee.title",
name: _carton.consigneeName,
fcsID: _carton.consigneeFCSID);
2024-09-23 18:37:21 +06:30
// final billWidget = Expanded(
// child: Padding(
// padding: EdgeInsets.only(left: 0, top: 15),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// Icon(Ionicons.document_text_outline,
// color: primaryColor, size: 20),
// Text("Bill to",
// style: TextStyle(color: primaryColor, fontSize: 15))
// ],
// )));
2024-02-09 13:35:32 +06:30
final userRowBox = Row(
mainAxisAlignment: MainAxisAlignment.start,
2024-10-01 18:15:53 +06:30
crossAxisAlignment: CrossAxisAlignment.start,
2024-02-09 13:35:32 +06:30
children: [
2025-03-07 17:41:09 +06:30
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
consigneeNameBox,
],
),
),
// _carton.billTo == billToConsignee ? billWidget : const SizedBox()
],
)),
2024-02-09 13:35:32 +06:30
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
senderBox,
],
),
),
2024-09-23 18:37:21 +06:30
// _carton.billTo == billToSender ? billWidget : const SizedBox()
2024-02-09 13:35:32 +06:30
],
),
),
],
2024-02-09 12:16:18 +06:30
);
2024-02-09 13:35:32 +06:30
final cargosBox = Padding(
2024-10-01 18:15:53 +06:30
padding: const EdgeInsets.only(top: 20),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LocalText(context, 'box.cargo.type',
color: Colors.black54,
fontSize: 16,
fontWeight: FontWeight.normal),
2024-10-01 18:15:53 +06:30
_cargoTypes.isNotEmpty
? Padding(
2025-03-07 17:41:09 +06:30
padding: EdgeInsets.only(right: 0),
2024-10-01 18:15:53 +06:30
child: Text("${removeTrailingZeros(totalWeight)} lb",
textAlign: TextAlign.end,
style: TextStyle(color: Colors.black54, fontSize: 15)))
: const SizedBox()
],
),
2025-03-07 17:41:09 +06:30
Padding(
padding: const EdgeInsets.only(right: 0),
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _cargoTypes.asMap().entries.map((e) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: Container(
color: e.key.isEven ? Colors.grey.shade300 : oddColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
e.value.name ?? "",
style: TextStyle(
color: Colors.black, fontSize: 15),
),
Text(
"${removeTrailingZeros(e.value.weight)} lb",
textAlign: TextAlign.end,
style: TextStyle(
color: Colors.black, fontSize: 15))
],
),
e.value.isMixCargo
? Padding(
padding: const EdgeInsets.only(left: 20),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: e.value.mixCargoes.map((c) {
return Padding(
padding: const EdgeInsets.symmetric(
vertical: 2),
child: Text(
"- ${c.name}",
style: TextStyle(fontSize: 14),
),
);
}).toList()),
)
: const SizedBox()
],
),
2025-03-07 17:41:09 +06:30
),
);
}).toList()),
],
),
),
]),
);
2024-10-01 18:15:53 +06:30
2025-03-07 17:41:09 +06:30
final surchargeItemBox = Padding(
padding: const EdgeInsets.only(top: 16),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
LocalText(context, 'box.input_surcharge_item',
color: Colors.black54, fontSize: 16, fontWeight: FontWeight.normal),
Padding(
padding: const EdgeInsets.only(right: 0),
2024-10-01 18:15:53 +06:30
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
2025-03-07 17:41:09 +06:30
children: _surchareItems.asMap().entries.map((e) {
2024-10-01 18:15:53 +06:30
return Padding(
2025-03-07 17:41:09 +06:30
padding: const EdgeInsets.symmetric(vertical: 2),
child: Container(
2025-03-12 17:49:27 +06:30
color: e.key.isEven ? Colors.grey.shade300 : oddColor,
2025-03-07 17:41:09 +06:30
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
e.value.name ?? "",
2025-03-12 17:49:27 +06:30
style:
TextStyle(color: Colors.black, fontSize: 15),
2025-03-07 17:41:09 +06:30
),
2025-03-12 17:49:27 +06:30
Text(
"${removeTrailingZeros((e.value.qty).toDouble())} pc",
2025-03-07 17:41:09 +06:30
textAlign: TextAlign.end,
2025-03-12 17:49:27 +06:30
style: TextStyle(
color: Colors.black, fontSize: 15))
2025-03-07 17:41:09 +06:30
],
),
2024-10-01 18:15:53 +06:30
),
);
}).toList()),
],
),
),
2025-03-07 17:41:09 +06:30
]),
);
final img = MultiImageFile(
2024-02-05 17:28:53 +06:30
enabled: false,
2025-03-07 17:41:09 +06:30
controller: multiImgController,
2024-02-05 17:28:53 +06:30
title: "Receipt File",
);
2024-02-09 12:21:49 +06:30
2024-02-09 13:35:32 +06:30
final uploadImageBtn = Padding(
padding: EdgeInsets.only(left: 200.0, right: 8.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xff272262),
elevation: 3,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0)),
minimumSize: Size(10, 35),
),
onPressed: () async {
bool? updated = await Navigator.push(
context,
CupertinoPageRoute(
builder: (context) =>
CartonImageUploadEditor(carton: _carton)),
);
if (updated ?? false) {
Carton? c = await context
.read<CartonModel>()
.getCarton(widget.carton.id ?? "");
if (c == null) return;
_carton = c;
_init();
}
},
child: LocalText(context, "box.imageupload.title",
color: Colors.white, fontSize: 14)),
2024-02-09 13:35:32 +06:30
);
2024-02-26 17:26:25 +06:30
final deleteBtn = Padding(
2024-02-09 13:35:32 +06:30
padding: const EdgeInsets.symmetric(horizontal: 30),
child: LocalButton(
color: dangerColor,
textKey: "box.delete.btn",
callBack: () {
_delete();
},
),
);
2020-12-11 17:34:56 +06:30
2025-03-07 17:41:09 +06:30
final shipmentBox = Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LocalText(context, "package.shipment.title",
fontSize: 15, color: Colors.black54),
const SizedBox(height: 5),
Container(
decoration: BoxDecoration(
border: Border.all(color: dividerColor),
borderRadius: BorderRadius.circular(5),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Column(
children: [
DisplayText(
text: _shipment?.shipmentNumber,
labelTextKey: "FCSshipment.number",
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: DisplayText(
text: _shipment != null
? _shipment!.cutoffDate != null
? dateFormatter.format(_shipment!.cutoffDate!)
: ""
: "",
labelTextKey: "FCSshipment.cutoff_date",
)),
Flexible(
child: DisplayText(
text: _shipment != null
? _shipment!.etaDate != null
? dateFormatter.format(_shipment!.etaDate!)
: ""
: "",
labelTextKey: "FCSshipment.ETA",
)),
],
)
],
),
),
)
],
),
);
2020-10-14 16:53:16 +06:30
return LocalProgress(
inAsyncCall: _isLoading,
child: Scaffold(
appBar: LocalAppBar(
2025-03-07 17:41:09 +06:30
titleWidget: Column(
children: [
LocalText(context, "box.info.title",
fontSize: 20, color: primaryColor),
Text(_carton.cartonNumber ?? '',
style: TextStyle(fontSize: 15, color: Colors.black))
],
),
2024-02-09 12:21:49 +06:30
backgroundColor: Colors.white,
labelColor: primaryColor,
arrowColor: primaryColor,
actions: <Widget>[
2025-03-07 17:41:09 +06:30
cartonQrBox,
2025-02-17 20:13:30 +06:30
_carton.status == carton_packed_status
? IconButton(
icon: Icon(Icons.edit, color: primaryColor),
onPressed: _gotoEditor)
: const SizedBox(),
2024-02-09 12:21:49 +06:30
]),
body: Container(
padding: const EdgeInsets.only(left: 20, right: 20),
child: ListView(children: <Widget>[
2024-02-09 17:40:51 +06:30
Row(
children: [
Flexible(child: cartonTypeBox),
2024-02-09 17:40:51 +06:30
],
),
fromPackage ? userRowBox : const SizedBox(),
2025-03-07 17:41:09 +06:30
fromPackage
? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(child: billInfoBox),
Flexible(child: lastMileBox),
],
)
: const SizedBox(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
2024-09-23 18:37:21 +06:30
Flexible(child: cartonSizeBox),
2025-03-12 17:49:27 +06:30
_packages.isEmpty
? const SizedBox()
: Flexible(child: packageLengthBox),
],
),
2025-03-12 17:49:27 +06:30
fromPackage
? const SizedBox()
: _mixCartons.isEmpty
? const SizedBox()
: mixCartonLengthBox,
2025-03-07 17:41:09 +06:30
shipmentBox,
// _packages.isEmpty
// ? const SizedBox()
// : Padding(
// padding: const EdgeInsets.only(top: 15),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// LocalText(context, "box.package",
// color: Colors.black54, fontSize: 15),
// const SizedBox(height: 5),
// Column(
// children: getPackageList(_packages),
// ),
// ],
// ),
// ),
// _mixCartons.isEmpty
// ? const SizedBox()
// : Padding(
// padding: const EdgeInsets.only(top: 15),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// LocalText(context, "box.shipment.boxes",
// color: Colors.black54, fontSize: 15),
// const SizedBox(height: 5),
// Column(children: getCartonList(_mixCartons)),
// ],
// ),
// ),
2024-10-01 18:15:53 +06:30
cargosBox,
2025-03-07 17:41:09 +06:30
_surchareItems.isNotEmpty
? surchargeItemBox
: const SizedBox(),
2024-10-01 18:15:53 +06:30
const SizedBox(height: 10),
2024-02-09 13:35:32 +06:30
uploadImageBtn,
2024-10-01 18:15:53 +06:30
_carton.photoUrls.isNotEmpty
? const SizedBox(height: 10)
: const SizedBox(),
img,
_carton.photoUrls.isNotEmpty
? const SizedBox(height: 40)
: const SizedBox(),
2025-02-17 20:13:30 +06:30
_carton.status == carton_packed_status
? deleteBtn
: const SizedBox(),
const SizedBox(height: 20)
]))));
2024-02-06 17:42:12 +06:30
}
2020-12-11 17:34:56 +06:30
2024-02-09 13:35:32 +06:30
List<Widget> getPackageList(List<Package> list) {
return list.map((p) {
return Container(
padding: EdgeInsets.only(top: 0),
2025-03-12 17:49:27 +06:30
child: Row(children: <Widget>[Text(p.trackingID ?? "")]));
2024-02-09 13:35:32 +06:30
}).toList();
}
List<Widget> getCartonList(List<Carton> list) {
return list.map((c) {
return Container(
padding: EdgeInsets.only(top: 0),
2025-03-12 17:49:27 +06:30
child: Row(children: <Widget>[Text(c.cartonNumber ?? '')]));
2024-02-09 13:35:32 +06:30
}).toList();
}
2020-10-14 16:53:16 +06:30
_gotoEditor() async {
bool? updated = false;
if (_carton.cartonType == mix_carton) {
updated = await Navigator.push<bool>(
context,
CupertinoPageRoute(
builder: (context) => MixCartonEditor(carton: _carton)),
);
}
if (_carton.cartonType == carton_from_packages) {
updated = await Navigator.push<bool>(
context,
CupertinoPageRoute(
builder: (context) => CartonPackageEditor(carton: _carton)),
);
}
2024-02-09 13:49:18 +06:30
if (updated ?? false) {
Carton? c =
await context.read<CartonModel>().getCarton(widget.carton.id ?? "");
if (c == null) return;
_carton = c;
_init();
2020-10-20 06:19:10 +06:30
}
}
2024-02-26 17:26:25 +06:30
_delete() {
2020-10-20 06:19:10 +06:30
showConfirmDialog(context, "box.delete.confirm", () {
_deleteCarton();
});
}
_deleteCarton() async {
setState(() {
_isLoading = true;
});
try {
await context.read<CartonModel>().deleteCarton(widget.carton);
Navigator.pop(context, true);
2020-10-20 06:19:10 +06:30
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
2020-10-14 16:53:16 +06:30
}
}