feat : sale out of Province
This commit is contained in:
@@ -22,6 +22,7 @@ class OutOfProvinceLogic extends GetxController {
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
getStewardDashBord();
|
||||
getRolesProducts();
|
||||
}
|
||||
|
||||
Future<void> getAllocatedMade() async {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart' show Colors;
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:rasadyar_auth/data/services/token_storage_service.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/chicken_repository.dart';
|
||||
import 'package:rasadyar_chicken/data/repositories/chicken_repository_imp.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/home/view.dart';
|
||||
@@ -28,8 +29,6 @@ class RootLogic extends GetxController {
|
||||
GlobalKey<NavigatorState>(),
|
||||
];
|
||||
|
||||
|
||||
|
||||
late DioRemote dioRemote;
|
||||
var tokenService = Get.find<TokenStorageService>();
|
||||
late ChickenRepository chickenRepository;
|
||||
@@ -37,6 +36,8 @@ class RootLogic extends GetxController {
|
||||
RxList<ErrorLocationType> errorLocationType = RxList();
|
||||
RxMap<int, dynamic> inventoryExpandedList = RxMap();
|
||||
|
||||
RxList<IranProvinceCityModel> provinces = <IranProvinceCityModel>[].obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
@@ -44,6 +45,8 @@ class RootLogic extends GetxController {
|
||||
dioRemote.init();
|
||||
chickenRepository = ChickenRepositoryImpl(dioRemote);
|
||||
|
||||
getProvinces();
|
||||
|
||||
/*getInventory();
|
||||
getKillHouseDistributionInfo();*/
|
||||
}
|
||||
@@ -65,4 +68,16 @@ class RootLogic extends GetxController {
|
||||
void changePage(int index) {
|
||||
currentPage.value = index;
|
||||
}
|
||||
|
||||
Future<void> getProvinces() async {
|
||||
try {
|
||||
final res = await chickenRepository.getProvince();
|
||||
if (res != null) {
|
||||
provinces.clear();
|
||||
provinces.value = res;
|
||||
}
|
||||
} catch (e) {
|
||||
provinces.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,191 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:rasadyar_auth/data/utils/safe_call.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/out_of_province/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/root/logic.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
class SalesOutOfProvinceLogic extends GetxController {
|
||||
RxBool isExpanded = false.obs;
|
||||
RxBool isSubmitButtonEnabled = false.obs;
|
||||
RxList<int> isExpandedList = <int>[].obs;
|
||||
RxBool searchIsSelected = false.obs;
|
||||
|
||||
//TODO add this to Di
|
||||
ImagePicker imagePicker = ImagePicker();
|
||||
|
||||
Rx<Resource<List<StewardFreeBar>>> purchaseOutOfProvinceList = Resource<List<StewardFreeBar>>.loading().obs;
|
||||
Rxn<ProductModel> selectedProduct = Rxn();
|
||||
|
||||
RxList<IranProvinceCityModel> cites = <IranProvinceCityModel>[].obs;
|
||||
Rxn<IranProvinceCityModel> selectedProvince = Rxn();
|
||||
Rxn<IranProvinceCityModel> selectedCity = Rxn();
|
||||
Rxn<XFile> selectedImage = Rxn<XFile>();
|
||||
RxnString _base64Image = RxnString();
|
||||
RxnString editImageUrl = RxnString();
|
||||
|
||||
RootLogic get rootLogic => Get.find<RootLogic>();
|
||||
|
||||
OutOfProvinceLogic get outOfTheProvinceLogic => Get.find<OutOfProvinceLogic>();
|
||||
|
||||
TextEditingController sellerNameController = TextEditingController();
|
||||
TextEditingController sellerPhoneController = TextEditingController();
|
||||
TextEditingController carcassVolumeController = TextEditingController();
|
||||
TextEditingController carcassWeightController = TextEditingController();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
// TODO: implement onReady
|
||||
super.onReady();
|
||||
getStewardPurchaseOutOfProvince();
|
||||
selectedProvince.listen((p0) => getCites());
|
||||
setupListeners();
|
||||
debounce(searchedValue, (callback) => getStewardPurchaseOutOfProvince(), time: Duration(milliseconds: 2000));
|
||||
ever(searchIsSelected, (data) {
|
||||
if (data == false) {
|
||||
searchedValue.value = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// TODO: implement onClose
|
||||
sellerNameController.dispose();
|
||||
sellerPhoneController.dispose();
|
||||
carcassVolumeController.dispose();
|
||||
carcassWeightController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
Future<void> getStewardPurchaseOutOfProvince() async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 10,
|
||||
page: 1,
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value,
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) {
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
purchaseOutOfProvinceList.value = Resource<List<StewardFreeBar>>.empty();
|
||||
} else {
|
||||
purchaseOutOfProvinceList.value = Resource<List<StewardFreeBar>>.success(res!.results!);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getCites() async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''),
|
||||
onSuccess: (result) {
|
||||
if (result != null && result.isNotEmpty) {
|
||||
cites.value = result;
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void setupListeners() {
|
||||
sellerNameController.addListener(checkFormValid);
|
||||
sellerPhoneController.addListener(checkFormValid);
|
||||
carcassVolumeController.addListener(checkFormValid);
|
||||
carcassWeightController.addListener(checkFormValid);
|
||||
|
||||
ever(selectedProvince, (_) => checkFormValid());
|
||||
ever(selectedCity, (_) => checkFormValid());
|
||||
ever(selectedProduct, (_) => checkFormValid());
|
||||
ever(selectedImage, (data) async {
|
||||
checkFormValid();
|
||||
if (data?.path != null) {
|
||||
_base64Image.value = await convertImageToBase64(data!.path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void checkFormValid() {
|
||||
isSubmitButtonEnabled.value =
|
||||
sellerNameController.text.isNotEmpty &&
|
||||
sellerPhoneController.text.isNotEmpty &&
|
||||
carcassVolumeController.text.isNotEmpty &&
|
||||
carcassWeightController.text.isNotEmpty &&
|
||||
selectedProvince.value != null &&
|
||||
selectedCity.value != null &&
|
||||
selectedProduct.value != null &&
|
||||
selectedImage.value != null;
|
||||
}
|
||||
|
||||
Future<void> createStewardPurchaseOutOfProvince() async => await safeCall(
|
||||
call: () async {
|
||||
CreateStewardFreeBar createStewardFreeBar = CreateStewardFreeBar(
|
||||
productKey: selectedProduct.value!.key,
|
||||
killHouseName: sellerNameController.text,
|
||||
killHouseMobile: sellerPhoneController.text,
|
||||
province: selectedProvince.value!.name,
|
||||
city: selectedCity.value!.name,
|
||||
weightOfCarcasses: int.parse(carcassWeightController.text),
|
||||
barImage: _base64Image.value,
|
||||
date: DateTime.now().formattedYHMS,
|
||||
);
|
||||
final res = await rootLogic.chickenRepository.createStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: createStewardFreeBar,
|
||||
);
|
||||
},
|
||||
onSuccess: (result) {
|
||||
getStewardPurchaseOutOfProvince();
|
||||
resetSubmitForm();
|
||||
},
|
||||
);
|
||||
|
||||
void resetSubmitForm() {
|
||||
sellerNameController.clear();
|
||||
sellerPhoneController.clear();
|
||||
carcassVolumeController.clear();
|
||||
carcassWeightController.clear();
|
||||
selectedProvince.value = null;
|
||||
selectedCity.value = null;
|
||||
selectedProduct.value = null;
|
||||
selectedImage.value = null;
|
||||
_base64Image.value = null;
|
||||
editImageUrl.value = null;
|
||||
|
||||
isSubmitButtonEnabled.value = false;
|
||||
}
|
||||
|
||||
void setEditData(StewardFreeBar item) {
|
||||
iLog(item.barImage);
|
||||
editImageUrl.value = item.barImage;
|
||||
sellerNameController.text = item.killHouseName ?? '';
|
||||
sellerPhoneController.text = item.killHouseMobile ?? '';
|
||||
carcassVolumeController.text = item.weightOfCarcasses?.toString() ?? '';
|
||||
carcassWeightController.text = item.weightOfCarcasses?.toString() ?? '';
|
||||
selectedProvince.value = IranProvinceCityModel(name: item.province);
|
||||
selectedCity.value = IranProvinceCityModel(name: item.city);
|
||||
selectedProduct.value = outOfTheProvinceLogic.rolesProductsModel.firstWhere(
|
||||
(element) => element.key == item.product!.key,
|
||||
);
|
||||
isSubmitButtonEnabled.value = true;
|
||||
}
|
||||
|
||||
Future<void> deleteStewardPurchaseOutOfProvince(String key) async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.deleteStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
stewardFreeBarKey: key,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
@@ -25,28 +30,34 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
Assets.vec.chickenSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: const ColorFilter.mode(
|
||||
Colors.white,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'رصدطیور',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: Colors.white),
|
||||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
),
|
||||
Text('رصدطیور', style: AppFonts.yekan16Bold.copyWith(color: Colors.white)),
|
||||
],
|
||||
),
|
||||
additionalActions: [
|
||||
Assets.vec.searchSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
GestureDetector(
|
||||
onTap: (){
|
||||
|
||||
controller.searchIsSelected.value = !controller.searchIsSelected.value;
|
||||
|
||||
},
|
||||
child: Assets.vec.searchSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Assets.vec.filterOutlineSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Get.bottomSheet(filterBottomSheet());
|
||||
},
|
||||
child: Assets.vec.filterOutlineSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
],
|
||||
@@ -55,43 +66,62 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
routePageWidget(),
|
||||
_buildSearchWidget(),
|
||||
Expanded(child: saleListWidget()),
|
||||
],
|
||||
),
|
||||
floatingActionButton: RFab.add(onPressed: () {}),
|
||||
floatingActionButton: RFab.add(
|
||||
onPressed: () {
|
||||
Get.bottomSheet(addPurchasedInformationBottomSheet(), isScrollControlled: true);
|
||||
},
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
|
||||
);
|
||||
}
|
||||
|
||||
ListView saleListWidget() {
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 18, 80),
|
||||
itemBuilder: (context, index) {
|
||||
return ObxValue(
|
||||
(data) => saleListItem(data, index),
|
||||
controller.isExpandedList,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8),
|
||||
itemCount: 5,
|
||||
);
|
||||
Widget saleListWidget() {
|
||||
return ObxValue((data) {
|
||||
switch (data.value.status) {
|
||||
case Status.initial:
|
||||
case Status.loading:
|
||||
return Center(child: CupertinoActivityIndicator());
|
||||
case Status.success:
|
||||
return ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: BouncingScrollPhysics(),
|
||||
padding: EdgeInsets.fromLTRB(8, 8, 18, 80),
|
||||
itemBuilder: (context, index) {
|
||||
return ObxValue(
|
||||
(expandList) => saleListItem(expandList: expandList, index: index, item: data.value.data![index]),
|
||||
controller.isExpandedList,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => SizedBox(height: 8),
|
||||
itemCount: data.value.data?.length ?? 0,
|
||||
);
|
||||
case Status.error:
|
||||
return Center(
|
||||
child: Text(
|
||||
data.value.message ?? 'خطا در دریافت اطلاعات',
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.error),
|
||||
),
|
||||
);
|
||||
case Status.empty:
|
||||
return emptyWidget();
|
||||
}
|
||||
}, controller.purchaseOutOfProvinceList);
|
||||
}
|
||||
|
||||
Widget emptyWidget() {
|
||||
return Center(
|
||||
child: Text(
|
||||
'داده ای دریافت نشد!',
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
child: Text('داده ای دریافت نشد!', style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkHover)),
|
||||
);
|
||||
}
|
||||
|
||||
GestureDetector saleListItem(RxList<int> data, int index) {
|
||||
GestureDetector saleListItem({required RxList<int> expandList, required int index, required StewardFreeBar item}) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (data.contains(index)) {
|
||||
if (expandList.contains(index)) {
|
||||
controller.isExpandedList.remove(index);
|
||||
} else {
|
||||
controller.isExpandedList.add(index);
|
||||
@@ -100,7 +130,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
child: AnimatedContainer(
|
||||
duration: Duration(milliseconds: 400),
|
||||
alignment: Alignment.center,
|
||||
height: data.contains(index) ? 210 : 56,
|
||||
height: expandList.contains(index) ? 170 : 56,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: Alignment.centerRight,
|
||||
@@ -108,7 +138,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
AnimatedContainer(
|
||||
width: Get.width - 30,
|
||||
duration: Duration(milliseconds: 300),
|
||||
height: data.contains(index) ? 210 : 56,
|
||||
height: expandList.contains(index) ? 170 : 56,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
@@ -121,27 +151,23 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Text(
|
||||
'1403/5/5',
|
||||
item.date?.formattedJalaliDate ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
Text(
|
||||
'افلاک',
|
||||
item.killHouseName ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
Text(
|
||||
'kg 200 مرغ گرم ',
|
||||
'kg ${item.weightOfCarcasses} ${item.product?.name}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
||||
),
|
||||
|
||||
Text(
|
||||
'لرستان-خرم آباد',
|
||||
'${item.province}-${item.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
@@ -152,39 +178,46 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
secondChild: Container(
|
||||
padding: EdgeInsets.fromLTRB(8, 12, 14, 12),
|
||||
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Assets.vec.editSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.blueNormal,
|
||||
BlendMode.srcIn,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
controller.setEditData(item);
|
||||
Get.bottomSheet(
|
||||
addPurchasedInformationBottomSheet(true),
|
||||
isScrollControlled: true,
|
||||
).whenComplete(() {
|
||||
controller.resetSubmitForm();
|
||||
});
|
||||
},
|
||||
child: Assets.vec.editSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
|
||||
Text(
|
||||
'لرستان - خرم آباد',
|
||||
'${item.province}-${item.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: AppColor.greenDark,
|
||||
),
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.greenDark),
|
||||
),
|
||||
|
||||
Assets.vec.trashSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.error,
|
||||
BlendMode.srcIn,
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
buildDeleteDialog(
|
||||
onConfirm: () => controller.deleteStewardPurchaseOutOfProvince(item.key!),
|
||||
);
|
||||
},
|
||||
child: Assets.vec.trashSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: ColorFilter.mode(AppColor.error, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -195,19 +228,15 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 1,
|
||||
color: AppColor.blueLightHover,
|
||||
),
|
||||
side: BorderSide(width: 1, color: AppColor.blueLightHover),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: buildRow('تاریخ', '07:15:00 - 1402/07/01'),
|
||||
child: buildRow('تاریخ', item.date?.formattedJalaliDateYHMS ?? 'N/A'),
|
||||
),
|
||||
|
||||
buildRow('مشخصات فروشنده', 'افلاک - 09203659874'),
|
||||
buildRow('وزن خریداری شده', '200 کیلوگرم'),
|
||||
buildRow('لاشه خریداری شده', '200 عدد'),
|
||||
buildRow('مشخصات فروشنده', '${item.killHouseName} - ${item.killHouseMobile ?? 'N/A'}'),
|
||||
buildRow('وزن خریداری شده', '${item.weightOfCarcasses?.toInt()} کیلوگرم'),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [Icon(CupertinoIcons.chevron_up, size: 12)],
|
||||
@@ -215,9 +244,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
],
|
||||
),
|
||||
),
|
||||
crossFadeState: data.contains(index)
|
||||
? CrossFadeState.showSecond
|
||||
: CrossFadeState.showFirst,
|
||||
crossFadeState: expandList.contains(index) ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
||||
duration: Duration(milliseconds: 300),
|
||||
),
|
||||
),
|
||||
@@ -230,16 +257,10 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.greenLightHover,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(
|
||||
width: 0.50,
|
||||
color: AppColor.greenDarkActive,
|
||||
),
|
||||
border: Border.all(width: 0.50, color: AppColor.greenDarkActive),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
(index + 1).toString(),
|
||||
style: AppFonts.yekan12.copyWith(color: Colors.black),
|
||||
),
|
||||
child: Text((index + 1).toString(), style: AppFonts.yekan12.copyWith(color: Colors.black)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -262,10 +283,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
Assets.vec.cubeSearchSvg.svg(
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: const ColorFilter.mode(
|
||||
AppColor.blueNormal,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
colorFilter: const ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
SizedBox(width: 6),
|
||||
],
|
||||
@@ -293,9 +311,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.darkGreyDarkHover,
|
||||
),
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
@@ -303,8 +319,354 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
child: Text(
|
||||
value,
|
||||
textAlign: TextAlign.left,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.darkGreyDarkHover,
|
||||
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget addPurchasedInformationBottomSheet([bool isOnEdit = false]) {
|
||||
return BaseBottomSheet(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
isOnEdit ? 'ویرایش اطلاعات خرید' : 'ثبت اطلاعات خرید',
|
||||
style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover),
|
||||
),
|
||||
_productTypeWidget(),
|
||||
RTextField(
|
||||
controller: controller.sellerNameController,
|
||||
label: 'نام فروشنده',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.sellerPhoneController,
|
||||
label: 'تلفن فروشنده',
|
||||
keyboardType: TextInputType.phone,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
),
|
||||
_provinceWidget(),
|
||||
_cityWidget(),
|
||||
RTextField(
|
||||
controller: controller.carcassWeightController,
|
||||
label: 'وزن لاشه',
|
||||
keyboardType: TextInputType.number,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.carcassVolumeController,
|
||||
label: 'حجم لاشه',
|
||||
onChanged: (p0) {
|
||||
iLog(controller.carcassVolumeController.text);
|
||||
},
|
||||
keyboardType: TextInputType.number,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
),
|
||||
_imageCarcasesWidget(isOnEdit),
|
||||
submitButtonWidget(isOnEdit),
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget submitButtonWidget(bool isOnEdit) {
|
||||
return ObxValue((data) {
|
||||
return RElevated(
|
||||
text: isOnEdit ? 'ویرایش خرید' : 'ثبت خرید جدید',
|
||||
onPressed: data.value
|
||||
? () async {
|
||||
await controller.createStewardPurchaseOutOfProvince();
|
||||
Get.back();
|
||||
}
|
||||
: null,
|
||||
height: 40,
|
||||
);
|
||||
}, controller.isSubmitButtonEnabled);
|
||||
}
|
||||
|
||||
Widget _productTypeWidget() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<ProductModel>(
|
||||
items: controller.outOfTheProvinceLogic.rolesProductsModel,
|
||||
onChanged: (value) {
|
||||
controller.selectedProduct.value = value;
|
||||
print('Selected Product: ${value.name}');
|
||||
},
|
||||
selectedItem: controller.selectedProduct.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب محصول'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _provinceWidget() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: controller.rootLogic.provinces,
|
||||
onChanged: (value) {
|
||||
controller.selectedProvince.value = value;
|
||||
print('Selected Product: ${value.name}');
|
||||
},
|
||||
selectedItem: controller.selectedProvince.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب استان'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _cityWidget() {
|
||||
return ObxValue((data) {
|
||||
return OverlayDropdownWidget<IranProvinceCityModel>(
|
||||
items: data,
|
||||
onChanged: (value) {
|
||||
controller.selectedCity.value = value;
|
||||
print('Selected Product: ${value.name}');
|
||||
},
|
||||
selectedItem: controller.selectedCity.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب شهر'),
|
||||
);
|
||||
}, controller.cites);
|
||||
}
|
||||
|
||||
SizedBox _imageCarcasesWidget(bool isOnEdit) {
|
||||
return SizedBox(
|
||||
width: Get.width,
|
||||
height: 250,
|
||||
child: Card(
|
||||
color: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return Container(
|
||||
width: Get.width,
|
||||
decoration: BoxDecoration(color: AppColor.lightGreyNormal, borderRadius: BorderRadius.circular(8)),
|
||||
child: Center(
|
||||
child: isOnEdit
|
||||
? Image.network(controller.editImageUrl.value ?? '')
|
||||
: data.value == null
|
||||
? Assets.images.placeHolder.image(height: 150, width: 200)
|
||||
: Image.file(File(data.value!.path), fit: BoxFit.cover),
|
||||
),
|
||||
);
|
||||
}, controller.selectedImage),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
Container(
|
||||
width: Get.width,
|
||||
height: 40,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('تصویر بار', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
controller.selectedImage.value = await controller.imagePicker.pickImage(
|
||||
source: ImageSource.camera,
|
||||
imageQuality: 60,
|
||||
maxWidth: 1080,
|
||||
maxHeight: 720,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueNormal,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
padding: EdgeInsetsGeometry.symmetric(horizontal: 6, vertical: 4),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('دوربین', style: AppFonts.yekan14.copyWith(color: Colors.white)),
|
||||
SizedBox(width: 8),
|
||||
Icon(CupertinoIcons.camera, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 16),
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
controller.selectedImage.value = await controller.imagePicker.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
imageQuality: 60,
|
||||
maxWidth: 1080,
|
||||
maxHeight: 720,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueNormal,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
),
|
||||
padding: EdgeInsetsGeometry.symmetric(horizontal: 6, vertical: 4),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('گالری', style: AppFonts.yekan14.copyWith(color: Colors.white)),
|
||||
SizedBox(width: 8),
|
||||
Icon(CupertinoIcons.photo, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> buildDeleteDialog({required Future<void> Function() onConfirm}) async {
|
||||
await Get.defaultDialog(
|
||||
title: 'حذف خرید',
|
||||
middleText: 'آیا از حذف این خرید مطمئن هستید؟',
|
||||
confirm: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: AppColor.error, foregroundColor: Colors.white),
|
||||
onPressed: () async {
|
||||
await onConfirm();
|
||||
Get.back();
|
||||
},
|
||||
child: Text('بله'),
|
||||
),
|
||||
cancel: ElevatedButton(
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
child: Text('خیر'),
|
||||
),
|
||||
).whenComplete(() => controller.getStewardPurchaseOutOfProvince());
|
||||
}
|
||||
|
||||
Widget filterBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 250,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover)),
|
||||
Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
date: controller.fromDateFilter,
|
||||
onChanged: (jalali) => controller.fromDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
isFrom: false,
|
||||
date: controller.toDateFilter,
|
||||
onChanged: (jalali) => controller.toDateFilter.value = jalali,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
RElevated(
|
||||
text: 'اعمال فیلتر',
|
||||
onPressed: () {
|
||||
controller.getStewardPurchaseOutOfProvince();
|
||||
Get.back();
|
||||
},
|
||||
height: 40,
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
GestureDetector timeFilterWidget({
|
||||
isFrom = true,
|
||||
required Rx<Jalali> date,
|
||||
required Function(Jalali jalali) onChanged,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.bottomSheet(modalDatePicker((value) => onChanged(value)));
|
||||
},
|
||||
child: Container(
|
||||
height: 35,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(width: 1, color: AppColor.blueNormal),
|
||||
),
|
||||
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.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
Text(isFrom ? 'از' : 'تا', style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal)),
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return Text(
|
||||
date.value.formatCompactDate(),
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(color: AppColor.lightGreyNormalActive),
|
||||
);
|
||||
}, date),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Container modalDatePicker(ValueChanged<Jalali> onDateSelected) {
|
||||
Jalali? tempPickedDate;
|
||||
return Container(
|
||||
height: 250,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
|
||||
CupertinoButton(
|
||||
child: Text('تایید', style: AppFonts.yekan14),
|
||||
onPressed: () {
|
||||
onDateSelected(tempPickedDate ?? Jalali.now());
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
CupertinoButton(
|
||||
child: Text('لغو', style: AppFonts.yekan14.copyWith(color: AppColor.error)),
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(height: 0, thickness: 1),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: PersianCupertinoDatePicker(
|
||||
initialDateTime: Jalali.now(),
|
||||
mode: PersianCupertinoDatePickerMode.date,
|
||||
onDateTimeChanged: (dateTime) {
|
||||
tempPickedDate = dateTime;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -312,4 +674,36 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ObxValue<RxBool> _buildSearchWidget() {
|
||||
return ObxValue((data) {
|
||||
return AnimatedContainer(
|
||||
duration: Duration(milliseconds: 300),
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
curve: Curves.easeInOut,
|
||||
height: data.value ? 50 : 0,
|
||||
child: Visibility(
|
||||
visible: data.value,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: RTextField(
|
||||
suffixIcon: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Assets.vec.searchSvg.svg(
|
||||
width: 10,
|
||||
height: 10,
|
||||
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
||||
),
|
||||
),
|
||||
hintText: 'جستجو',
|
||||
onChanged: (value) {
|
||||
controller.searchedValue.value = value;
|
||||
},
|
||||
controller: TextEditingController(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}, controller.searchIsSelected);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user