diff --git a/assets/icons/inspection_poultry.svg b/assets/icons/inspection_poultry.svg
new file mode 100644
index 0000000..62afa66
--- /dev/null
+++ b/assets/icons/inspection_poultry.svg
@@ -0,0 +1,10 @@
+
diff --git a/assets/vec/inspection_poultry.svg.vec b/assets/vec/inspection_poultry.svg.vec
new file mode 100644
index 0000000..0e70288
Binary files /dev/null and b/assets/vec/inspection_poultry.svg.vec differ
diff --git a/packages/chicken/lib/data/common/fa_user_role.dart b/packages/chicken/lib/data/common/fa_user_role.dart
index 52e19c2..af8e17f 100644
--- a/packages/chicken/lib/data/common/fa_user_role.dart
+++ b/packages/chicken/lib/data/common/fa_user_role.dart
@@ -1,4 +1,5 @@
import 'package:rasadyar_chicken/features/city_jahad/presentation/routes/routes.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/features/province_inspector/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/features/province_operator/presentation/routes/routes.dart';
@@ -149,7 +150,7 @@ Map getFaUserRoleWithOnTap(String? role) {
case "Dispenser":
return {"پخش کننده": null};
case "CityPoultry":
- return {"طیور شهرستان": null};
+ return {"طیور شهرستان": CityPoultryRoutes.initCityPoultry};
case "ParentCompany":
return {"شرکت مادر": null};
case "ColdHouseSteward":
diff --git a/packages/chicken/lib/data/di/chicken_di.dart b/packages/chicken/lib/data/di/chicken_di.dart
index 483852e..65a6a7d 100644
--- a/packages/chicken/lib/data/di/chicken_di.dart
+++ b/packages/chicken/lib/data/di/chicken_di.dart
@@ -10,6 +10,7 @@ import 'package:rasadyar_chicken/features/steward/data/di/steward_di.dart';
import 'package:rasadyar_chicken/features/province_operator/data/di/province_operator_di.dart';
import 'package:rasadyar_chicken/features/province_inspector/data/di/province_inspector_di.dart';
import 'package:rasadyar_chicken/features/city_jahad/data/di/city_jahad_di.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/di/city_poultry_di.dart';
import 'package:rasadyar_chicken/features/vet_farm/data/di/vet_farm_di.dart';
import 'package:rasadyar_chicken/features/super_admin/data/di/super_admin_di.dart';
import 'package:rasadyar_chicken/features/province_supervisor/data/di/province_supervisor_di.dart';
@@ -74,6 +75,9 @@ Future setupChickenDI() async {
// Setup city_jahad feature DI
await setupCityJahadDI(diChicken, dioRemote);
+ // Setup city_poultry feature DI
+ await setupCityPoultryDI(diChicken, dioRemote);
+
// Setup vet_farm feature DI
await setupVetFarmDI(diChicken, dioRemote);
@@ -138,6 +142,7 @@ Future newSetupAuthDI(String newUrl) async {
await setupProvinceOperatorDI(diChicken, dioRemote);
await setupProvinceInspectorDI(diChicken, dioRemote);
await setupCityJahadDI(diChicken, dioRemote);
+ await setupCityPoultryDI(diChicken, dioRemote);
await setupVetFarmDI(diChicken, dioRemote);
await setupSuperAdminDI(diChicken, dioRemote);
await setupProvinceSupervisorDI(diChicken, dioRemote);
diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart
index 9f8d12a..219f702 100644
--- a/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart
@@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/A',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart
index dc3671a..b249908 100644
--- a/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart
+++ b/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart
@@ -23,7 +23,7 @@ class CityJahadHomeLogic extends GetxController {
CityJahadActionItem(
title: "بازرسی مزارع طیور",
route: CityJahadRoutes.newInspectionCityJahad,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/features/city_poultry/city_poultry.dart b/packages/chicken/lib/features/city_poultry/city_poultry.dart
new file mode 100644
index 0000000..46c55f8
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/city_poultry.dart
@@ -0,0 +1,4 @@
+export 'data/di/city_poultry_di.dart';
+export 'presentation/routes/routes.dart';
+export 'presentation/routes/pages.dart';
+
diff --git a/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart
new file mode 100644
index 0000000..06c1d93
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart
@@ -0,0 +1,16 @@
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart';
+import 'package:rasadyar_core/core.dart';
+
+abstract class CityPoultryRemoteDataSource {
+ Future?> getSubmitInspectionList({
+ required String token,
+ Map? queryParameters,
+ });
+
+ Future submitInspection({
+ required String token,
+ required SubmitInspectionResponse request,
+ });
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart
new file mode 100644
index 0000000..c50aefb
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart
@@ -0,0 +1,40 @@
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart';
+import 'package:rasadyar_core/core.dart';
+
+class CityPoultryRemoteDataSourceImpl implements CityPoultryRemoteDataSource {
+ final DioRemote _httpClient;
+
+ CityPoultryRemoteDataSourceImpl(this._httpClient);
+
+ @override
+ Future?> getSubmitInspectionList({
+ required String token,
+ Map? queryParameters,
+ }) async {
+ var res = await _httpClient.get(
+ '/poultry_science_report/',
+ headers: {'Authorization': 'Bearer $token'},
+ queryParameters: queryParameters,
+ fromJson: (json) => PaginationModel.fromJson(
+ json,
+ (json) => PoultryScienceReport.fromJson(json as Map),
+ ),
+ );
+ return res.data;
+ }
+
+ @override
+ Future submitInspection({
+ required String token,
+ required SubmitInspectionResponse request,
+ }) async {
+ await _httpClient.post(
+ '/poultry_science_report/',
+ headers: {'Authorization': 'Bearer $token'},
+ data: request.toJson(),
+ );
+ }
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/data/di/city_poultry_di.dart b/packages/chicken/lib/features/city_poultry/data/di/city_poultry_di.dart
new file mode 100644
index 0000000..b428c8d
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/data/di/city_poultry_di.dart
@@ -0,0 +1,36 @@
+import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source_impl.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository_impl.dart';
+import 'package:rasadyar_core/core.dart';
+
+/// Setup dependency injection for city_poultry feature
+Future setupCityPoultryDI(GetIt di, DioRemote dioRemote) async {
+ di.registerLazySingleton(
+ () => CityPoultryRemoteDataSourceImpl(dioRemote),
+ );
+
+ di.registerLazySingleton(
+ () => CityPoultryRepositoryImpl(di.get()),
+ );
+}
+
+/// Re-register city_poultry dependencies (used when base URL changes)
+Future reRegisterCityPoultryDI(GetIt di, DioRemote dioRemote) async {
+ await reRegister(di, () => CityPoultryRemoteDataSourceImpl(dioRemote));
+ await reRegister(
+ di,
+ () => CityPoultryRepositoryImpl(di.get()),
+ );
+}
+
+/// Helper function to re-register a dependency
+Future reRegister(
+ GetIt di,
+ T Function() factory,
+) async {
+ if (di.isRegistered()) {
+ await di.unregister();
+ }
+ di.registerLazySingleton(factory);
+}
diff --git a/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository.dart b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository.dart
new file mode 100644
index 0000000..e20a362
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository.dart
@@ -0,0 +1,16 @@
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart';
+import 'package:rasadyar_core/core.dart';
+
+abstract class CityPoultryRepository {
+ Future?> getSubmitInspectionList({
+ required String token,
+ Map? queryParameters,
+ });
+
+ Future submitInspection({
+ required String token,
+ required SubmitInspectionResponse request,
+ });
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository_impl.dart b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository_impl.dart
new file mode 100644
index 0000000..61f33ff
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/data/repositories/city_poultry_repository_impl.dart
@@ -0,0 +1,31 @@
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/datasources/remote/city_poultry_remote_data_source.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository.dart';
+import 'package:rasadyar_core/core.dart';
+
+class CityPoultryRepositoryImpl implements CityPoultryRepository {
+ final CityPoultryRemoteDataSource _remote;
+
+ CityPoultryRepositoryImpl(this._remote);
+
+ @override
+ Future?> getSubmitInspectionList({
+ required String token,
+ Map? queryParameters,
+ }) async {
+ return await _remote.getSubmitInspectionList(
+ token: token,
+ queryParameters: queryParameters,
+ );
+ }
+
+ @override
+ Future submitInspection({
+ required String token,
+ required SubmitInspectionResponse request,
+ }) async {
+ return await _remote.submitInspection(token: token, request: request);
+ }
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/logic.dart
new file mode 100644
index 0000000..dbbd23d
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/logic.dart
@@ -0,0 +1,96 @@
+import 'package:rasadyar_chicken/data/di/chicken_di.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/logic.dart';
+import 'package:rasadyar_core/core.dart';
+
+class ActiveHatchingLogic extends GetxController {
+ CityPoultryRootLogic rootLogic = Get.find();
+ BaseLogic baseLogic = Get.find();
+ late PoultryScienceRepository poultryScienceRepository;
+ Rx>> activeHatchingList =
+ Resource>.loading().obs;
+
+ final RxBool isLoadingMoreList = false.obs;
+ RxInt currentPage = 1.obs;
+ RxInt expandedIndex = RxInt(-1);
+ List routesName = ['اقدام', 'جوجه ریزی فعال'];
+
+ Rx fromDateFilter = Jalali.now().obs;
+ Rx toDateFilter = Jalali.now().obs;
+ RxnString searchedValue = RxnString();
+
+ @override
+ void onInit() {
+ super.onInit();
+ poultryScienceRepository = diChicken.get();
+ }
+
+ @override
+ void onReady() {
+ super.onReady();
+ getHatchingList();
+ }
+
+ @override
+ void onClose() {
+ super.onClose();
+ baseLogic.clearSearch();
+ }
+
+ Future getHatchingList([bool isLoadingMore = false]) async {
+ if (isLoadingMore) {
+ isLoadingMoreList.value = true;
+ } else {
+ activeHatchingList.value =
+ Resource>.loading();
+ }
+
+ if (searchedValue.value != null &&
+ searchedValue.value!.trim().isNotEmpty &&
+ currentPage.value > 1) {
+ currentPage.value = 1;
+ }
+
+ safeCall(
+ call: () async => await poultryScienceRepository.getHatchingPoultry(
+ token: rootLogic.tokenService.accessToken.value!,
+ queryParameters: buildQueryParams(
+ queryParams: {'type': 'hatching'},
+ role: 'CityPoultry',
+ pageSize: 50,
+ page: currentPage.value,
+ ),
+ ),
+ onSuccess: (res) {
+ if ((res?.count ?? 0) == 0) {
+ activeHatchingList.value =
+ Resource>.empty();
+ } else {
+ activeHatchingList.value =
+ Resource>.success(
+ PaginationModel(
+ count: res?.count ?? 0,
+ next: res?.next,
+ previous: res?.previous,
+ results: [
+ ...(activeHatchingList.value.data?.results ?? []),
+ ...(res?.results ?? []),
+ ],
+ ),
+ );
+ }
+ },
+ );
+ }
+
+ void toggleExpanded(int index) {
+ expandedIndex.value = expandedIndex.value == index ? -1 : index;
+ }
+
+ Future onRefresh() async {
+ currentPage.value = 1;
+ await getHatchingList();
+ }
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/view.dart
new file mode 100644
index 0000000..27f71da
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/active_hatching/view.dart
@@ -0,0 +1,236 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/active_hatching/logic.dart';
+import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart';
+import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_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';
+
+class ActiveHatchingPage extends GetView {
+ const ActiveHatchingPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ChickenBasePage(
+ hasSearch: true,
+ hasFilter: false,
+ backId: cityPoultryActionKey,
+ routes: controller.routesName,
+ onSearchChanged: (data) {
+ controller.searchedValue.value = data;
+ controller.getHatchingList();
+ },
+ child: hatchingWidget(),
+ );
+ }
+
+ Widget hatchingWidget() {
+ return 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.value.isEqual(index),
+ onTap: () => controller.toggleExpanded(index),
+ index: index,
+ child: itemListWidget(item),
+ secondChild: itemListExpandedWidget(item),
+ labelColor: AppColor.blueLight,
+ labelIcon: Assets.vec.activeFramSvg.path,
+ );
+ }, controller.expandedIndex);
+ },
+ itemCount: data.value.data?.results?.length ?? 0,
+ separatorBuilder: (context, index) => SizedBox(height: 8.h),
+ onLoadMore: () async => controller.getHatchingList(true),
+ );
+ }, controller.activeHatchingList);
+ }
+
+ Container itemListExpandedWidget(HatchingModel 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?.user?.fullname ?? 'N/A',
+ textAlign: TextAlign.center,
+ style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
+ ),
+ Spacer(),
+
+ Visibility(
+ child: Text(
+ item.violation == true ? 'پیگیری' : 'عادی',
+ textAlign: TextAlign.center,
+ style: AppFonts.yekan10.copyWith(color: AppColor.redDark),
+ ),
+ ),
+ ],
+ ),
+ 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.breed?.first.breed ?? 'N/A'}',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ Text(
+ ' سن${item.age} (روز)',
+
+ style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
+ ),
+ Text(
+ ' دوره جوجه ریزی:${item.period}',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ],
+ ),
+ ),
+
+ buildRow(
+ title: 'شماره مجوز جوجه ریزی',
+ value: item.licenceNumber ?? 'N/A',
+ ),
+ buildUnitRow(
+ title: 'حجم جوجه ریزی',
+ value: item.quantity.separatedByCommaFa,
+ unit: '(قطعه)',
+ ),
+ buildUnitRow(
+ title: 'مانده در سالن',
+ value: item.leftOver.separatedByCommaFa,
+ unit: '(قطعه)',
+ ),
+ buildUnitRow(
+ title: 'تلفات',
+ value: item.losses.separatedByCommaFa,
+ unit: '(قطعه)',
+ ),
+ buildRow(
+ title: 'دامپزشک فارم',
+ value:
+ '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})',
+ ),
+ buildRow(
+ title: 'شرح بازرسی',
+ value: item.reportInfo?.image == false
+ ? 'ارسال تصویر جوجه ریزی فارم '
+ : 'تکمیل شده',
+ titleStyle: AppFonts.yekan14.copyWith(
+ color: (item.reportInfo?.image ?? false)
+ ? AppColor.greenNormal
+ : AppColor.redDark,
+ ),
+ valueStyle: AppFonts.yekan14.copyWith(
+ color: (item.reportInfo?.image ?? false)
+ ? AppColor.greenNormal
+ : AppColor.redDark,
+ ),
+ ),
+
+ RElevated(
+ height: 40.h,
+ isFullWidth: true,
+ onPressed: () {
+ Get.find().setHatchingModel(
+ item,
+ );
+ Get.bottomSheet(
+ CreateInspectionBottomSheet(),
+ isScrollControlled: true,
+ ignoreSafeArea: false,
+ ).then((value) {
+ if (Get.isRegistered()) {
+ Get.find().clearForm();
+ }
+ });
+ },
+ child: Text('ثبت بازرسی'),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget itemListWidget(HatchingModel item) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ SizedBox(width: 20),
+ Expanded(
+ flex: 2,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 3,
+ children: [
+ Text(
+ item.poultry?.user?.fullname ?? 'ندارد',
+ textAlign: TextAlign.start,
+ style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
+ ),
+ Text(
+ item.poultry?.user?.mobile ?? 'ندارد',
+ 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.poultry?.unitName ?? 'ندارد',
+ textAlign: TextAlign.start,
+ style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
+ ),
+ Text(
+ item.licenceNumber ?? 'ندارد',
+ textAlign: TextAlign.left,
+ style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
+ ),
+ ],
+ ),
+ ),
+ Expanded(
+ flex: 1,
+ child: Assets.vec.scanSvg.svg(
+ width: 32.w,
+ height: 32.h,
+ colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/home/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/home/logic.dart
new file mode 100644
index 0000000..b7000b0
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/home/logic.dart
@@ -0,0 +1,29 @@
+import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart';
+import 'package:rasadyar_core/core.dart';
+
+class CityPoultryActionItem {
+ final String title;
+ final String route;
+ final String icon;
+
+ CityPoultryActionItem({
+ required this.title,
+ required this.route,
+ required this.icon,
+ });
+}
+
+class CityPoultryHomeLogic extends GetxController {
+ RxList items = [
+ CityPoultryActionItem(
+ title: "جوجه ریزی فعال",
+ route: CityPoultryRoutes.activeHatchingCityPoultry,
+ icon: Assets.vec.activeFramSvg.path,
+ ),
+ CityPoultryActionItem(
+ title: "بازرسی مزارع طیور",
+ route: CityPoultryRoutes.newInspectionCityPoultry,
+ icon: Assets.vec.inspectionPoultrySvg.path,
+ ),
+ ].obs;
+}
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/home/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/home/view.dart
new file mode 100644
index 0000000..80fd793
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/home/view.dart
@@ -0,0 +1,47 @@
+import 'package:flutter/material.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 CityPoultryHomePage extends GetView {
+ CityPoultryHomePage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ChickenBasePage(
+ isBase: true,
+ hasNews: true,
+ hasNotification: true,
+ child: gridWidget(),
+ );
+ }
+
+ Widget gridWidget() {
+ return ObxValue((data) {
+ return GridView.builder(
+ physics: BouncingScrollPhysics(),
+ padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w),
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 2,
+ mainAxisSpacing: 24.h,
+ crossAxisSpacing: 24.w,
+ ),
+ itemCount: data.length,
+ hitTestBehavior: HitTestBehavior.opaque,
+ itemBuilder: (BuildContext context, int index) {
+ var item = data[index];
+ return GlassMorphismCardIcon(
+ title: item.title,
+ vecIcon: item.icon,
+ onTap: () async {
+ Get.toNamed(item.route, id: cityPoultryActionKey);
+ },
+ );
+ },
+ );
+ }, controller.items);
+ }
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/logic.dart
new file mode 100644
index 0000000..ffde772
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/logic.dart
@@ -0,0 +1,160 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/logic.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart';
+import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
+import 'package:rasadyar_core/core.dart';
+
+class NewInspectionLogic extends GetxController {
+ BaseLogic baseLogic = Get.find();
+
+ Rx>> submitInspectionList =
+ Resource>.loading().obs;
+
+ CityPoultryRootLogic rootLogic = Get.find();
+
+ final RxBool isLoadingMoreAllocationsMade = false.obs;
+ RxInt currentPage = 1.obs;
+ RxInt expandedIndex = RxInt(-1);
+ RxList pickedImages = [].obs;
+
+ RxBool isOnUpload = false.obs;
+
+ RxDouble presentUpload = 0.0.obs;
+ RxList routesName = RxList();
+ RxInt selectedSegmentIndex = 0.obs;
+
+ RxnString searchedValue = RxnString();
+ Rx fromDateFilter = Jalali.now().obs;
+ Rx toDateFilter = Jalali.now().obs;
+
+ @override
+ void onInit() {
+ super.onInit();
+
+ routesName.value = ['اقدام'].toList();
+
+ ever(selectedSegmentIndex, (callback) {
+ routesName.removeLast();
+ routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی');
+ });
+ }
+
+ @override
+ void onReady() {
+ super.onReady();
+
+ getReport();
+ }
+
+ @override
+ void onClose() {
+ super.onClose();
+ baseLogic.clearSearch();
+ }
+
+ Future getReport([bool isLoadingMore = false]) async {
+ if (isLoadingMore) {
+ isLoadingMoreAllocationsMade.value = true;
+ } else {
+ submitInspectionList.value =
+ Resource>.loading();
+ }
+
+ if (searchedValue.value != null &&
+ searchedValue.value!.trim().isNotEmpty &&
+ currentPage.value > 1) {
+ currentPage.value = 1;
+ }
+
+ safeCall(
+ call: () async =>
+ await rootLogic.cityPoultryRepository.getSubmitInspectionList(
+ token: rootLogic.tokenService.accessToken.value!,
+ queryParameters: buildQueryParams(
+ role: 'CityPoultry',
+ pageSize: 50,
+ search: 'filter',
+
+ page: currentPage.value,
+ ),
+ ),
+ onSuccess: (res) {
+ if ((res?.count ?? 0) == 0) {
+ submitInspectionList.value =
+ Resource>.empty();
+ } else {
+ submitInspectionList.value =
+ Resource>.success(
+ PaginationModel(
+ count: res?.count ?? 0,
+ next: res?.next,
+ previous: res?.previous,
+ results: [
+ ...(submitInspectionList.value.data?.results ?? []),
+ ...(res?.results ?? []),
+ ],
+ ),
+ );
+ }
+ },
+ );
+ }
+
+ Future pickImages() async {
+ determineCurrentPosition();
+ var tmp = await pickCameraImage();
+ if (tmp?.path != null && pickedImages.length < 7) {
+ pickedImages.add(tmp!);
+ }
+ }
+
+ void removeImage(int index) {
+ pickedImages.removeAt(index);
+ }
+
+ void closeBottomSheet() {
+ Get.back();
+ }
+
+ double calculateUploadProgress({required int sent, required int total}) {
+ if (total != 0) {
+ double progress = (sent * 100 / total) / 100;
+ return progress;
+ } else {
+ return 0.0;
+ }
+ }
+
+ void toggleExpanded(int index) {
+ expandedIndex.value = expandedIndex.value == index ? -1 : index;
+ }
+
+ void setSearchValue(String? data) {
+ dLog('Search Value: $data');
+ searchedValue.value = data?.trim();
+ getReport();
+ }
+
+ Future onRefresh() async {
+ currentPage.value = 1;
+ await getReport();
+ }
+
+ String getStatus(PoultryScienceReport item) {
+ final status = item.reportInformation?.inspectionStatus ?? item.state;
+ if (status == null || status.isEmpty) {
+ return 'در حال بررسی';
+ }
+ return status;
+ }
+
+ Color getStatusColor(PoultryScienceReport item) {
+ final status = item.reportInformation?.inspectionStatus ?? item.state;
+ if (status == null || status.isEmpty) {
+ return AppColor.yellowNormal;
+ }
+ // میتوانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید
+ return AppColor.greenNormal;
+ }
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/view.dart
new file mode 100644
index 0000000..d77fcc1
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/new_inspection/view.dart
@@ -0,0 +1,1134 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_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_core/core.dart';
+
+import 'logic.dart';
+
+class NewInspectionPage extends GetView {
+ const NewInspectionPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ChickenBasePage(
+ hasBack: true,
+ hasFilter: true,
+ hasSearch: true,
+ onFilterTap: () {
+ Get.bottomSheet(filterBottomSheet());
+ },
+ onRefresh: controller.onRefresh,
+ onSearchChanged: (data) => controller.setSearchValue(data),
+ backId: cityPoultryActionKey,
+ routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName),
+ child: Column(children: [reportWidget()]),
+ );
+ }
+
+ Widget reportWidget() {
+ 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.value.isEqual(index),
+ onTap: () => controller.toggleExpanded(index),
+ index: index,
+ child: itemListWidgetReport(item),
+ secondChild: itemListExpandedWidgetReport(item),
+ labelColor: AppColor.greenLight,
+ labelIcon: Assets.vec.cubeSearchSvg.path,
+ );
+ }, controller.expandedIndex);
+ },
+ itemCount: data.value.data?.results?.length ?? 0,
+ separatorBuilder: (context, index) => SizedBox(height: 8.h),
+ onLoadMore: () async => controller.getReport(true),
+ );
+ }, controller.submitInspectionList),
+ );
+ }
+
+ Widget itemListExpandedWidgetReport(PoultryScienceReport item) {
+ return Container(
+ padding: EdgeInsets.symmetric(horizontal: 8),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ spacing: 8,
+ children: [
+ buildRow(
+ title: 'وضعیت بازرسی',
+ value: controller.getStatus(item),
+ titleStyle: AppFonts.yekan14.copyWith(
+ color: controller.getStatusColor(item),
+ ),
+ valueStyle: AppFonts.yekan14.copyWith(
+ color: controller.getStatusColor(item),
+ ),
+ ),
+ if (item.hatching?.poultry?.unitName != null)
+ buildRow(
+ title: 'مرغداری',
+ value: item.hatching?.poultry?.unitName ?? '-',
+ ),
+ if (item.hatching?.id != null)
+ buildRow(
+ title: 'شناسه جوجهریزی',
+ value: item.hatching!.id.toString(),
+ ),
+
+ if (item
+ .reportInformation
+ ?.technicalOfficer
+ ?.technicalHealthOfficer !=
+ null)
+ buildRow(
+ title: 'کارشناس بهداشت',
+ value:
+ item
+ .reportInformation!
+ .technicalOfficer!
+ .technicalHealthOfficer ??
+ '-',
+ ),
+ if (item
+ .reportInformation
+ ?.technicalOfficer
+ ?.technicalEngineeringOfficer !=
+ null)
+ buildRow(
+ title: 'کارشناس فنی',
+ value:
+ item
+ .reportInformation!
+ .technicalOfficer!
+ .technicalEngineeringOfficer ??
+ '-',
+ ),
+ if (item.reportInformation?.casualties?.normalLosses != null ||
+ item.reportInformation?.casualties?.abnormalLosses != null)
+ buildUnitRow(
+ title: 'تلفات عادی',
+ value: (item.reportInformation?.casualties?.normalLosses ?? 0)
+ .toString(),
+ unit: '(قطعه)',
+ ),
+ if (item.reportInformation?.casualties?.abnormalLosses != null)
+ buildUnitRow(
+ title: 'تلفات غیرعادی',
+ value: item.reportInformation!.casualties!.abnormalLosses
+ .toString(),
+ unit: '(قطعه)',
+ ),
+
+ if (item.reportInformation?.inspectionNotes != null &&
+ item.reportInformation!.inspectionNotes!.isNotEmpty)
+ buildRow(
+ title: 'یادداشت بازرسی',
+ value: item.reportInformation!.inspectionNotes ?? '-',
+ ),
+
+ RElevated(
+ text: 'جزییات',
+ isFullWidth: true,
+ width: 150.w,
+ height: 40.h,
+ onPressed: () {
+ showDetailsBottomSheet(item);
+ },
+ textStyle: AppFonts.yekan16.copyWith(color: Colors.white),
+ backgroundColor: AppColor.greenNormal,
+ ),
+ ],
+ ),
+ );
+ }
+
+ Row itemListWidgetReport(PoultryScienceReport item) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ children: [
+ SizedBox(width: 20),
+ Expanded(
+ flex: 2,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ spacing: 5,
+ children: [
+ Text(
+ 'شناسه جوجهریزی: ${item.hatching?.id ?? '-'}',
+ textAlign: TextAlign.center,
+ style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
+ ),
+
+ Text(
+ item.createDate?.toJalali.formatCompactDate() ?? '-',
+ style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon),
+ ),
+ ],
+ ),
+ ),
+ Expanded(
+ flex: 3,
+ child: Column(
+ spacing: 5,
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text(
+ 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}',
+ textAlign: TextAlign.center,
+ style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
+ ),
+ if (item.reportInformation?.inspectionStatus != null)
+ Text(
+ 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}',
+ textAlign: TextAlign.center,
+ style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon),
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ void showDetailsBottomSheet(PoultryScienceReport item) {
+ Get.bottomSheet(
+ isScrollControlled: true,
+ BaseBottomSheet(
+ height: Get.height * 0.8,
+ rootChild: DetailsBottomSheetWidget(item: item),
+ ),
+ );
+ }
+
+ Widget filterBottomSheet() {
+ return BaseBottomSheet(
+ height: 200,
+ child: Column(
+ spacing: 16,
+ children: [
+ Text(
+ 'فیلترها',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
+ ),
+ Row(
+ spacing: 8,
+ children: [
+ Expanded(
+ child: dateFilterWidget(
+ date: controller.fromDateFilter,
+ onChanged: (jalali) =>
+ controller.fromDateFilter.value = jalali,
+ ),
+ ),
+ Expanded(
+ child: dateFilterWidget(
+ isFrom: false,
+ date: controller.toDateFilter,
+ onChanged: (jalali) => controller.toDateFilter.value = jalali,
+ ),
+ ),
+ ],
+ ),
+ RElevated(
+ text: 'اعمال فیلتر',
+ isFullWidth: true,
+ backgroundColor: AppColor.greenNormal,
+ onPressed: () {
+ controller.getReport();
+ Get.back();
+ },
+ height: 40,
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class DetailsBottomSheetWidget extends StatefulWidget {
+ final PoultryScienceReport item;
+
+ const DetailsBottomSheetWidget({super.key, required this.item});
+
+ @override
+ State createState() =>
+ _DetailsBottomSheetWidgetState();
+}
+
+class _DetailsBottomSheetWidgetState extends State {
+ int selectedTabIndex = 0;
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Row(
+ children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 4,
+ vertical: 10,
+ ),
+ child: Text(
+ 'جزییات',
+ style: AppFonts.yekan18Bold.copyWith(
+ color: AppColor.iconColor,
+ ),
+ ),
+ ),
+ ],
+ ),
+ Divider(color: AppColor.blackLightHover, height: 1, thickness: 1),
+ tabBarWidget(
+ [
+ 'اطلاعات کلی',
+ 'شرایط سالن',
+ 'تلفات',
+ 'کارشناس',
+ 'نهاده',
+ 'زیرساخت',
+ 'نیروی انسانی',
+ 'تسهیلات',
+ ],
+ selectedTabIndex,
+ (index) => setState(() => selectedTabIndex = index),
+ ),
+ ],
+ ),
+ ),
+ Expanded(
+ child: SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: _buildTableContent(),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget _buildTableContent() {
+ switch (selectedTabIndex) {
+ case 0:
+ return generalInfoTable();
+ case 1:
+ return generalConditionHallTable();
+ case 2:
+ return casualtiesTable();
+ case 3:
+ return technicalOfficerTable();
+ case 4:
+ return inputStatusTable();
+ case 5:
+ return infrastructureEnergyTable();
+ case 6:
+ return hrTable();
+ case 7:
+ return facilitiesTable();
+ default:
+ return generalInfoTable();
+ }
+ }
+
+ Widget technicalOfficerTable() {
+ final officer = widget.item.reportInformation?.technicalOfficer;
+ if (officer == null) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(20),
+ child: Text(
+ 'اطلاعاتی وجود ندارد',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'کارشناس فنی',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ rTableRow(
+ title: 'کارشناس بهداشت',
+ value: officer.technicalHealthOfficer ?? '-',
+ ),
+ rTableRow(
+ title: 'کارشناس فنی',
+ value: officer.technicalEngineeringOfficer ?? '-',
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget generalInfoTable() {
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'اطلاعات کلی',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ rTableRow(
+ title: 'وضعیت بازرسی',
+ value:
+ widget.item.reportInformation?.inspectionStatus ??
+ widget.item.state ??
+ '-',
+ ),
+ rTableRow(
+ title: 'یادداشت بازرسی',
+ value: widget.item.reportInformation?.inspectionNotes ?? '-',
+ ),
+ rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'),
+ if (widget.item.lat != null && widget.item.log != null)
+ rTableRow(
+ title: 'موقعیت',
+ value: '${widget.item.lat}, ${widget.item.log}',
+ ),
+ if (widget.item.hatching?.id != null)
+ rTableRow(
+ title: 'شناسه جوجه ریزی',
+ value: widget.item.hatching!.id.toString(),
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget generalConditionHallTable() {
+ final hall = widget.item.reportInformation?.generalConditionHall;
+ if (hall == null) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(20),
+ child: Text(
+ 'اطلاعاتی وجود ندارد',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'شرایط عمومی سالن',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'),
+ rTableRow(
+ title: 'وضعیت تهویه',
+ value: hall.ventilationStatus ?? '-',
+ ),
+ rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'),
+ rTableRow(title: 'دما', value: hall.temperature ?? '-'),
+ rTableRow(
+ title: 'منبع آب آشامیدنی',
+ value: hall.drinkingWaterSource ?? '-',
+ ),
+ rTableRow(
+ title: 'کیفیت آب آشامیدنی',
+ value: hall.drinkingWaterQuality ?? '-',
+ ),
+ ],
+ ),
+ ),
+ if (hall.images != null && hall.images!.isNotEmpty) ...[
+ SizedBox(height: 16),
+ Text(
+ 'تصاویر',
+ style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor),
+ ),
+ SizedBox(height: 10),
+ SizedBox(
+ height: 100.h,
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+ itemCount: hall.images!.length,
+ separatorBuilder: (context, index) => SizedBox(width: 10),
+ itemBuilder: (context, index) => GestureDetector(
+ onTap: () => showImageDialog(hall.images!, index),
+ child: Container(
+ width: 80.w,
+ height: 80.h,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ image: DecorationImage(
+ fit: BoxFit.cover,
+ image: NetworkImage(hall.images![index]),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ],
+ );
+ }
+
+ Widget casualtiesTable() {
+ final casualties = widget.item.reportInformation?.casualties;
+ if (casualties == null) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(20),
+ child: Text(
+ 'اطلاعاتی وجود ندارد',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'تلفات',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ if (casualties.normalLosses != null)
+ rTableRow(
+ title: 'تلفات عادی',
+ value: casualties.normalLosses.toString(),
+ ),
+ if (casualties.abnormalLosses != null)
+ rTableRow(
+ title: 'تلفات غیرعادی',
+ value: casualties.abnormalLosses.toString(),
+ ),
+ rTableRow(
+ title: 'منبع جوجه ریزی',
+ value: casualties.sourceOfHatching ?? '-',
+ ),
+ rTableRow(
+ title: 'علت تلفات غیرعادی',
+ value: casualties.causeAbnormalLosses ?? '-',
+ ),
+ rTableRow(
+ title: 'نوع بیماری',
+ value: casualties.typeDisease ?? '-',
+ ),
+ rTableRow(
+ title: 'نمونهبرداری انجام شده',
+ value: casualties.samplingDone == true ? 'بله' : 'خیر',
+ ),
+ rTableRow(
+ title: 'نوع نمونهبرداری',
+ value: casualties.typeSampling ?? '-',
+ ),
+ ],
+ ),
+ ),
+ if (casualties.images != null && casualties.images!.isNotEmpty) ...[
+ SizedBox(height: 16),
+ Text(
+ 'تصاویر',
+ style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor),
+ ),
+ SizedBox(height: 10),
+ SizedBox(
+ height: 100.h,
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+ itemCount: casualties.images!.length,
+ separatorBuilder: (context, index) => SizedBox(width: 10),
+ itemBuilder: (context, index) => GestureDetector(
+ onTap: () => showImageDialog(casualties.images!, index),
+ child: Container(
+ width: 80.w,
+ height: 80.h,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ image: DecorationImage(
+ fit: BoxFit.cover,
+ image: NetworkImage(casualties.images![index]),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ],
+ );
+ }
+
+ Widget inputStatusTable() {
+ final inputStatus = widget.item.reportInformation?.inputStatus;
+ if (inputStatus == null) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(20),
+ child: Text(
+ 'اطلاعاتی وجود ندارد',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'وضعیت نهاده',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ rTableRow(
+ title: 'وضعیت نهاده',
+ value: inputStatus.inputStatus ?? '-',
+ ),
+ rTableRow(
+ title: 'نام شرکت',
+ value: inputStatus.companyName ?? '-',
+ ),
+ rTableRow(
+ title: 'کد پیگیری',
+ value: inputStatus.trackingCode ?? '-',
+ ),
+ rTableRow(
+ title: 'نوع دانه',
+ value: inputStatus.typeOfGrain ?? '-',
+ ),
+ rTableRow(
+ title: 'موجودی در انبار',
+ value: inputStatus.inventoryInWarehouse ?? '-',
+ ),
+ rTableRow(
+ title: 'موجودی تا بازدید',
+ value: inputStatus.inventoryUntilVisit ?? '-',
+ ),
+ rTableRow(
+ title: 'درجه دانه',
+ value: inputStatus.gradeGrain ?? '-',
+ ),
+ ],
+ ),
+ ),
+ if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[
+ SizedBox(height: 16),
+ Text(
+ 'تصاویر',
+ style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor),
+ ),
+ SizedBox(height: 10),
+ SizedBox(
+ height: 100.h,
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+ itemCount: inputStatus.images!.length,
+ separatorBuilder: (context, index) => SizedBox(width: 10),
+ itemBuilder: (context, index) => GestureDetector(
+ onTap: () => showImageDialog(inputStatus.images!, index),
+ child: Container(
+ width: 80.w,
+ height: 80.h,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ image: DecorationImage(
+ fit: BoxFit.cover,
+ image: NetworkImage(inputStatus.images![index]),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ],
+ );
+ }
+
+ Widget infrastructureEnergyTable() {
+ final infra = widget.item.reportInformation?.infrastructureEnergy;
+ if (infra == null) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(20),
+ child: Text(
+ 'اطلاعاتی وجود ندارد',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'زیرساخت و انرژی',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ rTableRow(
+ title: 'نوع ژنراتور',
+ value: infra.generatorType ?? '-',
+ ),
+ rTableRow(
+ title: 'مدل ژنراتور',
+ value: infra.generatorModel ?? '-',
+ ),
+ rTableRow(
+ title: 'تعداد ژنراتور',
+ value: infra.generatorCount ?? '-',
+ ),
+ rTableRow(
+ title: 'ظرفیت ژنراتور',
+ value: infra.generatorCapacity ?? '-',
+ ),
+ rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'),
+ rTableRow(
+ title: 'عملکرد ژنراتور',
+ value: infra.generatorPerformance ?? '-',
+ ),
+ rTableRow(
+ title: 'موجودی سوخت اضطراری',
+ value: infra.emergencyFuelInventory ?? '-',
+ ),
+ rTableRow(
+ title: 'تاریخچه قطع برق',
+ value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر',
+ ),
+ if (infra.hasPowerCutHistory == true) ...[
+ rTableRow(
+ title: 'مدت قطع برق',
+ value: infra.powerCutDuration ?? '-',
+ ),
+ rTableRow(
+ title: 'ساعت قطع برق',
+ value: infra.powerCutHour ?? '-',
+ ),
+ ],
+ rTableRow(
+ title: 'یادداشت اضافی',
+ value: infra.additionalNotes ?? '-',
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget hrTable() {
+ final hr = widget.item.reportInformation?.hr;
+ if (hr == null) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(20),
+ child: Text(
+ 'اطلاعاتی وجود ندارد',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'نیروی انسانی',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ if (hr.numberEmployed != null)
+ rTableRow(
+ title: 'تعداد شاغلین',
+ value: hr.numberEmployed.toString(),
+ ),
+ if (hr.numberIndigenous != null)
+ rTableRow(
+ title: 'تعداد بومی',
+ value: hr.numberIndigenous.toString(),
+ ),
+ if (hr.numberNonIndigenous != null)
+ rTableRow(
+ title: 'تعداد غیربومی',
+ value: hr.numberNonIndigenous.toString(),
+ ),
+ rTableRow(
+ title: 'وضعیت قرارداد',
+ value: hr.contractStatus ?? '-',
+ ),
+ rTableRow(
+ title: 'آموزش دیده',
+ value: hr.trained == true ? 'بله' : 'خیر',
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget facilitiesTable() {
+ final facilities = widget.item.reportInformation?.facilities;
+ if (facilities == null) {
+ return Center(
+ child: Padding(
+ padding: const EdgeInsets.all(20),
+ child: Text(
+ 'اطلاعاتی وجود ندارد',
+ style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ );
+ }
+
+ return Column(
+ children: [
+ SizedBox(height: 10),
+ Row(
+ children: [
+ Text(
+ 'تسهیلات',
+ style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ],
+ ),
+ SizedBox(height: 10),
+ Container(
+ clipBehavior: Clip.hardEdge,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Column(
+ children: [
+ rTableRow(
+ title: 'دارای تسهیلات',
+ value: facilities.hasFacilities == true ? 'بله' : 'خیر',
+ ),
+ rTableRow(
+ title: 'نوع تسهیلات',
+ value: facilities.typeOfFacility ?? '-',
+ ),
+ if (facilities.amount != null)
+ rTableRow(title: 'مبلغ', value: facilities.amount.toString()),
+ rTableRow(title: 'تاریخ', value: facilities.date ?? '-'),
+ rTableRow(
+ title: 'وضعیت بازپرداخت',
+ value: facilities.repaymentStatus ?? '-',
+ ),
+ rTableRow(
+ title: 'درخواست تسهیلات',
+ value: facilities.requestFacilities ?? '-',
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget tabBarWidget(
+ List tabs,
+ int selectedIndex,
+ Function(int) onTabSelected,
+ ) {
+ return SizedBox(
+ height: 40.h,
+ width: Get.width,
+ child: Column(
+ children: [
+ SingleChildScrollView(
+ scrollDirection: Axis.horizontal,
+ reverse: true,
+ child: Row(
+ children: [
+ ...tabs.map(
+ (tab) => GestureDetector(
+ onTap: () => onTabSelected(tabs.indexOf(tab)),
+ behavior: HitTestBehavior.opaque,
+ child: Container(
+ padding: EdgeInsets.symmetric(
+ horizontal: 10,
+ vertical: 11,
+ ),
+ decoration: BoxDecoration(
+ border: tab == tabs[selectedIndex]
+ ? Border(
+ bottom: BorderSide(
+ color: AppColor.blueNormalOld,
+ width: 3,
+ ),
+ )
+ : null,
+ ),
+ child: Text(
+ tab,
+ style: AppFonts.yekan12Bold.copyWith(
+ color: tab == tabs[selectedIndex]
+ ? AppColor.blueNormalOld
+ : AppColor.mediumGrey,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ Divider(color: AppColor.blackLightHover, height: 1, thickness: 1),
+ ],
+ ),
+ );
+ }
+
+ Row rTableRow({String? title, String? value}) {
+ return Row(
+ children: [
+ Expanded(
+ flex: 1,
+ child: Container(
+ padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11),
+ alignment: Alignment.centerRight,
+ decoration: BoxDecoration(
+ color: AppColor.bgLight2,
+ border: Border(
+ bottom: BorderSide(color: AppColor.blackLightHover, width: 1),
+ ),
+ ),
+ child: Text(
+ title ?? '',
+ style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor),
+ ),
+ ),
+ ),
+ Expanded(
+ flex: 1,
+ child: Container(
+ padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11),
+ alignment: Alignment.centerRight,
+ decoration: BoxDecoration(
+ border: Border(
+ bottom: BorderSide(color: AppColor.blackLightHover, width: 1),
+ ),
+ ),
+ child: Text(
+ value ?? '',
+ style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ void showImageDialog(List images, int initialIndex) {
+ final pageController = PageController(initialPage: initialIndex);
+ final currentIndex = initialIndex.obs;
+
+ Get.dialog(
+ Dialog(
+ backgroundColor: Colors.transparent,
+ insetPadding: EdgeInsets.zero,
+ child: Container(
+ width: Get.width,
+ height: Get.height,
+ color: Colors.black,
+ child: Stack(
+ children: [
+ PageView.builder(
+ controller: pageController,
+ itemCount: images.length,
+ onPageChanged: (index) {
+ currentIndex.value = index;
+ },
+ itemBuilder: (context, index) {
+ return InteractiveViewer(
+ minScale: 0.5,
+ maxScale: 4.0,
+ child: Center(
+ child: Image.network(
+ images[index],
+ fit: BoxFit.contain,
+ loadingBuilder: (context, child, loadingProgress) {
+ if (loadingProgress == null) return child;
+ return Center(
+ child: CircularProgressIndicator(
+ value: loadingProgress.expectedTotalBytes != null
+ ? loadingProgress.cumulativeBytesLoaded /
+ loadingProgress.expectedTotalBytes!
+ : null,
+ color: Colors.white,
+ ),
+ );
+ },
+ errorBuilder: (context, error, stackTrace) {
+ return Center(
+ child: Icon(
+ Icons.error,
+ color: Colors.white,
+ size: 50,
+ ),
+ );
+ },
+ ),
+ ),
+ );
+ },
+ ),
+ Positioned(
+ top: 40,
+ right: 16,
+ child: IconButton(
+ icon: Icon(Icons.close, color: Colors.white, size: 30),
+ onPressed: () => Get.back(),
+ ),
+ ),
+ if (images.length > 1)
+ Positioned(
+ bottom: 20,
+ left: 0,
+ right: 0,
+ child: Center(
+ child: Obx(
+ () => Container(
+ padding: EdgeInsets.symmetric(
+ horizontal: 12,
+ vertical: 6,
+ ),
+ decoration: BoxDecoration(
+ color: Colors.black54,
+ borderRadius: BorderRadius.circular(20),
+ ),
+ child: Text(
+ '${currentIndex.value + 1} / ${images.length}',
+ style: TextStyle(color: Colors.white, fontSize: 14),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ barrierDismissible: true,
+ );
+ }
+}
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/root/logic.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/root/logic.dart
new file mode 100644
index 0000000..327dcb3
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/root/logic.dart
@@ -0,0 +1,100 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:rasadyar_chicken/data/di/chicken_di.dart';
+import 'package:rasadyar_chicken/features/city_poultry/data/repositories/city_poultry_repository.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/pages.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart';
+import 'package:rasadyar_chicken/features/common/presentation/page/profile/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';
+
+enum ErrorLocationType { serviceDisabled, permissionDenied, none }
+
+class CityPoultryRootLogic extends GetxController {
+ var tokenService = Get.find();
+
+ late CityPoultryRepository cityPoultryRepository;
+
+ RxList errorLocationType = RxList();
+ RxMap homeExpandedList = RxMap();
+ DateTime? _lastBackPressed;
+
+ RxInt currentPage = 0.obs;
+
+ final pages = [
+ Navigator(
+ key: Get.nestedKey(cityPoultryActionKey),
+ onGenerateRoute: (settings) {
+ final page = CityPoultryPages.pages.firstWhere(
+ (e) => e.name == settings.name,
+ orElse: () => CityPoultryPages.pages.firstWhere(
+ (e) => e.name == CityPoultryRoutes.homeCityPoultry,
+ ),
+ );
+
+ return buildRouteFromGetPage(page);
+ },
+ ),
+
+ ProfilePage(),
+ ];
+
+ @override
+ void onInit() {
+ super.onInit();
+ cityPoultryRepository = diChicken.get();
+ }
+
+ void toggleExpanded(int index) {
+ if (homeExpandedList.keys.contains(index)) {
+ homeExpandedList.remove(index);
+ } else {
+ homeExpandedList[index] = false;
+ }
+ }
+
+ void rootErrorHandler(DioException error) {
+ handleGeneric(error, () {
+ tokenService.deleteModuleTokens(Module.chicken);
+ });
+ }
+
+ void changePage(int index) {
+ currentPage.value = index;
+ }
+
+ void popBackTaped() async {
+ final nestedKey = Get.nestedKey(cityPoultryActionKey);
+
+ final currentRoute = Get.routing.current;
+
+ // بررسی کن که آیا route فعلی یکی از routeهای داخلی است
+ final isInternalRoute =
+ currentRoute == CityPoultryRoutes.activeHatchingCityPoultry ||
+ currentRoute == CityPoultryRoutes.newInspectionCityPoultry ||
+ currentRoute == CityPoultryRoutes.actionCityPoultry;
+
+ // فقط اگر میتوان pop کرد و در یکی از صفحههای داخلی هستیم، pop کن
+ if ( isInternalRoute) {
+ Get.back(id: cityPoultryActionKey);
+ return;
+ }
+
+ // اگر در صفحه home هستیم، منطق خروج از اپ را اجرا کن
+ final now = DateTime.now();
+ if (_lastBackPressed == null ||
+ now.difference(_lastBackPressed!) > Duration(seconds: 2)) {
+ _lastBackPressed = now;
+ Get.snackbar(
+ 'خروج از برنامه',
+ 'برای خروج دوباره بازگشت را بزنید',
+ snackPosition: SnackPosition.TOP,
+ duration: Duration(seconds: 2),
+ backgroundColor: AppColor.warning,
+ );
+ } else {
+ await SystemNavigator.pop();
+ }
+ }
+}
diff --git a/packages/chicken/lib/features/city_poultry/presentation/pages/root/view.dart b/packages/chicken/lib/features/city_poultry/presentation/pages/root/view.dart
new file mode 100644
index 0000000..27df552
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/pages/root/view.dart
@@ -0,0 +1,59 @@
+import 'package:flutter/material.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 CityPoultryRootPage extends GetView {
+ const CityPoultryRootPage({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ChickenBasePage(
+ isFullScreen: true,
+ onPopScopTaped: controller.popBackTaped,
+ child: ObxValue((data) {
+ return Stack(
+ children: [
+ IndexedStack(children: controller.pages, index: data.value),
+ Positioned(
+ right: 0,
+ left: 0,
+ bottom: 0,
+ child: RBottomNavigation(
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ items: [
+
+ RBottomNavigationItem(
+ label: 'خانه',
+ icon: Assets.vec.homeSvg.path,
+ isSelected: controller.currentPage.value == 0,
+ onTap: () {
+ Get.nestedKey(
+ cityPoultryActionKey,
+ )?.currentState?.popUntil((route) => route.isFirst);
+ controller.changePage(0);
+ },
+ ),
+ RBottomNavigationItem(
+ label: 'پروفایل',
+ icon: Assets.vec.profileCircleSvg.path,
+ isSelected: controller.currentPage.value == 1,
+ onTap: () {
+ Get.nestedKey(
+ cityPoultryActionKey,
+ )?.currentState?.popUntil((route) => route.isFirst);
+ controller.changePage(1);
+ },
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }, controller.currentPage),
+ );
+ }
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/presentation/routes/pages.dart b/packages/chicken/lib/features/city_poultry/presentation/routes/pages.dart
new file mode 100644
index 0000000..f0d97bc
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/routes/pages.dart
@@ -0,0 +1,67 @@
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/home/logic.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/home/view.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/logic.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/root/view.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/active_hatching/logic.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/active_hatching/view.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/new_inspection/logic.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/pages/new_inspection/view.dart';
+import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/routes.dart';
+import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart';
+import 'package:rasadyar_chicken/presentation/routes/global_binding.dart';
+import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart';
+import 'package:rasadyar_core/core.dart';
+
+class CityPoultryPages {
+ CityPoultryPages._();
+
+ static List get pages => [
+ GetPage(
+ name: CityPoultryRoutes.initCityPoultry,
+ page: () => CityPoultryRootPage(),
+ middlewares: [AuthMiddleware()],
+ bindings: [
+ GlobalBinding(),
+ BindingsBuilder(() {
+ Get.lazyPut(() => ChickenBaseLogic(), fenix: true);
+ Get.lazyPut(() => CityPoultryRootLogic());
+ Get.lazyPut(() => CityPoultryHomeLogic());
+ }),
+ ],
+ ),
+ GetPage(
+ name: CityPoultryRoutes.homeCityPoultry,
+ page: () => CityPoultryHomePage(),
+ middlewares: [AuthMiddleware()],
+ binding: BindingsBuilder(() {
+ Get.put(CityPoultryHomeLogic());
+ Get.lazyPut(() => ChickenBaseLogic());
+ }),
+ ),
+
+ GetPage(
+ name: CityPoultryRoutes.activeHatchingCityPoultry,
+ page: () => ActiveHatchingPage(),
+ middlewares: [AuthMiddleware()],
+ bindings: [
+ GlobalBinding(),
+ BindingsBuilder(() {
+ Get.lazyPut(() => ActiveHatchingLogic());
+ Get.lazyPut(() => CreateInspectionBottomSheetLogic());
+ }),
+ ],
+ ),
+ GetPage(
+ name: CityPoultryRoutes.newInspectionCityPoultry,
+ page: () => NewInspectionPage(),
+ middlewares: [AuthMiddleware()],
+ bindings: [
+ GlobalBinding(),
+ BindingsBuilder(() {
+ Get.lazyPut(() => NewInspectionLogic());
+ }),
+ ],
+ ),
+ ];
+}
+
diff --git a/packages/chicken/lib/features/city_poultry/presentation/routes/routes.dart b/packages/chicken/lib/features/city_poultry/presentation/routes/routes.dart
new file mode 100644
index 0000000..9c24c65
--- /dev/null
+++ b/packages/chicken/lib/features/city_poultry/presentation/routes/routes.dart
@@ -0,0 +1,11 @@
+sealed class CityPoultryRoutes {
+ CityPoultryRoutes._();
+
+ static const _base = '/chicken/cityPoultry';
+ static const initCityPoultry = '$_base/';
+ static const homeCityPoultry = '$_base/home';
+ static const actionCityPoultry = '$_base/action';
+ static const activeHatchingCityPoultry = '$_base/activeHatching';
+ static const newInspectionCityPoultry = '$_base/newInspection';
+}
+
diff --git a/packages/chicken/lib/features/common/presentation/page/auth/logic.dart b/packages/chicken/lib/features/common/presentation/page/auth/logic.dart
index 9842eec..c1a3286 100644
--- a/packages/chicken/lib/features/common/presentation/page/auth/logic.dart
+++ b/packages/chicken/lib/features/common/presentation/page/auth/logic.dart
@@ -131,6 +131,7 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin {
'killhouse',
'provinceinspector',
'cityjahad',
+ 'citypoultry',
'jahad',
'vetfarm',
'provincesupervisor',
diff --git a/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart
index 6f0b218..47b6c15 100644
--- a/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart
@@ -175,12 +175,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -195,12 +195,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/Aaq',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart b/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart
index f8d9114..ecb8033 100644
--- a/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart
+++ b/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart
@@ -23,7 +23,7 @@ class JahadHomeLogic extends GetxController {
JahadActionItem(
title: "بازرسی مزارع طیور",
route: JahadRoutes.newInspectionJahad,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart
index 467cfad..03ac3b9 100644
--- a/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart
@@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/Aaq',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart
index 9db46d1..ae7ae10 100644
--- a/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart
+++ b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart
@@ -40,7 +40,7 @@ class PoultryActionLogic extends GetxController {
PoultryActionItem(
title: "بازرسی مزارع طیور",
route: PoultryScienceRoutes.newInspectionPoultryScience,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart
index 4fa0611..95c0cfc 100644
--- a/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart
@@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/Aaq',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart
index 5400e75..ae37109 100644
--- a/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart
+++ b/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart
@@ -24,7 +24,7 @@ class ProvinceInspectorHomeLogic extends GetxController {
ProvinceInspectorActionItem(
title: "بازرسی مزارع طیور",
route: ProvinceInspectorRoutes.newInspectionProvinceInspector,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart
index 950ecaa..c0cd0dc 100644
--- a/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart
@@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/Aaq',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart
index 778e68f..bd098b8 100644
--- a/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart
+++ b/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart
@@ -24,7 +24,7 @@ class ProvinceOperatorHomeLogic extends GetxController {
ProvinceOperatorHomeItem(
title: "بازرسی مزارع طیور",
route: ProvinceOperatorRoutes.newInspectionProvinceOperator,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart
index 28553c4..3da44a2 100644
--- a/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart
@@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/Aaq',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart
index 61d4abe..2e13b69 100644
--- a/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart
+++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart
@@ -24,7 +24,7 @@ class ProvinceSupervisorHomeLogic extends GetxController {
ProvinceSupervisorActionItem(
title: "بازرسی مزارع طیور",
route: ProvinceSupervisorRoutes.newInspectionProvinceSupervisor,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart
index c663465..9db13c9 100644
--- a/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart
@@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/Aaq',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart b/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart
index 7a720d3..8b5805d 100644
--- a/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart
+++ b/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart
@@ -20,7 +20,7 @@ class SuperAdminHomeLogic extends GetxController {
SuperAdminHomeItem(
title: "بازرسی مزارع طیور",
route: SuperAdminRoutes.newInspectionSuperAdmin,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart
index 3d0f986..b68eb54 100644
--- a/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart
+++ b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart
@@ -193,12 +193,12 @@ class ActiveHatchingPage extends GetView {
spacing: 3,
children: [
Text(
- item.poultry?.user?.fullname ?? 'N/A',
+ item.poultry?.user?.fullname ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
Text(
- item.poultry?.user?.mobile ?? 'N/A',
+ item.poultry?.user?.mobile ?? 'ندارد',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
),
@@ -213,12 +213,12 @@ class ActiveHatchingPage extends GetView {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
- item.poultry?.unitName ?? 'N/Aaq',
+ item.poultry?.unitName ?? 'ندارد',
textAlign: TextAlign.start,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark),
),
Text(
- item.poultry?.licenceNumber ?? 'N/A',
+ item.licenceNumber ?? 'ندارد',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart
index 25da47a..56a6ac1 100644
--- a/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart
+++ b/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart
@@ -19,7 +19,7 @@ class VetFarmHomeLogic extends GetxController {
VetFarmHomeItem(
title: "بازرسی مزارع طیور",
route: VetFarmRoutes.newInspectionVetFarm,
- icon: Assets.vec.activeFramSvg.path,
+ icon: Assets.vec.inspectionPoultrySvg.path,
),
].obs;
}
diff --git a/packages/chicken/lib/presentation/routes/pages.dart b/packages/chicken/lib/presentation/routes/pages.dart
index e08ddce..469f555 100644
--- a/packages/chicken/lib/presentation/routes/pages.dart
+++ b/packages/chicken/lib/presentation/routes/pages.dart
@@ -1,3 +1,4 @@
+import 'package:rasadyar_chicken/features/city_poultry/presentation/routes/pages.dart';
import 'package:rasadyar_chicken/features/common/common.dart';
import 'package:rasadyar_chicken/features/kill_house/action/logic.dart';
import 'package:rasadyar_chicken/features/kill_house/action/view.dart';
@@ -66,6 +67,10 @@ sealed class ChickenPages {
...JahadPages.pages,
//endregion
+ //region City Poultry Pages
+ ...CityPoultryPages.pages,
+ //endregion
+
//region Poultry Farm Inspection
GetPage(
name: ChickenRoutes.poultryFarmInspectionHome,
diff --git a/packages/chicken/lib/presentation/utils/nested_keys_utils.dart b/packages/chicken/lib/presentation/utils/nested_keys_utils.dart
index 745df67..4f6dd52 100644
--- a/packages/chicken/lib/presentation/utils/nested_keys_utils.dart
+++ b/packages/chicken/lib/presentation/utils/nested_keys_utils.dart
@@ -41,6 +41,11 @@ const int cityJahadActionKey = 112;
//endregion
+//region city poultry Keys
+const int cityPoultryActionKey = 117;
+
+//endregion
+
//region vet farm Keys
const int vetFarmActionKey = 113;
diff --git a/packages/core/lib/presentation/common/assets.gen.dart b/packages/core/lib/presentation/common/assets.gen.dart
index 1108d38..e5d7b17 100644
--- a/packages/core/lib/presentation/common/assets.gen.dart
+++ b/packages/core/lib/presentation/common/assets.gen.dart
@@ -229,6 +229,9 @@ class $AssetsIconsGen {
/// File path: assets/icons/inspection.svg
SvgGenImage get inspection => const SvgGenImage('assets/icons/inspection.svg');
+ /// File path: assets/icons/inspection_poultry.svg
+ SvgGenImage get inspectionPoultry => const SvgGenImage('assets/icons/inspection_poultry.svg');
+
/// File path: assets/icons/key.svg
SvgGenImage get key => const SvgGenImage('assets/icons/key.svg');
@@ -456,6 +459,7 @@ class $AssetsIconsGen {
information,
inside,
inspection,
+ inspectionPoultry,
key,
liveStock,
lock,
@@ -748,6 +752,9 @@ class $AssetsVecGen {
/// File path: assets/vec/inspection.svg.vec
SvgGenImage get inspectionSvg => const SvgGenImage.vec('assets/vec/inspection.svg.vec');
+ /// File path: assets/vec/inspection_poultry.svg.vec
+ SvgGenImage get inspectionPoultrySvg => const SvgGenImage.vec('assets/vec/inspection_poultry.svg.vec');
+
/// File path: assets/vec/key.svg.vec
SvgGenImage get keySvg => const SvgGenImage.vec('assets/vec/key.svg.vec');
@@ -975,6 +982,7 @@ class $AssetsVecGen {
informationSvg,
insideSvg,
inspectionSvg,
+ inspectionPoultrySvg,
keySvg,
liveStockSvg,
lockSvg,