feat : search and filter

This commit is contained in:
2025-09-17 14:20:35 +03:30
parent e933d22f8f
commit 3811cb6ca0
9 changed files with 181 additions and 69 deletions

View File

@@ -86,4 +86,9 @@ abstract class PoultryScienceRemoteDatasource {
required String token, required String token,
Map<String, dynamic>? queryParameters, Map<String, dynamic>? queryParameters,
}); });
Future<void> deletePoultryOder({
required String token,
required String orderId,
});
} }

View File

@@ -223,14 +223,20 @@ class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasourc
queryParameters: queryParameters, queryParameters: queryParameters,
fromJson: (json) => PaginationModel<PoultryOrder>.fromJson( fromJson: (json) => PaginationModel<PoultryOrder>.fromJson(
json, json,
(data) => PoultryOrder.fromJson(data as Map<String, dynamic>), (data) => PoultryOrder.fromJson(data as Map<String, dynamic>),
), ),
); );
dLog(res.data.runtimeType);
return res.data; return res.data;
} }
@override
Future<void> deletePoultryOder({required String token, required String orderId}) async {
await _httpClient.delete(
'/Poultry_Request/$orderId/',
headers: {'Authorization': 'Bearer $token'},
);
}
//endregion //endregion
} }

View File

@@ -84,5 +84,8 @@ abstract class PoultryScienceRepository {
required String token, required String token,
Map<String, dynamic>? queryParameters, Map<String, dynamic>? queryParameters,
}); });
Future<void> deletePoultryOder({
required String token,
required String orderId,
});
} }

View File

@@ -134,4 +134,12 @@ class PoultryScienceRepositoryImp implements PoultryScienceRepository {
}) async { }) async {
return await datasource.getPoultryOderList(token: token, queryParameters: queryParameters); return await datasource.getPoultryOderList(token: token, queryParameters: queryParameters);
} }
@override
Future<void> deletePoultryOder({
required String token,
required String orderId,
}) async {
await datasource.deletePoultryOder(token: token, orderId: orderId);
}
} }

View File

@@ -16,12 +16,10 @@ class GenocideLogic extends GetxController {
final RxBool isLoadingMore = false.obs; final RxBool isLoadingMore = false.obs;
Rx<Jalali> fromDateFilter = Jalali final RxBool isLoadingDelete = false.obs;
.now()
.obs; Rx<Jalali> fromDateFilter = Jalali.now().obs;
Rx<Jalali> toDateFilter = Jalali Rx<Jalali> toDateFilter = Jalali.now().obs;
.now()
.obs;
RxnString searchedValue = RxnString(); RxnString searchedValue = RxnString();
/* final RxBool isLoadingMoreAllocationsMade = false.obs; /* final RxBool isLoadingMoreAllocationsMade = false.obs;
@@ -52,20 +50,19 @@ class GenocideLogic extends GetxController {
currentPage.value = 1; currentPage.value = 1;
} }
await safeCall( await safeCall(
call: () => call: () async => await rootLogic.poultryRepository.getPoultryOderList(
rootLogic.poultryRepository.getPoultryOderList( token: rootLogic.tokenService.accessToken.value!,
token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams(
queryParameters: buildQueryParams( pageSize: 20,
pageSize: 20, page: currentPage.value,
page: currentPage.value, search: 'filter',
search: 'filter', role: gService.getRole(Module.chicken),
role: gService.getRole(Module.chicken), value: searchedValue.value,
value: searchedValue.value, fromDate: fromDateFilter.value.toDateTime(),
fromDate: fromDateFilter.value.toDateTime(), toDate: toDateFilter.value.toDateTime(),
toDate: toDateFilter.value.toDateTime(), queryParams: {'today': null},
queryParams: {'today': null} ),
), ),
),
onSuccess: (res) async { onSuccess: (res) async {
await Future.delayed(Duration(milliseconds: 500)); await Future.delayed(Duration(milliseconds: 500));
if ((res?.count ?? 0) == 0) { if ((res?.count ?? 0) == 0) {
@@ -83,4 +80,19 @@ class GenocideLogic extends GetxController {
}, },
); );
} }
Future<void> deletePoultryOrder(int id) async {
isExpandedList.clear();
await safeCall(
call: () async => await rootLogic.poultryRepository.deletePoultryOder(
token: rootLogic.tokenService.accessToken.value!,
orderId: id.toString(),
),
onSuccess: (_) {
defaultShowSuccessMessage('درخواست با موفقیت حذف شد');
},
);
}
} }

View File

@@ -3,6 +3,7 @@ import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_orde
import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.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 'package:rasadyar_core/core.dart';
import 'logic.dart'; import 'logic.dart';
@@ -14,8 +15,13 @@ class GenocidePage extends GetView<GenocideLogic> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BasePage( return BasePage(
routes: controller.routes, routes: controller.routes,
hasSearch: false, hasSearch: true,
hasFilter: false, hasFilter: true,
onSearchChanged: (data) {
controller.searchedValue.value = data;
controller.getPoultryOrderList();
},
filteringWidget: filterBottomSheet(),
onBackPressed: () => Get.back(id: poultryFirstKey), onBackPressed: () => Get.back(id: poultryFirstKey),
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat, floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
floatingActionButton: RFab.add( floatingActionButton: RFab.add(
@@ -128,8 +134,41 @@ class GenocidePage extends GetView<GenocideLogic> {
buildRow(title: 'میانگین وزنی', value: '${(item.indexWeight)} (کیلوگرم)'), buildRow(title: 'میانگین وزنی', value: '${(item.indexWeight)} (کیلوگرم)'),
buildRow(title: 'قیمت مرغدار', value: '${item.amount.separatedByComma} (ریال)'), buildRow(title: 'قیمت مرغدار', value: '${item.amount.separatedByComma} (ریال)'),
buildRow(title: 'مانده در سالن ', value: '${item.hatching?.leftOver.separatedByComma ?? 0} (قطعه)'), buildRow(
title: 'مانده در سالن ',
value: '${item.hatching?.leftOver.separatedByComma ?? 0} (قطعه)',
),
buildRow(title: ' وضعیت', value: getState(item)), buildRow(title: ' وضعیت', value: getState(item)),
Visibility(
visible: item.stateProcess == 'pending',
child: ObxValue((data) {
return ROutlinedElevatedIcon(
height: 40.h,
width: Get.width,
text: 'حذف',
icon: Assets.vec.trashSvg.svg(
width: 16.w,
height: 16.h,
colorFilter: ColorFilter.mode(AppColor.error, BlendMode.srcIn),
),
textStyle: AppFonts.yekan16Bold.copyWith(color: AppColor.error),
borderColor: AppColor.error,
foregroundColor: AppColor.error,
pressedBackgroundColor: AppColor.error,
onPressed: data.value
? null
: () => _buildDeleteDialog(
onConfirm: () async {
Get.back();
await controller.deletePoultryOrder(item.id!);
controller.getPoultryOrderList();
},
),
);
}, controller.isLoadingDelete),
),
], ],
), ),
); );
@@ -191,32 +230,63 @@ class GenocidePage extends GetView<GenocideLogic> {
], ],
); );
} }
}
String getRequestType(PoultryOrder item) { String getRequestType(PoultryOrder item) {
if (item.market ?? false) { if (item.market ?? false) {
return 'پنل معاملات'; return 'پنل معاملات';
} else if (item.union ?? false) { } else if (item.union ?? false) {
return 'اتحادیه'; return 'اتحادیه';
} else { } else {
return 'خرید مستقیم'; return 'خرید مستقیم';
}
} }
}
String getKillType(PoultryOrder item) { String getKillType(PoultryOrder item) {
if (item.export ?? false) { if (item.export ?? false) {
return 'صادرات'; return 'صادرات';
} else if (item.freezing ?? false) { } else if (item.freezing ?? false) {
return 'انجماد'; return 'انجماد';
} else { } else {
return 'عادی'; return 'عادی';
}
} }
}
String getState(PoultryOrder item) { String getState(PoultryOrder item) {
if (item.stateProcess == 'pending') { if (item.stateProcess == 'pending') {
return 'در انتظار تایید'; return 'در انتظار تایید';
} else { } else {
return 'تایید شده'; return 'تایید شده';
}
} }
}
void _buildDeleteDialog({required VoidCallback onConfirm}) {
Get.defaultDialog(
title: 'حذف درخواست کشتار',
middleText: 'آیا از حذف این درخواست کشتار مطمئن هستید؟',
confirm: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: AppColor.error,
foregroundColor: Colors.white,
),
onPressed: onConfirm,
child: Text('بله'),
),
cancel: ElevatedButton(
onPressed: () {
Get.back();
},
child: Text('خیر'),
),
);
}
Widget filterBottomSheet() => filterBottomSheetWidget(
fromDate: controller.fromDateFilter,
onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali,
toDate: controller.toDateFilter,
onChangedToDate: (jalali) => controller.toDateFilter.value = jalali,
onSubmit: () => controller.getPoultryOrderList(),
);
}

View File

@@ -349,9 +349,14 @@ class KillingRegistrationLogic extends GetxController {
onSuccess: (result) async { onSuccess: (result) async {
defaultShowSuccessMessage( defaultShowSuccessMessage(
'ثبت با موفقیت انجام شد', 'ثبت با موفقیت انجام شد',
onDismissed: () { durationInSeconds: 2,
Get.back(id: poultryFirstKey); onDismissed: () async {
fLog('Kill Registration onDismissed');
Future.delayed(Duration(milliseconds: 300), () {
Get.back(id: poultryFirstKey);
});
}, },
); );
}, },
onError: (error, stackTrace) {}, onError: (error, stackTrace) {},

View File

@@ -9,7 +9,10 @@ GestureDetector dateFilterWidget({
}) { }) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
Get.bottomSheet(modalDatePicker(onDateSelected: (value) => onChanged(value))); Get.bottomSheet(modalDatePicker(onDateSelected: (value) {
date = value.obs;
onChanged(value);
}));
}, },
child: Container( child: Container(
height: 35, height: 35,

View File

@@ -22,14 +22,14 @@ class ROutlinedElevatedIcon extends StatefulWidget {
final VoidCallback? onPressed; final VoidCallback? onPressed;
final double width; final double width;
final double height; final double height;
Color? foregroundColor; final Color? foregroundColor;
Color? backgroundColor; final Color? backgroundColor;
Color? borderColor; final Color? borderColor;
Color? disabledBackgroundColor; final Color? disabledBackgroundColor;
Color? pressedBackgroundColor; final Color? pressedBackgroundColor;
double? radius; final double? radius;
TextStyle? textStyle; final TextStyle? textStyle;
Widget? icon; final Widget? icon;
@override @override
State<ROutlinedElevatedIcon> createState() => _ROutlinedElevatedIconState(); State<ROutlinedElevatedIcon> createState() => _ROutlinedElevatedIconState();
@@ -40,7 +40,6 @@ class _ROutlinedElevatedIconState extends State<ROutlinedElevatedIcon> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return OutlinedButton.icon( return OutlinedButton.icon(
icon: widget.icon, icon: widget.icon,
label: Text(widget.text), label: Text(widget.text),
onPressed: widget.onPressed, onPressed: widget.onPressed,
style: ButtonStyle( style: ButtonStyle(
@@ -91,11 +90,9 @@ class _ROutlinedElevatedIconState extends State<ROutlinedElevatedIcon> {
if (states.contains(WidgetState.pressed)) { if (states.contains(WidgetState.pressed)) {
return Colors.white; return Colors.white;
} else if (states.contains(WidgetState.disabled)) { } else if (states.contains(WidgetState.disabled)) {
return widget.foregroundColor?.disabledColor ?? return widget.foregroundColor?.disabledColor ?? AppColor.blueNormal.withAlpha(38);
AppColor.blueNormal.withAlpha(38);
} else if (states.contains(WidgetState.hovered)) { } else if (states.contains(WidgetState.hovered)) {
return widget.foregroundColor?.hoverColor ?? return widget.foregroundColor?.hoverColor ?? AppColor.blueNormal.withAlpha(50);
AppColor.blueNormal.withAlpha(50);
} }
return widget.foregroundColor ?? AppColor.blueNormal; return widget.foregroundColor ?? AppColor.blueNormal;
}), }),
@@ -106,10 +103,13 @@ class _ROutlinedElevatedIconState extends State<ROutlinedElevatedIcon> {
), ),
fixedSize: WidgetStatePropertyAll(Size(widget.width, widget.height)), fixedSize: WidgetStatePropertyAll(Size(widget.width, widget.height)),
padding: WidgetStatePropertyAll(EdgeInsets.zero), padding: WidgetStatePropertyAll(EdgeInsets.zero),
textStyle: WidgetStatePropertyAll( textStyle: WidgetStateProperty.resolveWith<TextStyle?>((states) {
widget.textStyle ?? if (states.contains(WidgetState.pressed)) {
AppFonts.yekan24.copyWith(color: AppColor.blueNormal), return widget.textStyle?.copyWith(color: Colors.white) ??
), AppFonts.yekan18.copyWith(color: Colors.white);
}
return widget.textStyle ?? AppFonts.yekan18.copyWith(color: AppColor.blueNormal);
}),
), ),
); );
} }