import 'package:fcs/constants.dart'; import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/carton/carton_image_upload_editor.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/package/model/package_model.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/multi_img_controller.dart'; import 'package:fcs/pages/widgets/multi_img_file.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import '../../domain/entities/carton_size.dart'; import '../carton_size/model/carton_size_model.dart'; import '../widgets/local_button.dart'; import 'carton_package_editor.dart'; import 'mix_carton/mix_carton_editor.dart'; import 'model/carton_model.dart'; import 'print_qr_code_page.dart'; class CartonInfo extends StatefulWidget { final Carton carton; CartonInfo({required this.carton}); @override _CartonInfoState createState() => _CartonInfoState(); } class _CartonInfoState extends State { final DateFormat dateFormat = DateFormat("d MMM yyyy"); final NumberFormat numberFormatter = NumberFormat("#,###"); MultiImgController _multiImgController = MultiImgController(); bool _isLoading = false; late Carton _carton; List _cargoTypes = []; List _surchareItems = []; List _mixCartons = []; List _packages = []; double totalWeight = 0.0; double totalSurchargeCount = 0.0; CartonSize? standardSize; @override void initState() { _carton = widget.carton; _init(); super.initState(); } _init() async { try { _isLoading = true; _multiImgController.setImageUrls = _carton.photoUrls; _cargoTypes = _carton.cargoTypes; _surchareItems = _carton.surchareItems; // check carton size type List cartonSizes = context.read().cartonSizes; var sameLength = cartonSizes.any((size) => size.length == _carton.length); var sameWidth = cartonSizes.any((size) => size.width == _carton.width); var sameHeight = cartonSizes.any((size) => size.height == _carton.height); bool isStandartSize = sameLength && sameWidth && sameHeight; if (isStandartSize) { _carton.cartonSizeType = standardCarton; standardSize = cartonSizes.firstWhere((size) => size.length == _carton.length && size.width == _carton.width && size.height == _carton.height); } else if (_carton.length == 0 && _carton.width == 0 && _carton.height == 0) { _carton.cartonSizeType = packageCarton; } else { _carton.cartonSizeType = customCarton; } if (_carton.cartonType == carton_from_packages) { _packages = await context .read() .getPackagesByIds(_carton.packageIDs); } if (_carton.cartonType == mix_carton) { _mixCartons = await context .read() .getCartonsByIds(_carton.cartonIDs); _cargoTypes.sort((a, b) => a.name!.compareTo(b.name!)); _surchareItems.sort((a, b) => a.name!.compareTo(b.name!)); } totalWeight = _carton.cargoTypes.fold(0, (sum, value) => sum + value.weight); totalSurchargeCount = _surchareItems.fold(0, (sum, value) => sum + value.qty); } finally { _isLoading = false; } if (mounted) { setState(() {}); } } @override Widget build(BuildContext context) { var fromPackage = _carton.cartonType == carton_from_packages; String? boxDimension = _carton.cartonSizeType == standardCarton ? "${standardSize?.name} - ${standardSize?.length.toInt()}”x${standardSize?.width.toInt()}”x${standardSize?.height.toInt()}”" : _carton.cartonSizeType == customCarton ? "${_carton.length.toInt()}”x${_carton.width.toInt()}”x${_carton.height.toInt()}”" : null; final cartonNumberBox = DisplayText( text: _carton.cartonNumber, labelTextKey: "box.number", ); final cartonQrBox = IconButton( onPressed: () { Navigator.push( context, CupertinoPageRoute( builder: (context) => PrintQrCodePage(carton: _carton)), ); }, icon: Icon(AntDesign.qrcode, color: Colors.black)); final cartonTypeBox = DisplayText( text: _carton.cartonType == carton_from_packages ? "For packages" : _carton.cartonType == mix_carton ? carton_mix_carton : '', labelTextKey: "box.carton.type", ); final billInfoBox = DisplayText( text: _carton.billTo == billToSender ? "Sender" : _carton.billTo == billToConsignee ? "Consignee" : null, labelTextKey: "box.bill_to", ); final shipmentBox = DisplayText( text: _carton.fcsShipmentNumber, labelTextKey: "box.fcs_shipment_num", ); final lastMileBox = DisplayText( text: _carton.lastMile == delivery_caton ? 'Delivery' : _carton.lastMile == pickup_carton ? 'Pick-up' : '', labelTextKey: "box.delivery_type", ); final cartonSizeBox = DisplayText( subText: Text("${boxDimension ?? 'No defined size'}"), labelTextKey: "box.select_carton_size", ); final senderBox = DisplayText( text: _carton.senderName == null ? "" : _carton.senderName, subText: Text(_carton.senderFCSID ?? "", style: textStyle), labelTextKey: "box.name", ); final consigneeNameBox = DisplayText( text: _carton.consigneeName != null ? _carton.consigneeName : "", subText: Text(_carton.consigneeFCSID ?? "", style: textStyle), labelTextKey: "processing.consignee.name", ); // 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)) // ], // ))); final userRowBox = Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ senderBox, ], ), ), // _carton.billTo == billToSender ? billWidget : const SizedBox() ], ), ), Expanded( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ consigneeNameBox, ], ), ), // _carton.billTo == billToConsignee ? billWidget : const SizedBox() ], )) ], ); final cargosBox = Padding( 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), _cargoTypes.isNotEmpty ? Padding( padding: EdgeInsets.only(right: 50), child: Text("${removeTrailingZeros(totalWeight)} lb", textAlign: TextAlign.end, style: TextStyle(color: Colors.black54, fontSize: 15))) : const SizedBox() ], ), Container( child: Padding( padding: const EdgeInsets.only(right: 50), child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: _cargoTypes.map((e) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( e.name ?? "", style: TextStyle(color: Colors.black, fontSize: 15), ), Text("${removeTrailingZeros(e.weight)} lb", textAlign: TextAlign.end, style: TextStyle( color: Colors.black, fontSize: 15)) ], ), ); }).toList()), ], ), ), ), ]), ); final surchargeItemBox = Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Padding( padding: const EdgeInsets.only(right: 50), child: Column( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: _surchareItems.map((e) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( e.name ?? "", style: TextStyle(color: Colors.black, fontSize: 15), ), Text("${removeTrailingZeros((e.qty).toDouble())} pc", textAlign: TextAlign.end, style: TextStyle(color: Colors.black, fontSize: 15)) ], ), ); }).toList()), ], ), ), ), ]); final img = MultiImageFile( enabled: false, controller: _multiImgController, title: "Receipt File", ); 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() .getCarton(widget.carton.id ?? ""); if (c == null) return; _carton = c; _init(); } }, child: LocalText(context, "box.imageupload.title", color: Colors.white, fontSize: 14)), ); final deleteBtn = Padding( padding: const EdgeInsets.symmetric(horizontal: 30), child: LocalButton( color: dangerColor, textKey: "box.delete.btn", callBack: () { _delete(); }, ), ); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: LocalAppBar( labelKey: "box.info.title", backgroundColor: Colors.white, labelColor: primaryColor, arrowColor: primaryColor, actions: [ _carton.status == carton_packed_status ? IconButton( icon: Icon(Icons.edit, color: primaryColor), onPressed: _gotoEditor) : const SizedBox(), ]), body: Container( padding: const EdgeInsets.only(left: 20, right: 20), child: ListView(children: [ Row(children: [ Flexible(child: cartonNumberBox, flex: 1), Flexible( child: cartonQrBox, ), ]), Row( children: [ Flexible(child: cartonTypeBox), ], ), fromPackage ? userRowBox : const SizedBox(), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ fromPackage ? Flexible(child: billInfoBox) : SizedBox(), Flexible(child: shipmentBox), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ fromPackage ? Flexible(child: lastMileBox) : const SizedBox(), Flexible(child: cartonSizeBox), ], ), _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)), ], ), ), cargosBox, surchargeItemBox, const SizedBox(height: 10), uploadImageBtn, _carton.photoUrls.isNotEmpty ? const SizedBox(height: 10) : const SizedBox(), img, _carton.photoUrls.isNotEmpty ? const SizedBox(height: 40) : const SizedBox(), _carton.status == carton_packed_status ? deleteBtn : const SizedBox(), const SizedBox(height: 20) ])))); } List getPackageList(List list) { return list.map((p) { return Container( padding: EdgeInsets.only(top: 0), child: Container( child: Row(children: [new Text(p.trackingID ?? "")]), )); }).toList(); } List getCartonList(List list) { return list.map((c) { return Container( padding: EdgeInsets.only(top: 0), child: Container( child: Row(children: [new Text(c.cartonNumber ?? '')]), )); }).toList(); } _gotoEditor() async { bool? updated = false; if (_carton.cartonType == mix_carton) { updated = await Navigator.push( context, CupertinoPageRoute( builder: (context) => MixCartonEditor(carton: _carton)), ); } if (_carton.cartonType == carton_from_packages) { updated = await Navigator.push( context, CupertinoPageRoute( builder: (context) => CartonPackageEditor(carton: _carton)), ); } if (updated ?? false) { Carton? c = await context.read().getCarton(widget.carton.id ?? ""); if (c == null) return; _carton = c; _init(); } } _delete() { showConfirmDialog(context, "box.delete.confirm", () { _deleteCarton(); }); } _deleteCarton() async { setState(() { _isLoading = true; }); try { await context.read().deleteCarton(widget.carton); Navigator.pop(context, true); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } }