Files
rasadyar_application/packages/chicken/lib/features/poultry_science/inspection/logic.dart

267 lines
7.7 KiB
Dart
Raw Normal View History

2025-09-21 15:42:08 +03:30
import 'package:flutter/material.dart';
2025-09-07 17:20:01 +03:30
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/features/poultry_science/root/logic.dart';
2025-09-07 17:20:01 +03:30
import 'package:rasadyar_core/core.dart';
class InspectionPoultryScienceLogic extends GetxController {
2025-09-27 09:35:00 +03:30
BaseLogic baseLogic = Get.find<BaseLogic>();
2025-09-07 17:20:01 +03:30
Rx<Resource<PaginationModel<HatchingModel>>> hatchingList =
Resource<PaginationModel<HatchingModel>>.loading().obs;
Rx<Resource<PaginationModel<HatchingReport>>> hatchingReportList =
Resource<PaginationModel<HatchingReport>>.loading().obs;
PoultryScienceRootLogic rootLogic = Get.find<PoultryScienceRootLogic>();
Rx<LatLng> currentLocation = LatLng(34.798315281272544, 48.51479142983491).obs;
final RxBool isLoadingMoreAllocationsMade = false.obs;
RxInt currentPage = 1.obs;
2025-09-20 13:12:16 +03:30
RxInt expandedIndex = RxInt(-1);
2025-09-07 17:20:01 +03:30
RxList<XFile> pickedImages = <XFile>[].obs;
final List<MultipartFile> _multiPartPickedImages = <MultipartFile>[];
RxBool isOnUpload = false.obs;
RxDouble presentUpload = 0.0.obs;
RxList<String> routesName = RxList();
RxInt selectedSegmentIndex = 0.obs;
2025-09-21 15:42:08 +03:30
RxnString searchedValue = RxnString();
Rx<Jalali> fromDateFilter = Jalali.now().obs;
Rx<Jalali> toDateFilter = Jalali.now().obs;
2025-09-07 17:20:01 +03:30
@override
void onInit() {
super.onInit();
routesName.value = ['اقدام'].toList();
2025-09-30 09:56:22 +03:30
2025-09-07 17:20:01 +03:30
ever(selectedSegmentIndex, (callback) {
routesName.removeLast();
routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی');
});
}
@override
void onReady() {
super.onReady();
getHatchingList();
getHatchingReport();
2025-09-08 10:18:43 +03:30
checkLocationPermission(request: true);
2025-09-07 17:20:01 +03:30
ever(pickedImages, (callback) {
_multiPartPickedImages.clear();
for (var element in pickedImages) {
_multiPartPickedImages.add(
MultipartFile.fromFileSync(element.path, filename: element.name),
);
}
});
}
@override
void onClose() {
super.onClose();
2025-09-29 15:00:31 +03:30
baseLogic.clearSearch();
2025-09-07 17:20:01 +03:30
}
Future<void> getHatchingList([bool isLoadingMore = false]) async {
if (isLoadingMore) {
isLoadingMoreAllocationsMade.value = true;
} else {
hatchingList.value = Resource<PaginationModel<HatchingModel>>.loading();
}
2025-09-21 15:42:08 +03:30
2025-09-07 17:20:01 +03:30
if (searchedValue.value != null &&
searchedValue.value!.trim().isNotEmpty &&
currentPage.value > 1) {
currentPage.value = 1;
2025-09-21 15:42:08 +03:30
}
2025-09-07 17:20:01 +03:30
safeCall(
call: () async => await rootLogic.poultryRepository.getHatchingPoultry(
token: rootLogic.tokenService.accessToken.value!,
queryParameters: buildQueryParams(
queryParams: {'type': 'hatching', 'report': true},
2025-09-13 11:36:44 +03:30
role: 'PoultryScience',
2025-09-21 15:42:08 +03:30
search: 'filter',
value: searchedValue.value,
fromDate: fromDateFilter.value.toDateTime(),
toDate: toDateFilter.value.toDateTime(),
2025-09-07 17:20:01 +03:30
pageSize: 50,
page: currentPage.value,
),
),
onSuccess: (res) {
if ((res?.count ?? 0) == 0) {
hatchingList.value = Resource<PaginationModel<HatchingModel>>.empty();
} else {
hatchingList.value = Resource<PaginationModel<HatchingModel>>.success(
PaginationModel<HatchingModel>(
count: res?.count ?? 0,
next: res?.next,
previous: res?.previous,
results: [...(hatchingList.value.data?.results ?? []), ...(res?.results ?? [])],
),
);
}
},
);
}
Future<void> getHatchingReport([bool isLoadingMore = false]) async {
if (isLoadingMore) {
isLoadingMoreAllocationsMade.value = true;
} else {
hatchingReportList.value = Resource<PaginationModel<HatchingReport>>.loading();
}
2025-09-21 15:42:08 +03:30
2025-09-07 17:20:01 +03:30
if (searchedValue.value != null &&
searchedValue.value!.trim().isNotEmpty &&
currentPage.value > 1) {
currentPage.value = 1;
2025-09-21 15:42:08 +03:30
}
2025-09-07 17:20:01 +03:30
safeCall(
call: () async => await rootLogic.poultryRepository.getHatchingPoultryReport(
token: rootLogic.tokenService.accessToken.value!,
queryParameters: buildQueryParams(
role: 'PoultryScience',
pageSize: 50,
search: 'filter',
2025-09-21 15:42:08 +03:30
value: searchedValue.value,
fromDate: fromDateFilter.value.toDateTime(),
toDate: toDateFilter.value.toDateTime(),
2025-09-07 17:20:01 +03:30
page: currentPage.value,
),
),
onSuccess: (res) {
if ((res?.count ?? 0) == 0) {
hatchingReportList.value = Resource<PaginationModel<HatchingReport>>.empty();
} else {
hatchingReportList.value = Resource<PaginationModel<HatchingReport>>.success(
PaginationModel<HatchingReport>(
count: res?.count ?? 0,
next: res?.next,
previous: res?.previous,
results: [...(hatchingReportList.value.data?.results ?? []), ...(res?.results ?? [])],
),
);
}
},
);
}
Future<void> pickImages() async {
determineCurrentPosition();
2025-09-08 10:18:43 +03:30
var tmp = await pickCameraImage();
2025-09-07 17:20:01 +03:30
if (tmp?.path != null && pickedImages.length < 7) {
pickedImages.add(tmp!);
}
}
void removeImage(int index) {
pickedImages.removeAt(index);
}
void clearImages() {
pickedImages.clear();
}
Future<void> submitInspectionReport({required int id}) async {
isOnUpload.value = true;
2025-09-08 10:58:38 +03:30
final tmpFiles = await Future.wait(
pickedImages.map((element) => MultipartFile.fromFile(element.path, filename: element.name)),
);
2025-09-07 17:20:01 +03:30
2025-09-07 17:37:30 +03:30
var data = FormData.fromMap({
2025-09-08 10:25:25 +03:30
'file': tmpFiles,
2025-09-07 17:37:30 +03:30
'hatching_id': id.toString(),
'lat': currentLocation.value.latitude.toString(),
'log': currentLocation.value.longitude.toString(),
});
2025-09-07 17:20:01 +03:30
safeCall(
call: () async => await rootLogic.poultryRepository.submitPoultryScienceReport(
token: rootLogic.tokenService.accessToken.value!,
2025-09-07 17:37:30 +03:30
data: data,
2025-09-07 17:20:01 +03:30
onSendProgress: (sent, total) {
presentUpload.value = calculateUploadProgress(sent: sent, total: total);
},
),
onSuccess: (res) {
closeBottomSheet();
clearImages();
getHatchingList();
getHatchingReport();
isOnUpload.value = false;
},
2025-09-07 17:37:30 +03:30
onError: (error, stackTrace) async {
2025-09-07 17:20:01 +03:30
clearImages();
isOnUpload.value = false;
2025-09-07 17:37:30 +03:30
await Future.delayed(const Duration(seconds: 4)).then((value) => closeBottomSheet());
2025-09-07 17:20:01 +03:30
},
showError: true,
);
}
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;
}
}
2025-09-20 13:12:16 +03:30
void toggleExpanded(int index) {
expandedIndex.value = expandedIndex.value == index ? -1 : index;
}
2025-09-21 15:42:08 +03:30
String getStatus(HatchingReport item) {
if (item.state == 'accepted') {
return 'تکمیل شده';
} else if (item.state == 'rejected') {
return 'رد شده';
} else {
return 'در حال بررسی';
}
}
Color getStatusColor(HatchingReport item) {
if (item.state == 'accepted') {
return AppColor.greenNormal;
} else if (item.state == 'rejected') {
return AppColor.redNormal;
} else {
return AppColor.yellowNormal;
}
}
void setSearchValue(String? data) {
2025-09-27 09:35:00 +03:30
dLog('Search Value: $data');
2025-09-21 15:42:08 +03:30
searchedValue.value = data?.trim();
2025-09-27 09:35:00 +03:30
final isReporter = selectedSegmentIndex.value == 1;
2025-09-21 15:42:08 +03:30
if (isReporter) {
getHatchingReport();
} else {
getHatchingList();
}
}
2025-09-27 09:35:00 +03:30
2025-10-07 14:21:09 +03:30
Future<void> onRefresh() async {
currentPage.value = 1;
await Future.wait([getHatchingList(), getHatchingReport()]);
}
}