diff --git a/packages/chicken/lib/presentation/pages/root/logic.dart b/packages/chicken/lib/presentation/pages/root/logic.dart index 4786e7c..a131e66 100644 --- a/packages/chicken/lib/presentation/pages/root/logic.dart +++ b/packages/chicken/lib/presentation/pages/root/logic.dart @@ -1,6 +1,8 @@ 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_auth/data/utils/safe_call.dart'; +import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.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'; @@ -22,15 +24,13 @@ class RootLogic extends GetxController { Container(color: Colors.amber), ]; - - late DioRemote dioRemote; var tokenService = Get.find(); late ChickenRepository chickenRepository; RxList errorLocationType = RxList(); RxMap inventoryExpandedList = RxMap(); - + Rxn inventoryModel = Rxn(); RxList provinces = [].obs; @override @@ -42,8 +42,8 @@ class RootLogic extends GetxController { getProvinces(); - /*getInventory(); - getKillHouseDistributionInfo();*/ + getInventory(); + //getKillHouseDistributionInfo(); } void toggleExpanded(int index) { @@ -54,6 +54,29 @@ class RootLogic extends GetxController { } } + Future getInventory() async { + await safeCall?>( + call: () async => await chickenRepository.getInventory(token: tokenService.accessToken.value!), + onSuccess: (result) { + if (result != null) { + inventoryModel.value = result.first; + } + }, + onError: (error, stackTrace) { + switch (error.response?.statusCode) { + case 401: + errorHandler(error); + break; + case 403: + errorHandler(error); + break; + default: + errorHandler(error); + } + }, + ); + } + void rootErrorHandler(DioException error) { handleGeneric(error, () { tokenService.deleteTokens(); @@ -75,4 +98,10 @@ class RootLogic extends GetxController { provinces.clear(); } } + + void errorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteTokens(); + }); + } } diff --git a/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart b/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart index 972beb8..8451ba1 100644 --- a/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart +++ b/packages/chicken/lib/presentation/pages/sales_in_province/logic.dart @@ -11,14 +11,18 @@ import 'package:rasadyar_core/core.dart'; class SalesInProvinceLogic extends GetxController { var rootLogic = Get.find(); - Rxn?> allocatedMadeModel = - Rxn?>(); + Rxn?> allocatedMadeModel = Rxn?>(); RxList isExpandedList = [].obs; RxList rolesProductsModel = RxList(); - + RxBool searchIsSelected = false.obs; + RxnString searchedValue = RxnString(); RxList guildsModel = [].obs; + GlobalKey formKey = GlobalKey(); + + Rxn fromDateFilter = Rxn(null); + Rxn toDateFilter = Rxn(null); Rxn selectedProductModel = Rxn(); Rxn selectedGuildModel = Rxn(); Rxn guildProfile = Rxn(); @@ -37,8 +41,8 @@ class SalesInProvinceLogic extends GetxController { final RxBool addPageAllocationsMade = false.obs; final RxBool hasMoreDataAllocationsMade = true.obs; - Rxn selectedAllocationModelForUpdate = - Rxn(); + Rxn selectedAllocationModelForUpdate = Rxn(); + SubmitStewardAllocation? tmpStewardAllocation; @override void onInit() { @@ -51,17 +55,16 @@ class SalesInProvinceLogic extends GetxController { ever(saleType, (callback) { getGuilds(); }); - - weight.listen((num) { - totalCost.value = num * pricePerKilo.value; + debounce(weight, time: Duration(milliseconds: 110), (callback) { + totalCost.value = callback * weight.value; }); - pricePerKilo.listen((num) { - totalCost.value = num * weight.value; + debounce(pricePerKilo, time: Duration(milliseconds: 100), (callback) { + totalCost.value = callback * weight.value; }); totalCost.listen((data) { - totalCostController.text = data.toString(); + totalCostController.text = data.toString().separatedByComma; isValid.value = weight.value > 0 && @@ -78,15 +81,23 @@ class SalesInProvinceLogic extends GetxController { getAllocatedMade(); } }); + + debounce(searchedValue, (callback) => getAllocatedMade(), time: Duration(milliseconds: 2000)); + ever(searchIsSelected, (data) { + if (data == false) { + searchedValue.value = null; + } + }); } Future getAllocatedMade() async { - if (isLoadingMoreAllocationsMade.value || - !hasMoreDataAllocationsMade.value) { + if (isLoadingMoreAllocationsMade.value || !hasMoreDataAllocationsMade.value) { return; } - if (addPageAllocationsMade.value) { + if (searchIsSelected.value) { + currentPageAllocationsMade.value = 1; + } else if (addPageAllocationsMade.value) { currentPageAllocationsMade.value++; } safeCall( @@ -97,6 +108,7 @@ class SalesInProvinceLogic extends GetxController { pageSize: 20, search: 'filter', role: 'Steward', + value: searchedValue.value, ), ), onSuccess: (result) { @@ -157,8 +169,7 @@ class SalesInProvinceLogic extends GetxController { safeCall( call: () async => await rootLogic.chickenRepository.confirmAllAllocation( token: rootLogic.tokenService.accessToken.value!, - allocationTokens: - allocatedMadeModel.value?.map((e) => e.key!).toList() ?? [], + allocationTokens: allocatedMadeModel.value?.map((e) => e.key!).toList() ?? [], ), onSuccess: (result) { getAllocatedMade(); @@ -169,9 +180,8 @@ class SalesInProvinceLogic extends GetxController { Future getRolesProducts() async { safeCall( - call: () async => await rootLogic.chickenRepository.getRolesProducts( - token: rootLogic.tokenService.accessToken.value!, - ), + call: () async => + await rootLogic.chickenRepository.getRolesProducts(token: rootLogic.tokenService.accessToken.value!), onSuccess: (result) { if (result != null) { rolesProductsModel.value = result; @@ -186,10 +196,7 @@ class SalesInProvinceLogic extends GetxController { safeCall( call: () async => await rootLogic.chickenRepository.getGuilds( token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams( - queryParams: {'free': saleType.value == 2 ? true : false}, - role: 'Steward', - ), + queryParameters: buildQueryParams(queryParams: {'free': saleType.value == 2 ? true : false}, role: 'Steward'), ), onSuccess: (result) { if (result != null) { @@ -215,9 +222,7 @@ class SalesInProvinceLogic extends GetxController { Future getGuildProfile() async { await safeCall( - call: () async => await rootLogic.chickenRepository.getProfile( - token: rootLogic.tokenService.accessToken.value!, - ), + call: () async => await rootLogic.chickenRepository.getProfile(token: rootLogic.tokenService.accessToken.value!), onError: (error, stackTrace) {}, onSuccess: (result) { guildProfile.value = result; @@ -225,30 +230,31 @@ class SalesInProvinceLogic extends GetxController { ); } - Future submitAllocation() async { - SubmitStewardAllocation stewardAllocation = SubmitStewardAllocation( + void setSubmitData() { + 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", + buyerType: selectedGuildModel.value?.steward == true ? "Steward" : "Guild", amount: pricePerKilo.value, totalAmount: totalCost.value, weightOfCarcasses: weight.value, + sellType:saleType.value ==2 ? "free" :'exclusive', + numberOfCarcasses: 0, guildKey: selectedGuildModel.value?.key, productKey: selectedProductModel.value?.key, - date: DateTime.now().formattedGregorianDate, + date: DateTime.now().formattedDashedGregorian, type: "manual", ); + } + Future submitAllocation() async { safeCall( - call: () async => - await rootLogic.chickenRepository.postSubmitStewardAllocation( - token: rootLogic.tokenService.accessToken.value!, - request: stewardAllocation, - ), + call: () async => await rootLogic.chickenRepository.postSubmitStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + request: tmpStewardAllocation!, + ), onSuccess: (result) { getAllocatedMade(); @@ -259,11 +265,10 @@ class SalesInProvinceLogic extends GetxController { Future deleteAllocation(AllocatedMadeModel model) async { safeCall( - call: () async => - await rootLogic.chickenRepository.deleteStewardAllocation( - token: rootLogic.tokenService.accessToken.value!, - queryParameters: {'steward_allocation_key': model.key}, - ), + call: () async => await rootLogic.chickenRepository.deleteStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: {'steward_allocation_key': model.key}, + ), onSuccess: (result) { getAllocatedMade(); @@ -286,9 +291,7 @@ class SalesInProvinceLogic extends GetxController { pricePerKilo.value = item.amount ?? 0; totalCost.value = item.totalAmount ?? 0; weightController.text = weight.value.toString().separatedByComma; - pricePerKiloController.text = pricePerKilo.value - .toString() - .separatedByComma; + pricePerKiloController.text = pricePerKilo.value.toString().separatedByComma; totalCostController.text = totalCost.value.toString().separatedByComma; isValid.value = true; } @@ -314,11 +317,10 @@ class SalesInProvinceLogic extends GetxController { ); safeCall( - call: () async => - await rootLogic.chickenRepository.updateStewardAllocation( - token: rootLogic.tokenService.accessToken.value!, - request: updatedAllocationModel, - ), + call: () async => await rootLogic.chickenRepository.updateStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + request: updatedAllocationModel, + ), onSuccess: (result) { getAllocatedMade(); diff --git a/packages/chicken/lib/presentation/pages/sales_in_province/view.dart b/packages/chicken/lib/presentation/pages/sales_in_province/view.dart index b9c5bbe..f0b2aeb 100644 --- a/packages/chicken/lib/presentation/pages/sales_in_province/view.dart +++ b/packages/chicken/lib/presentation/pages/sales_in_province/view.dart @@ -3,9 +3,9 @@ import 'package:flutter/services.dart'; import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.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/inventory/inventory_model.dart'; import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; import 'package:rasadyar_chicken/presentation/pages/entering_the_warehouse/string_utils.dart'; +import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_core/core.dart'; import 'logic.dart'; @@ -18,11 +18,7 @@ class SalesInProvincePage extends GetView { return Scaffold( appBar: RAppBar( titleTextStyle: AppFonts.yekan16Bold.copyWith(color: Colors.white), - centerTitle: true, - hasBack: true, - onBackPressed: () { - Get.back(id: 1); - }, + hasBack: false, leadingWidth: 155, leading: Row( mainAxisSize: MainAxisSize.min, @@ -31,43 +27,31 @@ class SalesInProvincePage extends GetView { 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: [ GestureDetector( onTap: () { - // controller.searchIsSelected.value = !controller.searchIsSelected.value; + controller.searchIsSelected.value = !controller.searchIsSelected.value; }, child: Assets.vec.searchSvg.svg( width: 24, height: 24, - colorFilter: const ColorFilter.mode( - Colors.white, - BlendMode.srcIn, - ), + colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), ), ), SizedBox(width: 8), GestureDetector( onTap: () { - // Get.bottomSheet(filterBottomSheet()); + Get.bottomSheet(filterBottomSheet()); }, child: Assets.vec.filterOutlineSvg.svg( width: 20, height: 20, - colorFilter: const ColorFilter.mode( - Colors.white, - BlendMode.srcIn, - ), + colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), ), ), SizedBox(width: 8), @@ -77,21 +61,16 @@ class SalesInProvincePage extends GetView { child: Column( children: [ routePageWidget(), - + buildSearchWidget(), inventoryWidget(), allocationsMade(), - SizedBox(height: 40), ], ), ), floatingActionButton: RFab.add( onPressed: () { - Get.bottomSheet( - showAddBottomSheet(), - isScrollControlled: true, - backgroundColor: Colors.transparent, - ); + Get.bottomSheet(showAddBottomSheet(), isScrollControlled: true, backgroundColor: Colors.transparent); }, ), floatingActionButtonLocation: FloatingActionButtonLocation.startFloat, @@ -99,123 +78,18 @@ class SalesInProvincePage extends GetView { } Widget inventoryWidget() { - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Column( - children: [ - const SizedBox(height: 20), - Align( - alignment: Alignment.centerRight, - child: Text( - 'موجودی انبار', - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), - ), - ), - SizedBox(height: 4), - /* ObxValue( - (data) => data.isEmpty - ? Container( - margin: const EdgeInsets.symmetric(vertical: 2), - height: 80, - padding: EdgeInsets.all(6), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: AppColor.blueNormal, width: 1), - ), - child: Center(child: CircularProgressIndicator()), - ) - : ListView.separated( - shrinkWrap: true, - itemCount: controller.rootLogic.inventoryList.length, - separatorBuilder: (context, index) => - const SizedBox(height: 8), - itemBuilder: (context, index) { - return ObxValue((expand) { - return GestureDetector( - onTap: () { - controller.rootLogic.toggleExpanded(index); - }, - behavior: HitTestBehavior.opaque, - child: AnimatedContainer( - onEnd: () { - controller - .rootLogic - .inventoryExpandedList[index] = !controller - .rootLogic - .inventoryExpandedList[index]!; - }, - margin: const EdgeInsets.symmetric(vertical: 2), - padding: EdgeInsets.all(6), - curve: Curves.easeInOut, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8), - border: Border.all( - color: AppColor.blueNormal, - width: 1, - ), - ), - duration: const Duration(seconds: 1), - height: expand.keys.contains(index) ? 300 : 80, - child: inventoryItem( - isExpanded: - expand.keys.contains(index) && expand[index]!, - index: index, - model: controller.rootLogic.inventoryList[index], - ), - ), - ); - }, controller.rootLogic.inventoryExpandedList); - }, - ), - controller.rootLogic.inventoryList, - ),*/ - ], - ), - ); - } - - Widget inventoryItem({ - required bool isExpanded, - required int index, - required InventoryModel model, - }) { - return Column( - mainAxisAlignment: MainAxisAlignment.center, - spacing: 8, - children: [ - buildRow('نام محصول', model.name ?? ''), - Visibility( - visible: isExpanded, - child: Column( - spacing: 8, - children: [ - buildRow('وزن خریدهای دولتی داخل استان (کیلوگرم)', '0326598653'), - buildRow( - 'وزن خریدهای آزاد داخل استان (کیلوگرم)', - model.receiveFreeCarcassesWeight.toString(), - ), - buildRow( - 'وزن خریدهای خارج استان (کیلوگرم)', - model.freeBuyingCarcassesWeight.toString(), - ), - buildRow( - 'کل ورودی به انبار (کیلوگرم)', - model.totalFreeBarsCarcassesWeight.toString(), - ), - buildRow( - 'کل فروش (کیلوگرم)', - model.realAllocatedWeight.toString(), - ), - buildRow( - 'مانده انبار (کیلوگرم)', - model.totalRemainWeight.toString(), - ), - ], - ), - ), - ], + return Container( + width: Get.width, + height: 39, + margin: EdgeInsets.all(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), ); } @@ -230,9 +104,7 @@ class SalesInProvincePage extends GetView { child: Text( title, textAlign: TextAlign.right, - style: AppFonts.yekan14.copyWith( - color: AppColor.darkGreyDarkHover, - ), + style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), ), Flexible( @@ -240,9 +112,7 @@ class SalesInProvincePage extends GetView { child: Text( value, textAlign: TextAlign.left, - style: AppFonts.yekan14.copyWith( - color: AppColor.darkGreyDarkHover, - ), + style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), ), ), ], @@ -253,21 +123,16 @@ class SalesInProvincePage extends GetView { Widget allocationsMade() { return Column( children: [ - const SizedBox(height: 20), Padding( padding: const EdgeInsets.symmetric(horizontal: 6), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - 'تخصیصات صورت گرفته', - style: AppFonts.yekan16Bold.copyWith( - color: AppColor.blueNormal, - ), - ), + Text('تخصیصات صورت گرفته', style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal)), RElevated( text: 'تایید یکجا', height: 30, + textStyle: AppFonts.yekan12.copyWith(color: Colors.white), onPressed: () { controller.confirmAllAllocations(); }, @@ -321,15 +186,10 @@ class SalesInProvincePage extends GetView { } final result = data.value![index]; return ObxValue((data) { - return allocationsMadeListItem( - expandList: controller.isExpandedList, - index: index, - item: result, - ); + return allocationsMadeListItem(expandList: controller.isExpandedList, index: index, item: result); }, controller.isExpandedList); }, - separatorBuilder: (BuildContext context, int index) => - SizedBox(height: 8), + separatorBuilder: (BuildContext context, int index) => SizedBox(height: 8), ), ); } @@ -348,137 +208,139 @@ class SalesInProvincePage extends GetView { top: 16, bottom: MediaQuery.of(Get.context!).viewInsets.bottom + 16, ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - '${isEditMode ? 'ویرایش' :'ثبت' } توزیع/ فروش', - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), - ), - 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), - SizedBox( - height: 40, - child: ObxValue((data) { - return Row( - children: [ - Radio( - value: 1, - groupValue: controller.saleType.value, - onChanged: (value) { - controller.saleType.value = value!; - - controller.selectedGuildModel.value = null; - controller.selectedGuildModel.refresh(); - }, - ), - Text('فروش اختصاصی', style: AppFonts.yekan14), - SizedBox(width: 12), - Radio( - value: 2, - groupValue: controller.saleType.value, - onChanged: (value) { - controller.saleType.value = value!; - }, - ), - Text('فروش آزاد', style: AppFonts.yekan14), - ], - ); - }, controller.saleType), - ), - const SizedBox(height: 12), - - guildsDropDown(), - - - ], + child: Form( + key: controller.formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '${isEditMode ? 'ویرایش' : 'ثبت'} توزیع/ فروش', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), ), - ), - const SizedBox(height: 12), - RTextField( - controller: controller.weightController, - keyboardType: TextInputType.number, - borderColor: AppColor.darkGreyLight, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - SeparatorInputFormatter(), - ], + 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), + SizedBox( + height: 40, + child: ObxValue((data) { + return Row( + children: [ + Radio( + value: 1, + groupValue: controller.saleType.value, + onChanged: (value) { + controller.saleType.value = value!; - onChanged: (p0) { - controller.weight.value = int.tryParse(p0.clearComma) ?? 0; - }, - label: 'وزن لاشه', - ), - const SizedBox(height: 12), - RTextField( - controller: controller.pricePerKiloController, - borderColor: AppColor.darkGreyLight, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - SeparatorInputFormatter(), - ], + controller.selectedGuildModel.value = null; + controller.selectedGuildModel.refresh(); + }, + ), + Text('فروش اختصاصی', style: AppFonts.yekan14), + SizedBox(width: 12), + Radio( + value: 2, + groupValue: controller.saleType.value, + onChanged: (value) { + controller.saleType.value = value!; + }, + ), + Text('فروش آزاد', style: AppFonts.yekan14), + ], + ); + }, controller.saleType), + ), + const SizedBox(height: 12), - onChanged: (p0) { - controller.pricePerKilo.value = - int.tryParse(p0.clearComma) ?? 0; - }, - keyboardType: TextInputType.number, - label: 'قیمت هر کیلو', - ), - const SizedBox(height: 12), - ObxValue( - (p0) => RTextField( + guildsDropDown(), + ], + ), + ), + 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), + RTextField( + controller: controller.pricePerKiloController, + borderColor: AppColor.darkGreyLight, + inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + + 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(), - ], + inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], borderColor: AppColor.darkGreyLight, - initText: controller.totalCost.value - .toString() - .separatedByComma, controller: controller.totalCostController, label: 'هزینه کل', ), - controller.totalCost, - ), - const SizedBox(height: 20), - ObxValue((data) { - return RElevated( - text:isEditMode? 'ویرایش': 'ثبت', - textStyle: AppFonts.yekan16.copyWith(color: Colors.white), - height: 40, - onPressed: data.value - ? () async { - isEditMode - ? await controller.submitAllocation() - : await controller.updateAllocation(); + const SizedBox(height: 20), + ObxValue((data) { + return RElevated( + text: isEditMode ? 'ویرایش' : 'ثبت', + 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()); + } + }; - controller.clearForm(); - controller.getAllocatedMade(); - Get.back(); - } - : null, - ); - }, controller.isValid), - const SizedBox(height: 20), - ], + controller.clearForm(); + controller.getAllocatedMade(); + Get.back();*/ + } + : null, + ); + }, controller.isValid), + const SizedBox(height: 20), + ], + ), ), ), ); @@ -538,10 +400,7 @@ class SalesInProvincePage extends GetView { 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), ], @@ -575,10 +434,7 @@ class SalesInProvincePage extends GetView { child: Container( width: Get.width, margin: const EdgeInsets.fromLTRB(0, 0, 10, 0), - decoration: BoxDecoration( - color: getTintColor(item), - borderRadius: BorderRadius.circular(8), - ), + decoration: BoxDecoration(color: getTintColor(item), borderRadius: BorderRadius.circular(8)), child: AnimatedSize( duration: Duration(milliseconds: 400), alignment: Alignment.center, @@ -627,18 +483,14 @@ class SalesInProvincePage extends GetView { Text( item.steward?.user?.fullname ?? 'N/A', textAlign: TextAlign.center, - style: AppFonts.yekan14.copyWith( - color: AppColor.blueNormal, - ), + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), ), SizedBox(height: 2), Text( - item.createDate?.formattedJalaliDate, + item.createDate?.formattedJalaliDate ?? 'N/A', textAlign: TextAlign.center, - style: AppFonts.yekan14.copyWith( - color: AppColor.bgDark, - ), + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), ), ], ), @@ -654,16 +506,12 @@ class SalesInProvincePage extends GetView { Text( '${item.weightOfCarcasses.separatedByComma} Kg', textAlign: TextAlign.center, - style: AppFonts.yekan12.copyWith( - color: AppColor.bgDark, - ), + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), ), Text( '${item.amount.separatedByComma} ریال', textAlign: TextAlign.center, - style: AppFonts.yekan12.copyWith( - color: AppColor.darkGreyDark, - ), + style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDark), ), ], ), @@ -673,9 +521,7 @@ class SalesInProvincePage extends GetView { child: Text( '${item.allocationType?.faAllocationType}', textAlign: TextAlign.center, - style: AppFonts.yekan10.copyWith( - color: AppColor.darkGreyDark, - ), + style: AppFonts.yekan10.copyWith(color: AppColor.darkGreyDark), ), ), @@ -686,16 +532,12 @@ class SalesInProvincePage extends GetView { 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, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { @@ -710,87 +552,53 @@ class SalesInProvincePage extends GetView { child: Assets.vec.editSvg.svg( width: 20, height: 20, - colorFilter: ColorFilter.mode( - AppColor.blueNormal, - BlendMode.srcIn, - ), + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), ), ), Text( item.allocationType?.faAllocationType, textAlign: TextAlign.center, - style: AppFonts.yekan16.copyWith( - color: AppColor.greenDark, - ), + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), ), GestureDetector( onTap: () { buildDeleteDialog( - onConfirm: () => - controller.deleteAllocation(item), + onConfirm: () { + expandList.remove(index); + return controller.deleteAllocation(item); + }, ); }, child: Assets.vec.trashSvg.svg( width: 16, height: 16, - colorFilter: ColorFilter.mode( - AppColor.error, - BlendMode.srcIn, - ), + colorFilter: ColorFilter.mode(AppColor.error, BlendMode.srcIn), ), ), ], ), - buildRow( - 'تاریخ ثبت', - item.date!.formattedJalaliDate ?? 'N/A', - ), + buildRow('تاریخ ثبت', item.date!.formattedJalaliDate ?? 'N/A'), buildRow( 'نام و نام خانوادگی خریدار', - getBuyerInformation(item)?.user?.fullname ?? - 'N/A', - ), - buildRow( - 'شماره خریدار', - getBuyerInformation(item)?.user?.mobile ?? - 'N/A', - ), - buildRow( - 'نوع فروش', - item.sellType?.faItem ?? 'N/A', - ), - buildRow( - 'قیمت هر کیلو', - '${item.amount.separatedByComma ?? 0} ریال ', - ), - buildRow( - 'قیمت کل', - '${item.totalAmount.separatedByComma ?? 0} ریال', + getBuyerInformation(item)?.user?.fullname ?? 'N/A', ), + buildRow('شماره خریدار', getBuyerInformation(item)?.user?.mobile ?? 'N/A'), + buildRow('نوع فروش', item.sellType?.faItem ?? 'N/A'), + buildRow('قیمت هر کیلو', '${item.amount.separatedByComma ?? 0} ریال '), + buildRow('قیمت کل', '${item.totalAmount.separatedByComma ?? 0} ریال'), buildRow( 'وزن تخصیصی', '${item.weightOfCarcasses?.toInt().separatedByComma ?? 0} کیلوگرم', ), - buildRow( - 'کداحراز', - item.registrationCode?.toString() ?? 'N/A', - ), + buildRow('کداحراز', item.registrationCode?.toString() ?? 'N/A'), buildRow( 'وضعیت کد احراز', - item.systemRegistrationCode == true - ? "ارسال شده" - : "ارسال نشده" ?? 'N/A', - ), - buildRow( - 'افت وزن(کیلوگرم)', - item.weightLossOfCarcasses - ?.toInt() - .toString() ?? - 'N/A', + item.systemRegistrationCode == true ? "ارسال شده" : "ارسال نشده" ?? 'N/A', ), + buildRow('افت وزن(کیلوگرم)', item.weightLossOfCarcasses?.toInt().toString() ?? 'N/A'), Row( spacing: 10, @@ -800,25 +608,17 @@ class SalesInProvincePage extends GetView { backgroundColor: AppColor.greenNormal, height: 40, text: 'تایید', - textStyle: AppFonts.yekan18.copyWith( - color: Colors.white, - ), + textStyle: AppFonts.yekan18.copyWith(color: Colors.white), onPressed: () { - ConformAllocation confromation = - ConformAllocation( - allocation_key: item.key, - number_of_carcasses: - item.numberOfCarcasses, - weight_of_carcasses: item - .weightOfCarcasses - ?.toInt(), - amount: item.amount, - total_amount: item.totalAmount, - ); - - controller.confirmAllocation( - confromation, + ConformAllocation confromation = ConformAllocation( + allocation_key: item.key, + number_of_carcasses: item.numberOfCarcasses, + weight_of_carcasses: item.weightOfCarcasses?.toInt(), + amount: item.amount, + total_amount: item.totalAmount, ); + + controller.confirmAllocation(confromation); }, ), ), @@ -827,13 +627,9 @@ class SalesInProvincePage extends GetView { height: 40, borderColor: AppColor.error, text: 'رد', - textStyle: AppFonts.yekan18.copyWith( - color: AppColor.error, - ), + textStyle: AppFonts.yekan18.copyWith(color: AppColor.error), onPressed: () { - controller.denyAllocation( - item.key ?? '', - ); + controller.denyAllocation(item.key ?? ''); }, ), ), @@ -853,11 +649,7 @@ class SalesInProvincePage extends GetView { child: Center( child: RotatedBox( quarterTurns: 3, - child: Text( - item.state?.faItem, - style: AppFonts.yekan8, - textAlign: TextAlign.center, - ), + child: Text(item.state?.faItem, style: AppFonts.yekan8, textAlign: TextAlign.center), ), ), ), @@ -875,16 +667,10 @@ class SalesInProvincePage extends GetView { 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)), ), ), ], @@ -918,17 +704,12 @@ class SalesInProvincePage extends GetView { } } - Future buildDeleteDialog({ - required Future Function() onConfirm, - }) async { + Future buildDeleteDialog({required Future Function() onConfirm}) async { await Get.defaultDialog( title: 'حذف ', middleText: 'آیا از حذف این مورد مطمئن هستید؟', confirm: ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: AppColor.error, - foregroundColor: Colors.white, - ), + style: ElevatedButton.styleFrom(backgroundColor: AppColor.error, foregroundColor: Colors.white), onPressed: () async { await onConfirm(); Get.back(); @@ -943,4 +724,232 @@ class SalesInProvincePage extends GetView { ), ).whenComplete(() => controller.getAllocatedMade()); } + + ObxValue 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); + } + + 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.getAllocatedMade(); + Get.back(); + }, + height: 40, + ), + SizedBox(height: 16), + ], + ), + ); + } + + GestureDetector timeFilterWidget({ + isFrom = true, + required Rxn 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() ?? Jalali.now().formatCompactDate(), + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.lightGreyNormalActive), + ); + }, date), + ), + ], + ), + ), + ); + } + + Container modalDatePicker(ValueChanged onDateSelected) { + Jalali? tempPickedDate; + return Container( + height: 250, + color: Colors.white, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + 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: Jalali.now(), + mode: PersianCupertinoDatePickerMode.date, + onDateTimeChanged: (dateTime) { + tempPickedDate = dateTime; + }, + ), + ), + ), + ], + ), + ); + } + + Widget show2StepAddBottomSheet() { + return BaseBottomSheet( + height: Get.height*.35, + child: Column( + spacing: 8, + children: [ + buildRow('تاریخ ثبت', controller.tmpStewardAllocation?.date?.formattedJalaliDate ?? 'N/A'), + buildRow( + 'نام و نام خانوادگی خریدار', + 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 ?? + 'N/A', + ), + + buildRow('قیمت هر کیلو', '${controller.tmpStewardAllocation?.amount.separatedByComma ?? 0} ریال '), + buildRow( + 'وزن تخصیصی', + '${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByComma ?? 0} کیلوگرم', + ), + buildRow('قیمت کل', '${controller.tmpStewardAllocation?.totalAmount.separatedByComma ?? 0} ریال'), + + Row( + spacing: 10, + children: [ + Expanded( + child: RElevated( + backgroundColor: AppColor.greenNormal, + height: 40, + text: 'ثبت', + textStyle: AppFonts.yekan18.copyWith(color: Colors.white), + onPressed: () async { + await controller.submitAllocation(); + Get..back()..back(); + }, + ), + ), + Expanded( + child: ROutlinedElevated( + height: 40, + borderColor: AppColor.error, + text: ' بازگشت', + textStyle: AppFonts.yekan18.copyWith(color: AppColor.error), + onPressed: () { + Get.until((route) => route.settings.name == ChickenRoutes.salesInProvince); + }, + ), + ), + ], + ), + ], + ), + ); + } } diff --git a/packages/core/lib/utils/date_time_utils.dart b/packages/core/lib/utils/date_time_utils.dart index 30d6bf2..7cf2645 100644 --- a/packages/core/lib/utils/date_time_utils.dart +++ b/packages/core/lib/utils/date_time_utils.dart @@ -1,38 +1,35 @@ import 'package:intl/intl.dart'; import 'package:persian_datetime_picker/persian_datetime_picker.dart'; -extension XDateTime on String{ +extension XDateTime on String { get toDateTime => DateTime.parse(this); - get formattedJalaliDate{ - final dateTime = DateTime.parse(this); + String get formattedJalaliDate { + String tmp = contains("/") ? replaceAll("/", "-") : this; + final dateTime = DateTime.parse(tmp); final jalaliDate = Jalali.fromDateTime(dateTime); return "${jalaliDate.year}/${jalaliDate.month.toString().padLeft(2, '0')}/${jalaliDate.day.toString().padLeft(2, '0')}"; + } - get formattedJalaliDateYHMS { + String get formattedJalaliDateYHMS { final dateTime = DateTime.parse(this); final jalaliDate = Jalali.fromDateTime(dateTime); return "${jalaliDate.hour.toString().padLeft(2, '0')}:${jalaliDate.minute.toString().padLeft(2, '0')} - ${jalaliDate.year}/${jalaliDate.month.toString().padLeft(2, '0')}/${jalaliDate.day.toString().padLeft(2, '0')}"; } - - get formattedYHMS{ + String get formattedYHMS { return DateFormat('yyyy-MM-dd HH:mm:ss').format(toDateTime); } } - - -extension XDateTime2 on DateTime{ - - - get formattedJalaliDate{ +extension XDateTime2 on DateTime { + get formattedJalaliDate { final jalaliDate = Jalali.fromDateTime(this); return "${jalaliDate.year}/${jalaliDate.month.toString().padLeft(2, '0')}/${jalaliDate.day.toString().padLeft(2, '0')}"; } - get formattedYHMS{ + get formattedYHMS { return DateFormat('yyyy-MM-dd HH:mm:ss').format(this); } } diff --git a/packages/core/lib/utils/string_utils.dart b/packages/core/lib/utils/string_utils.dart index 555bcbe..148434e 100644 --- a/packages/core/lib/utils/string_utils.dart +++ b/packages/core/lib/utils/string_utils.dart @@ -7,7 +7,7 @@ extension XString on String { return number != null ? formatter.format(number) : this; } - get clearComma { + String get clearComma { return replaceAll(RegExp(r'\D'), ''); } }