diff --git a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.dart b/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.dart index 3ab099b..6efce7b 100644 --- a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.dart +++ b/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.dart @@ -6,7 +6,7 @@ part 'segmentation_model.g.dart'; @freezed abstract class SegmentationModel with _$SegmentationModel { - const factory SegmentationModel({String? key, Buyer? buyer, DateTime? date, double? weight}) = + const factory SegmentationModel({String? key, Buyer? buyer, DateTime? date, int? weight}) = _SegmentationModel; factory SegmentationModel.fromJson(Map json) => diff --git a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.freezed.dart b/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.freezed.dart index 0546eca..74e1a86 100644 --- a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.freezed.dart +++ b/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.freezed.dart @@ -16,7 +16,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$SegmentationModel { - String? get key; Buyer? get buyer; DateTime? get date; double? get weight; + String? get key; Buyer? get buyer; DateTime? get date; int? get weight; /// Create a copy of SegmentationModel /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -49,7 +49,7 @@ abstract mixin class $SegmentationModelCopyWith<$Res> { factory $SegmentationModelCopyWith(SegmentationModel value, $Res Function(SegmentationModel) _then) = _$SegmentationModelCopyWithImpl; @useResult $Res call({ - String? key, Buyer? buyer, DateTime? date, double? weight + String? key, Buyer? buyer, DateTime? date, int? weight }); @@ -72,7 +72,7 @@ key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable as String?,buyer: freezed == buyer ? _self.buyer : buyer // ignore: cast_nullable_to_non_nullable as Buyer?,date: freezed == date ? _self.date : date // ignore: cast_nullable_to_non_nullable as DateTime?,weight: freezed == weight ? _self.weight : weight // ignore: cast_nullable_to_non_nullable -as double?, +as int?, )); } /// Create a copy of SegmentationModel @@ -101,7 +101,7 @@ class _SegmentationModel implements SegmentationModel { @override final String? key; @override final Buyer? buyer; @override final DateTime? date; -@override final double? weight; +@override final int? weight; /// Create a copy of SegmentationModel /// with the given fields replaced by the non-null parameter values. @@ -136,7 +136,7 @@ abstract mixin class _$SegmentationModelCopyWith<$Res> implements $SegmentationM factory _$SegmentationModelCopyWith(_SegmentationModel value, $Res Function(_SegmentationModel) _then) = __$SegmentationModelCopyWithImpl; @override @useResult $Res call({ - String? key, Buyer? buyer, DateTime? date, double? weight + String? key, Buyer? buyer, DateTime? date, int? weight }); @@ -159,7 +159,7 @@ key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable as String?,buyer: freezed == buyer ? _self.buyer : buyer // ignore: cast_nullable_to_non_nullable as Buyer?,date: freezed == date ? _self.date : date // ignore: cast_nullable_to_non_nullable as DateTime?,weight: freezed == weight ? _self.weight : weight // ignore: cast_nullable_to_non_nullable -as double?, +as int?, )); } diff --git a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.g.dart b/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.g.dart index 22b4989..82835b2 100644 --- a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.g.dart +++ b/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.g.dart @@ -15,7 +15,7 @@ _SegmentationModel _$SegmentationModelFromJson(Map json) => date: json['date'] == null ? null : DateTime.parse(json['date'] as String), - weight: (json['weight'] as num?)?.toDouble(), + weight: (json['weight'] as num?)?.toInt(), ); Map _$SegmentationModelToJson(_SegmentationModel instance) => diff --git a/packages/chicken/lib/data/repositories/chicken_repository.dart b/packages/chicken/lib/data/repositories/chicken_repository.dart index 54c88f7..35697da 100644 --- a/packages/chicken/lib/data/repositories/chicken_repository.dart +++ b/packages/chicken/lib/data/repositories/chicken_repository.dart @@ -148,6 +148,8 @@ abstract class ChickenRepository { Map? queryParameters, }); + Future createSegmentation({required String token, required SegmentationModel model}); + Future editSegmentation({required String token, required SegmentationModel model}); Future deleteSegmentation({required String token, required String key}); diff --git a/packages/chicken/lib/data/repositories/chicken_repository_imp.dart b/packages/chicken/lib/data/repositories/chicken_repository_imp.dart index 3e1a80a..42d6c75 100644 --- a/packages/chicken/lib/data/repositories/chicken_repository_imp.dart +++ b/packages/chicken/lib/data/repositories/chicken_repository_imp.dart @@ -450,6 +450,15 @@ class ChickenRepositoryImpl implements ChickenRepository { return res.data; } + @override + Future createSegmentation({required String token, required SegmentationModel model}) async { + await _httpClient.post( + '/app-segmentation/', + data: model.toJson()..removeWhere((key, value) => value == null), + headers: {'Authorization': 'Bearer $token'}, + ); + } + @override Future editSegmentation({required String token, required SegmentationModel model}) async { await _httpClient.put( diff --git a/packages/chicken/lib/presentation/pages/root/logic.dart b/packages/chicken/lib/presentation/pages/root/logic.dart index 4d020da..57bfeeb 100644 --- a/packages/chicken/lib/presentation/pages/root/logic.dart +++ b/packages/chicken/lib/presentation/pages/root/logic.dart @@ -1,6 +1,5 @@ import 'dart:async'; -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'; @@ -13,6 +12,7 @@ import 'package:rasadyar_chicken/presentation/pages/buy/view.dart'; import 'package:rasadyar_chicken/presentation/pages/home/view.dart'; import 'package:rasadyar_chicken/presentation/pages/profile/view.dart'; import 'package:rasadyar_chicken/presentation/pages/sale/view.dart'; +import 'package:rasadyar_chicken/presentation/pages/segmentation/view.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -21,13 +21,7 @@ enum ErrorLocationType { serviceDisabled, permissionDenied, none } class RootLogic extends GetxController { RxInt currentPage = 2.obs; - List pages = [ - BuyPage(), - SalePage(), - HomePage(), - Container(color: Colors.blue), - ProfilePage(), - ]; + List pages = [BuyPage(), SalePage(), HomePage(), SegmentationPage(), ProfilePage()]; final defaultRoutes = {0: ChickenRoutes.buy, 1: ChickenRoutes.sale}; diff --git a/packages/chicken/lib/presentation/pages/segmentation/logic.dart b/packages/chicken/lib/presentation/pages/segmentation/logic.dart new file mode 100644 index 0000000..257e699 --- /dev/null +++ b/packages/chicken/lib/presentation/pages/segmentation/logic.dart @@ -0,0 +1,192 @@ +import 'package:flutter/cupertino.dart'; +import 'package:rasadyar_auth/data/utils/safe_call.dart'; +import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class SegmentationLogic extends GetxController { + RootLogic rootLogic = Get.find(); + + RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + + late List routesName; + RxInt selectedSegmentIndex = 0.obs; + RxBool isExpanded = false.obs; + + RxList isExpandedList = [].obs; + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + GlobalKey formKey = GlobalKey(); + TextEditingController weightController = TextEditingController(); + RxBool isSaleSubmitButtonEnabled = false.obs; + + RxList rolesProductsModel = RxList(); + Rxn selectedProduct = Rxn(); + Rxn selectedSegment = Rxn(); + + Rx>> segmentationList = + Resource>.loading().obs; + + @override + void onInit() { + super.onInit(); + routesName = ['قطعه‌بندی'].toList(); + getAllSegmentation(); + } + + @override + void onReady() { + super.onReady(); + setUpListener(); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + } + + void setSearchValue(String? value) { + searchedValue.value = value?.trim(); + } + + void setUpListener() { + debounce( + searchedValue, + (callback) => getAllSegmentation(), + time: Duration(milliseconds: timeDebounce), + ); + } + + void setEditData(SegmentationModel item) { + selectedSegment.value = item; + weightController.text = item.weight.toString(); + } + + void clearForm() { + weightController.clear(); + isSaleSubmitButtonEnabled.value = false; + selectedProduct.value = null; + selectedSegment.value = null; + formKey.currentState?.reset(); + } + + Future getAllSegmentation([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + segmentationList.value = Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; // Reset to first page if search value is set + } + + await safeCall( + call: () async => await rootLogic.chickenRepository.getSegmentation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + pageSize: 20, + page: currentPage.value, + search: 'filter', + role: 'Steward', + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + ), + ), + + onSuccess: (result) { + if ((result?.count ?? 0) == 0) { + segmentationList.value = Resource>.empty(); + } else { + segmentationList.value = Resource>.success( + PaginationModel( + count: result?.count ?? 0, + next: result?.next, + previous: result?.previous, + results: [ + ...(segmentationList.value.data?.results ?? []), + ...(result?.results ?? []), + ], + ), + ); + + isLoadingMoreAllocationsMade.value = false; + } + }, + ); + } + + Future deleteSegmentation(String key) async { + await safeCall( + call: () => rootLogic.chickenRepository.deleteSegmentation( + token: rootLogic.tokenService.accessToken.value!, + key: key, + ), + ); + } + + Future getRolesProducts() async { + safeCall( + call: () async => await rootLogic.chickenRepository.getRolesProducts( + token: rootLogic.tokenService.accessToken.value!, + ), + onSuccess: (result) { + if (result != null) { + rolesProductsModel.value = result; + + selectedProduct.value = rolesProductsModel.first; + } + }, + onError: (error, stacktrace) {}, + ); + } + + Future editSegment() async { + var res = true; + safeCall( + call: () async => await rootLogic.chickenRepository.editSegmentation( + token: rootLogic.tokenService.accessToken.value!, + model: SegmentationModel( + key: selectedSegment.value?.key, + weight: int.tryParse(weightController.text) ?? 0, + ), + ), + onSuccess: (result) { + res = true; + }, + onError: (error, stacktrace) { + res = false; + }, + ); + return res; + } + + Future createSegment() async { + var res = true; + safeCall( + call: () async => await rootLogic.chickenRepository.createSegmentation( + token: rootLogic.tokenService.accessToken.value!, + model: SegmentationModel( + key: selectedProduct.value?.key, + weight: int.tryParse(weightController.text) ?? 0, + ), + ), + onSuccess: (result) { + res = true; + }, + onError: (error, stacktrace) { + res = false; + }, + ); + return res; + } +} diff --git a/packages/chicken/lib/presentation/pages/segmentation/view.dart b/packages/chicken/lib/presentation/pages/segmentation/view.dart new file mode 100644 index 0000000..2cf5101 --- /dev/null +++ b/packages/chicken/lib/presentation/pages/segmentation/view.dart @@ -0,0 +1,331 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; +import 'package:rasadyar_chicken/presentation/widget/list_item/list_item.dart'; +import 'package:rasadyar_chicken/presentation/widget/list_row_item.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class SegmentationPage extends GetView { + @override + Widget build(BuildContext context) { + return BasePage( + routes: controller.routesName, + onSearchChanged: (data) => controller.setSearchValue(data), + filteringWidget: filterBottomSheet(), + isBase: true, + widgets: [ + Expanded( + child: ObxValue((data) { + return RPaginatedListView( + onLoadMore: () async => controller.getAllSegmentation(true), + onRefresh: () async { + controller.currentPage.value = 1; + await controller.getAllSegmentation(); + }, + hasMore: data.value.data?.next != null, + listType: ListType.separated, + resource: data.value, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ListItem2( + selected: val.contains(index), + onTap: () => controller.isExpandedList.toggle(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item, index), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.timerSvg.path, + ); + }, controller.isExpandedList); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.segmentationList), + ), + ], + + floatingActionButton: RFab.add( + onPressed: () { + //TODO + //Get.bottomSheet(addOrEditSaleBottomSheet(), isScrollControlled: true); + }, + ), + ); + } + + Widget filterBottomSheet() => filterBottomSheetWidget( + fromDate: controller.fromDateFilter, + onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali, + toDate: controller.toDateFilter, + onChangedToDate: (jalali) => controller.toDateFilter.value = jalali, + onSubmit: () => controller.getAllSegmentation(), + ); + + itemListWidget(SegmentationModel item) { + return 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( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + item.buyer?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + + SizedBox(height: 2), + Text( + item.buyer?.shop ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + SizedBox(width: 4), + Expanded( + flex: 4, + child: Text( + item.date?.formattedJalaliDate, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ), + Expanded( + flex: 2, + child: Text( + '${item.weight} KG', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ), + ], + ); + } + + itemListExpandedWidget(SegmentationModel item, int index) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Container( + height: 32, + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: ShapeDecoration( + color: AppColor.blueLight, + shape: RoundedRectangleBorder( + side: BorderSide(width: 1, color: AppColor.blueLightHover), + borderRadius: BorderRadius.circular(8), + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + spacing: 3, + children: [ + Text( + DateTimeExtensions(item.date)?.toJalali().formatter.wN ?? 'N/A', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + + Text( + '${DateTimeExtensions(item.date)?.toJalali().formatter.d} ${DateTimeExtensions(item.date)?.toJalali().formatter.mN ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + ], + ), + + Text( + '${DateTimeExtensions(item.date)?.toJalali().formatter.y}', + style: AppFonts.yekan20.copyWith(color: AppColor.textColor), + ), + + Text( + '${DateTimeExtensions(item.date)?.toJalali().formatter.tHH}:${DateTimeExtensions(item.date)?.toJalali().formatter.tMM ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + buildRow(title: 'مشخصات خریدار', value: item.buyer?.fullname ?? 'N/A'), + buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'N/A'), + buildRow(title: 'نام واحد', value: item.buyer?.shop ?? 'N/A'), + buildRow(title: 'وزن قطعه‌بندی', value: '${item.weight?.separatedByComma}'), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + RElevated( + text: 'ویرایش', + width: 150.w, + height: 40.h, + onPressed: () { + controller.setEditData(item); + Get.bottomSheet( + addOrEditBottomSheet(true), + isScrollControlled: true, + ).whenComplete(() { + controller.clearForm(); + }); + }, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ROutlinedElevated( + text: 'حذف', + textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal), + width: 150.w, + height: 40.h, + onPressed: () { + buildDeleteDialog( + onConfirm: () async { + controller.isExpandedList.remove(index); + controller.deleteSegmentation(item.key!); + }, + onRefresh: () => controller.getAllSegmentation(), + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ], + ), + ); + } + + Widget addOrEditBottomSheet([bool isOnEdit = false]) { + return BaseBottomSheet( + height: 500.h, + child: SingleChildScrollView( + child: Form( + key: controller.formKey, + child: Column( + spacing: 16, + children: [ + Text( + isOnEdit ? 'ویرایش قطعه‌بندی' : 'افزودن قطعه‌بندی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + _productDropDown(), + + Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Column( + spacing: 12, + children: [ + RTextField( + controller: controller.weightController, + label: 'وزن', + keyboardType: TextInputType.number, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + + validator: (value) { + if (value == null) { + return 'لطفاً وزن لاشه را وارد کنید'; + } + return null; + }, + ), + submitButtonWidget(isOnEdit), + ], + ), + ), + SizedBox(), + ], + ), + ), + ), + ); + } + + Widget submitButtonWidget(bool isOnEdit) { + return ObxValue((data) { + return RElevated( + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + text: isOnEdit ? 'ویرایش' : 'ثبت', + onPressed: data.value + ? () async { + var res = isOnEdit + ? await controller.editSegment() + : await controller.createSegment(); + if (res) { + controller.getAllSegmentation(); + controller.clearForm(); + Get.back(); + } + } + : null, + height: 40, + ); + }, controller.isSaleSubmitButtonEnabled); + } + + Widget _productDropDown() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rolesProductsModel, + height: 56, + hasDropIcon: false, + background: Colors.white, + onChanged: (value) { + controller.selectedProduct.value = value; + }, + selectedItem: controller.selectedProduct.value, + initialValue: controller.selectedProduct.value, + itemBuilder: (item) => Text(item.name ?? 'بدون نام'), + labelBuilder: (item) => Row( + spacing: 8, + children: [ + (item?.name?.contains('مرغ گرم') ?? false) + ? Assets.images.chicken.image(width: 40, height: 40) + : Assets.vec.placeHolderSvg.svg(width: 40, height: 40), + + Text(item?.name ?? 'انتخاب محصول'), + Spacer(), + Text( + 'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0}', + ), + ], + ), + ); + }); + } +} diff --git a/packages/chicken/lib/presentation/routes/pages.dart b/packages/chicken/lib/presentation/routes/pages.dart index ed401e7..b207d91 100644 --- a/packages/chicken/lib/presentation/routes/pages.dart +++ b/packages/chicken/lib/presentation/routes/pages.dart @@ -20,6 +20,7 @@ import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/logic. import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province/view.dart'; import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province_buyers/logic.dart'; import 'package:rasadyar_chicken/presentation/pages/sales_out_of_province_sales_list/logic.dart'; +import 'package:rasadyar_chicken/presentation/pages/segmentation/logic.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; import 'package:rasadyar_chicken/presentation/widget/search/logic.dart'; @@ -40,6 +41,7 @@ sealed class ChickenPages { Get.lazyPut(() => BuyLogic()); Get.lazyPut(() => SaleLogic()); Get.lazyPut(() => ProfileLogic()); + Get.lazyPut(() => SegmentationLogic()); }), ), @@ -53,7 +55,6 @@ sealed class ChickenPages { }), ), - //sales GetPage( name: ChickenRoutes.sale, @@ -61,9 +62,9 @@ sealed class ChickenPages { middlewares: [AuthMiddleware()], binding: BindingsBuilder(() { Get.lazyPut(() => SaleLogic()); - Get.lazyPut(() => BaseLogic()); - Get.lazyPut(() => SalesOutOfProvinceLogic()); - Get.lazyPut(() => RootLogic()); + Get.lazyPut(() => BaseLogic()); + Get.lazyPut(() => SalesOutOfProvinceLogic()); + Get.lazyPut(() => RootLogic()); }), ), GetPage( @@ -83,7 +84,7 @@ sealed class ChickenPages { middlewares: [AuthMiddleware()], binding: BindingsBuilder(() { Get.lazyPut(() => BaseLogic()); - Get.lazyPut(() => SalesInProvinceLogic()); + Get.lazyPut(() => SalesInProvinceLogic()); Get.lazyPut(() => SearchLogic()); }), ), @@ -98,7 +99,6 @@ sealed class ChickenPages { Get.lazyPut(() => BuyLogic()); }), ), - GetPage( name: ChickenRoutes.buysOutOfProvince, page: () => BuyOutOfProvincePage(), @@ -106,10 +106,9 @@ sealed class ChickenPages { binding: BindingsBuilder(() { Get.lazyPut(() => BaseLogic()); Get.lazyPut(() => SearchLogic()); - Get.lazyPut(() => BuyOutOfProvinceLogic()); + Get.lazyPut(() => BuyOutOfProvinceLogic()); }), ), - GetPage( name: ChickenRoutes.buysInProvince, page: () => BuyInProvincePage(), @@ -117,9 +116,9 @@ sealed class ChickenPages { binding: BindingsBuilder(() { Get.lazyPut(() => BaseLogic()); Get.lazyPut(() => SearchLogic()); - Get.lazyPut(() => BuyInProvinceLogic()); - Get.lazyPut(() => BuyInProvinceWaitingLogic()); - Get.lazyPut(() => BuyInProvinceAllLogic()); + Get.lazyPut(() => BuyInProvinceLogic()); + Get.lazyPut(() => BuyInProvinceWaitingLogic()); + Get.lazyPut(() => BuyInProvinceAllLogic()); }), ), ]; diff --git a/packages/chicken/lib/presentation/routes/routes.dart b/packages/chicken/lib/presentation/routes/routes.dart index ce08250..ba16f5d 100644 --- a/packages/chicken/lib/presentation/routes/routes.dart +++ b/packages/chicken/lib/presentation/routes/routes.dart @@ -6,6 +6,7 @@ sealed class ChickenRoutes { static const home = '$_base/home'; static const buy = '$_base/buy'; static const sale = '$_base/sale'; + static const segmentation = '$_base/segmentation'; //buys static const buysOutOfProvince = '$buy/buyOutOfProvince'; @@ -14,4 +15,6 @@ sealed class ChickenRoutes { //sales static const salesInProvince = '$sale/SalesInProvince'; static const salesOutOfProvince = '$sale/saleOutOfProvince'; + + } diff --git a/packages/core/lib/core.dart b/packages/core/lib/core.dart index ce8d522..6d9a392 100644 --- a/packages/core/lib/core.dart +++ b/packages/core/lib/core.dart @@ -48,9 +48,9 @@ export 'package:image_picker/image_picker.dart'; //utils export 'utils/logger_utils.dart'; export 'utils/network/network.dart'; -export 'utils/date_time_utils.dart'; -export 'utils/num_utils.dart'; +export 'utils/extension/date_time_utils.dart'; +export 'utils/extension/num_utils.dart'; export 'utils/map_utils.dart'; export 'utils/route_utils.dart'; -export 'utils/string_utils.dart'; +export 'utils/extension/string_utils.dart'; export 'utils/separator_input_formatter.dart'; diff --git a/packages/core/lib/utils/extension/date_time_utils.dart b/packages/core/lib/utils/extension/date_time_utils.dart new file mode 100644 index 0000000..caa653a --- /dev/null +++ b/packages/core/lib/utils/extension/date_time_utils.dart @@ -0,0 +1,13 @@ +import 'package:intl/intl.dart'; +import 'package:persian_datetime_picker/persian_datetime_picker.dart'; + +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 { + return DateFormat('yyyy-MM-dd HH:mm:ss').format(this); + } +} diff --git a/packages/core/lib/utils/num_utils.dart b/packages/core/lib/utils/extension/num_utils.dart similarity index 100% rename from packages/core/lib/utils/num_utils.dart rename to packages/core/lib/utils/extension/num_utils.dart diff --git a/packages/core/lib/utils/date_time_utils.dart b/packages/core/lib/utils/extension/string_utils.dart similarity index 74% rename from packages/core/lib/utils/date_time_utils.dart rename to packages/core/lib/utils/extension/string_utils.dart index 0c045ff..47252a1 100644 --- a/packages/core/lib/utils/date_time_utils.dart +++ b/packages/core/lib/utils/extension/string_utils.dart @@ -1,7 +1,18 @@ import 'package:intl/intl.dart'; import 'package:persian_datetime_picker/persian_datetime_picker.dart'; -extension XDateTime on String { +extension XString on String { + String get separatedByComma { + final formatter = NumberFormat('#,###'); + final number = num.tryParse(this); + return number != null ? formatter.format(number) : this; + } + + String get clearComma { + return replaceAll(RegExp(r'\D'), ''); + } + + get toDateTime => DateTime.parse(this); String get formattedJalaliDate { @@ -26,15 +37,4 @@ extension XDateTime on String { final dateTime = DateTime.parse(this); return Jalali.fromDateTime(dateTime); } -} - -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 { - return DateFormat('yyyy-MM-dd HH:mm:ss').format(this); - } -} +} \ No newline at end of file diff --git a/packages/core/lib/utils/string_utils.dart b/packages/core/lib/utils/string_utils.dart deleted file mode 100644 index 148434e..0000000 --- a/packages/core/lib/utils/string_utils.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:intl/intl.dart'; - -extension XString on String { - String get separatedByComma { - final formatter = NumberFormat('#,###'); - final number = num.tryParse(this); - return number != null ? formatter.format(number) : this; - } - - String get clearComma { - return replaceAll(RegExp(r'\D'), ''); - } -} diff --git a/packages/core/lib/utils/utils.dart b/packages/core/lib/utils/utils.dart new file mode 100644 index 0000000..8701a53 --- /dev/null +++ b/packages/core/lib/utils/utils.dart @@ -0,0 +1,14 @@ +export 'mixins/pagination_controller_mixin.dart'; + +export 'network/network.dart'; + +export 'extension/date_time_utils.dart'; +export 'extension/num_utils.dart'; +export 'extension/string_utils.dart'; + +export 'apk_updater.dart'; +export 'logger_utils.dart'; +export 'map_utils.dart'; +export 'route_utils.dart'; +export 'separator_input_formatter.dart'; +