feat: add otp code for sell order

fix: form for segmentation
This commit is contained in:
2025-11-04 15:48:48 +03:30
parent 6269445536
commit f2183fd2de
22 changed files with 1220 additions and 1288 deletions

View File

@@ -0,0 +1,395 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.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/pages/steward/segmentation/logic.dart';
import 'package:rasadyar_core/core.dart';
Widget addOrEditBottomSheet(SegmentationLogic controller, {bool isOnEdit = false}) {
return BaseBottomSheet(
height: isOnEdit ? 350.h : 600.h,
child: SingleChildScrollView(
child: Form(
key: controller.formKey,
child: Column(
spacing: 16,
children: [
Text(
isOnEdit ? 'ویرایش قطعه‌بندی' : 'افزودن قطعه‌بندی',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
),
_productDropDown(controller),
Visibility(
visible: isOnEdit == false,
child: Container(
height: 50.h,
clipBehavior: Clip.none,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
child: Stack(
fit: StackFit.expand,
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Positioned(
child: Container(color: Colors.white, child: Text("انبار")),
top: -10,
right: 8,
),
Obx(() {
return RadioGroup(
groupValue: controller.quotaType.value,
onChanged: (value) {
controller.quotaType.value = value ?? 0;
},
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: GestureDetector(
onTap: () {
controller.quotaType.value = 1;
},
child: Row(
children: [
Radio(value: 1),
Text('دولتی', style: AppFonts.yekan14),
],
),
),
),
Expanded(
child: GestureDetector(
onTap: () {
controller.quotaType.value = 2;
},
child: Row(
children: [
Radio(value: 2),
Text('آزاد', style: AppFonts.yekan14),
],
),
),
),
],
),
);
}),
],
),
),
),
Obx(() {
return MonthlyDataCalendar(
label: 'تاریخ تولید گوشت',
selectedDate: controller.productionDate.value?.formatCompactDate(),
onDateSelect: (value) {
controller.productionDate.value = value.date;
controller.remainingStock.value = value.remainingStock;
},
dayData: controller.quotaType.value == 1
? controller.governmentalProductionDateData
: controller.freeProductionDateData,
);
}),
RTextField(
controller: controller.weightController,
keyboardType: TextInputType.number,
autoValidateMode: AutovalidateMode.onUserInteraction,
borderColor: AppColor.darkGreyLight,
filledColor: AppColor.bgLight,
filled: true,
inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()],
validator: (value) {
if ((int.tryParse(value?.clearComma ?? '0') ?? 0) >
(controller.remainingStock.value ?? 0)) {
return 'وزن تخصیصی بیشتر از موجودی انبار است';
}
return null;
},
onChanged: (p0) {
controller.weight.value = int.tryParse(p0.clearComma) ?? 0;
},
label: 'وزن لاشه (کیلوگرم)',
),
Visibility(
visible: isOnEdit == false,
child: Container(
height: 58.h,
clipBehavior: Clip.none,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
child: Stack(
fit: StackFit.expand,
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Positioned(
child: Container(color: Colors.white, child: Text("فروش")),
top: -10,
right: 8,
),
Obx(() {
return RadioGroup(
groupValue: controller.priceType.value,
onChanged: (value) {
controller.priceType.value = value!;
},
child: Row(
children: [
Expanded(
child: GestureDetector(
onTap: (controller.broadcastPrice.value?.active ?? false)
? () {
controller.priceType.value = 1;
}
: null,
child: Row(
children: [
Radio(
value: 1,
enabled: controller.broadcastPrice.value?.active ?? false,
),
Text(
'قیمت مصوب',
style: AppFonts.yekan14.copyWith(
color: (controller.broadcastPrice.value?.active ?? false)
? AppColor.textColor
: AppColor.labelTextColor,
),
),
],
),
),
),
Expanded(
child: GestureDetector(
onTap: () {
controller.priceType.value = 2;
},
child: Row(
children: [
Radio(value: 2),
Text('قیمت آزاد', style: AppFonts.yekan14),
],
),
),
),
],
),
);
}),
],
),
),
),
Visibility(
visible: isOnEdit == false,
child: Column(
spacing: 12,
children: [
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.darkGreyLight, width: 1),
),
child: Column(
children: [
const SizedBox(height: 8),
SizedBox(
height: 40,
child: ObxValue((data) {
return RadioGroup(
onChanged: (value) {
controller.segmentType.value = value!;
controller.selectedGuildModel.value = null;
controller.selectedGuildModel.refresh();
},
groupValue: controller.segmentType.value,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Radio(value: 1),
Text('قطعه‌بندی(کاربر)', style: AppFonts.yekan14),
SizedBox(width: 12),
Radio(value: 2),
Text('تخصیص به قطعه‌بند', style: AppFonts.yekan14),
],
),
);
}, controller.priceType),
),
const SizedBox(height: 12),
ObxValue((data) {
return Visibility(
visible: data.value == 2,
child: guildsDropDown(controller),
);
}, controller.segmentType),
],
),
),
],
),
),
submitButtonWidget(controller, isOnEdit: isOnEdit),
SizedBox(),
],
),
),
),
);
}
Widget submitButtonWidget(SegmentationLogic controller, {bool isOnEdit = false}) {
return ObxValue((data) {
return RElevated(
isFullWidth: true,
backgroundColor: AppColor.greenNormal,
text: isOnEdit ? 'ویرایش' : 'ثبت',
onPressed: data.value
? () async {
var res = isOnEdit
? await controller.editSegment()
: await controller.createSegment();
if (res) {
Get.back();
}
}
: null,
height: 40,
);
}, controller.isSubmitButtonEnabled);
}
Widget _productDropDown(SegmentationLogic controller) {
return Obx(() {
return OverlayDropdownWidget<ProductModel>(
items: controller.rootLogic.rolesProductsModel,
height: 56,
hasDropIcon: false,
background: Colors.white,
onChanged: (value) {
controller.selectedProduct.value = value;
},
selectedItem: controller.selectedProduct.value,
initialValue: controller.selectedProduct.value,
itemBuilder: (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(),
ObxValue((data) {
return Visibility(visible: data.value != null, child: Text('موجودی: $data'));
}, controller.remainingStock),
],
),
);
});
}
Widget guildsDropDown(SegmentationLogic controller) {
return Obx(() {
final item = controller.selectedGuildModel.value;
return OverlayDropdownWidget<GuildModel>(
key: ValueKey(item?.user?.fullname ?? ''),
items: controller.guildsModel,
onChanged: (value) {
controller.selectedGuildModel.value = value;
},
selectedItem: item,
itemBuilder: (item) => Text(
item.user != null
? '${item.steward == true ? 'مباشر' : 'صنف'} ${item.user!.fullname} (${item.user!.mobile})'
: 'بدون نام',
),
labelBuilder: (item) => Text(
item?.user != null
? '${item?.steward == true ? 'مباشر' : 'صنف'} ${item?.user!.fullname} (${item?.user!.mobile})'
: 'انتخاب مباشر/صنف',
),
);
});
}
Container modalDatePicker(SegmentationLogic controller, ValueChanged<Jalali> onDateSelected) {
Jalali currentDate = Jalali.now();
Jalali? tempPickedDate;
return Container(
height: 250,
color: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
child: Row(
children: [
SizedBox(width: 20),
RElevated(
height: 35,
width: 70,
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
onPressed: () {
onDateSelected(tempPickedDate ?? Jalali.now());
Get.back();
},
text: 'تایید',
),
Spacer(),
RElevated(
height: 35,
width: 70,
backgroundColor: AppColor.error,
textStyle: AppFonts.yekan14.copyWith(color: Colors.white),
onPressed: () {
onDateSelected(tempPickedDate ?? Jalali.now());
Get.back();
},
text: 'لغو',
),
SizedBox(width: 20),
],
),
),
Divider(height: 0, thickness: 1),
Expanded(
child: Container(
child: PersianCupertinoDatePicker(
initialDateTime: controller.saleDate.value,
mode: PersianCupertinoDatePickerMode.date,
maximumDate: currentDate.addDays(3),
minimumDate: currentDate.toDateTime().subtract(Duration(days: 1)).toString().toJalali,
maximumYear: currentDate.year,
minimumYear: currentDate.year,
onDateTimeChanged: (dateTime) {
tempPickedDate = dateTime;
},
),
),
),
],
),
);
}