feat : search and filter in buyer out of the province
This commit is contained in:
@@ -468,8 +468,6 @@ class BuysOutOfProvincePage extends GetView<BuysOutOfProvinceLogic> {
|
||||
}
|
||||
|
||||
Widget _productTypeWidget() {
|
||||
tLog(controller.outOfTheProvinceLogic.rolesProductsModel);
|
||||
iLog(controller.selectedProduct.value);
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<ProductModel>(
|
||||
items: controller.outOfTheProvinceLogic.rolesProductsModel,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_auth/data/utils/safe_call.dart';
|
||||
import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_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';
|
||||
@@ -12,16 +14,21 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
RxInt currentIndex = 0.obs;
|
||||
|
||||
RxBool isExpanded = false.obs;
|
||||
RxBool isSubmitButtonEnabled = false.obs;
|
||||
RxBool isBuyerSubmitButtonEnabled = false.obs;
|
||||
RxBool isSaleSubmitButtonEnabled = false.obs;
|
||||
RxList<int> isExpandedList = <int>[].obs;
|
||||
RxBool searchIsSelected = false.obs;
|
||||
|
||||
//TODO add this to Di
|
||||
ImagePicker imagePicker = ImagePicker();
|
||||
|
||||
Rx<Resource<List<OutProvinceCarcassesBuyer>>> buyerList = Resource<List<OutProvinceCarcassesBuyer>>.loading().obs;
|
||||
Rx<Resource<List<OutProvinceCarcassesBuyer>>> buyerList =
|
||||
Resource<List<OutProvinceCarcassesBuyer>>.loading().obs;
|
||||
Rx<Resource<List<StewardFreeSaleBar>>> salesList =
|
||||
Resource<List<StewardFreeSaleBar>>.loading().obs;
|
||||
|
||||
Rxn<ProductModel> selectedProduct = Rxn();
|
||||
Rxn<OutProvinceCarcassesBuyer> selectedBuyer = Rxn();
|
||||
|
||||
RxList<IranProvinceCityModel> cites = <IranProvinceCityModel>[].obs;
|
||||
Rxn<IranProvinceCityModel> selectedProvince = Rxn();
|
||||
@@ -29,7 +36,8 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
|
||||
RootLogic get rootLogic => Get.find<RootLogic>();
|
||||
|
||||
OutOfProvinceLogic get outOfTheProvinceLogic => Get.find<OutOfProvinceLogic>();
|
||||
OutOfProvinceLogic get outOfTheProvinceLogic =>
|
||||
Get.find<OutOfProvinceLogic>();
|
||||
|
||||
GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
TextEditingController buyerNameController = TextEditingController();
|
||||
@@ -37,21 +45,39 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
TextEditingController buyerPhoneController = TextEditingController();
|
||||
TextEditingController buyerUnitNameController = TextEditingController();
|
||||
|
||||
Rx<Jalali> fromDateFilter = Jalali.now().obs;
|
||||
Rx<Jalali> toDateFilter = Jalali.now().obs;
|
||||
//Sale
|
||||
TextEditingController quarantineCodeController = TextEditingController();
|
||||
TextEditingController saleWeightController = TextEditingController();
|
||||
Rx<Jalali> saleDate = Jalali
|
||||
.now()
|
||||
.obs;
|
||||
String? key;
|
||||
|
||||
Rx<Jalali> fromDateFilter = Jalali
|
||||
.now()
|
||||
.obs;
|
||||
Rx<Jalali> toDateFilter = Jalali
|
||||
.now()
|
||||
.obs;
|
||||
RxnString searchedValue = RxnString();
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
getOutProvinceCarcassesBuyer();
|
||||
getOutProvinceSales();
|
||||
|
||||
selectedProvince.listen((p0) => getCites());
|
||||
tLog(selectedProduct.value);
|
||||
outOfTheProvinceLogic.rolesProductsModel.listen((lists) {
|
||||
selectedProduct.value = lists.first;
|
||||
});
|
||||
setupListeners();
|
||||
debounce(searchedValue, (callback) => getOutProvinceCarcassesBuyer(), time: Duration(milliseconds: 2000));
|
||||
debounce(
|
||||
searchedValue,
|
||||
(callback) => getOutProvinceCarcassesBuyer(),
|
||||
time: Duration(milliseconds: 2000),
|
||||
);
|
||||
ever(searchIsSelected, (data) {
|
||||
if (data == false) {
|
||||
searchedValue.value = null;
|
||||
@@ -74,22 +100,53 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
|
||||
Future<void> getOutProvinceCarcassesBuyer() async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getOutProvinceCarcassesBuyer(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 10,
|
||||
page: 1,
|
||||
state: 'buyer-list',
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value ?? '',
|
||||
),
|
||||
),
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.getOutProvinceCarcassesBuyer(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 10,
|
||||
page: 1,
|
||||
state: 'buyer-list',
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value ?? '',
|
||||
),
|
||||
),
|
||||
onSuccess: (res) {
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
buyerList.value = Resource<List<OutProvinceCarcassesBuyer>>.empty();
|
||||
} else {
|
||||
buyerList.value = Resource<List<OutProvinceCarcassesBuyer>>.success(res!.results!);
|
||||
buyerList.value = Resource<List<OutProvinceCarcassesBuyer>>.success(
|
||||
res!.results!,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getOutProvinceSales() async {
|
||||
await safeCall(
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.getStewardFreeSaleBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
queryParameters: buildQueryParams(
|
||||
pageSize: 10,
|
||||
page: 1,
|
||||
state: 'buyer-list',
|
||||
search: 'filter',
|
||||
role: 'Steward',
|
||||
value: searchedValue.value ?? '',
|
||||
fromDate: fromDateFilter.value.toDateTime(),
|
||||
toDate: toDateFilter.value.toDateTime(),
|
||||
),
|
||||
),
|
||||
onSuccess: (res) {
|
||||
if ((res?.count ?? 0) == 0) {
|
||||
salesList.value = Resource<List<StewardFreeSaleBar>>.empty();
|
||||
} else {
|
||||
salesList.value = Resource<List<StewardFreeSaleBar>>.success(
|
||||
res!.results!,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -97,7 +154,10 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
|
||||
Future<void> getCites() async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''),
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.getCity(
|
||||
provinceName: selectedProvince.value?.name ?? '',
|
||||
),
|
||||
onSuccess: (result) {
|
||||
if (result != null && result.isNotEmpty) {
|
||||
cites.value = result;
|
||||
@@ -107,25 +167,44 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
}
|
||||
|
||||
void setupListeners() {
|
||||
buyerNameController.addListener(checkFormValid);
|
||||
buyerLastNameController.addListener(checkFormValid);
|
||||
buyerPhoneController.addListener(checkFormValid);
|
||||
buyerUnitNameController.addListener(checkFormValid);
|
||||
//buyer form listeners
|
||||
buyerNameController.addListener(checkBuyerFormValid);
|
||||
buyerLastNameController.addListener(checkBuyerFormValid);
|
||||
buyerPhoneController.addListener(checkBuyerFormValid);
|
||||
buyerUnitNameController.addListener(checkBuyerFormValid);
|
||||
|
||||
ever(selectedProvince, (_) => checkFormValid());
|
||||
ever(selectedCity, (_) => checkFormValid());
|
||||
ever(selectedProduct, (_) => checkFormValid());
|
||||
ever(selectedProvince, (_) => checkBuyerFormValid());
|
||||
ever(selectedCity, (_) => checkBuyerFormValid());
|
||||
ever(selectedProduct, (_) => checkBuyerFormValid());
|
||||
|
||||
//sales form listeners
|
||||
saleWeightController.addListener(checkSalesFormValid);
|
||||
quarantineCodeController.addListener(checkSalesFormValid);
|
||||
ever(selectedBuyer, (_) => checkSalesFormValid);
|
||||
ever(selectedProduct, (_) => checkSalesFormValid);
|
||||
ever(saleDate, (_) => checkSalesFormValid());
|
||||
}
|
||||
|
||||
void checkFormValid() {
|
||||
isSubmitButtonEnabled.value =
|
||||
void checkBuyerFormValid() {
|
||||
isBuyerSubmitButtonEnabled.value =
|
||||
buyerNameController.text.isNotEmpty &&
|
||||
buyerLastNameController.text.isNotEmpty &&
|
||||
buyerPhoneController.text.isNotEmpty &&
|
||||
buyerUnitNameController.text.isNotEmpty &&
|
||||
selectedProvince.value != null &&
|
||||
selectedCity.value != null &&
|
||||
selectedProduct.value != null;
|
||||
buyerLastNameController.text.isNotEmpty &&
|
||||
buyerPhoneController.text.isNotEmpty &&
|
||||
buyerUnitNameController.text.isNotEmpty &&
|
||||
selectedProvince.value != null &&
|
||||
selectedCity.value != null &&
|
||||
selectedProduct.value != null;
|
||||
}
|
||||
|
||||
void checkSalesFormValid() {
|
||||
isSaleSubmitButtonEnabled.value =
|
||||
saleDate.value
|
||||
.toString()
|
||||
.isNotEmpty &&
|
||||
selectedProduct.value != null &&
|
||||
selectedBuyer.value != null &&
|
||||
saleWeightController.text.isNotEmpty &&
|
||||
quarantineCodeController.text.isNotEmpty;
|
||||
}
|
||||
|
||||
Future<bool> createBuyer() async {
|
||||
@@ -144,7 +223,8 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
mobile: buyerPhoneController.text,
|
||||
role: 'Steward',
|
||||
);
|
||||
final res = await rootLogic.chickenRepository.createOutProvinceCarcassesBuyer(
|
||||
final res = await rootLogic.chickenRepository
|
||||
.createOutProvinceCarcassesBuyer(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: buyer,
|
||||
);
|
||||
@@ -166,26 +246,101 @@ class SalesOutOfProvinceLogic extends GetxController {
|
||||
selectedProvince.value = null;
|
||||
selectedCity.value = null;
|
||||
selectedProduct.value = null;
|
||||
|
||||
isSubmitButtonEnabled.value = false;
|
||||
key = null;
|
||||
isBuyerSubmitButtonEnabled.value = false;
|
||||
}
|
||||
|
||||
void setEditData(OutProvinceCarcassesBuyer item) {
|
||||
void setEditDataBuyer(OutProvinceCarcassesBuyer item) {
|
||||
buyerNameController.text = item.firstName ?? '';
|
||||
buyerLastNameController.text = item.lastName ?? '';
|
||||
buyerUnitNameController.text = item.unitName ?? '';
|
||||
buyerPhoneController.text = item.mobile ?? '';
|
||||
selectedProvince.value = IranProvinceCityModel(name: item.province);
|
||||
selectedCity.value = IranProvinceCityModel(name: item.city);
|
||||
isSubmitButtonEnabled.value = true;
|
||||
isBuyerSubmitButtonEnabled.value = true;
|
||||
}
|
||||
|
||||
void setEditDataSales(StewardFreeSaleBar item) {
|
||||
quarantineCodeController.text = item.clearanceCode ?? '';
|
||||
saleWeightController.text =
|
||||
item.weightOfCarcasses?.toInt().toString() ?? '';
|
||||
saleDate.value = Jalali.fromDateTime(DateTime.parse(item.date!));
|
||||
selectedCity.value = IranProvinceCityModel(name: item.city);
|
||||
selectedBuyer.value = buyerList.value.data?.firstWhere(
|
||||
(element) => element.key == item.buyer?.key,
|
||||
);
|
||||
selectedProduct.value =
|
||||
outOfTheProvinceLogic.rolesProductsModel.value.first;
|
||||
key = item.key;
|
||||
isSaleSubmitButtonEnabled.value = true;
|
||||
}
|
||||
|
||||
Future<void> deleteStewardPurchaseOutOfProvince(String key) async {
|
||||
await safeCall(
|
||||
call: () => rootLogic.chickenRepository.deleteStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
stewardFreeBarKey: key,
|
||||
),
|
||||
call: () =>
|
||||
rootLogic.chickenRepository
|
||||
.deleteStewardPurchasesOutSideOfTheProvince(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
stewardFreeBarKey: key,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool> createSale() async {
|
||||
bool res = false;
|
||||
StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
|
||||
buyerKey: selectedBuyer.value?.key,
|
||||
numberOfCarcasses: 0,
|
||||
weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
|
||||
date: saleDate.value
|
||||
.toDateTime()
|
||||
.formattedDashedGregorian,
|
||||
clearanceCode: quarantineCodeController.text,
|
||||
productKey: selectedProduct.value?.key,
|
||||
);
|
||||
await safeCall(
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.createOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: requestBody,
|
||||
),
|
||||
onSuccess: (_) {
|
||||
res = true;
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
|
||||
void clearSaleForm() {
|
||||
quarantineCodeController.clear();
|
||||
saleWeightController.clear();
|
||||
saleDate.value = Jalali.now();
|
||||
selectedBuyer.value = null;
|
||||
selectedProduct.value = null;
|
||||
isBuyerSubmitButtonEnabled.value = false;
|
||||
}
|
||||
|
||||
Future<bool> editSale() async {
|
||||
bool res = false;
|
||||
StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest(
|
||||
numberOfCarcasses: 0,
|
||||
weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma),
|
||||
date: saleDate.value
|
||||
.toDateTime()
|
||||
.formattedDashedGregorian,
|
||||
clearanceCode: quarantineCodeController.text,
|
||||
key:key
|
||||
);
|
||||
await safeCall(
|
||||
call: () =>
|
||||
rootLogic.chickenRepository.updateOutProvinceStewardFreeBar(
|
||||
token: rootLogic.tokenService.accessToken.value!,
|
||||
body: requestBody,
|
||||
),
|
||||
onSuccess: (_) {
|
||||
res = true;
|
||||
},
|
||||
);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/logic.
|
||||
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/widgets/search_widget.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'empty_widget.dart';
|
||||
import '../widgets/empty_widget.dart';
|
||||
|
||||
class BuyersPage extends GetView<SalesOutOfProvinceLogic> {
|
||||
const BuyersPage({super.key});
|
||||
@@ -181,7 +181,7 @@ class BuyersPage extends GetView<SalesOutOfProvinceLogic> {
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
controller.setEditData(item);
|
||||
controller.setEditDataBuyer(item);
|
||||
Get.bottomSheet(
|
||||
addOrEditBuyerBottomSheet(true),
|
||||
isScrollControlled: true,
|
||||
@@ -368,7 +368,7 @@ class BuyersPage extends GetView<SalesOutOfProvinceLogic> {
|
||||
: null,
|
||||
height: 40,
|
||||
);
|
||||
}, controller.isSubmitButtonEnabled);
|
||||
}, controller.isBuyerSubmitButtonEnabled);
|
||||
}
|
||||
|
||||
Widget _provinceWidget() {
|
||||
@@ -0,0 +1,596 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart';
|
||||
import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/logic.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/widgets/empty_widget.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import '../widgets/search_widget.dart';
|
||||
|
||||
class SalesPage extends GetView<SalesOutOfProvinceLogic> {
|
||||
const SalesPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
searchWidget(controller.searchIsSelected, (data) {
|
||||
controller.searchedValue.value = data;
|
||||
|
||||
//TODO: Implement search functionality
|
||||
controller.getOutProvinceSales();
|
||||
}),
|
||||
|
||||
salesListWidget(),
|
||||
],
|
||||
),
|
||||
floatingActionButton: RFab.add(
|
||||
onPressed: () {
|
||||
Get.bottomSheet(addOrEditSaleBottomSheet(), isScrollControlled: true);
|
||||
},
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
|
||||
);
|
||||
}
|
||||
|
||||
Widget salesListWidget() {
|
||||
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) => salesListItem(
|
||||
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.salesList);
|
||||
}
|
||||
|
||||
GestureDetector salesListItem({
|
||||
required RxList<int> expandList,
|
||||
required int index,
|
||||
required StewardFreeSaleBar item,
|
||||
}) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if (expandList.contains(index)) {
|
||||
controller.isExpandedList.remove(index);
|
||||
} else {
|
||||
controller.isExpandedList.add(index);
|
||||
}
|
||||
},
|
||||
child: AnimatedSize(
|
||||
duration: Duration(milliseconds: 400),
|
||||
alignment: Alignment.center,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
alignment: Alignment.centerRight,
|
||||
children: [
|
||||
AnimatedSize(
|
||||
duration: Duration(milliseconds: 300),
|
||||
child: Container(
|
||||
width: Get.width - 30,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(
|
||||
width: 0.5,
|
||||
color: AppColor.darkGreyNormal,
|
||||
),
|
||||
),
|
||||
child: AnimatedCrossFade(
|
||||
alignment: Alignment.center,
|
||||
firstChild: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
SizedBox(width: 12),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
item.date?.formattedJalaliDate ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: AppColor.bgDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
item.buyer?.fullname ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.blueNormal,
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
item.buyer?.mobile ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.bgDark,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Text(
|
||||
item.buyer?.unitName ?? 'N/A',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: AppColor.bgDark,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${item.weightOfCarcasses?.separatedByComma ?? 0}KG',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: AppColor.bgDark,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
'${item.buyer?.province}\n${item.buyer?.city}',
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan12.copyWith(
|
||||
color: AppColor.bgDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Icon(CupertinoIcons.chevron_down, size: 12),
|
||||
SizedBox(width: 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
secondChild: Container(
|
||||
padding: EdgeInsets.fromLTRB(8, 12, 14, 12),
|
||||
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
controller.setEditDataSales(item);
|
||||
Get.bottomSheet(
|
||||
addOrEditSaleBottomSheet(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,
|
||||
),
|
||||
),
|
||||
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
buildDeleteDialog(
|
||||
onConfirm: () => controller
|
||||
.deleteStewardPurchaseOutOfProvince(
|
||||
item.key!,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Assets.vec.trashSvg.svg(
|
||||
width: 20,
|
||||
height: 20,
|
||||
colorFilter: ColorFilter.mode(
|
||||
AppColor.error,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
height: 32,
|
||||
padding: EdgeInsets.symmetric(horizontal: 4),
|
||||
decoration: ShapeDecoration(
|
||||
color: AppColor.blueLight,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 1,
|
||||
color: AppColor.blueLightHover,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
child: buildRow(
|
||||
'تاریخ',
|
||||
item.date?.formattedJalaliDateYHMS ?? 'N/A',
|
||||
),
|
||||
),
|
||||
buildRow(
|
||||
'مشخصات خریدار',
|
||||
item.buyer?.fullname ?? 'N/A',
|
||||
),
|
||||
buildRow('تلفن خریدار', item.buyer?.mobile ?? 'N/A'),
|
||||
buildRow('نام واحد', item.buyer?.unitName ?? 'N/A'),
|
||||
buildRow(
|
||||
'وزن لاشه',
|
||||
'${item.weightOfCarcasses?.separatedByComma}',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
crossFadeState: expandList.contains(index)
|
||||
? CrossFadeState.showSecond
|
||||
: CrossFadeState.showFirst,
|
||||
duration: Duration(milliseconds: 300),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
right: -12,
|
||||
child: Container(
|
||||
width: index < 999 ? 24 : null,
|
||||
height: index < 999 ? 24 : null,
|
||||
padding: EdgeInsets.all(2),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.greenLightHover,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
border: Border.all(
|
||||
width: 0.50,
|
||||
color: AppColor.greenDarkActive,
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
(index + 1).toString(),
|
||||
style: AppFonts.yekan12.copyWith(color: Colors.black),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildRow(String title, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
title,
|
||||
textAlign: TextAlign.right,
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.darkGreyDarkHover,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
value,
|
||||
textAlign: TextAlign.left,
|
||||
|
||||
style: AppFonts.yekan14.copyWith(
|
||||
color: AppColor.darkGreyDarkHover,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget addOrEditSaleBottomSheet([bool isOnEdit = false]) {
|
||||
return BaseBottomSheet(
|
||||
height: 600,
|
||||
child: SingleChildScrollView(
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: Column(
|
||||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
isOnEdit ? 'ویرایش فروش' : 'افزودن فروش',
|
||||
style: AppFonts.yekan16Bold.copyWith(
|
||||
color: AppColor.darkGreyDarkHover,
|
||||
),
|
||||
),
|
||||
_productWidget(),
|
||||
_buyerWidget(),
|
||||
RTextField(
|
||||
controller: controller.saleWeightController,
|
||||
label: 'وزن لاشه',
|
||||
keyboardType: TextInputType.number,
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
SeparatorInputFormatter(),
|
||||
],
|
||||
|
||||
validator: (value) {
|
||||
if (value == null) {
|
||||
return 'لطفاً وزن لاشه را وارد کنید';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
RTextField(
|
||||
controller: controller.quarantineCodeController,
|
||||
label: 'کد قرنطینه',
|
||||
borderColor: AppColor.darkGreyLight,
|
||||
validator: (value) {
|
||||
if (value == null) {
|
||||
return 'لطفاً کد قرنطینه را وارد کنید';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
|
||||
Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
Expanded(
|
||||
child: timeFilterWidget(
|
||||
date: controller.saleDate,
|
||||
onChanged: (jalali) => controller.saleDate.value = jalali,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
submitButtonWidget(isOnEdit),
|
||||
SizedBox(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget submitButtonWidget(bool isOnEdit) {
|
||||
return ObxValue((data) {
|
||||
return RElevated(
|
||||
text: isOnEdit ? 'ویرایش' : 'ثبت',
|
||||
onPressed: data.value
|
||||
? () async {
|
||||
var res = isOnEdit
|
||||
? await controller.editSale()
|
||||
: await controller.createSale();
|
||||
if (res) {
|
||||
controller.getOutProvinceSales();
|
||||
controller.clearSaleForm();
|
||||
Get.back();
|
||||
}
|
||||
}
|
||||
: null,
|
||||
height: 40,
|
||||
);
|
||||
}, controller.isSaleSubmitButtonEnabled);
|
||||
}
|
||||
|
||||
Widget _buyerWidget() {
|
||||
return Obx(() {
|
||||
return OverlayDropdownWidget<OutProvinceCarcassesBuyer>(
|
||||
items: controller.buyerList.value.data ?? [],
|
||||
onChanged: (value) {
|
||||
controller.selectedBuyer.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedBuyer.value,
|
||||
itemBuilder: (item) => Text(item.buyer?.fullname ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.buyer?.fullname ?? 'انتخاب خریدار'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _productWidget() {
|
||||
return ObxValue((data) {
|
||||
return OverlayDropdownWidget<ProductModel>(
|
||||
items: controller.outOfTheProvinceLogic.rolesProductsModel,
|
||||
onChanged: (value) {
|
||||
controller.selectedProduct.value = value;
|
||||
},
|
||||
selectedItem: controller.selectedProduct.value,
|
||||
initialValue: controller.selectedProduct.value,
|
||||
itemBuilder: (item) => Text(item.name ?? 'بدون نام'),
|
||||
labelBuilder: (item) => Text(item?.name ?? 'انتخاب محصول'),
|
||||
);
|
||||
}, controller.selectedProduct);
|
||||
}
|
||||
|
||||
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.bgDark),
|
||||
),
|
||||
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.yekan16.copyWith(color: AppColor.bgDark),
|
||||
),
|
||||
Expanded(
|
||||
child: ObxValue((data) {
|
||||
return Text(
|
||||
date.value.formatCompactDate(),
|
||||
textAlign: TextAlign.center,
|
||||
style: AppFonts.yekan16.copyWith(
|
||||
color: AppColor.darkGreyDark,
|
||||
),
|
||||
);
|
||||
}, 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(
|
||||
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,
|
||||
onDateTimeChanged: (dateTime) {
|
||||
tempPickedDate = dateTime;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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.getOutProvinceSales());
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@ 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_chicken/presentation/pages/sales_out_of_province/widgets/buyers_page.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/pages/buyers_page.dart';
|
||||
import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/pages/sales_page.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
import 'logic.dart';
|
||||
@@ -56,7 +57,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
visible: controller.currentIndex.value==0,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// Get.bottomSheet(filterBottomSheet());
|
||||
Get.bottomSheet(filterBottomSheet());
|
||||
},
|
||||
child: Assets.vec.filterOutlineSvg.svg(
|
||||
width: 20,
|
||||
@@ -98,7 +99,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
children: [
|
||||
salePage(),
|
||||
SalesPage(),
|
||||
BuyersPage()
|
||||
],
|
||||
),
|
||||
@@ -668,6 +669,8 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
).whenComplete(() => controller.getStewardPurchaseOutOfProvince());
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
Widget filterBottomSheet() {
|
||||
return BaseBottomSheet(
|
||||
height: 250,
|
||||
@@ -697,7 +700,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
RElevated(
|
||||
text: 'اعمال فیلتر',
|
||||
onPressed: () {
|
||||
controller.getStewardPurchaseOutOfProvince();
|
||||
controller.getOutProvinceSales();
|
||||
Get.back();
|
||||
},
|
||||
height: 40,
|
||||
@@ -706,7 +709,7 @@ class SalesOutOfProvincePage extends GetView<SalesOutOfProvinceLogic> {
|
||||
],
|
||||
),
|
||||
);
|
||||
}*/
|
||||
}
|
||||
|
||||
GestureDetector timeFilterWidget({
|
||||
isFrom = true,
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:rasadyar_core/core.dart';
|
||||
|
||||
Widget emptyWidget() {
|
||||
return Center(
|
||||
child: Text('داده ای دریافت نشد!', style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkHover)),
|
||||
return Expanded(
|
||||
child: Center(
|
||||
child: Text('داده ای دریافت نشد!', style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkHover)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user