add submit widget for mix carton

This commit is contained in:
tzw
2024-02-05 11:13:12 +06:30
parent 16ad71f257
commit ea206bed13
16 changed files with 1089 additions and 104 deletions

View File

@@ -326,6 +326,9 @@
"box.package_size":"Package",
"box.select.cartion":"Select cartons",
"box.no_carton":"There is no cartons in this shipment.",
"box.crete.carton":"Create carton",
"box.carton.type":"Carton Type",
"box.select.delivery":"Select delivery type",
"Boxes End ================================================================":"",
"Delivery Start ================================================================":"",

View File

@@ -325,6 +325,9 @@
"box.package_size":"Package",
"box.select.cartion":"Select cartons",
"box.no_carton":"There is no cartons in this shipment.",
"box.crete.carton":"Create carton",
"box.carton.type":"Carton Type",
"box.select.delivery":"Select delivery type",
"Boxes End ================================================================":"",
"Delivery Start ================================================================":"",

View File

@@ -5,7 +5,7 @@ class CargoType {
double weight;
bool isChecked;
int qty;
bool? isCutomDuty;
bool isCutomDuty;
double customDutyFee;
double calRate;
double calWeight;
@@ -21,7 +21,7 @@ class CargoType {
this.calRate = 0,
this.isChecked = false,
this.qty = 0,
this.isCutomDuty,
this.isCutomDuty = false,
this.customDutyFee = 0});
factory CargoType.fromMap(Map<String, dynamic> map, String id) {

View File

@@ -14,7 +14,9 @@ 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 'mix_cation/mix_cartion_editor.dart';
import '../main/util.dart';
import 'carton_editor_for_package.dart';
import 'mix_carton/mix_carton_editor.dart';
import 'carton_row.dart';
class CartonEditor extends StatefulWidget {
@@ -26,7 +28,7 @@ class CartonEditor extends StatefulWidget {
}
class _CartonEditorState extends State<CartonEditor> {
List<String> cartonTypes = [carton_from_packages, carton_mix_carton];
List<String> _cartonTypes = [carton_from_packages, carton_mix_carton];
List<Carton> _cartons = [];
bool _isLoading = false;
@@ -34,23 +36,26 @@ class _CartonEditorState extends State<CartonEditor> {
int _billToValue = 1;
String? _selectedCartonType;
User? consignee;
User? sender;
User? _consignee;
User? _sender;
Carton? _carton;
@override
void initState() {
_init();
super.initState();
}
_init() {
if (widget.carton != null) {
_carton = widget.carton;
_selectedCartonType = _carton!.cartonType;
_isNew = false;
consignee = User(
_consignee = User(
id: _carton!.userID, fcsID: _carton!.fcsID, name: _carton!.userName);
sender = User(
_sender = User(
id: _carton!.senderID,
fcsID: _carton!.senderFCSID,
name: _carton!.senderName);
@@ -62,6 +67,20 @@ class _CartonEditorState extends State<CartonEditor> {
Carton(cartonNumber: "A177(A)-3#2", cartonWeight: 35.5),
Carton(cartonNumber: "A177(A)-3#1", cartonWeight: 25.5)
];
_sender = User(
name: "ptd-phyo44 kaelone",
fcsID: "FCS-8X6V",
phoneNumber: "+959444444444",
id: "48u_4s-HiQeW-HwSqeRd9TSMWh3mLZfSk5rpaUEh_zw");
_consignee = User(
id: "HsIwG88K-0_HSazgEy5QR27kcjkOvfv7_Sr1JP18Q1A",
name: "One One",
phoneNumber: "+959111111111",
fcsID: "FCS-EFRF");
}
if (mounted) {
setState(() {});
}
}
@@ -107,7 +126,7 @@ class _CartonEditorState extends State<CartonEditor> {
final cartonTypeBox = LocalRadioButtons(
readOnly: !_isNew,
values: cartonTypes,
values: _cartonTypes,
selectedValue: _selectedCartonType,
callback: (String? v) {
setState(() {
@@ -125,6 +144,22 @@ class _CartonEditorState extends State<CartonEditor> {
onTap: () {
//for packages
if (isFromPackages) {
if (_sender == null) {
showMsgDialog(
context, "Error", "Please select sender's FCS ID");
return;
}
if (_consignee == null) {
showMsgDialog(
context, "Error", "Please select consignee's FCS ID");
return;
}
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => CartonEditorForPackage(
sender: _sender!, consignee: _consignee!)));
}
// for mix cartion
else {
@@ -153,25 +188,25 @@ class _CartonEditorState extends State<CartonEditor> {
icon: Icon(Icons.search, color: Colors.black),
onPressed: () => searchUser(context, onUserSelect: (u) {
setState(() {
this.consignee = u;
this._consignee = u;
});
}, popPage: true)),
],
);
final consigneefcsIDBox = DisplayText(
text: consignee != null ? consignee!.fcsID : "",
text: _consignee != null ? _consignee!.fcsID : "",
labelTextKey: "processing.fcs.id",
icon: FcsIDIcon(),
);
final consigneePhoneBox = DisplayText(
text: consignee != null ? consignee!.phoneNumber : "",
text: _consignee != null ? _consignee!.phoneNumber : "",
labelTextKey: "processing.phone",
iconData: MaterialCommunityIcons.phone);
final consigneeNameBox = DisplayText(
text: consignee != null ? consignee!.name : "",
text: _consignee != null ? _consignee!.name : "",
labelTextKey: "processing.consignee.name",
maxLines: 2,
iconData: MaterialCommunityIcons.account_arrow_left);
@@ -199,25 +234,25 @@ class _CartonEditorState extends State<CartonEditor> {
icon: Icon(Icons.search, color: Colors.black),
onPressed: () => searchUser(context, onUserSelect: (u) {
setState(() {
this.sender = u;
this._sender = u;
});
}, popPage: true)),
],
);
final senderIDBox = DisplayText(
text: sender != null ? sender!.fcsID : "",
text: _sender != null ? _sender!.fcsID : "",
labelTextKey: "processing.fcs.id",
icon: FcsIDIcon());
final senderPhoneBox = DisplayText(
text: sender != null ? sender!.phoneNumber : "",
text: _sender != null ? _sender!.phoneNumber : "",
labelTextKey: "processing.phone",
iconData: MaterialCommunityIcons.phone,
);
final senderNameBox = DisplayText(
text: sender != null ? sender!.name : "",
text: _sender != null ? _sender!.name : "",
labelTextKey: "processing.shipper.name",
maxLines: 2,
iconData: MaterialCommunityIcons.account_arrow_right);

View File

@@ -0,0 +1,217 @@
// ignore_for_file: deprecated_member_use
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../../../domain/constants.dart';
import '../../../domain/entities/carton.dart';
import '../../../domain/entities/carton_size.dart';
import '../../../domain/entities/fcs_shipment.dart';
import '../../../domain/vo/local_step.dart';
import '../../../helpers/theme.dart';
import '../../domain/entities/user.dart';
import '../main/util.dart';
import '../widgets/local_text.dart';
import '../widgets/progress.dart';
import '../widgets/step_widget.dart';
import 'carton_size_widget.dart';
import 'mix_carton/mix_carton_submit.dart';
class CartonEditorForPackage extends StatefulWidget {
final User sender;
final User consignee;
const CartonEditorForPackage({Key? key, required this.sender, required this.consignee}) : super(key: key);
@override
State<CartonEditorForPackage> createState() => _CartonEditorForPackageState();
}
class _CartonEditorForPackageState extends State<CartonEditorForPackage> {
var dateFormatter = DateFormat('dd MMM yyyy');
final NumberFormat numberFormatter = NumberFormat("#,###");
List<LocalStep> steps = [
LocalStep(lable: 'Size', stepType: StepType.SIZE),
LocalStep(lable: 'Packages', stepType: StepType.PACKAGES),
LocalStep(lable: 'Cargos', stepType: StepType.CARGOS),
LocalStep(lable: 'Submit', stepType: StepType.SUBMIT)
];
List<Carton> _cartions = [];
int currentStep = 0;
double _length = 0;
double _width = 0;
double _height = 0;
FcsShipment? _shipment;
String _cartonSizeType = standardCarton;
CartonSize? _standardSize;
bool _isLoading = false;
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
if (currentStep == 0) {
Navigator.of(context).pop();
}
if (currentStep > 0) {
setState(() {
currentStep -= 1;
});
}
return Future.value(false);
},
child: LocalProgress(
inAsyncCall: _isLoading,
child: Scaffold(
appBar: AppBar(
elevation: 0,
centerTitle: true,
leading: IconButton(
icon: const Icon(CupertinoIcons.back,
color: primaryColor, size: 25),
onPressed: () {
if (currentStep == 0) {
Navigator.of(context).pop();
}
if (currentStep > 0) {
setState(() {
currentStep -= 1;
});
}
},
),
backgroundColor: Colors.white,
title: LocalText(context, 'boxes.new',
color: primaryColor, fontSize: 20),
),
body: Column(
children: [
StepperWidget(
labels: steps.map((e) => e.lable).toList(),
currentStep: currentStep,
eachStepWidth: MediaQuery.of(context).size.width / 4,
onChange: (index) {
if (index > currentStep) {
return;
}
setState(() {
currentStep = index;
});
},
),
getContent(currentStep)
],
))),
);
}
Widget getContent(int index) {
var step = steps[index];
if (step.stepType == StepType.SIZE) {
return Expanded(
child: CartonSizeWidget(
sender: widget.sender,
consignee: widget.consignee,
shipment: _shipment,
cartonSizeType: _cartonSizeType,
standardSize: _standardSize,
length: _length,
width: _width,
height: _height,
onPrevious: () {
Navigator.pop(context);
},
onContinue: (shipment, cartonSizeType,
{standardSize, length, width, height}) {
setState(() {
_shipment = shipment;
_cartonSizeType = cartonSizeType;
_standardSize = standardSize;
_length = length ?? 0;
_width = width ?? 0;
_height = height ?? 0;
currentStep += 1;
});
},
));
} else if (step.stepType == StepType.PACKAGES) {
return Expanded(
child: Text("PACKAGES"),
// child: CartonSelectionWidget(
// shipment: _shipment!,
// cartons: _cartions,
// onContinue: (cartons) {
// setState(() {
// _cartions = List.from(cartons);
// currentStep += 1;
// });
// },
// onPrevious: (cartons) {
// setState(() {
// _cartions = List.from(cartons);
// currentStep -= 1;
// });
// },
// ),
);
} else if (step.stepType == StepType.CARGOS) {
return Expanded(
child: Text("cargos"),
// child: CartonSelectionWidget(
// shipment: _shipment!,
// cartons: _cartions,
// onContinue: (cartons) {
// setState(() {
// _cartions = List.from(cartons);
// currentStep += 1;
// });
// },
// onPrevious: (cartons) {
// setState(() {
// _cartions = List.from(cartons);
// currentStep -= 1;
// });
// },
// ),
);
} else {
return Expanded(
child: MixCartonSubmit(
cartonSizeType: _cartonSizeType,
standardSize: _standardSize,
length: _length,
width: _width,
height: _height,
shipment: _shipment!,
cartons: _cartions,
onCreate: () {
_create();
},
onPrevious: () {
setState(() {
currentStep -= 1;
});
},
),
);
}
}
_create() async {
setState(() {
_isLoading = true;
});
try {
Navigator.pop(context, true);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
}

View File

@@ -199,8 +199,9 @@ class _CartonInfoState extends State<CartonInfo> {
final customerNameBox = DisplayText(
text: _box!.userName == null ? "" : _box!.userName,
text1: _box!.fcsID == null ? "" : _box!.fcsID,
subText: Text(_box!.fcsID ?? "", style: textStyle),
labelTextKey: "box.name",
//iconData: Icons.person,
);
@@ -212,7 +213,8 @@ class _CartonInfoState extends State<CartonInfo> {
final consigneeNameBox = DisplayText(
text: _box!.userName != null ? _box!.userName : "",
text1: _box!.fcsID != null ? _box!.fcsID : "",
subText: Text(_box!.fcsID ?? "", style: textStyle),
labelTextKey: "processing.consignee.name",
//maxLines: 2,
//iconData: Ionicons.document_text_outline,
@@ -365,48 +367,52 @@ class _CartonInfoState extends State<CartonInfo> {
// ],)
// ]),),
Padding(padding: EdgeInsets.only(left: 30),
child:
Row(
Padding(
padding: EdgeInsets.only(left: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [Expanded(child: cartonTypeBox,
children: [
Expanded(
child: cartonTypeBox,
flex: 1,
),
Flexible(
child: cartonQrBox,
),
],)),
],
)),
Padding(padding: EdgeInsets.only(left: 30),
child:
Row(
Padding(
padding: EdgeInsets.only(left: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [Expanded(child: shipmentBox,
children: [
Expanded(
child: shipmentBox,
flex: 1,
),
Flexible(
child: deliveryBox,
),
],)),
Padding(padding: EdgeInsets.only(left: 30),
child:
Row(
],
)),
Padding(
padding: EdgeInsets.only(left: 30),
child: Row(
children: [
Flexible(child: customerNameBox,
Flexible(
child: customerNameBox,
),
Flexible(
child: consigneeNameBox,
),
Flexible(child:
Column(
children: [
Flexible(
child: Column(children: [
Icon(Ionicons.document_text_outline),
Text("Bill to",style:TextStyle(color:Colors.blue))
]
Text("Bill to", style: TextStyle(color: Colors.blue))
])),
],
)),
],)),
//LocalTitle(textKey: "box.shipment_info"),
// shipmentBox,
@@ -429,9 +435,7 @@ class _CartonInfoState extends State<CartonInfo> {
// ],
// )
// : Container(),
Padding(padding: EdgeInsets.only(left: 30),
child:
packageBox),
Padding(padding: EdgeInsets.only(left: 30), child: packageBox),
isMixBox ? mixTypeBox : Container(),
isMixBox ? LocalTitle(textKey: "box.mix_caton_title") : Container(),
isMixBox

View File

@@ -0,0 +1,375 @@
import 'package:fcs/pages/widgets/local_radio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'package:provider/provider.dart';
import '../../../domain/constants.dart';
import '../../../domain/entities/carton_size.dart';
import '../../../domain/entities/fcs_shipment.dart';
import '../../../helpers/theme.dart';
import '../../domain/entities/user.dart';
import '../carton_size/model/carton_size_model.dart';
import '../fcs_shipment/model/fcs_shipment_model.dart';
import '../main/util.dart';
import '../widgets/box_size_picker.dart';
import '../widgets/continue_button.dart';
import '../widgets/display_text.dart';
import '../widgets/local_dropdown.dart';
import '../widgets/local_text.dart';
import '../widgets/local_title.dart';
import '../widgets/previous_button.dart';
typedef OnPrevious = Function();
typedef OnContinue = Function(FcsShipment shipment, String cartonSizeType,
{CartonSize? standardSize, double? length, double? width, double? height});
class CartonSizeWidget extends StatefulWidget {
final OnPrevious? onPrevious;
final OnContinue? onContinue;
final User sender;
final User consignee;
final FcsShipment? shipment;
final String cartonSizeType;
final CartonSize? standardSize;
final double? length;
final double? width;
final double? height;
const CartonSizeWidget(
{Key? key,
this.onPrevious,
this.onContinue,
this.shipment,
required this.cartonSizeType,
this.standardSize,
this.length,
this.width,
this.height,
required this.sender,
required this.consignee})
: super(key: key);
@override
State<CartonSizeWidget> createState() => _CartonSizeWidgetState();
}
class _CartonSizeWidgetState extends State<CartonSizeWidget> {
FcsShipment? _shipment;
String _cartionSizeType = standardCarton;
List<FcsShipment> _shipments = [];
CartonSize? _selectStandardSize;
TextEditingController _widthController = new TextEditingController();
TextEditingController _heightController = new TextEditingController();
TextEditingController _lengthController = new TextEditingController();
@override
void initState() {
_init();
super.initState();
}
_init() async {
_shipment = widget.shipment;
_cartionSizeType = widget.cartonSizeType;
List<CartonSize> cartonSizes = context.read<CartonSizeModel>().cartonSizes;
_selectStandardSize = widget.standardSize ?? cartonSizes.first;
_lengthController.text =
widget.length == null ? "0" : widget.length.toString();
_widthController.text =
widget.width == null ? "0" : widget.width.toString();
_heightController.text =
widget.height == null ? "0" : widget.height.toString();
var fcsShipments =
await context.read<FcsShipmentModel>().getActiveFcsShipments();
_shipments = fcsShipments;
if (mounted) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
List<CartonSize> cartonSizes = context.watch<CartonSizeModel>().cartonSizes;
bool isStandardSize = _cartionSizeType == standardCarton;
bool isCustomSize = _cartionSizeType == customCarton;
bool isNoneDefinedSize = _cartionSizeType == packageCartion;
final senderBox = DisplayText(
text: widget.sender.name,
labelTextKey: "box.sender.title",
iconData: MaterialCommunityIcons.account_arrow_right,
);
final consigneeBox = DisplayText(
text: widget.consignee.name,
labelTextKey: "box.consignee.title",
iconData: MaterialCommunityIcons.account_arrow_left,
);
final userRow = Row(
children: [
Flexible(
child: senderBox,
flex: 2,
),
Flexible(child: consigneeBox)
],
);
final continueBtn = ContinueButton(onTap: () {
double l = double.tryParse(_lengthController.text) ?? 0;
double w = double.tryParse(_widthController.text) ?? 0;
double h = double.tryParse(_heightController.text) ?? 0;
if (_shipment == null) {
showMsgDialog(context, "Error", "Please select shipment");
return;
}
if (isStandardSize &&
_selectStandardSize == null &&
!isCustomSize &&
!isNoneDefinedSize) {
showMsgDialog(
context, "Error", "Please select the standard cartion size");
return;
}
if (isCustomSize &&
!isStandardSize &&
!isNoneDefinedSize &&
(l == 0 || w == 0 || h == 0)) {
showMsgDialog(context, "Error", "Please add the cartion size");
return;
}
if (widget.onContinue != null) {
widget.onContinue!(_shipment!, _cartionSizeType,
standardSize: _selectStandardSize, length: l, width: w, height: h);
}
});
final previousBtn = PreviousButton(onTap: () {
if (widget.onPrevious != null) {
widget.onPrevious!();
}
});
final standardSizeBox = Padding(
padding: const EdgeInsets.only(left: 34.0, top: 8),
child: IgnorePointer(
ignoring: !isStandardSize,
child: DropdownButton<CartonSize>(
isDense: true,
value: _selectStandardSize,
style: TextStyle(color: Colors.black, fontSize: 14),
underline: Container(height: 1, color: Colors.grey),
onChanged: (newValue) {
setState(() {
_selectStandardSize = newValue!;
});
},
isExpanded: true,
items:
cartonSizes.map<DropdownMenuItem<CartonSize>>((CartonSize value) {
return DropdownMenuItem<CartonSize>(
value: value,
child: Row(
children: [
Text("${value.name} - ",
style: TextStyle(
color: isStandardSize ? Colors.black : labelColor)),
Text(
"${value.length.toInt()}”x${value.width.toInt()}”x${value.height.toInt()}",
style: TextStyle(color: labelColor)),
],
),
);
}).toList(),
),
),
);
final lengthBox = BoxSizePicker(
lableKey: 'box.length',
controller: _lengthController,
enable: isCustomSize);
final widthBox = BoxSizePicker(
lableKey: 'box.width',
controller: _widthController,
enable: isCustomSize);
final heightBox = BoxSizePicker(
lableKey: 'box.height',
controller: _heightController,
enable: isCustomSize);
final customSizeBox = Padding(
padding: const EdgeInsets.only(left: 34.0),
child: Row(
children: [
Flexible(child: lengthBox),
Flexible(child: widthBox),
Flexible(child: heightBox)
],
),
);
final cartonSizedBox = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// standard carton size
InkWell(
onTap: () {
setState(() {
_cartionSizeType = standardCarton;
});
},
child: Row(children: <Widget>[
LocalRadio(
value: standardCarton,
groupValue: _cartionSizeType,
onChanged: (p0) {
setState(() {
_cartionSizeType = standardCarton;
});
},
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: LocalText(context, 'box.standard_carton_size',
fontSize: 15,
color: isStandardSize ? primaryColor : labelColor),
),
)
]),
),
standardSizeBox,
const SizedBox(height: 20),
// custom size
InkWell(
onTap: () {
setState(() {
_cartionSizeType = customCarton;
});
},
child: Row(children: <Widget>[
LocalRadio(
value: customCarton,
groupValue: _cartionSizeType,
onChanged: (p0) {
setState(() {
_cartionSizeType = customCarton;
});
},
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: LocalText(context, 'box.custom_size',
fontSize: 15,
color: isCustomSize ? primaryColor : Colors.black54),
),
)
]),
),
customSizeBox,
const SizedBox(height: 10),
// not defined size
InkWell(
onTap: () {
setState(() {
_cartionSizeType = packageCartion;
});
},
child: Row(children: <Widget>[
LocalRadio(
value: packageCartion,
groupValue: _cartionSizeType,
onChanged: (p0) {
setState(() {
_cartionSizeType = packageCartion;
});
},
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: LocalText(context, 'box.package_size',
fontSize: 15,
color: isNoneDefinedSize ? primaryColor : Colors.black54),
),
)
]),
),
Padding(
padding: const EdgeInsets.only(left: 34.0),
child: Text(
"No defined size",
style: TextStyle(
fontSize: 14,
color: isNoneDefinedSize ? Colors.black : labelColor),
),
)
],
);
final fcsShipmentsBox = Container(
padding: EdgeInsets.only(top: 10),
child: LocalDropdown<FcsShipment>(
callback: (v) {
setState(() {
_shipment = v;
});
},
labelKey: "box.shipment",
iconData: Ionicons.ios_airplane,
display: (u) => u.shipmentNumber,
selectedValue: _shipment,
values: _shipments,
));
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView(
padding: EdgeInsets.only(left: 10, right: 10),
children: [
const SizedBox(height: 8),
userRow,
LocalTitle(textKey: "box.select_carton_size"),
const SizedBox(height: 8),
cartonSizedBox,
const SizedBox(height: 8),
LocalTitle(textKey: "box.select_shipment"),
const SizedBox(height: 5),
fcsShipmentsBox
],
)),
Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
widget.onPrevious == null ? const SizedBox() : previousBtn,
continueBtn
// warehouse != null ? continueBtn : const SizedBox(),
],
),
),
const SizedBox(
height: 20,
),
],
);
}
}

View File

@@ -36,7 +36,7 @@ class CartonSelectionResult extends StatelessWidget {
var model = context.watch<CartonSelectionModel>();
List<Carton> searchResults = model.cartons;
return searchResults.isEmpty
return searchResults.isEmpty && !model.isLoading
? Center(
child: LocalText(context, 'box.no_carton',
color: Colors.black, fontSize: 15))

View File

@@ -1,6 +1,6 @@
import 'package:fcs/domain/entities/fcs_shipment.dart';
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/carton/mix_cation/carton_selection_result.dart';
import 'package:fcs/pages/carton/mix_carton/carton_selection_result.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

View File

@@ -11,11 +11,13 @@ import '../../../domain/entities/carton_size.dart';
import '../../../domain/entities/fcs_shipment.dart';
import '../../../domain/vo/local_step.dart';
import '../../../helpers/theme.dart';
import '../../main/util.dart';
import '../../widgets/local_text.dart';
import '../../widgets/progress.dart';
import '../../widgets/step_widget.dart';
import '../model/carton_selection_model.dart';
import 'carton_selection_widget.dart';
import 'mix_carton_submit.dart';
import 'type_widget.dart';
class MixCartonEditor extends StatefulWidget {
@@ -43,7 +45,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
double _height = 0;
FcsShipment? _shipment;
String _cartionSizeType = standardCarton;
String _cartonSizeType = standardCarton;
CartonSize? _standardSize;
bool _isLoading = false;
@@ -97,7 +99,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
StepperWidget(
labels: steps.map((e) => e.lable).toList(),
currentStep: currentStep,
eachStepWidth: 120,
eachStepWidth: MediaQuery.of(context).size.width / 3,
onChange: (index) {
if (index > currentStep) {
return;
@@ -119,7 +121,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
return Expanded(
child: TypeWidget(
shipment: _shipment,
cartonSizeType: _cartionSizeType,
cartonSizeType: _cartonSizeType,
standardSize: _standardSize,
length: _length,
width: _width,
@@ -131,7 +133,7 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
{standardSize, length, width, height}) {
setState(() {
_shipment = shipment;
_cartionSizeType = cartonSizeType;
_cartonSizeType = cartonSizeType;
_standardSize = standardSize;
_length = length ?? 0;
_width = width ?? 0;
@@ -161,27 +163,39 @@ class _MixCartonEditorState extends State<MixCartonEditor> {
);
} else {
return Expanded(
child: Text("Submit"),
// child: StockAdjustmentSubmit(
// warehouse: _warehouse?.name,
// products: products,
// onCreate: () {
// if (user != null && user.hasInventoryCreate()) {
// showConfirmDialog(context, 'stock_adjustment_confirm', _create);
// } else {
// showDialog(
// context: context,
// builder: (BuildContext context) => const AuthorizedDialog(
// uiFunction: funcInventoriesCreate));
// }
// },
// onPrevious: () {
// setState(() {
// currentStep -= 1;
// });
// },
// ),
child: MixCartonSubmit(
cartonSizeType: _cartonSizeType,
standardSize: _standardSize,
length: _length,
width: _width,
height: _height,
shipment: _shipment!,
cartons: _cartions,
onCreate: () {
_create();
},
onPrevious: () {
setState(() {
currentStep -= 1;
});
},
),
);
}
}
_create() async {
setState(() {
_isLoading = true;
});
try {
Navigator.pop(context, true);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
}

View File

@@ -0,0 +1,289 @@
import 'package:flutter/material.dart';
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
import 'package:intl/intl.dart';
import '../../../domain/constants.dart';
import '../../../domain/entities/cargo_type.dart';
import '../../../domain/entities/carton.dart';
import '../../../domain/entities/carton_size.dart';
import '../../../domain/entities/fcs_shipment.dart';
import '../../../helpers/theme.dart';
import '../../widgets/local_text.dart';
import '../../widgets/previous_button.dart';
import '../../widgets/submit_text_widget.dart';
import "package:collection/collection.dart";
typedef OnCreateMixCarton = Function();
typedef OnPrevious = Function();
class MixCartonSubmit extends StatefulWidget {
final FcsShipment shipment;
final List<Carton> cartons;
final String cartonSizeType;
final CartonSize? standardSize;
final double length;
final double width;
final double height;
final OnCreateMixCarton? onCreate;
final OnPrevious? onPrevious;
const MixCartonSubmit(
{Key? key,
this.onCreate,
this.onPrevious,
required this.shipment,
this.cartons = const [],
this.standardSize,
required this.cartonSizeType,
this.length = 0,
this.width = 0,
this.height = 0})
: super(key: key);
@override
State<MixCartonSubmit> createState() => _MixCartonSubmitState();
}
class _MixCartonSubmitState extends State<MixCartonSubmit> {
final NumberFormat numberFormatter = NumberFormat("#,###");
Map<String?, double> _mapCargosByWeight = {};
Map<String?, double> _mapCargosByCustomDutyFee = {};
@override
void initState() {
_init();
super.initState();
}
_init() {
List<CargoType> _cargoTypes = [];
for (var c in widget.cartons) {
_cargoTypes.addAll(c.cargoTypes);
}
// get cargos by weight
Map<String?, List<CargoType>> _cargosByWeight =
groupCargos(_cargoTypes.where((e) => !e.isCutomDuty).toList());
_cargosByWeight.forEach((key, value) {
double total = value.fold(0, (sum, item) => sum + item.weight);
_mapCargosByWeight[key] = total;
});
// get cargos by custom duty fee
Map<String?, List<CargoType>> _cargosByCustomDutyFee =
groupCargos(_cargoTypes.where((e) => e.isCutomDuty).toList());
_cargosByCustomDutyFee.forEach((key, value) {
double total = value.fold(0, (sum, item) => sum + item.qty);
_mapCargosByCustomDutyFee[key] = total;
});
if (mounted) {
setState(() {});
}
}
Map<String?, List<CargoType>> groupCargos(List<CargoType> cargos) {
var groups = groupBy(cargos, (CargoType e) {
String? _categoryName = e.name;
return _categoryName;
});
return groups;
}
@override
Widget build(BuildContext context) {
String? boxDimension = widget.cartonSizeType == standardCarton
? "${widget.standardSize?.name} - ${widget.standardSize?.length.toInt()}”x${widget.standardSize?.width.toInt()}”x${widget.standardSize?.height.toInt()}"
: widget.cartonSizeType == customCarton
? "${widget.length.toInt()}”x${widget.width.toInt()}”x${widget.height.toInt()}"
: null;
final cartonType = Padding(
padding: const EdgeInsets.only(top: 10),
child: SubmitTextWidget(
labelKey: 'box.carton.type',
text: 'Mix Carton',
subText: boxDimension,
),
);
final shipmentBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: SubmitTextWidget(
labelKey: 'box.shipment',
text: widget.shipment.shipmentNumber ?? '',
subText: widget.shipment.status ?? "",
),
);
final cartonsBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Padding(
padding: const EdgeInsets.only(left: 5, bottom: 5),
child: LocalText(context, 'box.cartion.count',
translationVariables: [widget.cartons.length.toString()],
color: primaryColor,
fontSize: 16,
fontWeight: FontWeight.normal),
),
Container(
decoration: BoxDecoration(
border: Border.all(color: primaryColor),
borderRadius: BorderRadius.circular(5),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
spacing: 15,
children: widget.cartons.map((e) {
return SizedBox(
width: MediaQuery.of(context).size.width / 2.5,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 3),
child: Text(
e.cartonNumber ?? "",
style: TextStyle(color: Colors.black, fontSize: 15),
),
),
);
}).toList()),
),
),
]),
);
final cargosBox = Padding(
padding: const EdgeInsets.only(top: 10),
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Padding(
padding: const EdgeInsets.only(left: 5, bottom: 5),
child: LocalText(context, 'box.cargo.type',
color: primaryColor, fontSize: 16, fontWeight: FontWeight.normal),
),
Container(
decoration: BoxDecoration(
border: Border.all(color: primaryColor),
borderRadius: BorderRadius.circular(5),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _mapCargosByWeight.entries.map((e) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
e.key ?? "",
style:
TextStyle(color: Colors.black, fontSize: 15),
),
Text("${numberFormatter.format(e.value)} lb",
style: TextStyle(
color: Colors.black, fontSize: 15))
],
),
);
}).toList()),
const SizedBox(height: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: _mapCargosByCustomDutyFee.entries.map((e) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
e.key ?? "",
style: TextStyle(color: labelColor, fontSize: 15),
),
Text("${numberFormatter.format(e.value)} pc",
style:
TextStyle(color: labelColor, fontSize: 15))
],
),
);
}).toList()),
],
),
),
),
]),
);
final createBtn = InkWell(
onTap: () {
if (widget.onCreate != null) {
widget.onCreate!();
}
},
child: Container(
alignment: Alignment.bottomRight,
height: 45,
width: 150,
decoration: BoxDecoration(
color: primaryColor,
borderRadius: BorderRadius.circular(5),
),
child: TextButton(
onPressed: null,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: LocalText(context, 'box.crete.carton',
color: Colors.white, fontSize: 15),
),
const SizedBox(width: 5),
const Icon(
MaterialCommunityIcons.check_circle_outline,
color: Colors.white,
),
],
),
),
));
final previousBtn = PreviousButton(onTap: () {
if (widget.onPrevious != null) {
widget.onPrevious!();
}
});
return Column(
children: [
Expanded(
child: ListView(
padding: const EdgeInsets.all(20),
children: [
cartonType,
const SizedBox(height: 10),
shipmentBox,
const SizedBox(height: 10),
widget.cartons.isNotEmpty ? cartonsBox : const SizedBox(),
const SizedBox(height: 10),
cargosBox,
const SizedBox(height: 20),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [previousBtn, createBtn],
),
),
const SizedBox(height: 20)
],
);
}
}

View File

@@ -15,6 +15,8 @@ class CartonSelectionModel extends BaseModel {
bool reachEnd = false;
List<Carton> cartons = [];
bool isLoading= false;
// for default carton
DocumentSnapshot? _lastDocument;
bool ended = false;
@@ -96,6 +98,7 @@ class CartonSelectionModel extends BaseModel {
int rowPerPage = 20;
try {
isLoading = true;
String path = "/$cartons_collection";
Query query = FirebaseFirestore.instance
.collection(path)
@@ -131,6 +134,8 @@ class CartonSelectionModel extends BaseModel {
notifyListeners();
} catch (e) {
log.warning("error:$e");
}finally{
isLoading = false;
}
}

View File

@@ -1,7 +1,6 @@
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart';
import 'package:fcs/pages/widgets/local_app_bar.dart';
import 'package:fcs/pages/widgets/local_popup_menu_button.dart';
import 'package:fcs/pages/widgets/local_popupmenu.dart';
import 'package:fcs/pages/widgets/local_text.dart';
import 'package:fcs/pages/widgets/progress.dart';

View File

@@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
class DisplayText extends StatelessWidget {
final String? text;
final String? text1;
final Widget? subText;
final String? labelTextKey;
final IconData? iconData;
final int? maxLines;
@@ -14,11 +14,10 @@ class DisplayText extends StatelessWidget {
final Color? borderColor;
final Widget? icon;
const DisplayText({
Key? key,
this.text,
this.text1,
this.subText,
this.labelTextKey,
this.iconData,
this.maxLines = 1,
@@ -72,12 +71,9 @@ class DisplayText extends StatelessWidget {
text!,
style: textStyle,
),
text1 == null
subText == null
? Container()
: Text(
text1!,
style: textStyle,
),
: subText!,
],
),
),

View File

@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import '../../helpers/theme.dart';
import 'local_text.dart';
class SubmitTextWidget extends StatelessWidget {
final String labelKey;
final String text;
final String? subText;
const SubmitTextWidget(
{Key? key, required this.labelKey, required this.text, this.subText})
: super(key: key);
@override
Widget build(BuildContext context) {
return Column(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Padding(
padding: const EdgeInsets.only(left: 5, bottom: 5),
child: LocalText(context, labelKey,
color: primaryColor, fontSize: 16, fontWeight: FontWeight.normal),
),
Container(
decoration: BoxDecoration(
border: Border.all(color: primaryColor),
borderRadius: BorderRadius.circular(5),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(text,
style: const TextStyle(
fontSize: 16.0, fontWeight: FontWeight.w500)),
subText == null
? const SizedBox()
: Text(subText!,
style:
const TextStyle(fontSize: 14.0, color: Colors.grey)),
],
),
),
)
]);
}
}