Files
rasadyar_application/packages/chicken/lib/presentation/pages/steward/segmentation/view.dart
2025-10-07 14:21:09 +03:30

495 lines
18 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart';
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart';
import 'package:rasadyar_core/core.dart';
import 'logic.dart';
class SegmentationPage extends GetView<SegmentationLogic> {
@override
Widget build(BuildContext context) {
return ChickenBasePage(
routes: controller.routesName,
onSearchChanged: (data) => controller.setSearchValue(data),
onFilterTap: () {
Get.bottomSheet(filterBottomSheet());
},
onRefresh: controller.onRefresh,
hasBack: false,
child: Stack(
children: [
Positioned.fill(
child: ObxValue((data) {
return RPaginatedListView(
onLoadMore: () async => controller.getAllSegmentation(true),
hasMore: data.value.data?.next != null,
listType: ListType.separated,
resource: data.value,
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
itemBuilder: (context, index) {
var item = data.value.data!.results![index];
return ObxValue((val) {
return ExpandableListItem2(
selected: val.contains(index),
onTap: () => controller.isExpandedList.toggle(index),
index: index,
child: itemListWidget(item),
secondChild: itemListExpandedWidget(item, index),
labelColor: AppColor.blueLight,
labelIconColor: AppColor.customGrey,
labelIcon: Assets.vec.convertCubeSvg.path,
);
}, controller.isExpandedList);
},
itemCount: data.value.data?.results?.length ?? 0,
separatorBuilder: (context, index) => SizedBox(height: 8.h),
);
}, controller.segmentationList),
),
Positioned(
right: 10,
bottom: 90.h,
child: RFab.add(
onPressed: () {
Get.bottomSheet(
addOrEditBottomSheet(),
isScrollControlled: true,
ignoreSafeArea: false,
).whenComplete(() {
controller.clearForm();
//defaultShowSuccessMessage('با موفقیت ثبت شد');
});
},
),
),
],
),
);
}
Widget filterBottomSheet() => filterBottomSheetWidget(
fromDate: controller.fromDateFilter,
onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali,
toDate: controller.toDateFilter,
onChangedToDate: (jalali) => controller.toDateFilter.value = jalali,
onSubmit: () => controller.getAllSegmentation(),
);
itemListWidget(SegmentationModel item) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(width: 12),
Expanded(
flex: 3,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 4,
children: [
Text(
item.toGuild != null ? 'مباشر' : 'قطعه‌بند',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
Text(
item.date?.formattedJalaliDate ?? 'N/A',
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
],
),
),
SizedBox(width: 4),
Expanded(
flex: 5,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
item.toGuild != null
? item.toGuild?.user?.fullname ?? 'N/A'
: item.buyer?.fullname ?? 'N/A',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
SizedBox(height: 2),
Text(
item.toGuild != null
? item.toGuild?.guildsName ?? 'N/A'
: item.buyer?.shop ?? 'N/A',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
],
),
),
SizedBox(width: 4),
Expanded(
flex: 2,
child: Text(
'${item.weight.separatedByCommaFa} KG',
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
),
],
);
}
itemListExpandedWidget(SegmentationModel item, int index) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column(
spacing: 8,
children: [
Container(
height: 32,
padding: EdgeInsets.symmetric(horizontal: 8),
decoration: ShapeDecoration(
color: AppColor.blueLight,
shape: RoundedRectangleBorder(
side: BorderSide(width: 1, color: AppColor.blueLightHover),
borderRadius: BorderRadius.circular(8),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
spacing: 3,
children: [
Text(
DateTimeExtensions(item.date)?.toJalali().formatter.wN ?? 'N/A',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
Text(
'${DateTimeExtensions(item.date)?.toJalali().formatter.d} ${DateTimeExtensions(item.date)?.toJalali().formatter.mN ?? 'N/A'}',
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
],
),
Text(
'${DateTimeExtensions(item.date)?.toJalali().formatter.y}',
style: AppFonts.yekan20.copyWith(color: AppColor.textColor),
),
Text(
'${DateTimeExtensions(item.date)?.toJalali().formatter.tHH}:${DateTimeExtensions(item.date)?.toJalali().formatter.tMM ?? 'N/A'}',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
],
),
),
buildRow(
title: 'مشخصات خریدار',
value: item.toGuild != null
? item.toGuild?.user?.fullname ?? 'N/A'
: item.buyer?.fullname ?? 'N/A',
),
buildRow(
title: 'تلفن خریدار',
value: item.toGuild != null
? item.toGuild?.user?.mobile ?? 'N/A'
: item.buyer?.mobile ?? 'N/A',
),
buildRow(
title: 'نام واحد',
value: item.toGuild != null
? item.toGuild?.guildsName ?? 'N/A'
: item.buyer?.shop ?? 'N/A',
),
buildRow(title: 'ماهیت', value: item.toGuild != null ? 'مباشر' : 'قطعه‌بند'),
buildRow(title: 'وزن قطعه‌بندی', value: '${item.weight?.separatedByCommaFa}'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 16.w,
children: [
RElevated(
text: 'ویرایش',
width: 150.w,
height: 40.h,
onPressed: () {
controller.setEditData(item);
Get.bottomSheet(
addOrEditBottomSheet(true),
isScrollControlled: true,
ignoreSafeArea: false,
).whenComplete(() {
controller.clearForm();
});
},
textStyle: AppFonts.yekan20.copyWith(color: Colors.white),
backgroundColor: AppColor.greenNormal,
),
ROutlinedElevated(
text: 'حذف',
textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal),
width: 150.w,
height: 40.h,
onPressed: () {
buildDeleteDialog(
onConfirm: () async {
controller.isExpandedList.remove(index);
controller.deleteSegmentation(item.key!);
},
onRefresh: () => controller.getAllSegmentation(),
);
},
borderColor: AppColor.redNormal,
),
],
),
],
),
);
}
Widget addOrEditBottomSheet([bool isOnEdit = false]) {
return BaseBottomSheet(
height: 480.h,
child: SingleChildScrollView(
child: Form(
key: controller.formKey,
child: Column(
spacing: 16,
children: [
Text(
isOnEdit ? 'ویرایش قطعه‌بندی' : 'افزودن قطعه‌بندی',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
),
_productDropDown(),
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
child: Column(
children: [
const SizedBox(height: 8),
SizedBox(
height: 40,
child: ObxValue((data) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Radio(
value: 1,
groupValue: controller.segmentType.value,
onChanged: (value) {
controller.segmentType.value = value!;
controller.selectedGuildModel.value = null;
controller.selectedGuildModel.refresh();
},
),
Text('قطعه‌بندی(کاربر)', style: AppFonts.yekan14),
SizedBox(width: 12),
Radio(
value: 2,
groupValue: controller.segmentType.value,
onChanged: (value) {
controller.segmentType.value = value!;
},
),
Text('تخصیص به قطعه‌بند', style: AppFonts.yekan14),
],
);
}, controller.saleType),
),
const SizedBox(height: 12),
ObxValue((data) {
return Visibility(visible: data.value == 2, child: guildsDropDown());
}, controller.segmentType),
],
),
),
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
child: Column(
children: [
const SizedBox(height: 8),
SizedBox(
height: 40,
child: ObxValue((data) {
return RadioGroup(
onChanged: (value) {
controller.saleType.value = value ?? 0;
controller.selectedGuildModel.value = null;
controller.selectedGuildModel.refresh();
},
groupValue: controller.saleType.value,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Radio(value: 1),
Text('فروش دولتی', style: AppFonts.yekan14),
SizedBox(width: 12),
Radio(value: 2),
Text('فروش آزاد', style: AppFonts.yekan14),
],
),
);
}, controller.saleType),
),
const SizedBox(height: 12),
SizedBox(
height: 40,
child: ObxValue((data) {
return RadioGroup(
onChanged: (value) {
controller.quotaType.value = value ?? 0;
},
groupValue: controller.quotaType.value,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Radio(value: 1),
Text('انبار دولتی', style: AppFonts.yekan14),
SizedBox(width: 12),
Radio(value: 2),
Text('انبار آزاد', style: AppFonts.yekan14),
],
),
);
}, controller.saleType),
),
],
),
),
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
child: Column(
spacing: 12,
children: [
UnitTextField(
hint: 'وزن',
unit: 'کیلوگرم',
controller: controller.weightController,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
],
validator: (value) {
if (value == null) {
return 'لطفاً وزن لاشه را وارد کنید';
}
return null;
},
),
submitButtonWidget(isOnEdit),
],
),
),
SizedBox(),
],
),
),
),
);
}
Widget submitButtonWidget(bool isOnEdit) {
return ObxValue((data) {
return RElevated(
isFullWidth: true,
backgroundColor: AppColor.greenNormal,
text: isOnEdit ? 'ویرایش' : 'ثبت',
onPressed: data.value
? () async {
var res = isOnEdit
? await controller.editSegment()
: await controller.createSegment();
if (res) {
await controller.getAllSegmentation();
controller.clearForm();
Get.back();
}
}
: null,
height: 40,
);
}, controller.isSubmitButtonEnabled);
}
Widget _productDropDown() {
return Obx(() {
return OverlayDropdownWidget<ProductModel>(
items: controller.rootLogic.rolesProductsModel,
height: 56,
hasDropIcon: false,
background: Colors.white,
onChanged: (value) {
controller.selectedProduct.value = value;
},
selectedItem: controller.selectedProduct.value,
initialValue: controller.selectedProduct.value,
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
labelBuilder: (item) => Row(
spacing: 8,
children: [
(item?.name?.contains('مرغ گرم') ?? false)
? Assets.images.chicken.image(width: 40, height: 40)
: Assets.vec.placeHolderSvg.svg(width: 40, height: 40),
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی: ${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0} کیلوگرم',
),
],
),
);
});
}
Widget guildsDropDown() {
return Obx(() {
final item = controller.selectedGuildModel.value;
return OverlayDropdownWidget<GuildModel>(
key: ValueKey(item?.user?.fullname ?? ''),
items: controller.guildsModel,
onChanged: (value) {
controller.selectedGuildModel.value = value;
},
selectedItem: item,
itemBuilder: (item) => Text(
item.user != null
? '${item.steward == true ? 'مباشر' : 'صنف'} ${item.user!.fullname} (${item.user!.mobile})'
: 'بدون نام',
),
labelBuilder: (item) => Text(
item?.user != null
? '${item?.steward == true ? 'مباشر' : 'صنف'} ${item?.user!.fullname} (${item?.user!.mobile})'
: 'انتخاب مباشر/صنف',
),
);
});
}
}