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/features/poultry_science/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class InspectionPoultryScienceLogic extends GetxController { BaseLogic baseLogic = Get.find(); Rx>> hatchingList = Resource>.loading().obs; Rx>> hatchingReportList = Resource>.loading().obs; PoultryScienceRootLogic rootLogic = Get.find(); Rx currentLocation = LatLng(34.798315281272544, 48.51479142983491).obs; final RxBool isLoadingMoreAllocationsMade = false.obs; RxInt currentPage = 1.obs; RxInt expandedIndex = RxInt(-1); RxList pickedImages = [].obs; final List _multiPartPickedImages = []; 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(); getHatchingList(); getHatchingReport(); checkLocationPermission(request: true); ever(pickedImages, (callback) { _multiPartPickedImages.clear(); for (var element in pickedImages) { _multiPartPickedImages.add( MultipartFile.fromFileSync(element.path, filename: element.name), ); } }); } @override void onClose() { super.onClose(); baseLogic.clearSearch(); } Future getHatchingList([bool isLoadingMore = false]) async { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { hatchingList.value = Resource>.loading(); } if (searchedValue.value != null && searchedValue.value!.trim().isNotEmpty && currentPage.value > 1) { currentPage.value = 1; } safeCall( call: () async => await rootLogic.poultryRepository.getHatchingPoultry( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( queryParams: {'type': 'hatching', 'report': true}, role: 'PoultryScience', search: 'filter', value: searchedValue.value, fromDate: fromDateFilter.value.toDateTime(), toDate: toDateFilter.value.toDateTime(), pageSize: 50, page: currentPage.value, ), ), onSuccess: (res) { if ((res?.count ?? 0) == 0) { hatchingList.value = Resource>.empty(); } else { hatchingList.value = Resource>.success( PaginationModel( count: res?.count ?? 0, next: res?.next, previous: res?.previous, results: [...(hatchingList.value.data?.results ?? []), ...(res?.results ?? [])], ), ); } }, ); } Future getHatchingReport([bool isLoadingMore = false]) async { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { hatchingReportList.value = Resource>.loading(); } if (searchedValue.value != null && searchedValue.value!.trim().isNotEmpty && currentPage.value > 1) { currentPage.value = 1; } safeCall( call: () async => await rootLogic.poultryRepository.getHatchingPoultryReport( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( role: 'PoultryScience', pageSize: 50, search: 'filter', value: searchedValue.value, fromDate: fromDateFilter.value.toDateTime(), toDate: toDateFilter.value.toDateTime(), page: currentPage.value, ), ), onSuccess: (res) { if ((res?.count ?? 0) == 0) { hatchingReportList.value = Resource>.empty(); } else { hatchingReportList.value = Resource>.success( PaginationModel( count: res?.count ?? 0, next: res?.next, previous: res?.previous, results: [...(hatchingReportList.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 clearImages() { pickedImages.clear(); } Future submitInspectionReport({required int id}) async { isOnUpload.value = true; final tmpFiles = await Future.wait( pickedImages.map((element) => MultipartFile.fromFile(element.path, filename: element.name)), ); var data = FormData.fromMap({ 'file': tmpFiles, 'hatching_id': id.toString(), 'lat': currentLocation.value.latitude.toString(), 'log': currentLocation.value.longitude.toString(), }); safeCall( call: () async => await rootLogic.poultryRepository.submitPoultryScienceReport( token: rootLogic.tokenService.accessToken.value!, data: data, onSendProgress: (sent, total) { presentUpload.value = calculateUploadProgress(sent: sent, total: total); }, ), onSuccess: (res) { closeBottomSheet(); clearImages(); getHatchingList(); getHatchingReport(); isOnUpload.value = false; }, onError: (error, stackTrace) async { clearImages(); isOnUpload.value = false; await Future.delayed(const Duration(seconds: 4)).then((value) => closeBottomSheet()); }, 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; } } void toggleExpanded(int index) { expandedIndex.value = expandedIndex.value == index ? -1 : index; } 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) { dLog('Search Value: $data'); searchedValue.value = data?.trim(); final isReporter = selectedSegmentIndex.value == 1; if (isReporter) { getHatchingReport(); } else { getHatchingList(); } } Future onRefresh() async { currentPage.value = 1; await Future.wait([getHatchingList(), getHatchingReport()]); } }