feat : segment page

This commit is contained in:
2025-07-15 09:03:11 +03:30
parent f79a3ae46f
commit b1496b1ed0
15 changed files with 63 additions and 63 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

View File

@@ -6,7 +6,7 @@ part 'segmentation_model.g.dart';
@freezed
abstract class SegmentationModel with _$SegmentationModel {
const factory SegmentationModel({String? key, Buyer? buyer, DateTime? date, int? weight}) =
const factory SegmentationModel({String? key, Buyer? buyer, DateTime? date, int? weight,String? result}) =
_SegmentationModel;
factory SegmentationModel.fromJson(Map<String, dynamic> json) =>

View File

@@ -16,7 +16,7 @@ T _$identity<T>(T value) => value;
/// @nodoc
mixin _$SegmentationModel {
String? get key; Buyer? get buyer; DateTime? get date; int? get weight;
String? get key; Buyer? get buyer; DateTime? get date; int? get weight; String? get result;
/// Create a copy of SegmentationModel
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -29,16 +29,16 @@ $SegmentationModelCopyWith<SegmentationModel> get copyWith => _$SegmentationMode
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SegmentationModel&&(identical(other.key, key) || other.key == key)&&(identical(other.buyer, buyer) || other.buyer == buyer)&&(identical(other.date, date) || other.date == date)&&(identical(other.weight, weight) || other.weight == weight));
return identical(this, other) || (other.runtimeType == runtimeType&&other is SegmentationModel&&(identical(other.key, key) || other.key == key)&&(identical(other.buyer, buyer) || other.buyer == buyer)&&(identical(other.date, date) || other.date == date)&&(identical(other.weight, weight) || other.weight == weight)&&(identical(other.result, result) || other.result == result));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,key,buyer,date,weight);
int get hashCode => Object.hash(runtimeType,key,buyer,date,weight,result);
@override
String toString() {
return 'SegmentationModel(key: $key, buyer: $buyer, date: $date, weight: $weight)';
return 'SegmentationModel(key: $key, buyer: $buyer, date: $date, weight: $weight, result: $result)';
}
@@ -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, int? weight
String? key, Buyer? buyer, DateTime? date, int? weight, String? result
});
@@ -66,13 +66,14 @@ class _$SegmentationModelCopyWithImpl<$Res>
/// Create a copy of SegmentationModel
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? key = freezed,Object? buyer = freezed,Object? date = freezed,Object? weight = freezed,}) {
@pragma('vm:prefer-inline') @override $Res call({Object? key = freezed,Object? buyer = freezed,Object? date = freezed,Object? weight = freezed,Object? result = freezed,}) {
return _then(_self.copyWith(
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 int?,
as int?,result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
as String?,
));
}
/// Create a copy of SegmentationModel
@@ -95,13 +96,14 @@ $BuyerCopyWith<$Res>? get buyer {
@JsonSerializable()
class _SegmentationModel implements SegmentationModel {
const _SegmentationModel({this.key, this.buyer, this.date, this.weight});
const _SegmentationModel({this.key, this.buyer, this.date, this.weight, this.result});
factory _SegmentationModel.fromJson(Map<String, dynamic> json) => _$SegmentationModelFromJson(json);
@override final String? key;
@override final Buyer? buyer;
@override final DateTime? date;
@override final int? weight;
@override final String? result;
/// Create a copy of SegmentationModel
/// with the given fields replaced by the non-null parameter values.
@@ -116,16 +118,16 @@ Map<String, dynamic> toJson() {
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SegmentationModel&&(identical(other.key, key) || other.key == key)&&(identical(other.buyer, buyer) || other.buyer == buyer)&&(identical(other.date, date) || other.date == date)&&(identical(other.weight, weight) || other.weight == weight));
return identical(this, other) || (other.runtimeType == runtimeType&&other is _SegmentationModel&&(identical(other.key, key) || other.key == key)&&(identical(other.buyer, buyer) || other.buyer == buyer)&&(identical(other.date, date) || other.date == date)&&(identical(other.weight, weight) || other.weight == weight)&&(identical(other.result, result) || other.result == result));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,key,buyer,date,weight);
int get hashCode => Object.hash(runtimeType,key,buyer,date,weight,result);
@override
String toString() {
return 'SegmentationModel(key: $key, buyer: $buyer, date: $date, weight: $weight)';
return 'SegmentationModel(key: $key, buyer: $buyer, date: $date, weight: $weight, result: $result)';
}
@@ -136,7 +138,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, int? weight
String? key, Buyer? buyer, DateTime? date, int? weight, String? result
});
@@ -153,13 +155,14 @@ class __$SegmentationModelCopyWithImpl<$Res>
/// Create a copy of SegmentationModel
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? key = freezed,Object? buyer = freezed,Object? date = freezed,Object? weight = freezed,}) {
@override @pragma('vm:prefer-inline') $Res call({Object? key = freezed,Object? buyer = freezed,Object? date = freezed,Object? weight = freezed,Object? result = freezed,}) {
return _then(_SegmentationModel(
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 int?,
as int?,result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
as String?,
));
}

View File

@@ -16,6 +16,7 @@ _SegmentationModel _$SegmentationModelFromJson(Map<String, dynamic> json) =>
? null
: DateTime.parse(json['date'] as String),
weight: (json['weight'] as num?)?.toInt(),
result: json['result'] as String?,
);
Map<String, dynamic> _$SegmentationModelToJson(_SegmentationModel instance) =>
@@ -24,6 +25,7 @@ Map<String, dynamic> _$SegmentationModelToJson(_SegmentationModel instance) =>
'buyer': instance.buyer,
'date': instance.date?.toIso8601String(),
'weight': instance.weight,
'result': instance.result,
};
_Buyer _$BuyerFromJson(Map<String, dynamic> json) => _Buyer(

View File

@@ -152,5 +152,5 @@ abstract class ChickenRepository {
Future<void> editSegmentation({required String token, required SegmentationModel model});
Future<void> deleteSegmentation({required String token, required String key});
Future<SegmentationModel?> deleteSegmentation({required String token, required String key});
}

View File

@@ -469,11 +469,14 @@ class ChickenRepositoryImpl implements ChickenRepository {
}
@override
Future<void> deleteSegmentation({required String token, required String key}) async {
await _httpClient.delete(
Future<SegmentationModel?> deleteSegmentation({required String token, required String key}) async {
var res = await _httpClient.delete(
'/app-segmentation/0/',
queryParameters: {'key': key},
headers: {'Authorization': 'Bearer $token'},
fromJson: (json) => SegmentationModel.fromJson(json),
);
return res.data;
}
}

View File

@@ -31,7 +31,7 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
return RPaginatedListView(
listType: ListType.separated,
resource: data.value,
hasMore:data.value.data?.next!=null ,
hasMore: data.value.data?.next != null,
padding: EdgeInsets.fromLTRB(8, 8, 8, 80),
itemBuilder: (context, index) {
var item = data.value.data!.results![index];
@@ -356,17 +356,10 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
},
),
RTextField(
UnitTextField(
controller: controller.carcassWeightController,
label: 'وزن',
filled: true,
suffixIcon: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Assets.vec.killogramSvg.svg(),
),
filledColor: AppColor.bgLight,
keyboardType: TextInputType.number,
borderColor: AppColor.darkGreyLight,
hint: 'وزن',
unit: 'کیلوگرم',
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
SeparatorInputFormatter(),
@@ -589,10 +582,8 @@ class BuyOutOfProvincePage extends GetView<BuyOutOfProvinceLogic> {
},
height: 40,
),
],
),
);
}
}

View File

@@ -1,4 +1,5 @@
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/response/roles_products/roles_products.dart';
import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart';
@@ -75,10 +76,8 @@ class SegmentationLogic extends GetxController {
void clearForm() {
weightController.text = '0';
isSubmitButtonEnabled.value = false;
selectedProduct.value = null;
selectedSegment.value = null;
formKey.currentState?.reset();
}
void validateForm() {
@@ -142,6 +141,7 @@ class SegmentationLogic extends GetxController {
Future<void> deleteSegmentation(String key) async {
await safeCall(
showError: true,
call: () => rootLogic.chickenRepository.deleteSegmentation(
token: rootLogic.tokenService.accessToken.value!,
key: key,
@@ -152,6 +152,7 @@ class SegmentationLogic extends GetxController {
Future<bool> editSegment() async {
var res = true;
safeCall(
showError: true,
call: () async => await rootLogic.chickenRepository.editSegmentation(
token: rootLogic.tokenService.accessToken.value!,
model: SegmentationModel(

View File

@@ -17,7 +17,7 @@ class SegmentationPage extends GetView<SegmentationLogic> {
routes: controller.routesName,
onSearchChanged: (data) => controller.setSearchValue(data),
filteringWidget: filterBottomSheet(),
isBase: true,
hasBack: false,
widgets: [
Expanded(
child: ObxValue((data) {
@@ -41,7 +41,8 @@ class SegmentationPage extends GetView<SegmentationLogic> {
child: itemListWidget(item),
secondChild: itemListExpandedWidget(item, index),
labelColor: AppColor.blueLight,
labelIcon: Assets.vec.timerSvg.path,
labelIconColor: AppColor.customGrey,
labelIcon: Assets.vec.convertCubeSvg.path,
);
}, controller.isExpandedList);
},
@@ -51,11 +52,10 @@ class SegmentationPage extends GetView<SegmentationLogic> {
}, controller.segmentationList),
),
],
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
floatingActionButton: RFab.add(
onPressed: () {
//TODO
//Get.bottomSheet(addOrEditSaleBottomSheet(), isScrollControlled: true);
Get.bottomSheet(addOrEditBottomSheet(), isScrollControlled: true);
},
),
);
@@ -221,7 +221,7 @@ class SegmentationPage extends GetView<SegmentationLogic> {
Widget addOrEditBottomSheet([bool isOnEdit = false]) {
return BaseBottomSheet(
height: 500.h,
height: 300.h,
child: SingleChildScrollView(
child: Form(
key: controller.formKey,
@@ -244,18 +244,14 @@ class SegmentationPage extends GetView<SegmentationLogic> {
child: Column(
spacing: 12,
children: [
RTextField(
UnitTextField(
hint: 'وزن',
unit: 'کیلوگرم',
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 'لطفاً وزن لاشه را وارد کنید';
@@ -295,13 +291,13 @@ class SegmentationPage extends GetView<SegmentationLogic> {
: null,
height: 40,
);
}, controller.isSaleSubmitButtonEnabled);
}, controller.isSubmitButtonEnabled);
}
Widget _productDropDown() {
return Obx(() {
return OverlayDropdownWidget<ProductModel>(
items: controller.rolesProductsModel,
items: controller.rootLogic.rolesProductsModel,
height: 56,
hasDropIcon: false,
background: Colors.white,
@@ -321,7 +317,7 @@ class SegmentationPage extends GetView<SegmentationLogic> {
Text(item?.name ?? 'انتخاب محصول'),
Spacer(),
Text(
'موجودی:${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0}',
'موجودی: ${controller.rootLogic.inventoryModel.value?.totalRemainWeight.separatedByComma ?? 0} کیلوگرم',
),
],
),

View File

@@ -193,7 +193,10 @@ class ListItem2 extends StatelessWidget {
width: 16.w,
height: 16.h,
//TODO
colorFilter: ColorFilter.mode(labelIconColor ?? AppColor.mediumGreyDarkActive, BlendMode.srcIn),
colorFilter: ColorFilter.mode(
labelIconColor ?? AppColor.mediumGreyDarkActive,
BlendMode.srcIn,
),
),
),
),

View File

@@ -6,7 +6,6 @@ class DioRemote implements IHttpClient {
late Dio dio;
final AppInterceptor interceptors;
DioRemote({this.baseUrl, required this.interceptors});
@override
@@ -90,6 +89,7 @@ class DioRemote implements IHttpClient {
Map<String, String>? headers,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
T Function(Map<String, dynamic> json)? fromJson,
}) async {
final response = await dio.put(
path,
@@ -100,6 +100,11 @@ class DioRemote implements IHttpClient {
onReceiveProgress: onReceiveProgress,
cancelToken: ApiHandler.globalCancelToken,
);
if (fromJson != null && response.data is Map<String, dynamic>) {
response.data = fromJson(response.data);
return DioResponse<T>(response);
}
return DioResponse<T>(response);
}
@@ -109,6 +114,7 @@ class DioRemote implements IHttpClient {
dynamic data,
Map<String, dynamic>? queryParameters,
Map<String, String>? headers,
T Function(Map<String, dynamic> json)? fromJson,
}) async {
final response = await dio.delete<T>(
path,

View File

@@ -149,6 +149,7 @@ class AppColor {
static const Color mediumGreyDarker = Color(
0xFF323232,
); // #323232 rgb(50, 50, 50)
static const Color customGrey = Color(0xFF808081); // #808081 rgb(128, 128, 129)
//endregion
//region ---Light Grey Colors ---

View File

@@ -143,9 +143,6 @@ class $AssetsIconsGen {
/// File path: assets/icons/key.svg
SvgGenImage get key => const SvgGenImage('assets/icons/key.svg');
/// File path: assets/icons/killogram.svg
SvgGenImage get killogram => const SvgGenImage('assets/icons/killogram.svg');
/// File path: assets/icons/liveStock.svg
SvgGenImage get liveStock => const SvgGenImage('assets/icons/liveStock.svg');
@@ -285,7 +282,6 @@ class $AssetsIconsGen {
inside,
inspection,
key,
killogram,
liveStock,
lock,
logout,
@@ -468,9 +464,6 @@ class $AssetsVecGen {
/// File path: assets/vec/key.svg.vec
SvgGenImage get keySvg => const SvgGenImage.vec('assets/vec/key.svg.vec');
/// File path: assets/vec/killogram.svg.vec
SvgGenImage get killogramSvg => const SvgGenImage.vec('assets/vec/killogram.svg.vec');
/// File path: assets/vec/liveStock.svg.vec
SvgGenImage get liveStockSvg => const SvgGenImage.vec('assets/vec/liveStock.svg.vec');
@@ -610,7 +603,6 @@ class $AssetsVecGen {
insideSvg,
inspectionSvg,
keySvg,
killogramSvg,
liveStockSvg,
lockSvg,
logoutSvg,

View File

@@ -110,6 +110,11 @@ bool _isRetryableError(dynamic error) {
String _getErrorMessage(dynamic error) {
if (error is DioException) {
final responseData = error.response?.data;
if (responseData is Map<String, dynamic> && responseData['result'] != null) {
return responseData['result'].toString();
}
switch (error.type) {
case DioExceptionType.connectionTimeout:
return 'خطا در اتصال - زمان اتصال تمام شد';