refactor: update data source and repository structure by removing unused files, enhancing model integration, and adjusting import paths for better organization

This commit is contained in:
2025-12-07 12:33:39 +03:30
parent c28a4a3177
commit 02686115cb
129 changed files with 5269 additions and 545 deletions

View File

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

View File

@@ -0,0 +1,587 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart';
import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart';
import 'package:rasadyar_core/core.dart';
import 'logic.dart';
class KillingRegistrationPage extends GetView<KillingRegistrationLogic> {
const KillingRegistrationPage({super.key});
@override
Widget build(BuildContext context) {
return Form(
key: controller.formKey,
child: Column(
children: [
poultryFarmWidget(),
poultryUserListWidget(),
poultryHatchingWidget(),
ObxValue((data) {
return Visibility(
visible: controller.selectedPoultryHatching.value != null,
child: Column(
children: [
informationWidget(),
killDateWidget(
date: controller.killsDate,
onChanged: (Jalali jalali) {
controller.killsDate.value = jalali;
},
),
quantityKillsWidget(),
],
),
);
}, controller.selectedPoultryHatching),
ObxValue((data) {
return Visibility(
visible: data.value,
child: Column(children: [averageWeightKillsWidget()]),
);
}, controller.quantityKillsIsCompleted),
ObxValue((data) {
return Visibility(
visible: data.value,
child: Column(
children: [
saleTypeWidget(),
priceWidget(),
buyerListWidget(),
slaughterhouseSelectedWidget(),
submitButtonWidget(),
],
),
);
}, controller.averageWeightKillsIsCompleted),
],
),
);
}
Widget poultryFarmWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h),
child: ObxValue((data) {
return ResourceOverlayDropdown<AllPoultry>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.clearSelectedStep1();
controller.selectedPoultry.value = value;
controller.getUserPoultryList();
},
selectedItem: controller.selectedPoultry.value,
itemBuilder: (item) => labelPoultryWidget(item),
labelBuilder: (item) => labelPoultryWidget(item),
);
}, controller.allPoultryList),
);
}
Widget labelPoultryWidget(AllPoultry? item) {
if (item == null) {
return Row(
children: [
Assets.vec.farmSvg.svg(
width: 28.w,
height: 28.h,
colorFilter: const ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn),
),
SizedBox(width: 4.w),
Text('انتخاب مرغداری', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)),
],
);
} else {
return Text('${item.unitName} (${item.address?.city?.name})', maxLines: 2);
}
}
Widget poultryUserListWidget() {
return ObxValue((data) {
if (data.value == null) {
return SizedBox.shrink();
}
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8.w),
child: ObxValue((data) {
return ResourceOverlayDropdown<KillRequestPoultry>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.clearSelectedStep2();
controller.selectedKillRequestPoultry.value = value;
controller.getPoultryHatchingList();
},
selectedItem: controller.selectedKillRequestPoultry.value,
itemBuilder: (item) => labelPoultryUser(item),
labelBuilder: (item) => labelPoultryUser(item),
);
}, controller.poultryList),
);
}, controller.selectedPoultry);
}
Widget labelPoultryUser(KillRequestPoultry? item) {
if (item == null) {
return Row(
children: [
Assets.vec.chickenHouseSvg.svg(
width: 28.w,
height: 28.h,
colorFilter: const ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn),
),
SizedBox(width: 6.w),
Text('محل پرورش', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)),
],
);
} else {
return Text(item.unitName ?? '-');
}
}
Widget poultryHatchingWidget() {
return ObxValue((data) {
if (data.value == null) {
return SizedBox.shrink();
}
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h),
child: ObxValue((data) {
return ResourceOverlayDropdown<PoultryHatching>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.selectedPoultryHatching.value = value;
},
selectedItem: controller.selectedPoultryHatching.value,
itemBuilder: (item) => labelPoultryHatching(item),
labelBuilder: (item) => labelPoultryHatching(item),
);
}, controller.poultryHatchingList),
);
}, controller.selectedKillRequestPoultry);
}
Widget labelPoultryHatching(PoultryHatching? item) {
if (item == null) {
return Row(
children: [
Assets.vec.calendarSvg.svg(
width: 28.w,
height: 28.h,
colorFilter: const ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn),
),
SizedBox(width: 6.w),
Text('دوره جوجه ریزی', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)),
],
);
} else {
return Text(
' دوره ${item.period} سالن ${item.hall} نژاد ${item.chickenBreed} باقیمانده ${item.leftOver} قطعه ',
);
}
}
Widget informationWidget() {
return Container(
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
margin: EdgeInsets.fromLTRB(8.w, 0, 8.w, 10.h),
padding: EdgeInsets.all(7),
child: ObxValue(
(data) => Column(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Text(
'اطلاعات مرغداری',
textAlign: TextAlign.right,
style: AppFonts.yekan14Bold.copyWith(color: AppColor.blueNormal),
),
),
Container(
decoration: ShapeDecoration(
color: const Color(0xFFEAEFFF),
shape: RoundedRectangleBorder(
side: BorderSide(width: 1, color: const Color(0xFFE0E7FF)),
borderRadius: BorderRadius.circular(8),
),
),
padding: EdgeInsets.all(4),
child: buildUnitRow(
title: 'تعداد جوجه ریزی',
value: data.value?.quantity.separatedByCommaFa,
unit: 'قطعه',
),
),
buildUnitRow(
title: 'تلفات',
value: data.value?.losses.separatedByCommaFa,
unit: 'قطعه',
padding: EdgeInsetsGeometry.symmetric(horizontal: 4),
),
buildUnitRow(
title: 'باقیمانده',
value: data.value?.leftOver.separatedByCommaFa,
unit: 'قطعه',
padding: EdgeInsetsGeometry.symmetric(horizontal: 4),
),
buildUnitRow(
title: 'سن جوجه',
value: data.value?.chickenAge.separatedByCommaFa,
unit: 'روز',
padding: EdgeInsetsGeometry.symmetric(horizontal: 4),
),
buildUnitRow(
title: 'مجوز فروش آزاد',
value:
data.value?.freeGovernmentalInfo?.totalFreeCommitmentQuantity.separatedByCommaFa,
unit: 'قطعه',
padding: EdgeInsetsGeometry.symmetric(horizontal: 4),
),
buildUnitRow(
title: 'مانده فروش آزاد',
value: data
.value
?.freeGovernmentalInfo
?.leftTotalFreeCommitmentQuantity
.separatedByCommaFa,
unit: 'قطعه',
padding: EdgeInsetsGeometry.symmetric(horizontal: 4),
),
buildUnitRow(
title: 'تلفن مرغدار',
value: data.value?.poultry?.userprofile?.mobile,
unit: '',
padding: EdgeInsetsGeometry.symmetric(horizontal: 4),
),
],
),
controller.selectedPoultryHatching,
),
);
}
Widget killDateWidget({required Rx<Jalali> date, required Function(Jalali jalali) onChanged}) {
return GestureDetector(
onTap: () {
Get.bottomSheet(modalDatePicker(onDateSelected: (value) => onChanged(value)));
},
child: Container(
height: 40,
margin: EdgeInsets.symmetric(horizontal: 8.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 1, color: AppColor.darkGreyLight),
),
padding: EdgeInsets.symmetric(horizontal: 11, vertical: 4),
child: Row(
spacing: 8,
children: [
Assets.vec.calendarSvg.svg(
width: 24,
height: 24,
colorFilter: const ColorFilter.mode(AppColor.bgDark, BlendMode.srcIn),
),
Text('تاریخ کشتار', style: AppFonts.yekan14.copyWith(color: AppColor.bgDark)),
Spacer(),
ObxValue((data) {
return Text(
date.value.formatCompactDate(),
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark),
);
}, date),
],
),
),
);
}
Widget quantityKillsWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h),
child: RTextField(
label: 'تعداد کشتار (قطعه)',
filled: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'تعداد کشتار را وارد کنید';
}
final count = double.tryParse(value.replaceAll(',', ''));
if (controller.isFreeSale.value) {
if (count! >
(controller
.selectedPoultryHatching
.value
?.freeGovernmentalInfo
?.leftTotalFreeCommitmentQuantity ??
0)) {
return 'مجوز فروش آزاد شما کافی نیست';
}
} else {
if (count! > (controller.selectedPoultryHatching.value?.leftOver ?? 0)) {
return 'تعداد کشتار نباید بیشتر از باقیمانده جوجه ریزی باشد';
}
}
return null;
},
textInputAction: TextInputAction.next,
filledColor: Colors.white,
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
controller: controller.quantityKillsController,
),
);
}
Widget averageWeightKillsWidget() {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8.w),
child: RTextField(
label: 'میانگین وزن (کیلوگرم)',
filled: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'میانگین وزن را وارد کنید';
}
final weight = double.tryParse(value.replaceAll(',', ''));
if (weight == null || weight <= 0) {
return 'میانگین وزن باید عددی بزرگتر از صفر باشد';
} else if (weight >
(controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.toWeight ??
10000) ||
weight <
(controller
.selectedPoultryHatching
.value
?.managementHatchingAgeRange
?.fromWeight ??
-10000)) {
return 'میانگین وزن باید بین ${controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.fromWeight} تا ${controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.toWeight} کیلوگرم باشد';
}
return null;
},
filledColor: Colors.white,
keyboardType: TextInputType.number,
inputFormatters: [FirstDigitDecimalFormatter()],
controller: controller.averageWeightKillsController,
),
);
}
Widget saleTypeWidget() {
return Container(
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h),
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h),
child: ObxValue((data) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 4,
children: [
Text(
'نوع فروش',
textAlign: TextAlign.center,
style: AppFonts.yekan14Bold.copyWith(color: AppColor.blueNormal),
),
RadioGroup(
groupValue: data.value ? 1 : 0,
onChanged: (value) {
controller.changeSaleType();
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Radio(value: 0, activeColor: AppColor.blueNormal),
Text('دولتی', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)),
Spacer(),
Radio(value: 1, activeColor: AppColor.blueNormal),
Text('آزاد', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)),
],
),
),
],
);
}, controller.isFreeSale),
);
}
Widget priceWidget() {
return ObxValue((data) {
if (!data.value) {
return Container(
height: 40.h,
margin: EdgeInsets.symmetric(horizontal: 8.w),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 1.w, color: AppColor.whiteNormalHover),
),
padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 4.h),
child: Row(
spacing: 8,
children: [
Text('قیمت مصوب', style: AppFonts.yekan14.copyWith(color: AppColor.textColor)),
Spacer(),
ObxValue((data) {
return Text(
' ${data.value.separatedByCommaFa} ریال',
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
);
}, controller.generatedApprovedPrice),
],
),
);
} else {
return Padding(
padding: EdgeInsets.fromLTRB(8.w, 0, 8.w, 0),
child: RTextField(
label: 'قیمت پیشنهادی (ریال)',
validator: (value) {
if (value == null || value.isEmpty) {
return 'قیمت پیشنهادی را وارد کنید';
}
final price = double.tryParse(value.replaceAll(',', ''));
if (price == null || price <= 0) {
return 'قیمت پیشنهادی باید عددی بزرگتر از صفر باشد';
}
return null;
},
filled: true,
borderColor: AppColor.whiteNormalHover,
filledColor: AppColor.accent1,
keyboardType: TextInputType.number,
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
controller: controller.priceFreeSaleController,
),
);
}
}, controller.isFreeSale);
}
Widget buyerListWidget() {
return Padding(
padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 8.w),
child: ObxValue((data) {
return Visibility(
visible: data.value?.provinceAllowChooseKillHouse?.allowState ?? false,
child: ObxValue((data) {
return ResourceOverlayDropdown<KillHousePoultry>(
items: data.value,
background: Colors.white,
onChanged: (value) {
controller.selectedKillHouse.value = value;
},
selectedItem: controller.selectedKillHouse.value,
itemBuilder: (item) => Text(buildKillHouseLabel(item)),
labelBuilder: (item) => Text(buildKillHouseLabel(item)),
);
}, controller.killHouseList),
);
}, controller.selectedKillRequestPoultry),
);
}
String buildKillHouseLabel(KillHousePoultry? item) {
if (item == null) {
return 'خریدار/ظرفیت باقیمانده';
} else {
return '${item.name} / ${item.quantitySum} قطعه ';
}
}
Widget slaughterhouseSelectedWidget() {
return Container(
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
margin: EdgeInsets.symmetric(horizontal: 8.w),
padding: EdgeInsets.symmetric(horizontal: 8.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 8.h),
Text('عملیات کشتار', style: AppFonts.yekan14Bold.copyWith(color: AppColor.blueNormal)),
SizedBox(height: 8.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ObxValue((data) {
return Visibility(
visible: data.value?.permission ?? false,
child: ObxValue(
(data) => TitleCheckBox(
title: ' انجماد',
onChanged: (_) {
controller.isFreezedSelected.value = !controller.isFreezedSelected.value;
},
isSelected: data.value,
),
controller.isFreezedSelected,
),
);
}, controller.sellForFreezing),
ObxValue((data) {
return TitleCheckBox(
title: 'پنل معاملات',
onChanged: (_) {
controller.isMarketSelected.value = !controller.isMarketSelected.value;
},
isSelected: data.value,
);
}, controller.isMarketSelected),
ObxValue((data) {
return Visibility(
visible: data.value?.allow ?? false,
child: ObxValue((data) {
return TitleCheckBox(
title: 'صادرات',
isSelected: data.value,
onChanged: (_) {
controller.isExportSelected.value = !controller.isExportSelected.value;
},
);
}, controller.isExportSelected),
);
}, controller.poultryExport),
],
),
SizedBox(height: 8.h),
],
),
);
}
Widget submitButtonWidget() {
return ObxValue((data) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 12.h),
child: RElevated(
enabled: data.value,
height: 45.h,
isFullWidth: true,
disabledBackgroundColor: AppColor.greenDarkHover,
backgroundColor: AppColor.greenNormal,
textStyle: AppFonts.yekan16Bold.copyWith(color: Colors.white),
onPressed: () {
controller.submitKillRegistration();
},
text: 'ثبت کشتار',
),
);
}, controller.isOnSubmitLoading);
}
}