feat : new bottom sheet

This commit is contained in:
2025-07-08 11:10:31 +03:30
parent 639a8dd585
commit bbaeb6c2a5
9 changed files with 429 additions and 299 deletions

View File

@@ -18,6 +18,7 @@ class BuyInProvincePage extends GetView<BuyInProvinceLogic> {
onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(),
widgets: [
inventoryWidget(),
segmentWidget(),
ObxValue((index) {
return Expanded(
@@ -88,4 +89,23 @@ class BuyInProvincePage extends GetView<BuyInProvinceLogic> {
),
);
}
Widget inventoryWidget() {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, controller.rootLogic.inventoryModel),
);
}
}

View File

@@ -24,6 +24,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(),
widgets: [
inventoryWidget(),
Expanded(
child: ObxValue((data) {
return RPaginatedListView(
@@ -554,4 +555,23 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
),
);
}
Widget inventoryWidget() {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, controller.rootLogic.inventoryModel),
);
}
}

View File

@@ -74,16 +74,27 @@ class SalesInProvinceLogic extends GetxController {
totalCost.value = callback * weight.value;
});
totalCost.listen((data) {
totalCostController.text = data.toString().separatedByComma;
totalCostController.text = data
.toString()
.separatedByComma;
isValid.value =
weight.value > 0 &&
pricePerKilo.value > 0 &&
totalCost.value > 0 &&
selectedProductModel.value != null &&
selectedGuildModel.value != null;
pricePerKilo.value > 0 &&
totalCost.value > 0 &&
selectedProductModel.value != null &&
selectedGuildModel.value != null;
});
everAll([
totalCost,
weight,
pricePerKilo,
totalCost,
selectedProductModel,
selectedGuildModel
], (callback) => checkVerification(),);
scrollControllerAllocationsMade.addListener(() {
if (scrollControllerAllocationsMade.position.pixels >=
@@ -95,7 +106,7 @@ class SalesInProvinceLogic extends GetxController {
debounce(
searchedValue,
(callback) => getAllocatedMade(),
(callback) => getAllocatedMade(),
time: Duration(milliseconds: timeDebounce),
);
}
@@ -114,7 +125,8 @@ class SalesInProvinceLogic extends GetxController {
}
safeCall(
call: () async => await rootLogic.chickenRepository.getAllocatedMade(
call: () async =>
await rootLogic.chickenRepository.getAllocatedMade(
token: rootLogic.tokenService.accessToken.value!,
queryParameters: buildQueryParams(
page: currentPage.value,
@@ -154,15 +166,16 @@ class SalesInProvinceLogic extends GetxController {
void checkVerification() {
isValid.value =
weight.value > 0 &&
pricePerKilo.value > 0 &&
totalCost.value > 0 &&
selectedProductModel.value != null &&
selectedGuildModel.value != null;
pricePerKilo.value > 0 &&
totalCost.value > 0 &&
selectedProductModel.value != null &&
selectedGuildModel.value != null;
}
void confirmAllocation(ConformAllocation allocation) {
safeCall(
call: () async => await rootLogic.chickenRepository.confirmAllocation(
call: () async =>
await rootLogic.chickenRepository.confirmAllocation(
token: rootLogic.tokenService.accessToken.value!,
allocation: allocation.toJson(),
),
@@ -175,7 +188,8 @@ class SalesInProvinceLogic extends GetxController {
void denyAllocation(String token) {
safeCall(
call: () async => await rootLogic.chickenRepository.denyAllocation(
call: () async =>
await rootLogic.chickenRepository.denyAllocation(
token: rootLogic.tokenService.accessToken.value!,
allocationToken: token,
),
@@ -188,7 +202,8 @@ class SalesInProvinceLogic extends GetxController {
Future<void> confirmAllAllocations() async {
safeCall(
call: () async => await rootLogic.chickenRepository.confirmAllAllocation(
call: () async =>
await rootLogic.chickenRepository.confirmAllAllocation(
token: rootLogic.tokenService.accessToken.value!,
allocationTokens: allocatedList.value.data?.results?.map((e) => e.key!).toList() ?? [],
),
@@ -201,7 +216,8 @@ class SalesInProvinceLogic extends GetxController {
Future<void> getRolesProducts() async {
safeCall(
call: () async => await rootLogic.chickenRepository.getRolesProducts(
call: () async =>
await rootLogic.chickenRepository.getRolesProducts(
token: rootLogic.tokenService.accessToken.value!,
),
onSuccess: (result) {
@@ -216,7 +232,8 @@ class SalesInProvinceLogic extends GetxController {
Future<void> getGuilds() async {
safeCall(
call: () async => await rootLogic.chickenRepository.getGuilds(
call: () async =>
await rootLogic.chickenRepository.getGuilds(
token: rootLogic.tokenService.accessToken.value!,
queryParameters: buildQueryParams(
queryParams: {'free': saleType.value == 2 ? true : false},
@@ -247,7 +264,8 @@ class SalesInProvinceLogic extends GetxController {
Future<void> getGuildProfile() async {
await safeCall(
call: () async => await rootLogic.chickenRepository.getProfile(
call: () async =>
await rootLogic.chickenRepository.getProfile(
token: rootLogic.tokenService.accessToken.value!,
),
onError: (error, stackTrace) {},
@@ -261,7 +279,8 @@ class SalesInProvinceLogic extends GetxController {
tmpStewardAllocation = SubmitStewardAllocation(
approvedPriceStatus: false,
allocationType:
'${guildProfile.value?.steward == true ? "steward" : "guild"}_${selectedGuildModel.value?.steward == true ? "steward" : "guild"}',
'${guildProfile.value?.steward == true ? "steward" : "guild"}_${selectedGuildModel.value
?.steward == true ? "steward" : "guild"}',
sellerType: guildProfile.value?.steward == true ? "Steward" : "Guild",
buyerType: selectedGuildModel.value?.steward == true ? "Steward" : "Guild",
amount: pricePerKilo.value,
@@ -271,14 +290,17 @@ class SalesInProvinceLogic extends GetxController {
numberOfCarcasses: 0,
guildKey: selectedGuildModel.value?.key,
productKey: selectedProductModel.value?.key,
date: DateTime.now().formattedDashedGregorian,
date: DateTime
.now()
.formattedDashedGregorian,
type: "manual",
);
}
Future<void> submitAllocation() async {
safeCall(
call: () async => await rootLogic.chickenRepository.postSubmitStewardAllocation(
call: () async =>
await rootLogic.chickenRepository.postSubmitStewardAllocation(
token: rootLogic.tokenService.accessToken.value!,
request: tmpStewardAllocation!,
),
@@ -292,7 +314,8 @@ class SalesInProvinceLogic extends GetxController {
Future<void> deleteAllocation(AllocatedMadeModel model) async {
safeCall(
call: () async => await rootLogic.chickenRepository.deleteStewardAllocation(
call: () async =>
await rootLogic.chickenRepository.deleteStewardAllocation(
token: rootLogic.tokenService.accessToken.value!,
queryParameters: {'steward_allocation_key': model.key},
),
@@ -318,9 +341,15 @@ class SalesInProvinceLogic extends GetxController {
weight.value = item.weightOfCarcasses ?? 0;
pricePerKilo.value = item.amount ?? 0;
totalCost.value = item.totalAmount ?? 0;
weightController.text = weight.value.toString().separatedByComma;
pricePerKiloController.text = pricePerKilo.value.toString().separatedByComma;
totalCostController.text = totalCost.value.toString().separatedByComma;
weightController.text = weight.value
.toString()
.separatedByComma;
pricePerKiloController.text = pricePerKilo.value
.toString()
.separatedByComma;
totalCostController.text = totalCost.value
.toString()
.separatedByComma;
isValid.value = true;
}
@@ -345,7 +374,8 @@ class SalesInProvinceLogic extends GetxController {
);
safeCall(
call: () async => await rootLogic.chickenRepository.updateStewardAllocation(
call: () async =>
await rootLogic.chickenRepository.updateStewardAllocation(
token: rootLogic.tokenService.accessToken.value!,
request: updatedAllocationModel,
),

View File

@@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.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/presentation/routes/routes.dart';
import 'package:rasadyar_chicken/presentation/utils/string_utils.dart';
import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart';
import 'package:rasadyar_chicken/presentation/widget/list_item/list_item.dart';
@@ -19,10 +20,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
Widget build(BuildContext context) {
return Scaffold(
body: BasePage(
routesWidget: ObxValue(
(route) => buildPageRoute(route),
controller.routesName,
),
routesWidget: ObxValue((route) => buildPageRoute(route), controller.routesName),
onBackPressed: () => Get.back(id: 1),
onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(),
@@ -89,10 +87,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
await controller.confirmAllAllocations();
},
message: 'تایید یکجا',
icon: Assets.vec.clipboardTaskSvg.svg(
width: 40.w,
height: 40.h,
),
icon: Assets.vec.clipboardTaskSvg.svg(width: 40.w, height: 40.h),
backgroundColor: controller.bgConfirmAllColor.value,
),
);
@@ -109,10 +104,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
),
decoration: BoxDecoration(color: AppColor.greenLight, borderRadius: BorderRadius.circular(8)),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
@@ -165,18 +157,13 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
child: Assets.vec.hotChickenSvg.svg(
width: 24,
height: 24,
colorFilter: ColorFilter.mode(
AppColor.blueNormal,
BlendMode.srcIn,
),
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
),
),
Text(
'${item.weightOfCarcasses?.separatedByComma}kg',
textAlign: TextAlign.left,
style: AppFonts.yekan12.copyWith(
color: AppColor.blueNormal,
),
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
],
),
@@ -207,10 +194,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
itemListExpandedWidget(AllocatedMadeModel item, int index) {
return Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
child: Column(
spacing: 8,
children: [
@@ -250,16 +234,12 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
children: [
Text(
item.date?.toJalali.formatter.wN ?? 'N/A',
style: AppFonts.yekan14.copyWith(
color: AppColor.textColor,
),
style: AppFonts.yekan14.copyWith(color: AppColor.textColor),
),
Text(
'${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'N/A'}',
style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal,
),
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
),
],
),
@@ -279,8 +259,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
buildRow(
title: 'نام و نام خانوادگی فروشنده',
value:
controller.getBuyerInformation(item)?.user?.fullname ?? 'N/A',
value: controller.getBuyerInformation(item)?.user?.fullname ?? 'N/A',
),
buildRow(
@@ -298,20 +277,12 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
title: 'افت وزن(کیلوگرم)',
value: item.weightLossOfCarcasses?.toInt().toString() ?? 'N/A',
),
buildRow(
title: 'قیمت کل',
value: '${item.totalAmount?.separatedByComma} ریال',
),
buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByComma} ریال'),
buildRow(
title: 'کداحراز',
value: item.registrationCode?.toString() ?? 'ندارد',
),
buildRow(title: 'کداحراز', value: item.registrationCode?.toString() ?? 'ندارد'),
buildRow(
title: 'وضعیت کد احراز',
value: item.systemRegistrationCode == true
? "ارسال شده"
: "ارسال نشده",
value: item.systemRegistrationCode == true ? "ارسال شده" : "ارسال نشده",
),
Row(
@@ -360,45 +331,36 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
Widget addOrEditBottomSheet([bool isEditMode = false]) {
return BaseBottomSheet(
height: Get.height * (isEditMode ? 0.45 : 0.75),
child: Padding(
padding: EdgeInsets.only(
left: 16,
right: 16,
top: 16,
bottom: MediaQuery.of(Get.context!).viewInsets.bottom + 16,
),
child: Form(
key: controller.formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${isEditMode ? 'ویرایش' : 'ثبت'} توزیع/ فروش',
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
child: Form(
key: controller.formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${isEditMode ? 'ویرایش' : 'ثبت'} توزیع/ فروش',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor),
),
const SizedBox(height: 12),
productDropDown(),
const SizedBox(height: 12),
Visibility(
visible: isEditMode == false,
child: Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
),
Visibility(
visible: isEditMode == false,
child: Column(
children: [
const SizedBox(height: 12),
RTextField(
controller: TextEditingController(),
label: 'تاریخ',
enabled: false,
initText: Jalali.now().formatCompactDate(),
),
const SizedBox(height: 12),
Material(
type: MaterialType.transparency,
child: productDropDown(),
),
const SizedBox(height: 12),
const SizedBox(height: 8),
SizedBox(
height: 40,
child: ObxValue((data) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Radio(
value: 1,
@@ -430,99 +392,129 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
],
),
),
const SizedBox(height: 12),
RTextField(
controller: controller.weightController,
keyboardType: TextInputType.number,
borderColor: AppColor.darkGreyLight,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
],
validator: (value) {
if (int.parse(value!.clearComma) >
(controller
.rootLogic
.inventoryModel
.value
?.totalRemainWeight
?.toInt() ??
100)) {
return 'وزن تخصیصی بیشتر از موجودی انبار است';
}
return null;
},
onChanged: (p0) {
controller.weight.value = int.tryParse(p0.clearComma) ?? 0;
},
label: 'وزن لاشه',
),
const SizedBox(height: 12),
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
const SizedBox(height: 12),
RTextField(
controller: controller.pricePerKiloController,
borderColor: AppColor.darkGreyLight,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
],
child: Column(
spacing: 12,
children: [
Visibility(
visible: isEditMode == false,
child: Column(
children: [
const SizedBox(height: 8),
ObxValue((data) {
return RTextField(
controller: TextEditingController(),
filledColor: AppColor.bgLight,
filled: true,
label: 'تاریخ',
onTap: () {
Get.bottomSheet(
modalDatePicker((value) {
controller.fromDateFilter.value = value;
controller.fromDateFilter.refresh();
}),
);
},
borderColor: AppColor.darkGreyLight,
initText: (data.value ?? Jalali.now()).formatCompactDate(),
);
}, controller.fromDateFilter),
],
),
),
onChanged: (p0) {
controller.pricePerKilo.value =
int.tryParse(p0.clearComma) ?? 0;
},
keyboardType: TextInputType.number,
label: 'قیمت هر کیلو',
),
const SizedBox(height: 12),
RTextField(
enabled: false,
keyboardType: TextInputType.number,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
],
borderColor: AppColor.darkGreyLight,
controller: controller.totalCostController,
label: 'هزینه کل',
),
const SizedBox(height: 20),
ObxValue((data) {
return RElevated(
text: isEditMode ? 'ویرایش' : 'ثبت',
isFullWidth: true,
textStyle: AppFonts.yekan16.copyWith(color: Colors.white),
height: 40,
onPressed: data.value
? () async {
if (controller.formKey.currentState?.validate() ??
false) {
iLog("s2");
controller.setSubmitData();
iLog("s3");
// Get.bottomSheet(show2StepAddBottomSheet());
}
/* isEditMode
? await controller.updateAllocation()
: () {
iLog("s1");
if (controller.formKey.currentState?.validate() ?? false) {
iLog("s2");
controller.setSubmitData();
iLog("s3");
Get.bottomSheet(show2StepAddBottomSheet());
}
};
RTextField(
controller: controller.weightController,
keyboardType: TextInputType.number,
borderColor: AppColor.darkGreyLight,
filledColor: AppColor.bgLight,
filled: true,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
],
validator: (value) {
if (int.parse(value!.clearComma) >
(controller.rootLogic.inventoryModel.value?.totalRemainWeight?.toInt() ??
100)) {
return 'وزن تخصیصی بیشتر از موجودی انبار است';
}
return null;
},
onChanged: (p0) {
controller.weight.value = int.tryParse(p0.clearComma) ?? 0;
},
label: 'وزن لاشه',
),
controller.clearForm();
controller.getAllocatedMade();
Get.back();*/
}
: null,
);
}, controller.isValid),
const SizedBox(height: 20),
],
),
RTextField(
controller: controller.pricePerKiloController,
borderColor: AppColor.darkGreyLight,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
],
filledColor: AppColor.bgLight,
filled: true,
onChanged: (p0) {
controller.pricePerKilo.value = int.tryParse(p0.clearComma) ?? 0;
},
keyboardType: TextInputType.number,
label: 'قیمت هر کیلو',
),
RTextField(
variant: RTextFieldVariant.noBorder,
enabled: false,
keyboardType: TextInputType.number,
filledColor: AppColor.bgLight,
filled: true,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
],
controller: controller.totalCostController,
label: 'هزینه کل',
),
ObxValue((data) {
return RElevated(
text: isEditMode ? 'ویرایش' : 'ثبت',
isFullWidth: true,
textStyle: AppFonts.yekan16.copyWith(color: Colors.white),
backgroundColor: AppColor.greenNormal,
height: 40,
onPressed: data.value
? () async {
if (isEditMode) {
await controller.updateAllocation();
controller.clearForm();
controller.getAllocatedMade();
controller.rootLogic.getInventory();
Get.back();
} else {
if (controller.formKey.currentState?.validate() ?? false) {
controller.setSubmitData();
await Get.bottomSheet(show2StepAddBottomSheet());
}
}
}
: null,
);
}, controller.isValid),
],
),
),
const SizedBox(height: 20),
],
),
),
);
@@ -556,12 +548,28 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
return Obx(() {
return OverlayDropdownWidget<ProductModel>(
items: controller.rolesProductsModel,
height: 56,
hasDropIcon: false,
background: Colors.white,
onChanged: (value) {
controller.selectedProductModel.value = value;
},
selectedItem: controller.selectedProductModel.value,
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
labelBuilder: (item) => Text(item?.name ?? 'انتخاب محصول'),
labelBuilder: (item) => Row(
spacing: 8,
children: [
(item?.name?.contains('مرغ گرم') ?? false)
? Assets.images.chicken.image(width: 40, height: 40)
: Assets.vec.placeHolderSvg.svg(width: 40, height: 40),
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0}',
),
],
),
);
});
}
@@ -572,20 +580,14 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
child: Column(
spacing: 16,
children: [
Text(
'فیلترها',
style: AppFonts.yekan16Bold.copyWith(
color: AppColor.darkGreyDarkHover,
),
),
Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover)),
Row(
spacing: 8,
children: [
Expanded(
child: timeFilterWidget(
date: controller.fromDateFilter,
onChanged: (jalali) =>
controller.fromDateFilter.value = jalali,
onChanged: (jalali) => controller.fromDateFilter.value = jalali,
),
),
Expanded(
@@ -634,10 +636,7 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
Assets.vec.calendarSvg.svg(
width: 24,
height: 24,
colorFilter: const ColorFilter.mode(
AppColor.blueNormal,
BlendMode.srcIn,
),
colorFilter: const ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
),
Text(
isFrom ? 'از' : 'تا',
@@ -646,12 +645,9 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
Expanded(
child: ObxValue((data) {
return Text(
date.value?.formatCompactDate() ??
Jalali.now().formatCompactDate(),
date.value?.formatCompactDate() ?? Jalali.now().formatCompactDate(),
textAlign: TextAlign.center,
style: AppFonts.yekan16.copyWith(
color: AppColor.lightGreyNormalActive,
),
style: AppFonts.yekan16.copyWith(color: AppColor.lightGreyNormalActive),
);
}, date),
),
@@ -716,33 +712,48 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
);
}
/* Widget show2StepAddBottomSheet() {
Widget show2StepAddBottomSheet() {
return BaseBottomSheet(
height: Get.height*.35,
height: Get.height * .35,
child: Column(
spacing: 8,
children: [
buildRow('تاریخ ثبت', controller.tmpStewardAllocation?.date?.formattedJalaliDate ?? 'N/A'),
buildRow(
'نام و نام خانوادگی خریدار',
controller.guildsModel
title: 'تاریخ ثبت',
value: controller.tmpStewardAllocation?.date?.formattedJalaliDate ?? 'N/A',
),
buildRow(
title: 'نام و نام خانوادگی خریدار',
value:
controller.guildsModel
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
.user
?.fullname ??
'N/A',
),
buildRow(
'شماره خریدار',
controller.guildsModel.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey).user?.mobile ??
title: 'شماره خریدار',
value:
controller.guildsModel
.firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey)
.user
?.mobile ??
'N/A',
),
buildRow('قیمت هر کیلو', '${controller.tmpStewardAllocation?.amount.separatedByComma ?? 0} ریال '),
buildRow(
'وزن تخصیصی',
'${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByComma ?? 0} کیلوگرم',
title: 'قیمت هر کیلو',
value: '${controller.tmpStewardAllocation?.amount.separatedByComma ?? 0} ریال ',
),
buildRow(
title: 'وزن تخصیصی',
value:
'${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByComma ?? 0} کیلوگرم',
),
buildRow(
title: 'قیمت کل',
value: '${controller.tmpStewardAllocation?.totalAmount.separatedByComma ?? 0} ریال',
),
buildRow('قیمت کل', '${controller.tmpStewardAllocation?.totalAmount.separatedByComma ?? 0} ریال'),
Row(
spacing: 10,
@@ -754,8 +765,10 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
text: 'ثبت',
textStyle: AppFonts.yekan18.copyWith(color: Colors.white),
onPressed: () async {
await controller.submitAllocation();
Get..back()..back();
await controller.submitAllocation();
Get
..back()
..back();
},
),
),
@@ -775,5 +788,5 @@ class SalesInProvincePage extends GetView<SalesInProvinceLogic> {
],
),
);
}*/
}
}

View File

@@ -21,6 +21,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(),
widgets: [
inventoryWidget(),
segmentWidget(),
Expanded(
child: ObxValue((index) {
@@ -100,4 +101,23 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
),
);
}
Widget inventoryWidget() {
return Container(
width: Get.width,
height: 39,
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: AppColor.greenLight,
borderRadius: BorderRadius.circular(8),
),
alignment: Alignment.center,
child: ObxValue((data) {
return Text(
' موجودی انبار: ${data.value?.totalRemainWeight?.toInt().separatedByComma ?? '0'} کیلوگرم',
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover),
);
}, controller.rootLogic.inventoryModel),
);
}
}

View File

@@ -1,5 +1,4 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
part 'pagination_model.freezed.dart';
part 'pagination_model.g.dart';

View File

@@ -13,7 +13,7 @@ class BaseBottomSheet extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
height: height ?? MediaQuery.of(context).size.height * 0.85,
padding: EdgeInsets.symmetric(vertical: 15, horizontal: 20),
padding: EdgeInsets.symmetric(vertical: 15, horizontal: 10),
decoration: BoxDecoration(
color: bgColor ?? Colors.white,
borderRadius: BorderRadius.only(

View File

@@ -34,6 +34,7 @@ class RTextField extends StatefulWidget {
final FormFieldValidator<String>? validator;
final void Function(String)? onChanged;
final void Function(String)? onSubmitted;
final VoidCallback? onTap;
final List<TextInputFormatter>? inputFormatters;
final Widget? suffix;
@@ -68,6 +69,7 @@ class RTextField extends StatefulWidget {
this.onSubmitted,
this.borderColor,
this.inputFormatters,
this.onTap,
this.suffix,
});
@@ -80,12 +82,12 @@ class RTextField extends StatefulWidget {
bool get _passwordNoBorder => variant == RTextFieldVariant.passwordNoBorder;
InputBorder get _inputBorder => _noBorder || _passwordNoBorder
? InputBorder.none
: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: borderColor ?? AppColor.lightGreyDarkActive, width: 1),
);
InputBorder get _inputBorder => OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: _noBorder || _passwordNoBorder
? BorderSide.none
: BorderSide(color: borderColor ?? AppColor.darkGreyLight, width: 1),
);
}
class _RTextFieldState extends State<RTextField> {
@@ -142,6 +144,7 @@ class _RTextFieldState extends State<RTextField> {
inputFormatters: widget.inputFormatters,
enabled: widget.enabled,
obscureText: obscure,
onTap: widget.onTap,
onTapOutside: (_) => FocusScope.of(context).unfocus(),
onFieldSubmitted: widget.onSubmitted,
maxLength: widget.maxLength,

View File

@@ -7,6 +7,9 @@ class OverlayDropdownWidget<T> extends StatefulWidget {
final List<T> items;
final T? selectedItem;
final T? initialValue;
final int? height;
final Color? background;
final bool? hasDropIcon;
final Widget Function(T item) itemBuilder;
final Widget Function(T? selected) labelBuilder;
final void Function(T selected)? onChanged;
@@ -21,6 +24,9 @@ class OverlayDropdownWidget<T> extends StatefulWidget {
this.onChanged,
this.selectedItem,
this.contentPadding,
this.height,
this.background,
this.hasDropIcon = true,
});
@override
@@ -58,7 +64,6 @@ class _OverlayDropdownState<T> extends State<OverlayDropdownWidget<T>> {
elevation: 4,
borderRadius: BorderRadius.circular(8),
child: Container(
decoration: BoxDecoration(
color: AppColor.bgLight,
border: Border.all(color: AppColor.darkGreyLight),
@@ -81,7 +86,9 @@ class _OverlayDropdownState<T> extends State<OverlayDropdownWidget<T>> {
_removeOverlay();
},
child: Padding(
padding: widget.contentPadding ?? const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
padding:
widget.contentPadding ??
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: widget.itemBuilder(item),
),
);
@@ -120,19 +127,25 @@ class _OverlayDropdownState<T> extends State<OverlayDropdownWidget<T>> {
_isOpen.value ? _removeOverlay() : _showOverlay();
},
child: Container(
height: 40,
height: widget.height?.toDouble() ?? 40,
width: Get.width,
padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
color: AppColor.bgLight,
color: widget.background ?? AppColor.bgLight,
border: Border.all(color: AppColor.darkGreyLight),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
widget.labelBuilder(selectedItem),
Icon(_isOpen.value ? CupertinoIcons.chevron_up : CupertinoIcons.chevron_down, size: 14),
Expanded(child: widget.labelBuilder(selectedItem)),
Visibility(
visible: widget.hasDropIcon!,
child: Icon(
_isOpen.value ? CupertinoIcons.chevron_up : CupertinoIcons.chevron_down,
size: 14,
),
),
],
),
),
@@ -140,7 +153,6 @@ class _OverlayDropdownState<T> extends State<OverlayDropdownWidget<T>> {
}
}
class OverlayDropdownWidget2<T> extends StatefulWidget {
final List<T> items;
final T? selectedItem;
@@ -208,65 +220,73 @@ class _OverlayDropdownState2<T> extends State<OverlayDropdownWidget2<T>> {
child: Material(
elevation: 4,
borderRadius: BorderRadius.circular(8),
child: Obx(() => Container(
decoration: BoxDecoration(
color: AppColor.bgLight,
border: Border.all(color: AppColor.darkGreyLight),
borderRadius: BorderRadius.circular(8),
),
constraints: BoxConstraints(maxHeight: 300),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8),
child: TextField(
controller: _searchController,
decoration: const InputDecoration(
hintText: 'جستجو...',
isDense: true,
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
border: OutlineInputBorder(),
),
onChanged: (query) {
_filteredItems.value = widget.items
.where((item) =>
widget.itemToString?.call(item).toLowerCase().contains(query.toLowerCase()) ??
false)
.toList();
},
),
),
if (_filteredItems.isEmpty)
const Padding(
padding: EdgeInsets.all(16.0),
child: Text("نتیجه‌ای یافت نشد."),
),
if (_filteredItems.isNotEmpty)
Expanded(
child: ListView(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
children: _filteredItems.map((item) {
return InkWell(
onTap: () {
widget.onChanged?.call(item);
setState(() {
selectedItem = item;
});
_removeOverlay();
},
child: Padding(
padding: widget.contentPadding ??
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: widget.itemBuilder(item),
),
);
}).toList(),
child: Obx(
() => Container(
decoration: BoxDecoration(
color: AppColor.bgLight,
border: Border.all(color: AppColor.darkGreyLight),
borderRadius: BorderRadius.circular(8),
),
constraints: BoxConstraints(maxHeight: 300),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8),
child: TextField(
controller: _searchController,
decoration: const InputDecoration(
hintText: 'جستجو...',
isDense: true,
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
border: OutlineInputBorder(),
),
onChanged: (query) {
_filteredItems.value = widget.items
.where(
(item) =>
widget.itemToString
?.call(item)
.toLowerCase()
.contains(query.toLowerCase()) ??
false,
)
.toList();
},
),
),
],
if (_filteredItems.isEmpty)
const Padding(
padding: EdgeInsets.all(16.0),
child: Text("نتیجه‌ای یافت نشد."),
),
if (_filteredItems.isNotEmpty)
Expanded(
child: ListView(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
children: _filteredItems.map((item) {
return InkWell(
onTap: () {
widget.onChanged?.call(item);
setState(() {
selectedItem = item;
});
_removeOverlay();
},
child: Padding(
padding:
widget.contentPadding ??
const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: widget.itemBuilder(item),
),
);
}).toList(),
),
),
],
),
),
)),
),
),
),
],
@@ -309,13 +329,18 @@ class _OverlayDropdownState2<T> extends State<OverlayDropdownWidget2<T>> {
border: Border.all(color: AppColor.darkGreyLight),
borderRadius: BorderRadius.circular(8),
),
child: Obx(() => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
widget.labelBuilder(selectedItem),
Icon(_isOpen.value ? CupertinoIcons.chevron_up : CupertinoIcons.chevron_down, size: 14),
],
)),
child: Obx(
() => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: widget.labelBuilder(selectedItem)),
Icon(
_isOpen.value ? CupertinoIcons.chevron_up : CupertinoIcons.chevron_down,
size: 14,
),
],
),
),
),
),
);