refactor : rename files and update routes for poultry actions

feat : poultry kill registration and poultry OrderList

** Made With Nima **
This commit is contained in:
2025-09-16 15:47:35 +03:30
parent 87a0955697
commit e933d22f8f
81 changed files with 22780 additions and 192 deletions

View File

@@ -1,12 +1,13 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/di/chicken_di.dart';
import 'package:rasadyar_chicken/data/models/request/change_password/change_password_request_model.dart';
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/root/logic.dart';
import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart';
import 'package:rasadyar_core/core.dart';
class ProfileLogic extends GetxController {
StewardRootLogic rootLogic = Get.find<StewardRootLogic>();
ChickenRepository chickenRepository = diChicken.get<ChickenRepository>();
GService gService = Get.find<GService>();
TokenStorageService tokenService = Get.find<TokenStorageService>();
RxInt selectedInformationType = 0.obs;
@@ -78,9 +79,8 @@ class ProfileLogic extends GetxController {
Future<void> getUserProfile() async {
userProfile.value = Resource.loading();
await safeCall<UserProfile?>(
call: () async => await rootLogic.chickenRepository.getUserProfile(
token: rootLogic.tokenService.accessToken.value!,
),
call: () async =>
await chickenRepository.getUserProfile(token: tokenService.accessToken.value!),
onSuccess: (result) {
if (result != null) {
userProfile.value = Resource.success(result);
@@ -92,8 +92,7 @@ class ProfileLogic extends GetxController {
Future<void> getCites() async {
await safeCall(
call: () =>
rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''),
call: () => chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''),
onSuccess: (result) {
if (result != null && result.isNotEmpty) {
cites.value = result;
@@ -115,8 +114,8 @@ class ProfileLogic extends GetxController {
);
isOnLoading.value = true;
await safeCall(
call: () async => await rootLogic.chickenRepository.updateUserProfile(
token: rootLogic.tokenService.accessToken.value!,
call: () async => await chickenRepository.updateUserProfile(
token: tokenService.accessToken.value!,
userProfile: userProfile,
),
onSuccess: (result) {
@@ -136,8 +135,8 @@ class ProfileLogic extends GetxController {
);
await safeCall(
call: () async => await rootLogic.chickenRepository.updatePassword(
token: rootLogic.tokenService.accessToken.value!,
call: () async => await chickenRepository.updatePassword(
token: tokenService.accessToken.value!,
model: model,
),
);
@@ -147,7 +146,7 @@ class ProfileLogic extends GetxController {
Future<void> getUserRole() async {
userLocal.value = Resource.loading();
await safeCall<UserLocalModel?>(
call: () async => rootLogic.tokenService.getUserLocal(Module.chicken),
call: () async => tokenService.getUserLocal(Module.chicken),
onSuccess: (result) {
if (result != null) {
userLocal.value = Resource.success(result);
@@ -164,7 +163,8 @@ class ProfileLogic extends GetxController {
}
Future<void> changeUserRole(String newRole) async {
await gService.saveSelectedRole(Module.chicken, newRole);
dLog(newRole);
await gService.saveRoute(Module.chicken, newRole);
Get.offAllNamed(newRole);
}

View File

@@ -4,7 +4,6 @@ import 'package:flutter/cupertino.dart' hide Image;
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/common/fa_user_role.dart';
import 'package:rasadyar_chicken/data/di/chicken_di.dart';
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart';
import 'package:rasadyar_core/core.dart';
@@ -461,33 +460,6 @@ class ProfilePage extends GetView<ProfileLogic> {
);
}
Widget _provinceWidget() {
return Obx(() {
return OverlayDropdownWidget<IranProvinceCityModel>(
items: controller.rootLogic.provinces,
onChanged: (value) {
controller.selectedProvince.value = value;
},
selectedItem: controller.selectedProvince.value,
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
labelBuilder: (item) => Text(item?.name ?? 'انتخاب استان'),
);
});
}
Widget _cityWidget() {
return ObxValue((data) {
return OverlayDropdownWidget<IranProvinceCityModel>(
items: data,
onChanged: (value) {
controller.selectedCity.value = value;
},
selectedItem: controller.selectedCity.value,
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
labelBuilder: (item) => Text(item?.name ?? 'انتخاب شهر'),
);
}, controller.cites);
}
Widget changePasswordBottomSheet() {
return BaseBottomSheet(
@@ -616,7 +588,7 @@ class ProfilePage extends GetView<ProfileLogic> {
backgroundColor: AppColor.error,
onPressed: () async {
await Future.wait([
controller.rootLogic.tokenService.deleteModuleTokens(Module.chicken),
controller.tokenService.deleteModuleTokens(Module.chicken),
controller.gService.clearSelectedModule(),
]).then((value) async {
await removeChickenDI();
@@ -660,7 +632,7 @@ class ProfilePage extends GetView<ProfileLogic> {
Map tmpRole = getFaUserRoleWithOnTap(item?[index]);
return CustomChip(
isSelected:
controller.gService.getSelectedRole(Module.chicken) == tmpRole.values.first,
controller.gService.getRoute(Module.chicken) == tmpRole.values.first,
title: tmpRole.keys.first,
index: index,
onTap: (int p1) {

View File

@@ -42,10 +42,15 @@ class RolePage extends GetView<RoleLogic> {
title: role.keys.first,
onTap: () async {
String route = role.values.first;
await controller.gService.saveSelectedRole(
await controller.gService.saveRoute(
Module.chicken,
route,
);
await controller.gService.saveRole(
Module.chicken,
data[index],
);
Get.offAllNamed(route);
},
);

View File

@@ -3,6 +3,7 @@ import 'package:get/get.dart';
import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart';
import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/active_hatching/logic.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_core/presentation/widget/list_item/list_item2.dart';
@@ -17,7 +18,7 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
hasSearch: false,
hasFilter: false,
routes: controller.routesName,
onBackPressed: () => Get.back(id: 0),
onBackPressed: () => Get.back(id: poultryFirstKey),
widgets: [
hatchingWidget()
],
@@ -127,11 +128,11 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
buildRow(title: 'شماره مجوز جوجه ریزی', value: item.licenceNumber ?? 'N/A'),
buildRow(
title: 'حجم جوجه ریزی',
value: item.quantity.separatedByComma,
value: item.quantity.separatedByCommaFa,
valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
buildRow(title: 'مانده در سالن', value: item.leftOver.separatedByComma),
buildRow(title: 'تلفات', value: item.losses.separatedByComma),
buildRow(title: 'مانده در سالن', value: item.leftOver.separatedByCommaFa),
buildRow(title: 'تلفات', value: item.losses.separatedByCommaFa),
buildRow(
title: 'دامپزشک فارم',
value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/response/poultry/poultry_farm.dart';
import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/home/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
import 'package:rasadyar_core/core.dart';

View File

@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/response/poultry/poultry_farm.dart';
import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_core/core.dart';
@@ -14,7 +16,7 @@ class FarmPage extends GetView<FarmLogic> {
routes: controller.routes,
hasFilter: false,
hasSearch: false,
onBackPressed: () => Get.back(id: 0),
onBackPressed: () => Get.back(id: poultryFirstKey),
widgets: [firstTagInformation(), farmListWidget()],
);
}
@@ -131,7 +133,7 @@ class FarmPage extends GetView<FarmLogic> {
title: 'دامپزشک فارم',
value: '${item.vetFarm?.fullName ?? '-'} (${item.vetFarm?.mobile ?? '-'})',
),
buildRow(title: 'ظرفیت فارم', value: item.totalCapacity.separatedByComma),
buildRow(title: 'ظرفیت فارم', value: item.totalCapacity.separatedByCommaFa),
buildRow(
title: 'جوجه ریزی فعال (تعداد دوره) ',
value:

View File

@@ -0,0 +1,86 @@
import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
import 'package:rasadyar_core/core.dart';
class GenocideLogic extends GetxController {
List<String> routes = ['اقدام', 'درخواست کشتارها'];
var tokenService = Get.find<TokenStorageService>();
var gService = Get.find<GService>();
var rootLogic = Get.find<PoultryScienceRootLogic>();
Rx<Resource<PaginationModel<PoultryOrder>>> poultryOrderList =
Resource<PaginationModel<PoultryOrder>>.loading().obs;
RxList<int> isExpandedList = <int>[].obs;
final RxInt currentPage = 1.obs;
final RxBool isLoadingMore = false.obs;
Rx<Jalali> fromDateFilter = Jalali
.now()
.obs;
Rx<Jalali> toDateFilter = Jalali
.now()
.obs;
RxnString searchedValue = RxnString();
/* final RxBool isLoadingMoreAllocationsMade = false.obs;
final RxBool isOnLoadingSubmitOrEdit = false.obs;*/
@override
void onReady() {
super.onReady();
getPoultryOrderList();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
}
Future<void> getPoultryOrderList([bool loadingMore = false]) async {
if (loadingMore) {
isLoadingMore.value = true;
} else {
poultryOrderList.value = Resource<PaginationModel<PoultryOrder>>.loading();
}
if (searchedValue.value != null &&
searchedValue.value!.trim().isNotEmpty &&
currentPage.value > 1) {
currentPage.value = 1;
}
await safeCall(
call: () =>
rootLogic.poultryRepository.getPoultryOderList(
token: rootLogic.tokenService.accessToken.value!,
queryParameters: buildQueryParams(
pageSize: 20,
page: currentPage.value,
search: 'filter',
role: gService.getRole(Module.chicken),
value: searchedValue.value,
fromDate: fromDateFilter.value.toDateTime(),
toDate: toDateFilter.value.toDateTime(),
queryParams: {'today': null}
),
),
onSuccess: (res) async {
await Future.delayed(Duration(milliseconds: 500));
if ((res?.count ?? 0) == 0) {
poultryOrderList.value = Resource<PaginationModel<PoultryOrder>>.empty();
} else {
poultryOrderList.value = Resource<PaginationModel<PoultryOrder>>.success(
PaginationModel<PoultryOrder>(
count: res?.count ?? 0,
next: res?.next,
previous: res?.previous,
results: [...(poultryOrderList.value.data?.results ?? []), ...(res?.results ?? [])],
),
);
}
},
);
}
}

View File

@@ -0,0 +1,222 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart';
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_core/core.dart';
import 'logic.dart';
class GenocidePage extends GetView<GenocideLogic> {
const GenocidePage({super.key});
@override
Widget build(BuildContext context) {
return BasePage(
routes: controller.routes,
hasSearch: false,
hasFilter: false,
onBackPressed: () => Get.back(id: poultryFirstKey),
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
floatingActionButton: RFab.add(
onPressed: () {
Get.toNamed(ChickenRoutes.killingRegistrationPoultryScience, id: poultryFirstKey);
},
),
widgets: [poultryOrderListWidget()],
);
}
Widget poultryOrderListWidget() {
return Expanded(
child: ObxValue((data) {
return RPaginatedListView(
listType: ListType.separated,
resource: data.value,
hasMore: data.value.data?.next != null,
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),
labelColor: AppColor.blueLight,
labelIcon: Assets.vec.cubeScanSvg.path,
);
}, controller.isExpandedList);
},
itemCount: data.value.data?.results?.length ?? 0,
separatorBuilder: (context, index) => SizedBox(height: 8.h),
onLoadMore: () async => controller.getPoultryOrderList(true),
onRefresh: () async {
controller.currentPage.value = 1;
await controller.getPoultryOrderList();
},
);
}, controller.poultryOrderList),
);
}
Container itemListExpandedWidget(PoultryOrder item) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column(
spacing: 8,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
item.poultry?.unitName ?? 'N/A',
textAlign: TextAlign.center,
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
),
Spacer(),
Visibility(
child: Text(
'${item.poultry?.address?.province?.name} / ${item.poultry?.address?.city?.name}',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
),
],
),
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: [
Text(
'سن مرغ: ${item.hatching?.age ?? '-'}',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
Text(
item.sendDate?.formattedJalaliDate ?? '-',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
Text(
'تعداد:${item.quantity.separatedByComma ?? '-'} (قطعه)',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
],
),
),
buildRow(title: 'کد سفارش', value: '${item.orderCode} '),
buildRow(
title: 'نوع فروش',
value: (item.freeSaleInProvince ?? false) ? 'آزاد' : 'دولتی ',
),
buildRow(title: 'نوع کشتار ', value: getKillType(item)),
buildRow(title: 'درخواست', value: getRequestType(item) ?? 'N/A'),
buildRow(title: 'میانگین وزنی', value: '${(item.indexWeight)} (کیلوگرم)'),
buildRow(title: 'قیمت مرغدار', value: '${item.amount.separatedByComma} (ریال)'),
buildRow(title: 'مانده در سالن ', value: '${item.hatching?.leftOver.separatedByComma ?? 0} (قطعه)'),
buildRow(title: ' وضعیت', value: getState(item)),
],
),
);
}
Widget itemListWidget(PoultryOrder item) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 20),
Expanded(
flex: 2,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
spacing: 3,
children: [
Text(
item.poultry?.unitName ?? 'N/A',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
item.sendDate?.formattedJalaliDate ?? '-',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
],
),
),
Expanded(
flex: 3,
child: Column(
spacing: 3,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'کد سفارش : ${item.orderCode ?? '-'}',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
'تعداد:${item.quantity.separatedByComma ?? '-'} (قطعه)',
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
],
),
),
Expanded(
flex: 1,
child: Assets.vec.scanSvg.svg(
width: 32.w,
height: 32.h,
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
),
),
],
);
}
}
String getRequestType(PoultryOrder item) {
if (item.market ?? false) {
return 'پنل معاملات';
} else if (item.union ?? false) {
return 'اتحادیه';
} else {
return 'خرید مستقیم';
}
}
String getKillType(PoultryOrder item) {
if (item.export ?? false) {
return 'صادرات';
} else if (item.freezing ?? false) {
return 'انجماد';
} else {
return 'عادی';
}
}
String getState(PoultryOrder item) {
if (item.stateProcess == 'pending') {
return 'در انتظار تایید';
} else {
return 'تایید شده';
}
}

View File

@@ -116,13 +116,13 @@ class PoultryScienceHomeLogic extends GetxController {
tagInfo['first'] = tagInfo['first']!.map((tag) {
if (tag.labelTitle == 'کل فارم ها') {
return tag.copyWith(
value: result.farmCount?.separatedByComma ?? '0',
value: result.farmCount?.separatedByCommaFa ?? '0',
isLoading: false,
);
}
if (tag.labelTitle == 'تعداد جوجه ریزی') {
return tag.copyWith(
value: result.hatchingCount?.separatedByComma ?? '0',
value: result.hatchingCount?.separatedByCommaFa ?? '0',
isLoading: false,
);
}
@@ -134,12 +134,12 @@ class PoultryScienceHomeLogic extends GetxController {
switch (tag.labelTitle) {
case 'حجم جوجه ریزی':
return tag.copyWith(
value: result.hatchingQuantity?.separatedByComma ?? '0',
value: result.hatchingQuantity?.separatedByCommaFa ?? '0',
isLoading: false,
);
case 'مانده در سالن':
return tag.copyWith(
value: result.hatchingLeftOver?.separatedByComma ?? '0',
value: result.hatchingLeftOver?.separatedByCommaFa ?? '0',
isLoading: false,
);
default:
@@ -152,12 +152,12 @@ class PoultryScienceHomeLogic extends GetxController {
switch (tag.labelTitle) {
case 'تلفات':
return tag.copyWith(
value: result.hatchingLosses?.separatedByComma ?? '0',
value: result.hatchingLosses?.separatedByCommaFa ?? '0',
isLoading: false,
);
case 'حجم کشتار شده':
return tag.copyWith(
value: result.hatchingKilledQuantity?.separatedByComma ?? '0',
value: result.hatchingKilledQuantity?.separatedByCommaFa ?? '0',
isLoading: false,
);
default:
@@ -169,12 +169,12 @@ class PoultryScienceHomeLogic extends GetxController {
switch (element.labelTitle) {
case 'کمترین سن جوجه ریزی':
return element.copyWith(
value: result.hatchingMinAge?.separatedByComma ?? '0',
value: result.hatchingMinAge?.separatedByCommaFa ?? '0',
isLoading: false,
);
case 'بیشترین سن جوجه ریزی':
return element.copyWith(
value: result.hatchingMaxAge?.separatedByComma ?? '0',
value: result.hatchingMaxAge?.separatedByCommaFa ?? '0',
isLoading: false,
);
default:

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart';
import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.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/page_route.dart';
import 'package:rasadyar_core/core.dart';
@@ -18,7 +19,7 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
hasBack: true,
hasFilter: false,
routesWidget: ObxValue((route) => buildPageRoute(route), controller.routesName),
onBackPressed: () => Get.back(id: 0),
onBackPressed: () => Get.back(id: poultryFirstKey),
widgets: [
segmentWidget(),
@@ -132,11 +133,11 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
buildRow(title: 'شماره مجوز جوجه ریزی', value: item.licenceNumber ?? 'N/A'),
buildRow(
title: 'حجم جوجه ریزی',
value: item.quantity.separatedByComma,
value: item.quantity.separatedByCommaFa,
valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
buildRow(title: 'مانده در سالن', value: item.leftOver.separatedByComma),
buildRow(title: 'تلفات', value: item.losses.separatedByComma),
buildRow(title: 'مانده در سالن', value: item.leftOver.separatedByCommaFa),
buildRow(title: 'تلفات', value: item.losses.separatedByCommaFa),
buildRow(
title: 'دامپزشک فارم',
value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
@@ -425,14 +426,14 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
buildRow(title: 'شماره مجوز جوجه ریزی', value: item.hatching?.licenceNumber ?? 'N/A'),
buildRow(
title: 'حجم جوجه ریزی',
value: item.hatching?.quantity.separatedByComma ?? 'N/A',
value: item.hatching?.quantity.separatedByCommaFa ?? 'N/A',
valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
buildRow(
title: 'مانده در سالن',
value: item.hatching?.leftOver.separatedByComma ?? 'N/A',
value: item.hatching?.leftOver.separatedByCommaFa ?? 'N/A',
),
buildRow(title: 'تلفات', value: item.hatching?.losses.separatedByComma ?? 'N/A'),
buildRow(title: 'تلفات', value: item.hatching?.losses.separatedByCommaFa ?? 'N/A'),
buildRow(
title: 'دامپزشک فارم',
value:

View File

@@ -0,0 +1,360 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart';
import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart';
import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart';
import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart';
import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_core/core.dart';
class KillingRegistrationLogic extends GetxController {
List<String> routes = ['اقدام', 'درخواست کشتارها', 'ثبت کشتار'];
var tokenService = Get.find<TokenStorageService>();
var gService = Get.find<GService>();
var rootLogic = Get.find<PoultryScienceRootLogic>();
GlobalKey<FormState> formKey = GlobalKey<FormState>();
Rxn<ApprovedPrice> approvedPrice = Rxn<ApprovedPrice>();
Rx<Jalali> killsDate = Jalali.now().obs;
Rxn<SellForFreezing> sellForFreezing = Rxn<SellForFreezing>();
Rxn<PoultryExport> poultryExport = Rxn<PoultryExport>();
TextEditingController quantityKillsController = TextEditingController();
TextEditingController quantityLoseController = TextEditingController(text: 0.toString());
TextEditingController averageWeightKillsController = TextEditingController();
TextEditingController priceFreeSaleController = TextEditingController();
RxInt generatedApprovedPrice = 0.obs;
RxBool isOnSubmitLoading = false.obs;
RxBool isExportSelected = false.obs;
RxBool isFreezedSelected = false.obs;
RxBool isMarketSelected = false.obs;
RxBool isFreeSale = false.obs;
//step 1
Rx<Resource<List<AllPoultry>>> allPoultryList = Resource<List<AllPoultry>>.loading().obs;
Rxn<AllPoultry> selectedPoultry = Rxn();
//step 2
Rx<Resource<List<KillRequestPoultry>>> poultryList = Resource<List<KillRequestPoultry>>.success(
[],
).obs;
Rxn<KillRequestPoultry> selectedKillRequestPoultry = Rxn();
//step 3
Rx<Resource<List<PoultryHatching>>> poultryHatchingList = Resource<List<PoultryHatching>>.success(
[],
).obs;
Rxn<PoultryHatching> selectedPoultryHatching = Rxn();
//step 5
Rx<Resource<List<KillHousePoultry>>> killHouseList = Resource<List<KillHousePoultry>>.success(
[],
).obs;
Rxn<KillHousePoultry> selectedKillHouse = Rxn();
@override
void onReady() {
super.onReady();
getApprovedPrice();
getAllPoultryList();
getSellForFreezing();
getPoultryExport();
priceListener();
ever(selectedKillRequestPoultry, (callback) {
if (callback?.provinceAllowChooseKillHouse?.allowState ?? false) {
getKillHouseList();
}
});
everAll(
[selectedPoultry, selectedKillRequestPoultry, selectedPoultryHatching, selectedKillHouse],
(callback) {
checkSubmitButton();
},
);
}
@override
void onClose() {
super.onClose();
quantityKillsController.dispose();
quantityLoseController.dispose();
averageWeightKillsController.dispose();
priceFreeSaleController.dispose();
clearSelectedStep1();
clearSelectedStep2();
selectedKillHouse.value = null;
killHouseList.value = Resource<List<KillHousePoultry>>.success([]);
}
void priceListener() {
quantityKillsController.addListener(() {
if (averageWeightKillsController.text.isNotEmpty && quantityKillsController.text.isNotEmpty) {
generatedApprovedPrice.value = calculateApprovedPrice().toInt();
priceFreeSaleController.text = generatedApprovedPrice.value.separatedByComma;
checkSubmitButton();
} else {
generatedApprovedPrice.value = 0;
priceFreeSaleController.text = '0';
checkSubmitButton();
}
});
averageWeightKillsController.addListener(() {
if (averageWeightKillsController.text.isNotEmpty && quantityKillsController.text.isNotEmpty) {
generatedApprovedPrice.value = calculateApprovedPrice().toInt();
priceFreeSaleController.text = generatedApprovedPrice.value.separatedByComma;
checkSubmitButton();
} else {
generatedApprovedPrice.value = 0;
priceFreeSaleController.text = '0';
checkSubmitButton();
}
});
priceFreeSaleController.addListener(() {
final text = priceFreeSaleController.text;
if (text.isNotEmpty) {
generatedApprovedPrice.value = int.parse(text.replaceAll(',', ''));
} else {
generatedApprovedPrice.value = 0;
}
checkSubmitButton();
});
}
void clearSelectedStep1() {
selectedPoultry.value = null;
selectedKillRequestPoultry.value = null;
selectedPoultryHatching.value = null;
poultryList.value = Resource<List<KillRequestPoultry>>.success([]);
poultryHatchingList.value = Resource<List<PoultryHatching>>.success([]);
}
void clearSelectedStep2() {
selectedKillRequestPoultry.value = null;
selectedPoultryHatching.value = null;
poultryHatchingList.value = Resource<List<PoultryHatching>>.success([]);
}
Future<void> getApprovedPrice() async {
await safeCall(
call: () async => await rootLogic.poultryRepository.getApprovedPrice(
token: tokenService.accessToken.value ?? '',
),
onSuccess: (result) {
if (result != null) {
approvedPrice.value = result;
}
},
onError: (error, stackTrace) {},
);
}
Future<void> getAllPoultryList() async {
await safeCall(
call: () async => await rootLogic.poultryRepository.getAllPoultry(
token: tokenService.accessToken.value ?? '',
queryParameters: buildRawQueryParams(role: gService.getRole(Module.chicken)),
),
onSuccess: (result) {
if (result != null) {
allPoultryList.value = Resource<List<AllPoultry>>.success(result);
}
},
onError: (error, stackTrace) {
allPoultryList.value = Resource<List<AllPoultry>>.error('$error -- $stackTrace');
},
);
}
Future<void> getSellForFreezing() async {
await safeCall(
call: () async => await rootLogic.poultryRepository.getSellForFreezing(
token: tokenService.accessToken.value ?? '',
),
onSuccess: (result) {
if (result != null) {
sellForFreezing.value = result;
}
},
onError: (error, stackTrace) {},
);
}
Future<void> getPoultryExport() async {
await safeCall(
call: () async => await rootLogic.poultryRepository.getPoultryExport(
token: tokenService.accessToken.value ?? '',
),
onSuccess: (result) {
if (result != null) {
poultryExport.value = result;
}
},
onError: (error, stackTrace) {},
);
}
Future<void> getUserPoultryList() async {
poultryList.value = Resource<List<KillRequestPoultry>>.loading();
await safeCall(
call: () async => await rootLogic.poultryRepository.getUserPoultry(
token: tokenService.accessToken.value ?? '',
queryParameters: buildQueryParams(
value: selectedPoultry.value?.user?.mobile,
queryParams: {'type': 'filter'},
),
),
onSuccess: (result) {
if (result != null) {
poultryList.value = Resource<List<KillRequestPoultry>>.success(result);
}
},
onError: (error, stackTrace) {
poultryList.value = Resource<List<KillRequestPoultry>>.error('$error -- $stackTrace');
},
);
}
Future<void> getPoultryHatchingList() async {
poultryHatchingList.value = Resource<List<PoultryHatching>>.loading();
await safeCall(
call: () async => await rootLogic.poultryRepository.getPoultryHatching(
token: tokenService.accessToken.value ?? '',
queryParameters: buildRawQueryParams(
queryParams: {'key': selectedKillRequestPoultry.value?.key},
),
),
onSuccess: (result) {
if (result != null) {
poultryHatchingList.value = Resource<List<PoultryHatching>>.success(result);
}
},
onError: (error, stackTrace) {
poultryHatchingList.value = Resource<List<PoultryHatching>>.error('$error -- $stackTrace');
},
);
}
Future<void> getKillHouseList() async {
killHouseList.value = Resource<List<KillHousePoultry>>.loading();
await safeCall(
call: () async => await rootLogic.poultryRepository.getKillHouseList(
token: tokenService.accessToken.value ?? '',
queryParameters: buildRawQueryParams(
queryParams: {'show_poultry': '', 'date': DateTime.now().formattedDashedGregorian},
),
),
onSuccess: (result) {
if (result != null) {
killHouseList.value = Resource<List<KillHousePoultry>>.success(result);
}
},
onError: (error, stackTrace) {
killHouseList.value = Resource<List<KillHousePoultry>>.error('$error -- $stackTrace');
},
);
}
double calculateApprovedPrice() {
final inputWeight = double.parse(averageWeightKillsController.text) * 1000;
final lowestWeight = approvedPrice.value?.lowestWeight ?? 0;
final highestWeight = approvedPrice.value?.highestWeight ?? 0;
final lowestPrice = approvedPrice.value?.lowestPrice ?? 0;
final highestPrice = approvedPrice.value?.highestPrice ?? 0;
if (inputWeight <= lowestWeight) {
return lowestPrice;
} else if (inputWeight >= highestWeight) {
return highestPrice;
} else {
final diffWeight = highestWeight - lowestWeight;
final diffPrice = highestPrice - lowestPrice;
final fraction = diffPrice / diffWeight;
final diffFromMinWeight = inputWeight - lowestWeight;
return diffFromMinWeight * fraction + lowestPrice;
}
}
void changeSaleType() {
isFreeSale.value = !isFreeSale.value;
generatedApprovedPrice.value = calculateApprovedPrice().toInt();
}
void checkSubmitButton() {
isOnSubmitLoading.value =
selectedPoultry.value != null &&
selectedKillRequestPoultry.value != null &&
selectedPoultryHatching.value != null &&
quantityKillsController.text.isNotEmpty &&
averageWeightKillsController.text.isNotEmpty &&
((selectedKillRequestPoultry.value?.provinceAllowChooseKillHouse?.mandatory ?? false)
? selectedKillHouse.value != null
: true);
}
Future<void> submitKillRegistration() async {
isOnSubmitLoading.value = false;
if (!formKey.currentState!.validate()) {
return;
}
KillRegistrationRequest registrationRequest = KillRegistrationRequest(
indexWeight: double.parse(averageWeightKillsController.text),
amount: generatedApprovedPrice.value,
approvedPrice: approvedPrice.value?.approved ?? false,
auctionList: [],
cash: true,
chickenBreed: selectedPoultryHatching.value?.chickenBreed,
confirmPoultryMobile: selectedPoultry.value?.user?.mobile,
credit: false,
export: isExportSelected.value,
financialOperation: "outside-system",
freeSaleInProvince: isMarketSelected.value,
freezing: isFreezedSelected.value,
killHouseList: [
if (selectedKillHouse.value != null)
'${selectedKillHouse.value?.name}(${selectedKillHouse.value?.fullname})',
],
killReqKey: selectedKillHouse.value?.killReqKey,
losses: quantityLoseController.text,
market: isMarketSelected.value,
operatorKey: "",
poultryHatchingKey: selectedPoultryHatching.value?.key,
poultryKey: selectedPoultry.value?.key,
quantity: int.parse(quantityKillsController.text),
role: gService.getRole(Module.chicken),
sendDate: killsDate.value.toDateTime().formattedDashedGregorian,
);
await safeCall(
call: () async => await rootLogic.poultryRepository.submitKillRegistration(
token: tokenService.accessToken.value ?? '',
request: registrationRequest,
),
onSuccess: (result) async {
defaultShowSuccessMessage(
'ثبت با موفقیت انجام شد',
onDismissed: () {
Get.back(id: poultryFirstKey);
},
);
},
onError: (error, stackTrace) {},
);
}
}

View File

@@ -0,0 +1,496 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_core/core.dart';
import 'logic.dart';
class KillingRegistrationPage extends GetView<KillingRegistrationLogic> {
const KillingRegistrationPage({super.key});
@override
Widget build(BuildContext context) {
return BasePageWithScroll(
hasSearch: false,
hasFilter: false,
routes: controller.routes,
onBackPressed: () => Get.back(id: poultryFirstKey),
widgets: [
poultryFarmWidget(),
poultryUserListWidget(),
poultryHatchingWidget(),
ObxValue((data) {
return Visibility(
visible: controller.selectedPoultryHatching.value != null,
child: Form(
key: controller.formKey,
child: Column(
children: [
informationWidget(),
killDateWidget(
date: controller.killsDate,
onChanged: (Jalali jalali) {
controller.killsDate.value = jalali;
},
),
loseWidget(),
quantityKillsWidget(),
averageWeightKillsWidget(),
saleTypeWidget(),
priceWidget(),
buyerListWidget(),
slaughterhouseSelectedWidget(),
submitButtonWidget(),
],
),
),
);
}, controller.selectedPoultryHatching),
],
);
}
Widget informationWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
child: ObxValue(
(data) => Column(
spacing: 8,
children: [
buildUnitRow(
title: 'تعداد جوجه ریزی',
value: data.value?.quantity.separatedByCommaFa,
unit: 'قطعه',
),
buildUnitRow(
title: 'جمع تلفات ثبت شده دامپزشک و مرغدار',
value: data.value?.losses.separatedByCommaFa,
unit: 'قطعه',
),
buildUnitRow(
title: 'باقیمانده',
value: data.value?.leftOver.separatedByCommaFa,
unit: 'قطعه',
),
buildUnitRow(
title: 'سن مرغ',
value: data.value?.chickenAge.separatedByCommaFa,
unit: 'روز',
),
buildUnitRow(
title: 'مجوز فروش آزاد',
value: data.value?.freeGovernmentalInfo?.totalFreeCommitmentQuantity.separatedByCommaFa,
unit: 'قطعه',
),
buildUnitRow(
title: 'مانده فروش آزاد',
value: data
.value
?.freeGovernmentalInfo
?.leftTotalFreeCommitmentQuantity
.separatedByCommaFa,
unit: 'قطعه',
),
],
),
controller.selectedPoultryHatching,
),
);
}
Widget poultryFarmWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
child: ObxValue((data) {
return ResourceOverlayDropdown<AllPoultry>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.clearSelectedStep1();
controller.selectedPoultry.value = value;
controller.getUserPoultryList();
},
selectedItem: controller.selectedPoultry.value,
itemBuilder: (item) => Text(labelPoultry(item), maxLines: 2),
labelBuilder: (item) => Text(labelPoultry(item)),
);
}, controller.allPoultryList),
);
}
String labelPoultry(AllPoultry? item) {
if (item == null) {
return 'انتخاب مرغداری';
} else {
return '${item.unitName} (${item.address?.city?.name}) / ${item.user?.fullname} (${item.user?.mobile}) / ${item.lastHatchingRemainQuantity} قطعه ';
}
}
Widget poultryUserListWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: ObxValue((data) {
return ResourceOverlayDropdown<KillRequestPoultry>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.clearSelectedStep2();
controller.selectedKillRequestPoultry.value = value;
controller.getPoultryHatchingList();
},
selectedItem: controller.selectedKillRequestPoultry.value,
itemBuilder: (item) => Text(item.unitName ?? '-'),
labelBuilder: (item) => Text(item?.unitName ?? 'محل پرورش'),
);
}, controller.poultryList),
);
}
Widget poultryHatchingWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
child: ObxValue((data) {
return ResourceOverlayDropdown<PoultryHatching>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.selectedPoultryHatching.value = value;
},
selectedItem: controller.selectedPoultryHatching.value,
itemBuilder: (item) => Text(labelPoultryHatching(item)),
labelBuilder: (item) => Text(labelPoultryHatching(item)),
);
}, controller.poultryHatchingList),
);
}
String labelPoultryHatching(PoultryHatching? item) {
if (item == null) {
return 'دوره جوجه ریزی';
} else {
return ' دوره ${item.period} سالن ${item.hall} نژاد ${item.chickenBreed} باقیمانده ${item.leftOver} قطعه ';
}
}
Widget killDateWidget({required Rx<Jalali> date, required Function(Jalali jalali) onChanged}) {
return GestureDetector(
onTap: () {
Get.bottomSheet(modalDatePicker(onDateSelected: (value) => onChanged(value)));
},
child: Container(
height: 40,
margin: EdgeInsets.symmetric(horizontal: 20.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 1, color: AppColor.darkGreyLight),
),
padding: EdgeInsets.symmetric(horizontal: 11, vertical: 4),
child: Row(
spacing: 8,
children: [
Assets.vec.calendarSvg.svg(
width: 24,
height: 24,
colorFilter: const ColorFilter.mode(AppColor.bgDark, BlendMode.srcIn),
),
Text('تاریخ کشتار', style: AppFonts.yekan14.copyWith(color: AppColor.bgDark)),
Spacer(),
ObxValue((data) {
return Text(
date.value.formatCompactDate(),
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark),
);
}, date),
],
),
),
);
}
Widget loseWidget() {
return Padding(
padding: EdgeInsets.fromLTRB(20.w, 10.h, 20.w, 0),
child: RTextField(
label: 'تعداد تلفات (قطعه)',
filled: true,
filledColor: Colors.white,
keyboardType: TextInputType.number,
controller: controller.quantityLoseController,
),
);
}
Widget quantityKillsWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
child: RTextField(
label: 'تعداد کشتار (قطعه)',
filled: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'تعداد کشتار را وارد کنید';
}
final count = double.tryParse(value.replaceAll(',', ''));
if (controller.isFreeSale.value) {
if (count! >
(controller
.selectedPoultryHatching
.value
?.freeGovernmentalInfo
?.leftTotalFreeCommitmentQuantity ??
0)) {
return 'مجوز فروش آزاد شما کافی نیست';
}
} else {
if (count! > (controller.selectedPoultryHatching.value?.leftOver ?? 0)) {
return 'تعداد کشتار نباید بیشتر از باقیمانده جوجه ریزی باشد';
}
}
return null;
},
textInputAction: TextInputAction.next,
filledColor: Colors.white,
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
controller: controller.quantityKillsController,
),
);
}
Widget averageWeightKillsWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: RTextField(
label: 'میانگین وزن (کیلوگرم)',
filled: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'میانگین وزن را وارد کنید';
}
final weight = double.tryParse(value.replaceAll(',', ''));
if (weight == null || weight <= 0) {
return 'میانگین وزن باید عددی بزرگتر از صفر باشد';
} else if (weight >
(controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.toWeight ??
10000) ||
weight <
(controller
.selectedPoultryHatching
.value
?.managementHatchingAgeRange
?.fromWeight ??
-10000)) {
return 'میانگین وزن باید بین ${controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.fromWeight} تا ${controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.toWeight} کیلوگرم باشد';
}
return null;
},
filledColor: Colors.white,
keyboardType: TextInputType.number,
controller: controller.averageWeightKillsController,
),
);
}
Widget saleTypeWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
child: ObxValue((data) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
CustomChip(
title: 'فروش دولتی',
index: 0,
onTap: (int p1) {
controller.changeSaleType();
},
isSelected: !(data.value),
),
CustomChip(
title: 'فروش آزاد',
index: 1,
onTap: (int p1) {
controller.changeSaleType();
},
isSelected: data.value,
),
],
);
}, controller.isFreeSale),
);
}
Widget priceWidget() {
return ObxValue((data){
if(!data.value){
return Container(
height: 40.h,
margin: EdgeInsets.symmetric(horizontal: 20.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 1.w, color: AppColor.darkGreyLight),
),
padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 4.h),
child: Row(
spacing: 8,
children: [
Text('قیمت مصوب', style: AppFonts.yekan14.copyWith(color: AppColor.bgDark)),
Spacer(),
ObxValue((data) {
return Text(
' ${data.value.separatedByCommaFa} ریال',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark),
);
}, controller.generatedApprovedPrice),
],
),
);
}else{
return Padding(
padding: EdgeInsets.fromLTRB(20.w, 10.h, 20.w, 0),
child: RTextField(
label: 'قیمت پیشنهادی (ریال)',
validator: (value) {
if (value == null || value.isEmpty) {
return 'قیمت پیشنهادی را وارد کنید';
}
final price = double.tryParse(value.replaceAll(',', ''));
dLog(controller.priceFreeSaleController.text);
fLog(value);
if (price == null || price <= 0) {
return 'قیمت پیشنهادی باید عددی بزرگتر از صفر باشد';
}
return null;
},
filled: true,
filledColor: Colors.white,
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
controller: controller.priceFreeSaleController,
),
);
}
}, controller.isFreeSale);
}
Widget buyerListWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
child: ObxValue((data) {
return Visibility(
visible: data.value?.provinceAllowChooseKillHouse?.allowState ?? false,
child: ObxValue((data) {
return ResourceOverlayDropdown<KillHousePoultry>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.selectedKillHouse.value = value;
},
selectedItem: controller.selectedKillHouse.value,
itemBuilder: (item) => Text(buildKillHouseLabel(item)),
labelBuilder: (item) => Text(buildKillHouseLabel(item)),
);
}, controller.killHouseList),
);
}, controller.selectedKillRequestPoultry),
);
}
String buildKillHouseLabel(KillHousePoultry? item) {
if (item == null) {
return 'خریدار/ظرفیت باقیمانده';
} else {
return '${item.name} / ${item.quantitySum} قطعه ';
}
}
Widget slaughterhouseSelectedWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: Wrap(
spacing: 10,
runSpacing: 10,
children: [
ObxValue((data) {
return Visibility(
visible: data.value?.permission ?? false,
child: ObxValue(
(data) => CheckBoxChips(
title: 'کشتار برای انجماد',
data: data.value,
onTap: (p1) {
controller.isFreezedSelected.value = !controller.isFreezedSelected.value;
},
isSelected: data.value,
),
controller.isFreezedSelected,
),
);
}, controller.sellForFreezing),
ObxValue((data) {
return CheckBoxChips(
title: 'نمایش در پنل معاملات',
data: 0,
onTap: (int p1) {
controller.isMarketSelected.value = !controller.isMarketSelected.value;
},
isSelected: data.value,
);
}, controller.isMarketSelected),
ObxValue((data) {
return Visibility(
visible: data.value?.allow ?? false,
child: ObxValue((data) {
return CheckBoxChips(
title: 'کشتار برای صادرات',
data: data.value,
onTap: (_) {
controller.isExportSelected.value = !controller.isExportSelected.value;
},
isSelected: data.value,
);
}, controller.isExportSelected),
);
}, controller.poultryExport),
],
),
);
}
Widget submitButtonWidget() {
return ObxValue((data) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h),
child: RElevated(
enabled: data.value,
height: 45.h,
isFullWidth: true,
backgroundColor: AppColor.greenNormal,
textStyle: AppFonts.yekan16Bold.copyWith(color: Colors.white),
onPressed: () {
controller.submitKillRegistration();
},
text: 'ثبت کشتار',
),
);
}, controller.isOnSubmitLoading);
}
}

View File

@@ -18,7 +18,7 @@ class PoultryActionLogic extends GetxController {
),
PoultryActionItem(
title: "ثبت کشتار",
route: ChickenRoutes.killingRegistrationPoultryScience,
route: ChickenRoutes.genocidePoultryScience,
icon: Assets.vec.noteRemoveSvg.path,
),
PoultryActionItem(

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/app_bar.dart';
import 'package:rasadyar_core/core.dart';
@@ -53,7 +54,7 @@ class PoultryActionPage extends GetView<PoultryActionLogic> {
vecIcon: item.icon,
iconColor: AppColor.blueNormal,
onTap: () async {
Get.toNamed(item.route, id: 0);
Get.toNamed(item.route, id: poultryFirstKey);
},
);
},

View File

@@ -4,6 +4,7 @@ import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_scien
import 'package:rasadyar_chicken/presentation/pages/common/profile/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/home/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/poultry_action/view.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart';
import 'package:rasadyar_chicken/presentation/utils/utils.dart';
import 'package:rasadyar_core/core.dart';
@@ -12,9 +13,11 @@ enum ErrorLocationType { serviceDisabled, permissionDenied, none }
class PoultryScienceRootLogic extends GetxController {
RxInt currentPage = 1.obs;
List<Widget> pages = [PoultryActionPage(), PoultryScienceHomePage(), ProfilePage()];
late DioRemote dioRemote;
var tokenService = Get.find<TokenStorageService>();
late PoultryScienceRepository poultryRepository;
RxList<ErrorLocationType> errorLocationType = RxList();
RxMap<int, dynamic> homeExpandedList = RxMap();
@@ -46,4 +49,17 @@ class PoultryScienceRootLogic extends GetxController {
void changePage(int index) {
currentPage.value = index;
}
int getNestedKey() {
switch (currentPage.value) {
case 0:
return poultryFirstKey;
case 1:
return poultrySecondKey;
case 2:
return poultryThirdKey;
default:
return poultryFirstKey;
}
}
}

View File

@@ -18,7 +18,7 @@ class PoultryScienceRootPage extends GetView<PoultryScienceRootLogic> {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) async {
final nestedKey = Get.nestedKey(controller.currentPage.value);
final nestedKey = Get.nestedKey(controller.getNestedKey());
final currentNavigator = nestedKey?.currentState;
if (currentNavigator?.canPop() ?? false) {

View File

@@ -92,7 +92,7 @@ class BuyInProvinceAllPage extends GetView<BuyInProvinceAllLogic> {
),
),
Text(
'${item.weightOfCarcasses?.separatedByComma}kg',
'${item.weightOfCarcasses?.separatedByCommaFa}kg',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
@@ -206,9 +206,9 @@ class BuyInProvinceAllPage extends GetView<BuyInProvinceAllLogic> {
buildRow(title: 'محصول', value: item.product?.name ?? 'N/A'),
buildRow(
title: 'وزن خریداری شده',
value: '${item.weightOfCarcasses?.separatedByComma} کیلوگرم',
value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم',
),
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByComma} ریال'),
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByCommaFa} ریال'),
Visibility(
visible: item.receiverState == 'pending',
child: Row(

View File

@@ -109,7 +109,7 @@ class BuyInProvinceWaitingPage extends GetView<BuyInProvinceWaitingLogic> {
),
),
Text(
'${item.weightOfCarcasses?.separatedByComma}kg',
'${item.weightOfCarcasses?.separatedByCommaFa}kg',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
@@ -218,9 +218,9 @@ class BuyInProvinceWaitingPage extends GetView<BuyInProvinceWaitingLogic> {
buildRow(title: 'محصول', value: item.product?.name ?? 'N/A'),
buildRow(
title: 'وزن خریداری شده',
value: '${item.weightOfCarcasses?.separatedByComma} کیلوگرم',
value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم',
),
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByComma} ریال'),
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByCommaFa} ریال'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 16.w,

View File

@@ -142,7 +142,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
buildRow(title: 'محصول', value: item.product?.name ?? 'N/A'),
buildRow(
title: 'وزن خریداری شده',
value: '${item.weightOfCarcasses?.separatedByComma} کیلوگرم',
value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم',
),
buildRowOnTapped(
title: 'مشاهده بارنامه',
@@ -269,7 +269,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
),
),
Text(
'${item.weightOfCarcasses?.separatedByComma}kg',
'${item.weightOfCarcasses?.separatedByCommaFa}kg',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
@@ -427,7 +427,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0}',
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0}',
),
],
),

View File

@@ -175,7 +175,7 @@ class HomePage extends GetView<HomeLogic> {
child: _informationIconCard(
title: 'توزیع داخل استان',
isLoading: data.value == null,
description: data.value?.freeSalesWeight.separatedByComma ?? '0',
description: data.value?.freeSalesWeight.separatedByCommaFa ?? '0',
iconPath: Assets.vec.truckSvg.path,
iconColor: const Color.fromRGBO(85, 97, 93, 1),
bgDescriptionColor: const Color(0xFFE6FAF5),
@@ -186,7 +186,7 @@ class HomePage extends GetView<HomeLogic> {
child: _informationIconCard(
title: 'توزیع خارج استان',
isLoading: data.value == null,
description: data.value?.stewardAllocationsWeight.separatedByComma ?? '0',
description: data.value?.stewardAllocationsWeight.separatedByCommaFa ?? '0',
iconPath: Assets.vec.truckFastSvg.path,
iconColor: Color(0xFF647379),
bgDescriptionColor: const Color(0xFFEAEFFF),
@@ -223,7 +223,7 @@ class HomePage extends GetView<HomeLogic> {
description: data.value != null
? ((data.value?.provinceGovernmentalCarcassesWeight ?? 0) +
(data.value?.provinceFreeCarcassesWeight ?? 0))
.separatedByComma
.separatedByCommaFa
: '0',
iconPath: Assets.vec.cubeSvg.path,
iconColor: const Color(0xFF6C5D60),
@@ -235,7 +235,7 @@ class HomePage extends GetView<HomeLogic> {
child: _informationLabelCard(
title: 'خارج استان',
isLoading: data.value == null,
description: data.value?.freeBuyingCarcassesWeight.separatedByComma ?? '0',
description: data.value?.freeBuyingCarcassesWeight.separatedByCommaFa ?? '0',
iconPath: Assets.vec.cubeSearchSvg.path,
iconColor: Color(0xFF2D5FFF),
bgLabelColor: const Color(0xFFAFCBFF),
@@ -259,7 +259,7 @@ class HomePage extends GetView<HomeLogic> {
child: _informationLabelCard(
title: 'مانده انبار',
isLoading: data.value == null,
description: data.value?.totalRemainWeight.separatedByComma ?? '0',
description: data.value?.totalRemainWeight.separatedByCommaFa ?? '0',
iconPath: Assets.vec.cubeSearchSvg.path,
iconColor: const Color(0xFF426060),
bgDescriptionColor: const Color(0xFFC7DFE0),
@@ -270,7 +270,7 @@ class HomePage extends GetView<HomeLogic> {
child: _informationLabelCard(
title: 'توزیع شده',
isLoading: data.value == null,
description: data.value?.realAllocatedWeight.separatedByComma ?? '0',
description: data.value?.realAllocatedWeight.separatedByCommaFa ?? '0',
iconPath: Assets.vec.cubeRotateSvg.path,
iconColor: Color(0xFF5C4D64),
bgLabelColor: Color(0xFFC8B8D1),
@@ -295,7 +295,7 @@ class HomePage extends GetView<HomeLogic> {
title: 'بارهای امروز',
titleColor: AppColor.blueNormal,
isLoading: data.value == null,
description: data.value?.separatedByComma ?? '0',
description: data.value?.separatedByCommaFa ?? '0',
iconPath: Assets.vec.cubeSearchSvg.path,
iconColor: AppColor.blueNormal,
bgDescriptionColor: Colors.white,
@@ -314,9 +314,9 @@ class HomePage extends GetView<HomeLogic> {
return _informationLabelCard(
title: 'درانتظار تایید',
isLoading: data.value == null,
description: data.value?.totalNotEnteredBars.separatedByComma ?? '0',
description: data.value?.totalNotEnteredBars.separatedByCommaFa ?? '0',
unit:
'(${data.value?.totalNotEnteredKillHouseRequestsWeight.separatedByComma})\nکیلوگرم',
'(${data.value?.totalNotEnteredKillHouseRequestsWeight.separatedByCommaFa})\nکیلوگرم',
iconPath: Assets.vec.cubeWattingSvg.path,
bgDescriptionColor: Colors.white,
gradient: LinearGradient(

View File

@@ -178,7 +178,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
),
),
Text(
'${item.weightOfCarcasses?.separatedByComma}kg',
'${item.weightOfCarcasses?.separatedByCommaFa}kg',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
@@ -186,7 +186,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
),
SizedBox(height: 2),
Text(
'${item.amount.separatedByComma} ریال',
'${item.amount.separatedByCommaFa} ریال',
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDark),
),
@@ -303,13 +303,13 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
),
buildRow(
title: 'وزن خریداری شده',
value: '${item.weightOfCarcasses?.separatedByComma} کیلوگرم',
value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم',
),
buildRow(
title: 'افت وزن(کیلوگرم)',
value: item.weightLossOfCarcasses?.toInt().toString() ?? 'N/A',
),
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByComma} ریال'),
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByCommaFa} ریال'),
buildRow(title: 'کداحراز', value: item.registrationCode?.toString() ?? 'ندارد'),
buildRow(
@@ -603,7 +603,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0}',
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0}',
),
],
),
@@ -780,16 +780,16 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
buildRow(
title: 'قیمت هر کیلو',
value: '${controller.tmpStewardAllocation?.amount.separatedByComma ?? 0} ریال ',
value: '${controller.tmpStewardAllocation?.amount.separatedByCommaFa ?? 0} ریال ',
),
buildRow(
title: 'وزن تخصیصی',
value:
'${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByComma ?? 0} کیلوگرم',
'${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByCommaFa ?? 0} کیلوگرم',
),
buildRow(
title: 'قیمت کل',
value: '${controller.tmpStewardAllocation?.totalAmount.separatedByComma ?? 0} ریال',
value: '${controller.tmpStewardAllocation?.totalAmount.separatedByCommaFa ?? 0} ریال',
),
Row(

View File

@@ -156,7 +156,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
'${item.weightOfCarcasses?.separatedByComma ?? 0}KG',
'${item.weightOfCarcasses?.separatedByCommaFa ?? 0}KG',
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
@@ -235,7 +235,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
buildRow(title: 'مشخصات خریدار', value: item.buyer?.fullname ?? 'N/A'),
buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'N/A'),
buildRow(title: 'نام واحد', value: item.buyer?.unitName ?? 'N/A'),
buildRow(title: 'وزن لاشه', value: '${item.weightOfCarcasses?.separatedByComma}'),
buildRow(title: 'وزن لاشه', value: '${item.weightOfCarcasses?.separatedByCommaFa}'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
@@ -419,7 +419,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0}',
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0}',
),
],
),

View File

@@ -281,9 +281,9 @@ class SalesOutOfProvinceBuyersPage extends GetView<SalesOutOfProvinceBuyersLogic
buildRow(title: 'نام واحد', value: item.unitName ?? 'N/A'),
buildRow(
title: 'تعداد درخواست ها',
value: '${item.requestsInfo?.numberOfRequests.separatedByComma}',
value: '${item.requestsInfo?.numberOfRequests.separatedByCommaFa}',
),
buildRow(title: 'وزن', value: '${item.requestsInfo?.totalWeight.separatedByComma}'),
buildRow(title: 'وزن', value: '${item.requestsInfo?.totalWeight.separatedByCommaFa}'),
Row(
mainAxisAlignment: MainAxisAlignment.center,

View File

@@ -121,7 +121,7 @@ class SalesOutOfProvinceSalesListPage extends GetView<SalesOutOfProvinceSalesLis
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
'${item.weightOfCarcasses?.separatedByComma ?? 0}KG',
'${item.weightOfCarcasses?.separatedByCommaFa ?? 0}KG',
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
@@ -200,7 +200,7 @@ class SalesOutOfProvinceSalesListPage extends GetView<SalesOutOfProvinceSalesLis
buildRow(title: 'مشخصات خریدار', value: item.buyer?.fullname ?? 'N/A'),
buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'N/A'),
buildRow(title: 'نام واحد', value: item.buyer?.unitName ?? 'N/A'),
buildRow(title: 'وزن لاشه', value: '${item.weightOfCarcasses?.separatedByComma}'),
buildRow(title: 'وزن لاشه', value: '${item.weightOfCarcasses?.separatedByCommaFa}'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
@@ -384,7 +384,7 @@ class SalesOutOfProvinceSalesListPage extends GetView<SalesOutOfProvinceSalesLis
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0}',
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0}',
),
],
),

View File

@@ -129,7 +129,7 @@ class SegmentationPage extends GetView<SegmentationLogic> {
Expanded(
flex: 2,
child: Text(
'${item.weight.separatedByComma} KG',
'${item.weight.separatedByCommaFa} KG',
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
@@ -204,7 +204,7 @@ class SegmentationPage extends GetView<SegmentationLogic> {
: item.buyer?.shop ?? 'N/A',
),
buildRow(title: 'ماهیت', value: item.toGuild != null ? 'مباشر' : 'قطعه‌بند'),
buildRow(title: 'وزن قطعه‌بندی', value: '${item.weight?.separatedByComma}'),
buildRow(title: 'وزن قطعه‌بندی', value: '${item.weight?.separatedByCommaFa}'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
@@ -394,7 +394,7 @@ class SegmentationPage extends GetView<SegmentationLogic> {
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی: ${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0} کیلوگرم',
'موجودی: ${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByCommaFa ?? 0} کیلوگرم',
),
],
),

View File

@@ -0,0 +1,19 @@
import 'package:rasadyar_chicken/presentation/pages/common/profile/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/root/logic.dart';
import 'package:rasadyar_chicken/presentation/widget/search/logic.dart';
import 'package:rasadyar_core/core.dart';
import '../widget/base_page/logic.dart';
class GlobalBinding extends Bindings {
@override
void dependencies() {
Get.put(BaseLogic(), permanent: true);
Get.lazyPut(() => ProfileLogic(), fenix: true);
Get.lazyPut(() => SearchLogic(), fenix: true);
//root logics
}
}

View File

@@ -1,20 +1,26 @@
import 'package:rasadyar_chicken/presentation/pages/common/auth/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/common/auth/view.dart';
import 'package:rasadyar_chicken/presentation/pages/common/profile/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/common/profile/view.dart';
import 'package:rasadyar_chicken/presentation/pages/common/role/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/common/role/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/active_hatching/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/active_hatching/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/farm/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/farm/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/genocide/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/genocide/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/home/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/inspection/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/inspection/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/killing_registration/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/killing_registration/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/poultry_action/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/poultry_action/view.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/logic.dart';
import 'package:rasadyar_chicken/presentation/pages/poultry_science/root/view.dart';
import 'package:rasadyar_chicken/presentation/pages/steward/steward.dart';
import 'package:rasadyar_chicken/presentation/routes/global_binding.dart';
import 'package:rasadyar_chicken/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
import 'package:rasadyar_chicken/presentation/widget/captcha/logic.dart';
@@ -42,21 +48,22 @@ sealed class ChickenPages {
}),
),
//region Steward Pages
GetPage(
name: ChickenRoutes.initSteward,
page: () => StewardRootPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => StewardRootLogic());
Get.lazyPut(() => HomeLogic());
Get.lazyPut(() => BuyLogic());
Get.lazyPut(() => SaleLogic());
Get.lazyPut(() => ProfileLogic());
Get.lazyPut(() => SegmentationLogic());
Get.lazyPut(() => SearchLogic());
}),
bindings: [
GlobalBinding(),
BindingsBuilder(() {
Get.lazyPut(() => StewardRootLogic());
Get.lazyPut(() => HomeLogic());
Get.lazyPut(() => BuyLogic());
Get.lazyPut(() => SaleLogic());
Get.lazyPut(() => SegmentationLogic());
}),
],
),
GetPage(
@@ -154,15 +161,15 @@ sealed class ChickenPages {
name: ChickenRoutes.initPoultryScience,
page: () => PoultryScienceRootPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => BaseLogic());
Get.lazyPut(() => SearchLogic());
Get.lazyPut(() => PoultryScienceRootLogic());
Get.lazyPut(() => StewardRootLogic());
Get.lazyPut(() => PoultryScienceHomeLogic());
Get.lazyPut(() => ProfileLogic());
Get.lazyPut(() => PoultryActionLogic());
}),
bindings: [
GlobalBinding(),
BindingsBuilder(() {
Get.lazyPut(() => PoultryScienceRootLogic());
Get.lazyPut(() => PoultryScienceHomeLogic());
Get.lazyPut(() => PoultryActionLogic());
}),
],
),
GetPage(
@@ -202,6 +209,25 @@ sealed class ChickenPages {
Get.lazyPut(() => PoultryScienceRootLogic());
}),
),
GetPage(
name: ChickenRoutes.genocidePoultryScience,
page: () => GenocidePage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => GenocideLogic());
Get.lazyPut(() => PoultryScienceRootLogic());
}),
),
GetPage(
name: ChickenRoutes.killingRegistrationPoultryScience,
page: () => KillingRegistrationPage(),
middlewares: [AuthMiddleware()],
binding: BindingsBuilder(() {
Get.lazyPut(() => KillingRegistrationLogic());
Get.lazyPut(() => GenocideLogic());
Get.lazyPut(() => PoultryScienceRootLogic());
}),
),
//endregion
];
}

View File

@@ -4,6 +4,7 @@ sealed class ChickenRoutes {
static const auth = '/AuthChicken';
static const _base = '/chicken';
static const role = '$_base/role';
static const String profile = '$_base/profile';
//region Steward Routes
static const _steward = '$_base/steward';
@@ -31,6 +32,10 @@ sealed class ChickenRoutes {
static const inspectionPoultryScience = '$_poultryScience/inspection';
static const farmPoultryScience = '$_poultryScience/farm';
static const activeHatchingPoultryScience = '$_poultryScience/activeHatching';
static const killingRegistrationPoultryScience = '$_poultryScience/KillingRegistration';
static const genocidePoultryScience = '$_poultryScience/genocidePoultryScience';
static const killingRegistrationPoultryScience = '$genocidePoultryScience/KillingRegistration';
//endregion
}

View File

@@ -6,7 +6,7 @@ import 'package:rasadyar_chicken/presentation/widget/search/logic.dart';
import 'package:rasadyar_chicken/presentation/widget/search/view.dart';
import 'package:rasadyar_core/core.dart';
class BasePage extends StatefulWidget {
class BasePage extends StatefulWidget {
const BasePage({
super.key,
this.routes,
@@ -51,10 +51,11 @@ class _BasePageState extends State<BasePage> {
BaseLogic get controller => Get.find<BaseLogic>();
Worker? filterWorker;
bool _isBottomSheetOpen = false;
@override
void initState() {
super.initState();
/* filterWorker = ever(controller.isFilterSelected, (bool isSelected) {
/* filterWorker = ever(controller.isFilterSelected, (bool isSelected) {
if (!mounted) return;
if (isSelected && widget.filteringWidget != null) {
@@ -92,6 +93,7 @@ class _BasePageState extends State<BasePage> {
filterWorker?.dispose();
super.dispose();
}
void _onFilterTap() {
if (widget.hasFilter && widget.filteringWidget != null) {
// بررسی اینکه آیا این route در top است یا نه
@@ -110,7 +112,6 @@ class _BasePageState extends State<BasePage> {
}
}
@override
Widget build(BuildContext context) {
return PopScope(
@@ -143,3 +144,109 @@ class _BasePageState extends State<BasePage> {
);
}
}
class BasePageWithScroll extends StatefulWidget {
const BasePageWithScroll({
super.key,
this.routes,
required this.widgets,
this.routesWidget,
this.floatingActionButtonLocation,
this.floatingActionButton,
this.onSearchChanged,
this.hasBack = true,
this.hasFilter = true,
this.hasSearch = true,
this.isBase = false,
this.onBackPressed,
this.onFilterTap,
this.onSearchTap,
this.filteringWidget,
}) : assert(
(routes != null) || routesWidget != null,
'Either routes or routesWidget must be provided.',
);
final List<String>? routes;
final Widget? routesWidget;
final List<Widget> widgets;
final FloatingActionButtonLocation? floatingActionButtonLocation;
final Widget? floatingActionButton;
final Widget? filteringWidget;
final void Function(String?)? onSearchChanged;
final bool hasBack;
final bool hasFilter;
final bool hasSearch;
final bool isBase;
final VoidCallback? onBackPressed;
final GestureTapCallback? onFilterTap;
final GestureTapCallback? onSearchTap;
@override
State<BasePageWithScroll> createState() => _BasePageWithScrollState();
}
class _BasePageWithScrollState extends State<BasePageWithScroll> {
BaseLogic get controller => Get.find<BaseLogic>();
Worker? filterWorker;
@override
void dispose() {
filterWorker?.dispose();
super.dispose();
}
void _onFilterTap() {
if (widget.hasFilter && widget.filteringWidget != null) {
// بررسی اینکه آیا این route در top است یا نه
final currentRoute = ModalRoute.of(context);
if (currentRoute?.isCurrent != true) {
return;
}
// مستقیماً bottomSheet را باز کنید
Get.bottomSheet(
widget.filteringWidget!,
isScrollControlled: true,
isDismissible: true,
enableDrag: true,
);
}
}
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, result) => widget.onBackPressed,
child: Scaffold(
backgroundColor: AppColor.bgLight,
appBar: chickenAppBar(
hasBack: widget.isBase ? false : widget.hasBack,
onBackPressed: widget.onBackPressed,
hasFilter: widget.hasFilter,
hasSearch: widget.hasSearch,
isBase: widget.isBase,
onFilterTap: widget.hasFilter ? _onFilterTap : null,
onSearchTap: widget.hasSearch ? () => Get.find<SearchLogic>().toggleSearch() : null,
),
body: SingleChildScrollView(
physics: BouncingScrollPhysics(),
padding: EdgeInsets.symmetric(vertical: 8.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.routesWidget != null ? widget.routesWidget! : buildPageRoute(widget.routes!),
if (!widget.isBase && widget.hasSearch) ...{
SearchWidget(onSearchChanged: widget.onSearchChanged),
},
...widget.widgets,
],
),
),
floatingActionButtonLocation: widget.floatingActionButtonLocation,
floatingActionButton: widget.floatingActionButton,
),
);
}
}

View File

@@ -15,7 +15,7 @@ Widget inventoryWidget(StewardRootLogic rootLogic) {
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByCommaFa ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, rootLogic.inventoryModel),