generate freight bill

dev_branch
Priya Chetiwal 2025-02-04 20:09:25 +05:30
parent faf484e8e0
commit a52b90a7d2
9 changed files with 1011 additions and 636 deletions

View File

@ -546,6 +546,13 @@ class _CustomDropdownState<T> extends State<CustomDropdown<T>> {
style: 12.txtSBoldGrey,
overflow: TextOverflow.ellipsis,
),
// Text(
// selectedItem != null
// ? widget.itemLabel(selectedItem as T)
// : widget.hintText,
// style: 12.txtSBoldGrey,
// overflow: TextOverflow.ellipsis,
// ),
),
const Icon(
Icons.keyboard_arrow_down_outlined,

View File

@ -24,6 +24,7 @@ class _DashboardScreenState extends State<DashboardScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.white,
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: AppColors.secondaryClr,

View File

@ -5,6 +5,7 @@ import 'package:shayog/components/common/common_button.dart';
import 'package:shayog/components/styles/app_colors.dart';
import 'package:shayog/components/styles/textStyles.dart';
import 'package:shayog/feature/presentation/widgets/text_view.dart';
import 'package:shayog/services/model/generate_freight_model.dart';
import 'package:sizer/sizer.dart';
import 'package:vph_web_date_picker/vph_web_date_picker.dart';
import '../../../../../../../components/common/common_btn.dart';
@ -23,6 +24,10 @@ class GenerateFrightBill extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Obx(
() => controller.isFilterVisible.value
? Column(
children: [
Container(
padding: EdgeInsets.all(16),
@ -38,23 +43,39 @@ class GenerateFrightBill extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text:
"Plant"),
TextView(text: "Plant", isRequired: true),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
borderClr: AppColors.clrGrey,
items: controller.plant,
itemLabel: (item) => "${item.plantCode}-${item.plantDesc}",
itemLabel: (item) =>
"${item.plantCode} - ${item.plantDesc}",
// Dropdown should show both
onSelected: (selected) {
if (selected != null) {
controller.selectPlant.value = selected.plantCode ?? "";
print(
"selectPlant${controller.selectPlant.value}");
controller.selectPlantFreight.value =
selected.plantCode ?? "";
controller.showPlantErrorFreight
.value = false;
}
},
hintText: "Select Plant",
),
Obx(() => controller
.showPlantErrorFreight.value
? Padding(
padding:
const EdgeInsets.only(top: 4),
child: Text(
'Please select a plant',
style: TextStyle(
color: Colors.red,
fontSize: 12),
),
)
: SizedBox.shrink()),
],
),
),
@ -64,23 +85,39 @@ class GenerateFrightBill extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text:"Product Name"),
TextView(
text: "Product Name", isRequired: true),
SizedBox(height: 8),
CustomDropdown<dynamic>(
width: 250,
backClr: AppColors.clrD9,
borderClr: AppColors.clrGrey,
items: controller.product,
itemLabel: (item) => "${item.materialCode}-${item.materialDescription}",
itemLabel: (item) =>
"${item.materialCode}-${item.materialDescription}",
onSelected: (selected) {
if (selected != null) {
controller.selectProduct.value = selected;
print(
"selectPlant${controller.selectProduct.value}");
controller.selectProductFreight
.value = selected.materialCode;
controller.showProductErrorFreight
.value = false;
}
},
hintText: "Select Product Name",
),
Obx(() => controller
.showProductErrorFreight.value
? Padding(
padding:
const EdgeInsets.only(top: 4),
child: Text(
'Please select a Product',
style: TextStyle(
color: Colors.red,
fontSize: 12),
),
)
: SizedBox.shrink()),
],
),
),
@ -90,7 +127,9 @@ class GenerateFrightBill extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text:"Transaction Type"),
TextView(
text: "Transaction Type",
isRequired: true),
SizedBox(height: 8),
CustomDropdown<String>(
backClr: AppColors.clrD9,
@ -99,95 +138,126 @@ class GenerateFrightBill extends StatelessWidget {
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
controller.selectTransactionType.value = selected;
print(
"selectTransactionType${controller.selectTransactionType.value}");
controller
.selectTransactionTypeFreight
.value = selected;
controller.showTransactionErrorFreight
.value = false;
}
},
hintText: "Select Transaction Type",
),
Obx(() => controller
.showTransactionErrorFreight.value
? Padding(
padding:
const EdgeInsets.only(top: 4),
child: Text(
'Please select Transaction Type',
style: TextStyle(
color: Colors.red,
fontSize: 12),
),
)
: SizedBox.shrink()),
],
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 16.0, left: 0, right: 8),
padding: const EdgeInsets.only(
top: 16.0, left: 0, right: 8),
child: Row(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
TextView(text:"MRN Date Range"),
TextView(text: "MRN Date Range"),
Container(
margin: EdgeInsets.only(top: 8),
height: 35,
child: TextFormField(
key: controller.fromTextFieldKey,
controller: controller.fromController,
onTap: () async {
final pickedDate = await showWebDatePicker(
final pickedDate =
await showWebDatePicker(
width: 20.w,
context: controller
.fromTextFieldKey.currentContext!,
initialDate: controller.fromSelectedDate,
.fromTextFieldKey
.currentContext!,
initialDate:
controller.fromSelectedDate,
firstDate: DateTime(2000),
lastDate: DateTime.now(),
);
if (pickedDate != null) {
controller.fromSelectedDate = pickedDate;
String formattedDate =
controller.getFormattedDate(pickedDate);
controller.fromSelectedDate =
pickedDate;
String formattedDate = controller
.getFormattedDate(pickedDate);
controller.fromController.text =
formattedDate;
controller.dateCheck.value = true;
}
},
decoration: InputDecoration(
fillColor:AppColors.clrD9,
fillColor: AppColors.clrD9,
filled: true,
hintText: 'Select MRN Date Range',
hintStyle: TextStyle(
fontSize: 12,
overflow: TextOverflow.ellipsis),
overflow:
TextOverflow.ellipsis),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
borderSide:
BorderSide(color: AppColors.black),
borderRadius:
BorderRadius.circular(2.0),
borderSide: BorderSide(
color: AppColors.black),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
borderSide:
BorderSide(color: AppColors.clrGrey),
borderRadius:
BorderRadius.circular(2.0),
borderSide: BorderSide(
color: AppColors.clrGrey),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
borderSide:
BorderSide(color: AppColors.clrGrey),
borderRadius:
BorderRadius.circular(2.0),
borderSide: BorderSide(
color: AppColors.clrGrey),
),
disabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(2.0),
borderSide:
BorderSide(color: AppColors.clrGrey),
borderRadius:
BorderRadius.circular(2.0),
borderSide: BorderSide(
color: AppColors.clrGrey),
),
suffixIcon: controller.dateCheck.value
suffixIcon: controller
.dateCheck.value
? InkWell(
onTap: () {
controller.dateCheck.value = false;
controller.fromController.clear();
controller.fromSelectedDate =
controller.dateCheck
.value = false;
controller.fromController
.clear();
controller
.fromSelectedDate =
DateTime.now();
},
child: Icon(Icons.close, size: 1.2.w),
child: Icon(Icons.close,
size: 1.2.w),
)
: null,
contentPadding: const EdgeInsets.symmetric(
horizontal: 12.0, vertical: 0.0),
contentPadding:
const EdgeInsets.symmetric(
horizontal: 12.0,
vertical: 0.0),
),
),
),
@ -198,9 +268,10 @@ class GenerateFrightBill extends StatelessWidget {
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
TextView(text:"From Location"),
TextView(text: "From Location"),
SizedBox(height: 8),
CustomDropdown<dynamic>(
backClr: AppColors.clrD9,
@ -209,7 +280,8 @@ class GenerateFrightBill extends StatelessWidget {
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
controller.selectLocation.value = selected;
controller.selectLocation.value =
selected;
}
},
hintText: "Select From Location",
@ -224,18 +296,20 @@ class GenerateFrightBill extends StatelessWidget {
//flex: 2,
child: Column(
children: [
TextView(text:
"",
TextView(
text: "",
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
mainAxisAlignment:
MainAxisAlignment.end,
children: [
CommonBtn(
bkClr: Colors.white,
text: AppStrings.cancel,
clickAction: () {},
clickAction: () =>
controller.clearFilters(),
),
SizedBox(width: 16),
CommonButton(
@ -243,11 +317,32 @@ class GenerateFrightBill extends StatelessWidget {
height: 30,
width: 100,
text: AppStrings.submit,
clickAction: () {
controller.postData();
},
// clickAction: () {
// // controller.postData();
// controller.handleFilterSubmit();
// },
clickAction: () =>
controller.handleFilterSubmit(),
),
// CommonButton(
// borderRadius: 4,
// height: 30,
// width: 100,
// text: AppStrings.submit,
// clickAction: () {
// controller.validateFields();
//
// if (controller.showPlantError.value ||
// controller.showProductError.value ||
// controller.showTransactionError.value
// ) {
// print('controller.showProductError.value ${controller.showProductError.value}');
//
// } else {
// controller.postData();
// }
// },
// ),
],
),
),
@ -259,6 +354,41 @@ class GenerateFrightBill extends StatelessWidget {
],
),
),
],
)
: SizedBox.shrink(),
),
Obx(() {
List<Content> filteredData = controller.filterGrnDetails.where((item) {
return (controller.selectPlantFreight.value.isEmpty || item.plantCode == controller.selectPlantFreight.value) &&
(controller.selectProductFreight.value.isEmpty || item.materialCode == controller.selectProductFreight.value) &&
(controller.selectTransactionTypeFreight.value.isEmpty || item.transporterCode == controller.selectTransactionTypeFreight.value);
}).toList();
if (controller.isLoading.value) {
return Center(child: CircularProgressIndicator());
}
if (controller.errorMessage.isNotEmpty) {
return Center(child: Text(controller.errorMessage.value));
}
if (controller.grnDetails.isEmpty ) {
return Center(child: Text('No data available.'));
}
return controller.isFilterVisible.value
// If filter is visible, check if any of the fields are empty
?
controller.selectPlantFreight.value.isEmpty
||
controller.selectProductFreight.value.isEmpty ||
controller.selectTransactionTypeFreight.value.isEmpty
// If the fields are empty, show a message or do not display the table
? Center(child: Text('No Data Found', style: TextStyle(fontSize: 16, color: Colors.grey)))
:
Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 10),
margin: EdgeInsets.only(top: 16),
@ -266,7 +396,9 @@ class GenerateFrightBill extends StatelessWidget {
color: AppColors.primaryClr,
child: Row(
children: [
TextView(text: AppStrings.viewGrnDetails, style: 14.txtBoldWhite),
TextView(
text: AppStrings.viewGrnDetails,
style: 14.txtBoldWhite),
Spacer(),
CommonBtn(
width: 150,
@ -274,12 +406,13 @@ class GenerateFrightBill extends StatelessWidget {
borderClr: AppColors.primaryClr,
style: 12.txtBoldBlue,
text: "Generate Freight Bill",
// text: AppStrings.save,
clickAction: () {
bool hasSelectedRows = controller.grnDetails
.any((element) => element.isSelected);
if (!hasSelectedRows) {
showPopup(context: context, onClick: () {
showPopup(
context: context,
onClick: () {
Get.back();
});
} else {
@ -290,7 +423,6 @@ class GenerateFrightBill extends StatelessWidget {
positiveBtCallback: () {
Get.back();
controller.addFreightBill();
showFreightBill(context);
},
negativeBtCallback: () {});
@ -299,19 +431,7 @@ class GenerateFrightBill extends StatelessWidget {
],
),
),
Obx(() {
if (controller.isLoading.value) {
return Center(child: CircularProgressIndicator());
}
if (controller.errorMessage.isNotEmpty) {
return Center(child: Text(controller.errorMessage.value));
}
if (controller.grnDetails.isEmpty) {
return Center(child: Text('No data available.'));
}
return Scrollbar(
Scrollbar(
thumbVisibility: true,
controller: controller.verticalScrollController,
child: SingleChildScrollView(
@ -332,10 +452,189 @@ class GenerateFrightBill extends StatelessWidget {
child: DataTable(
dataRowHeight: 28,
headingRowHeight: 40,
headingRowColor: WidgetStateProperty.all(AppColors.clrF2),
headingRowColor:
WidgetStateProperty.all(AppColors.clrF2),
border: TableBorder(
horizontalInside: BorderSide(color: AppColors.clrGrey),
verticalInside: BorderSide(color: AppColors.clrGrey),
horizontalInside:
BorderSide(color: AppColors.clrGrey),
verticalInside:
BorderSide(color: AppColors.clrGrey),
bottom: BorderSide(color: AppColors.clrGrey),
left: BorderSide(color: AppColors.clrGrey),
right: BorderSide(color: AppColors.clrGrey),
top: BorderSide(color: AppColors.clrGrey),
),
columns: [
DataColumn(
label: Transform.scale(
scale: 0.80,
// Adjust this scale to make the checkbox bigger or smaller
child: Checkbox(
value: controller.selectAllField.value,
onChanged: (value) {
controller.selectAllFilter(value ?? false);
},
activeColor: AppColors.primaryClr,
checkColor: Colors.white,
materialTapTargetSize: MaterialTapTargetSize
.shrinkWrap, // Avoids large tap area
),
),
),
// dataColumn(AppStrings.srNo),
dataColumn(AppStrings.mrnNo),
dataColumn(AppStrings.plantNo),
dataColumn(AppStrings.product),
dataColumn(AppStrings.date),
dataColumn(AppStrings.fromLocation),
dataColumn(AppStrings.vehicleNo),
dataColumn(AppStrings.transporterLrNo),
dataColumn(AppStrings.transporterLrNoDate),
dataColumn(AppStrings.dispQty),
dataColumn(AppStrings.netQty),
dataColumn(AppStrings.billingQty),
dataColumn(AppStrings.vom),
dataColumn(AppStrings.freightRate),
dataColumn(AppStrings.freightAmount),
],
rows: List<DataRow>.generate(
controller.filterGrnDetails.length, (index) {
final stoppage = controller.filterGrnDetails[index];
return DataRow(
selected: stoppage.isSelected,
cells: [
DataCell(
Transform.scale(
scale: 0.80,
child: Checkbox(
value: stoppage.isSelected,
onChanged: (value) {
controller.toggleSelectionFilter(
index, value ?? false);
},
activeColor: AppColors.primaryClr,
// Custom color when selected
checkColor: Colors.white,
// Custom color for check mark
materialTapTargetSize: MaterialTapTargetSize
.shrinkWrap, // Avoids large tap area
),
),
),
// editableCell(index, "0${index + 1}"),
editableCell(index, stoppage.grnNo ?? ""),
editableCell(index, stoppage.plantCode ?? ""),
editableCell(
index, stoppage.materialCode ?? ""),
editableCell(
index,
DateFormat('yyyy-MM-dd').format(
stoppage.grnDate ?? DateTime.now())),
editableCell(
index, stoppage.fromLocation ?? ""),
editableCell(index, stoppage.vehicleNo ?? ""),
editableCell(index, stoppage.lrNo ?? ""),
editableCell(
index,
DateFormat('yyyy-MM-dd').format(
stoppage.lrDate ?? DateTime.now())),
editableCell(
index, stoppage.dispQty?.toString() ?? ""),
editableCell(
index, stoppage.netQty?.toString() ?? ""),
editableCell(index,
stoppage.billingQty?.toString() ?? ""),
editableCell(index,
stoppage.freightRate?.toString() ?? ""),
editableCell(index,
stoppage.shipmentCost?.toString() ?? ""),
editableCell(
index, stoppage.statusId?.toString() ?? ""),
],
);
}),
),
),
),
),
),
),
],
):
Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 10),
margin: EdgeInsets.only(top: 16),
height: 45,
color: AppColors.primaryClr,
child: Row(
children: [
TextView(
text: AppStrings.viewGrnDetails,
style: 14.txtBoldWhite),
Spacer(),
CommonBtn(
width: 150,
bkClr: AppColors.white,
borderClr: AppColors.primaryClr,
style: 12.txtBoldBlue,
text: "Generate Freight Bill",
clickAction: () {
bool hasSelectedRows = controller.grnDetails
.any((element) => element.isSelected);
if (!hasSelectedRows) {
showPopup(
context: context,
onClick: () {
Get.back();
});
} else {
CommonAlertDialog.showDialog(
message: "Are you sure want to\nsave this?",
positiveText: "Save",
negativeText: "Cancel",
positiveBtCallback: () {
Get.back();
controller.addFreightBill();
showFreightBill(context);
},
negativeBtCallback: () {});
}
}),
],
),
),
Scrollbar(
thumbVisibility: true,
controller: controller.verticalScrollController,
child: SingleChildScrollView(
controller: controller.verticalScrollController,
child: Scrollbar(
thumbVisibility: true,
controller: controller.horizontalScrollController,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
controller: controller.horizontalScrollController,
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey.shade400,
width: 1.0,
),
),
child: DataTable(
dataRowHeight: 28,
headingRowHeight: 40,
headingRowColor:
WidgetStateProperty.all(AppColors.clrF2),
border: TableBorder(
horizontalInside:
BorderSide(color: AppColors.clrGrey),
verticalInside:
BorderSide(color: AppColors.clrGrey),
bottom: BorderSide(color: AppColors.clrGrey),
left: BorderSide(color: AppColors.clrGrey),
right: BorderSide(color: AppColors.clrGrey),
@ -375,8 +674,8 @@ class GenerateFrightBill extends StatelessWidget {
dataColumn(AppStrings.freightRate),
dataColumn(AppStrings.freightAmount),
],
rows: List<DataRow>.generate(controller.grnDetails.length,
(index) {
rows: List<DataRow>.generate(
controller.grnDetails.length, (index) {
final stoppage = controller.grnDetails[index];
return DataRow(
@ -403,28 +702,30 @@ class GenerateFrightBill extends StatelessWidget {
// editableCell(index, "0${index + 1}"),
editableCell(index, stoppage.grnNo ?? ""),
editableCell(index, stoppage.plantCode ?? ""),
editableCell(index, stoppage.materialCode ?? ""),
editableCell(
index, stoppage.materialCode ?? ""),
editableCell(
index,
DateFormat('yyyy-MM-dd').format(
stoppage.grnDate ?? DateTime.now())),
editableCell(index, stoppage.fromLocation ?? ""),
editableCell(
index, stoppage.fromLocation ?? ""),
editableCell(index, stoppage.vehicleNo ?? ""),
editableCell(index, stoppage.lrNo ?? ""),
editableCell(
index,
DateFormat('yyyy-MM-dd')
.format(stoppage.lrDate ?? DateTime.now())),
DateFormat('yyyy-MM-dd').format(
stoppage.lrDate ?? DateTime.now())),
editableCell(
index, stoppage.dispQty?.toString() ?? ""),
editableCell(
index, stoppage.netQty?.toString() ?? ""),
editableCell(
index, stoppage.billingQty?.toString() ?? ""),
editableCell(
index, stoppage.freightRate?.toString() ?? ""),
editableCell(
index, stoppage.shipmentCost?.toString() ?? ""),
editableCell(index,
stoppage.billingQty?.toString() ?? ""),
editableCell(index,
stoppage.freightRate?.toString() ?? ""),
editableCell(index,
stoppage.shipmentCost?.toString() ?? ""),
editableCell(
index, stoppage.statusId?.toString() ?? ""),
],
@ -435,11 +736,11 @@ class GenerateFrightBill extends StatelessWidget {
),
),
),
),
],
);
}),
],
);
}
}

View File

@ -41,7 +41,7 @@ class PendingGeneration extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text:
"Plant"),
"Plant", isRequired: true),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
@ -50,13 +50,21 @@ class PendingGeneration extends StatelessWidget {
itemLabel: (item) => "${item.plantCode}-${item.plantDesc}",
onSelected: (selected) {
if (selected != null) {
controller.selectPlant.value = selected.plantCode ?? "";
print(
"selectPlant${controller.selectPlant.value}");
controller.selectPlantPending.value = selected.plantCode ?? "";
controller.showPlantErrorPending.value = false;
}
},
hintText: "Select Plant",
),
Obx(() => controller.showPlantErrorPending.value
? Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
'Please select a plant',
style: TextStyle(color: Colors.red, fontSize: 12),
),
)
: SizedBox.shrink()),
],
),
),
@ -66,7 +74,7 @@ class PendingGeneration extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text:"Product Name"),
TextView(text:"Product Name", isRequired: true),
SizedBox(height: 8),
CustomDropdown<dynamic>(
width: 250,
@ -76,7 +84,7 @@ class PendingGeneration extends StatelessWidget {
itemLabel: (item) => "${item.materialCode}-${item.materialDescription}",
onSelected: (selected) {
if (selected != null) {
controller.selectProduct.value = selected;
controller.selectProductPending.value = selected;
print(
"selectPlant${controller.selectProduct.value}");
}
@ -92,7 +100,7 @@ class PendingGeneration extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text:"Transaction Type"),
TextView(text:"Transaction Type", isRequired: true),
SizedBox(height: 8),
CustomDropdown<String>(
backClr: AppColors.clrD9,
@ -101,13 +109,20 @@ class PendingGeneration extends StatelessWidget {
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
controller.selectTransactionType.value = selected;
print(
"selectTransactionType${controller.selectTransactionType.value}");
}
controller.selectTransactionTypePending.value = selected;
controller.showTransactionErrorPending.value = false; }
},
hintText: "Select Transaction Type",
),
Obx(() => controller.showTransactionErrorPending.value
? Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
'Please select Transaction Type',
style: TextStyle(color: Colors.red, fontSize: 12),
),
)
: SizedBox.shrink()),
],
),
),
@ -258,7 +273,16 @@ class PendingGeneration extends StatelessWidget {
text: AppStrings.submit,
clickAction: () {
controller.validateFieldsPending();
if (controller.showPlantErrorPending.value ||
controller.showProductErrorPending.value ||
controller.showTransactionErrorPending.value
) {
} else {
controller.postData();
}
},
),
],

View File

@ -41,7 +41,7 @@ class ViewFreightBill extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text: "Plant"),
TextView(text: "Plant", isRequired: true),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
@ -53,12 +53,23 @@ class ViewFreightBill extends StatelessWidget {
if (selected != null) {
controller.selectPlant.value =
selected.plantCode ?? "";
controller.showPlantErrorFreight.value = false;
print(
"selectPlant${controller.selectPlant.value}");
}
},
hintText: "Select Plant",
),
Obx(() =>
controller.showPlantErrorFreight.value
? Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
'Please select a plant',
style: TextStyle(color: Colors.red, fontSize: 12),
),
)
: SizedBox.shrink()),
],
),
),
@ -68,7 +79,7 @@ class ViewFreightBill extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text: "Product Name"),
TextView(text: "Product Name", isRequired: true),
SizedBox(height: 8),
CustomDropdown<dynamic>(
width: 250,
@ -81,7 +92,8 @@ class ViewFreightBill extends StatelessWidget {
if (selected != null) {
controller.selectProduct.value = selected;
print(
"selectPlant${controller.selectProduct.value}");
"selectPlant${controller.selectProduct
.value}");
}
},
hintText: "Select Product Name",
@ -95,7 +107,7 @@ class ViewFreightBill extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(text: "Transaction Type"),
TextView(text: "Transaction Type", isRequired: true),
SizedBox(height: 8),
CustomDropdown<String>(
backClr: AppColors.clrD9,
@ -105,12 +117,25 @@ class ViewFreightBill extends StatelessWidget {
onSelected: (selected) {
if (selected != null) {
controller.selectTransactionType.value = selected;
controller.showTransactionErrorFreight.value =
false;
print(
"selectTransactionType${controller.selectTransactionType.value}");
"selectTransactionType${controller
.selectTransactionType.value}");
}
},
hintText: "Select Transaction Type",
),
Obx(() =>
controller.showTransactionErrorFreight.value
? Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
'Please select Transaction Type',
style: TextStyle(color: Colors.red, fontSize: 12),
),
)
: SizedBox.shrink()),
],
),
),
@ -247,7 +272,20 @@ class ViewFreightBill extends StatelessWidget {
width: 100,
text: AppStrings.submit,
clickAction: () {
if (controller.showPlantErrorFreight
.value ||
controller.showProductErrorFreight
.value ||
controller.showTransactionErrorFreight
.value
) {
print(
'controller.showProductError.value ${controller
.showProductError.value}');
} else {
controller.postData();
}
},
),
],
@ -351,7 +389,8 @@ class ViewFreightBill extends StatelessWidget {
dataColumn(AppStrings.plant),
dataColumn(
AppStrings.productName,
onSort: (_, __) => controller.changeSort(
onSort: (_, __) =>
controller.changeSort(
AppStrings.productName.toLowerCase()),
),
dataColumn(AppStrings.freightBillNo),
@ -414,7 +453,8 @@ class ViewFreightBill extends StatelessWidget {
editableCell(index,
"${freightBill.trasnporterInvoiceNo}"),
editableCell(index,
"${freightBill.trasnporterInvoiceNoDate}"),
"${freightBill
.trasnporterInvoiceNoDate}"),
editableCell(
index, "${freightBill.billingQty}"),
editableCell(index, "${freightBill.uom}"),
@ -430,12 +470,14 @@ class ViewFreightBill extends StatelessWidget {
editableCell(
index, "${freightBill.freightAmount}"),
editableCell(index,
"${freightBill.trasnporterInvoiceNoDate}"),
"${freightBill
.trasnporterInvoiceNoDate}"),
editableCell(index, "${freightBill.status}"),
editableCell(
index, "${freightBill.totalGst}"),
editableCell(index,
"${freightBill.trasnporterInvoiceNoDate}"),
"${freightBill
.trasnporterInvoiceNoDate}"),
editableCell(index, "${freightBill.utr5No}"),
editableCell(
index, "${freightBill.utr1Date}"),
@ -490,8 +532,8 @@ class ViewFreightBill extends StatelessWidget {
);
}
void showFreightBillDetailsDialog(
BuildContext context, FreightBill freightBill) {
void showFreightBillDetailsDialog(BuildContext context,
FreightBill freightBill) {
showDialog(
context: context,
builder: (BuildContext context) {
@ -552,7 +594,8 @@ class ViewFreightBill extends StatelessWidget {
dataColumn(AppStrings.mrnNo),
dataColumn(
AppStrings.plantName,
onSort: (_, __) => controller.changeSort(
onSort: (_, __) =>
controller.changeSort(
AppStrings.productName.toLowerCase()),
),
dataColumn(AppStrings.product),

View File

@ -163,17 +163,22 @@ class _TransportViewState extends State<TransportView> {
style: 12.txtBoldWhite,
),
),
Obx(
() => Visibility(
visible: ctrl.selectedUser.value >= 1,
visible: ctrl.selectedUser.value == 0,
child: InkWell(
onTap: ctrl.toggleContainer,
child: Image.asset(AppImages.filter,
height: 16, width: 16)),
onTap: () {
ctrl.toggleFilter(); // Toggle visibility on tap
},
child: Image.asset(AppImages.filter, height: 16, width: 16),
),
),
Visibility(
visible: ctrl.selectedUser.value >= 1,
),
Obx(
() => Visibility(
visible: ctrl.selectedUser.value == 0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TextView(
@ -182,183 +187,14 @@ class _TransportViewState extends State<TransportView> {
),
),
),
],
),
),
Obx(
() => ctrl.isSelected.value
? Container(
margin: EdgeInsets.symmetric(vertical: 16),
padding: EdgeInsets.all(16),
color: AppColors.clrF2,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(
text: "Plant",
),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
borderClr: AppColors.clrGrey,
items: ctrl.plantList,
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
ctrl.selectedPlant.value = selected;
}
},
hintText: 'Select Plant'),
],
)),
SizedBox(width: 16),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(
text: "Freight Bill No.",
),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
borderClr: AppColors.clrGrey,
items: ctrl.freightBillList,
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
ctrl.selectedFreight.value =
selected;
}
},
hintText: 'Select Freight Number'),
],
)),
SizedBox(width: 16),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextView(
text: "Product Name",
),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
borderClr: AppColors.clrGrey,
items: ctrl.plantList,
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
ctrl.selectedPlant.value = selected;
}
},
hintText: 'Select Product'),
],
)),
],
),
SizedBox(height: 12),
Row(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
TextView(
text: "Plant",
),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
borderClr: AppColors.clrGrey,
items: ctrl.plantList,
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
ctrl.selectedPlant.value =
selected;
}
},
hintText: 'Select Product'),
],
)),
SizedBox(width: 16),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
TextView(
text: "Transaction Type",
),
SizedBox(height: 8),
CustomDropdown(
backClr: AppColors.clrD9,
borderClr: AppColors.clrGrey,
items: ctrl.plantList,
itemLabel: (item) => item,
onSelected: (selected) {
if (selected != null) {
ctrl.selectedPlant.value =
selected;
}
},
hintText: 'Select Product'),
],
)),
SizedBox(width: 16),
Expanded(
child: Column(
children: [
TextView(
text: "",
),
SizedBox(height: 8),
Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
CommonBtn(
bkClr: Colors.white,
text: AppStrings.cancel,
clickAction: () {
ctrl.isSelected.value = false;
},
),
SizedBox(width: 16),
CommonBtn(
text: AppStrings.submit,
style: 14.txtSBoldWhite,
clickAction: () {
ctrl.isSelected.value = false;
},
),
],
),
],
),
),
],
),
],
),
)
: SizedBox(),
),
Obx(() {
switch (ctrl.selectedUser.value) {
case 0:

View File

@ -20,13 +20,23 @@ class TransportController extends GetxController {
var selectProduct = ''.obs;
var selectLocation = ''.obs;
var selectTransactionType = ''.obs;
RxString selectPlantFreight = ''.obs;
var selectProductFreight = ''.obs;
var selectLocationFreight = ''.obs;
var selectTransactionTypeFreight = ''.obs;
RxString selectPlantPending = ''.obs;
var selectProductPending = ''.obs;
var selectLocationPending = ''.obs;
var selectTransactionTypePending = ''.obs;
var selectedItem = false.obs;
var grnDetails = <Content>[].obs;
var filterGrnDetails = <Content>[].obs;
var product = <Prodect>[].obs;
var plant = <Plant>[].obs;
var freightBill = [].obs;
var fromLocation = [].obs;
var grnList = [].obs;
RxBool showE = false.obs;
RxBool selectAllField = false.obs;
void toggleSelection(int index, bool? value) {
@ -34,6 +44,26 @@ class TransportController extends GetxController {
grnDetails.refresh();
}
void toggleSelectionFilter(int index, bool? value) {
filterGrnDetails[index].isSelected = value!;
filterGrnDetails.refresh();
}
RxBool isFilterVisible = false.obs;
final int initialRecordCount = 20;
// Validation variables
RxBool showPlantError = false.obs;
RxBool showProductError = false.obs;
RxBool showTransactionError = false.obs;
void toggleFilter() {
isFilterVisible.value = !isFilterVisible.value; // Toggle the value
if (!isFilterVisible.value) {
// Clear filters when hiding
clearFilters();
}
}
void selectAll(bool value) {
for (var item in grnDetails) {
item.isSelected = value;
@ -41,12 +71,48 @@ class TransportController extends GetxController {
selectAllField.value = value;
grnDetails.refresh();
}
void selectAllFilter(bool value) {
for (var item in filterGrnDetails) {
item.isSelected = value;
}
selectAllField.value = value;
filterGrnDetails.refresh();
}
RxBool showPlantErrorFreight = false.obs;
RxBool showProductErrorFreight = false.obs;
RxBool showTransactionErrorFreight = false.obs;
final selectProductValFreight = ''.obs;
RxBool showPlantErrorPending = false.obs;
RxBool showProductErrorPending = false.obs;
RxBool showTransactionErrorPending = false.obs;
final selectProductValPending = Rx<dynamic>(null);
void validateFields() {
showPlantError.value = selectPlant.value.isEmpty;
showTransactionError.value = selectTransactionType.value.isEmpty;
}
void validateFieldsPending() {
showPlantErrorPending.value = selectPlantPending.value.isEmpty;
showTransactionErrorPending.value =
selectTransactionTypePending.value.isEmpty;
showProductErrorPending.value = selectProductValPending.value == null;
}
void validateFieldsGenerateFreight() {
showPlantErrorFreight.value = selectPlantFreight.value.isEmpty;
showTransactionErrorFreight.value =
selectTransactionTypeFreight.value.isEmpty;
showProductErrorFreight.value = selectProductFreight.value.isEmpty;
}
@override
void onInit() {
getFreightBills();
viewFreightView();
grnPending();
postData();
super.onInit();
}
@ -104,6 +170,100 @@ class TransportController extends GetxController {
}
}
void displayFilteredData() async {
try {
isLoading.value = true;
// Construct requestBody to filter based on selected values
Map<String, String> requestBody = {
"plant": selectPlantFreight.value,
"productNane": selectProductFreight.value,
"transactionType": selectTransactionTypeFreight.value,
"fromLocation": selectLocation.value, // If required
"grnFromDate": "",
"grnToDate": ""
};
// Make the API call
var response = await PostRequests.addFreightBill(requestBody);
if (response != null) {
print("API Response: $response"); // Debug print the API response
List<Content> flattenedContent =
response.content!.expand((list) => list).toList();
print("Flattened content size: ${flattenedContent.length}");
print("Filter criteria: Plant: ${selectPlantFreight.value}, Product: ${selectProductFreight.value}, Transaction: ${selectTransactionTypeFreight.value}");
// Apply filters locally on the fetched data
List<Content> filteredData = flattenedContent.where((item) {
return (selectPlantFreight.value.isEmpty || item.plantCode == selectPlantFreight.value)
&&
(selectProductFreight.value.isEmpty || item.materialCode == selectProductFreight.value) &&
(selectTransactionTypeFreight.value.isEmpty || item.transporterCode == selectTransactionTypeFreight.value
);
}).toList();
print("Filtered Data: ${filteredData.length}");
filterGrnDetails.assignAll(filteredData);
print("✅ Filtered Data: ${filteredData.length} items displayed.");
} else {
print("❌ No response from API.");
}
} finally {
isLoading.value = false;
}
}
// void handleFilterSubmit() {
// validateFieldsGenerateFreight();
//
// if (showPlantError.value ||
// showProductError.value ||
// showTransactionError.value) {
// print('show errr');
// } else {
// postData();
// }
// }
void handleFilterSubmit() {
// Step 1: Validate input fields
validateFieldsGenerateFreight();
// Step 2: Check if any required field is empty
if (selectPlantFreight.value.isEmpty ||
selectProductFreight.value.isEmpty ||
selectTransactionTypeFreight.value.isEmpty
) {
print('⚠️ Required fields are empty. Showing filtered data instead of calling API.');
// TODO: Implement logic to show filtered data here
displayFilteredData();
} else {
// Step 3: If all fields are filled, proceed with API call
print('✅ All fields are valid. Calling API...');
// postData();
// displayFilteredData();
}
}
void clearFilters() {
selectPlantFreight.value = '';
selectProductFreight.value = '';
selectTransactionTypeFreight.value = '';
fromController.clear();
showPlantError.value = false;
showProductError.value = false;
showTransactionError.value = false;
postData(); // Reload initial data
}
getFreightBills() async {
try {
isLoading.value = true;
@ -161,9 +321,9 @@ class TransportController extends GetxController {
addFreightBill() async {
try {
grnListLoader.value = true;
final addDataFromgrnDetails = grnDetails.isEmpty ? filterGrnDetails : grnDetails;
// Filter the selected rows
final List<Map<String, dynamic>> selectedGrns = grnDetails
final List<Map<String, dynamic>> selectedGrns = addDataFromgrnDetails
.where((grn) => grn.isSelected) // Get only the selected rows
.map((grn) => {
"grn_id": grn.grnId,
@ -206,6 +366,7 @@ class TransportController extends GetxController {
var pageSize = 2.obs;
var sortField = "grn_date".obs;
var sortDirection = "desc".obs;
// viewFreightView({int? page, String? sort, String? direction}) async {
// try {
// freightViewLoader.value = true;
@ -244,6 +405,7 @@ class TransportController extends GetxController {
RxInt currentPage = 1.obs;
RxInt totalPages = 3.obs;
final int limit = 10;
viewFreightView() async {
try {
freightViewLoader.value = true;
@ -310,6 +472,7 @@ class TransportController extends GetxController {
}
var grnPendingData = <GrnPending>[].obs;
grnPending() async {
try {
grnPendingLoader.value = true;

View File

@ -305,5 +305,5 @@ packages:
source: hosted
version: "1.1.0"
sdks:
dart: ">=3.6.1 <4.0.0"
dart: ">=3.6.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"

View File

@ -19,7 +19,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ^3.6.1
sdk: ^3.6.0
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions