import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart'; import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart'; import 'package:rasadyar_chicken/presentation/pages/steward/root/logic.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; class SegmentationLogic extends GetxController { StewardRootLogic rootLogic = Get.find(); RxBool isLoadingMoreAllocationsMade = false.obs; RxInt currentPage = 1.obs; late List routesName; RxInt selectedSegmentIndex = 0.obs; RxBool isExpanded = false.obs; RxInt expandedListIndex = (-1).obs; Rx fromDateFilter = Jalali.now().obs; Rx toDateFilter = Jalali.now().obs; RxnString searchedValue = RxnString(); RxInt segmentType = 1.obs; RxInt priceType = 2.obs; RxInt quotaType = 2.obs; GlobalKey formKey = GlobalKey(); TextEditingController weightController = TextEditingController(text: '0'); RxBool isSubmitButtonEnabled = false.obs; Rxn selectedGuildModel = Rxn(); Rxn selectedProduct = Rxn(); Rxn selectedSegment = Rxn(); Rxn broadcastPrice = Rxn(); Rx>> segmentationList = Resource>.loading().obs; RxList guildsModel = [].obs; Rx saleDate = Jalali.now().obs; RxInt weight = 0.obs; Rxn productionDate = Rxn(null); Rxn remainingStock = Rxn(null); Map freeProductionDateData = {}; Map governmentalProductionDateData = {}; @override void onInit() { super.onInit(); routesName = ['قطعه‌بندی'].toList(); once(rootLogic.rolesProductsModel, (callback) => selectedProduct.value = callback.first); getAllSegmentation(); getGuilds(); ever(quotaType, (_) { remainingStock.value = null; productionDate.value = null; }); _updateGovernmentalProductionDateData(); _updateFreeProductionDateData(); ever(rootLogic.stewardRemainWeight, (callback) { _updateGovernmentalProductionDateData(); _updateFreeProductionDateData(); }); } void _updateGovernmentalProductionDateData() { List dates = rootLogic.stewardRemainWeight.value?.governmental ?? []; governmentalProductionDateData = { for (var element in dates) element.day.toString().toJalali.formatCompactDate(): DayData( value: element.amount?.toInt(), ), }; } void _updateFreeProductionDateData() { var dates = rootLogic.stewardRemainWeight.value?.free ?? []; freeProductionDateData = { for (var element in dates) element.day.toString().toJalali.formatCompactDate(): DayData( value: element.amount?.toInt(), ), }; } @override void onReady() { super.onReady(); setUpListener(); } void setSearchValue(String? value) { searchedValue.value = value?.trim(); } void setUpListener() { debounce( searchedValue, (callback) => getAllSegmentation(), time: Duration(milliseconds: timeDebounce), ); everAll([selectedSegment, quotaType, priceType], (_) { validateForm(); }); weightController.addListener(() => validateForm()); } void setEditData(SegmentationModel item) { selectedSegment.value = item; weightController.text = item.weight.toString(); } void clearForm() { weightController.text = '0'; selectedSegment.value = null; selectedGuildModel.value = null; productionDate.value = null; segmentType.value = 1; priceType.value = 2; quotaType.value = 1; remainingStock.value = null; } void validateForm() { var weight = int.tryParse(weightController.text.trim().clearComma) ?? 0; var hasWeight = (remainingStock.value ?? 0) > weight; isSubmitButtonEnabled.value = selectedProduct.value != null && weightController.text.isNotEmpty && hasWeight && productionDate.value != null && weight > 0 && (segmentType.value == 1 || (segmentType.value == 2 && selectedGuildModel.value != null)); } Future getAllSegmentation([bool isLoadingMore = false]) async { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { segmentationList.value = Resource>.loading(); } if (searchedValue.value != null && searchedValue.value!.trim().isNotEmpty && currentPage.value > 1) { currentPage.value = 1; // Reset to first page if search value is set } await safeCall( showError: true, call: () async => await rootLogic.chickenRepository.getSegmentation( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( pageSize: 20, page: currentPage.value, search: 'filter', role: 'Steward', value: searchedValue.value, fromDate: fromDateFilter.value.toDateTime(), toDate: toDateFilter.value.toDateTime(), ), ), onSuccess: (result) { if ((result?.count ?? 0) == 0) { segmentationList.value = Resource>.empty(); } else { segmentationList.value = Resource>.success( PaginationModel( count: result?.count ?? 0, next: result?.next, previous: result?.previous, results: [ ...(segmentationList.value.data?.results ?? []), ...(result?.results ?? []), ], ), ); isLoadingMoreAllocationsMade.value = false; } }, ); } Future deleteSegmentation(String key) async { await safeCall( showError: true, showSuccess: true, call: () => rootLogic.chickenRepository.deleteSegmentation( token: rootLogic.tokenService.accessToken.value!, key: key, ), ); } Future editSegment() async { var res = true; safeCall( showError: true, call: () async => await rootLogic.chickenRepository.editSegmentation( token: rootLogic.tokenService.accessToken.value!, model: SegmentationModel( key: selectedSegment.value?.key, weight: int.tryParse(weightController.text.clearComma) ?? 0, productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, ), ), onSuccess: (result) { res = true; onRefresh(); }, onError: (error, stacktrace) { res = false; }, ); return res; } Future createSegment() async { var res = true; SegmentationModel segmentationModel = SegmentationModel( productKey: selectedProduct.value?.key, weight: int.tryParse(weightController.text.clearComma) ?? 0, saleType: priceType.value == 1 ? 'governmental' : 'free', quota: quotaType.value == 1 ? 'governmental' : 'free', ); if (segmentType.value == 2) { segmentationModel = segmentationModel.copyWith(guildKey: selectedGuildModel.value?.key); } segmentationModel = segmentationModel.copyWith( productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, ); await safeCall( showError: true, call: () async => await rootLogic.chickenRepository.createSegmentation( token: rootLogic.tokenService.accessToken.value!, model: segmentationModel, ), onSuccess: (result) async { res = true; isSubmitButtonEnabled.value = false; onRefresh(); Future.delayed( Duration(seconds: 1), () => defaultShowSuccessMessage("قطعه‌بندی با موفقیت ثبت شد!"), ); Get.back(); }, onError: (error, stacktrace) { res = false; }, ); return res; } Future getGuilds() async { safeCall( call: () async => await rootLogic.chickenRepository.getGuilds( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams(queryParams: {'all': true}, role: 'Steward'), ), onSuccess: (result) { if (result != null) { guildsModel.clear(); guildsModel.addAll(result); } }, onError: (error, stacktrace) {}, ); } Future onRefresh() async { toggleExpansion(); currentPage.value = 1; await rootLogic.onRefresh(); await getAllSegmentation(); await getBroadcastPrice(); _updateFreeProductionDateData(); _updateGovernmentalProductionDateData(); } Future getBroadcastPrice() async { safeCall( call: () async => await rootLogic.chickenRepository.getBroadcastPrice( token: rootLogic.tokenService.accessToken.value!, ), onSuccess: (result) { broadcastPrice.value = result; if (broadcastPrice.value?.active == true) { priceType.value = 2; } }, onError: (error, stacktrace) {}, ); } void toggleExpansion({int? index}) { if (expandedListIndex.value == index || index == null) { expandedListIndex.value = -1; } else { expandedListIndex.value = index; } } }