diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index aed2f1e..fbb47e0 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -13,6 +13,7 @@ + diff --git a/android/local.properties b/android/local.properties index 8cd06f6..6325406 100644 --- a/android/local.properties +++ b/android/local.properties @@ -1,5 +1,5 @@ sdk.dir=C:\\Users\\Housh11\\AppData\\Local\\Android\\sdk flutter.sdk=C:\\src\\flutter flutter.buildMode=debug -flutter.versionName=1.3.33 -flutter.versionCode=30 \ No newline at end of file +flutter.versionName=1.3.39 +flutter.versionCode=35 \ No newline at end of file diff --git a/devtools_options.yaml b/devtools_options.yaml index ff5a421..a39b6d9 100644 --- a/devtools_options.yaml +++ b/devtools_options.yaml @@ -1,4 +1,6 @@ description: This file stores settings for Dart & Flutter DevTools. documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states extensions: - - hive_ce: true \ No newline at end of file + - hive_ce: true + - provider: true + - shared_preferences: true \ No newline at end of file diff --git a/lib/data/model/app_info_model.dart b/lib/data/model/app_info_model.dart index e6eb9f9..e7b6d15 100644 --- a/lib/data/model/app_info_model.dart +++ b/lib/data/model/app_info_model.dart @@ -5,14 +5,21 @@ part 'app_info_model.g.dart'; @freezed abstract class AppInfoModel with _$AppInfoModel { - const factory AppInfoModel({String? key, String? download_link, Info? info}) = _AppInfoModel; + const factory AppInfoModel({String? key, String? file, Info? info}) = + _AppInfoModel; - factory AppInfoModel.fromJson(Map json) => _$AppInfoModelFromJson(json); + factory AppInfoModel.fromJson(Map json) => + _$AppInfoModelFromJson(json); } @freezed abstract class Info with _$Info { - const factory Info({String? version, String? module, bool? required}) = _Info; + const factory Info({ + String? version, + String? minVersion, + String? module, + bool? required, + }) = _Info; factory Info.fromJson(Map json) => _$InfoFromJson(json); } diff --git a/lib/data/model/app_info_model.freezed.dart b/lib/data/model/app_info_model.freezed.dart index dc05818..05bf09d 100644 --- a/lib/data/model/app_info_model.freezed.dart +++ b/lib/data/model/app_info_model.freezed.dart @@ -15,7 +15,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$AppInfoModel { - String? get key; String? get download_link; Info? get info; + String? get key; String? get file; Info? get info; /// Create a copy of AppInfoModel /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -28,16 +28,16 @@ $AppInfoModelCopyWith get copyWith => _$AppInfoModelCopyWithImpl Object.hash(runtimeType,key,download_link,info); +int get hashCode => Object.hash(runtimeType,key,file,info); @override String toString() { - return 'AppInfoModel(key: $key, download_link: $download_link, info: $info)'; + return 'AppInfoModel(key: $key, file: $file, info: $info)'; } @@ -48,7 +48,7 @@ abstract mixin class $AppInfoModelCopyWith<$Res> { factory $AppInfoModelCopyWith(AppInfoModel value, $Res Function(AppInfoModel) _then) = _$AppInfoModelCopyWithImpl; @useResult $Res call({ - String? key, String? download_link, Info? info + String? key, String? file, Info? info }); @@ -65,10 +65,10 @@ class _$AppInfoModelCopyWithImpl<$Res> /// Create a copy of AppInfoModel /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? key = freezed,Object? download_link = freezed,Object? info = freezed,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? key = freezed,Object? file = freezed,Object? info = freezed,}) { return _then(_self.copyWith( key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable -as String?,download_link: freezed == download_link ? _self.download_link : download_link // ignore: cast_nullable_to_non_nullable +as String?,file: freezed == file ? _self.file : file // ignore: cast_nullable_to_non_nullable as String?,info: freezed == info ? _self.info : info // ignore: cast_nullable_to_non_nullable as Info?, )); @@ -167,10 +167,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( String? key, String? download_link, Info? info)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( String? key, String? file, Info? info)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _AppInfoModel() when $default != null: -return $default(_that.key,_that.download_link,_that.info);case _: +return $default(_that.key,_that.file,_that.info);case _: return orElse(); } @@ -188,10 +188,10 @@ return $default(_that.key,_that.download_link,_that.info);case _: /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( String? key, String? download_link, Info? info) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( String? key, String? file, Info? info) $default,) {final _that = this; switch (_that) { case _AppInfoModel(): -return $default(_that.key,_that.download_link,_that.info);case _: +return $default(_that.key,_that.file,_that.info);case _: throw StateError('Unexpected subclass'); } @@ -208,10 +208,10 @@ return $default(_that.key,_that.download_link,_that.info);case _: /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? key, String? download_link, Info? info)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? key, String? file, Info? info)? $default,) {final _that = this; switch (_that) { case _AppInfoModel() when $default != null: -return $default(_that.key,_that.download_link,_that.info);case _: +return $default(_that.key,_that.file,_that.info);case _: return null; } @@ -223,11 +223,11 @@ return $default(_that.key,_that.download_link,_that.info);case _: @JsonSerializable() class _AppInfoModel implements AppInfoModel { - const _AppInfoModel({this.key, this.download_link, this.info}); + const _AppInfoModel({this.key, this.file, this.info}); factory _AppInfoModel.fromJson(Map json) => _$AppInfoModelFromJson(json); @override final String? key; -@override final String? download_link; +@override final String? file; @override final Info? info; /// Create a copy of AppInfoModel @@ -243,16 +243,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppInfoModel&&(identical(other.key, key) || other.key == key)&&(identical(other.download_link, download_link) || other.download_link == download_link)&&(identical(other.info, info) || other.info == info)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppInfoModel&&(identical(other.key, key) || other.key == key)&&(identical(other.file, file) || other.file == file)&&(identical(other.info, info) || other.info == info)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,key,download_link,info); +int get hashCode => Object.hash(runtimeType,key,file,info); @override String toString() { - return 'AppInfoModel(key: $key, download_link: $download_link, info: $info)'; + return 'AppInfoModel(key: $key, file: $file, info: $info)'; } @@ -263,7 +263,7 @@ abstract mixin class _$AppInfoModelCopyWith<$Res> implements $AppInfoModelCopyWi factory _$AppInfoModelCopyWith(_AppInfoModel value, $Res Function(_AppInfoModel) _then) = __$AppInfoModelCopyWithImpl; @override @useResult $Res call({ - String? key, String? download_link, Info? info + String? key, String? file, Info? info }); @@ -280,10 +280,10 @@ class __$AppInfoModelCopyWithImpl<$Res> /// Create a copy of AppInfoModel /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? key = freezed,Object? download_link = freezed,Object? info = freezed,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? key = freezed,Object? file = freezed,Object? info = freezed,}) { return _then(_AppInfoModel( key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable -as String?,download_link: freezed == download_link ? _self.download_link : download_link // ignore: cast_nullable_to_non_nullable +as String?,file: freezed == file ? _self.file : file // ignore: cast_nullable_to_non_nullable as String?,info: freezed == info ? _self.info : info // ignore: cast_nullable_to_non_nullable as Info?, )); @@ -308,7 +308,7 @@ $InfoCopyWith<$Res>? get info { /// @nodoc mixin _$Info { - String? get version; String? get module; bool? get required; + String? get version; String? get minVersion; String? get module; bool? get required; /// Create a copy of Info /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -321,16 +321,16 @@ $InfoCopyWith get copyWith => _$InfoCopyWithImpl(this as Info, _$ide @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is Info&&(identical(other.version, version) || other.version == version)&&(identical(other.module, module) || other.module == module)&&(identical(other.required, required) || other.required == required)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is Info&&(identical(other.version, version) || other.version == version)&&(identical(other.minVersion, minVersion) || other.minVersion == minVersion)&&(identical(other.module, module) || other.module == module)&&(identical(other.required, required) || other.required == required)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,version,module,required); +int get hashCode => Object.hash(runtimeType,version,minVersion,module,required); @override String toString() { - return 'Info(version: $version, module: $module, required: $required)'; + return 'Info(version: $version, minVersion: $minVersion, module: $module, required: $required)'; } @@ -341,7 +341,7 @@ abstract mixin class $InfoCopyWith<$Res> { factory $InfoCopyWith(Info value, $Res Function(Info) _then) = _$InfoCopyWithImpl; @useResult $Res call({ - String? version, String? module, bool? required + String? version, String? minVersion, String? module, bool? required }); @@ -358,9 +358,10 @@ class _$InfoCopyWithImpl<$Res> /// Create a copy of Info /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? version = freezed,Object? module = freezed,Object? required = freezed,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? version = freezed,Object? minVersion = freezed,Object? module = freezed,Object? required = freezed,}) { return _then(_self.copyWith( version: freezed == version ? _self.version : version // ignore: cast_nullable_to_non_nullable +as String?,minVersion: freezed == minVersion ? _self.minVersion : minVersion // ignore: cast_nullable_to_non_nullable as String?,module: freezed == module ? _self.module : module // ignore: cast_nullable_to_non_nullable as String?,required: freezed == required ? _self.required : required // ignore: cast_nullable_to_non_nullable as bool?, @@ -448,10 +449,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( String? version, String? module, bool? required)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( String? version, String? minVersion, String? module, bool? required)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _Info() when $default != null: -return $default(_that.version,_that.module,_that.required);case _: +return $default(_that.version,_that.minVersion,_that.module,_that.required);case _: return orElse(); } @@ -469,10 +470,10 @@ return $default(_that.version,_that.module,_that.required);case _: /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( String? version, String? module, bool? required) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( String? version, String? minVersion, String? module, bool? required) $default,) {final _that = this; switch (_that) { case _Info(): -return $default(_that.version,_that.module,_that.required);case _: +return $default(_that.version,_that.minVersion,_that.module,_that.required);case _: throw StateError('Unexpected subclass'); } @@ -489,10 +490,10 @@ return $default(_that.version,_that.module,_that.required);case _: /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? version, String? module, bool? required)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? version, String? minVersion, String? module, bool? required)? $default,) {final _that = this; switch (_that) { case _Info() when $default != null: -return $default(_that.version,_that.module,_that.required);case _: +return $default(_that.version,_that.minVersion,_that.module,_that.required);case _: return null; } @@ -504,10 +505,11 @@ return $default(_that.version,_that.module,_that.required);case _: @JsonSerializable() class _Info implements Info { - const _Info({this.version, this.module, this.required}); + const _Info({this.version, this.minVersion, this.module, this.required}); factory _Info.fromJson(Map json) => _$InfoFromJson(json); @override final String? version; +@override final String? minVersion; @override final String? module; @override final bool? required; @@ -524,16 +526,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _Info&&(identical(other.version, version) || other.version == version)&&(identical(other.module, module) || other.module == module)&&(identical(other.required, required) || other.required == required)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Info&&(identical(other.version, version) || other.version == version)&&(identical(other.minVersion, minVersion) || other.minVersion == minVersion)&&(identical(other.module, module) || other.module == module)&&(identical(other.required, required) || other.required == required)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,version,module,required); +int get hashCode => Object.hash(runtimeType,version,minVersion,module,required); @override String toString() { - return 'Info(version: $version, module: $module, required: $required)'; + return 'Info(version: $version, minVersion: $minVersion, module: $module, required: $required)'; } @@ -544,7 +546,7 @@ abstract mixin class _$InfoCopyWith<$Res> implements $InfoCopyWith<$Res> { factory _$InfoCopyWith(_Info value, $Res Function(_Info) _then) = __$InfoCopyWithImpl; @override @useResult $Res call({ - String? version, String? module, bool? required + String? version, String? minVersion, String? module, bool? required }); @@ -561,9 +563,10 @@ class __$InfoCopyWithImpl<$Res> /// Create a copy of Info /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? version = freezed,Object? module = freezed,Object? required = freezed,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? version = freezed,Object? minVersion = freezed,Object? module = freezed,Object? required = freezed,}) { return _then(_Info( version: freezed == version ? _self.version : version // ignore: cast_nullable_to_non_nullable +as String?,minVersion: freezed == minVersion ? _self.minVersion : minVersion // ignore: cast_nullable_to_non_nullable as String?,module: freezed == module ? _self.module : module // ignore: cast_nullable_to_non_nullable as String?,required: freezed == required ? _self.required : required // ignore: cast_nullable_to_non_nullable as bool?, diff --git a/lib/data/model/app_info_model.g.dart b/lib/data/model/app_info_model.g.dart index 90cd6a5..3619ebe 100644 --- a/lib/data/model/app_info_model.g.dart +++ b/lib/data/model/app_info_model.g.dart @@ -9,7 +9,7 @@ part of 'app_info_model.dart'; _AppInfoModel _$AppInfoModelFromJson(Map json) => _AppInfoModel( key: json['key'] as String?, - download_link: json['download_link'] as String?, + file: json['file'] as String?, info: json['info'] == null ? null : Info.fromJson(json['info'] as Map), @@ -18,18 +18,20 @@ _AppInfoModel _$AppInfoModelFromJson(Map json) => Map _$AppInfoModelToJson(_AppInfoModel instance) => { 'key': instance.key, - 'download_link': instance.download_link, + 'file': instance.file, 'info': instance.info, }; _Info _$InfoFromJson(Map json) => _Info( version: json['version'] as String?, + minVersion: json['minVersion'] as String?, module: json['module'] as String?, required: json['required'] as bool?, ); Map _$InfoToJson(_Info instance) => { 'version': instance.version, + 'minVersion': instance.minVersion, 'module': instance.module, 'required': instance.required, }; diff --git a/lib/infrastructure/utils/local_storage_utils.dart b/lib/infrastructure/utils/local_storage_utils.dart index 8df0853..ac7bbfe 100644 --- a/lib/infrastructure/utils/local_storage_utils.dart +++ b/lib/infrastructure/utils/local_storage_utils.dart @@ -1,6 +1,6 @@ import 'package:rasadyar_app/presentation/routes/app_pages.dart'; import 'package:rasadyar_chicken/data/di/chicken_di.dart'; -import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_inspection/injection/inspection_di.dart'; import 'package:rasadyar_inspection/inspection.dart'; @@ -22,7 +22,7 @@ Future seedTargetPage() async { functions: ["setupLiveStockDI"], ), TargetPage( - route: ChickenRoutes.initSteward, + route: StewardRoutes.initSteward, module: Module.chicken, functions: ["setupChickenDI"], ), diff --git a/lib/presentation/pages/modules/logic.dart b/lib/presentation/pages/modules/logic.dart index 2b65c7b..38c4c5b 100644 --- a/lib/presentation/pages/modules/logic.dart +++ b/lib/presentation/pages/modules/logic.dart @@ -102,7 +102,7 @@ class ModulesLogic extends GetxController { Future navigateToModule(Module module) async { var target = getAuthTargetPage(module).entries.first; - + if (target.value?[0] != null) { isLoading.value = !isLoading.value; await target.value?[0]?.call(); diff --git a/lib/presentation/pages/splash/logic.dart b/lib/presentation/pages/splash/logic.dart index d6fc2db..d088dfc 100644 --- a/lib/presentation/pages/splash/logic.dart +++ b/lib/presentation/pages/splash/logic.dart @@ -185,7 +185,7 @@ class SplashLogic extends GetxController with GetTickerProviderStateMixin { try { final info = await PackageInfo.fromPlatform(); int version = info.version.versionNumber; - var res = await _dio.get("https://rsibackend.rasadyaar.ir/app/apk-info/"); + var res = await _dio.get("https://rsibackend.rasadyar.com/app/rasadyar-app-info/"); appInfoModel = AppInfoModel.fromJson(res.data); @@ -214,7 +214,7 @@ class SplashLogic extends GetxController with GetTickerProviderStateMixin { while (attempts < retryCount && !success) { try { await _dio.download( - appInfoModel?.download_link ?? '', + appInfoModel?.file ?? '', filePath, onReceiveProgress: (count, total) { if (total != -1 && total > 0) { diff --git a/output.json b/output.json new file mode 100644 index 0000000..b058660 --- /dev/null +++ b/output.json @@ -0,0 +1,74 @@ +{ + "lat": 35.8245784, + "log": 50.9479516, + "hatching_id": 4560, + "role": "SuperAdmin", + "report_information": { + "general_condition_hall": { + "images": [ + "https://s3.rasadyar.com/rasadyar/202512141551550.jpg", + "https://s3.rasadyar.com/rasadyar/202512141551560.jpg" + ], + "health_status": "عالی", + "ventilation_status": "عالی", + "bed_condition": "خشک", + "temperature": 25, + "drinking_water_source": null, + "drinking_water_quality": null + }, + "casualties": { + "normal_losses": null, + "abnormal_losses": null, + "source_of_hatching": null, + "cause_abnormal_losses": null, + "type_disease": null, + "sampling_done": null, + "type_sampling": null, + "images": null + }, + "technical_officer": { + "technical_health_officer": "", + "technical_engineering_officer": "" + }, + "input_status": { + "input_status": null, + "company_name": null, + "tracking_code": "", + "type_of_grain": null, + "inventory_in_warehouse": "", + "inventory_until_visit": "", + "grade_grain": null, + "images": null + }, + "infrastructure_energy": { + "generator_type": "", + "generator_model": "", + "generator_count": "", + "generator_capacity": "", + "fuel_type": null, + "generator_performance": null, + "emergency_fuel_inventory": "", + "has_power_cut_history": null, + "power_cut_duration": "", + "power_cut_hour": "", + "additional_notes": "" + }, + "hr": { + "number_employed": null, + "number_indigenous": null, + "number_non_indigenous": null, + "contract_status": null, + "trained": null + }, + "facilities": { + "has_facilities": null, + "type_of_facility": null, + "amount": null, + "date": null, + "repayment_status": null, + "request_facilities": null + }, + "inspection_status": "تایید شده", + "inspection_notes": "تست" + } +} \ No newline at end of file diff --git a/packages/chicken/devtools_options.yaml b/packages/chicken/devtools_options.yaml index ff5a421..a39b6d9 100644 --- a/packages/chicken/devtools_options.yaml +++ b/packages/chicken/devtools_options.yaml @@ -1,4 +1,6 @@ description: This file stores settings for Dart & Flutter DevTools. documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states extensions: - - hive_ce: true \ No newline at end of file + - hive_ce: true + - provider: true + - shared_preferences: true \ No newline at end of file diff --git a/packages/chicken/lib/data/common/fa_user_role.dart b/packages/chicken/lib/data/common/fa_user_role.dart index fa616dd..52e19c2 100644 --- a/packages/chicken/lib/data/common/fa_user_role.dart +++ b/packages/chicken/lib/data/common/fa_user_role.dart @@ -1,3 +1,12 @@ +import 'package:rasadyar_chicken/features/city_jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; String getFaUserRole(String? role) { @@ -88,7 +97,7 @@ Map getFaUserRoleWithOnTap(String? role) { case "Poultry": return {"مرغدار": null}; case "ProvinceOperator": - return {"مدیر اجرایی": null}; + return {"مدیر اجرایی": ProvinceOperatorRoutes.initProvinceOperator}; case "ProvinceFinancial": return {"مالی اتحادیه": null}; case "KillHouse": @@ -96,17 +105,17 @@ Map getFaUserRoleWithOnTap(String? role) { case "KillHouseVet": return {"دامپزشک کشتارگاه": null}; case "VetFarm": - return {"دامپزشک فارم": null}; + return {"دامپزشک فارم": VetFarmRoutes.initVetFarm}; case "Driver": return {"راننده": null}; case "ProvinceInspector": - return {"بازرس اتحادیه": null}; + return {"بازرس اتحادیه": ProvinceInspectorRoutes.initProvinceInspector}; case "VetSupervisor": return {"دامپزشک کل": null}; case "Jahad": - return {"جهاد کشاورزی استان": null}; + return {"جهاد کشاورزی استان": JahadRoutes.initJahad}; case "CityJahad": - return {"جهاد کشاورزی شهرستان": null}; + return {"جهاد کشاورزی شهرستان": CityJahadRoutes.initCityJahad}; case "ProvincialGovernment": return {"استانداری": null}; case "Guilds": @@ -122,7 +131,7 @@ Map getFaUserRoleWithOnTap(String? role) { case "Observatory": return {"رصدخانه": null}; case "ProvinceSupervisor": - return {"ناظر استان": null}; + return {"ناظر استان": ProvinceSupervisorRoutes.initProvinceSupervisor}; case "GuildRoom": return {"اتاق اصناف": null}; case "PosCompany": @@ -130,7 +139,7 @@ Map getFaUserRoleWithOnTap(String? role) { case "LiveStockSupport": return {"پشتیبانی امور دام": null}; case "SuperAdmin": - return {"ادمین کل": null}; + return {"ادمین کل": SuperAdminRoutes.initSuperAdmin}; case "ChainCompany": return {"شرکت زنجیره": null}; case "AdminX": @@ -150,9 +159,9 @@ Map getFaUserRoleWithOnTap(String? role) { case "LiveStockProvinceJahad": return {"جهاد استان": null}; case "Steward": - return {"مباشر": ChickenRoutes.initSteward}; + return {"مباشر": StewardRoutes.initSteward}; case "PoultryScience": - return {"کارشناس طیور": ChickenRoutes.initPoultryScience}; + return {"کارشناس طیور": PoultryScienceRoutes.initPoultryScience}; default: return {"نامشخص": null}; } diff --git a/packages/chicken/lib/data/data_source/remote/chicken/chicken_remote.dart b/packages/chicken/lib/data/data_source/remote/chicken/chicken_remote.dart deleted file mode 100644 index 41492d8..0000000 --- a/packages/chicken/lib/data/data_source/remote/chicken/chicken_remote.dart +++ /dev/null @@ -1,208 +0,0 @@ -import 'package:rasadyar_chicken/data/models/request/change_password/change_password_request_model.dart'; -import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart'; -import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; -import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart'; -import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; -import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart'; -import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; -import 'package:rasadyar_chicken/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; -import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/imported_loads_model/imported_loads_model.dart'; -import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.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/segmentation_model/segmentation_model.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart' - hide ProductModel; -import 'package:rasadyar_core/core.dart'; - -abstract class ChickenRemoteDatasource { - Future?> getRolesProducts({ - required String token, - CancelToken? cancelToken, - Map? queryParameters, - }); - Future getKillHouseDistributionInfo({ - required String token, - }); - - Future getGeneralBarInformation({ - required String token, - Map? queryParameters, - }); - - Future?> getWaitingArrivals({ - required String token, - Map? queryParameters, - }); - - Future setSateForArrivals({ - required String token, - required Map request, - }); - - Future?> getImportedLoadsModel({ - required String token, - Map? queryParameters, - }); - - Future?> getAllocatedMade({ - required String token, - Map? queryParameters, - }); - - Future confirmAllocation({ - required String token, - required Map allocation, - }); - - Future denyAllocation({ - required String token, - required String allocationToken, - }); - - Future confirmAllAllocation({ - required String token, - required List allocationTokens, - }); - - Future?> getGuilds({ - required String token, - Map? queryParameters, - }); - - Future getProfile({required String token}); - - Future postSubmitStewardAllocation({ - required String token, - required SubmitStewardAllocation request, - }); - - Future deleteStewardAllocation({ - required String token, - Map? queryParameters, - }); - - Future updateStewardAllocation({ - required String token, - required ConformAllocation request, - }); - - Future getStewardDashboard({ - required String token, - required String stratDate, - required String endDate, - }); - - Future getDashboardKillHouseFreeBar({ - required String token, - required String stratDate, - required String endDate, - }); - - Future?> - getStewardPurchasesOutSideOfTheProvince({ - required String token, - Map? queryParameters, - }); - - Future createStewardPurchasesOutSideOfTheProvince({ - required String token, - required CreateStewardFreeBar body, - }); - - Future deleteStewardPurchasesOutSideOfTheProvince({ - required String token, - Map? queryParameters, - }); - - Future editStewardPurchasesOutSideOfTheProvince({ - required String token, - Map? queryParameters, - }); - - Future?> - getOutProvinceCarcassesBuyer({ - required String token, - Map? queryParameters, - }); - - Future createOutProvinceCarcassesBuyer({ - required String token, - required OutProvinceCarcassesBuyer body, - }); - - Future?> getProvince({CancelToken? cancelToken}); - - Future?> getCity({required String provinceName}); - - Future?> getStewardFreeSaleBar({ - required String token, - Map? queryParameters, - }); - - Future createOutProvinceStewardFreeBar({ - required String token, - required StewardFreeSaleBarRequest body, - }); - - Future updateOutProvinceStewardFreeBar({ - required String token, - required StewardFreeSaleBarRequest body, - }); - - Future deleteOutProvinceStewardFreeBar({ - required String token, - required String key, - }); - - Future getUserProfile({required String token}); - - Future updateUserProfile({ - required String token, - required UserProfile userProfile, - }); - - Future updatePassword({ - required String token, - required ChangePasswordRequestModel model, - }); - - Future?> getSegmentation({ - required String token, - 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, - }); - - Future getBroadcastPrice({required String token}); - - Future getStewardSalesInfoDashboard({ - required String token, - Map? queryParameters, - }); - - Future getStewardRemainWeight({required String token}); -} diff --git a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote.dart b/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote.dart deleted file mode 100644 index 3a892c4..0000000 --- a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart'; -import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; -import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart'; -import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart'; -import 'package:rasadyar_core/core.dart'; - -abstract class PoultryScienceRemoteDatasource { - Future getHomePoultryScience({ - required String token, - required String type, - }); - - Future?> getHatchingPoultry({ - required String token, - Map? queryParameters, - }); - - Future submitPoultryScienceReport({ - required String token, - required FormData data, - ProgressCallback? onSendProgress, - }); - - Future?> getPoultryScienceReport({ - required String token, - Map? queryParameters, - }); - - Future?> getPoultryScienceFarmList({ - required String token, - Map? queryParameters, - }); - - Future getApprovedPrice({ required String token, - Map? queryParameters,}); - - Future?> getAllPoultry({ - required String token, - Map? queryParameters, - }); - - - Future getSellForFreezing({ - required String token, - Map? queryParameters, - }); - - - Future getPoultryExport({ - required String token, - Map? queryParameters, - }); - - - Future?> getUserPoultry({ - required String token, - Map? queryParameters, - }); - - Future?> getPoultryHatching({ - required String token, - Map? queryParameters, - }); - - Future?> getKillHouseList({ - required String token, - Map? queryParameters, - }); - - Future submitKillRegistration({ - required String token, - required KillRegistrationRequest request, - }); - - - Future?> getPoultryOderList({ - required String token, - Map? queryParameters, - }); - - Future deletePoultryOder({ - required String token, - required String orderId, - }); -} diff --git a/packages/chicken/lib/data/di/chicken_di.dart b/packages/chicken/lib/data/di/chicken_di.dart index 9c1f84c..483852e 100644 --- a/packages/chicken/lib/data/di/chicken_di.dart +++ b/packages/chicken/lib/data/di/chicken_di.dart @@ -1,23 +1,19 @@ -import 'package:rasadyar_chicken/chicken.dart'; import 'package:rasadyar_chicken/data/common/dio_error_handler.dart'; -import 'package:rasadyar_chicken/data/data_source/local/chicken_local.dart'; -import 'package:rasadyar_chicken/data/data_source/local/chicken_local_imp.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote_imp.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/chicken/chicken_remote.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/chicken/chicken_remote_imp.dart'; +import 'package:rasadyar_chicken/features/common/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/common/data/di/common_di.dart'; import 'package:rasadyar_chicken/data/data_source/remote/kill_house/kill_house_remote.dart'; import 'package:rasadyar_chicken/data/data_source/remote/kill_house/kill_house_remote_impl.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart'; -import 'package:rasadyar_chicken/data/repositories/auth/auth_repository.dart'; -import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart'; -import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart'; -import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository_imp.dart'; import 'package:rasadyar_chicken/data/repositories/kill_house/kill_house_repository.dart'; import 'package:rasadyar_chicken/data/repositories/kill_house/kill_house_repository_impl.dart'; -import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository.dart'; -import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository_imp.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/di/poultry_science_di.dart'; +import 'package:rasadyar_chicken/features/steward/data/di/steward_di.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/di/province_operator_di.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/di/province_inspector_di.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/di/city_jahad_di.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/di/vet_farm_di.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/di/super_admin_di.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/di/province_supervisor_di.dart'; +import 'package:rasadyar_chicken/features/jahad/data/di/jahad_di.dart'; import 'package:rasadyar_core/core.dart'; GetIt diChicken = GetIt.asNewInstance(); @@ -40,7 +36,7 @@ Future setupChickenDI() async { }, clearTokenCallback: () async { await tokenService.deleteModuleTokens(Module.chicken); - Get.offAllNamed(ChickenRoutes.auth, arguments: Module.chicken); + Get.offAllNamed(CommonRoutes.auth, arguments: Module.chicken); }, ), instanceName: 'chickenInterceptor', @@ -60,47 +56,42 @@ Future setupChickenDI() async { final dioRemote = diChicken.get(); await dioRemote.init(); - diChicken.registerLazySingleton( - () => AuthRemoteDataSourceImp(dioRemote), - ); + // Setup common feature DI + await setupCommonDI(diChicken, dioRemote); - diChicken.registerLazySingleton( - () => AuthRepositoryImpl(diChicken.get()), - ); + // Setup poultry_science feature DI + await setupPoultryScienceDI(diChicken, dioRemote); - diChicken.registerLazySingleton( - () => ChickenRemoteDatasourceImp(diChicken.get()), - ); + // Setup steward feature DI + await setupStewardDI(diChicken, dioRemote); - diChicken.registerLazySingleton( - () => ChickenLocalDataSourceImp(), - ); + // Setup province_operator feature DI + await setupProvinceOperatorDI(diChicken, dioRemote); - diChicken.registerLazySingleton( - () => ChickenRepositoryImp( - remote: diChicken.get(), - local: diChicken.get(), - ), - ); + // Setup province_inspector feature DI + await setupProvinceInspectorDI(diChicken, dioRemote); - diChicken.registerLazySingleton( - () => PoultryScienceRemoteDatasourceImp(diChicken.get()), - ); + // Setup city_jahad feature DI + await setupCityJahadDI(diChicken, dioRemote); - diChicken.registerLazySingleton( - () => PoultryScienceRepositoryImp( - diChicken.get(), - ), - ); + // Setup vet_farm feature DI + await setupVetFarmDI(diChicken, dioRemote); + + // Setup super_admin feature DI + await setupSuperAdminDI(diChicken, dioRemote); + + // Setup province_supervisor feature DI + await setupProvinceSupervisorDI(diChicken, dioRemote); + + // Setup jahad feature DI + await setupJahadDI(diChicken, dioRemote); //region kill house module DI diChicken.registerLazySingleton( () => KillHouseRemoteDataSourceImpl(diChicken.get()), ); diChicken.registerLazySingleton( - () => KillHouseRepositoryImpl( - diChicken.get(), - ), + () => KillHouseRepositoryImpl(diChicken.get()), ); //endregion } @@ -108,35 +99,26 @@ Future setupChickenDI() async { Future newSetupAuthDI(String newUrl) async { var tokenService = Get.find(); - // همیشه baseUrl جدید رو ذخیره کن await tokenService.saveBaseUrl(Module.chicken, newUrl); - // Re-register AppInterceptor - if (diChicken.isRegistered( - instanceName: 'chickenInterceptor', - )) { - await diChicken.unregister( - instanceName: 'chickenInterceptor', - ); - } + // پاک‌سازی DI مخصوص ماژول مرغ + await diChicken.resetScope(); + diChicken.pushNewScope(); + + // --- Re-register AppInterceptor diChicken.registerLazySingleton( () => AppInterceptor( refreshTokenCallback: () async => null, - saveTokenCallback: (String newToken) async { - // await tokenService.saveAccessToken(newToken); - }, + saveTokenCallback: (newToken) async {}, clearTokenCallback: () async { await tokenService.deleteModuleTokens(Module.chicken); - Get.offAllNamed(ChickenRoutes.auth, arguments: Module.chicken); + Get.offAllNamed(CommonRoutes.auth, arguments: Module.chicken); }, ), instanceName: 'chickenInterceptor', ); - // Re-register DioRemote - if (diChicken.isRegistered()) { - await diChicken.unregister(); - } + // --- Re-register DioRemote diChicken.registerLazySingleton( () => DioRemote( baseUrl: newUrl, @@ -145,35 +127,21 @@ Future newSetupAuthDI(String newUrl) async { ), ), ); + final dioRemote = diChicken.get(); await dioRemote.init(); - // Re-register dependent layers - await reRegister( - () => AuthRemoteDataSourceImp(dioRemote), - ); - await reRegister( - () => AuthRepositoryImpl(diChicken.get()), - ); - await reRegister( - () => ChickenRemoteDatasourceImp(dioRemote), - ); - await reRegister(() => ChickenLocalDataSourceImp()); - await reRegister( - () => ChickenRepositoryImp( - remote: diChicken.get(), - local: diChicken.get(), - ), - ); - - await reRegister( - () => PoultryScienceRemoteDatasourceImp(dioRemote), - ); - await reRegister( - () => PoultryScienceRepositoryImp( - diChicken.get(), - ), - ); + // --- common, poultry_science, steward, and other features + await setupCommonDI(diChicken, dioRemote); + await setupPoultryScienceDI(diChicken, dioRemote); + await setupStewardDI(diChicken, dioRemote); + await setupProvinceOperatorDI(diChicken, dioRemote); + await setupProvinceInspectorDI(diChicken, dioRemote); + await setupCityJahadDI(diChicken, dioRemote); + await setupVetFarmDI(diChicken, dioRemote); + await setupSuperAdminDI(diChicken, dioRemote); + await setupProvinceSupervisorDI(diChicken, dioRemote); + await setupJahadDI(diChicken, dioRemote); } Future reRegister(T Function() factory) async { diff --git a/packages/chicken/lib/data/repositories/chicken/chicken_repository.dart b/packages/chicken/lib/data/repositories/chicken/chicken_repository.dart deleted file mode 100644 index 0f35283..0000000 --- a/packages/chicken/lib/data/repositories/chicken/chicken_repository.dart +++ /dev/null @@ -1,224 +0,0 @@ -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart'; -import 'package:rasadyar_chicken/data/models/request/change_password/change_password_request_model.dart'; -import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart'; -import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; -import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart'; -import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; -import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart'; -import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; -import 'package:rasadyar_chicken/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; -import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/imported_loads_model/imported_loads_model.dart'; -import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.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/segmentation_model/segmentation_model.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart' - hide ProductModel; -import 'package:rasadyar_core/core.dart'; - -import '../../models/request/create_steward_free_bar/create_steward_free_bar.dart'; - -abstract class ChickenRepository { - //region Remote - Future?> getRolesProducts({ - required String token, - CancelToken? cancelToken, - Map? queryParameters, - }); - - //region Steward - - Future getKillHouseDistributionInfo({ - required String token, - }); - - Future getGeneralBarInformation({ - required String token, - Map? queryParameters, - }); - - Future?> getWaitingArrivals({ - required String token, - Map? queryParameters, - }); - - Future setSateForArrivals({ - required String token, - required Map request, - }); - - Future?> getImportedLoadsModel({ - required String token, - Map? queryParameters, - }); - - Future?> getAllocatedMade({ - required String token, - Map? queryParameters, - }); - - Future confirmAllocation({ - required String token, - required Map allocation, - }); - - Future denyAllocation({ - required String token, - required String allocationToken, - }); - - Future confirmAllAllocation({ - required String token, - required List allocationTokens, - }); - - Future?> getGuilds({ - required String token, - Map? queryParameters, - }); - - Future getProfile({required String token}); - - Future postSubmitStewardAllocation({ - required String token, - required SubmitStewardAllocation request, - }); - - Future deleteStewardAllocation({ - required String token, - Map? queryParameters, - }); - - Future updateStewardAllocation({ - required String token, - required ConformAllocation request, - }); - - Future getStewardDashboard({ - required String token, - required String stratDate, - required String endDate, - }); - - Future getDashboardKillHouseFreeBar({ - required String token, - required String stratDate, - required String endDate, - }); - - Future?> - getStewardPurchasesOutSideOfTheProvince({ - required String token, - Map? queryParameters, - }); - - Future createStewardPurchasesOutSideOfTheProvince({ - required String token, - required CreateStewardFreeBar body, - }); - - Future editStewardPurchasesOutSideOfTheProvince({ - required String token, - required CreateStewardFreeBar body, - }); - - Future deleteStewardPurchasesOutSideOfTheProvince({ - required String token, - Map? queryParameters, - }); - - Future?> - getOutProvinceCarcassesBuyer({ - required String token, - Map? queryParameters, - }); - - Future createOutProvinceCarcassesBuyer({ - required String token, - required OutProvinceCarcassesBuyer body, - }); - - Future?> getProvince({CancelToken? cancelToken}); - - Future?> getCity({required String provinceName}); - - Future?> getStewardFreeSaleBar({ - required String token, - Map? queryParameters, - }); - - Future createOutProvinceStewardFreeBar({ - required String token, - required StewardFreeSaleBarRequest body, - }); - - Future updateOutProvinceStewardFreeBar({ - required String token, - required StewardFreeSaleBarRequest body, - }); - - Future deleteOutProvinceStewardFreeBar({ - required String token, - required String key, - }); - - Future getUserProfile({required String token}); - - Future updateUserProfile({ - required String token, - required UserProfile userProfile, - }); - - Future updatePassword({ - required String token, - required ChangePasswordRequestModel model, - }); - - Future?> getSegmentation({ - required String token, - 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, - }); - - Future getBroadcastPrice({required String token}); - - Future getStewardSalesInfoDashboard({ - required String token, - Map? queryParameters, - }); - - Future getStewardRemainWeight({required String token}); - - //endregion - - //endregion - - //region local - Future initWidleyUsed(); - - WidelyUsedLocalModel? getAllWidely(); - //endregion -} diff --git a/packages/chicken/lib/data/repositories/chicken/chicken_repository_imp.dart b/packages/chicken/lib/data/repositories/chicken/chicken_repository_imp.dart deleted file mode 100644 index d9f280a..0000000 --- a/packages/chicken/lib/data/repositories/chicken/chicken_repository_imp.dart +++ /dev/null @@ -1,434 +0,0 @@ -import 'package:rasadyar_chicken/data/data_source/local/chicken_local.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/chicken/chicken_remote.dart'; -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart'; -import 'package:rasadyar_chicken/data/models/request/change_password/change_password_request_model.dart'; -import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart'; -import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; -import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart'; -import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; -import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart'; -import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; -import 'package:rasadyar_chicken/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; -import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/imported_loads_model/imported_loads_model.dart'; -import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.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/segmentation_model/segmentation_model.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart' - hide ProductModel; -import 'package:rasadyar_core/core.dart'; - -import 'chicken_repository.dart'; - -class ChickenRepositoryImp implements ChickenRepository { - final ChickenRemoteDatasource remote; - final ChickenLocalDataSource local; - - ChickenRepositoryImp({required this.remote, required this.local}); - - //region Remote - - @override - Future getKillHouseDistributionInfo({ - required String token, - }) async { - var res = await remote.getKillHouseDistributionInfo(token: token); - return res; - } - - @override - Future getGeneralBarInformation({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getGeneralBarInformation( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future?> getWaitingArrivals({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getWaitingArrivals( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future setSateForArrivals({ - required String token, - required Map request, - }) async { - await remote.setSateForArrivals(token: token, request: request); - } - - @override - Future?> getImportedLoadsModel({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getImportedLoadsModel( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future?> getAllocatedMade({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getAllocatedMade( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future confirmAllocation({ - required String token, - required Map allocation, - }) async { - await remote.confirmAllocation(token: token, allocation: allocation); - } - - @override - Future denyAllocation({ - required String token, - required String allocationToken, - }) async { - await remote.denyAllocation(token: token, allocationToken: allocationToken); - } - - @override - Future confirmAllAllocation({ - required String token, - required List allocationTokens, - }) async { - await remote.confirmAllAllocation( - token: token, - allocationTokens: allocationTokens, - ); - } - - @override - Future?> getRolesProducts({ - required String token, - CancelToken? cancelToken, - Map? queryParameters, - }) async { - var res = await remote.getRolesProducts( - token: token, - cancelToken: cancelToken, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future?> getGuilds({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getGuilds( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future getProfile({required String token}) async { - var res = await remote.getProfile(token: token); - return res; - } - - @override - Future postSubmitStewardAllocation({ - required String token, - required SubmitStewardAllocation request, - }) async { - await remote.postSubmitStewardAllocation(token: token, request: request); - } - - @override - Future deleteStewardAllocation({ - required String token, - Map? queryParameters, - }) async { - await remote.deleteStewardAllocation( - token: token, - queryParameters: queryParameters, - ); - } - - @override - Future updateStewardAllocation({ - required String token, - required ConformAllocation request, - }) async { - await remote.updateStewardAllocation(token: token, request: request); - } - - @override - Future getStewardDashboard({ - required String token, - required String stratDate, - required String endDate, - }) async { - var res = await remote.getStewardDashboard( - token: token, - stratDate: stratDate, - endDate: endDate, - ); - return res; - } - - @override - Future getDashboardKillHouseFreeBar({ - required String token, - required String stratDate, - required String endDate, - }) async { - var res = await remote.getDashboardKillHouseFreeBar( - token: token, - stratDate: stratDate, - endDate: endDate, - ); - return res; - } - - @override - Future?> - getStewardPurchasesOutSideOfTheProvince({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getStewardPurchasesOutSideOfTheProvince( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future?> getCity({ - required String provinceName, - }) async { - var res = await remote.getCity(provinceName: provinceName); - return res; - } - - @override - Future?> getProvince({ - CancelToken? cancelToken, - }) async { - var res = await remote.getProvince(cancelToken: cancelToken); - return res; - } - - @override - Future createStewardPurchasesOutSideOfTheProvince({ - required String token, - required CreateStewardFreeBar body, - }) async { - await remote.createStewardPurchasesOutSideOfTheProvince( - token: token, - body: body, - ); - } - - @override - Future editStewardPurchasesOutSideOfTheProvince({ - required String token, - required CreateStewardFreeBar body, - }) async { - return await remote.editStewardPurchasesOutSideOfTheProvince( - token: token, - queryParameters: body.toJson() - ..removeWhere((key, value) => value == null), - ); - } - - @override - Future deleteStewardPurchasesOutSideOfTheProvince({ - required String token, - Map? queryParameters, - }) async { - await remote.deleteStewardPurchasesOutSideOfTheProvince( - token: token, - queryParameters: queryParameters, - ); - } - - @override - Future?> - getOutProvinceCarcassesBuyer({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getOutProvinceCarcassesBuyer( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future createOutProvinceCarcassesBuyer({ - required String token, - required OutProvinceCarcassesBuyer body, - }) async { - await remote.createOutProvinceCarcassesBuyer(token: token, body: body); - } - - @override - Future?> getStewardFreeSaleBar({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getStewardFreeSaleBar( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future createOutProvinceStewardFreeBar({ - required String token, - required StewardFreeSaleBarRequest body, - }) async { - await remote.createOutProvinceStewardFreeBar(token: token, body: body); - } - - @override - Future updateOutProvinceStewardFreeBar({ - required String token, - required StewardFreeSaleBarRequest body, - }) async { - await remote.updateOutProvinceStewardFreeBar(token: token, body: body); - } - - @override - Future deleteOutProvinceStewardFreeBar({ - required String token, - required String key, - }) async { - await remote.deleteOutProvinceStewardFreeBar(token: token, key: key); - } - - @override - Future getUserProfile({required String token}) async { - var res = await remote.getUserProfile(token: token); - return res; - } - - @override - Future updateUserProfile({ - required String token, - required UserProfile userProfile, - }) async { - await remote.updateUserProfile(token: token, userProfile: userProfile); - } - - @override - Future updatePassword({ - required String token, - required ChangePasswordRequestModel model, - }) async { - await remote.updatePassword(token: token, model: model); - } - - @override - Future?> getSegmentation({ - required String token, - Map? queryParameters, - }) async { - var res = await remote.getSegmentation( - token: token, - queryParameters: queryParameters, - ); - return res; - } - - @override - Future createSegmentation({ - required String token, - required SegmentationModel model, - }) async { - await remote.createSegmentation(token: token, model: model); - } - - @override - Future editSegmentation({ - required String token, - required SegmentationModel model, - }) async { - await remote.editSegmentation(token: token, model: model); - } - - @override - Future deleteSegmentation({ - required String token, - required String key, - }) async { - var res = await remote.deleteSegmentation(token: token, key: key); - return res; - } - - @override - Future getBroadcastPrice({required String token}) async { - var res = await remote.getBroadcastPrice(token: token); - return res; - } - - //endregion - - //region local - @override - WidelyUsedLocalModel? getAllWidely() => local.getAllWidely(); - - @override - Future initWidleyUsed() async { - await local.initWidleyUsed(); - } - - @override - Future getStewardSalesInfoDashboard({ - required String token, - Map? queryParameters, - }) async { - return await remote.getStewardSalesInfoDashboard( - token: token, - queryParameters: queryParameters, - ); - } - - @override - Future getStewardRemainWeight({ - required String token, - }) async { - return await remote.getStewardRemainWeight(token: token); - } - - //endregion -} diff --git a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository.dart b/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository.dart deleted file mode 100644 index f1546fc..0000000 --- a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart'; -import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; -import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart'; -import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart'; -import 'package:rasadyar_core/core.dart'; - -abstract class PoultryScienceRepository { - Future getHomePoultry({required String token, required String type}); - - Future?> getHatchingPoultry({ - required String token, - Map? queryParameters, - }); - - - Future submitPoultryScienceReport({ - required String token, - required FormData data, - ProgressCallback? onSendProgress, - }); - - - Future?> getHatchingPoultryReport({ - required String token, - Map? queryParameters, - }); - - Future?> getPoultryScienceFarmList({ - required String token, - Map? queryParameters, - }); - - Future getApprovedPrice({ required String token, - Map? queryParameters,}); - - - Future?> getAllPoultry({ - required String token, - Map? queryParameters, - }); - - - Future getSellForFreezing({ - required String token, - Map? queryParameters, - }); - - - Future getPoultryExport({ - required String token, - Map? queryParameters, - }); - - Future?> getUserPoultry({ - required String token, - Map? queryParameters, - }); - - Future?> getPoultryHatching({ - required String token, - Map? queryParameters, - }); - - Future?> getKillHouseList({ - required String token, - Map? queryParameters, - }); - - Future submitKillRegistration({ - required String token, - required KillRegistrationRequest request, - }); - - Future?> getPoultryOderList({ - required String token, - Map? queryParameters, - }); - Future deletePoultryOder({ - required String token, - required String orderId, - }); -} diff --git a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository_imp.dart b/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository_imp.dart deleted file mode 100644 index 7bbed7c..0000000 --- a/packages/chicken/lib/data/repositories/poultry_science/poultry_science_repository_imp.dart +++ /dev/null @@ -1,145 +0,0 @@ -import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote.dart'; -import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart'; -import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; -import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart'; -import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart'; -import 'package:rasadyar_core/core.dart'; - -import 'poultry_science_repository.dart'; - -class PoultryScienceRepositoryImp implements PoultryScienceRepository { - final PoultryScienceRemoteDatasource datasource; - - PoultryScienceRepositoryImp(this.datasource); - - @override - Future getHomePoultry({ - required String token, - required String type, - }) async => await datasource.getHomePoultryScience(token: token, type: type); - - @override - Future?> getHatchingPoultry({ - required String token, - Map? queryParameters, - }) async => await datasource.getHatchingPoultry(token: token, queryParameters: queryParameters); - - @override - Future submitPoultryScienceReport({ - required String token, - required FormData data, - ProgressCallback? onSendProgress, - }) async => await datasource.submitPoultryScienceReport( - token: token, - data: data, - onSendProgress: onSendProgress, - ); - - @override - Future?> getHatchingPoultryReport({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getPoultryScienceReport(token: token, queryParameters: queryParameters); - } - - @override - Future?> getPoultryScienceFarmList({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getPoultryScienceFarmList( - token: token, - queryParameters: queryParameters, - ); - } - - @override - Future getApprovedPrice({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getApprovedPrice(token: token, queryParameters: queryParameters); - } - - @override - Future?> getAllPoultry({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getAllPoultry(token: token, queryParameters: queryParameters); - } - - @override - Future getPoultryExport({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getPoultryExport(token: token, queryParameters: queryParameters); - } - - @override - Future getSellForFreezing({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getSellForFreezing(token: token, queryParameters: queryParameters); - } - - @override - Future?> getUserPoultry({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getUserPoultry(token: token, queryParameters: queryParameters); - } - - @override - Future?> getPoultryHatching({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getPoultryHatching(token: token, queryParameters: queryParameters); - } - - @override - Future?> getKillHouseList({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getKillHouseList(token: token, queryParameters: queryParameters); - } - - @override - Future submitKillRegistration({ - required String token, - required KillRegistrationRequest request, - }) async { - await datasource.submitKillRegistration(token: token, request: request); - } - - @override - Future?> getPoultryOderList({ - required String token, - Map? queryParameters, - }) async { - return await datasource.getPoultryOderList(token: token, queryParameters: queryParameters); - } - - @override - Future deletePoultryOder({ - required String token, - required String orderId, - }) async { - await datasource.deletePoultryOder(token: token, orderId: orderId); - } -} diff --git a/packages/chicken/lib/features/city_jahad/city_jahad.dart b/packages/chicken/lib/features/city_jahad/city_jahad.dart new file mode 100644 index 0000000..f61a0e6 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/city_jahad.dart @@ -0,0 +1,3 @@ +export 'data/di/city_jahad_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source.dart b/packages/chicken/lib/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source.dart new file mode 100644 index 0000000..98583e6 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class CityJahadRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source_impl.dart b/packages/chicken/lib/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source_impl.dart new file mode 100644 index 0000000..94950cf --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source_impl.dart @@ -0,0 +1,39 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityJahadRemoteDataSourceImpl implements CityJahadRemoteDataSource { + final DioRemote _httpClient; + + CityJahadRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} diff --git a/packages/chicken/lib/features/city_jahad/data/di/city_jahad_di.dart b/packages/chicken/lib/features/city_jahad/data/di/city_jahad_di.dart new file mode 100644 index 0000000..76fd618 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/data/di/city_jahad_di.dart @@ -0,0 +1,36 @@ +import 'package:rasadyar_chicken/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/repositories/city_jahad_repository.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/repositories/city_jahad_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for city_jahad feature +Future setupCityJahadDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => CityJahadRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => CityJahadRepositoryImpl(di.get()), + ); +} + +/// Re-register city_jahad dependencies (used when base URL changes) +Future reRegisterCityJahadDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => CityJahadRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => CityJahadRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/city_jahad/data/repositories/city_jahad_repository.dart b/packages/chicken/lib/features/city_jahad/data/repositories/city_jahad_repository.dart new file mode 100644 index 0000000..bd0e67a --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/data/repositories/city_jahad_repository.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class CityJahadRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/city_jahad/data/repositories/city_jahad_repository_impl.dart b/packages/chicken/lib/features/city_jahad/data/repositories/city_jahad_repository_impl.dart new file mode 100644 index 0000000..fabb064 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/data/repositories/city_jahad_repository_impl.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/datasources/remote/city_jahad_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/repositories/city_jahad_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityJahadRepositoryImpl implements CityJahadRepository { + final CityJahadRemoteDataSource _remote; + + CityJahadRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..7809be9 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,95 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + CityJahadRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'CityJahad', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..9f8d12a --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/active_hatching/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: cityJahadActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart new file mode 100644 index 0000000..dc3671a --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/home/logic.dart @@ -0,0 +1,29 @@ +import 'package:rasadyar_chicken/features/city_jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityJahadActionItem { + final String title; + final String route; + final String icon; + + CityJahadActionItem({ + required this.title, + required this.route, + required this.icon, + }); +} + +class CityJahadHomeLogic extends GetxController { + RxList items = [ + CityJahadActionItem( + title: "جوجه ریزی فعال", + route: CityJahadRoutes.activeHatchingCityJahad, + icon: Assets.vec.activeFramSvg.path, + ), + CityJahadActionItem( + title: "بازرسی مزارع طیور", + route: CityJahadRoutes.newInspectionCityJahad, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/home/view.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/home/view.dart new file mode 100644 index 0000000..7425760 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/home/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class CityJahadHomePage extends GetView { + CityJahadHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: cityJahadActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..ceb6f4f --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,160 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + CityJahadRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.cityJahadRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'CityJahad', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..ea77f82 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: cityJahadActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/root/logic.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/root/logic.dart new file mode 100644 index 0000000..6117f02 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/root/logic.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/city_jahad/data/repositories/city_jahad_repository.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class CityJahadRootLogic extends GetxController { + var tokenService = Get.find(); + + late CityJahadRepository cityJahadRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(cityJahadActionKey), + onGenerateRoute: (settings) { + final page = CityJahadPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => CityJahadPages.pages.firstWhere( + (e) => e.name == CityJahadRoutes.homeCityJahad, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + cityJahadRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/pages/root/view.dart b/packages/chicken/lib/features/city_jahad/presentation/pages/root/view.dart new file mode 100644 index 0000000..d2753c1 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/pages/root/view.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class CityJahadRootPage extends GetView { + const CityJahadRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + cityJahadActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + cityJahadActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/routes/pages.dart b/packages/chicken/lib/features/city_jahad/presentation/routes/pages.dart new file mode 100644 index 0000000..8035307 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/routes/pages.dart @@ -0,0 +1,66 @@ +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/city_jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class CityJahadPages { + CityJahadPages._(); + + static List get pages => [ + GetPage( + name: CityJahadRoutes.initCityJahad, + page: () => CityJahadRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => CityJahadRootLogic()); + Get.lazyPut(() => CityJahadHomeLogic()); + }), + ], + ), + GetPage( + name: CityJahadRoutes.homeCityJahad, + page: () => CityJahadHomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(CityJahadHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + + GetPage( + name: CityJahadRoutes.activeHatchingCityJahad, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: CityJahadRoutes.newInspectionCityJahad, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/city_jahad/presentation/routes/routes.dart b/packages/chicken/lib/features/city_jahad/presentation/routes/routes.dart new file mode 100644 index 0000000..5415f55 --- /dev/null +++ b/packages/chicken/lib/features/city_jahad/presentation/routes/routes.dart @@ -0,0 +1,10 @@ +sealed class CityJahadRoutes { + CityJahadRoutes._(); + + static const _base = '/chicken/cityJahad'; + static const initCityJahad = '$_base/'; + static const homeCityJahad = '$_base/home'; + static const actionCityJahad = '$_base/action'; + static const activeHatchingCityJahad = '$_base/activeHatching'; + static const newInspectionCityJahad = '$_base/newInspection'; +} diff --git a/packages/chicken/lib/features/common/auth/logic.dart b/packages/chicken/lib/features/common/auth/logic.dart index 6c349d6..fa74d23 100644 --- a/packages/chicken/lib/features/common/auth/logic.dart +++ b/packages/chicken/lib/features/common/auth/logic.dart @@ -4,10 +4,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:rasadyar_chicken/data/common/dio_error_handler.dart'; import 'package:rasadyar_chicken/data/di/chicken_di.dart'; -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; -import 'package:rasadyar_chicken/data/repositories/auth/auth_repository.dart'; -import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/auth/auth_repository.dart'; +import 'package:rasadyar_chicken/features/common/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/widget/captcha/logic.dart'; import 'package:rasadyar_core/core.dart'; @@ -28,7 +29,8 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { Rx> formKeySentOtp = GlobalKey().obs; Rx usernameController = TextEditingController().obs; Rx passwordController = TextEditingController().obs; - Rx phoneOtpNumberController = TextEditingController().obs; + Rx phoneOtpNumberController = + TextEditingController().obs; Rx otpCodeController = TextEditingController().obs; var captchaController = Get.find(); @@ -56,12 +58,18 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { void onInit() { super.onInit(); _textAnimationController = - AnimationController(vsync: this, duration: const Duration(milliseconds: 1200)) + AnimationController( + vsync: this, + duration: const Duration(milliseconds: 1200), + ) ..repeat(reverse: true, count: 2).whenComplete(() { showCard.value = true; }); - textAnimation = CurvedAnimation(parent: _textAnimationController, curve: Curves.easeInOut); + textAnimation = CurvedAnimation( + parent: _textAnimationController, + curve: Curves.easeInOut, + ); initUserPassData(); getDeviceModel(); @@ -98,7 +106,8 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { } bool _isFormValid() { - final isCaptchaValid = captchaController.formKey.currentState?.validate() ?? false; + final isCaptchaValid = + captchaController.formKey.currentState?.validate() ?? false; final isFormValid = formKey.currentState?.validate() ?? false; return isCaptchaValid && isFormValid; } @@ -117,13 +126,33 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { onSuccess: (result) async { await gService.saveSelectedModule(_module); await tokenStorageService.saveModule(_module); - await tokenStorageService.saveAccessToken(_module, result?.accessToken ?? ''); - await tokenStorageService.saveRefreshToken(_module, result?.accessToken ?? ''); + await tokenStorageService.saveAccessToken( + _module, + result?.accessToken ?? '', + ); + await tokenStorageService.saveRefreshToken( + _module, + result?.accessToken ?? '', + ); var tmpRoles = result?.role?.where((element) { - final allowedRoles = {'poultryscience', 'steward', 'killhouse'}; + final allowedRoles = { + 'poultryscience', + 'steward', + 'killhouse', + 'provinceinspector', + 'cityjahad', + 'jahad', + 'vetfarm', + 'provincesupervisor', + 'superadmin', + }; + final lowerElement = element.toString().toLowerCase().trim(); return allowedRoles.contains(lowerElement); }).toList(); + if (tmpRoles?.length==1) { + await tokenStorageService.saveRoles(_module, tmpRoles ?? []); + } await tokenStorageService.saveRoles(_module, tmpRoles ?? []); if (rememberMe.value) { @@ -142,11 +171,15 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { }, ); - if (tmpRoles!.length > 1) { - Get.offAndToNamed(ChickenRoutes.role); + + Get.offAndToNamed(CommonRoutes.role); + + +/* if (tmpRoles!.length > 1) { + Get.offAndToNamed(CommonRoutes.role); } else { - Get.offAllNamed(ChickenRoutes.initSteward); - } + Get.offAllNamed(StewardRoutes.initSteward); + } */ }, onError: (error, stackTrace) { if (error is DioException) { @@ -183,7 +216,9 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { } void initUserPassData() { - UserLocalModel? userLocalModel = tokenStorageService.getUserLocal(Module.chicken); + UserLocalModel? userLocalModel = tokenStorageService.getUserLocal( + Module.chicken, + ); if (userLocalModel?.username != null && userLocalModel?.password != null) { usernameController.value.text = userLocalModel?.username ?? ''; passwordController.value.text = userLocalModel?.password ?? ''; @@ -196,18 +231,14 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin { if (Platform.isAndroid) { final info = await deviceInfo.androidInfo; - print('Device: ${info.manufacturer} ${info.model}'); - print('Android version: ${info.version.release}'); + deviceName.value = 'Device:${info.manufacturer} Model:${info.model} version ${info.version.release}'; } else if (Platform.isIOS) { final info = await deviceInfo.iosInfo; - print('Device: ${info.utsname.machine} (${info.name})'); - print('System version: ${info.systemVersion}'); + deviceName.value = 'Device:${info.utsname.machine} Model:${info.model} version ${info.systemVersion}'; - } else { - print('Unsupported platform'); - } + } else {} } } diff --git a/packages/chicken/lib/features/common/auth/view.dart b/packages/chicken/lib/features/common/auth/view.dart index fae7a03..8e52e08 100644 --- a/packages/chicken/lib/features/common/auth/view.dart +++ b/packages/chicken/lib/features/common/auth/view.dart @@ -43,12 +43,16 @@ class AuthPage extends GetView { Text( 'به سامانه رصدطیور خوش آمدید!', textAlign: TextAlign.right, - style: AppFonts.yekan25Bold.copyWith(color: AppColor.darkGreyDarkActive), + style: AppFonts.yekan25Bold.copyWith( + color: AppColor.darkGreyDarkActive, + ), ), Text( 'سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالا های اساسی', textAlign: TextAlign.center, - style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkActive), + style: AppFonts.yekan16.copyWith( + color: AppColor.darkGreyDarkActive, + ), ), ], ), @@ -80,7 +84,9 @@ class AuthPage extends GetView { vecPath: Assets.vec.rasadToyorSvg.path, width: 85.w, height: 85.h, - titleStyle: AppFonts.yekan20Bold.copyWith(color: Color(0xFF4665AF)), + titleStyle: AppFonts.yekan20Bold.copyWith( + color: Color(0xFF4665AF), + ), title: 'رصدطیور', ), SizedBox(height: 20.h), @@ -91,7 +97,9 @@ class AuthPage extends GetView { children: [ TextSpan( text: 'مطالعه بیانیه ', - style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDark), + style: AppFonts.yekan16.copyWith( + color: AppColor.darkGreyDark, + ), ), TextSpan( recognizer: TapGestureRecognizer() @@ -104,7 +112,9 @@ class AuthPage extends GetView { ); }, text: 'حریم خصوصی', - style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan16.copyWith( + color: AppColor.blueNormal, + ), ), ], ), @@ -128,6 +138,7 @@ class AuthPage extends GetView { child: Column( children: [ RTextField( + height: 40.h, label: 'نام کاربری', maxLength: 11, maxLines: 1, @@ -150,7 +161,8 @@ class AuthPage extends GetView { padding: const EdgeInsets.fromLTRB(0, 8, 6, 8), child: Assets.vec.callSvg.svg(width: 12, height: 12), ), - suffixIcon: controller.usernameController.value.text.trim().isNotEmpty + suffixIcon: + controller.usernameController.value.text.trim().isNotEmpty ? clearButton(() { controller.usernameController.value.clear(); controller.usernameController.refresh(); @@ -165,7 +177,9 @@ class AuthPage extends GetView { return null; }, style: AppFonts.yekan13, - errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal), + errorStyle: AppFonts.yekan13.copyWith( + color: AppColor.redNormal, + ), labelStyle: AppFonts.yekan13, boxConstraints: const BoxConstraints( maxHeight: 40, @@ -177,6 +191,7 @@ class AuthPage extends GetView { const SizedBox(height: 26), ObxValue( (passwordController) => RTextField( + height: 40.h, label: 'رمز عبور', filled: false, obscure: true, @@ -199,7 +214,9 @@ class AuthPage extends GetView { return null; }, style: AppFonts.yekan13, - errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal), + errorStyle: AppFonts.yekan13.copyWith( + color: AppColor.redNormal, + ), labelStyle: AppFonts.yekan13, prefixIcon: Padding( padding: const EdgeInsets.fromLTRB(0, 8, 8, 8), @@ -226,19 +243,26 @@ class AuthPage extends GetView { ObxValue((data) { return Checkbox( materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - visualDensity: VisualDensity(horizontal: -4, vertical: 4), + visualDensity: VisualDensity( + horizontal: -4, + vertical: 4, + ), tristate: true, value: data.value, onChanged: (value) { data.value = value ?? false; }, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), activeColor: AppColor.blueNormal, ); }, controller.rememberMe), Text( 'مرا به خاطر بسپار', - style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark), + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDark, + ), ), ], ), @@ -283,11 +307,16 @@ class AuthPage extends GetView { children: [ Text( 'بيانيه حريم خصوصی', - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), ), Text( 'اطلاعات مربوط به هر شخص، حریم خصوصی وی محسوب می‌شود. حفاظت و حراست از اطلاعات شخصی در سامانه رصد یار، نه تنها موجب حفظ امنیت کاربران می‌شود، بلکه باعث اعتماد بیشتر و مشارکت آنها در فعالیت‌های جاری می‌گردد. هدف از این بیانیه، آگاه ساختن شما درباره ی نوع و نحوه ی استفاده از اطلاعاتی است که در هنگام استفاده از سامانه رصد یار ، از جانب شما دریافت می‌گردد. شرکت هوشمند سازان خود را ملزم به رعایت حریم خصوصی همه شهروندان و کاربران سامانه دانسته و آن دسته از اطلاعات کاربران را که فقط به منظور ارائه خدمات کفایت می‌کند، دریافت کرده و از انتشار آن یا در اختیار قرار دادن آن به دیگران خودداری مینماید.', - style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8), + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + height: 1.8, + ), ), ], ), @@ -307,7 +336,9 @@ class AuthPage extends GetView { children: [ Text( 'چگونگی جمع آوری و استفاده از اطلاعات کاربران', - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), ), Text( '''الف: اطلاعاتی که شما خود در اختيار این سامانه قرار می‌دهيد، شامل موارد زيرهستند: @@ -319,7 +350,10 @@ class AuthPage extends GetView { ⦁ تعداد بازدیدهای روزانه در درگاه. ⦁ هدف ما از دریافت این اطلاعات استفاده از آنها در تحلیل عملکرد کاربران درگاه می باشد تا بتوانیم در خدمت رسانی بهتر عمل کنیم. ''', - style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8), + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + height: 1.8, + ), ), ], ), @@ -339,11 +373,16 @@ class AuthPage extends GetView { children: [ Text( 'امنیت اطلاعات', - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), ), Text( 'متعهدیم که امنیت اطلاعات شما را تضمین نماییم و برای جلوگیری از هر نوع دسترسی غیرمجاز و افشای اطلاعات شما از همه شیوه‌‌های لازم استفاده می‌کنیم تا امنیت اطلاعاتی را که به صورت آنلاین گردآوری می‌کنیم، حفظ شود. لازم به ذکر است در سامانه ما، ممکن است به سایت های دیگری لینک شوید، وقتی که شما از طریق این لینک‌ها از سامانه ما خارج می‌شوید، توجه داشته باشید که ما بر دیگر سایت ها کنترل نداریم و سازمان تعهدی بر حفظ حریم شخصی آنان در سایت مقصد نخواهد داشت و مراجعه کنندگان میبایست به بیانیه حریم شخصی آن سایت ها مراجعه نمایند.', - style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8), + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + height: 1.8, + ), ), ], ), diff --git a/packages/chicken/lib/features/common/common.dart b/packages/chicken/lib/features/common/common.dart new file mode 100644 index 0000000..7aa6fff --- /dev/null +++ b/packages/chicken/lib/features/common/common.dart @@ -0,0 +1,2 @@ +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/data/data_source/local/chicken_local.dart b/packages/chicken/lib/features/common/data/datasources/local/chicken_local.dart similarity index 59% rename from packages/chicken/lib/data/data_source/local/chicken_local.dart rename to packages/chicken/lib/features/common/data/datasources/local/chicken_local.dart index e02478a..1c0a6e0 100644 --- a/packages/chicken/lib/data/data_source/local/chicken_local.dart +++ b/packages/chicken/lib/features/common/data/datasources/local/chicken_local.dart @@ -1,4 +1,4 @@ -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; abstract class ChickenLocalDataSource { Future openBox(); diff --git a/packages/chicken/lib/data/data_source/local/chicken_local_imp.dart b/packages/chicken/lib/features/common/data/datasources/local/chicken_local_imp.dart similarity index 81% rename from packages/chicken/lib/data/data_source/local/chicken_local_imp.dart rename to packages/chicken/lib/features/common/data/datasources/local/chicken_local_imp.dart index f66c786..20053ff 100644 --- a/packages/chicken/lib/data/data_source/local/chicken_local_imp.dart +++ b/packages/chicken/lib/features/common/data/datasources/local/chicken_local_imp.dart @@ -1,4 +1,5 @@ -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_core/core.dart'; import 'chicken_local.dart'; @@ -22,7 +23,7 @@ class ChickenLocalDataSourceImp implements ChickenLocalDataSource { color: AppColor.greenLightActive.toARGB32(), iconColor: AppColor.greenNormal.toARGB32(), iconPath: Assets.vec.cubeSearchSvg.path, - path: ChickenRoutes.buysInProvinceSteward, + path: StewardRoutes.buysInProvinceSteward, ), WidelyUsedLocalItem( index: 1, @@ -31,7 +32,7 @@ class ChickenLocalDataSourceImp implements ChickenLocalDataSource { color: AppColor.blueLightActive.toARGB32(), iconColor: AppColor.blueNormal.toARGB32(), iconPath: Assets.vec.cubeSvg.path, - path: ChickenRoutes.salesInProvinceSteward, + path: StewardRoutes.salesInProvinceSteward, ), WidelyUsedLocalItem( @@ -40,7 +41,7 @@ class ChickenLocalDataSourceImp implements ChickenLocalDataSource { color: AppColor.blueLightActive.toARGB32(), iconColor: AppColor.blueNormal.toARGB32(), iconPath: Assets.vec.cubeRotateSvg.path, - path: ChickenRoutes.buysInProvinceSteward, + path: StewardRoutes.buysInProvinceSteward, ), ]; */ } diff --git a/packages/chicken/lib/data/data_source/remote/auth/auth_remote.dart b/packages/chicken/lib/features/common/data/datasources/remote/auth/auth_remote.dart similarity index 51% rename from packages/chicken/lib/data/data_source/remote/auth/auth_remote.dart rename to packages/chicken/lib/features/common/data/datasources/remote/auth/auth_remote.dart index c42add7..da26686 100644 --- a/packages/chicken/lib/data/data_source/remote/auth/auth_remote.dart +++ b/packages/chicken/lib/features/common/data/datasources/remote/auth/auth_remote.dart @@ -1,6 +1,6 @@ -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; abstract class AuthRemoteDataSource { Future login({required Map authRequest}); @@ -11,6 +11,6 @@ abstract class AuthRemoteDataSource { Future getUserInfo(String phoneNumber); - /// Calls `/steward-app-login/` endpoint with required token and `server` as query param, plus optional extra query parameters. + Future stewardAppLogin({required String token, Map? queryParameters}); } diff --git a/packages/chicken/lib/data/data_source/remote/auth/auth_remote_imp.dart b/packages/chicken/lib/features/common/data/datasources/remote/auth/auth_remote_imp.dart similarity index 88% rename from packages/chicken/lib/data/data_source/remote/auth/auth_remote_imp.dart rename to packages/chicken/lib/features/common/data/datasources/remote/auth/auth_remote_imp.dart index a0b85f8..a240cee 100644 --- a/packages/chicken/lib/data/data_source/remote/auth/auth_remote_imp.dart +++ b/packages/chicken/lib/features/common/data/datasources/remote/auth/auth_remote_imp.dart @@ -1,5 +1,5 @@ -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; import 'package:rasadyar_core/core.dart'; import 'auth_remote.dart'; diff --git a/packages/chicken/lib/features/common/data/datasources/remote/common/common_remote.dart b/packages/chicken/lib/features/common/data/datasources/remote/common/common_remote.dart new file mode 100644 index 0000000..b289b38 --- /dev/null +++ b/packages/chicken/lib/features/common/data/datasources/remote/common/common_remote.dart @@ -0,0 +1,75 @@ +import 'package:rasadyar_chicken/features/common/data/model/request/change_password/change_password_request_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/bar_information/bar_information.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild_profile/guild_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class CommonRemoteDatasource { + Future?> getInventory({ + required String token, + CancelToken? cancelToken, + }); + + Future getKillHouseDistributionInfo({ + required String token, + }); + + Future getGeneralBarInformation({ + required String token, + Map? queryParameters, + }); + + Future?> getRolesProducts({required String token}); + + Future?> getGuilds({ + required String token, + Map? queryParameters, + }); + + Future getProfile({required String token}); + + Future?> getProvince({CancelToken? cancelToken}); + + Future?> getCity({required String provinceName}); + + Future getUserProfile({required String token}); + + Future updateUserProfile({ + required String token, + required UserProfile userProfile, + }); + + Future updatePassword({ + required String token, + required ChangePasswordRequestModel model, + }); + + Future?> getSegmentation({ + required String token, + 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, + }); + + Future getBroadcastPrice({required String token}); +} diff --git a/packages/chicken/lib/features/common/data/datasources/remote/common/common_remote_imp.dart b/packages/chicken/lib/features/common/data/datasources/remote/common/common_remote_imp.dart new file mode 100644 index 0000000..f977f40 --- /dev/null +++ b/packages/chicken/lib/features/common/data/datasources/remote/common/common_remote_imp.dart @@ -0,0 +1,238 @@ +import 'package:rasadyar_chicken/features/common/data/model/request/change_password/change_password_request_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/bar_information/bar_information.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild_profile/guild_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'common_remote.dart'; + +class CommonRemoteDatasourceImp implements CommonRemoteDatasource { + final DioRemote _httpClient; + + CommonRemoteDatasourceImp(this._httpClient); + + @override + Future?> getInventory({ + required String token, + CancelToken? cancelToken, + }) async { + var res = await _httpClient.get( + '/roles-products/?role=Steward', + headers: {'Authorization': 'Bearer $token'}, + + fromJsonList: (json) => (json) + .map((item) => InventoryModel.fromJson(item as Map)) + .toList(), + ); + + return res.data; + } + + @override + Future getKillHouseDistributionInfo({ + required String token, + }) async { + var res = await _httpClient.get( + '/kill-house-distribution-info/?role=Steward', + headers: {'Authorization': 'Bearer $token'}, + fromJson: KillHouseDistributionInfo.fromJson, + ); + + return res.data; + } + + @override + Future getGeneralBarInformation({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/bars_for_kill_house_dashboard/', + queryParameters: queryParameters, + headers: {'Authorization': 'Bearer $token'}, + fromJson: BarInformation.fromJson, + ); + return res.data; + } + + @override + Future?> getRolesProducts({required String token}) async { + var res = await _httpClient.get( + '/roles-products/?role=Steward', + headers: {'Authorization': 'Bearer $token'}, + fromJsonList: (json) => json + .map((item) => ProductModel.fromJson(item as Map)) + .toList(), + ); + return res.data; + } + + @override + Future?> getGuilds({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/guilds/', + queryParameters: queryParameters, + headers: {'Authorization': 'Bearer $token'}, + fromJsonList: (json) => json + .map((item) => GuildModel.fromJson(item as Map)) + .toList(), + ); + return res.data; + } + + @override + Future getProfile({required String token}) async { + var res = await _httpClient.get( + '/guilds/0/?profile', + headers: {'Authorization': 'Bearer $token'}, + fromJson: GuildProfile.fromJson, + ); + return res.data; + } + + @override + Future?> getCity({ + required String provinceName, + }) async { + var res = await _httpClient.get( + '/iran_city/', + queryParameters: {'name': provinceName}, + fromJsonList: (json) => json + .map( + (item) => + IranProvinceCityModel.fromJson(item as Map), + ) + .toList(), + ); + return res.data; + } + + @override + Future?> getProvince({ + CancelToken? cancelToken, + }) async { + var res = await _httpClient.get( + '/iran_province/', + fromJsonList: (json) => json + .map( + (item) => + IranProvinceCityModel.fromJson(item as Map), + ) + .toList(), + ); + return res.data; + } + + @override + Future getUserProfile({required String token}) async { + var res = await _httpClient.get( + '/system_user_profile/?self-profile', + headers: {'Authorization': 'Bearer $token'}, + fromJson: (json) => UserProfile.fromJson(json), + ); + + return res.data; + } + + @override + Future updateUserProfile({ + required String token, + required UserProfile userProfile, + }) async { + await _httpClient.put( + '/system_user_profile/0/', + headers: {'Authorization': 'Bearer $token'}, + data: userProfile.toJson()..removeWhere((key, value) => value == null), + ); + } + + @override + Future updatePassword({ + required String token, + required ChangePasswordRequestModel model, + }) async { + await _httpClient.post( + '/api/change_password/', + headers: {'Authorization': 'Bearer $token'}, + data: model.toJson()..removeWhere((key, value) => value == null), + ); + } + + @override + Future?> getSegmentation({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/app-segmentation/', + queryParameters: queryParameters, + headers: {'Authorization': 'Bearer $token'}, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => SegmentationModel.fromJson(json as Map), + ), + ); + 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( + '/app-segmentation/0/', + data: model.toJson()..removeWhere((key, value) => value == null), + headers: {'Authorization': 'Bearer $token'}, + ); + } + + @override + Future 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; + } + + @override + Future getBroadcastPrice({required String token}) async { + var res = await _httpClient.get( + '/broadcast-price/', + headers: {'Authorization': 'Bearer $token'}, + + fromJson: (json) => BroadcastPrice.fromJson(json), + ); + + return res.data; + } +} diff --git a/packages/chicken/lib/features/common/data/di/common_di.dart b/packages/chicken/lib/features/common/data/di/common_di.dart new file mode 100644 index 0000000..b9026e4 --- /dev/null +++ b/packages/chicken/lib/features/common/data/di/common_di.dart @@ -0,0 +1,66 @@ +import 'package:rasadyar_chicken/features/common/data/datasources/local/chicken_local.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/local/chicken_local_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/common/common_remote.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/common/common_remote_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/auth/auth_repository.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/auth/auth_repository_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/common/common_repository.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/common/common_repository_imp.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for common feature +Future setupCommonDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => AuthRemoteDataSourceImp(dioRemote), + ); + + di.registerLazySingleton( + () => AuthRepositoryImpl(di.get()), + ); + + di.registerLazySingleton( + () => CommonRemoteDatasourceImp(dioRemote), + ); + + di.registerLazySingleton( + () => ChickenLocalDataSourceImp(), + ); + + di.registerLazySingleton( + () => CommonRepositoryImp( + remote: di.get(), + local: di.get(), + ), + ); +} + +/// Re-register common dependencies (used when base URL changes) +Future reRegisterCommonDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => AuthRemoteDataSourceImp(dioRemote)); + await reRegister( + di, + () => AuthRepositoryImpl(di.get()), + ); + await reRegister(di, () => CommonRemoteDatasourceImp(dioRemote)); + await reRegister(di, () => ChickenLocalDataSourceImp()); + await reRegister( + di, + () => CommonRepositoryImp( + remote: di.get(), + local: di.get(), + ), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/data/models/local/widely_used_local_model.dart b/packages/chicken/lib/features/common/data/model/local/widely_used_local_model.dart similarity index 100% rename from packages/chicken/lib/data/models/local/widely_used_local_model.dart rename to packages/chicken/lib/features/common/data/model/local/widely_used_local_model.dart diff --git a/packages/chicken/lib/data/models/local/widely_used_local_model.g.dart b/packages/chicken/lib/features/common/data/model/local/widely_used_local_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/local/widely_used_local_model.g.dart rename to packages/chicken/lib/features/common/data/model/local/widely_used_local_model.g.dart diff --git a/packages/chicken/lib/data/models/request/change_password/change_password_request_model.dart b/packages/chicken/lib/features/common/data/model/request/change_password/change_password_request_model.dart similarity index 100% rename from packages/chicken/lib/data/models/request/change_password/change_password_request_model.dart rename to packages/chicken/lib/features/common/data/model/request/change_password/change_password_request_model.dart diff --git a/packages/chicken/lib/data/models/request/change_password/change_password_request_model.freezed.dart b/packages/chicken/lib/features/common/data/model/request/change_password/change_password_request_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/change_password/change_password_request_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/request/change_password/change_password_request_model.freezed.dart diff --git a/packages/chicken/lib/data/models/request/change_password/change_password_request_model.g.dart b/packages/chicken/lib/features/common/data/model/request/change_password/change_password_request_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/change_password/change_password_request_model.g.dart rename to packages/chicken/lib/features/common/data/model/request/change_password/change_password_request_model.g.dart diff --git a/packages/chicken/lib/data/models/request/login_request/login_request_model.dart b/packages/chicken/lib/features/common/data/model/request/login_request/login_request_model.dart similarity index 100% rename from packages/chicken/lib/data/models/request/login_request/login_request_model.dart rename to packages/chicken/lib/features/common/data/model/request/login_request/login_request_model.dart diff --git a/packages/chicken/lib/data/models/request/login_request/login_request_model.freezed.dart b/packages/chicken/lib/features/common/data/model/request/login_request/login_request_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/login_request/login_request_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/request/login_request/login_request_model.freezed.dart diff --git a/packages/chicken/lib/data/models/request/login_request/login_request_model.g.dart b/packages/chicken/lib/features/common/data/model/request/login_request/login_request_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/login_request/login_request_model.g.dart rename to packages/chicken/lib/features/common/data/model/request/login_request/login_request_model.g.dart diff --git a/packages/chicken/lib/data/models/request/submit_kill_house_free_bar/submit_kill_house_free_bar.dart b/packages/chicken/lib/features/common/data/model/request/submit_kill_house_free_bar/submit_kill_house_free_bar.dart similarity index 100% rename from packages/chicken/lib/data/models/request/submit_kill_house_free_bar/submit_kill_house_free_bar.dart rename to packages/chicken/lib/features/common/data/model/request/submit_kill_house_free_bar/submit_kill_house_free_bar.dart diff --git a/packages/chicken/lib/data/models/request/submit_kill_house_free_bar/submit_kill_house_free_bar.freezed.dart b/packages/chicken/lib/features/common/data/model/request/submit_kill_house_free_bar/submit_kill_house_free_bar.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/submit_kill_house_free_bar/submit_kill_house_free_bar.freezed.dart rename to packages/chicken/lib/features/common/data/model/request/submit_kill_house_free_bar/submit_kill_house_free_bar.freezed.dart diff --git a/packages/chicken/lib/data/models/request/submit_kill_house_free_bar/submit_kill_house_free_bar.g.dart b/packages/chicken/lib/features/common/data/model/request/submit_kill_house_free_bar/submit_kill_house_free_bar.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/submit_kill_house_free_bar/submit_kill_house_free_bar.g.dart rename to packages/chicken/lib/features/common/data/model/request/submit_kill_house_free_bar/submit_kill_house_free_bar.g.dart diff --git a/packages/chicken/lib/data/models/response/auth/auth_response_model.dart b/packages/chicken/lib/features/common/data/model/response/auth/auth_response_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/auth/auth_response_model.dart rename to packages/chicken/lib/features/common/data/model/response/auth/auth_response_model.dart diff --git a/packages/chicken/lib/data/models/response/auth/auth_response_model.freezed.dart b/packages/chicken/lib/features/common/data/model/response/auth/auth_response_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/auth/auth_response_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/auth/auth_response_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/auth/auth_response_model.g.dart b/packages/chicken/lib/features/common/data/model/response/auth/auth_response_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/auth/auth_response_model.g.dart rename to packages/chicken/lib/features/common/data/model/response/auth/auth_response_model.g.dart diff --git a/packages/chicken/lib/data/models/response/bar_information/bar_information.dart b/packages/chicken/lib/features/common/data/model/response/bar_information/bar_information.dart similarity index 100% rename from packages/chicken/lib/data/models/response/bar_information/bar_information.dart rename to packages/chicken/lib/features/common/data/model/response/bar_information/bar_information.dart diff --git a/packages/chicken/lib/data/models/response/bar_information/bar_information.freezed.dart b/packages/chicken/lib/features/common/data/model/response/bar_information/bar_information.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/bar_information/bar_information.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/bar_information/bar_information.freezed.dart diff --git a/packages/chicken/lib/data/models/response/bar_information/bar_information.g.dart b/packages/chicken/lib/features/common/data/model/response/bar_information/bar_information.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/bar_information/bar_information.g.dart rename to packages/chicken/lib/features/common/data/model/response/bar_information/bar_information.g.dart diff --git a/packages/chicken/lib/data/models/response/broadcast_price/broadcast_price.dart b/packages/chicken/lib/features/common/data/model/response/broadcast_price/broadcast_price.dart similarity index 100% rename from packages/chicken/lib/data/models/response/broadcast_price/broadcast_price.dart rename to packages/chicken/lib/features/common/data/model/response/broadcast_price/broadcast_price.dart diff --git a/packages/chicken/lib/data/models/response/broadcast_price/broadcast_price.freezed.dart b/packages/chicken/lib/features/common/data/model/response/broadcast_price/broadcast_price.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/broadcast_price/broadcast_price.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/broadcast_price/broadcast_price.freezed.dart diff --git a/packages/chicken/lib/data/models/response/broadcast_price/broadcast_price.g.dart b/packages/chicken/lib/features/common/data/model/response/broadcast_price/broadcast_price.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/broadcast_price/broadcast_price.g.dart rename to packages/chicken/lib/features/common/data/model/response/broadcast_price/broadcast_price.g.dart diff --git a/packages/chicken/lib/data/models/response/captcha/captcha_response_model.dart b/packages/chicken/lib/features/common/data/model/response/captcha/captcha_response_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/captcha/captcha_response_model.dart rename to packages/chicken/lib/features/common/data/model/response/captcha/captcha_response_model.dart diff --git a/packages/chicken/lib/data/models/response/captcha/captcha_response_model.freezed.dart b/packages/chicken/lib/features/common/data/model/response/captcha/captcha_response_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/captcha/captcha_response_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/captcha/captcha_response_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/captcha/captcha_response_model.g.dart b/packages/chicken/lib/features/common/data/model/response/captcha/captcha_response_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/captcha/captcha_response_model.g.dart rename to packages/chicken/lib/features/common/data/model/response/captcha/captcha_response_model.g.dart diff --git a/packages/chicken/lib/data/models/response/guild/guild_model.dart b/packages/chicken/lib/features/common/data/model/response/guild/guild_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/guild/guild_model.dart rename to packages/chicken/lib/features/common/data/model/response/guild/guild_model.dart diff --git a/packages/chicken/lib/data/models/response/guild/guild_model.freezed.dart b/packages/chicken/lib/features/common/data/model/response/guild/guild_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/guild/guild_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/guild/guild_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/guild/guild_model.g.dart b/packages/chicken/lib/features/common/data/model/response/guild/guild_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/guild/guild_model.g.dart rename to packages/chicken/lib/features/common/data/model/response/guild/guild_model.g.dart diff --git a/packages/chicken/lib/data/models/response/guild_profile/guild_profile.dart b/packages/chicken/lib/features/common/data/model/response/guild_profile/guild_profile.dart similarity index 100% rename from packages/chicken/lib/data/models/response/guild_profile/guild_profile.dart rename to packages/chicken/lib/features/common/data/model/response/guild_profile/guild_profile.dart diff --git a/packages/chicken/lib/data/models/response/guild_profile/guild_profile.freezed.dart b/packages/chicken/lib/features/common/data/model/response/guild_profile/guild_profile.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/guild_profile/guild_profile.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/guild_profile/guild_profile.freezed.dart diff --git a/packages/chicken/lib/data/models/response/guild_profile/guild_profile.g.dart b/packages/chicken/lib/features/common/data/model/response/guild_profile/guild_profile.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/guild_profile/guild_profile.g.dart rename to packages/chicken/lib/features/common/data/model/response/guild_profile/guild_profile.g.dart diff --git a/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.dart b/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.dart new file mode 100644 index 0000000..b6ed7c6 --- /dev/null +++ b/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.dart @@ -0,0 +1,56 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'inventory_model.freezed.dart'; +part 'inventory_model.g.dart'; + +@freezed +abstract class InventoryModel with _$InventoryModel { + const factory InventoryModel({ + int? id, + String? key, + String? createDate, + String? modifyDate, + bool? trash, + String? name, + int? provinceGovernmentalCarcassesQuantity, + int? provinceGovernmentalCarcassesWeight, + int? provinceFreeCarcassesQuantity, + int? provinceFreeCarcassesWeight, + int? receiveGovernmentalCarcassesQuantity, + int? receiveGovernmentalCarcassesWeight, + int? receiveFreeCarcassesQuantity, + int? receiveFreeCarcassesWeight, + int? freeBuyingCarcassesQuantity, + int? freeBuyingCarcassesWeight, + int? totalGovernmentalCarcassesQuantity, + int? totalGovernmentalCarcassesWeight, + int? totalFreeBarsCarcassesQuantity, + int? totalFreeBarsCarcassesWeight, + double? weightAverage, + int? totalCarcassesQuantity, + int? totalCarcassesWeight, + int? freezingQuantity, + int? freezingWeight, + int? lossWeight, + int? outProvinceAllocatedQuantity, + int? outProvinceAllocatedWeight, + int? provinceAllocatedQuantity, + int? provinceAllocatedWeight, + int? realAllocatedQuantity, + int? realAllocatedWeight, + int? coldHouseAllocatedWeight, + int? posAllocatedWeight, + int? segmentationWeight, + int? totalRemainQuantity, + int? totalRemainWeight, + int? freePrice, + int? approvedPrice, + bool? approvedPriceStatus, + int? parentProduct, + int? killHouse, + int? guild, + }) = _InventoryModel; // Changed to _InventoryModel + + factory InventoryModel.fromJson(Map json) => + _$InventoryModelFromJson(json); +} \ No newline at end of file diff --git a/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.freezed.dart b/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.freezed.dart new file mode 100644 index 0000000..9c0ac0d --- /dev/null +++ b/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.freezed.dart @@ -0,0 +1,403 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'inventory_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$InventoryModel { + + int? get id; String? get key; String? get createDate; String? get modifyDate; bool? get trash; String? get name; int? get provinceGovernmentalCarcassesQuantity; int? get provinceGovernmentalCarcassesWeight; int? get provinceFreeCarcassesQuantity; int? get provinceFreeCarcassesWeight; int? get receiveGovernmentalCarcassesQuantity; int? get receiveGovernmentalCarcassesWeight; int? get receiveFreeCarcassesQuantity; int? get receiveFreeCarcassesWeight; int? get freeBuyingCarcassesQuantity; int? get freeBuyingCarcassesWeight; int? get totalGovernmentalCarcassesQuantity; int? get totalGovernmentalCarcassesWeight; int? get totalFreeBarsCarcassesQuantity; int? get totalFreeBarsCarcassesWeight; double? get weightAverage; int? get totalCarcassesQuantity; int? get totalCarcassesWeight; int? get freezingQuantity; int? get freezingWeight; int? get lossWeight; int? get outProvinceAllocatedQuantity; int? get outProvinceAllocatedWeight; int? get provinceAllocatedQuantity; int? get provinceAllocatedWeight; int? get realAllocatedQuantity; int? get realAllocatedWeight; int? get coldHouseAllocatedWeight; int? get posAllocatedWeight; int? get segmentationWeight; int? get totalRemainQuantity; int? get totalRemainWeight; int? get freePrice; int? get approvedPrice; bool? get approvedPriceStatus; int? get parentProduct; int? get killHouse; int? get guild; +/// Create a copy of InventoryModel +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$InventoryModelCopyWith get copyWith => _$InventoryModelCopyWithImpl(this as InventoryModel, _$identity); + + /// Serializes this InventoryModel to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is InventoryModel&&(identical(other.id, id) || other.id == id)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.name, name) || other.name == name)&&(identical(other.provinceGovernmentalCarcassesQuantity, provinceGovernmentalCarcassesQuantity) || other.provinceGovernmentalCarcassesQuantity == provinceGovernmentalCarcassesQuantity)&&(identical(other.provinceGovernmentalCarcassesWeight, provinceGovernmentalCarcassesWeight) || other.provinceGovernmentalCarcassesWeight == provinceGovernmentalCarcassesWeight)&&(identical(other.provinceFreeCarcassesQuantity, provinceFreeCarcassesQuantity) || other.provinceFreeCarcassesQuantity == provinceFreeCarcassesQuantity)&&(identical(other.provinceFreeCarcassesWeight, provinceFreeCarcassesWeight) || other.provinceFreeCarcassesWeight == provinceFreeCarcassesWeight)&&(identical(other.receiveGovernmentalCarcassesQuantity, receiveGovernmentalCarcassesQuantity) || other.receiveGovernmentalCarcassesQuantity == receiveGovernmentalCarcassesQuantity)&&(identical(other.receiveGovernmentalCarcassesWeight, receiveGovernmentalCarcassesWeight) || other.receiveGovernmentalCarcassesWeight == receiveGovernmentalCarcassesWeight)&&(identical(other.receiveFreeCarcassesQuantity, receiveFreeCarcassesQuantity) || other.receiveFreeCarcassesQuantity == receiveFreeCarcassesQuantity)&&(identical(other.receiveFreeCarcassesWeight, receiveFreeCarcassesWeight) || other.receiveFreeCarcassesWeight == receiveFreeCarcassesWeight)&&(identical(other.freeBuyingCarcassesQuantity, freeBuyingCarcassesQuantity) || other.freeBuyingCarcassesQuantity == freeBuyingCarcassesQuantity)&&(identical(other.freeBuyingCarcassesWeight, freeBuyingCarcassesWeight) || other.freeBuyingCarcassesWeight == freeBuyingCarcassesWeight)&&(identical(other.totalGovernmentalCarcassesQuantity, totalGovernmentalCarcassesQuantity) || other.totalGovernmentalCarcassesQuantity == totalGovernmentalCarcassesQuantity)&&(identical(other.totalGovernmentalCarcassesWeight, totalGovernmentalCarcassesWeight) || other.totalGovernmentalCarcassesWeight == totalGovernmentalCarcassesWeight)&&(identical(other.totalFreeBarsCarcassesQuantity, totalFreeBarsCarcassesQuantity) || other.totalFreeBarsCarcassesQuantity == totalFreeBarsCarcassesQuantity)&&(identical(other.totalFreeBarsCarcassesWeight, totalFreeBarsCarcassesWeight) || other.totalFreeBarsCarcassesWeight == totalFreeBarsCarcassesWeight)&&(identical(other.weightAverage, weightAverage) || other.weightAverage == weightAverage)&&(identical(other.totalCarcassesQuantity, totalCarcassesQuantity) || other.totalCarcassesQuantity == totalCarcassesQuantity)&&(identical(other.totalCarcassesWeight, totalCarcassesWeight) || other.totalCarcassesWeight == totalCarcassesWeight)&&(identical(other.freezingQuantity, freezingQuantity) || other.freezingQuantity == freezingQuantity)&&(identical(other.freezingWeight, freezingWeight) || other.freezingWeight == freezingWeight)&&(identical(other.lossWeight, lossWeight) || other.lossWeight == lossWeight)&&(identical(other.outProvinceAllocatedQuantity, outProvinceAllocatedQuantity) || other.outProvinceAllocatedQuantity == outProvinceAllocatedQuantity)&&(identical(other.outProvinceAllocatedWeight, outProvinceAllocatedWeight) || other.outProvinceAllocatedWeight == outProvinceAllocatedWeight)&&(identical(other.provinceAllocatedQuantity, provinceAllocatedQuantity) || other.provinceAllocatedQuantity == provinceAllocatedQuantity)&&(identical(other.provinceAllocatedWeight, provinceAllocatedWeight) || other.provinceAllocatedWeight == provinceAllocatedWeight)&&(identical(other.realAllocatedQuantity, realAllocatedQuantity) || other.realAllocatedQuantity == realAllocatedQuantity)&&(identical(other.realAllocatedWeight, realAllocatedWeight) || other.realAllocatedWeight == realAllocatedWeight)&&(identical(other.coldHouseAllocatedWeight, coldHouseAllocatedWeight) || other.coldHouseAllocatedWeight == coldHouseAllocatedWeight)&&(identical(other.posAllocatedWeight, posAllocatedWeight) || other.posAllocatedWeight == posAllocatedWeight)&&(identical(other.segmentationWeight, segmentationWeight) || other.segmentationWeight == segmentationWeight)&&(identical(other.totalRemainQuantity, totalRemainQuantity) || other.totalRemainQuantity == totalRemainQuantity)&&(identical(other.totalRemainWeight, totalRemainWeight) || other.totalRemainWeight == totalRemainWeight)&&(identical(other.freePrice, freePrice) || other.freePrice == freePrice)&&(identical(other.approvedPrice, approvedPrice) || other.approvedPrice == approvedPrice)&&(identical(other.approvedPriceStatus, approvedPriceStatus) || other.approvedPriceStatus == approvedPriceStatus)&&(identical(other.parentProduct, parentProduct) || other.parentProduct == parentProduct)&&(identical(other.killHouse, killHouse) || other.killHouse == killHouse)&&(identical(other.guild, guild) || other.guild == guild)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hashAll([runtimeType,id,key,createDate,modifyDate,trash,name,provinceGovernmentalCarcassesQuantity,provinceGovernmentalCarcassesWeight,provinceFreeCarcassesQuantity,provinceFreeCarcassesWeight,receiveGovernmentalCarcassesQuantity,receiveGovernmentalCarcassesWeight,receiveFreeCarcassesQuantity,receiveFreeCarcassesWeight,freeBuyingCarcassesQuantity,freeBuyingCarcassesWeight,totalGovernmentalCarcassesQuantity,totalGovernmentalCarcassesWeight,totalFreeBarsCarcassesQuantity,totalFreeBarsCarcassesWeight,weightAverage,totalCarcassesQuantity,totalCarcassesWeight,freezingQuantity,freezingWeight,lossWeight,outProvinceAllocatedQuantity,outProvinceAllocatedWeight,provinceAllocatedQuantity,provinceAllocatedWeight,realAllocatedQuantity,realAllocatedWeight,coldHouseAllocatedWeight,posAllocatedWeight,segmentationWeight,totalRemainQuantity,totalRemainWeight,freePrice,approvedPrice,approvedPriceStatus,parentProduct,killHouse,guild]); + +@override +String toString() { + return 'InventoryModel(id: $id, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, name: $name, provinceGovernmentalCarcassesQuantity: $provinceGovernmentalCarcassesQuantity, provinceGovernmentalCarcassesWeight: $provinceGovernmentalCarcassesWeight, provinceFreeCarcassesQuantity: $provinceFreeCarcassesQuantity, provinceFreeCarcassesWeight: $provinceFreeCarcassesWeight, receiveGovernmentalCarcassesQuantity: $receiveGovernmentalCarcassesQuantity, receiveGovernmentalCarcassesWeight: $receiveGovernmentalCarcassesWeight, receiveFreeCarcassesQuantity: $receiveFreeCarcassesQuantity, receiveFreeCarcassesWeight: $receiveFreeCarcassesWeight, freeBuyingCarcassesQuantity: $freeBuyingCarcassesQuantity, freeBuyingCarcassesWeight: $freeBuyingCarcassesWeight, totalGovernmentalCarcassesQuantity: $totalGovernmentalCarcassesQuantity, totalGovernmentalCarcassesWeight: $totalGovernmentalCarcassesWeight, totalFreeBarsCarcassesQuantity: $totalFreeBarsCarcassesQuantity, totalFreeBarsCarcassesWeight: $totalFreeBarsCarcassesWeight, weightAverage: $weightAverage, totalCarcassesQuantity: $totalCarcassesQuantity, totalCarcassesWeight: $totalCarcassesWeight, freezingQuantity: $freezingQuantity, freezingWeight: $freezingWeight, lossWeight: $lossWeight, outProvinceAllocatedQuantity: $outProvinceAllocatedQuantity, outProvinceAllocatedWeight: $outProvinceAllocatedWeight, provinceAllocatedQuantity: $provinceAllocatedQuantity, provinceAllocatedWeight: $provinceAllocatedWeight, realAllocatedQuantity: $realAllocatedQuantity, realAllocatedWeight: $realAllocatedWeight, coldHouseAllocatedWeight: $coldHouseAllocatedWeight, posAllocatedWeight: $posAllocatedWeight, segmentationWeight: $segmentationWeight, totalRemainQuantity: $totalRemainQuantity, totalRemainWeight: $totalRemainWeight, freePrice: $freePrice, approvedPrice: $approvedPrice, approvedPriceStatus: $approvedPriceStatus, parentProduct: $parentProduct, killHouse: $killHouse, guild: $guild)'; +} + + +} + +/// @nodoc +abstract mixin class $InventoryModelCopyWith<$Res> { + factory $InventoryModelCopyWith(InventoryModel value, $Res Function(InventoryModel) _then) = _$InventoryModelCopyWithImpl; +@useResult +$Res call({ + int? id, String? key, String? createDate, String? modifyDate, bool? trash, String? name, int? provinceGovernmentalCarcassesQuantity, int? provinceGovernmentalCarcassesWeight, int? provinceFreeCarcassesQuantity, int? provinceFreeCarcassesWeight, int? receiveGovernmentalCarcassesQuantity, int? receiveGovernmentalCarcassesWeight, int? receiveFreeCarcassesQuantity, int? receiveFreeCarcassesWeight, int? freeBuyingCarcassesQuantity, int? freeBuyingCarcassesWeight, int? totalGovernmentalCarcassesQuantity, int? totalGovernmentalCarcassesWeight, int? totalFreeBarsCarcassesQuantity, int? totalFreeBarsCarcassesWeight, double? weightAverage, int? totalCarcassesQuantity, int? totalCarcassesWeight, int? freezingQuantity, int? freezingWeight, int? lossWeight, int? outProvinceAllocatedQuantity, int? outProvinceAllocatedWeight, int? provinceAllocatedQuantity, int? provinceAllocatedWeight, int? realAllocatedQuantity, int? realAllocatedWeight, int? coldHouseAllocatedWeight, int? posAllocatedWeight, int? segmentationWeight, int? totalRemainQuantity, int? totalRemainWeight, int? freePrice, int? approvedPrice, bool? approvedPriceStatus, int? parentProduct, int? killHouse, int? guild +}); + + + + +} +/// @nodoc +class _$InventoryModelCopyWithImpl<$Res> + implements $InventoryModelCopyWith<$Res> { + _$InventoryModelCopyWithImpl(this._self, this._then); + + final InventoryModel _self; + final $Res Function(InventoryModel) _then; + +/// Create a copy of InventoryModel +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? name = freezed,Object? provinceGovernmentalCarcassesQuantity = freezed,Object? provinceGovernmentalCarcassesWeight = freezed,Object? provinceFreeCarcassesQuantity = freezed,Object? provinceFreeCarcassesWeight = freezed,Object? receiveGovernmentalCarcassesQuantity = freezed,Object? receiveGovernmentalCarcassesWeight = freezed,Object? receiveFreeCarcassesQuantity = freezed,Object? receiveFreeCarcassesWeight = freezed,Object? freeBuyingCarcassesQuantity = freezed,Object? freeBuyingCarcassesWeight = freezed,Object? totalGovernmentalCarcassesQuantity = freezed,Object? totalGovernmentalCarcassesWeight = freezed,Object? totalFreeBarsCarcassesQuantity = freezed,Object? totalFreeBarsCarcassesWeight = freezed,Object? weightAverage = freezed,Object? totalCarcassesQuantity = freezed,Object? totalCarcassesWeight = freezed,Object? freezingQuantity = freezed,Object? freezingWeight = freezed,Object? lossWeight = freezed,Object? outProvinceAllocatedQuantity = freezed,Object? outProvinceAllocatedWeight = freezed,Object? provinceAllocatedQuantity = freezed,Object? provinceAllocatedWeight = freezed,Object? realAllocatedQuantity = freezed,Object? realAllocatedWeight = freezed,Object? coldHouseAllocatedWeight = freezed,Object? posAllocatedWeight = freezed,Object? segmentationWeight = freezed,Object? totalRemainQuantity = freezed,Object? totalRemainWeight = freezed,Object? freePrice = freezed,Object? approvedPrice = freezed,Object? approvedPriceStatus = freezed,Object? parentProduct = freezed,Object? killHouse = freezed,Object? guild = freezed,}) { + return _then(_self.copyWith( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int?,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable +as String?,createDate: freezed == createDate ? _self.createDate : createDate // ignore: cast_nullable_to_non_nullable +as String?,modifyDate: freezed == modifyDate ? _self.modifyDate : modifyDate // ignore: cast_nullable_to_non_nullable +as String?,trash: freezed == trash ? _self.trash : trash // ignore: cast_nullable_to_non_nullable +as bool?,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String?,provinceGovernmentalCarcassesQuantity: freezed == provinceGovernmentalCarcassesQuantity ? _self.provinceGovernmentalCarcassesQuantity : provinceGovernmentalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,provinceGovernmentalCarcassesWeight: freezed == provinceGovernmentalCarcassesWeight ? _self.provinceGovernmentalCarcassesWeight : provinceGovernmentalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,provinceFreeCarcassesQuantity: freezed == provinceFreeCarcassesQuantity ? _self.provinceFreeCarcassesQuantity : provinceFreeCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,provinceFreeCarcassesWeight: freezed == provinceFreeCarcassesWeight ? _self.provinceFreeCarcassesWeight : provinceFreeCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,receiveGovernmentalCarcassesQuantity: freezed == receiveGovernmentalCarcassesQuantity ? _self.receiveGovernmentalCarcassesQuantity : receiveGovernmentalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,receiveGovernmentalCarcassesWeight: freezed == receiveGovernmentalCarcassesWeight ? _self.receiveGovernmentalCarcassesWeight : receiveGovernmentalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,receiveFreeCarcassesQuantity: freezed == receiveFreeCarcassesQuantity ? _self.receiveFreeCarcassesQuantity : receiveFreeCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,receiveFreeCarcassesWeight: freezed == receiveFreeCarcassesWeight ? _self.receiveFreeCarcassesWeight : receiveFreeCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,freeBuyingCarcassesQuantity: freezed == freeBuyingCarcassesQuantity ? _self.freeBuyingCarcassesQuantity : freeBuyingCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,freeBuyingCarcassesWeight: freezed == freeBuyingCarcassesWeight ? _self.freeBuyingCarcassesWeight : freeBuyingCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,totalGovernmentalCarcassesQuantity: freezed == totalGovernmentalCarcassesQuantity ? _self.totalGovernmentalCarcassesQuantity : totalGovernmentalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalGovernmentalCarcassesWeight: freezed == totalGovernmentalCarcassesWeight ? _self.totalGovernmentalCarcassesWeight : totalGovernmentalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,totalFreeBarsCarcassesQuantity: freezed == totalFreeBarsCarcassesQuantity ? _self.totalFreeBarsCarcassesQuantity : totalFreeBarsCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalFreeBarsCarcassesWeight: freezed == totalFreeBarsCarcassesWeight ? _self.totalFreeBarsCarcassesWeight : totalFreeBarsCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,weightAverage: freezed == weightAverage ? _self.weightAverage : weightAverage // ignore: cast_nullable_to_non_nullable +as double?,totalCarcassesQuantity: freezed == totalCarcassesQuantity ? _self.totalCarcassesQuantity : totalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalCarcassesWeight: freezed == totalCarcassesWeight ? _self.totalCarcassesWeight : totalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,freezingQuantity: freezed == freezingQuantity ? _self.freezingQuantity : freezingQuantity // ignore: cast_nullable_to_non_nullable +as int?,freezingWeight: freezed == freezingWeight ? _self.freezingWeight : freezingWeight // ignore: cast_nullable_to_non_nullable +as int?,lossWeight: freezed == lossWeight ? _self.lossWeight : lossWeight // ignore: cast_nullable_to_non_nullable +as int?,outProvinceAllocatedQuantity: freezed == outProvinceAllocatedQuantity ? _self.outProvinceAllocatedQuantity : outProvinceAllocatedQuantity // ignore: cast_nullable_to_non_nullable +as int?,outProvinceAllocatedWeight: freezed == outProvinceAllocatedWeight ? _self.outProvinceAllocatedWeight : outProvinceAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,provinceAllocatedQuantity: freezed == provinceAllocatedQuantity ? _self.provinceAllocatedQuantity : provinceAllocatedQuantity // ignore: cast_nullable_to_non_nullable +as int?,provinceAllocatedWeight: freezed == provinceAllocatedWeight ? _self.provinceAllocatedWeight : provinceAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,realAllocatedQuantity: freezed == realAllocatedQuantity ? _self.realAllocatedQuantity : realAllocatedQuantity // ignore: cast_nullable_to_non_nullable +as int?,realAllocatedWeight: freezed == realAllocatedWeight ? _self.realAllocatedWeight : realAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,coldHouseAllocatedWeight: freezed == coldHouseAllocatedWeight ? _self.coldHouseAllocatedWeight : coldHouseAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,posAllocatedWeight: freezed == posAllocatedWeight ? _self.posAllocatedWeight : posAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,segmentationWeight: freezed == segmentationWeight ? _self.segmentationWeight : segmentationWeight // ignore: cast_nullable_to_non_nullable +as int?,totalRemainQuantity: freezed == totalRemainQuantity ? _self.totalRemainQuantity : totalRemainQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalRemainWeight: freezed == totalRemainWeight ? _self.totalRemainWeight : totalRemainWeight // ignore: cast_nullable_to_non_nullable +as int?,freePrice: freezed == freePrice ? _self.freePrice : freePrice // ignore: cast_nullable_to_non_nullable +as int?,approvedPrice: freezed == approvedPrice ? _self.approvedPrice : approvedPrice // ignore: cast_nullable_to_non_nullable +as int?,approvedPriceStatus: freezed == approvedPriceStatus ? _self.approvedPriceStatus : approvedPriceStatus // ignore: cast_nullable_to_non_nullable +as bool?,parentProduct: freezed == parentProduct ? _self.parentProduct : parentProduct // ignore: cast_nullable_to_non_nullable +as int?,killHouse: freezed == killHouse ? _self.killHouse : killHouse // ignore: cast_nullable_to_non_nullable +as int?,guild: freezed == guild ? _self.guild : guild // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [InventoryModel]. +extension InventoryModelPatterns on InventoryModel { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _InventoryModel value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _InventoryModel() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _InventoryModel value) $default,){ +final _that = this; +switch (_that) { +case _InventoryModel(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _InventoryModel value)? $default,){ +final _that = this; +switch (_that) { +case _InventoryModel() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( int? id, String? key, String? createDate, String? modifyDate, bool? trash, String? name, int? provinceGovernmentalCarcassesQuantity, int? provinceGovernmentalCarcassesWeight, int? provinceFreeCarcassesQuantity, int? provinceFreeCarcassesWeight, int? receiveGovernmentalCarcassesQuantity, int? receiveGovernmentalCarcassesWeight, int? receiveFreeCarcassesQuantity, int? receiveFreeCarcassesWeight, int? freeBuyingCarcassesQuantity, int? freeBuyingCarcassesWeight, int? totalGovernmentalCarcassesQuantity, int? totalGovernmentalCarcassesWeight, int? totalFreeBarsCarcassesQuantity, int? totalFreeBarsCarcassesWeight, double? weightAverage, int? totalCarcassesQuantity, int? totalCarcassesWeight, int? freezingQuantity, int? freezingWeight, int? lossWeight, int? outProvinceAllocatedQuantity, int? outProvinceAllocatedWeight, int? provinceAllocatedQuantity, int? provinceAllocatedWeight, int? realAllocatedQuantity, int? realAllocatedWeight, int? coldHouseAllocatedWeight, int? posAllocatedWeight, int? segmentationWeight, int? totalRemainQuantity, int? totalRemainWeight, int? freePrice, int? approvedPrice, bool? approvedPriceStatus, int? parentProduct, int? killHouse, int? guild)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _InventoryModel() when $default != null: +return $default(_that.id,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.name,_that.provinceGovernmentalCarcassesQuantity,_that.provinceGovernmentalCarcassesWeight,_that.provinceFreeCarcassesQuantity,_that.provinceFreeCarcassesWeight,_that.receiveGovernmentalCarcassesQuantity,_that.receiveGovernmentalCarcassesWeight,_that.receiveFreeCarcassesQuantity,_that.receiveFreeCarcassesWeight,_that.freeBuyingCarcassesQuantity,_that.freeBuyingCarcassesWeight,_that.totalGovernmentalCarcassesQuantity,_that.totalGovernmentalCarcassesWeight,_that.totalFreeBarsCarcassesQuantity,_that.totalFreeBarsCarcassesWeight,_that.weightAverage,_that.totalCarcassesQuantity,_that.totalCarcassesWeight,_that.freezingQuantity,_that.freezingWeight,_that.lossWeight,_that.outProvinceAllocatedQuantity,_that.outProvinceAllocatedWeight,_that.provinceAllocatedQuantity,_that.provinceAllocatedWeight,_that.realAllocatedQuantity,_that.realAllocatedWeight,_that.coldHouseAllocatedWeight,_that.posAllocatedWeight,_that.segmentationWeight,_that.totalRemainQuantity,_that.totalRemainWeight,_that.freePrice,_that.approvedPrice,_that.approvedPriceStatus,_that.parentProduct,_that.killHouse,_that.guild);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( int? id, String? key, String? createDate, String? modifyDate, bool? trash, String? name, int? provinceGovernmentalCarcassesQuantity, int? provinceGovernmentalCarcassesWeight, int? provinceFreeCarcassesQuantity, int? provinceFreeCarcassesWeight, int? receiveGovernmentalCarcassesQuantity, int? receiveGovernmentalCarcassesWeight, int? receiveFreeCarcassesQuantity, int? receiveFreeCarcassesWeight, int? freeBuyingCarcassesQuantity, int? freeBuyingCarcassesWeight, int? totalGovernmentalCarcassesQuantity, int? totalGovernmentalCarcassesWeight, int? totalFreeBarsCarcassesQuantity, int? totalFreeBarsCarcassesWeight, double? weightAverage, int? totalCarcassesQuantity, int? totalCarcassesWeight, int? freezingQuantity, int? freezingWeight, int? lossWeight, int? outProvinceAllocatedQuantity, int? outProvinceAllocatedWeight, int? provinceAllocatedQuantity, int? provinceAllocatedWeight, int? realAllocatedQuantity, int? realAllocatedWeight, int? coldHouseAllocatedWeight, int? posAllocatedWeight, int? segmentationWeight, int? totalRemainQuantity, int? totalRemainWeight, int? freePrice, int? approvedPrice, bool? approvedPriceStatus, int? parentProduct, int? killHouse, int? guild) $default,) {final _that = this; +switch (_that) { +case _InventoryModel(): +return $default(_that.id,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.name,_that.provinceGovernmentalCarcassesQuantity,_that.provinceGovernmentalCarcassesWeight,_that.provinceFreeCarcassesQuantity,_that.provinceFreeCarcassesWeight,_that.receiveGovernmentalCarcassesQuantity,_that.receiveGovernmentalCarcassesWeight,_that.receiveFreeCarcassesQuantity,_that.receiveFreeCarcassesWeight,_that.freeBuyingCarcassesQuantity,_that.freeBuyingCarcassesWeight,_that.totalGovernmentalCarcassesQuantity,_that.totalGovernmentalCarcassesWeight,_that.totalFreeBarsCarcassesQuantity,_that.totalFreeBarsCarcassesWeight,_that.weightAverage,_that.totalCarcassesQuantity,_that.totalCarcassesWeight,_that.freezingQuantity,_that.freezingWeight,_that.lossWeight,_that.outProvinceAllocatedQuantity,_that.outProvinceAllocatedWeight,_that.provinceAllocatedQuantity,_that.provinceAllocatedWeight,_that.realAllocatedQuantity,_that.realAllocatedWeight,_that.coldHouseAllocatedWeight,_that.posAllocatedWeight,_that.segmentationWeight,_that.totalRemainQuantity,_that.totalRemainWeight,_that.freePrice,_that.approvedPrice,_that.approvedPriceStatus,_that.parentProduct,_that.killHouse,_that.guild);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( int? id, String? key, String? createDate, String? modifyDate, bool? trash, String? name, int? provinceGovernmentalCarcassesQuantity, int? provinceGovernmentalCarcassesWeight, int? provinceFreeCarcassesQuantity, int? provinceFreeCarcassesWeight, int? receiveGovernmentalCarcassesQuantity, int? receiveGovernmentalCarcassesWeight, int? receiveFreeCarcassesQuantity, int? receiveFreeCarcassesWeight, int? freeBuyingCarcassesQuantity, int? freeBuyingCarcassesWeight, int? totalGovernmentalCarcassesQuantity, int? totalGovernmentalCarcassesWeight, int? totalFreeBarsCarcassesQuantity, int? totalFreeBarsCarcassesWeight, double? weightAverage, int? totalCarcassesQuantity, int? totalCarcassesWeight, int? freezingQuantity, int? freezingWeight, int? lossWeight, int? outProvinceAllocatedQuantity, int? outProvinceAllocatedWeight, int? provinceAllocatedQuantity, int? provinceAllocatedWeight, int? realAllocatedQuantity, int? realAllocatedWeight, int? coldHouseAllocatedWeight, int? posAllocatedWeight, int? segmentationWeight, int? totalRemainQuantity, int? totalRemainWeight, int? freePrice, int? approvedPrice, bool? approvedPriceStatus, int? parentProduct, int? killHouse, int? guild)? $default,) {final _that = this; +switch (_that) { +case _InventoryModel() when $default != null: +return $default(_that.id,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.name,_that.provinceGovernmentalCarcassesQuantity,_that.provinceGovernmentalCarcassesWeight,_that.provinceFreeCarcassesQuantity,_that.provinceFreeCarcassesWeight,_that.receiveGovernmentalCarcassesQuantity,_that.receiveGovernmentalCarcassesWeight,_that.receiveFreeCarcassesQuantity,_that.receiveFreeCarcassesWeight,_that.freeBuyingCarcassesQuantity,_that.freeBuyingCarcassesWeight,_that.totalGovernmentalCarcassesQuantity,_that.totalGovernmentalCarcassesWeight,_that.totalFreeBarsCarcassesQuantity,_that.totalFreeBarsCarcassesWeight,_that.weightAverage,_that.totalCarcassesQuantity,_that.totalCarcassesWeight,_that.freezingQuantity,_that.freezingWeight,_that.lossWeight,_that.outProvinceAllocatedQuantity,_that.outProvinceAllocatedWeight,_that.provinceAllocatedQuantity,_that.provinceAllocatedWeight,_that.realAllocatedQuantity,_that.realAllocatedWeight,_that.coldHouseAllocatedWeight,_that.posAllocatedWeight,_that.segmentationWeight,_that.totalRemainQuantity,_that.totalRemainWeight,_that.freePrice,_that.approvedPrice,_that.approvedPriceStatus,_that.parentProduct,_that.killHouse,_that.guild);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _InventoryModel implements InventoryModel { + const _InventoryModel({this.id, this.key, this.createDate, this.modifyDate, this.trash, this.name, this.provinceGovernmentalCarcassesQuantity, this.provinceGovernmentalCarcassesWeight, this.provinceFreeCarcassesQuantity, this.provinceFreeCarcassesWeight, this.receiveGovernmentalCarcassesQuantity, this.receiveGovernmentalCarcassesWeight, this.receiveFreeCarcassesQuantity, this.receiveFreeCarcassesWeight, this.freeBuyingCarcassesQuantity, this.freeBuyingCarcassesWeight, this.totalGovernmentalCarcassesQuantity, this.totalGovernmentalCarcassesWeight, this.totalFreeBarsCarcassesQuantity, this.totalFreeBarsCarcassesWeight, this.weightAverage, this.totalCarcassesQuantity, this.totalCarcassesWeight, this.freezingQuantity, this.freezingWeight, this.lossWeight, this.outProvinceAllocatedQuantity, this.outProvinceAllocatedWeight, this.provinceAllocatedQuantity, this.provinceAllocatedWeight, this.realAllocatedQuantity, this.realAllocatedWeight, this.coldHouseAllocatedWeight, this.posAllocatedWeight, this.segmentationWeight, this.totalRemainQuantity, this.totalRemainWeight, this.freePrice, this.approvedPrice, this.approvedPriceStatus, this.parentProduct, this.killHouse, this.guild}); + factory _InventoryModel.fromJson(Map json) => _$InventoryModelFromJson(json); + +@override final int? id; +@override final String? key; +@override final String? createDate; +@override final String? modifyDate; +@override final bool? trash; +@override final String? name; +@override final int? provinceGovernmentalCarcassesQuantity; +@override final int? provinceGovernmentalCarcassesWeight; +@override final int? provinceFreeCarcassesQuantity; +@override final int? provinceFreeCarcassesWeight; +@override final int? receiveGovernmentalCarcassesQuantity; +@override final int? receiveGovernmentalCarcassesWeight; +@override final int? receiveFreeCarcassesQuantity; +@override final int? receiveFreeCarcassesWeight; +@override final int? freeBuyingCarcassesQuantity; +@override final int? freeBuyingCarcassesWeight; +@override final int? totalGovernmentalCarcassesQuantity; +@override final int? totalGovernmentalCarcassesWeight; +@override final int? totalFreeBarsCarcassesQuantity; +@override final int? totalFreeBarsCarcassesWeight; +@override final double? weightAverage; +@override final int? totalCarcassesQuantity; +@override final int? totalCarcassesWeight; +@override final int? freezingQuantity; +@override final int? freezingWeight; +@override final int? lossWeight; +@override final int? outProvinceAllocatedQuantity; +@override final int? outProvinceAllocatedWeight; +@override final int? provinceAllocatedQuantity; +@override final int? provinceAllocatedWeight; +@override final int? realAllocatedQuantity; +@override final int? realAllocatedWeight; +@override final int? coldHouseAllocatedWeight; +@override final int? posAllocatedWeight; +@override final int? segmentationWeight; +@override final int? totalRemainQuantity; +@override final int? totalRemainWeight; +@override final int? freePrice; +@override final int? approvedPrice; +@override final bool? approvedPriceStatus; +@override final int? parentProduct; +@override final int? killHouse; +@override final int? guild; + +/// Create a copy of InventoryModel +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$InventoryModelCopyWith<_InventoryModel> get copyWith => __$InventoryModelCopyWithImpl<_InventoryModel>(this, _$identity); + +@override +Map toJson() { + return _$InventoryModelToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _InventoryModel&&(identical(other.id, id) || other.id == id)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.name, name) || other.name == name)&&(identical(other.provinceGovernmentalCarcassesQuantity, provinceGovernmentalCarcassesQuantity) || other.provinceGovernmentalCarcassesQuantity == provinceGovernmentalCarcassesQuantity)&&(identical(other.provinceGovernmentalCarcassesWeight, provinceGovernmentalCarcassesWeight) || other.provinceGovernmentalCarcassesWeight == provinceGovernmentalCarcassesWeight)&&(identical(other.provinceFreeCarcassesQuantity, provinceFreeCarcassesQuantity) || other.provinceFreeCarcassesQuantity == provinceFreeCarcassesQuantity)&&(identical(other.provinceFreeCarcassesWeight, provinceFreeCarcassesWeight) || other.provinceFreeCarcassesWeight == provinceFreeCarcassesWeight)&&(identical(other.receiveGovernmentalCarcassesQuantity, receiveGovernmentalCarcassesQuantity) || other.receiveGovernmentalCarcassesQuantity == receiveGovernmentalCarcassesQuantity)&&(identical(other.receiveGovernmentalCarcassesWeight, receiveGovernmentalCarcassesWeight) || other.receiveGovernmentalCarcassesWeight == receiveGovernmentalCarcassesWeight)&&(identical(other.receiveFreeCarcassesQuantity, receiveFreeCarcassesQuantity) || other.receiveFreeCarcassesQuantity == receiveFreeCarcassesQuantity)&&(identical(other.receiveFreeCarcassesWeight, receiveFreeCarcassesWeight) || other.receiveFreeCarcassesWeight == receiveFreeCarcassesWeight)&&(identical(other.freeBuyingCarcassesQuantity, freeBuyingCarcassesQuantity) || other.freeBuyingCarcassesQuantity == freeBuyingCarcassesQuantity)&&(identical(other.freeBuyingCarcassesWeight, freeBuyingCarcassesWeight) || other.freeBuyingCarcassesWeight == freeBuyingCarcassesWeight)&&(identical(other.totalGovernmentalCarcassesQuantity, totalGovernmentalCarcassesQuantity) || other.totalGovernmentalCarcassesQuantity == totalGovernmentalCarcassesQuantity)&&(identical(other.totalGovernmentalCarcassesWeight, totalGovernmentalCarcassesWeight) || other.totalGovernmentalCarcassesWeight == totalGovernmentalCarcassesWeight)&&(identical(other.totalFreeBarsCarcassesQuantity, totalFreeBarsCarcassesQuantity) || other.totalFreeBarsCarcassesQuantity == totalFreeBarsCarcassesQuantity)&&(identical(other.totalFreeBarsCarcassesWeight, totalFreeBarsCarcassesWeight) || other.totalFreeBarsCarcassesWeight == totalFreeBarsCarcassesWeight)&&(identical(other.weightAverage, weightAverage) || other.weightAverage == weightAverage)&&(identical(other.totalCarcassesQuantity, totalCarcassesQuantity) || other.totalCarcassesQuantity == totalCarcassesQuantity)&&(identical(other.totalCarcassesWeight, totalCarcassesWeight) || other.totalCarcassesWeight == totalCarcassesWeight)&&(identical(other.freezingQuantity, freezingQuantity) || other.freezingQuantity == freezingQuantity)&&(identical(other.freezingWeight, freezingWeight) || other.freezingWeight == freezingWeight)&&(identical(other.lossWeight, lossWeight) || other.lossWeight == lossWeight)&&(identical(other.outProvinceAllocatedQuantity, outProvinceAllocatedQuantity) || other.outProvinceAllocatedQuantity == outProvinceAllocatedQuantity)&&(identical(other.outProvinceAllocatedWeight, outProvinceAllocatedWeight) || other.outProvinceAllocatedWeight == outProvinceAllocatedWeight)&&(identical(other.provinceAllocatedQuantity, provinceAllocatedQuantity) || other.provinceAllocatedQuantity == provinceAllocatedQuantity)&&(identical(other.provinceAllocatedWeight, provinceAllocatedWeight) || other.provinceAllocatedWeight == provinceAllocatedWeight)&&(identical(other.realAllocatedQuantity, realAllocatedQuantity) || other.realAllocatedQuantity == realAllocatedQuantity)&&(identical(other.realAllocatedWeight, realAllocatedWeight) || other.realAllocatedWeight == realAllocatedWeight)&&(identical(other.coldHouseAllocatedWeight, coldHouseAllocatedWeight) || other.coldHouseAllocatedWeight == coldHouseAllocatedWeight)&&(identical(other.posAllocatedWeight, posAllocatedWeight) || other.posAllocatedWeight == posAllocatedWeight)&&(identical(other.segmentationWeight, segmentationWeight) || other.segmentationWeight == segmentationWeight)&&(identical(other.totalRemainQuantity, totalRemainQuantity) || other.totalRemainQuantity == totalRemainQuantity)&&(identical(other.totalRemainWeight, totalRemainWeight) || other.totalRemainWeight == totalRemainWeight)&&(identical(other.freePrice, freePrice) || other.freePrice == freePrice)&&(identical(other.approvedPrice, approvedPrice) || other.approvedPrice == approvedPrice)&&(identical(other.approvedPriceStatus, approvedPriceStatus) || other.approvedPriceStatus == approvedPriceStatus)&&(identical(other.parentProduct, parentProduct) || other.parentProduct == parentProduct)&&(identical(other.killHouse, killHouse) || other.killHouse == killHouse)&&(identical(other.guild, guild) || other.guild == guild)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hashAll([runtimeType,id,key,createDate,modifyDate,trash,name,provinceGovernmentalCarcassesQuantity,provinceGovernmentalCarcassesWeight,provinceFreeCarcassesQuantity,provinceFreeCarcassesWeight,receiveGovernmentalCarcassesQuantity,receiveGovernmentalCarcassesWeight,receiveFreeCarcassesQuantity,receiveFreeCarcassesWeight,freeBuyingCarcassesQuantity,freeBuyingCarcassesWeight,totalGovernmentalCarcassesQuantity,totalGovernmentalCarcassesWeight,totalFreeBarsCarcassesQuantity,totalFreeBarsCarcassesWeight,weightAverage,totalCarcassesQuantity,totalCarcassesWeight,freezingQuantity,freezingWeight,lossWeight,outProvinceAllocatedQuantity,outProvinceAllocatedWeight,provinceAllocatedQuantity,provinceAllocatedWeight,realAllocatedQuantity,realAllocatedWeight,coldHouseAllocatedWeight,posAllocatedWeight,segmentationWeight,totalRemainQuantity,totalRemainWeight,freePrice,approvedPrice,approvedPriceStatus,parentProduct,killHouse,guild]); + +@override +String toString() { + return 'InventoryModel(id: $id, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, name: $name, provinceGovernmentalCarcassesQuantity: $provinceGovernmentalCarcassesQuantity, provinceGovernmentalCarcassesWeight: $provinceGovernmentalCarcassesWeight, provinceFreeCarcassesQuantity: $provinceFreeCarcassesQuantity, provinceFreeCarcassesWeight: $provinceFreeCarcassesWeight, receiveGovernmentalCarcassesQuantity: $receiveGovernmentalCarcassesQuantity, receiveGovernmentalCarcassesWeight: $receiveGovernmentalCarcassesWeight, receiveFreeCarcassesQuantity: $receiveFreeCarcassesQuantity, receiveFreeCarcassesWeight: $receiveFreeCarcassesWeight, freeBuyingCarcassesQuantity: $freeBuyingCarcassesQuantity, freeBuyingCarcassesWeight: $freeBuyingCarcassesWeight, totalGovernmentalCarcassesQuantity: $totalGovernmentalCarcassesQuantity, totalGovernmentalCarcassesWeight: $totalGovernmentalCarcassesWeight, totalFreeBarsCarcassesQuantity: $totalFreeBarsCarcassesQuantity, totalFreeBarsCarcassesWeight: $totalFreeBarsCarcassesWeight, weightAverage: $weightAverage, totalCarcassesQuantity: $totalCarcassesQuantity, totalCarcassesWeight: $totalCarcassesWeight, freezingQuantity: $freezingQuantity, freezingWeight: $freezingWeight, lossWeight: $lossWeight, outProvinceAllocatedQuantity: $outProvinceAllocatedQuantity, outProvinceAllocatedWeight: $outProvinceAllocatedWeight, provinceAllocatedQuantity: $provinceAllocatedQuantity, provinceAllocatedWeight: $provinceAllocatedWeight, realAllocatedQuantity: $realAllocatedQuantity, realAllocatedWeight: $realAllocatedWeight, coldHouseAllocatedWeight: $coldHouseAllocatedWeight, posAllocatedWeight: $posAllocatedWeight, segmentationWeight: $segmentationWeight, totalRemainQuantity: $totalRemainQuantity, totalRemainWeight: $totalRemainWeight, freePrice: $freePrice, approvedPrice: $approvedPrice, approvedPriceStatus: $approvedPriceStatus, parentProduct: $parentProduct, killHouse: $killHouse, guild: $guild)'; +} + + +} + +/// @nodoc +abstract mixin class _$InventoryModelCopyWith<$Res> implements $InventoryModelCopyWith<$Res> { + factory _$InventoryModelCopyWith(_InventoryModel value, $Res Function(_InventoryModel) _then) = __$InventoryModelCopyWithImpl; +@override @useResult +$Res call({ + int? id, String? key, String? createDate, String? modifyDate, bool? trash, String? name, int? provinceGovernmentalCarcassesQuantity, int? provinceGovernmentalCarcassesWeight, int? provinceFreeCarcassesQuantity, int? provinceFreeCarcassesWeight, int? receiveGovernmentalCarcassesQuantity, int? receiveGovernmentalCarcassesWeight, int? receiveFreeCarcassesQuantity, int? receiveFreeCarcassesWeight, int? freeBuyingCarcassesQuantity, int? freeBuyingCarcassesWeight, int? totalGovernmentalCarcassesQuantity, int? totalGovernmentalCarcassesWeight, int? totalFreeBarsCarcassesQuantity, int? totalFreeBarsCarcassesWeight, double? weightAverage, int? totalCarcassesQuantity, int? totalCarcassesWeight, int? freezingQuantity, int? freezingWeight, int? lossWeight, int? outProvinceAllocatedQuantity, int? outProvinceAllocatedWeight, int? provinceAllocatedQuantity, int? provinceAllocatedWeight, int? realAllocatedQuantity, int? realAllocatedWeight, int? coldHouseAllocatedWeight, int? posAllocatedWeight, int? segmentationWeight, int? totalRemainQuantity, int? totalRemainWeight, int? freePrice, int? approvedPrice, bool? approvedPriceStatus, int? parentProduct, int? killHouse, int? guild +}); + + + + +} +/// @nodoc +class __$InventoryModelCopyWithImpl<$Res> + implements _$InventoryModelCopyWith<$Res> { + __$InventoryModelCopyWithImpl(this._self, this._then); + + final _InventoryModel _self; + final $Res Function(_InventoryModel) _then; + +/// Create a copy of InventoryModel +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? name = freezed,Object? provinceGovernmentalCarcassesQuantity = freezed,Object? provinceGovernmentalCarcassesWeight = freezed,Object? provinceFreeCarcassesQuantity = freezed,Object? provinceFreeCarcassesWeight = freezed,Object? receiveGovernmentalCarcassesQuantity = freezed,Object? receiveGovernmentalCarcassesWeight = freezed,Object? receiveFreeCarcassesQuantity = freezed,Object? receiveFreeCarcassesWeight = freezed,Object? freeBuyingCarcassesQuantity = freezed,Object? freeBuyingCarcassesWeight = freezed,Object? totalGovernmentalCarcassesQuantity = freezed,Object? totalGovernmentalCarcassesWeight = freezed,Object? totalFreeBarsCarcassesQuantity = freezed,Object? totalFreeBarsCarcassesWeight = freezed,Object? weightAverage = freezed,Object? totalCarcassesQuantity = freezed,Object? totalCarcassesWeight = freezed,Object? freezingQuantity = freezed,Object? freezingWeight = freezed,Object? lossWeight = freezed,Object? outProvinceAllocatedQuantity = freezed,Object? outProvinceAllocatedWeight = freezed,Object? provinceAllocatedQuantity = freezed,Object? provinceAllocatedWeight = freezed,Object? realAllocatedQuantity = freezed,Object? realAllocatedWeight = freezed,Object? coldHouseAllocatedWeight = freezed,Object? posAllocatedWeight = freezed,Object? segmentationWeight = freezed,Object? totalRemainQuantity = freezed,Object? totalRemainWeight = freezed,Object? freePrice = freezed,Object? approvedPrice = freezed,Object? approvedPriceStatus = freezed,Object? parentProduct = freezed,Object? killHouse = freezed,Object? guild = freezed,}) { + return _then(_InventoryModel( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int?,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable +as String?,createDate: freezed == createDate ? _self.createDate : createDate // ignore: cast_nullable_to_non_nullable +as String?,modifyDate: freezed == modifyDate ? _self.modifyDate : modifyDate // ignore: cast_nullable_to_non_nullable +as String?,trash: freezed == trash ? _self.trash : trash // ignore: cast_nullable_to_non_nullable +as bool?,name: freezed == name ? _self.name : name // ignore: cast_nullable_to_non_nullable +as String?,provinceGovernmentalCarcassesQuantity: freezed == provinceGovernmentalCarcassesQuantity ? _self.provinceGovernmentalCarcassesQuantity : provinceGovernmentalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,provinceGovernmentalCarcassesWeight: freezed == provinceGovernmentalCarcassesWeight ? _self.provinceGovernmentalCarcassesWeight : provinceGovernmentalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,provinceFreeCarcassesQuantity: freezed == provinceFreeCarcassesQuantity ? _self.provinceFreeCarcassesQuantity : provinceFreeCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,provinceFreeCarcassesWeight: freezed == provinceFreeCarcassesWeight ? _self.provinceFreeCarcassesWeight : provinceFreeCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,receiveGovernmentalCarcassesQuantity: freezed == receiveGovernmentalCarcassesQuantity ? _self.receiveGovernmentalCarcassesQuantity : receiveGovernmentalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,receiveGovernmentalCarcassesWeight: freezed == receiveGovernmentalCarcassesWeight ? _self.receiveGovernmentalCarcassesWeight : receiveGovernmentalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,receiveFreeCarcassesQuantity: freezed == receiveFreeCarcassesQuantity ? _self.receiveFreeCarcassesQuantity : receiveFreeCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,receiveFreeCarcassesWeight: freezed == receiveFreeCarcassesWeight ? _self.receiveFreeCarcassesWeight : receiveFreeCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,freeBuyingCarcassesQuantity: freezed == freeBuyingCarcassesQuantity ? _self.freeBuyingCarcassesQuantity : freeBuyingCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,freeBuyingCarcassesWeight: freezed == freeBuyingCarcassesWeight ? _self.freeBuyingCarcassesWeight : freeBuyingCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,totalGovernmentalCarcassesQuantity: freezed == totalGovernmentalCarcassesQuantity ? _self.totalGovernmentalCarcassesQuantity : totalGovernmentalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalGovernmentalCarcassesWeight: freezed == totalGovernmentalCarcassesWeight ? _self.totalGovernmentalCarcassesWeight : totalGovernmentalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,totalFreeBarsCarcassesQuantity: freezed == totalFreeBarsCarcassesQuantity ? _self.totalFreeBarsCarcassesQuantity : totalFreeBarsCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalFreeBarsCarcassesWeight: freezed == totalFreeBarsCarcassesWeight ? _self.totalFreeBarsCarcassesWeight : totalFreeBarsCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,weightAverage: freezed == weightAverage ? _self.weightAverage : weightAverage // ignore: cast_nullable_to_non_nullable +as double?,totalCarcassesQuantity: freezed == totalCarcassesQuantity ? _self.totalCarcassesQuantity : totalCarcassesQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalCarcassesWeight: freezed == totalCarcassesWeight ? _self.totalCarcassesWeight : totalCarcassesWeight // ignore: cast_nullable_to_non_nullable +as int?,freezingQuantity: freezed == freezingQuantity ? _self.freezingQuantity : freezingQuantity // ignore: cast_nullable_to_non_nullable +as int?,freezingWeight: freezed == freezingWeight ? _self.freezingWeight : freezingWeight // ignore: cast_nullable_to_non_nullable +as int?,lossWeight: freezed == lossWeight ? _self.lossWeight : lossWeight // ignore: cast_nullable_to_non_nullable +as int?,outProvinceAllocatedQuantity: freezed == outProvinceAllocatedQuantity ? _self.outProvinceAllocatedQuantity : outProvinceAllocatedQuantity // ignore: cast_nullable_to_non_nullable +as int?,outProvinceAllocatedWeight: freezed == outProvinceAllocatedWeight ? _self.outProvinceAllocatedWeight : outProvinceAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,provinceAllocatedQuantity: freezed == provinceAllocatedQuantity ? _self.provinceAllocatedQuantity : provinceAllocatedQuantity // ignore: cast_nullable_to_non_nullable +as int?,provinceAllocatedWeight: freezed == provinceAllocatedWeight ? _self.provinceAllocatedWeight : provinceAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,realAllocatedQuantity: freezed == realAllocatedQuantity ? _self.realAllocatedQuantity : realAllocatedQuantity // ignore: cast_nullable_to_non_nullable +as int?,realAllocatedWeight: freezed == realAllocatedWeight ? _self.realAllocatedWeight : realAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,coldHouseAllocatedWeight: freezed == coldHouseAllocatedWeight ? _self.coldHouseAllocatedWeight : coldHouseAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,posAllocatedWeight: freezed == posAllocatedWeight ? _self.posAllocatedWeight : posAllocatedWeight // ignore: cast_nullable_to_non_nullable +as int?,segmentationWeight: freezed == segmentationWeight ? _self.segmentationWeight : segmentationWeight // ignore: cast_nullable_to_non_nullable +as int?,totalRemainQuantity: freezed == totalRemainQuantity ? _self.totalRemainQuantity : totalRemainQuantity // ignore: cast_nullable_to_non_nullable +as int?,totalRemainWeight: freezed == totalRemainWeight ? _self.totalRemainWeight : totalRemainWeight // ignore: cast_nullable_to_non_nullable +as int?,freePrice: freezed == freePrice ? _self.freePrice : freePrice // ignore: cast_nullable_to_non_nullable +as int?,approvedPrice: freezed == approvedPrice ? _self.approvedPrice : approvedPrice // ignore: cast_nullable_to_non_nullable +as int?,approvedPriceStatus: freezed == approvedPriceStatus ? _self.approvedPriceStatus : approvedPriceStatus // ignore: cast_nullable_to_non_nullable +as bool?,parentProduct: freezed == parentProduct ? _self.parentProduct : parentProduct // ignore: cast_nullable_to_non_nullable +as int?,killHouse: freezed == killHouse ? _self.killHouse : killHouse // ignore: cast_nullable_to_non_nullable +as int?,guild: freezed == guild ? _self.guild : guild // ignore: cast_nullable_to_non_nullable +as int?, + )); +} + + +} + +// dart format on diff --git a/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.g.dart b/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.g.dart new file mode 100644 index 0000000..6bf5ba2 --- /dev/null +++ b/packages/chicken/lib/features/common/data/model/response/inventory/inventory_model.g.dart @@ -0,0 +1,127 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'inventory_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_InventoryModel _$InventoryModelFromJson( + Map json, +) => _InventoryModel( + id: (json['id'] as num?)?.toInt(), + key: json['key'] as String?, + createDate: json['create_date'] as String?, + modifyDate: json['modify_date'] as String?, + trash: json['trash'] as bool?, + name: json['name'] as String?, + provinceGovernmentalCarcassesQuantity: + (json['province_governmental_carcasses_quantity'] as num?)?.toInt(), + provinceGovernmentalCarcassesWeight: + (json['province_governmental_carcasses_weight'] as num?)?.toInt(), + provinceFreeCarcassesQuantity: + (json['province_free_carcasses_quantity'] as num?)?.toInt(), + provinceFreeCarcassesWeight: (json['province_free_carcasses_weight'] as num?) + ?.toInt(), + receiveGovernmentalCarcassesQuantity: + (json['receive_governmental_carcasses_quantity'] as num?)?.toInt(), + receiveGovernmentalCarcassesWeight: + (json['receive_governmental_carcasses_weight'] as num?)?.toInt(), + receiveFreeCarcassesQuantity: + (json['receive_free_carcasses_quantity'] as num?)?.toInt(), + receiveFreeCarcassesWeight: (json['receive_free_carcasses_weight'] as num?) + ?.toInt(), + freeBuyingCarcassesQuantity: (json['free_buying_carcasses_quantity'] as num?) + ?.toInt(), + freeBuyingCarcassesWeight: (json['free_buying_carcasses_weight'] as num?) + ?.toInt(), + totalGovernmentalCarcassesQuantity: + (json['total_governmental_carcasses_quantity'] as num?)?.toInt(), + totalGovernmentalCarcassesWeight: + (json['total_governmental_carcasses_weight'] as num?)?.toInt(), + totalFreeBarsCarcassesQuantity: + (json['total_free_bars_carcasses_quantity'] as num?)?.toInt(), + totalFreeBarsCarcassesWeight: + (json['total_free_bars_carcasses_weight'] as num?)?.toInt(), + weightAverage: (json['weight_average'] as num?)?.toDouble(), + totalCarcassesQuantity: (json['total_carcasses_quantity'] as num?)?.toInt(), + totalCarcassesWeight: (json['total_carcasses_weight'] as num?)?.toInt(), + freezingQuantity: (json['freezing_quantity'] as num?)?.toInt(), + freezingWeight: (json['freezing_weight'] as num?)?.toInt(), + lossWeight: (json['loss_weight'] as num?)?.toInt(), + outProvinceAllocatedQuantity: + (json['out_province_allocated_quantity'] as num?)?.toInt(), + outProvinceAllocatedWeight: (json['out_province_allocated_weight'] as num?) + ?.toInt(), + provinceAllocatedQuantity: (json['province_allocated_quantity'] as num?) + ?.toInt(), + provinceAllocatedWeight: (json['province_allocated_weight'] as num?)?.toInt(), + realAllocatedQuantity: (json['real_allocated_quantity'] as num?)?.toInt(), + realAllocatedWeight: (json['real_allocated_weight'] as num?)?.toInt(), + coldHouseAllocatedWeight: (json['cold_house_allocated_weight'] as num?) + ?.toInt(), + posAllocatedWeight: (json['pos_allocated_weight'] as num?)?.toInt(), + segmentationWeight: (json['segmentation_weight'] as num?)?.toInt(), + totalRemainQuantity: (json['total_remain_quantity'] as num?)?.toInt(), + totalRemainWeight: (json['total_remain_weight'] as num?)?.toInt(), + freePrice: (json['free_price'] as num?)?.toInt(), + approvedPrice: (json['approved_price'] as num?)?.toInt(), + approvedPriceStatus: json['approved_price_status'] as bool?, + parentProduct: (json['parent_product'] as num?)?.toInt(), + killHouse: (json['kill_house'] as num?)?.toInt(), + guild: (json['guild'] as num?)?.toInt(), +); + +Map _$InventoryModelToJson( + _InventoryModel instance, +) => { + 'id': instance.id, + 'key': instance.key, + 'create_date': instance.createDate, + 'modify_date': instance.modifyDate, + 'trash': instance.trash, + 'name': instance.name, + 'province_governmental_carcasses_quantity': + instance.provinceGovernmentalCarcassesQuantity, + 'province_governmental_carcasses_weight': + instance.provinceGovernmentalCarcassesWeight, + 'province_free_carcasses_quantity': instance.provinceFreeCarcassesQuantity, + 'province_free_carcasses_weight': instance.provinceFreeCarcassesWeight, + 'receive_governmental_carcasses_quantity': + instance.receiveGovernmentalCarcassesQuantity, + 'receive_governmental_carcasses_weight': + instance.receiveGovernmentalCarcassesWeight, + 'receive_free_carcasses_quantity': instance.receiveFreeCarcassesQuantity, + 'receive_free_carcasses_weight': instance.receiveFreeCarcassesWeight, + 'free_buying_carcasses_quantity': instance.freeBuyingCarcassesQuantity, + 'free_buying_carcasses_weight': instance.freeBuyingCarcassesWeight, + 'total_governmental_carcasses_quantity': + instance.totalGovernmentalCarcassesQuantity, + 'total_governmental_carcasses_weight': + instance.totalGovernmentalCarcassesWeight, + 'total_free_bars_carcasses_quantity': instance.totalFreeBarsCarcassesQuantity, + 'total_free_bars_carcasses_weight': instance.totalFreeBarsCarcassesWeight, + 'weight_average': instance.weightAverage, + 'total_carcasses_quantity': instance.totalCarcassesQuantity, + 'total_carcasses_weight': instance.totalCarcassesWeight, + 'freezing_quantity': instance.freezingQuantity, + 'freezing_weight': instance.freezingWeight, + 'loss_weight': instance.lossWeight, + 'out_province_allocated_quantity': instance.outProvinceAllocatedQuantity, + 'out_province_allocated_weight': instance.outProvinceAllocatedWeight, + 'province_allocated_quantity': instance.provinceAllocatedQuantity, + 'province_allocated_weight': instance.provinceAllocatedWeight, + 'real_allocated_quantity': instance.realAllocatedQuantity, + 'real_allocated_weight': instance.realAllocatedWeight, + 'cold_house_allocated_weight': instance.coldHouseAllocatedWeight, + 'pos_allocated_weight': instance.posAllocatedWeight, + 'segmentation_weight': instance.segmentationWeight, + 'total_remain_quantity': instance.totalRemainQuantity, + 'total_remain_weight': instance.totalRemainWeight, + 'free_price': instance.freePrice, + 'approved_price': instance.approvedPrice, + 'approved_price_status': instance.approvedPriceStatus, + 'parent_product': instance.parentProduct, + 'kill_house': instance.killHouse, + 'guild': instance.guild, +}; diff --git a/packages/chicken/lib/data/models/response/iran_province_city/iran_province_city_model.dart b/packages/chicken/lib/features/common/data/model/response/iran_province_city/iran_province_city_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/iran_province_city/iran_province_city_model.dart rename to packages/chicken/lib/features/common/data/model/response/iran_province_city/iran_province_city_model.dart diff --git a/packages/chicken/lib/data/models/response/iran_province_city/iran_province_city_model.freezed.dart b/packages/chicken/lib/features/common/data/model/response/iran_province_city/iran_province_city_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/iran_province_city/iran_province_city_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/iran_province_city/iran_province_city_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/iran_province_city/iran_province_city_model.g.dart b/packages/chicken/lib/features/common/data/model/response/iran_province_city/iran_province_city_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/iran_province_city/iran_province_city_model.g.dart rename to packages/chicken/lib/features/common/data/model/response/iran_province_city/iran_province_city_model.g.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart b/packages/chicken/lib/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart rename to packages/chicken/lib/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_distribution_info/kill_house_distribution_info.freezed.dart b/packages/chicken/lib/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_distribution_info/kill_house_distribution_info.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.freezed.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_distribution_info/kill_house_distribution_info.g.dart b/packages/chicken/lib/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_distribution_info/kill_house_distribution_info.g.dart rename to packages/chicken/lib/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.g.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_free_bar/kill_house_free_bar.dart b/packages/chicken/lib/features/common/data/model/response/kill_house_free_bar/kill_house_free_bar.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_free_bar/kill_house_free_bar.dart rename to packages/chicken/lib/features/common/data/model/response/kill_house_free_bar/kill_house_free_bar.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_free_bar/kill_house_free_bar.freezed.dart b/packages/chicken/lib/features/common/data/model/response/kill_house_free_bar/kill_house_free_bar.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_free_bar/kill_house_free_bar.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/kill_house_free_bar/kill_house_free_bar.freezed.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_free_bar/kill_house_free_bar.g.dart b/packages/chicken/lib/features/common/data/model/response/kill_house_free_bar/kill_house_free_bar.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_free_bar/kill_house_free_bar.g.dart rename to packages/chicken/lib/features/common/data/model/response/kill_house_free_bar/kill_house_free_bar.g.dart diff --git a/packages/chicken/lib/data/models/response/roles_products/roles_products.dart b/packages/chicken/lib/features/common/data/model/response/roles_products/roles_products.dart similarity index 100% rename from packages/chicken/lib/data/models/response/roles_products/roles_products.dart rename to packages/chicken/lib/features/common/data/model/response/roles_products/roles_products.dart diff --git a/packages/chicken/lib/data/models/response/roles_products/roles_products.freezed.dart b/packages/chicken/lib/features/common/data/model/response/roles_products/roles_products.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/roles_products/roles_products.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/roles_products/roles_products.freezed.dart diff --git a/packages/chicken/lib/data/models/response/roles_products/roles_products.g.dart b/packages/chicken/lib/features/common/data/model/response/roles_products/roles_products.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/roles_products/roles_products.g.dart rename to packages/chicken/lib/features/common/data/model/response/roles_products/roles_products.g.dart diff --git a/packages/chicken/lib/data/models/response/user_info/user_info_model.dart b/packages/chicken/lib/features/common/data/model/response/user_info/user_info_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_info/user_info_model.dart rename to packages/chicken/lib/features/common/data/model/response/user_info/user_info_model.dart diff --git a/packages/chicken/lib/data/models/response/user_info/user_info_model.freezed.dart b/packages/chicken/lib/features/common/data/model/response/user_info/user_info_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_info/user_info_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/user_info/user_info_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/user_info/user_info_model.g.dart b/packages/chicken/lib/features/common/data/model/response/user_info/user_info_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_info/user_info_model.g.dart rename to packages/chicken/lib/features/common/data/model/response/user_info/user_info_model.g.dart diff --git a/packages/chicken/lib/data/models/response/user_profile/user_profile.dart b/packages/chicken/lib/features/common/data/model/response/user_profile/user_profile.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_profile/user_profile.dart rename to packages/chicken/lib/features/common/data/model/response/user_profile/user_profile.dart diff --git a/packages/chicken/lib/data/models/response/user_profile/user_profile.freezed.dart b/packages/chicken/lib/features/common/data/model/response/user_profile/user_profile.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_profile/user_profile.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/user_profile/user_profile.freezed.dart diff --git a/packages/chicken/lib/data/models/response/user_profile/user_profile.g.dart b/packages/chicken/lib/features/common/data/model/response/user_profile/user_profile.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_profile/user_profile.g.dart rename to packages/chicken/lib/features/common/data/model/response/user_profile/user_profile.g.dart diff --git a/packages/chicken/lib/data/models/response/user_profile_model/user_profile_model.dart b/packages/chicken/lib/features/common/data/model/response/user_profile_model/user_profile_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_profile_model/user_profile_model.dart rename to packages/chicken/lib/features/common/data/model/response/user_profile_model/user_profile_model.dart diff --git a/packages/chicken/lib/data/models/response/user_profile_model/user_profile_model.freezed.dart b/packages/chicken/lib/features/common/data/model/response/user_profile_model/user_profile_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_profile_model/user_profile_model.freezed.dart rename to packages/chicken/lib/features/common/data/model/response/user_profile_model/user_profile_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/user_profile_model/user_profile_model.g.dart b/packages/chicken/lib/features/common/data/model/response/user_profile_model/user_profile_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/user_profile_model/user_profile_model.g.dart rename to packages/chicken/lib/features/common/data/model/response/user_profile_model/user_profile_model.g.dart diff --git a/packages/chicken/lib/data/repositories/auth/auth_repository.dart b/packages/chicken/lib/features/common/data/repositories/auth/auth_repository.dart similarity index 66% rename from packages/chicken/lib/data/repositories/auth/auth_repository.dart rename to packages/chicken/lib/features/common/data/repositories/auth/auth_repository.dart index 22d4599..444f63a 100644 --- a/packages/chicken/lib/data/repositories/auth/auth_repository.dart +++ b/packages/chicken/lib/features/common/data/repositories/auth/auth_repository.dart @@ -1,5 +1,5 @@ -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; abstract class AuthRepository { Future login({required Map authRequest}); diff --git a/packages/chicken/lib/data/repositories/auth/auth_repository_imp.dart b/packages/chicken/lib/features/common/data/repositories/auth/auth_repository_imp.dart similarity index 72% rename from packages/chicken/lib/data/repositories/auth/auth_repository_imp.dart rename to packages/chicken/lib/features/common/data/repositories/auth/auth_repository_imp.dart index 25992b2..b7ad64e 100644 --- a/packages/chicken/lib/data/repositories/auth/auth_repository_imp.dart +++ b/packages/chicken/lib/features/common/data/repositories/auth/auth_repository_imp.dart @@ -1,6 +1,6 @@ -import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart'; -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; import 'auth_repository.dart'; diff --git a/packages/chicken/lib/features/common/data/repositories/common/common_repository.dart b/packages/chicken/lib/features/common/data/repositories/common/common_repository.dart new file mode 100644 index 0000000..82fb2b5 --- /dev/null +++ b/packages/chicken/lib/features/common/data/repositories/common/common_repository.dart @@ -0,0 +1,85 @@ +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/request/change_password/change_password_request_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/bar_information/bar_information.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild_profile/guild_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class CommonRepository { + //region Remote + Future?> getInventory({ + required String token, + CancelToken? cancelToken, + }); + + Future getKillHouseDistributionInfo({ + required String token, + }); + + Future getGeneralBarInformation({ + required String token, + Map? queryParameters, + }); + + Future?> getRolesProducts({required String token}); + + Future?> getGuilds({ + required String token, + Map? queryParameters, + }); + + Future getProfile({required String token}); + + Future?> getProvince({CancelToken? cancelToken}); + + Future?> getCity({required String provinceName}); + + Future getUserProfile({required String token}); + + Future updateUserProfile({ + required String token, + required UserProfile userProfile, + }); + + Future updatePassword({ + required String token, + required ChangePasswordRequestModel model, + }); + + Future?> getSegmentation({ + required String token, + 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, + }); + + Future getBroadcastPrice({required String token}); + + //endregion + + //region local + Future initWidleyUsed(); + + WidelyUsedLocalModel? getAllWidely(); + //endregion +} diff --git a/packages/chicken/lib/features/common/data/repositories/common/common_repository_imp.dart b/packages/chicken/lib/features/common/data/repositories/common/common_repository_imp.dart new file mode 100644 index 0000000..550aab0 --- /dev/null +++ b/packages/chicken/lib/features/common/data/repositories/common/common_repository_imp.dart @@ -0,0 +1,172 @@ +import 'package:rasadyar_chicken/features/common/data/datasources/local/chicken_local.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/common/common_remote.dart'; +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/request/change_password/change_password_request_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/bar_information/bar_information.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild_profile/guild_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'common_repository.dart'; + +class CommonRepositoryImp implements CommonRepository { + final CommonRemoteDatasource remote; + final ChickenLocalDataSource local; + + CommonRepositoryImp({required this.remote, required this.local}); + + //region Remote + @override + Future?> getInventory({ + required String token, + CancelToken? cancelToken, + }) async { + var res = await remote.getInventory(token: token, cancelToken: cancelToken); + return res; + } + + @override + Future getKillHouseDistributionInfo({ + required String token, + }) async { + var res = await remote.getKillHouseDistributionInfo(token: token); + return res; + } + + @override + Future getGeneralBarInformation({ + required String token, + Map? queryParameters, + }) async { + var res = await remote.getGeneralBarInformation( + token: token, + queryParameters: queryParameters, + ); + return res; + } + + @override + Future?> getRolesProducts({required String token}) async { + var res = await remote.getRolesProducts(token: token); + return res; + } + + @override + Future?> getGuilds({ + required String token, + Map? queryParameters, + }) async { + var res = await remote.getGuilds( + token: token, + queryParameters: queryParameters, + ); + return res; + } + + @override + Future getProfile({required String token}) async { + var res = await remote.getProfile(token: token); + return res; + } + + @override + Future?> getCity({ + required String provinceName, + }) async { + var res = await remote.getCity(provinceName: provinceName); + return res; + } + + @override + Future?> getProvince({ + CancelToken? cancelToken, + }) async { + var res = await remote.getProvince(cancelToken: cancelToken); + return res; + } + + @override + Future getUserProfile({required String token}) async { + var res = await remote.getUserProfile(token: token); + return res; + } + + @override + Future updateUserProfile({ + required String token, + required UserProfile userProfile, + }) async { + await remote.updateUserProfile(token: token, userProfile: userProfile); + } + + @override + Future updatePassword({ + required String token, + required ChangePasswordRequestModel model, + }) async { + await remote.updatePassword(token: token, model: model); + } + + @override + Future?> getSegmentation({ + required String token, + Map? queryParameters, + }) async { + var res = await remote.getSegmentation( + token: token, + queryParameters: queryParameters, + ); + return res; + } + + @override + Future createSegmentation({ + required String token, + required SegmentationModel model, + }) async { + await remote.createSegmentation(token: token, model: model); + } + + @override + Future editSegmentation({ + required String token, + required SegmentationModel model, + }) async { + await remote.editSegmentation(token: token, model: model); + } + + @override + Future deleteSegmentation({ + required String token, + required String key, + }) async { + var res = await remote.deleteSegmentation(token: token, key: key); + return res; + } + + @override + Future getBroadcastPrice({required String token}) async { + var res = await remote.getBroadcastPrice(token: token); + return res; + } + + //endregion + + //region local + @override + WidelyUsedLocalModel? getAllWidely() => local.getAllWidely(); + + @override + Future initWidleyUsed() async { + await local.initWidleyUsed(); + } + + //endregion +} diff --git a/packages/chicken/lib/features/common/presentation/page/auth/logic.dart b/packages/chicken/lib/features/common/presentation/page/auth/logic.dart new file mode 100644 index 0000000..fa74d23 --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/page/auth/logic.dart @@ -0,0 +1,244 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/data/common/dio_error_handler.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/auth/auth_repository.dart'; +import 'package:rasadyar_chicken/features/common/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/widget/captcha/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +enum AuthType { useAndPass, otp } + +enum AuthStatus { init } + +enum OtpStatus { init, sent, verified, reSend } + +class AuthLogic extends GetxController with GetTickerProviderStateMixin { + GlobalKey formKey = GlobalKey(); + late AnimationController _textAnimationController; + late Animation textAnimation; + RxBool showCard = false.obs; + RxBool rememberMe = false.obs; + + Rx> formKeyOtp = GlobalKey().obs; + Rx> formKeySentOtp = GlobalKey().obs; + Rx usernameController = TextEditingController().obs; + Rx passwordController = TextEditingController().obs; + Rx phoneOtpNumberController = + TextEditingController().obs; + Rx otpCodeController = TextEditingController().obs; + + var captchaController = Get.find(); + + RxnString phoneNumber = RxnString(null); + RxBool isLoading = false.obs; + RxBool isDisabled = true.obs; + + GService gService = Get.find(); + TokenStorageService tokenStorageService = Get.find(); + + Rx authType = AuthType.useAndPass.obs; + Rx authStatus = AuthStatus.init.obs; + Rx otpStatus = OtpStatus.init.obs; + RxnString deviceName = RxnString(null); + + RxInt secondsRemaining = 120.obs; + Timer? _timer; + + AuthRepository authRepository = diChicken.get(); + + final Module _module = Get.arguments; + + @override + void onInit() { + super.onInit(); + _textAnimationController = + AnimationController( + vsync: this, + duration: const Duration(milliseconds: 1200), + ) + ..repeat(reverse: true, count: 2).whenComplete(() { + showCard.value = true; + }); + + textAnimation = CurvedAnimation( + parent: _textAnimationController, + curve: Curves.easeInOut, + ); + + initUserPassData(); + getDeviceModel(); + } + + @override + void onClose() { + _textAnimationController.dispose(); + _timer?.cancel(); + super.onClose(); + } + + void startTimer() { + _timer?.cancel(); + secondsRemaining.value = 120; + + _timer = Timer.periodic(const Duration(seconds: 1), (timer) { + if (secondsRemaining.value > 0) { + secondsRemaining.value--; + } else { + timer.cancel(); + } + }); + } + + void stopTimer() { + _timer?.cancel(); + } + + String get timeFormatted { + final minutes = secondsRemaining.value ~/ 60; + final seconds = secondsRemaining.value % 60; + return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}'; + } + + bool _isFormValid() { + final isCaptchaValid = + captchaController.formKey.currentState?.validate() ?? false; + final isFormValid = formKey.currentState?.validate() ?? false; + return isCaptchaValid && isFormValid; + } + + Future submitLoginForm() async { + if (!_isFormValid()) return; + AuthRepository authTmp = diChicken.get(); + isLoading.value = true; + await safeCall( + call: () => authTmp.login( + authRequest: { + "username": usernameController.value.text, + "password": passwordController.value.text, + }, + ), + onSuccess: (result) async { + await gService.saveSelectedModule(_module); + await tokenStorageService.saveModule(_module); + await tokenStorageService.saveAccessToken( + _module, + result?.accessToken ?? '', + ); + await tokenStorageService.saveRefreshToken( + _module, + result?.accessToken ?? '', + ); + var tmpRoles = result?.role?.where((element) { + final allowedRoles = { + 'poultryscience', + 'steward', + 'killhouse', + 'provinceinspector', + 'cityjahad', + 'jahad', + 'vetfarm', + 'provincesupervisor', + 'superadmin', + }; + + final lowerElement = element.toString().toLowerCase().trim(); + return allowedRoles.contains(lowerElement); + }).toList(); + if (tmpRoles?.length==1) { + await tokenStorageService.saveRoles(_module, tmpRoles ?? []); + } + + await tokenStorageService.saveRoles(_module, tmpRoles ?? []); + if (rememberMe.value) { + await tokenStorageService.saveUserPass( + _module, + usernameController.value.text, + passwordController.value.text, + ); + } + + authTmp.stewardAppLogin( + token: result?.accessToken ?? '', + queryParameters: { + "mobile": usernameController.value.text, + "device_name": deviceName.value, + }, + ); + + + Get.offAndToNamed(CommonRoutes.role); + + +/* if (tmpRoles!.length > 1) { + Get.offAndToNamed(CommonRoutes.role); + } else { + Get.offAllNamed(StewardRoutes.initSteward); + } */ + }, + onError: (error, stackTrace) { + if (error is DioException) { + diChicken.get().handle(error); + if ((error.type == DioExceptionType.unknown) || + (error.type == DioExceptionType.connectionError)) { + getUserInfo(usernameController.value.text); + } + } + captchaController.getCaptcha(); + }, + ); + isLoading.value = false; + } + + Future getUserInfo(String value) async { + isLoading.value = true; + await safeCall( + call: () async => await authRepository.getUserInfo(value), + onSuccess: (result) async { + if (result != null) { + await newSetupAuthDI(result.backend ?? ''); + await diChicken.allReady(); + } + }, + onError: (error, stackTrace) { + if (error is DioException) { + diChicken.get().handle(error); + } + captchaController.getCaptcha(); + }, + ); + isLoading.value = false; + } + + void initUserPassData() { + UserLocalModel? userLocalModel = tokenStorageService.getUserLocal( + Module.chicken, + ); + if (userLocalModel?.username != null && userLocalModel?.password != null) { + usernameController.value.text = userLocalModel?.username ?? ''; + passwordController.value.text = userLocalModel?.password ?? ''; + rememberMe.value = true; + } + } + + Future getDeviceModel() async { + final deviceInfo = DeviceInfoPlugin(); + + if (Platform.isAndroid) { + final info = await deviceInfo.androidInfo; + + deviceName.value = + 'Device:${info.manufacturer} Model:${info.model} version ${info.version.release}'; + } else if (Platform.isIOS) { + final info = await deviceInfo.iosInfo; + + deviceName.value = + 'Device:${info.utsname.machine} Model:${info.model} version ${info.systemVersion}'; + } else {} + } +} diff --git a/packages/chicken/lib/features/common/presentation/page/auth/view.dart b/packages/chicken/lib/features/common/presentation/page/auth/view.dart new file mode 100644 index 0000000..8e52e08 --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/page/auth/view.dart @@ -0,0 +1,394 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/captcha/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class AuthPage extends GetView { + const AuthPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + backGroundWidget: backGroundDecoration( + gradient: LinearGradient( + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + const Color(0xFFB2C9FF).withValues(alpha: 1.0), // 0% + const Color(0xFF40BB93).withValues(alpha: 0.11), // 50% + const Color(0xFF93B6D3).withValues(alpha: 1.0), // 100% + ], + stops: const [0.0, 0.5, 1.0], + ), + backgroundPath: Assets.images.patternChicken.path, + ), + onPopScopTaped: () => Get.back(result: -1), + child: Stack( + children: [ + Center( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 10.r), + child: FadeTransition( + opacity: controller.textAnimation, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 12, + children: [ + Text( + 'به سامانه رصدطیور خوش آمدید!', + textAlign: TextAlign.right, + style: AppFonts.yekan25Bold.copyWith( + color: AppColor.darkGreyDarkActive, + ), + ), + Text( + 'سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالا های اساسی', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: AppColor.darkGreyDarkActive, + ), + ), + ], + ), + ), + ), + ), + + Obx(() { + final screenHeight = MediaQuery.of(context).size.height; + final targetTop = (screenHeight - 676) / 2; + + return AnimatedPositioned( + duration: const Duration(milliseconds: 1200), + curve: Curves.linear, + top: controller.showCard.value ? targetTop : screenHeight, + left: 10.r, + right: 10.r, + child: Container( + width: 381.w, + height: 676.h, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(40), + ), + child: Column( + children: [ + SizedBox(height: 50.h), + LogoWidget( + vecPath: Assets.vec.rasadToyorSvg.path, + width: 85.w, + height: 85.h, + titleStyle: AppFonts.yekan20Bold.copyWith( + color: Color(0xFF4665AF), + ), + title: 'رصدطیور', + ), + SizedBox(height: 20.h), + useAndPassFrom(), + SizedBox(height: 24.h), + RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'مطالعه بیانیه ', + style: AppFonts.yekan16.copyWith( + color: AppColor.darkGreyDark, + ), + ), + TextSpan( + recognizer: TapGestureRecognizer() + ..onTap = () { + Get.bottomSheet( + privacyPolicyWidget(), + isScrollControlled: true, + enableDrag: true, + ignoreSafeArea: false, + ); + }, + text: 'حریم خصوصی', + style: AppFonts.yekan16.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + ), + ], + ), + ), + ); + }), + ], + ), + ); + } + + Widget useAndPassFrom() { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 30.r), + child: Form( + key: controller.formKey, + child: AutofillGroup( + child: Column( + children: [ + RTextField( + height: 40.h, + label: 'نام کاربری', + maxLength: 11, + maxLines: 1, + controller: controller.usernameController.value, + keyboardType: TextInputType.number, + inputFormatters: [PersianFormatter()], + initText: controller.usernameController.value.text, + autofillHints: [AutofillHints.username], + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: BorderSide(color: AppColor.textColor, width: 1), + ), + onChanged: (value) async { + controller.usernameController.value.text = value; + if (value.length == 11) { + await controller.getUserInfo(value); + } + }, + prefixIcon: Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 6, 8), + child: Assets.vec.callSvg.svg(width: 12, height: 12), + ), + suffixIcon: + controller.usernameController.value.text.trim().isNotEmpty + ? clearButton(() { + controller.usernameController.value.clear(); + controller.usernameController.refresh(); + }) + : null, + validator: (value) { + if (value == null || value.isEmpty) { + return '⚠️ شماره موبایل را وارد کنید'; + } else if (value.length < 10) { + return '⚠️ شماره موبایل باید 11 رقم باشد'; + } + return null; + }, + style: AppFonts.yekan13, + errorStyle: AppFonts.yekan13.copyWith( + color: AppColor.redNormal, + ), + labelStyle: AppFonts.yekan13, + boxConstraints: const BoxConstraints( + maxHeight: 40, + minHeight: 40, + maxWidth: 40, + minWidth: 40, + ), + ), + const SizedBox(height: 26), + ObxValue( + (passwordController) => RTextField( + height: 40.h, + label: 'رمز عبور', + filled: false, + obscure: true, + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: BorderSide(color: AppColor.textColor, width: 1), + ), + controller: passwordController.value, + autofillHints: [AutofillHints.password], + variant: RTextFieldVariant.password, + initText: passwordController.value.text, + inputFormatters: [PersianFormatter()], + onChanged: (value) { + passwordController.refresh(); + }, + validator: (value) { + if (value == null || value.isEmpty) { + return '⚠️ رمز عبور را وارد کنید'; + } + return null; + }, + style: AppFonts.yekan13, + errorStyle: AppFonts.yekan13.copyWith( + color: AppColor.redNormal, + ), + labelStyle: AppFonts.yekan13, + prefixIcon: Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 8, 8), + child: Assets.vec.keySvg.svg(width: 12, height: 12), + ), + boxConstraints: const BoxConstraints( + maxHeight: 34, + minHeight: 34, + maxWidth: 34, + minWidth: 34, + ), + ), + controller.passwordController, + ), + SizedBox(height: 26), + CaptchaWidget(), + + GestureDetector( + onTap: () { + controller.rememberMe.value = !controller.rememberMe.value; + }, + child: Row( + children: [ + ObxValue((data) { + return Checkbox( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + visualDensity: VisualDensity( + horizontal: -4, + vertical: 4, + ), + tristate: true, + value: data.value, + onChanged: (value) { + data.value = value ?? false; + }, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + activeColor: AppColor.blueNormal, + ); + }, controller.rememberMe), + Text( + 'مرا به خاطر بسپار', + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDark, + ), + ), + ], + ), + ), + + Obx(() { + return RElevated( + text: 'ورود', + isLoading: controller.isLoading.value, + onPressed: controller.isDisabled.value + ? null + : () async { + await controller.submitLoginForm(); + }, + width: Get.width, + height: 48, + ); + }), + ], + ), + ), + ), + ); + } + + Widget privacyPolicyWidget() { + return BaseBottomSheet( + child: Column( + spacing: 5, + children: [ + Container( + padding: EdgeInsets.all(8.w), + + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Column( + spacing: 3, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'بيانيه حريم خصوصی', + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + Text( + 'اطلاعات مربوط به هر شخص، حریم خصوصی وی محسوب می‌شود. حفاظت و حراست از اطلاعات شخصی در سامانه رصد یار، نه تنها موجب حفظ امنیت کاربران می‌شود، بلکه باعث اعتماد بیشتر و مشارکت آنها در فعالیت‌های جاری می‌گردد. هدف از این بیانیه، آگاه ساختن شما درباره ی نوع و نحوه ی استفاده از اطلاعاتی است که در هنگام استفاده از سامانه رصد یار ، از جانب شما دریافت می‌گردد. شرکت هوشمند سازان خود را ملزم به رعایت حریم خصوصی همه شهروندان و کاربران سامانه دانسته و آن دسته از اطلاعات کاربران را که فقط به منظور ارائه خدمات کفایت می‌کند، دریافت کرده و از انتشار آن یا در اختیار قرار دادن آن به دیگران خودداری مینماید.', + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + height: 1.8, + ), + ), + ], + ), + ), + Container( + padding: EdgeInsets.all(8.w), + + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 4, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'چگونگی جمع آوری و استفاده از اطلاعات کاربران', + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + Text( + '''الف: اطلاعاتی که شما خود در اختيار این سامانه قرار می‌دهيد، شامل موارد زيرهستند: +اقلام اطلاعاتی شامل شماره تلفن همراه، تاریخ تولد، کد پستی و کد ملی کاربران را دریافت مینماییم که از این اقلام، صرفا جهت احراز هویت کاربران استفاده خواهد شد. +ب: برخی اطلاعات ديگر که به صورت خودکار از شما دريافت میشود شامل موارد زير می‌باشد: +⦁ دستگاهی که از طریق آن سامانه رصد یار را مشاهده می‌نمایید( تلفن همراه، تبلت، رایانه). +⦁ نام و نسخه سیستم عامل و browser کامپیوتر شما. +⦁ اطلاعات صفحات بازدید شده. +⦁ تعداد بازدیدهای روزانه در درگاه. +⦁ هدف ما از دریافت این اطلاعات استفاده از آنها در تحلیل عملکرد کاربران درگاه می باشد تا بتوانیم در خدمت رسانی بهتر عمل کنیم. +''', + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + height: 1.8, + ), + ), + ], + ), + ), + Container( + padding: EdgeInsets.all(8.w), + + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 4, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + 'امنیت اطلاعات', + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + Text( + 'متعهدیم که امنیت اطلاعات شما را تضمین نماییم و برای جلوگیری از هر نوع دسترسی غیرمجاز و افشای اطلاعات شما از همه شیوه‌‌های لازم استفاده می‌کنیم تا امنیت اطلاعاتی را که به صورت آنلاین گردآوری می‌کنیم، حفظ شود. لازم به ذکر است در سامانه ما، ممکن است به سایت های دیگری لینک شوید، وقتی که شما از طریق این لینک‌ها از سامانه ما خارج می‌شوید، توجه داشته باشید که ما بر دیگر سایت ها کنترل نداریم و سازمان تعهدی بر حفظ حریم شخصی آنان در سایت مقصد نخواهد داشت و مراجعه کنندگان میبایست به بیانیه حریم شخصی آن سایت ها مراجعه نمایند.', + style: AppFonts.yekan14.copyWith( + color: AppColor.bgDark, + height: 1.8, + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/common/presentation/page/profile/logic.dart b/packages/chicken/lib/features/common/presentation/page/profile/logic.dart new file mode 100644 index 0000000..9622ecf --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/page/profile/logic.dart @@ -0,0 +1,257 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/common/data/model/request/change_password/change_password_request_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/common/common_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProfileLogic extends GetxController { + CommonRepository commonRepository = diChicken.get(); + GService gService = Get.find(); + TokenStorageService tokenService = Get.find(); + RxInt selectedInformationType = 0.obs; + Rxn birthDate = Rxn(); + + Rx> userProfile = Rx>( + Resource.loading(), + ); + Rx> userLocal = Rx>( + Resource.loading(), + ); + + TextEditingController nameController = TextEditingController(); + TextEditingController lastNameController = TextEditingController(); + TextEditingController nationalCodeController = TextEditingController(); + TextEditingController nationalIdController = TextEditingController(); + TextEditingController birthdayController = TextEditingController(); + + TextEditingController oldPasswordController = TextEditingController(); + TextEditingController newPasswordController = TextEditingController(); + TextEditingController retryNewPasswordController = TextEditingController(); + + RxList cites = [].obs; + Rxn selectedProvince = Rxn(); + Rxn selectedCity = Rxn(); + + GlobalKey formKey = GlobalKey(); + ImagePicker imagePicker = ImagePicker(); + Rxn selectedImage = Rxn(); + final RxnString _base64Image = RxnString(); + RxBool isOnLoading = false.obs; + + RxBool isUserInformationOpen = true.obs; + RxBool isUnitInformationOpen = false.obs; + + ScrollController scrollController = ScrollController(); + + @override + void onInit() { + super.onInit(); + ever(selectedImage, (data) async { + if (data?.path != null) { + _base64Image.value = await convertImageToBase64(data!.path); + } + }); + } + + @override + void onReady() { + super.onReady(); + getUserProfile(); + getUserRole(); + selectedProvince.listen((p0) => getCites()); + userProfile.listen((data) { + nameController.text = data.data?.firstName ?? ''; + lastNameController.text = data.data?.lastName ?? ''; + nationalCodeController.text = data.data?.nationalCode ?? ''; + nationalIdController.text = data.data?.nationalId ?? ''; + birthdayController.text = + data.data?.birthday?.toJalali.formatCompactDate() ?? ''; + birthDate.value = data.data?.birthday?.toJalali; + selectedProvince.value = IranProvinceCityModel( + name: data.data?.province ?? '', + id: data.data?.provinceNumber ?? 0, + ); + + selectedCity.value = IranProvinceCityModel( + name: data.data?.city ?? '', + id: data.data?.cityNumber ?? 0, + ); + }); + } + + Future getUserProfile() async { + userProfile.value = Resource.loading(); + await safeCall( + call: () async => await commonRepository.getUserProfile( + token: tokenService.accessToken.value!, + ), + onSuccess: (result) { + if (result != null) { + userProfile.value = Resource.success(result); + } + }, + onError: (error, stackTrace) {}, + ); + } + + Future getCites() async { + await safeCall( + call: () => commonRepository.getCity( + provinceName: selectedProvince.value?.name ?? '', + ), + onSuccess: (result) { + if (result != null && result.isNotEmpty) { + cites.value = result; + } + }, + ); + } + + Future updateUserProfile() async { + UserProfile userProfile = UserProfile( + firstName: nameController.text, + lastName: lastNameController.text, + nationalCode: nationalCodeController.text, + nationalId: nationalIdController.text, + birthday: birthDate.value + ?.toDateTime() + .formattedDashedGregorian + .toString(), + image: _base64Image.value, + personType: 'self', + type: 'self_profile', + ); + isOnLoading.value = true; + await safeCall( + call: () async => await commonRepository.updateUserProfile( + token: tokenService.accessToken.value!, + userProfile: userProfile, + ), + onSuccess: (result) { + isOnLoading.value = false; + }, + onError: (error, stackTrace) { + isOnLoading.value = false; + }, + ); + } + + Future updatePassword() async { + if (formKey.currentState?.validate() ?? false) { + ChangePasswordRequestModel model = ChangePasswordRequestModel( + username: userProfile.value.data?.mobile, + password: newPasswordController.text, + ); + + await safeCall( + call: () async => await commonRepository.updatePassword( + token: tokenService.accessToken.value!, + model: model, + ), + ); + } + } + + Future getUserRole() async { + userLocal.value = Resource.loading(); + await safeCall( + call: () async => tokenService.getUserLocal(Module.chicken), + onSuccess: (result) { + if (result != null) { + userLocal.value = Resource.success(result); + } + }, + onError: (error, stackTrace) {}, + ); + } + + void clearPasswordForm() { + oldPasswordController.clear(); + newPasswordController.clear(); + retryNewPasswordController.clear(); + } + + Future changeUserRole(String newRole) async { + dLog(newRole); + await gService.saveRoute(Module.chicken, newRole); + + Get.offAllNamed(newRole); + } + + void scrollToSelectedItem( + int index, { + double chipWidth = 100, + double spacing = 8, + GlobalKey? itemKey, + }) { + if (!scrollController.hasClients) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _performScroll(index, chipWidth, spacing, itemKey); + }); + } else { + _performScroll(index, chipWidth, spacing, itemKey); + } + } + + void _performScroll( + int index, + double chipWidth, + double spacing, + GlobalKey? itemKey, + ) { + if (!scrollController.hasClients) return; + + double targetOffset; + + // If we have a GlobalKey, use it for precise positioning + if (itemKey?.currentContext != null) { + final RenderBox? renderBox = + itemKey!.currentContext?.findRenderObject() as RenderBox?; + if (renderBox != null) { + final position = renderBox.localToGlobal(Offset.zero); + final scrollPosition = scrollController.position; + final viewportWidth = scrollPosition.viewportDimension; + final chipWidth = renderBox.size.width; + + // Get the scroll position of the item + final itemScrollPosition = position.dx - scrollPosition.pixels; + // Center the item + targetOffset = + scrollPosition.pixels + + itemScrollPosition - + (viewportWidth / 2) + + (chipWidth / 2); + } else { + // Fallback to estimated position + targetOffset = _calculateEstimatedPosition(index, chipWidth, spacing); + } + } else { + // Use estimated position + targetOffset = _calculateEstimatedPosition(index, chipWidth, spacing); + } + + scrollController.animateTo( + targetOffset.clamp(0.0, scrollController.position.maxScrollExtent), + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + + double _calculateEstimatedPosition( + int index, + double chipWidth, + double spacing, + ) { + final double itemPosition = (chipWidth + spacing) * index; + final double viewportWidth = scrollController.position.viewportDimension; + return itemPosition - (viewportWidth / 2) + (chipWidth / 2); + } + + @override + void onClose() { + scrollController.dispose(); + super.onClose(); + } +} diff --git a/packages/chicken/lib/features/common/presentation/page/profile/view.dart b/packages/chicken/lib/features/common/presentation/page/profile/view.dart new file mode 100644 index 0000000..3b3f635 --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/page/profile/view.dart @@ -0,0 +1,902 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart' hide Image; +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/data/common/fa_user_role.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class ProfilePage extends GetView { + const ProfilePage({super.key}); + + @override + Widget build(BuildContext context) { + return Column( + spacing: 30, + children: [ + Expanded( + child: Container( + color: AppColor.blueNormal, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row(), + ObxValue((data) { + final status = data.value.status; + + if (status == ResourceStatus.loading) { + return Container( + width: 128.w, + height: 128.h, + child: Center(child: CupertinoActivityIndicator(color: AppColor.greenNormal)), + ); + } + + if (status == ResourceStatus.error) { + return Container( + width: 128.w, + height: 128.h, + child: Center(child: Text('خطا در دریافت اطلاعات')), + ); + } + + // Default UI + + return Container( + width: 128.w, + height: 128.h, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: AppColor.blueLightActive, + ), + child: Center( + child: data.value.data?.image != null + ? CircleAvatar( + radius: 64.w, + backgroundImage: NetworkImage(data.value.data!.image!), + ) + : Icon(Icons.person, size: 64.w), + ), + ); + }, controller.userProfile), + ], + ), + ), + ), + Expanded( + flex: 3, + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + rolesWidget(), + SizedBox(height: 12.h), + + ObxValue((data) { + if (data.value.status == ResourceStatus.loading) { + return LoadingWidget(); + } else if (data.value.status == ResourceStatus.error) { + return ErrorWidget('خطا در دریافت اطلاعات کاربر'); + } else if (data.value.status == ResourceStatus.success) { + return Column( + spacing: 6, + children: [ + ObxValue((isOpen) { + return GestureDetector( + onTap: () => isOpen.toggle(), + child: AnimatedContainer( + height: isOpen.value ? 320.h : 47.h, + duration: Duration(milliseconds: 500), + curve: Curves.linear, + child: userProfileInformation(data.value), + ), + ); + }, controller.isUserInformationOpen), + + Visibility( + visible: + data.value.data?.unitName != null || + data.value.data?.unitAddress != null || + data.value.data?.unitPostalCode != null || + data.value.data?.unitRegistrationNumber != null || + data.value.data?.unitEconomicalNumber != null || + data.value.data?.unitCity != null || + data.value.data?.unitProvince != null || + data.value.data?.unitNationalId != null, + + child: ObxValue((isOpen) { + return GestureDetector( + onTap: () => isOpen.toggle(), + child: AnimatedContainer( + height: isOpen.value ? 320.h : 47.h, + duration: Duration(milliseconds: 500), + curve: Curves.linear, + child: unitInformation(data.value), + ), + ); + }, controller.isUnitInformationOpen), + ), + ], + ); + } else { + return SizedBox.shrink(); + } + }, controller.userProfile), + GestureDetector( + onTap: () { + Get.bottomSheet(changePasswordBottomSheet(), isScrollControlled: true); + }, + child: Container( + height: 47.h, + margin: EdgeInsets.symmetric(horizontal: 8, vertical: 8.h), + padding: EdgeInsets.symmetric(horizontal: 11.h, vertical: 8.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: const Color(0xFFD6D6D6)), + ), + child: Row( + spacing: 6, + children: [ + Assets.vec.lockSvg.svg( + width: 24.w, + height: 24.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + Text( + 'تغییر رمز عبور', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + ), + GestureDetector( + onTap: () { + Get.bottomSheet(exitBottomSheet(), isScrollControlled: true); + }, + child: Container( + height: 47.h, + margin: EdgeInsets.symmetric(horizontal: 8), + padding: EdgeInsets.symmetric(horizontal: 11.h, vertical: 8.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: const Color(0xFFD6D6D6)), + ), + child: Row( + spacing: 6, + children: [ + Assets.vec.logoutSvg.svg( + width: 24.w, + height: 24.h, + colorFilter: ColorFilter.mode(AppColor.redNormal, BlendMode.srcIn), + ), + Text( + 'خروج', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.redNormal), + ), + ], + ), + ), + ), + + SizedBox(height: 100), + ], + ), + ), + ), + ], + ); + } + + Container invoiceIssuanceInformation() => Container(); + + Widget bankInformationWidget() => Column( + spacing: 16, + children: [ + itemList(title: 'نام بانک', content: 'سامان'), + itemList(title: 'نام صاحب حساب', content: 'رضا رضایی'), + itemList(title: 'شماره کارت ', content: '54154545415'), + itemList(title: 'شماره حساب', content: '62565263263652'), + itemList(title: 'شماره شبا', content: '62565263263652'), + ], + ); + + Widget userProfileInformation(Resource value) { + UserProfile item = value.data!; + return Stack( + clipBehavior: Clip.none, + children: [ + Positioned.fill( + child: ObxValue( + (val) => Container( + height: val.value ? 320.h : 47.h, + margin: EdgeInsets.symmetric(horizontal: 8, vertical: val.value ? 8 : 0), + padding: EdgeInsets.symmetric(horizontal: 11.h, vertical: 8.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.5, color: AppColor.darkGreyLight), + ), + child: val.value + ? Column( + spacing: 6, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + GestureDetector( + onTap: () { + Get.bottomSheet( + userInformationBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ); + }, + child: Assets.vec.editSvg.svg( + width: 24.w, + height: 24.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ), + + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), + child: Column( + children: [ + itemList( + title: 'نام و نام خانوادگی', + content: item.fullname ?? 'نامشخص', + icon: Assets.vec.userSvg.path, + hasColoredBox: true, + ), + itemList( + title: 'کدملی', + content: item.nationalId ?? 'نامشخص', + icon: Assets.vec.tagUserSvg.path, + ), + itemList( + title: 'موبایل', + content: item.mobile ?? 'نامشخص', + icon: Assets.vec.callSvg.path, + ), + + itemList( + title: 'شماره شناسنامه', + content: item.nationalCode ?? 'نامشخص', + icon: Assets.vec.userSquareSvg.path, + ), + itemList( + title: 'تاریخ تولد', + content: item.birthday?.toJalali.formatCompactDate() ?? 'نامشخص', + icon: Assets.vec.calendarSvg.path, + ), + //todo + itemList( + title: 'استان', + content: item.province ?? 'نامشخص', + icon: Assets.vec.pictureFrameSvg.path, + ), + itemList( + title: 'شهر', + content: item.city ?? 'نامشخص', + icon: Assets.vec.mapSvg.path, + ), + ], + ), + ), + ], + ) + : Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [Icon(CupertinoIcons.chevron_down, color: AppColor.iconColor)], + ), + ), + controller.isUserInformationOpen, + ), + ), + ObxValue( + (isOpen) => AnimatedPositioned( + right: 16, + top: isOpen.value ? -7 : 11, + duration: Duration(milliseconds: 500), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: isOpen.value + ? BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.5, color: Color(0xFFA9A9A9)), + ) + : null, + child: Text( + 'اطلاعات هویتی', + style: AppFonts.yekan16.copyWith(color: AppColor.iconColor), + ), + ), + ), + controller.isUserInformationOpen, + ), + ], + ); + } + + Widget unitInformation(Resource value) { + UserProfile item = value.data!; + return Stack( + clipBehavior: Clip.none, + children: [ + Positioned.fill( + child: ObxValue( + (val) => Container( + height: val.value ? 320.h : 47.h, + margin: EdgeInsets.symmetric(horizontal: 8, vertical: val.value ? 12 : 0), + padding: EdgeInsets.symmetric(horizontal: 11.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.5, color: AppColor.darkGreyLight), + ), + child: val.value + ? Column( + children: [ + SizedBox(height: 5.h), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + GestureDetector( + onTap: () { + Get.bottomSheet( + userInformationBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ); + }, + child: Assets.vec.editSvg.svg( + width: 24.w, + height: 24.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ), + + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), + child: Column( + spacing: 2, + children: [ + itemList( + title: 'نام صنفی', + content: item.unitName ?? 'نامشخص', + hasColoredBox: true, + visible: item.unitName != null, + ), + itemList( + title: 'شناسنامه ملی', + content: item.unitNationalId ?? 'نامشخص', + visible: item.unitName != null, + ), + itemList( + title: 'شماره ثبت', + content: item.unitRegistrationNumber ?? 'نامشخص', + visible: item.unitName != null, + ), + + itemList( + title: 'کد اقتصادی', + content: item.unitEconomicalNumber ?? 'نامشخص', + visible: item.unitName != null, + ), + itemList( + title: 'کد پستی', + content: item.unitPostalCode ?? 'نامشخص', + visible: item.unitName != null, + ), + + itemList( + title: 'استان', + content: item.province ?? 'نامشخص', + visible: item.unitName != null, + ), + itemList( + title: 'شهر', + content: item.city ?? 'نامشخص', + visible: item.unitName != null, + ), + itemList(title: 'آدرس', content: item.unitAddress ?? 'نامشخص'), + ], + ), + ), + ], + ) + : Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [Icon(CupertinoIcons.chevron_down, color: AppColor.iconColor)], + ), + ), + controller.isUnitInformationOpen, + ), + ), + ObxValue( + (isOpen) => AnimatedPositioned( + right: 16, + top: isOpen.value ? -2 : 11, + duration: Duration(milliseconds: 500), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: isOpen.value + ? BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.5, color: Color(0xFFA9A9A9)), + ) + : null, + child: Text( + 'اطلاعات صنفی', + style: AppFonts.yekan16.copyWith(color: AppColor.iconColor), + ), + ), + ), + controller.isUnitInformationOpen, + ), + ], + ); + } + + Widget itemList({ + required String title, + required String content, + String? icon, + bool hasColoredBox = false, + bool? visible, + }) => Visibility( + visible: visible ?? true, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 6.h), + decoration: BoxDecoration( + color: hasColoredBox ? AppColor.greenLight : Colors.transparent, + borderRadius: BorderRadius.circular(8), + border: hasColoredBox + ? Border.all(width: 0.25, color: AppColor.bgDark) + : Border.all(width: 0, color: Colors.transparent), + ), + child: Row( + spacing: 4, + children: [ + if (icon != null) + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: SvgGenImage.vec(icon).svg( + width: 20.w, + height: 20.h, + colorFilter: ColorFilter.mode(AppColor.textColor, BlendMode.srcIn), + ), + ), + Text(title, style: AppFonts.yekan14.copyWith(color: AppColor.textColor)), + Spacer(), + Text(content, style: AppFonts.yekan14.copyWith(color: AppColor.textColor)), + ], + ), + ), + ); + + Widget cardActionWidget({ + required String title, + required VoidCallback onPressed, + required String icon, + bool selected = false, + ColorFilter? color, + Color? cardColor, + Color? cardIconColor, + Color? textColor, + }) { + return GestureDetector( + onTap: onPressed, + child: Column( + spacing: 4, + children: [ + Container( + width: 52.w, + height: 52.h, + padding: EdgeInsets.all(6), + decoration: ShapeDecoration( + color: cardColor ?? AppColor.blueLight, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + ), + child: Container( + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: cardIconColor, + borderRadius: BorderRadius.circular(8), + ), + child: SvgGenImage.vec(icon).svg( + width: 40.w, + height: 40.h, + colorFilter: color ?? ColorFilter.mode(Colors.white, BlendMode.srcIn), + ), + ), + ), + SizedBox(height: 2), + Text( + title, + style: AppFonts.yekan10.copyWith(color: AppColor.textColor), + textAlign: TextAlign.center, + ), + ], + ), + ); + } + + Widget userInformationBottomSheet() { + return BaseBottomSheet( + height: 750.h, + child: SingleChildScrollView( + child: Column( + spacing: 8, + children: [ + Text( + 'ویرایش اطلاعات هویتی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover), + ), + + 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.nameController, + label: 'نام', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + ), + RTextField( + controller: controller.lastNameController, + label: 'نام خانوادگی', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + ), + RTextField( + controller: controller.nationalCodeController, + label: 'شماره شناسنامه', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + ), + RTextField( + controller: controller.nationalIdController, + label: 'کد ملی', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + ), + + ObxValue((data) { + return RTextField( + controller: controller.birthdayController, + label: 'تاریخ تولد', + initText: data.value?.formatCompactDate() ?? '', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + onTap: () {}, + ); + }, controller.birthDate), + + SizedBox(), + ], + ), + ), + SizedBox(), + + 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: 8, + children: [ + Text( + 'عکس پروفایل', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + ObxValue((data) { + return Container( + width: Get.width, + height: 270, + decoration: BoxDecoration( + color: AppColor.lightGreyNormal, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.blackLight), + ), + child: Center( + child: data.value == null + ? Padding( + padding: const EdgeInsets.fromLTRB(30, 10, 10, 30), + child: Image.network( + controller.userProfile.value.data?.image ?? '', + ), + ) + : Image.file(File(data.value!.path), fit: BoxFit.cover), + ), + ); + }, controller.selectedImage), + + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RElevated( + text: 'گالری', + width: 150.w, + height: 40.h, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + onPressed: () async { + controller.selectedImage.value = await controller.imagePicker.pickImage( + source: ImageSource.gallery, + imageQuality: 60, + maxWidth: 1080, + maxHeight: 720, + ); + }, + ), + SizedBox(width: 16), + ROutlinedElevated( + text: 'دوربین', + width: 150.w, + height: 40.h, + textStyle: AppFonts.yekan20.copyWith(color: AppColor.blueNormal), + onPressed: () async { + controller.selectedImage.value = await controller.imagePicker.pickImage( + source: ImageSource.camera, + imageQuality: 60, + maxWidth: 1080, + maxHeight: 720, + ); + }, + ), + ], + ), + ], + ), + ), + Row( + spacing: 16, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ObxValue((data) { + return RElevated( + height: 40.h, + text: 'ویرایش', + isLoading: data.value, + onPressed: () async { + await controller.updateUserProfile(); + controller.getUserProfile(); + Get.back(); + }, + ); + }, controller.isOnLoading), + ROutlinedElevated( + height: 40.h, + text: 'انصراف', + borderColor: AppColor.blueNormal, + onPressed: () { + Get.back(); + }, + ), + ], + ), + ], + ), + ), + ); + } + + Widget changePasswordBottomSheet() { + return BaseBottomSheet( + height: 400.h, + child: SingleChildScrollView( + child: Form( + key: controller.formKey, + child: Column( + spacing: 8, + children: [ + Text( + 'تغییر رمز عبور', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.darkGreyDarkHover), + ), + SizedBox(), + RTextField( + controller: controller.oldPasswordController, + hintText: 'رمز عبور قبلی', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'رمز عبور را وارد کنید'; + } else if (controller.userProfile.value.data?.password != value) { + return 'رمز عبور صحیح نیست'; + } + return null; + }, + ), + RTextField( + controller: controller.newPasswordController, + hintText: 'رمز عبور جدید', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'رمز عبور را وارد کنید'; + } else if (value.length < 6) { + return 'رمز عبور باید بیش از 6 کارکتر باشد.'; + } + return null; + }, + ), + RTextField( + controller: controller.retryNewPasswordController, + hintText: 'تکرار رمز عبور جدید', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'رمز عبور را وارد کنید'; + } else if (value.length < 6) { + return 'رمز عبور باید بیش از 6 کارکتر باشد.'; + } else if (controller.newPasswordController.text != value) { + return 'رمز عبور جدید یکسان نیست'; + } + return null; + }, + ), + + SizedBox(), + + Row( + spacing: 16, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RElevated( + height: 40.h, + text: 'ویرایش', + onPressed: () async { + if (controller.formKey.currentState?.validate() != true) { + return; + } + await controller.updatePassword(); + controller.getUserProfile(); + controller.clearPasswordForm(); + Get.back(); + }, + ), + ROutlinedElevated( + height: 40.h, + text: 'انصراف', + borderColor: AppColor.blueNormal, + onPressed: () { + Get.back(); + }, + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget exitBottomSheet() { + return BaseBottomSheet( + height: 220.h, + child: SingleChildScrollView( + child: Form( + key: controller.formKey, + child: Column( + spacing: 8, + children: [ + Text('خروج', style: AppFonts.yekan16Bold.copyWith(color: AppColor.error)), + SizedBox(), + Text( + 'آیا مطمئن هستید که می‌خواهید از حساب کاربری خود خارج شوید؟', + textAlign: TextAlign.center, + style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor), + ), + + SizedBox(), + + Row( + spacing: 16, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RElevated( + height: 40.h, + text: 'خروج', + backgroundColor: AppColor.error, + onPressed: () async { + await Future.wait([ + controller.tokenService.deleteModuleTokens(Module.chicken), + controller.gService.clearSelectedModule(), + ]).then((value) async { + await removeChickenDI(); + Get.offAllNamed("/moduleList"); + }); + }, + ), + ROutlinedElevated( + height: 40.h, + text: 'انصراف', + borderColor: AppColor.blueNormal, + onPressed: () { + Get.back(); + }, + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget rolesWidget() { + return ObxValue((data) { + if (data.value.status == ResourceStatus.loading) { + return CupertinoActivityIndicator(); + } else if (data.value.status == ResourceStatus.error) { + return ErrorWidget('خطا در دریافت اطلاعات کاربر'); + } else if (data.value.status == ResourceStatus.success) { + List? item = data.value.data?.roles; + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + padding: EdgeInsets.symmetric(horizontal: 8.w), + physics: BouncingScrollPhysics(), + + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8.w, + children: List.generate(item?.length ?? 0, (index) { + Map tmpRole = getFaUserRoleWithOnTap(item?[index]); + return CustomChip( + isSelected: controller.gService.getRoute(Module.chicken) == tmpRole.values.first, + title: tmpRole.keys.first, + index: index, + onTap: (int p1) { + controller.changeUserRole(tmpRole.values.first); + }, + ); + }), + ), + ); + } else { + return SizedBox.shrink(); + } + }, controller.userLocal); + } +} diff --git a/packages/chicken/lib/features/common/presentation/page/role/logic.dart b/packages/chicken/lib/features/common/presentation/page/role/logic.dart new file mode 100644 index 0000000..3253738 --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/page/role/logic.dart @@ -0,0 +1,18 @@ +import 'package:rasadyar_core/core.dart'; + +class RoleLogic extends GetxController { + TokenStorageService tokenService = Get.find(); + GService gService = Get.find(); + RxList roles = [].obs; + + @override + void onInit() { + super.onInit(); + List items = tokenService.getUserLocal(Module.chicken)!.roles ?? []; + if (items.isNotEmpty) { + roles.assignAll(items); + } + } + + +} diff --git a/packages/chicken/lib/features/common/presentation/page/role/view.dart b/packages/chicken/lib/features/common/presentation/page/role/view.dart new file mode 100644 index 0000000..0f36180 --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/page/role/view.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/data/common/fa_user_role.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class RolePage extends GetView { + const RolePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + child: Column( + children: [ + Assets.images.selectRole.image(height: 212.h, width: Get.width.w, fit: BoxFit.cover), + ObxValue((data) { + return Expanded( + child: GridView.builder( + physics: BouncingScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisSpacing: 12.h, + crossAxisSpacing: 12.w, + childAspectRatio: 2, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + Map role = getFaUserRoleWithOnTap(data[index]); + return roleCard( + title: role.keys.first, + onTap: () async { + try { + String route = role.values.first; + await controller.gService.saveRoute(Module.chicken, route); + + await controller.gService.saveRole(Module.chicken, data[index]); + Get.offAllNamed(route); + } catch (e) { + eLog( + "احتمالا در\n ``getFaUserRoleWithOnTap`` \nروت اش را تعریف نکردی 👻👻 ==>$e ", + ); + } + }, + ); + }, + ), + ); + }, controller.roles), + ], + ), + ); + } +} + +Widget roleCard({required String title, Function()? onTap, int? width, int? height}) { + return Container( + width: width?.w ?? 128.w, + height: height?.h ?? 48.h, + margin: EdgeInsets.all(8.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.r), + border: Border.all(color: AppColor.blueNormal, width: 1.w), + ), + child: InkWell( + onTap: onTap, + child: Center( + child: Text( + title, + style: AppFonts.yekan12Bold.copyWith(color: AppColor.blueNormal), + textAlign: TextAlign.center, + ), + ), + ), + ); +} diff --git a/packages/chicken/lib/features/common/presentation/routes/pages.dart b/packages/chicken/lib/features/common/presentation/routes/pages.dart new file mode 100644 index 0000000..eb1bd53 --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/routes/pages.dart @@ -0,0 +1,34 @@ +import 'package:rasadyar_chicken/features/common/presentation/page/auth/logic.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/auth/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/logic.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/role/logic.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/role/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_chicken/presentation/widget/captcha/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class CommonPages { + CommonPages._(); + + static List get pages => [ + GetPage( + name: CommonRoutes.auth, + page: () => AuthPage(), + binding: BindingsBuilder(() { + Get.lazyPut(() => AuthLogic()); + Get.lazyPut(() => CaptchaWidgetLogic()); + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + }), + ), + GetPage( + name: CommonRoutes.role, + page: () => RolePage(), + binding: BindingsBuilder(() { + Get.lazyPut(() => RoleLogic()); + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + }), + ), + ]; +} diff --git a/packages/chicken/lib/features/common/presentation/routes/routes.dart b/packages/chicken/lib/features/common/presentation/routes/routes.dart new file mode 100644 index 0000000..17606e7 --- /dev/null +++ b/packages/chicken/lib/features/common/presentation/routes/routes.dart @@ -0,0 +1,8 @@ +sealed class CommonRoutes { + CommonRoutes._(); + + static const auth = '/AuthChicken'; + static const _base = '/chicken'; + static const role = '$_base/role'; + static const String profile = '$_base/profile'; +} diff --git a/packages/chicken/lib/features/common/profile/logic.dart b/packages/chicken/lib/features/common/profile/logic.dart index dc8447b..9622ecf 100644 --- a/packages/chicken/lib/features/common/profile/logic.dart +++ b/packages/chicken/lib/features/common/profile/logic.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:rasadyar_chicken/data/di/chicken_di.dart'; -import 'package:rasadyar_chicken/data/models/request/change_password/change_password_request_model.dart'; -import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart'; -import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart'; +import 'package:rasadyar_chicken/features/common/data/model/request/change_password/change_password_request_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/common/common_repository.dart'; import 'package:rasadyar_core/core.dart'; class ProfileLogic extends GetxController { - ChickenRepository chickenRepository = diChicken.get(); + CommonRepository commonRepository = diChicken.get(); GService gService = Get.find(); TokenStorageService tokenService = Get.find(); RxInt selectedInformationType = 0.obs; @@ -43,6 +43,8 @@ class ProfileLogic extends GetxController { RxBool isUserInformationOpen = true.obs; RxBool isUnitInformationOpen = false.obs; + ScrollController scrollController = ScrollController(); + @override void onInit() { super.onInit(); @@ -79,11 +81,10 @@ class ProfileLogic extends GetxController { }); } - Future getUserProfile() async { userProfile.value = Resource.loading(); await safeCall( - call: () async => await chickenRepository.getUserProfile( + call: () async => await commonRepository.getUserProfile( token: tokenService.accessToken.value!, ), onSuccess: (result) { @@ -97,7 +98,7 @@ class ProfileLogic extends GetxController { Future getCites() async { await safeCall( - call: () => chickenRepository.getCity( + call: () => commonRepository.getCity( provinceName: selectedProvince.value?.name ?? '', ), onSuccess: (result) { @@ -124,7 +125,7 @@ class ProfileLogic extends GetxController { ); isOnLoading.value = true; await safeCall( - call: () async => await chickenRepository.updateUserProfile( + call: () async => await commonRepository.updateUserProfile( token: tokenService.accessToken.value!, userProfile: userProfile, ), @@ -145,7 +146,7 @@ class ProfileLogic extends GetxController { ); await safeCall( - call: () async => await chickenRepository.updatePassword( + call: () async => await commonRepository.updatePassword( token: tokenService.accessToken.value!, model: model, ), @@ -178,4 +179,79 @@ class ProfileLogic extends GetxController { Get.offAllNamed(newRole); } + + void scrollToSelectedItem( + int index, { + double chipWidth = 100, + double spacing = 8, + GlobalKey? itemKey, + }) { + if (!scrollController.hasClients) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _performScroll(index, chipWidth, spacing, itemKey); + }); + } else { + _performScroll(index, chipWidth, spacing, itemKey); + } + } + + void _performScroll( + int index, + double chipWidth, + double spacing, + GlobalKey? itemKey, + ) { + if (!scrollController.hasClients) return; + + double targetOffset; + + // If we have a GlobalKey, use it for precise positioning + if (itemKey?.currentContext != null) { + final RenderBox? renderBox = + itemKey!.currentContext?.findRenderObject() as RenderBox?; + if (renderBox != null) { + final position = renderBox.localToGlobal(Offset.zero); + final scrollPosition = scrollController.position; + final viewportWidth = scrollPosition.viewportDimension; + final chipWidth = renderBox.size.width; + + // Get the scroll position of the item + final itemScrollPosition = position.dx - scrollPosition.pixels; + // Center the item + targetOffset = + scrollPosition.pixels + + itemScrollPosition - + (viewportWidth / 2) + + (chipWidth / 2); + } else { + // Fallback to estimated position + targetOffset = _calculateEstimatedPosition(index, chipWidth, spacing); + } + } else { + // Use estimated position + targetOffset = _calculateEstimatedPosition(index, chipWidth, spacing); + } + + scrollController.animateTo( + targetOffset.clamp(0.0, scrollController.position.maxScrollExtent), + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + + double _calculateEstimatedPosition( + int index, + double chipWidth, + double spacing, + ) { + final double itemPosition = (chipWidth + spacing) * index; + final double viewportWidth = scrollController.position.viewportDimension; + return itemPosition - (viewportWidth / 2) + (chipWidth / 2); + } + + @override + void onClose() { + scrollController.dispose(); + super.onClose(); + } } diff --git a/packages/chicken/lib/features/common/profile/view.dart b/packages/chicken/lib/features/common/profile/view.dart index 6db6aa2..3b3f635 100644 --- a/packages/chicken/lib/features/common/profile/view.dart +++ b/packages/chicken/lib/features/common/profile/view.dart @@ -4,7 +4,7 @@ import 'package:flutter/cupertino.dart' hide Image; import 'package:flutter/material.dart'; import 'package:rasadyar_chicken/data/common/fa_user_role.dart'; import 'package:rasadyar_chicken/data/di/chicken_di.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile/user_profile.dart'; import 'package:rasadyar_core/core.dart'; import 'logic.dart'; @@ -877,6 +877,7 @@ class ProfilePage extends GetView { scrollDirection: Axis.horizontal, padding: EdgeInsets.symmetric(horizontal: 8.w), physics: BouncingScrollPhysics(), + child: Row( mainAxisAlignment: MainAxisAlignment.center, spacing: 8.w, diff --git a/packages/chicken/lib/features/inspection/data/datasources/remote/chicken_remote_data_source.dart b/packages/chicken/lib/features/inspection/data/datasources/remote/chicken_remote_data_source.dart new file mode 100644 index 0000000..ddf9315 --- /dev/null +++ b/packages/chicken/lib/features/inspection/data/datasources/remote/chicken_remote_data_source.dart @@ -0,0 +1,3 @@ +abstract class ChickenRemoteDataSource { + Future getChickens(); +} \ No newline at end of file diff --git a/packages/chicken/lib/features/jahad/data/datasources/remote/jahad_remote_data_source.dart b/packages/chicken/lib/features/jahad/data/datasources/remote/jahad_remote_data_source.dart new file mode 100644 index 0000000..8499d17 --- /dev/null +++ b/packages/chicken/lib/features/jahad/data/datasources/remote/jahad_remote_data_source.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class JahadRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/jahad/data/datasources/remote/jahad_remote_data_source_impl.dart b/packages/chicken/lib/features/jahad/data/datasources/remote/jahad_remote_data_source_impl.dart new file mode 100644 index 0000000..d94513c --- /dev/null +++ b/packages/chicken/lib/features/jahad/data/datasources/remote/jahad_remote_data_source_impl.dart @@ -0,0 +1,39 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/jahad/data/datasources/remote/jahad_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class JahadRemoteDataSourceImpl implements JahadRemoteDataSource { + final DioRemote _httpClient; + + JahadRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} diff --git a/packages/chicken/lib/features/jahad/data/di/jahad_di.dart b/packages/chicken/lib/features/jahad/data/di/jahad_di.dart new file mode 100644 index 0000000..3a935d2 --- /dev/null +++ b/packages/chicken/lib/features/jahad/data/di/jahad_di.dart @@ -0,0 +1,36 @@ +import 'package:rasadyar_chicken/features/jahad/data/datasources/remote/jahad_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/jahad/data/datasources/remote/jahad_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/jahad/data/repositories/jahad_repository.dart'; +import 'package:rasadyar_chicken/features/jahad/data/repositories/jahad_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for jahad feature +Future setupJahadDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => JahadRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => JahadRepositoryImpl(di.get()), + ); +} + +/// Re-register jahad dependencies (used when base URL changes) +Future reRegisterJahadDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => JahadRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => JahadRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/jahad/data/repositories/jahad_repository.dart b/packages/chicken/lib/features/jahad/data/repositories/jahad_repository.dart new file mode 100644 index 0000000..84c763a --- /dev/null +++ b/packages/chicken/lib/features/jahad/data/repositories/jahad_repository.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class JahadRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/jahad/data/repositories/jahad_repository_impl.dart b/packages/chicken/lib/features/jahad/data/repositories/jahad_repository_impl.dart new file mode 100644 index 0000000..4c52ffc --- /dev/null +++ b/packages/chicken/lib/features/jahad/data/repositories/jahad_repository_impl.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/jahad/data/datasources/remote/jahad_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/jahad/data/repositories/jahad_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class JahadRepositoryImpl implements JahadRepository { + final JahadRemoteDataSource _remote; + + JahadRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/jahad/jahad.dart b/packages/chicken/lib/features/jahad/jahad.dart new file mode 100644 index 0000000..d0d033a --- /dev/null +++ b/packages/chicken/lib/features/jahad/jahad.dart @@ -0,0 +1,3 @@ +export 'data/di/jahad_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..e1ef389 --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,95 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + JahadRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'Jahad', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..1d116f6 --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart @@ -0,0 +1,244 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/active_hatching/view.dart +import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/active_hatching/logic.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/jahad/presentation/pages/active_hatching/view.dart +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: jahadActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart b/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart new file mode 100644 index 0000000..f8d9114 --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/home/logic.dart @@ -0,0 +1,29 @@ +import 'package:rasadyar_chicken/features/jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class JahadActionItem { + final String title; + final String route; + final String icon; + + JahadActionItem({ + required this.title, + required this.route, + required this.icon, + }); +} + +class JahadHomeLogic extends GetxController { + RxList items = [ + JahadActionItem( + title: "جوجه ریزی فعال", + route: JahadRoutes.activeHatchingJahad, + icon: Assets.vec.activeFramSvg.path, + ), + JahadActionItem( + title: "بازرسی مزارع طیور", + route: JahadRoutes.newInspectionJahad, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/jahad/presentation/pages/home/view.dart b/packages/chicken/lib/features/jahad/presentation/pages/home/view.dart new file mode 100644 index 0000000..0c042de --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/home/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class JahadHomePage extends GetView { + JahadHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: jahadActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/jahad/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/jahad/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..17f6200 --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + JahadRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await rootLogic.jahadRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'Jahad', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/jahad/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/jahad/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..8c494d3 --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: jahadActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/jahad/presentation/pages/root/logic.dart b/packages/chicken/lib/features/jahad/presentation/pages/root/logic.dart new file mode 100644 index 0000000..e31a5eb --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/root/logic.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/jahad/data/repositories/jahad_repository.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; + +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class JahadRootLogic extends GetxController { + var tokenService = Get.find(); + + late JahadRepository jahadRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(jahadActionKey), + onGenerateRoute: (settings) { + final page = JahadPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => JahadPages.pages.firstWhere( + (e) => e.name == JahadRoutes.homeJahad, + ), + ); + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + jahadRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/jahad/presentation/pages/root/view.dart b/packages/chicken/lib/features/jahad/presentation/pages/root/view.dart new file mode 100644 index 0000000..88d350e --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/pages/root/view.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class JahadRootPage extends GetView { + const JahadRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + jahadActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + jahadActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/jahad/presentation/routes/pages.dart b/packages/chicken/lib/features/jahad/presentation/routes/pages.dart new file mode 100644 index 0000000..4c72c1b --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/routes/pages.dart @@ -0,0 +1,66 @@ +import 'package:rasadyar_chicken/features/jahad/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class JahadPages { + JahadPages._(); + + static List get pages => [ + GetPage( + name: JahadRoutes.initJahad, + page: () => JahadRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => JahadRootLogic()); + Get.lazyPut(() => JahadHomeLogic()); + }), + ], + ), + GetPage( + name: JahadRoutes.homeJahad, + page: () => JahadHomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(JahadHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + + GetPage( + name: JahadRoutes.activeHatchingJahad, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: JahadRoutes.newInspectionJahad, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/jahad/presentation/routes/routes.dart b/packages/chicken/lib/features/jahad/presentation/routes/routes.dart new file mode 100644 index 0000000..d651478 --- /dev/null +++ b/packages/chicken/lib/features/jahad/presentation/routes/routes.dart @@ -0,0 +1,10 @@ +sealed class JahadRoutes { + JahadRoutes._(); + + static const _base = '/chicken/jahad'; + static const initJahad = '$_base/'; + static const homeJahad = '$_base/home'; + static const actionJahad = '$_base/action'; + static const activeHatchingJahad = '$_base/activeHatching'; + static const newInspectionJahad = '$_base/newInspection'; +} diff --git a/packages/chicken/lib/features/kill_house/root/logic.dart b/packages/chicken/lib/features/kill_house/root/logic.dart index cae61ab..87d3b4c 100644 --- a/packages/chicken/lib/features/kill_house/root/logic.dart +++ b/packages/chicken/lib/features/kill_house/root/logic.dart @@ -3,7 +3,7 @@ import 'package:rasadyar_chicken/data/di/chicken_di.dart'; import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; import 'package:rasadyar_chicken/data/repositories/kill_house/kill_house_repository.dart'; -import 'package:rasadyar_chicken/features/common/profile/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; import 'package:rasadyar_chicken/presentation/routes/pages.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; @@ -55,6 +55,4 @@ class KillHouseRootLogic extends GetxController { void changePage(int i) { currentPage.value = i; } - - } diff --git a/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart b/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart index 898c85d..ec9f6a5 100644 --- a/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart +++ b/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart @@ -1,16 +1,17 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart'; -import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart'; -import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; -import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; -import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; -import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart'; -import 'package:rasadyar_chicken/features/kill_house/warehouse_and_distribution/root/logic.dart'; -import 'package:rasadyar_chicken/features/kill_house/warehouse_and_distribution/sale/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild_profile/guild_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -56,7 +57,8 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { final RxBool hasMoreDataAllocationsMade = true.obs; Rxn broadcastPrice = Rxn(); - Rxn selectedAllocationModelForUpdate = Rxn(); + Rxn selectedAllocationModelForUpdate = + Rxn(); SubmitStewardAllocation? tmpStewardAllocation; Rxn productionDate = Rxn(null); @@ -133,7 +135,9 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } void _updateGovernmentalProductionDateData() { - /* List dates = rootLogic.stewardRemainWeight.value?.governmental ?? []; += + List dates = + rootLogic.stewardRemainWeight.value?.governmental ?? []; governmentalProductionDateData = { for (var element in dates) element.day.toString().toJalali.formatCompactDate(): DayData( @@ -156,7 +160,8 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { - allocatedList.value = Resource>.loading(); + allocatedList.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -165,8 +170,9 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { currentPage.value = 1; // Reset to first page if search value is set } - /* safeCall( - call: () async => await rootLogic.chickenRepository.getAllocatedMade( += + safeCall( + call: () async => await rootLogic.stewardRepository.getAllocatedMade( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( page: currentPage.value, @@ -181,18 +187,23 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { onSuccess: (res) async { await Future.delayed(Duration(milliseconds: 200)); if ((res?.count ?? 0) == 0) { - allocatedList.value = Resource>.empty(); + allocatedList.value = + Resource>.empty(); } else { - allocatedList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: isLoadingMore - ? [...(allocatedList.value.data?.results ?? []), ...(res?.results ?? [])] - : res?.results ?? [], - ), - ); + allocatedList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: isLoadingMore + ? [ + ...(allocatedList.value.data?.results ?? []), + ...(res?.results ?? []), + ] + : res?.results ?? [], + ), + ); isLoadingMoreAllocationsMade.value = false; if ((allocatedList.value.data?.results?.length ?? 0) > 1) { flashingFabBgColor(); @@ -209,10 +220,14 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { void checkVerification() { var hasWeight = quotaType.value == 1 ? weight.value <= - (governmentalProductionDateData[productionDate.value?.formatCompactDate()]?.value ?? + (governmentalProductionDateData[productionDate.value + ?.formatCompactDate()] + ?.value ?? 0) : weight.value <= - (freeProductionDateData[productionDate.value?.formatCompactDate()]?.value ?? 0); + (freeProductionDateData[productionDate.value?.formatCompactDate()] + ?.value ?? + 0); isValid.value = weight.value > 0 && @@ -224,8 +239,9 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } void confirmAllocation(ConformAllocation allocation) { - /* safeCall( - call: () async => await rootLogic.chickenRepository.confirmAllocation( += + safeCall( + call: () async => await rootLogic.stewardRepository.confirmAllocation( token: rootLogic.tokenService.accessToken.value!, allocation: allocation.toJson(), ), @@ -237,8 +253,9 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } void denyAllocation(String token) { - /* safeCall( - call: () async => await rootLogic.chickenRepository.denyAllocation( += + safeCall( + call: () async => await rootLogic.stewardRepository.denyAllocation( token: rootLogic.tokenService.accessToken.value!, allocationToken: token, ), @@ -250,10 +267,13 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } Future confirmAllAllocations() async { - /* safeCall( - call: () async => await rootLogic.chickenRepository.confirmAllAllocation( += + safeCall( + call: () async => await rootLogic.stewardRepository.confirmAllAllocation( token: rootLogic.tokenService.accessToken.value!, - allocationTokens: allocatedList.value.data?.results?.map((e) => e.key!).toList() ?? [], + allocationTokens: + allocatedList.value.data?.results?.map((e) => e.key!).toList() ?? + [], ), onSuccess: (result) { getAllocatedMade(); @@ -263,8 +283,9 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } Future getRolesProducts() async { - /* safeCall( - call: () async => await rootLogic.chickenRepository.getRolesProducts( += + safeCall( + call: () async => await rootLogic.commonRepository.getRolesProducts( token: rootLogic.tokenService.accessToken.value!, role: 'Steward', ), @@ -279,8 +300,9 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } Future getGuilds() async { - /* safeCall( - call: () async => await rootLogic.chickenRepository.getGuilds( += + safeCall( + call: () async => await rootLogic.commonRepository.getGuilds( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( //queryParams: {'free': saleType.value == 2 ? true : false}, @@ -311,8 +333,9 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } Future getGuildProfile() async { - /* await safeCall( - call: () async => await rootLogic.chickenRepository.getProfile( += + await safeCall( + call: () async => await rootLogic.commonRepository.getProfile( token: rootLogic.tokenService.accessToken.value!, ), onError: (error, stackTrace) {}, @@ -328,13 +351,17 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { allocationType: '${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, - productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, quota: quotaType.value == 1 ? 'governmental' : 'free', guildKey: selectedGuildModel.value?.key, productKey: selectedProductModel.value?.key, @@ -348,16 +375,20 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { /* safeCall( showError: true, - call: () async => await rootLogic.chickenRepository.postSubmitStewardAllocation( - token: rootLogic.tokenService.accessToken.value!, - request: tmpStewardAllocation!, - ), + call: () async => + await rootLogic.stewardRepository.postSubmitStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + request: tmpStewardAllocation!, + ), onSuccess: (result) { clearForm(); onRefresh(); rootLogic.onRefresh(); - Future.delayed(Duration(seconds: 1), () => defaultShowSuccessMessage("ثبت موفق بود")); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("ثبت موفق بود"), + ); Get.back(); }, onError: (error, stackTrace) {}, @@ -365,11 +396,13 @@ class WarehouseAndDistributionSalesInProvinceLogic 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}, - ), += + safeCall( + call: () async => + await rootLogic.stewardRepository.deleteStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: {'steward_allocation_key': model.key}, + ), onSuccess: (result) { getAllocatedMade(); @@ -393,7 +426,9 @@ class WarehouseAndDistributionSalesInProvinceLogic 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; productionDate.value = item.productionDate.toJalali; @@ -427,16 +462,20 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { /* safeCall( showError: true, - call: () async => await rootLogic.chickenRepository.updateStewardAllocation( - token: rootLogic.tokenService.accessToken.value!, - request: updatedAllocationModel, - ), + call: () async => + await rootLogic.stewardRepository.updateStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + request: updatedAllocationModel, + ), onSuccess: (result) { clearForm(); onRefresh(); rootLogic.onRefresh(); - Future.delayed(Duration(seconds: 1), () => defaultShowSuccessMessage("ویرایش موفق بود")); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("ویرایش موفق بود"), + ); Get.back(); }, onError: (error, stackTrace) {}, @@ -474,15 +513,18 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { } Future getBroadcastPrice() async { - /* safeCall( - call: () async => await rootLogic.chickenRepository.getBroadcastPrice( += + safeCall( + call: () async => await rootLogic.commonRepository.getBroadcastPrice( token: rootLogic.tokenService.accessToken.value!, ), onSuccess: (result) { broadcastPrice.value = result; if (broadcastPrice.value?.active == true) { pricePerKilo.value = broadcastPrice.value?.stewardPrice ?? 0; - pricePerKiloController.text = pricePerKilo.value.toString().separatedByComma; + pricePerKiloController.text = pricePerKilo.value + .toString() + .separatedByComma; priceType.value = 2; } }, @@ -494,7 +536,11 @@ class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { toggleExpansion(); currentPage.value = 1; hasMoreDataAllocationsMade.value = true; - await Future.wait([getAllocatedMade(), getRolesProducts(), rootLogic.onRefresh()]); + await Future.wait([ + getAllocatedMade(), + getRolesProducts(), + rootLogic.onRefresh(), + ]); } void toggleExpansion({int? index}) { diff --git a/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_out_of_province/view.dart b/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_out_of_province/view.dart index f45697e..76e4675 100644 --- a/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_out_of_province/view.dart +++ b/packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_out_of_province/view.dart @@ -1,10 +1,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.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/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; @@ -89,7 +89,7 @@ class WarehouseAndDistributionSalesOutOfProvincePage extends GetView getPoultryFarms(); +} + + + + diff --git a/packages/chicken/lib/features/poultry_farm_inspection/data/models/.gitkeep b/packages/chicken/lib/features/poultry_farm_inspection/data/models/.gitkeep new file mode 100644 index 0000000..3f2ff2d --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/data/models/.gitkeep @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/chicken/lib/features/poultry_farm_inspection/data/repositories/poultry_farm_repository.dart b/packages/chicken/lib/features/poultry_farm_inspection/data/repositories/poultry_farm_repository.dart new file mode 100644 index 0000000..c27fe0e --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/data/repositories/poultry_farm_repository.dart @@ -0,0 +1,7 @@ +abstract class PoultryFarmRepository { + // TODO: Implement repository interface +} + + + + diff --git a/packages/chicken/lib/features/poultry_farm_inspection/domain/.gitkeep b/packages/chicken/lib/features/poultry_farm_inspection/domain/.gitkeep new file mode 100644 index 0000000..3f2ff2d --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/domain/.gitkeep @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/chicken/lib/features/poultry_farm_inspection/poultry_farm_inspection.dart b/packages/chicken/lib/features/poultry_farm_inspection/poultry_farm_inspection.dart index fa5363a..7f918c9 100644 --- a/packages/chicken/lib/features/poultry_farm_inspection/poultry_farm_inspection.dart +++ b/packages/chicken/lib/features/poultry_farm_inspection/poultry_farm_inspection.dart @@ -1,2 +1,2 @@ -export 'home/logic.dart'; -export 'home/view.dart'; +export 'presentation/home/logic.dart'; +export 'presentation/home/view.dart'; diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/.gitkeep b/packages/chicken/lib/features/poultry_farm_inspection/presentation/.gitkeep new file mode 100644 index 0000000..3f2ff2d --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/.gitkeep @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/home/logic.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/home/logic.dart new file mode 100644 index 0000000..9b7757a --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/home/logic.dart @@ -0,0 +1,151 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; + + +class PoultryFarmInspectionHomeLogic extends GetxController + with GetTickerProviderStateMixin { + RxInt selectedSegmentIndex = 0.obs; + RxList>> inspectionList = RxList([ + Resource>.success( + PaginationModel(results: ["s", "b", "c", "d"]), + ), + ]); + RxList>> inactiveInspectionList = RxList([ + Resource>.success( + PaginationModel(results: ["s", "b", "c", "d"]), + ), + ]); + + RxInt expandedIndex = RxInt(-1); + + late TabController tabController; + + RxInt selectedTabIndex = 0.obs; + + RxInt activeStepperIndex = 0.obs; + + PageController pageController = PageController(initialPage: 0); + + //step1 + + TextEditingController nameOfThePoultryFarmUnit = TextEditingController(); + + //step2 + RxInt sanitaryConditionOfTheHallIndex = (-1).obs; + RxInt ventilationStatusIndex = (-1).obs; + RxInt beddingStatusIndex = (-1).obs; + RxInt waterQualityIndex = (-1).obs; + RxInt fuelTypeIndex = (-1).obs; + RxInt sampleTypeIndex = (-1).obs; + + //step3 + RxInt grainQualityInputIndex = (-1).obs; + RxInt generatorOperatingStatusIndex = (-1).obs; + RxInt workerContractStatusIndex = (-1).obs; + RxInt newBeneficiaryRequestIndex = (-1).obs; + + //step4 + RxInt inspectorConclusionIndex = (-1).obs; + TextEditingController inspectorConclusionDescriptionController = + TextEditingController(); + + @override + void onReady() { + super.onReady(); + + activeStepperIndex.listen((value) { + pageController.animateToPage( + value, + duration: Duration(milliseconds: 300), + curve: Curves.linear, + ); + }); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void changeSegmentIndex(int index) { + if (index == selectedSegmentIndex.value) { + return; + } + expandedIndex.value = -1; + selectedSegmentIndex.value = index; + } + + void changeTab(int index) { + if (index == selectedTabIndex.value) { + return; + } + selectedTabIndex.value = index; + } + + void clearForm() { + nameOfThePoultryFarmUnit.clear(); + activeStepperIndex.value = 0; + selectedTabIndex.value = 0; + } + + void setSanitaryConditionOfTheHallIndex(int index) { + sanitaryConditionOfTheHallIndex.value = + index == sanitaryConditionOfTheHallIndex.value ? -1 : index; + } + + void setFuelTypeIndex(int index) { + fuelTypeIndex.value = index == fuelTypeIndex.value ? -1 : index; + } + + void setVentilationStatusIndex(int index) { + ventilationStatusIndex.value = index == ventilationStatusIndex.value + ? -1 + : index; + } + + void setBeddingStatusIndex(int index) { + beddingStatusIndex.value = index == beddingStatusIndex.value ? -1 : index; + } + + void setWaterQualityIndex(int index) { + waterQualityIndex.value = index == waterQualityIndex.value ? -1 : index; + } + + void setSampleTypeIndex(int index) { + sampleTypeIndex.value = index == sampleTypeIndex.value ? -1 : index; + } + + void setGrainQualityInputIndex(int index) { + grainQualityInputIndex.value = index == grainQualityInputIndex.value + ? -1 + : index; + } + + void setGeneratorOperatingStatusIndex(int index) { + generatorOperatingStatusIndex.value = + index == generatorOperatingStatusIndex.value ? -1 : index; + } + + void setWorkerContractStatusIndex(int index) { + workerContractStatusIndex.value = index == workerContractStatusIndex.value + ? -1 + : index; + } + + void setNewBeneficiaryRequestIndex(int index) { + newBeneficiaryRequestIndex.value = index == newBeneficiaryRequestIndex.value + ? -1 + : index; + } + + void setInspectorConclusionIndex(int index) { + inspectorConclusionIndex.value = index == inspectorConclusionIndex.value + ? -1 + : index; + } +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/home/view.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/home/view.dart new file mode 100644 index 0000000..bd30cf3 --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/home/view.dart @@ -0,0 +1,934 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/info_card/info_card.dart'; +import 'package:rasadyar_core/core.dart'; + +import '../widgets/cu_bottom_sheet.dart'; +import 'logic.dart'; + +class PoultryFarmInspectionHomePage extends GetView { + const PoultryFarmInspectionHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + onFilterTap: () { + //TODO + }, + + onSearchTap: () { + //TODO + }, + + onSearchChanged: (data) { + //TODO + }, + backId: poultryFirstKey, + + child: Stack( + fit: StackFit.expand, + children: [ + Positioned.fill( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + infoCards(), + segmentWidget(), + ObxValue((data) { + return data.value == 0 ? activeInspectionWidget() : inactiveInspectionWidget(); + }, controller.selectedSegmentIndex), + ], + ), + ), + + Positioned( + right: 10, + bottom: 90.h, + child: RFab.add( + onPressed: () { + Get.bottomSheet( + addOrEditBottomSheet(controller), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) => controller.clearForm()); + }, + ), + ), + ], + ), + ); + } + + Padding infoCards() { + return Padding( + padding: const EdgeInsets.fromLTRB(9, 12, 9, 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + spacing: 8, + children: [ + cardInfo(value: 2225256, description: 'بازرسی شده', color: const Color(0xFFB6DED8)), + cardInfo(value: 2050, description: 'بازرسی نشده', color: const Color(0xFFE9CED7)), + cardInfo(value: 2225256, description: 'عملکرد مناسب', color: const Color(0xFFCFE0FF)), + cardInfo(value: 55225, description: 'عملکرد ضعیف', color: const Color(0xFFF3D6CB)), + ], + ), + ); + } + + Padding segmentWidget() { + return Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), + child: Row( + children: [ + Expanded( + child: RSegment( + children: ['بازرسی فعال', 'بایگانی'], + selectedIndex: 0, + borderColor: const Color(0xFFB4B4B4), + selectedBorderColor: AppColor.blueNormal, + selectedBackgroundColor: AppColor.blueLight, + onSegmentSelected: (index) => controller.changeSegmentIndex(index), + backgroundColor: AppColor.whiteGreyNormal, + ), + ), + ], + ), + ); + } + + Widget activeInspectionWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.first, + hasMore: false, + onLoadMore: () async {}, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: activeinspecitonItemListWidget(), + secondChild: avtiveInspectionItemListExpandedWidget(), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.checkSquareSvg.path, + labelIconColor: AppColor.mediumGreyDarkHover, + ); + }, controller.expandedIndex); + }, + itemCount: 2, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.inspectionList), + ); + } + + Container avtiveInspectionItemListExpandedWidget() { + const farmerName = 'آرمان صادقی'; + const showViolationLabel = true; + const violationLabel = 'پیگیری'; + const breed = 'راس ۳۰۸'; + const ageInDays = '۴۲'; + const growPeriod = 'بهار ۱۴۰۴'; + const licenceNumber = '۱۲۳۴۵۶۷۸'; + const chickVolume = '۲۵,۰۰۰'; + const hallRemain = '۲۳,۴۵۰'; + const losses = '۱,۵۵۰'; + const vetInfo = 'دکتر نرگس مرادی(۰۹۳۵۴۵۶۶۷۷۹)'; + const showReportButton = true; + const reportStatus = 'ارسال تصویر جوجه ریزی فارم'; + final reportColor = AppColor.redDark; + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + farmerName, + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + Visibility( + visible: showViolationLabel, + child: Text( + violationLabel, + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text('نژاد:$breed', style: AppFonts.yekan14.copyWith(color: AppColor.textColor)), + Text( + ' سن $ageInDays (روزه)', + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:$growPeriod', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + buildRow(title: 'شماره مجوز جوجه ریزی', value: licenceNumber), + buildUnitRow(title: 'حجم جوجه ریزی', value: chickVolume, unit: '(قطعه)'), + buildUnitRow(title: 'مانده در سالن', value: hallRemain, unit: '(قطعه)'), + buildUnitRow(title: 'تلفات', value: losses, unit: '(قطعه)'), + buildRow(title: 'دامپزشک فارم', value: vetInfo), + buildRow( + title: 'شرح بازرسی', + value: reportStatus, + titleStyle: AppFonts.yekan14.copyWith(color: reportColor), + valueStyle: AppFonts.yekan14.copyWith(color: reportColor), + ), + Visibility( + visible: showReportButton, + child: RElevated( + text: 'ثبت بازرسی', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () {}, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ), + ], + ), + ); + } + + Widget activeinspecitonItemListWidget() { + const farmerName = 'آرمان صادقی'; + const farmerMobile = '۰۹۱۲۱۲۳۴۵۶۷'; + const unitName = 'فارم نمونه آفتاب'; + const unitLicence = 'مجوز ۵۴۲۱-الف'; + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + farmerName, + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + farmerMobile, + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + unitName, + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + unitLicence, + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } + + Widget inactiveInspectionWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.first, + hasMore: false, + onLoadMore: () async {}, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: inActiveinspecitonItemListWidget(), + secondChild: inAvtiveInspectionItemListExpandedWidget(), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.checkSquareSvg.path, + labelIconColor: AppColor.mediumGreyDarkHover, + ); + }, controller.expandedIndex); + }, + itemCount: 5, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.inspectionList), + ); + } + + Widget inActiveinspecitonItemListWidget() { + const farmerName = 'زهرا موسوی'; + const farmerMobile = '۰۹۳۸۸۸۷۷۶۶۵'; + const unitName = 'کشت و پرورش افق سبز'; + const unitLicence = 'مجوز ۷۶۳۲-ج'; + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + farmerName, + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + farmerMobile, + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + unitName, + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + unitLicence, + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } + + Container inAvtiveInspectionItemListExpandedWidget() { + const farmerName = 'زهرا موسوی'; + const showViolationLabel = false; + const violationLabel = 'عادی'; + const breed = 'کاب ۵۰۰'; + const ageInDays = '۳۵'; + const growPeriod = 'پاییز ۱۴۰۳'; + const licenceNumber = '۸۹۴۵۶۱۲۳'; + const chickVolume = '۱۸,۵۰۰'; + const hallRemain = '۱۷,۹۴۰'; + const losses = '۵۶۰'; + const vetInfo = 'دکتر حمید نادری(۰۹۱۳۴۴۵۵۶۶۷)'; + const reportStatus = 'بازدید تایید شده'; + final reportColor = AppColor.greenNormal; + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + farmerName, + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + Visibility( + visible: showViolationLabel, + child: Text( + violationLabel, + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text('نژاد:$breed', style: AppFonts.yekan14.copyWith(color: AppColor.textColor)), + Text( + ' سن $ageInDays (روزه)', + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:$growPeriod', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + buildRow(title: 'شماره مجوز جوجه ریزی', value: licenceNumber), + buildUnitRow(title: 'حجم جوجه ریزی', value: chickVolume, unit: '(قطعه)'), + buildUnitRow(title: 'مانده در سالن', value: hallRemain, unit: '(قطعه)'), + buildUnitRow(title: 'تلفات', value: losses, unit: '(قطعه)'), + buildRow(title: 'دامپزشک فارم', value: vetInfo), + buildRow( + title: 'شرح بازرسی', + value: reportStatus, + titleStyle: AppFonts.yekan14.copyWith(color: reportColor), + valueStyle: AppFonts.yekan14.copyWith(color: reportColor), + ), + ROutlinedElevated( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Assets.vec.excelDownloadSvg.svg( + width: 24.w, + height: 24.h, + colorFilter: ColorFilter.mode(AppColor.greenDark, BlendMode.srcIn), + ), + + Text( + 'مشاهده جزییات ', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.greenDark), + ), + ], + ), + borderColor: AppColor.greenDark, + onPressed: () { + Get.bottomSheet(detailsWidget(), isScrollControlled: true, isDismissible: true); + }, + ), + ], + ), + ); + } + + Widget detailsWidget() { + return BaseBottomSheet( + height: Get.height * 0.8, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 10), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith(color: AppColor.iconColor), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ObxValue((data) { + return tabBarWidget( + ['اطلاعات', 'پاییش سلامت', 'زیرساخت', 'مستندات'], + controller.selectedTabIndex.value, + (index) => controller.changeTab(index), + ); + }, controller.selectedTabIndex), + + ObxValue((data) { + switch (data.value) { + case 0: + return infoTable(); + case 1: + return healthTable(); + case 2: + return infrastructureTable(); + case 3: + return documentsTable(); + default: + return infoTable(); + } + }, controller.selectedTabIndex), + ], + ), + ), + + // Expanded در سطح بالاتر + ], + ), + ); + } + + Container infoTable() { + return Container( + height: Get.height, + width: Get.width, + child: Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text('مشخصات کلی', style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor)), + ], + ), + SizedBox(height: 10), + + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + rTableRow(title: 'نام واحد مرغداری', value: 'لذیذ'), + rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'), + rTableRow(title: 'نام مالک / بهره‌بردار', value: 'مرغداری احمدی'), + rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'), + + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow(title: 'تاریخ ثبت جوجه ریزی', value: '1402/09/19 (10:12)'), + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow(title: 'تاریخ ثبت جوجه ریزی', value: '1402/09/19 (10:12)'), + ], + ), + ), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border(bottom: BorderSide(color: AppColor.blackLightHover, width: 1)), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border(bottom: BorderSide(color: AppColor.blackLightHover, width: 1)), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + Widget tabBarWidget(List tabs, int selectedIndex, Function(int) onTabSelected) { + return SizedBox( + height: 38.h, + width: Get.width, + child: Stack( + fit: StackFit.expand, + children: [ + Positioned( + right: 0, + top: 0, + bottom: 0, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 11), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border(bottom: BorderSide(color: AppColor.blueNormalOld, width: 3)) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ), + ], + ), + ); + } + + Widget healthTable() { + return Container( + height: Get.height, + width: Get.width, + child: Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text('پاییش سلامت', style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor)), + ], + ), + SizedBox(height: 10), + + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + rTableRow(title: 'نام واحد مرغداری', value: 'لذیذ'), + rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'), + rTableRow(title: 'نام مالک / بهره‌بردار', value: 'مرغداری احمدی'), + rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'), + + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow(title: 'تاریخ ثبت جوجه ریزی', value: '1402/09/19 (10:12)'), + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow(title: 'تاریخ ثبت جوجه ریزی', value: '1402/09/19 (10:12)'), + ], + ), + ), + ], + ), + ); + } + + Widget infrastructureTable() { + return Container( + height: Get.height, + width: Get.width, + child: Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text('زیرساخت', style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor)), + ], + ), + SizedBox(height: 10), + + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + children: [ + rTableRow(title: 'نام واحد مرغداری', value: 'لذیذ'), + rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'), + rTableRow(title: 'نام مالک / بهره‌بردار', value: 'مرغداری احمدی'), + rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'), + + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow(title: 'تاریخ ثبت جوجه ریزی', value: '1402/09/19 (10:12)'), + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow(title: 'تاریخ ثبت جوجه ریزی', value: '1402/09/19 (10:12)'), + ], + ), + ), + ], + ), + ); + } + + Widget documentsTable() { + return Container( + height: Get.height, + width: Get.width, + child: Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text('مستندات', style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor)), + ], + ), + + SizedBox(height: 16), + + Container( + height: 135.h, + width: Get.width, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 10, + children: [ + SizedBox( + height: 100.h, + width: Get.width, + child: ListView.separated( + itemCount: 10, + padding: EdgeInsets.symmetric(horizontal: 12), + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + color: Color(0x33000000), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage("https://picsum.photos/150/150?random=$index"), + ), + + borderRadius: BorderRadius.circular(8), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(width: 10), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Row( + children: [ + Text( + '200 فارم در این سالن تخمین زده شده است.', + textAlign: TextAlign.right, + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + ], + ), + ), + + SizedBox(height: 16), + + Container( + height: 135.h, + width: Get.width, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 10, + children: [ + SizedBox( + height: 100.h, + width: Get.width, + child: ListView.separated( + itemCount: 10, + padding: EdgeInsets.symmetric(horizontal: 12), + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + color: Color(0x33000000), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage( + "https://picsum.photos/150/150?random=${index * 2 + 1}", + ), + ), + + borderRadius: BorderRadius.circular(8), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(width: 10), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Row( + children: [ + Text( + 'انبار نهاده ها', + textAlign: TextAlign.right, + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + ], + ), + ), + + SizedBox(height: 16), + + Container( + height: 135.h, + width: Get.width, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 10, + children: [ + SizedBox( + height: 100.h, + width: Get.width, + child: ListView.separated( + itemCount: 10, + padding: EdgeInsets.symmetric(horizontal: 12), + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + color: Color(0x33000000), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage( + "https://picsum.photos/150/150?random=${index * 3 + 1}", + ), + ), + + borderRadius: BorderRadius.circular(8), + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(width: 10), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Row( + children: [ + Text( + 'تلفات', + textAlign: TextAlign.right, + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/card_info.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/card_info.dart new file mode 100644 index 0000000..807e5ca --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/card_info.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/home/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +Widget farmInfoWidget({ + required PoultryFarmInspectionHomeLogic controller, + required String title, + required Widget child, + EdgeInsets? padding, +}) { + return Stack( + clipBehavior: Clip.none, + children: [ + Positioned.fill( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: AppColor.mediumGrey), + ), + + padding: + padding ?? EdgeInsets.symmetric(horizontal: 12.w, vertical: 11.h), + child: child, + ), + ), + Positioned( + top: -17, + right: 7, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: AppColor.mediumGrey), + ), + child: Text( + title, + style: AppFonts.yekan14.copyWith(color: AppColor.iconColor), + ), + ), + ), + ], + ); +} + +Widget cardInfo({required Widget child, EdgeInsets? padding}) { + return Container( + width: Get.width, + padding: padding ?? EdgeInsets.symmetric(horizontal: 12.w, vertical: 14.h), + decoration: BoxDecoration( + color: AppColor.bgLight, + + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.blackLight), + ), + child: child, + ); +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/cu_bottom_sheet.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/cu_bottom_sheet.dart new file mode 100644 index 0000000..f08329d --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/cu_bottom_sheet.dart @@ -0,0 +1,224 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; +import '../home/logic.dart'; +import 'step1_page.dart'; +import 'step2_page.dart'; +import 'step3_page.dart'; +import 'step4_page.dart'; +import 'step5_page.dart'; + +Widget addOrEditBottomSheet(PoultryFarmInspectionHomeLogic controller) { + List pages = [ + step1Page(controller), + step2Page(controller), + step3Page(controller), + step4Page(controller), + step5Page(controller), + ]; + + return BaseBottomSheet( + height: Get.height, + rootChild: Column( + children: [ + ObxValue((data) { + return stepper(activeStep: data.value); + }, controller.activeStepperIndex), + Expanded( + child: PageView.builder( + physics: const NeverScrollableScrollPhysics(), + reverse: true, + controller: controller.pageController, + itemBuilder: (context, index) => pages[index], + ), + ), + + ObxValue((data) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + spacing: 16, + children: [ + Expanded( + child: RElevated( + height: 40.h, + backgroundColor: AppColor.greenNormal, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + + children: [ + Icon(Icons.arrow_back_ios, color: Colors.white), + + Text('ادامه'), + ], + ), + onPressed: () { + if (controller.activeStepperIndex.value <4) { + controller.activeStepperIndex.value++; + } + }, + ), + ), + Expanded( + child: ROutlinedElevated( + borderColor: AppColor.error, + height: 40.h, + child: Text('برگشت'), + enabled: controller.activeStepperIndex.value > 0, + onPressed: () { + if (controller.activeStepperIndex.value > 0) { + controller.activeStepperIndex.value--; + } + }, + ), + ), + ], + ), + ); + }, controller.activeStepperIndex), + ], + ), + ); +} + +class stepper extends StatelessWidget { + const stepper({super.key, required this.activeStep}); + final int activeStep; + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.ltr, + child: SizedBox( + height: 24, + width: Get.width, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 0 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '1', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 0 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 1 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 1 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '2', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 1 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 2 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 2 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '3', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 2 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 3 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 3 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '4', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 3 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 4 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 4 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '5', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 3 ? Colors.white : AppColor.iconColor, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step1_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step1_page.dart new file mode 100644 index 0000000..926a1e6 --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step1_page.dart @@ -0,0 +1,167 @@ +import 'package:flutter/material.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; +import 'package:rasadyar_core/core.dart'; + +import '../home/logic.dart'; + +Widget step1Page(PoultryFarmInspectionHomeLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 25.h), + + Container( + height: 610.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'اطلاعات پایه واحد', + child: basicUnitInformation(controller), + ), + ), + + SizedBox(height: 30.h), + + Container( + height: 400.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'اطلاعات جوجه ریزی', + child: hatchingInformation(controller), + ), + ), + SizedBox(height: 16.h), + ], + ), + ); +} + +Column basicUnitInformation(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نام واحد مرغداری', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'کد یکتا / شناسه واحد', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نام مالک / بهره‌بردار', + filled: true, + filledColor: AppColor.bgLight, + ), + + ResourceOverlayDropdown( + items: Resource.success(['مالک', 'بهره‌بردار', 'مشاور', 'دیگر']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نوع مالکیت'), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'کد ملی بهره‌بردار', + filled: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'شماره تماس بهره‌بردار', + filled: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'ظرفیت اسمی سالن‌ها', + filled: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نوع سیستم پرورش', + filled: true, + filledColor: AppColor.bgLight, + ), + + RElevated( + isFullWidth: true, + height: 40.h, + backgroundColor: AppColor.greenNormal, + onPressed: () {}, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Icon(Icons.my_location_rounded, color: Colors.white, size: 24), + Text('دریافت موقعیت جغرافیایی', style: AppFonts.yekan14.copyWith(color: Colors.white)), + ], + ), + ), + ], + ); +} + +Column hatchingInformation(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تاریخ جوجه ریزی', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد جوجه‌ریزی اولیه', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'منبع تهیه جوجه', + filled: true, + filledColor: AppColor.bgLight, + ), + + ResourceOverlayDropdown( + items: Resource.success(['سرابی', 'پژدر', 'روتوایلر', 'دیگر']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نوع نژاد'), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'گرید جوجه', + filled: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میانگین وزن جوجه در ورود', + filled: true, + filledColor: AppColor.bgLight, + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step2_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step2_page.dart new file mode 100644 index 0000000..9fc9bad --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step2_page.dart @@ -0,0 +1,500 @@ +import 'package:flutter/material.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; +import 'package:rasadyar_core/core.dart'; + +import '../home/logic.dart'; + +Widget step2Page(PoultryFarmInspectionHomeLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 35.h), + + Container( + height: 760.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'وضعیت عمومی سالن', + child: generalConditionOfTheHall(controller), + ), + ), + + SizedBox(height: 30.h), + + Container( + height: 430.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'تلفات', + child: casualtiesInformation(controller), + ), + ), + SizedBox(height: 24.h), + + Container( + height: 450.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'بیماری‌ها و وضعیت سلامت', + child: diseasesAndHealthInformation(controller), + ), + ), + ], + ), + ); +} + +Column generalConditionOfTheHall(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 12), + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all(width: 1, color: AppColor.blackLightHover), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg(width: 36, height: 36), + ), + ], + ), + ), + + Text( + 'تعداد موجود فعلی', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت بهداشتی سالن', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + formChips( + selectedIndex: data.value, + index: 0, + label: 'عالی', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + formChips( + selectedIndex: data.value, + index: 1, + label: 'خوب', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + formChips( + selectedIndex: data.value, + index: 2, + label: 'متوسط', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + formChips( + selectedIndex: data.value, + index: 3, + label: 'ضعیف', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + ], + ); + }, controller.sanitaryConditionOfTheHallIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text('وضعیت تهویه', style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2)), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setVentilationStatusIndex(index), + selectedIndex: data.value, + index: 0, + label: 'خشک', + ), + formChips( + onTap: (index) => controller.setVentilationStatusIndex(index), + selectedIndex: data.value, + index: 1, + label: 'نیمه‌مرطوب', + ), + formChips( + onTap: (index) => controller.setVentilationStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'مرطوب', + ), + ], + ); + }, controller.ventilationStatusIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text('وضعیت بستر', style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2)), + + ObxValue((data) { + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + spacing: 8, + children: [ + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 0, + label: 'خشک', + ), + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 1, + label: 'نیمه‌مرطوب', + ), + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'مرطوب', + ), + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'نیازمند اصلاح', + ), + ], + ), + ); + }, controller.beddingStatusIndex), + ], + ), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'دمای سالن', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + minLines: 1, + keyboardType: TextInputType.number, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'کیفیت آب مصرفی', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setWaterQualityIndex(index), + selectedIndex: data.value, + index: 0, + label: 'چاه', + ), + formChips( + onTap: (index) => controller.setWaterQualityIndex(index), + selectedIndex: data.value, + index: 1, + label: 'شهری', + ), + formChips( + onTap: (index) => controller.setWaterQualityIndex(index), + selectedIndex: data.value, + index: 2, + label: 'تصفیه‌شده', + ), + ], + ); + }, controller.waterQualityIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'کیفیت آب مصرفی', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + formChips( + onTap: (index) => controller.setFuelTypeIndex(index), + selectedIndex: data.value, + index: 0, + label: 'گازوییل', + ), + formChips( + onTap: (index) => controller.setFuelTypeIndex(index), + selectedIndex: data.value, + index: 1, + label: 'بنزین', + ), + formChips( + onTap: (index) => controller.setFuelTypeIndex(index), + selectedIndex: data.value, + index: 2, + label: 'گاز', + ), + formChips( + selectedIndex: data.value, + index: 3, + label: 'نفت', + onTap: (index) => controller.setFuelTypeIndex(index), + ), + ], + ); + }, controller.fuelTypeIndex), + ], + ), + ), + ], + ); +} + +ChoiceChip formChips({ + required int selectedIndex, + required int index, + required String label, + required Function(int) onTap, +}) { + return ChoiceChip( + selectedColor: AppColor.green1Normal, + labelStyle: index == selectedIndex + ? AppFonts.yekan14Bold.copyWith(color: Colors.white) + : AppFonts.yekan14.copyWith(color: AppColor.textColor), + surfaceTintColor: Colors.white, + checkmarkColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: index == selectedIndex + ? BorderSide.none + : BorderSide(width: 1, color: AppColor.blackLightHover), + ), + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6), + + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + label: Text(label), + selected: index == selectedIndex, + onSelected: (value) => onTap(index), + ); +} + +Column casualtiesInformation(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد تلفات عادی دوره', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تلفات غیرعادی', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'منبع تهیه جوجه', + filled: true, + filledColor: AppColor.bgLight, + ), + + ResourceOverlayDropdown( + items: Resource.success(['بیماری', 'قطعی برق', 'استرس گرمایی', 'مشکلات دانه']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'علت احتمالی تلفات غیرعادی'), + ), + + ResourceOverlayDropdown( + items: Resource.success(['انجام نشد', 'انجام شد']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نمونه‌برداری انجام‌شده'), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text('نوع نمونه', style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2)), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setSampleTypeIndex(index), + selectedIndex: data.value, + index: 0, + label: 'رنده', + ), + formChips( + onTap: (index) => controller.setSampleTypeIndex(index), + selectedIndex: data.value, + index: 1, + label: 'لاشه', + ), + formChips( + onTap: (index) => controller.setSampleTypeIndex(index), + selectedIndex: data.value, + index: 2, + label: 'ترکیبی', + ), + ], + ); + }, controller.sampleTypeIndex), + ], + ), + ), + ], + ); +} + +Column diseasesAndHealthInformation(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + ResourceOverlayDropdown( + items: Resource.success(['بیماری', 'قطعی برق', 'استرس گرمایی', 'مشکلات دانه']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'وجود علائم بیماری در گله'), + ), + + ResourceOverlayDropdown( + items: Resource.success(['انجام نشد', 'انجام شد']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نوع بیماری تشخیص داده‌شده / مشکوک'), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تاریخ واکسیناسیون‌های انجام‌شده', + filled: true, + filledColor: AppColor.bgLight, + ), + + ResourceOverlayDropdown( + items: Resource.success([ + 'واکسن 1', + 'واکسن 2', + 'واکسن 3', + 'واکسن 4', + 'واکسن 5', + 'واکسن 6', + 'واکسن 7', + 'واکسن 8', + 'واکسن 9', + 'واکسن 10', + ]), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نوع واکسن'), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'شرکت تولیدکننده', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نام مسئول فنی بهداشتی', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نام مسئول فنی نظام مهندسی', + filled: true, + filledColor: AppColor.bgLight, + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step3_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step3_page.dart new file mode 100644 index 0000000..86b2673 --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step3_page.dart @@ -0,0 +1,720 @@ +import 'package:flutter/material.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; +import 'package:rasadyar_core/core.dart'; + +import '../home/logic.dart'; + +Widget step3Page(PoultryFarmInspectionHomeLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 35.h), + + Container( + height: 410.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'نهاده و خوراک', + child: agriculturalInput(controller), + ), + ), + + SizedBox(height: 30.h), + + Container( + height: 650.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'زیرساخت و انرژی', + child: infrastructureAndEnergy(controller), + ), + ), + SizedBox(height: 24.h), + + Container( + height: 405.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'نیروی انسانی', + child: humanResources(controller), + ), + ), + SizedBox(height: 24.h), + + Container( + height: 440.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'تسهیلات و حمایت‌ها', + child: facilitiesAndSupport(controller), + ), + ), + ], + ), + ); +} + +Column agriculturalInput2(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all(width: 1, color: AppColor.blackLightHover), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg(width: 36, height: 36), + ), + ], + ), + ), + + Text( + 'تعداد موجود فعلی', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت بهداشتی سالن', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + formChips( + selectedIndex: data.value, + index: 0, + label: 'عالی', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + formChips( + selectedIndex: data.value, + index: 1, + label: 'خوب', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + formChips( + selectedIndex: data.value, + index: 2, + label: 'متوسط', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + formChips( + selectedIndex: data.value, + index: 3, + label: 'ضعیف', + onTap: (index) => controller.setSanitaryConditionOfTheHallIndex(index), + ), + ], + ); + }, controller.sanitaryConditionOfTheHallIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text('وضعیت تهویه', style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2)), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setVentilationStatusIndex(index), + selectedIndex: data.value, + index: 0, + label: 'خشک', + ), + formChips( + onTap: (index) => controller.setVentilationStatusIndex(index), + selectedIndex: data.value, + index: 1, + label: 'نیمه‌مرطوب', + ), + formChips( + onTap: (index) => controller.setVentilationStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'مرطوب', + ), + ], + ); + }, controller.ventilationStatusIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text('وضعیت بستر', style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2)), + + ObxValue((data) { + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + spacing: 8, + children: [ + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 0, + label: 'خشک', + ), + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 1, + label: 'نیمه‌مرطوب', + ), + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'مرطوب', + ), + formChips( + onTap: (index) => controller.setBeddingStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'نیازمند اصلاح', + ), + ], + ), + ); + }, controller.beddingStatusIndex), + ], + ), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'دمای سالن', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + minLines: 1, + keyboardType: TextInputType.number, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'کیفیت آب مصرفی', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setWaterQualityIndex(index), + selectedIndex: data.value, + index: 0, + label: 'چاه', + ), + formChips( + onTap: (index) => controller.setWaterQualityIndex(index), + selectedIndex: data.value, + index: 1, + label: 'شهری', + ), + formChips( + onTap: (index) => controller.setWaterQualityIndex(index), + selectedIndex: data.value, + index: 2, + label: 'تصفیه‌شده', + ), + ], + ); + }, controller.waterQualityIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'کیفیت آب مصرفی', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + formChips( + onTap: (index) => controller.setFuelTypeIndex(index), + selectedIndex: data.value, + index: 0, + label: 'گازوییل', + ), + formChips( + onTap: (index) => controller.setFuelTypeIndex(index), + selectedIndex: data.value, + index: 1, + label: 'بنزین', + ), + formChips( + onTap: (index) => controller.setFuelTypeIndex(index), + selectedIndex: data.value, + index: 2, + label: 'گاز', + ), + formChips( + selectedIndex: data.value, + index: 3, + label: 'نفت', + onTap: (index) => controller.setFuelTypeIndex(index), + ), + ], + ); + }, controller.fuelTypeIndex), + ], + ), + ), + ], + ); +} + +ChoiceChip formChips({ + required int selectedIndex, + required int index, + required String label, + required Function(int) onTap, +}) { + return ChoiceChip( + selectedColor: AppColor.green1Normal, + labelStyle: index == selectedIndex + ? AppFonts.yekan14Bold.copyWith(color: Colors.white) + : AppFonts.yekan14.copyWith(color: AppColor.textColor), + surfaceTintColor: Colors.white, + checkmarkColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: index == selectedIndex + ? BorderSide.none + : BorderSide(width: 1, color: AppColor.blackLightHover), + ), + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6), + + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + label: Text(label), + selected: index == selectedIndex, + onSelected: (value) => onTap(index), + ); +} + +Column infrastructureAndEnergy(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نوع ژنراتور', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'ظرفیت (KVA)', + filled: true, + filledColor: AppColor.bgLight, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت عملکرد ژنراتور', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setGeneratorOperatingStatusIndex(index), + selectedIndex: data.value, + index: 0, + label: 'سالم', + ), + formChips( + onTap: (index) => controller.setGeneratorOperatingStatusIndex(index), + selectedIndex: data.value, + index: 1, + label: 'نیمه‌سالم', + ), + formChips( + onTap: (index) => controller.setGeneratorOperatingStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'معیوب', + ), + ], + ); + }, controller.generatorOperatingStatusIndex), + ], + ), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میزان موجودی سوخت اضطراری (لیتر)', + filled: true, + filledColor: AppColor.bgLight, + ), + + ResourceOverlayDropdown( + items: Resource.success(['بیماری', 'قطعی برق', 'استرس گرمایی', 'مشکلات دانه']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'علت احتمالی تلفات غیرعادی'), + ), + + ResourceOverlayDropdown( + items: Resource.success(['ندارد', 'دارد']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'سابقه قطعی برق دوره جاری'), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد تلفات', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'مدت قطعی', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'توضیحات تکمیلی', + filled: true, + maxLines: 3, + minLines: 3, + filledColor: AppColor.bgLight, + ), + ], + ); +} + +Column agriculturalInput(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میزان نهاده مصرفی تا روز بازدید (کیلوگرم)', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میزان نهاده موجود در انبار', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میزان نهاده خریداری‌شده و حمل‌نشده از بازارگاه', + filled: true, + filledColor: AppColor.bgLight, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text('کیفیت دانه', style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2)), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setSampleTypeIndex(index), + selectedIndex: data.value, + index: 0, + label: 'خوب', + ), + formChips( + onTap: (index) => controller.setSampleTypeIndex(index), + selectedIndex: data.value, + index: 1, + label: 'متوسط', + ), + formChips( + onTap: (index) => controller.setGrainQualityInputIndex(index), + selectedIndex: data.value, + index: 2, + label: 'ضعیف', + ), + ], + ); + }, controller.grainQualityInputIndex), + ], + ), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'فرمول دانه (در صورت ارائه)', + filled: true, + minLines: 3, + maxLines: 3, + filledColor: AppColor.bgLight, + ), + ], + ); +} + +Column humanResources(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد افراد شاغل', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد افراد بومی', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد افراد غیر بومی', + filled: true, + maxLines: 3, + minLines: 3, + filledColor: AppColor.bgLight, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت قرارداد کارگران', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setWorkerContractStatusIndex(index), + selectedIndex: data.value, + index: 0, + label: 'دائم', + ), + formChips( + onTap: (index) => controller.setWorkerContractStatusIndex(index), + selectedIndex: data.value, + index: 1, + label: 'موقت', + ), + formChips( + onTap: (index) => controller.setWorkerContractStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'روزمزدی', + ), + ], + ); + }, controller.workerContractStatusIndex), + ], + ), + ), + + ResourceOverlayDropdown( + items: Resource.success(['آموزش‌ ندیده است', 'آموزش‌ دیده است']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'آموزش‌دیده در حوزه بهداشت و امنیت زیستی'), + ), + ], + ); +} + +Column facilitiesAndSupport(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تسهیلات دریافتی فعال', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نوع تسهیلات', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'مبلغ', + filled: true, + + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'سال دریافت', + filled: true, + + filledColor: AppColor.bgLight, + ), + + ResourceOverlayDropdown( + items: Resource.success(['دریافت نشده', 'دریافت شده']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'وضعیت بازپرداخت'), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'درخواست جدید بهره‌بردار', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 0, + label: 'نهاده', + ), + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 1, + label: 'تسهیلات', + ), + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 2, + label: 'واکسن', + ), + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 3, + label: 'تجهیزات', + ), + ], + ), + ); + }, controller.newBeneficiaryRequestIndex), + ], + ), + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step4_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step4_page.dart new file mode 100644 index 0000000..5570f4f --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step4_page.dart @@ -0,0 +1,488 @@ +import 'package:flutter/material.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; +import 'package:rasadyar_core/core.dart'; + +import '../home/logic.dart'; + +Widget step4Page(PoultryFarmInspectionHomeLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 35.h), + + Container( + height: 455.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'مستندات', + child: documents(controller), + ), + ), + + SizedBox(height: 30.h), + + Container( + height: 220.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'جمع‌بندی بازرس', + child: inspectorConclusion(controller), + ), + ), + SizedBox(height: 24.h), + ], + ), + ); +} + +Column documents(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + SizedBox(height: 10.h), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all(width: 1, color: AppColor.blackLightHover), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg(width: 36, height: 36), + ), + ], + ), + ), + + Text( + 'ثبت عکس سالن (حداقل ۳ زاویه) *', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all(width: 1, color: AppColor.blackLightHover), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg(width: 36, height: 36), + ), + ], + ), + ), + + Text( + 'ثبت عکس انبار نهاده‌ها', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ], + ), + ), + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all(width: 1, color: AppColor.blackLightHover), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg(width: 36, height: 36), + ), + ], + ), + ), + + Text('ثبت عکس تلفات', style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight)), + ], + ), + ), + ], + ); +} + +ChoiceChip formChips({ + required int selectedIndex, + required int index, + required String label, + required Function(int) onTap, +}) { + return ChoiceChip( + selectedColor: AppColor.green1Normal, + labelStyle: index == selectedIndex + ? AppFonts.yekan14Bold.copyWith(color: Colors.white) + : AppFonts.yekan14.copyWith(color: AppColor.textColor), + surfaceTintColor: Colors.white, + checkmarkColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: index == selectedIndex + ? BorderSide.none + : BorderSide(width: 1, color: AppColor.blackLightHover), + ), + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6), + + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + label: Text(label), + selected: index == selectedIndex, + onSelected: (value) => onTap(index), + ); +} + +Column inspectorConclusion(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت کلی واحد', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setInspectorConclusionIndex(index), + selectedIndex: data.value, + index: 0, + label: 'تایید شده', + ), + formChips( + onTap: (index) => controller.setInspectorConclusionIndex(index), + selectedIndex: data.value, + index: 1, + label: 'نیازمند اصلاح', + ), + formChips( + onTap: (index) => controller.setInspectorConclusionIndex(index), + selectedIndex: data.value, + index: 2, + label: 'پرریسک', + ), + ], + ), + ); + }, controller.inspectorConclusionIndex), + ], + ), + ), + + RTextField( + controller: controller.inspectorConclusionDescriptionController, + hintText: 'توصیه‌ها / اخطارها / اقدامات اصلاحی ...', + hintStyle: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + maxLines: 3, + minLines: 3, + filled: true, + filledColor: AppColor.bgLight, + ), + ], + ); +} + +Column agriculturalInput(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میزان نهاده مصرفی تا روز بازدید (کیلوگرم)', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میزان نهاده موجود در انبار', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'میزان نهاده خریداری‌شده و حمل‌نشده از بازارگاه', + filled: true, + filledColor: AppColor.bgLight, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text('کیفیت دانه', style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2)), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setSampleTypeIndex(index), + selectedIndex: data.value, + index: 0, + label: 'خوب', + ), + formChips( + onTap: (index) => controller.setSampleTypeIndex(index), + selectedIndex: data.value, + index: 1, + label: 'متوسط', + ), + formChips( + onTap: (index) => controller.setGrainQualityInputIndex(index), + selectedIndex: data.value, + index: 2, + label: 'ضعیف', + ), + ], + ); + }, controller.grainQualityInputIndex), + ], + ), + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'فرمول دانه (در صورت ارائه)', + filled: true, + minLines: 3, + maxLines: 3, + filledColor: AppColor.bgLight, + ), + ], + ); +} + +Column humanResources(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد افراد شاغل', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد افراد بومی', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تعداد افراد غیر بومی', + filled: true, + maxLines: 3, + minLines: 3, + filledColor: AppColor.bgLight, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت قرارداد کارگران', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setWorkerContractStatusIndex(index), + selectedIndex: data.value, + index: 0, + label: 'دائم', + ), + formChips( + onTap: (index) => controller.setWorkerContractStatusIndex(index), + selectedIndex: data.value, + index: 1, + label: 'موقت', + ), + formChips( + onTap: (index) => controller.setWorkerContractStatusIndex(index), + selectedIndex: data.value, + index: 2, + label: 'روزمزدی', + ), + ], + ); + }, controller.workerContractStatusIndex), + ], + ), + ), + + ResourceOverlayDropdown( + items: Resource.success(['آموزش‌ ندیده است', 'آموزش‌ دیده است']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'آموزش‌دیده در حوزه بهداشت و امنیت زیستی'), + ), + ], + ); +} + +Column facilitiesAndSupport(PoultryFarmInspectionHomeLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'تسهیلات دریافتی فعال', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'نوع تسهیلات', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'مبلغ', + filled: true, + + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.nameOfThePoultryFarmUnit, + label: 'سال دریافت', + filled: true, + + filledColor: AppColor.bgLight, + ), + + ResourceOverlayDropdown( + items: Resource.success(['دریافت نشده', 'دریافت شده']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'وضعیت بازپرداخت'), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'درخواست جدید بهره‌بردار', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 0, + label: 'نهاده', + ), + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 1, + label: 'تسهیلات', + ), + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 2, + label: 'واکسن', + ), + formChips( + onTap: (index) => controller.setNewBeneficiaryRequestIndex(index), + selectedIndex: data.value, + index: 3, + label: 'تجهیزات', + ), + ], + ); + }, controller.newBeneficiaryRequestIndex), + ], + ), + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step5_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step5_page.dart new file mode 100644 index 0000000..cd6ffa3 --- /dev/null +++ b/packages/chicken/lib/features/poultry_farm_inspection/presentation/widgets/step5_page.dart @@ -0,0 +1,598 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; + +import '../home/logic.dart'; + +Widget step5Page(PoultryFarmInspectionHomeLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: detailsWidget(controller), + ); +} + +Widget detailsWidget(PoultryFarmInspectionHomeLogic controller) { + return Column( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ObxValue((data) { + return tabBarWidget( + ['اطلاعات', 'پاییش سلامت', 'زیرساخت', 'مستندات'], + controller.selectedTabIndex.value, + (index) => controller.changeTab(index), + ); + }, controller.selectedTabIndex), + + ObxValue((data) { + switch (data.value) { + case 0: + return infoTable(); + case 1: + return healthTable(); + case 2: + return infrastructureTable(); + case 3: + return documentsTable(); + default: + return infoTable(); + } + }, controller.selectedTabIndex), + ], + ), + + // Expanded در سطح بالاتر + ], + ); +} + +Column infoTable() { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'مشخصات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'نام واحد مرغداری', value: 'لذیذ'), + rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'), + rTableRow(title: 'نام مالک / بهره‌بردار', value: 'مرغداری احمدی'), + rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'), + + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow( + title: 'تاریخ ثبت جوجه ریزی', + value: '1402/09/19 (10:12)', + ), + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow( + title: 'تاریخ ثبت جوجه ریزی', + value: '1402/09/19 (10:12)', + ), + ], + ), + ), + ], + ); +} + +Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); +} + +Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, +) { + return SizedBox( + height: 38.h, + width: Get.width, + child: Stack( + fit: StackFit.expand, + children: [ + Positioned( + right: 0, + top: 0, + bottom: 0, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 11), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Divider( + color: AppColor.blackLightHover, + height: 1, + thickness: 1, + ), + ), + ], + ), + ); +} + +Widget healthTable() { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'پاییش سلامت', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'نام واحد مرغداری', value: 'لذیذ'), + rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'), + rTableRow(title: 'نام مالک / بهره‌بردار', value: 'مرغداری احمدی'), + rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'), + + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow( + title: 'تاریخ ثبت جوجه ریزی', + value: '1402/09/19 (10:12)', + ), + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow( + title: 'تاریخ ثبت جوجه ریزی', + value: '1402/09/19 (10:12)', + ), + ], + ), + ), + ], + ); +} + +Widget infrastructureTable() { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'نام واحد مرغداری', value: 'لذیذ'), + rTableRow(title: 'کد یکتا / شناسه واحد', value: '2541415'), + rTableRow(title: 'نام مالک / بهره‌بردار', value: 'مرغداری احمدی'), + rTableRow(title: 'موجودی سوخت اضطراری', value: '200 لیتر'), + + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow( + title: 'تاریخ ثبت جوجه ریزی', + value: '1402/09/19 (10:12)', + ), + rTableRow(title: 'شهر/تعاونی', value: 'خرم آباد/تعاونی خرم آباد'), + + rTableRow(title: 'شماره تلفن واحد', value: '021-12345678'), + rTableRow(title: 'دامپزشک فارم', value: 'dd dd (05218569685)'), + + rTableRow(title: 'سالن', value: '2'), + rTableRow( + title: 'تاریخ ثبت جوجه ریزی', + value: '1402/09/19 (10:12)', + ), + ], + ), + ), + ], + ); +} + +Widget documentsTable() { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'مستندات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + + SizedBox(height: 16), + + Container( + height: 135.h, + width: Get.width, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 10, + children: [ + SizedBox( + height: 100.h, + width: Get.width, + child: ListView.separated( + itemCount: 10, + padding: EdgeInsets.symmetric(horizontal: 12), + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + color: Color(0x33000000), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage( + "https://picsum.photos/150/150?random=$index", + ), + ), + borderRadius: BorderRadius.circular(8), + ), + child: Stack( + fit: StackFit.expand, + children: [ + Positioned( + top: 6, + left: 6, + child: Container( + width: 24.w, + height: 24.h, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.80), + borderRadius: BorderRadius.circular(4), + ), + child: Assets.vec.trashSvg.svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode( + AppColor.redNormal, + BlendMode.srcIn, + ), + ), + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(width: 10), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Row( + children: [ + Text( + '200 فارم در این سالن تخمین زده شده است.', + textAlign: TextAlign.right, + style: AppFonts.yekan14Bold.copyWith( + color: AppColor.textColor, + ), + ), + ], + ), + ), + ], + ), + ), + + SizedBox(height: 16), + + Container( + height: 135.h, + width: Get.width, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 10, + children: [ + SizedBox( + height: 100.h, + width: Get.width, + child: ListView.separated( + itemCount: 10, + padding: EdgeInsets.symmetric(horizontal: 12), + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + color: Color(0x33000000), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage( + "https://picsum.photos/150/150?random=${index * 2 + 1}", + ), + ), + + borderRadius: BorderRadius.circular(8), + ), + child: Stack( + fit: StackFit.expand, + children: [ + Positioned( + top: 6, + left: 6, + child: Container( + width: 24.w, + height: 24.h, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.80), + borderRadius: BorderRadius.circular(4), + ), + child: Assets.vec.trashSvg.svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode( + AppColor.redNormal, + BlendMode.srcIn, + ), + ), + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(width: 10), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Row( + children: [ + Text( + 'انبار نهاده ها', + textAlign: TextAlign.right, + style: AppFonts.yekan14Bold.copyWith( + color: AppColor.textColor, + ), + ), + ], + ), + ), + ], + ), + ), + + SizedBox(height: 16), + + Container( + height: 135.h, + width: Get.width, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 10, + children: [ + SizedBox( + height: 100.h, + width: Get.width, + child: ListView.separated( + itemCount: 10, + padding: EdgeInsets.symmetric(horizontal: 12), + scrollDirection: Axis.horizontal, + itemBuilder: (context, index) { + return Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + color: Color(0x33000000), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage( + "https://picsum.photos/150/150?random=${index * 3 + 1}", + ), + ), + + borderRadius: BorderRadius.circular(8), + ), + child: Stack( + fit: StackFit.expand, + children: [ + Positioned( + top: 6, + left: 6, + child: Container( + width: 24.w, + height: 24.h, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Colors.white.withValues(alpha: 0.80), + borderRadius: BorderRadius.circular(4), + ), + child: Assets.vec.trashSvg.svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode( + AppColor.redNormal, + BlendMode.srcIn, + ), + ), + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) => SizedBox(width: 10), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 18), + child: Row( + children: [ + Text( + 'تلفات', + textAlign: TextAlign.right, + style: AppFonts.yekan14Bold.copyWith( + color: AppColor.textColor, + ), + ), + ], + ), + ), + ], + ), + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_farm_inspection/widgets/card_info.dart b/packages/chicken/lib/features/poultry_farm_inspection/widgets/card_info.dart index cf9da15..807e5ca 100644 --- a/packages/chicken/lib/features/poultry_farm_inspection/widgets/card_info.dart +++ b/packages/chicken/lib/features/poultry_farm_inspection/widgets/card_info.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/features/poultry_farm_inspection/home/logic.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/home/logic.dart'; import 'package:rasadyar_core/core.dart'; Widget farmInfoWidget({ diff --git a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step1_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step1_page.dart index 2ff435e..926a1e6 100644 --- a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step1_page.dart +++ b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step1_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/features/poultry_farm_inspection/widgets/card_info.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; import 'package:rasadyar_core/core.dart'; import '../home/logic.dart'; diff --git a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step2_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step2_page.dart index f7fba7a..9fc9bad 100644 --- a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step2_page.dart +++ b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step2_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/features/poultry_farm_inspection/widgets/card_info.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; import 'package:rasadyar_core/core.dart'; import '../home/logic.dart'; diff --git a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step3_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step3_page.dart index b03145c..86b2673 100644 --- a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step3_page.dart +++ b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step3_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/features/poultry_farm_inspection/widgets/card_info.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; import 'package:rasadyar_core/core.dart'; import '../home/logic.dart'; diff --git a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step4_page.dart b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step4_page.dart index 1dee69c..5570f4f 100644 --- a/packages/chicken/lib/features/poultry_farm_inspection/widgets/step4_page.dart +++ b/packages/chicken/lib/features/poultry_farm_inspection/widgets/step4_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/features/poultry_farm_inspection/widgets/card_info.dart'; += +import 'package:rasadyar_chicken/features/poultry_farm_inspection/presentation/widgets/card_info.dart'; import 'package:rasadyar_core/core.dart'; import '../home/logic.dart'; diff --git a/packages/chicken/lib/features/poultry_science/active_hatching/logic.dart b/packages/chicken/lib/features/poultry_science/active_hatching/logic.dart index c428715..f5868dd 100644 --- a/packages/chicken/lib/features/poultry_science/active_hatching/logic.dart +++ b/packages/chicken/lib/features/poultry_science/active_hatching/logic.dart @@ -1,10 +1,14 @@ -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; += +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class ActiveHatchingLogic extends GetxController { PoultryScienceRootLogic rootLogic = Get.find(); BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; Rx>> activeHatchingList = Resource>.loading().obs; @@ -17,6 +21,12 @@ class ActiveHatchingLogic extends GetxController { Rx toDateFilter = Jalali.now().obs; RxnString searchedValue = RxnString(); + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + @override void onReady() { super.onReady(); @@ -29,12 +39,12 @@ class ActiveHatchingLogic extends GetxController { baseLogic.clearSearch(); } - Future getHatchingList([bool isLoadingMore = false]) async { if (isLoadingMore) { isLoadingMoreList.value = true; } else { - activeHatchingList.value = Resource>.loading(); + activeHatchingList.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -44,7 +54,7 @@ class ActiveHatchingLogic extends GetxController { } safeCall( - call: () async => await rootLogic.poultryRepository.getHatchingPoultry( + call: () async => await poultryScienceRepository.getHatchingPoultry( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( queryParams: {'type': 'hatching'}, @@ -55,16 +65,21 @@ class ActiveHatchingLogic extends GetxController { ), onSuccess: (res) { if ((res?.count ?? 0) == 0) { - activeHatchingList.value = Resource>.empty(); + activeHatchingList.value = + Resource>.empty(); } else { - activeHatchingList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(activeHatchingList.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); } }, ); @@ -78,6 +93,4 @@ class ActiveHatchingLogic extends GetxController { currentPage.value = 1; await getHatchingList(); } - - } diff --git a/packages/chicken/lib/features/poultry_science/active_hatching/view.dart b/packages/chicken/lib/features/poultry_science/active_hatching/view.dart index 6877625..2aff667 100644 --- a/packages/chicken/lib/features/poultry_science/active_hatching/view.dart +++ b/packages/chicken/lib/features/poultry_science/active_hatching/view.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/features/poultry_science/active_hatching/logic.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/jahad/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_core/core.dart'; @@ -13,7 +16,7 @@ class ActiveHatchingPage extends GetView { return ChickenBasePage( hasSearch: true, hasFilter: false, - backId: poultryFirstKey, + backId: jahadActionKey, routes: controller.routesName, onSearchChanged: (data) { controller.searchedValue.value = data; @@ -50,7 +53,6 @@ class ActiveHatchingPage extends GetView { itemCount: data.value.data?.results?.length ?? 0, separatorBuilder: (context, index) => SizedBox(height: 8.h), onLoadMore: () async => controller.getHatchingList(true), - ); }, controller.activeHatchingList); } @@ -58,7 +60,10 @@ class ActiveHatchingPage extends GetView { Container itemListExpandedWidget(HatchingModel item) { return Container( padding: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), child: Column( spacing: 8, children: [ @@ -111,7 +116,10 @@ class ActiveHatchingPage extends GetView { ), ), - buildRow(title: 'شماره مجوز جوجه ریزی', value: item.licenceNumber ?? 'N/A'), + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), buildUnitRow( title: 'حجم جوجه ریزی', value: item.quantity.separatedByCommaFa, @@ -122,21 +130,52 @@ class ActiveHatchingPage extends GetView { value: item.leftOver.separatedByCommaFa, unit: '(قطعه)', ), - buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa, unit: '(قطعه)'), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), buildRow( title: 'دامپزشک فارم', - value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', ), buildRow( title: 'شرح بازرسی', - value: item.reportInfo?.image == false ? 'ارسال تصویر جوجه ریزی فارم ' : 'تکمیل شده', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', titleStyle: AppFonts.yekan14.copyWith( - color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark, + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, ), valueStyle: AppFonts.yekan14.copyWith( - color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark, + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, ), ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), ], ), ); diff --git a/packages/chicken/lib/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source.dart b/packages/chicken/lib/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source.dart new file mode 100644 index 0000000..68acd9c --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source.dart @@ -0,0 +1,109 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/approved_price/approved_price.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_export/poultry_export.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/kill_registration/kill_registration.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class PoultryScienceRemoteDataSource { + Future getHomePoultryScience({ + required String token, + required String type, + }); + + Future?> getHatchingPoultry({ + required String token, + Map? queryParameters, + }); + + Future submitPoultryScienceReport({ + required String token, + required FormData data, + ProgressCallback? onSendProgress, + }); + + Future?> getPoultryScienceReport({ + required String token, + Map? queryParameters, + }); + + Future?> getPoultryScienceFarmList({ + required String token, + Map? queryParameters, + }); + + Future getApprovedPrice({ + required String token, + Map? queryParameters, + }); + + Future?> getAllPoultry({ + required String token, + Map? queryParameters, + }); + + Future getSellForFreezing({ + required String token, + Map? queryParameters, + }); + + Future getPoultryExport({ + required String token, + Map? queryParameters, + }); + + Future?> getUserPoultry({ + required String token, + Map? queryParameters, + }); + + Future?> getPoultryHatching({ + required String token, + Map? queryParameters, + }); + + Future?> getKillHouseList({ + required String token, + Map? queryParameters, + }); + + Future submitKillRegistration({ + required String token, + required KillRegistrationRequest request, + }); + + Future?> getPoultryOderList({ + required String token, + Map? queryParameters, + }); + + Future deletePoultryOder({ + required String token, + required String orderId, + }); + + Future?> uploadImages({ + required String token, + required List images, + }); + + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart b/packages/chicken/lib/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source_impl.dart similarity index 60% rename from packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart rename to packages/chicken/lib/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source_impl.dart index a201d6f..0e41a29 100644 --- a/packages/chicken/lib/data/data_source/remote/poultry_science/poultry_science_remote_imp.dart +++ b/packages/chicken/lib/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source_impl.dart @@ -1,24 +1,26 @@ -import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart'; -import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; -import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart'; -import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/approved_price/approved_price.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_export/poultry_export.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/kill_registration/kill_registration.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source.dart'; import 'package:rasadyar_core/core.dart'; -import 'poultry_science_remote.dart'; - -class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasource { +class PoultryScienceRemoteDataSourceImpl + implements PoultryScienceRemoteDataSource { final DioRemote _httpClient; - PoultryScienceRemoteDatasourceImp(this._httpClient); + PoultryScienceRemoteDataSourceImpl(this._httpClient); @override Future getHomePoultryScience({ @@ -124,8 +126,9 @@ class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasourc '/get-all-poultry/', headers: {'Authorization': 'Bearer $token'}, queryParameters: queryParameters, - fromJsonList: (json) => - json.map((e) => AllPoultry.fromJson(e as Map)).toList(), + fromJsonList: (json) => json + .map((e) => AllPoultry.fromJson(e as Map)) + .toList(), ); return res.data; } @@ -167,7 +170,8 @@ class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasourc '/Poultry/', headers: {'Authorization': 'Bearer $token'}, queryParameters: queryParameters, - fromJsonList: (json) => json.map((e) => KillRequestPoultry.fromJson(e)).toList(), + fromJsonList: (json) => + json.map((e) => KillRequestPoultry.fromJson(e)).toList(), ); return res.data; } @@ -181,7 +185,8 @@ class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasourc '/poultry_hatching/', headers: {'Authorization': 'Bearer $token'}, queryParameters: queryParameters, - fromJsonList: (json) => json.map((e) => PoultryHatching.fromJson(e)).toList(), + fromJsonList: (json) => + json.map((e) => PoultryHatching.fromJson(e)).toList(), ); return res.data; } @@ -195,7 +200,8 @@ class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasourc '/kill_house_list/', headers: {'Authorization': 'Bearer $token'}, queryParameters: queryParameters, - fromJsonList: (json) => json.map((e) => KillHousePoultry.fromJson(e)).toList(), + fromJsonList: (json) => + json.map((e) => KillHousePoultry.fromJson(e)).toList(), ); return res.data; } @@ -231,12 +237,60 @@ class PoultryScienceRemoteDatasourceImp implements PoultryScienceRemoteDatasourc } @override - Future deletePoultryOder({required String token, required String orderId}) async { + Future deletePoultryOder({ + required String token, + required String orderId, + }) async { await _httpClient.delete( '/Poultry_Request/$orderId/', headers: {'Authorization': 'Bearer $token'}, ); } + @override + Future?> uploadImages({ + required String token, + required List images, + }) async { + var res = await _httpClient.post?>( + '/upload_image_to_server_for_poultry_science/', + headers: {'Authorization': 'Bearer $token'}, + data: FormData.fromMap({ + 'file': images.map((e) => MultipartFile.fromFileSync(e.path)).toList(), + }), + fromJson: (json) => List.from(json['urls'] as List), + ); + return res.data; + } + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } + //endregion } diff --git a/packages/chicken/lib/features/poultry_science/data/di/poultry_science_di.dart b/packages/chicken/lib/features/poultry_science/data/di/poultry_science_di.dart new file mode 100644 index 0000000..b91c006 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/di/poultry_science_di.dart @@ -0,0 +1,38 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for poultry_science feature +Future setupPoultryScienceDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => PoultryScienceRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => + PoultryScienceRepositoryImpl(di.get()), + ); +} + +/// Re-register poultry_science dependencies (used when base URL changes) +Future reRegisterPoultryScienceDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => PoultryScienceRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => + PoultryScienceRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/data/models/request/kill_registration/kill_registration.dart b/packages/chicken/lib/features/poultry_science/data/model/request/kill_registration/kill_registration.dart similarity index 100% rename from packages/chicken/lib/data/models/request/kill_registration/kill_registration.dart rename to packages/chicken/lib/features/poultry_science/data/model/request/kill_registration/kill_registration.dart diff --git a/packages/chicken/lib/data/models/request/kill_registration/kill_registration.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/request/kill_registration/kill_registration.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/kill_registration/kill_registration.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/request/kill_registration/kill_registration.freezed.dart diff --git a/packages/chicken/lib/data/models/request/kill_registration/kill_registration.g.dart b/packages/chicken/lib/features/poultry_science/data/model/request/kill_registration/kill_registration.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/kill_registration/kill_registration.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/request/kill_registration/kill_registration.g.dart diff --git a/packages/chicken/lib/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart b/packages/chicken/lib/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart new file mode 100644 index 0000000..50b32f2 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart @@ -0,0 +1,560 @@ +/// مدل داده‌ای برای ارسال اطلاعات بازرسی مرغداری به سرور +/// +/// این کلاس شامل تمام اطلاعات مربوط به بازرسی یک واحد مرغداری است که شامل: +/// - موقعیت جغرافیایی (عرض و طول جغرافیایی) +/// - شناسه جوجه‌ریزی +/// - نقش کاربر +/// - اطلاعات مختلف بازرسی در بخش‌های مختلف +/// +/// این مدل برای ارسال درخواست POST به endpoint `/poultry_science_report/` استفاده می‌شود. +class SubmitInspectionResponse { + /// سازنده کلاس SubmitInspectionResponse + /// + /// تمام پارامترها اختیاری هستند و می‌توانند null باشند. + SubmitInspectionResponse({ + this.lat, + this.log, + this.poultryHatchingId, + this.role, + this.generalConditionHall, + this.casualties, + this.technicalOfficer, + this.inputStatus, + this.infrastructureEnergy, + this.hr, + this.facilities, + this.inspectionStatus, + this.inspectionNotes, + }); + + /// عرض جغرافیایی (Latitude) محل بازرسی + String? lat; + + /// طول جغرافیایی (Longitude) محل بازرسی + String? log; + + /// شناسه یکتای جوجه‌ریزی که بازرسی برای آن انجام می‌شود + int? poultryHatchingId; + + /// نقش کاربری که بازرسی را انجام می‌دهد + String? role; + + /// اطلاعات مربوط به شرایط عمومی سالن مرغداری + GeneralConditionHall? generalConditionHall; + + /// اطلاعات مربوط به تلفات و خسارات + Casualties? casualties; + + /// اطلاعات مربوط به کارشناسان فنی + TechnicalOfficer? technicalOfficer; + + /// اطلاعات مربوط به وضعیت نهاده‌ها + InputStatus? inputStatus; + + /// اطلاعات مربوط به زیرساخت و انرژی + InfrastructureEnergy? infrastructureEnergy; + + /// اطلاعات مربوط به نیروی انسانی + Hr? hr; + + /// اطلاعات مربوط به تسهیلات + Facilities? facilities; + + /// وضعیت بازرسی (مثلاً: انجام شده، در حال انجام، لغو شده) + String? inspectionStatus; + + /// یادداشت‌ها و توضیحات بازرس + String? inspectionNotes; + + /// تبدیل شیء به فرمت JSON برای ارسال به سرور + /// + /// تمام اطلاعات بازرسی را در یک ساختار JSON سازماندهی می‌کند. + /// بخش‌های مختلف بازرسی در زیر کلید `report_information` قرار می‌گیرند. + Map toJson() { + return { + 'lat': lat, + 'log': log, + 'hatching_id': poultryHatchingId, + 'role': role, + 'report_information': { + 'general_condition_hall': generalConditionHall?.toJson(), + 'casualties': casualties?.toJson(), + 'technical_officer': technicalOfficer?.toJson(), + 'input_status': inputStatus?.toJson(), + 'infrastructure_energy': infrastructureEnergy?.toJson(), + 'hr': hr?.toJson(), + 'facilities': facilities?.toJson(), + 'inspection_status': inspectionStatus, + 'inspection_notes': inspectionNotes, + }, + }; + } + + /// ساخت شیء از JSON دریافتی از سرور + /// + /// این متد برای تبدیل پاسخ JSON سرور به یک شیء SubmitInspectionResponse استفاده می‌شود. + factory SubmitInspectionResponse.fromJson(Map json) { + return SubmitInspectionResponse( + lat: json['lat'].toString(), + log: json['log'].toString(), + poultryHatchingId: json['poultry_hatching_id'] as int?, + role: json['role'] as String?, + generalConditionHall: json['general_condition_hall'] != null + ? GeneralConditionHall.fromJson( + json['general_condition_hall'] as Map, + ) + : null, + casualties: json['casualties'] != null + ? Casualties.fromJson(json['casualties'] as Map) + : null, + technicalOfficer: json['technical_officer'] != null + ? TechnicalOfficer.fromJson( + json['technical_officer'] as Map, + ) + : null, + inputStatus: json['input_status'] != null + ? InputStatus.fromJson(json['input_status'] as Map) + : null, + infrastructureEnergy: json['infrastructure_energy'] != null + ? InfrastructureEnergy.fromJson( + json['infrastructure_energy'] as Map, + ) + : null, + hr: json['hr'] != null + ? Hr.fromJson(json['hr'] as Map) + : null, + facilities: json['facilities'] != null + ? Facilities.fromJson(json['facilities'] as Map) + : null, + inspectionStatus: json['inspection_status'] as String?, + inspectionNotes: json['inspection_notes'] as String?, + ); + } +} + +/// اطلاعات مربوط به شرایط عمومی سالن مرغداری +/// +/// این کلاس شامل اطلاعاتی در مورد وضعیت سلامت، تهویه، بستر، دما و آب آشامیدنی سالن است. +class GeneralConditionHall { + /// سازنده کلاس GeneralConditionHall + GeneralConditionHall({ + this.images, + this.healthStatus, + this.ventilationStatus, + this.bedCondition, + this.temperature, + this.drinkingWaterSource, + this.drinkingWaterQuality, + }); + + /// لیست آدرس تصاویر مربوط به شرایط سالن + List? images; + + /// وضعیت سلامت سالن + String? healthStatus; + + /// وضعیت سیستم تهویه + String? ventilationStatus; + + /// وضعیت بستر سالن + String? bedCondition; + + /// دمای سالن + String? temperature; + + /// منبع آب آشامیدنی + String? drinkingWaterSource; + + /// کیفیت آب آشامیدنی + String? drinkingWaterQuality; + + Map toJson() { + return { + 'images': images, + 'health_status': healthStatus, + 'ventilation_status': ventilationStatus, + 'bed_condition': bedCondition, + 'temperature': temperature, + 'drinking_water_source': drinkingWaterSource, + 'drinking_water_quality': drinkingWaterQuality, + }; + } + + factory GeneralConditionHall.fromJson(Map json) { + return GeneralConditionHall( + images: json['images'] != null + ? List.from(json['images'] as List) + : null, + healthStatus: json['health_status'] as String?, + ventilationStatus: json['ventilation_status'] as String?, + bedCondition: json['bed_condition'] as String?, + temperature: json['temperature'] as String?, + drinkingWaterSource: json['drinking_water_source'] as String?, + drinkingWaterQuality: json['drinking_water_quality'] as String?, + ); + } +} + +/// اطلاعات مربوط به تلفات و خسارات +/// +/// این کلاس شامل اطلاعاتی در مورد تلفات عادی و غیرعادی، منبع جوجه‌ریزی، +/// علت تلفات غیرعادی، نوع بیماری و نمونه‌برداری است. +class Casualties { + /// سازنده کلاس Casualties + Casualties({ + this.normalLosses, + this.abnormalLosses, + this.sourceOfHatching, + this.causeAbnormalLosses, + this.typeDisease, + this.samplingDone, + this.typeSampling, + this.images, + }); + + /// تعداد تلفات عادی + int? normalLosses; + + /// تعداد تلفات غیرعادی + int? abnormalLosses; + + /// منبع جوجه‌ریزی + String? sourceOfHatching; + + /// علت تلفات غیرعادی + String? causeAbnormalLosses; + + /// نوع بیماری (در صورت وجود) + String? typeDisease; + + /// آیا نمونه‌برداری انجام شده است؟ + bool? samplingDone; + + /// نوع نمونه‌برداری انجام شده + String? typeSampling; + + /// لیست آدرس تصاویر مربوط به تلفات + List? images; + + Map toJson() { + return { + 'normal_losses': normalLosses, + 'abnormal_losses': abnormalLosses, + 'source_of_hatching': sourceOfHatching, + 'cause_abnormal_losses': causeAbnormalLosses, + 'type_disease': typeDisease, + 'sampling_done': samplingDone, + 'type_sampling': typeSampling, + 'images': images, + }; + } + + factory Casualties.fromJson(Map json) { + return Casualties( + normalLosses: json['normal_losses'] as int?, + abnormalLosses: json['abnormal_losses'] as int?, + sourceOfHatching: json['source_of_hatching'] as String?, + causeAbnormalLosses: json['cause_abnormal_losses'] as String?, + typeDisease: json['type_disease'] as String?, + samplingDone: json['sampling_done'] as bool?, + typeSampling: json['type_sampling'] as String?, + images: json['images'] != null + ? List.from(json['images'] as List) + : null, + ); + } +} + +/// اطلاعات مربوط به کارشناسان فنی +/// +/// این کلاس شامل اطلاعات کارشناس بهداشت و کارشناس فنی مهندسی است. +class TechnicalOfficer { + /// سازنده کلاس TechnicalOfficer + TechnicalOfficer({ + this.technicalHealthOfficer, + this.technicalEngineeringOfficer, + }); + + /// نام یا اطلاعات کارشناس بهداشت + String? technicalHealthOfficer; + + /// نام یا اطلاعات کارشناس فنی مهندسی + String? technicalEngineeringOfficer; + + Map toJson() { + return { + 'technical_health_officer': technicalHealthOfficer, + 'technical_engineering_officer': technicalEngineeringOfficer, + }; + } + + factory TechnicalOfficer.fromJson(Map json) { + return TechnicalOfficer( + technicalHealthOfficer: json['technical_health_officer'] as String?, + technicalEngineeringOfficer: + json['technical_engineering_officer'] as String?, + ); + } +} + +/// اطلاعات مربوط به وضعیت نهاده‌ها +/// +/// این کلاس شامل اطلاعاتی در مورد نهاده‌های مصرفی مرغداری شامل: +/// وضعیت نهاده، نام شرکت، کد رهگیری، نوع دان، موجودی انبار و درجه دان است. +class InputStatus { + /// سازنده کلاس InputStatus + InputStatus({ + this.inputStatus, + this.companyName, + this.trackingCode, + this.typeOfGrain, + this.inventoryInWarehouse, + this.inventoryUntilVisit, + this.gradeGrain, + this.images, + }); + + /// وضعیت نهاده‌ها + String? inputStatus; + + /// نام شرکت تامین‌کننده نهاده + String? companyName; + + /// کد رهگیری نهاده + String? trackingCode; + + /// نوع دان مصرفی + String? typeOfGrain; + + /// موجودی نهاده در انبار + String? inventoryInWarehouse; + + /// موجودی نهاده تا زمان بازدید + String? inventoryUntilVisit; + + /// درجه دان + String? gradeGrain; + + /// لیست آدرس تصاویر مربوط به نهاده‌ها + List? images; + + Map toJson() { + return { + 'input_status': inputStatus, + 'company_name': companyName, + 'tracking_code': trackingCode, + 'type_of_grain': typeOfGrain, + 'inventory_in_warehouse': inventoryInWarehouse, + 'inventory_until_visit': inventoryUntilVisit, + 'grade_grain': gradeGrain, + 'images': images, + }; + } + + factory InputStatus.fromJson(Map json) { + return InputStatus( + inputStatus: json['input_status'] as String?, + companyName: json['company_name'] as String?, + trackingCode: json['tracking_code'] as String?, + typeOfGrain: json['type_of_grain'] as String?, + inventoryInWarehouse: json['inventory_in_warehouse'] as String?, + inventoryUntilVisit: json['inventory_until_visit'] as String?, + gradeGrain: json['grade_grain'] as String?, + images: json['images'] != null + ? List.from(json['images'] as List) + : null, + ); + } +} + +/// اطلاعات مربوط به زیرساخت و انرژی +/// +/// این کلاس شامل اطلاعاتی در مورد ژنراتور، سوخت، قطعی برق و سایر +/// اطلاعات مربوط به زیرساخت انرژی مرغداری است. +class InfrastructureEnergy { + /// سازنده کلاس InfrastructureEnergy + InfrastructureEnergy({ + this.generatorType, + this.generatorModel, + this.generatorCount, + this.generatorCapacity, + this.fuelType, + this.generatorPerformance, + this.emergencyFuelInventory, + this.hasPowerCutHistory, + this.powerCutDuration, + this.powerCutHour, + this.additionalNotes, + }); + + /// نوع ژنراتور + String? generatorType; + + /// مدل ژنراتور + String? generatorModel; + + /// تعداد ژنراتورها + String? generatorCount; + + /// ظرفیت ژنراتور + String? generatorCapacity; + + /// نوع سوخت ژنراتور + String? fuelType; + + /// عملکرد ژنراتور + String? generatorPerformance; + + /// موجودی سوخت اضطراری + String? emergencyFuelInventory; + + /// آیا سابقه قطعی برق وجود دارد؟ + bool? hasPowerCutHistory; + + /// مدت زمان قطعی برق + String? powerCutDuration; + + /// ساعت قطعی برق + String? powerCutHour; + + /// یادداشت‌های اضافی + String? additionalNotes; + + Map toJson() { + return { + 'generator_type': generatorType, + 'generator_model': generatorModel, + 'generator_count': generatorCount, + 'generator_capacity': generatorCapacity, + 'fuel_type': fuelType, + 'generator_performance': generatorPerformance, + 'emergency_fuel_inventory': emergencyFuelInventory, + 'has_power_cut_history': hasPowerCutHistory, + 'power_cut_duration': powerCutDuration, + 'power_cut_hour': powerCutHour, + 'additional_notes': additionalNotes, + }; + } + + factory InfrastructureEnergy.fromJson(Map json) { + return InfrastructureEnergy( + generatorType: json['generator_type'] as String?, + generatorModel: json['generator_model'] as String?, + generatorCount: json['generator_count'] as String?, + generatorCapacity: json['generator_capacity'] as String?, + fuelType: json['fuel_type'] as String?, + generatorPerformance: json['generator_performance'] as String?, + emergencyFuelInventory: json['emergency_fuel_inventory'] as String?, + hasPowerCutHistory: json['has_power_cut_history'] as bool?, + powerCutDuration: json['power_cut_duration'] as String?, + powerCutHour: json['power_cut_hour'] as String?, + additionalNotes: json['additional_notes'] as String?, + ); + } +} + +/// اطلاعات مربوط به نیروی انسانی +/// +/// این کلاس شامل اطلاعاتی در مورد تعداد کارکنان، وضعیت بومی/غیربومی بودن +/// کارکنان، وضعیت قرارداد و آموزش کارکنان است. +class Hr { + /// سازنده کلاس Hr + Hr({ + this.numberEmployed, + this.numberIndigenous, + this.numberNonIndigenous, + this.contractStatus, + this.trained, + }); + + /// تعداد کل کارکنان + int? numberEmployed; + + /// تعداد کارکنان بومی + int? numberIndigenous; + + /// تعداد کارکنان غیربومی + int? numberNonIndigenous; + + /// وضعیت قرارداد کارکنان + String? contractStatus; + + /// آیا کارکنان آموزش دیده‌اند؟ + bool? trained; + + Map toJson() { + return { + 'number_employed': numberEmployed, + 'number_indigenous': numberIndigenous, + 'number_non_indigenous': numberNonIndigenous, + 'contract_status': contractStatus, + 'trained': trained, + }; + } + + factory Hr.fromJson(Map json) { + return Hr( + numberEmployed: json['number_employed'] as int?, + numberIndigenous: json['number_indigenous'] as int?, + numberNonIndigenous: json['number_non_indigenous'] as int?, + contractStatus: json['contract_status'] as String?, + trained: json['trained'] as bool?, + ); + } +} + +/// اطلاعات مربوط به تسهیلات +/// +/// این کلاس شامل اطلاعاتی در مورد تسهیلات دریافتی مرغداری شامل: +/// وجود تسهیلات، نوع تسهیلات، مبلغ، تاریخ و وضعیت بازپرداخت است. +class Facilities { + /// سازنده کلاس Facilities + Facilities({ + this.hasFacilities, + this.typeOfFacility, + this.amount, + this.date, + this.repaymentStatus, + this.requestFacilities, + }); + + /// آیا تسهیلات دریافت شده است؟ + bool? hasFacilities; + + /// نوع تسهیلات + String? typeOfFacility; + + /// مبلغ تسهیلات + int? amount; + + /// تاریخ دریافت تسهیلات + String? date; + + /// وضعیت بازپرداخت تسهیلات + String? repaymentStatus; + + /// درخواست تسهیلات + String? requestFacilities; + + Map toJson() { + return { + 'has_facilities': hasFacilities, + 'type_of_facility': typeOfFacility, + 'amount': amount, + 'date': date, + 'repayment_status': repaymentStatus, + 'request_facilities': requestFacilities, + }; + } + + factory Facilities.fromJson(Map json) { + return Facilities( + hasFacilities: json['has_facilities'] as bool?, + typeOfFacility: json['type_of_facility'] as String?, + amount: json['amount'] as int?, + date: json['date'] as String?, + repaymentStatus: json['repayment_status'] as String?, + requestFacilities: json['request_facilities'] as String?, + ); + } +} diff --git a/packages/chicken/lib/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response_schema.json b/packages/chicken/lib/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response_schema.json new file mode 100644 index 0000000..e8a0899 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response_schema.json @@ -0,0 +1,430 @@ +{ + "description": "ساختار و توضیحات کامل مدل SubmitInspectionResponse برای ارسال اطلاعات بازرسی مرغداری", + "endpoint": "/poultry_science_report/", + "method": "POST", + "schema": { + "lat": { + "type": "string", + "required": false, + "description": "عرض جغرافیایی (Latitude) محل بازرسی", + "example": "35.6892" + }, + "log": { + "type": "string", + "required": false, + "description": "طول جغرافیایی (Longitude) محل بازرسی", + "example": "51.3890" + }, + "hatching_id": { + "type": "integer", + "required": false, + "description": "شناسه یکتای جوجه‌ریزی که بازرسی برای آن انجام می‌شود", + "example": 12345 + }, + "role": { + "type": "string", + "required": false, + "description": "نقش کاربری که بازرسی را انجام می‌دهد", + "example": "inspector" + }, + "report_information": { + "type": "object", + "required": false, + "description": "اطلاعات کامل بازرسی در بخش‌های مختلف", + "properties": { + "general_condition_hall": { + "type": "object", + "required": false, + "description": "اطلاعات مربوط به شرایط عمومی سالن مرغداری", + "properties": { + "images": { + "type": "array", + "items": { + "type": "string" + }, + "required": false, + "description": "لیست آدرس تصاویر مربوط به شرایط سالن" + }, + "health_status": { + "type": "string", + "required": false, + "description": "وضعیت سلامت سالن" + }, + "ventilation_status": { + "type": "string", + "required": false, + "description": "وضعیت سیستم تهویه" + }, + "bed_condition": { + "type": "string", + "required": false, + "description": "وضعیت بستر سالن" + }, + "temperature": { + "type": "string", + "required": false, + "description": "دمای سالن" + }, + "drinking_water_source": { + "type": "string", + "required": false, + "description": "منبع آب آشامیدنی" + }, + "drinking_water_quality": { + "type": "string", + "required": false, + "description": "کیفیت آب آشامیدنی" + } + } + }, + "casualties": { + "type": "object", + "required": false, + "description": "اطلاعات مربوط به تلفات و خسارات", + "properties": { + "normal_losses": { + "type": "integer", + "required": false, + "description": "تعداد تلفات عادی", + "example": 50 + }, + "abnormal_losses": { + "type": "integer", + "required": false, + "description": "تعداد تلفات غیرعادی", + "example": 10 + }, + "source_of_hatching": { + "type": "string", + "required": false, + "description": "منبع جوجه‌ریزی" + }, + "cause_abnormal_losses": { + "type": "string", + "required": false, + "description": "علت تلفات غیرعادی" + }, + "type_disease": { + "type": "string", + "required": false, + "description": "نوع بیماری (در صورت وجود)" + }, + "sampling_done": { + "type": "boolean", + "required": false, + "description": "آیا نمونه‌برداری انجام شده است؟", + "example": true + }, + "type_sampling": { + "type": "string", + "required": false, + "description": "نوع نمونه‌برداری انجام شده" + }, + "images": { + "type": "array", + "items": { + "type": "string" + }, + "required": false, + "description": "لیست آدرس تصاویر مربوط به تلفات" + } + } + }, + "technical_officer": { + "type": "object", + "required": false, + "description": "اطلاعات مربوط به کارشناسان فنی", + "properties": { + "technical_health_officer": { + "type": "string", + "required": false, + "description": "نام یا اطلاعات کارشناس بهداشت" + }, + "technical_engineering_officer": { + "type": "string", + "required": false, + "description": "نام یا اطلاعات کارشناس فنی مهندسی" + } + } + }, + "input_status": { + "type": "object", + "required": false, + "description": "اطلاعات مربوط به وضعیت نهاده‌ها", + "properties": { + "input_status": { + "type": "string", + "required": false, + "description": "وضعیت نهاده‌ها" + }, + "company_name": { + "type": "string", + "required": false, + "description": "نام شرکت تامین‌کننده نهاده" + }, + "tracking_code": { + "type": "string", + "required": false, + "description": "کد رهگیری نهاده" + }, + "type_of_grain": { + "type": "string", + "required": false, + "description": "نوع دان مصرفی" + }, + "inventory_in_warehouse": { + "type": "string", + "required": false, + "description": "موجودی نهاده در انبار" + }, + "inventory_until_visit": { + "type": "string", + "required": false, + "description": "موجودی نهاده تا زمان بازدید" + }, + "grade_grain": { + "type": "string", + "required": false, + "description": "درجه دان" + }, + "images": { + "type": "array", + "items": { + "type": "string" + }, + "required": false, + "description": "لیست آدرس تصاویر مربوط به نهاده‌ها" + } + } + }, + "infrastructure_energy": { + "type": "object", + "required": false, + "description": "اطلاعات مربوط به زیرساخت و انرژی", + "properties": { + "generator_type": { + "type": "string", + "required": false, + "description": "نوع ژنراتور" + }, + "generator_model": { + "type": "string", + "required": false, + "description": "مدل ژنراتور" + }, + "generator_count": { + "type": "string", + "required": false, + "description": "تعداد ژنراتورها" + }, + "generator_capacity": { + "type": "string", + "required": false, + "description": "ظرفیت ژنراتور" + }, + "fuel_type": { + "type": "string", + "required": false, + "description": "نوع سوخت ژنراتور" + }, + "generator_performance": { + "type": "string", + "required": false, + "description": "عملکرد ژنراتور" + }, + "emergency_fuel_inventory": { + "type": "string", + "required": false, + "description": "موجودی سوخت اضطراری" + }, + "has_power_cut_history": { + "type": "boolean", + "required": false, + "description": "آیا سابقه قطعی برق وجود دارد؟", + "example": true + }, + "power_cut_duration": { + "type": "string", + "required": false, + "description": "مدت زمان قطعی برق" + }, + "power_cut_hour": { + "type": "string", + "required": false, + "description": "ساعت قطعی برق" + }, + "additional_notes": { + "type": "string", + "required": false, + "description": "یادداشت‌های اضافی" + } + } + }, + "hr": { + "type": "object", + "required": false, + "description": "اطلاعات مربوط به نیروی انسانی", + "properties": { + "number_employed": { + "type": "integer", + "required": false, + "description": "تعداد کل کارکنان", + "example": 15 + }, + "number_indigenous": { + "type": "integer", + "required": false, + "description": "تعداد کارکنان بومی", + "example": 10 + }, + "number_non_indigenous": { + "type": "integer", + "required": false, + "description": "تعداد کارکنان غیربومی", + "example": 5 + }, + "contract_status": { + "type": "string", + "required": false, + "description": "وضعیت قرارداد کارکنان" + }, + "trained": { + "type": "boolean", + "required": false, + "description": "آیا کارکنان آموزش دیده‌اند؟", + "example": true + } + } + }, + "facilities": { + "type": "object", + "required": false, + "description": "اطلاعات مربوط به تسهیلات", + "properties": { + "has_facilities": { + "type": "boolean", + "required": false, + "description": "آیا تسهیلات دریافت شده است؟", + "example": true + }, + "type_of_facility": { + "type": "string", + "required": false, + "description": "نوع تسهیلات" + }, + "amount": { + "type": "integer", + "required": false, + "description": "مبلغ تسهیلات", + "example": 500000000 + }, + "date": { + "type": "string", + "required": false, + "description": "تاریخ دریافت تسهیلات" + }, + "repayment_status": { + "type": "string", + "required": false, + "description": "وضعیت بازپرداخت تسهیلات" + }, + "request_facilities": { + "type": "string", + "required": false, + "description": "درخواست تسهیلات" + } + } + }, + "inspection_status": { + "type": "string", + "required": false, + "description": "وضعیت بازرسی (مثلاً: انجام شده، در حال انجام، لغو شده)" + }, + "inspection_notes": { + "type": "string", + "required": false, + "description": "یادداشت‌ها و توضیحات بازرس" + } + } + } + }, + "example_request": { + "lat": "35.6892", + "log": "51.3890", + "hatching_id": 12345, + "role": "inspector", + "report_information": { + "general_condition_hall": { + "images": [ + "https://example.com/image1.jpg" + ], + "health_status": "خوب", + "ventilation_status": "مناسب", + "bed_condition": "تمیز", + "temperature": "25", + "drinking_water_source": "چاه", + "drinking_water_quality": "عالی" + }, + "casualties": { + "normal_losses": 50, + "abnormal_losses": 10, + "source_of_hatching": "مرکز جوجه‌کشی", + "cause_abnormal_losses": "بیماری", + "type_disease": "نیوکاسل", + "sampling_done": true, + "type_sampling": "خون", + "images": [] + }, + "technical_officer": { + "technical_health_officer": "احمد محمدی", + "technical_engineering_officer": "علی رضایی" + }, + "input_status": { + "input_status": "کافی", + "company_name": "شرکت دان", + "tracking_code": "TR123456", + "type_of_grain": "استارتر", + "inventory_in_warehouse": "5000 کیلوگرم", + "inventory_until_visit": "4500 کیلوگرم", + "grade_grain": "A", + "images": [] + }, + "infrastructure_energy": { + "generator_type": "دیزلی", + "generator_model": "کامینز", + "generator_count": "2", + "generator_capacity": "100 کیلووات", + "fuel_type": "گازوئیل", + "generator_performance": "عالی", + "emergency_fuel_inventory": "5000 لیتر", + "has_power_cut_history": true, + "power_cut_duration": "2 ساعت", + "power_cut_hour": "14:00", + "additional_notes": "ژنراتورها به درستی نگهداری می‌شوند" + }, + "hr": { + "number_employed": 15, + "number_indigenous": 10, + "number_non_indigenous": 5, + "contract_status": "قراردادی", + "trained": true + }, + "facilities": { + "has_facilities": true, + "type_of_facility": "وام", + "amount": 500000000, + "date": "1403/01/15", + "repayment_status": "در حال بازپرداخت", + "request_facilities": "درخواست تسهیلات جدید" + }, + "inspection_status": "انجام شده", + "inspection_notes": "بازرسی با موفقیت انجام شد" + } + } +} + + + + + + diff --git a/packages/chicken/lib/data/models/response/all_poultry/all_poultry.dart b/packages/chicken/lib/features/poultry_science/data/model/response/all_poultry/all_poultry.dart similarity index 100% rename from packages/chicken/lib/data/models/response/all_poultry/all_poultry.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/all_poultry/all_poultry.dart diff --git a/packages/chicken/lib/data/models/response/all_poultry/all_poultry.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/all_poultry/all_poultry.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/all_poultry/all_poultry.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/all_poultry/all_poultry.freezed.dart diff --git a/packages/chicken/lib/data/models/response/all_poultry/all_poultry.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/all_poultry/all_poultry.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/all_poultry/all_poultry.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/all_poultry/all_poultry.g.dart diff --git a/packages/chicken/lib/data/models/response/approved_price/approved_price.dart b/packages/chicken/lib/features/poultry_science/data/model/response/approved_price/approved_price.dart similarity index 100% rename from packages/chicken/lib/data/models/response/approved_price/approved_price.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/approved_price/approved_price.dart diff --git a/packages/chicken/lib/data/models/response/approved_price/approved_price.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/approved_price/approved_price.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/approved_price/approved_price.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/approved_price/approved_price.freezed.dart diff --git a/packages/chicken/lib/data/models/response/approved_price/approved_price.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/approved_price/approved_price.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/approved_price/approved_price.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/approved_price/approved_price.g.dart diff --git a/packages/chicken/lib/data/models/response/hatching/hatching_models.dart b/packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.dart similarity index 78% rename from packages/chicken/lib/data/models/response/hatching/hatching_models.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.dart index cc72dd4..3db0271 100644 --- a/packages/chicken/lib/data/models/response/hatching/hatching_models.dart +++ b/packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.dart @@ -4,7 +4,7 @@ part 'hatching_models.freezed.dart'; part 'hatching_models.g.dart'; @freezed -abstract class HatchingModel with _$HatchingModel{ +abstract class HatchingModel with _$HatchingModel { const factory HatchingModel({ int? id, Poultry? poultry, @@ -94,6 +94,11 @@ abstract class HatchingModel with _$HatchingModel{ String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, + num? totalDiseaseLosses, + num? totalFlockDestruction, + num? totalNormalFlockLosses, + num? totalForceMajeureLosses, + num? totalFireLosses, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, @@ -107,11 +112,13 @@ abstract class HatchingModel with _$HatchingModel{ String? tenantCity, bool? hasTenant, String? archiveDate, + bool? unknown, String? createdBy, String? modifiedBy, }) = _HatchingModel; - factory HatchingModel.fromJson(Map json) => _$HatchingModelFromJson(json); + factory HatchingModel.fromJson(Map json) => + _$HatchingModelFromJson(json); } @freezed @@ -180,24 +187,23 @@ abstract class Poultry with _$Poultry { num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, - int? interestLicenseId, + String? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet, }) = _Poultry; - factory Poultry.fromJson(Map json) => _$PoultryFromJson(json); + factory Poultry.fromJson(Map json) => + _$PoultryFromJson(json); } @freezed abstract class PoultryUser with _$PoultryUser { - const factory PoultryUser({ - String? fullname, - String? mobile, - }) = _PoultryUser; + const factory PoultryUser({String? fullname, String? mobile}) = _PoultryUser; - factory PoultryUser.fromJson(Map json) => _$PoultryUserFromJson(json); + factory PoultryUser.fromJson(Map json) => + _$PoultryUserFromJson(json); } @freezed @@ -209,27 +215,24 @@ abstract class PoultryAddress with _$PoultryAddress { String? postalCode, }) = _PoultryAddress; - factory PoultryAddress.fromJson(Map json) => _$PoultryAddressFromJson(json); + factory PoultryAddress.fromJson(Map json) => + _$PoultryAddressFromJson(json); } @freezed abstract class ProvinceRef with _$ProvinceRef { - const factory ProvinceRef({ - String? key, - String? name, - }) = _ProvinceRef; + const factory ProvinceRef({String? key, String? name}) = _ProvinceRef; - factory ProvinceRef.fromJson(Map json) => _$ProvinceRefFromJson(json); + factory ProvinceRef.fromJson(Map json) => + _$ProvinceRefFromJson(json); } @freezed abstract class CityRef with _$CityRef { - const factory CityRef({ - String? key, - String? name, - }) = _CityRef; + const factory CityRef({String? key, String? name}) = _CityRef; - factory CityRef.fromJson(Map json) => _$CityRefFromJson(json); + factory CityRef.fromJson(Map json) => + _$CityRefFromJson(json); } @freezed @@ -247,7 +250,8 @@ abstract class ChainCompany with _$ChainCompany { num? wallet, }) = _ChainCompany; - factory ChainCompany.fromJson(Map json) => _$ChainCompanyFromJson(json); + factory ChainCompany.fromJson(Map json) => + _$ChainCompanyFromJson(json); } @freezed @@ -289,7 +293,8 @@ abstract class ChainUser with _$ChainUser { String? unitAddress, }) = _ChainUser; - factory ChainUser.fromJson(Map json) => _$ChainUserFromJson(json); + factory ChainUser.fromJson(Map json) => + _$ChainUserFromJson(json); } @freezed @@ -306,27 +311,26 @@ abstract class ChainUserState with _$ChainUserState { String? nationalCode, }) = _ChainUserState; - factory ChainUserState.fromJson(Map json) => _$ChainUserStateFromJson(json); + factory ChainUserState.fromJson(Map json) => + _$ChainUserStateFromJson(json); } @freezed abstract class VetFarm with _$VetFarm { - const factory VetFarm({ - String? vetFarmFullName, - String? vetFarmMobile, - }) = _VetFarm; + const factory VetFarm({String? vetFarmFullName, String? vetFarmMobile}) = + _VetFarm; - factory VetFarm.fromJson(Map json) => _$VetFarmFromJson(json); + factory VetFarm.fromJson(Map json) => + _$VetFarmFromJson(json); } @freezed abstract class ActiveKill with _$ActiveKill { - const factory ActiveKill({ - bool? activeKill, - num? countOfRequest, - }) = _ActiveKill; + const factory ActiveKill({bool? activeKill, num? countOfRequest}) = + _ActiveKill; - factory ActiveKill.fromJson(Map json) => _$ActiveKillFromJson(json); + factory ActiveKill.fromJson(Map json) => + _$ActiveKillFromJson(json); } @freezed @@ -348,7 +352,8 @@ abstract class KillingInfo with _$KillingInfo { num? wareHouseBarsWeightLose, }) = _KillingInfo; - factory KillingInfo.fromJson(Map json) => _$KillingInfoFromJson(json); + factory KillingInfo.fromJson(Map json) => + _$KillingInfoFromJson(json); } @freezed @@ -361,17 +366,16 @@ abstract class FreeGovernmentalInfo with _$FreeGovernmentalInfo { num? leftTotalFreeCommitmentQuantity, }) = _FreeGovernmentalInfo; - factory FreeGovernmentalInfo.fromJson(Map json) => _$FreeGovernmentalInfoFromJson(json); + factory FreeGovernmentalInfo.fromJson(Map json) => + _$FreeGovernmentalInfoFromJson(json); } @freezed abstract class ReportInfo with _$ReportInfo { - const factory ReportInfo({ - bool? poultryScience, - bool? image, - }) = _ReportInfo; + const factory ReportInfo({bool? poultryScience, bool? image}) = _ReportInfo; - factory ReportInfo.fromJson(Map json) => _$ReportInfoFromJson(json); + factory ReportInfo.fromJson(Map json) => + _$ReportInfoFromJson(json); } @freezed @@ -382,18 +386,17 @@ abstract class LatestHatchingChange with _$LatestHatchingChange { String? fullName, }) = _LatestHatchingChange; - factory LatestHatchingChange.fromJson(Map json) => _$LatestHatchingChangeFromJson(json); + factory LatestHatchingChange.fromJson(Map json) => + _$LatestHatchingChangeFromJson(json); } @freezed abstract class Registrar with _$Registrar { - const factory Registrar({ - String? date, - String? role, - String? fullname, - }) = _Registrar; + const factory Registrar({String? date, String? role, String? fullname}) = + _Registrar; - factory Registrar.fromJson(Map json) => _$RegistrarFromJson(json); + factory Registrar.fromJson(Map json) => + _$RegistrarFromJson(json); } @freezed @@ -405,7 +408,8 @@ abstract class LastChange with _$LastChange { String? fullName, }) = _LastChange; - factory LastChange.fromJson(Map json) => _$LastChangeFromJson(json); + factory LastChange.fromJson(Map json) => + _$LastChangeFromJson(json); } @freezed @@ -416,6 +420,6 @@ abstract class BreedItem with _$BreedItem { num? remainQuantity, }) = _BreedItem; - factory BreedItem.fromJson(Map json) => _$BreedItemFromJson(json); + factory BreedItem.fromJson(Map json) => + _$BreedItemFromJson(json); } - diff --git a/packages/chicken/lib/data/models/response/hatching/hatching_models.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.freezed.dart similarity index 95% rename from packages/chicken/lib/data/models/response/hatching/hatching_models.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.freezed.dart index 4319232..862be95 100644 --- a/packages/chicken/lib/data/models/response/hatching/hatching_models.freezed.dart +++ b/packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.freezed.dart @@ -15,7 +15,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$HatchingModel { - int? get id; Poultry? get poultry; ChainCompany? get chainCompany; num? get age; dynamic get inspectionLosses; VetFarm? get vetFarm; ActiveKill? get activeKill; KillingInfo? get killingInfo; FreeGovernmentalInfo? get freeGovernmentalInfo; ReportInfo? get reportInfo; String? get key; String? get createDate; String? get modifyDate; bool? get trash; bool? get hasChainCompany; int? get poultryIdForeignKey; int? get poultryHatchingIdKey; num? get quantity; num? get losses; num? get leftOver; num? get killedQuantity; num? get extraKilledQuantity; num? get governmentalKilledQuantity; num? get governmentalQuantity; num? get freeKilledQuantity; num? get freeQuantity; num? get chainKilledQuantity; num? get chainKilledWeight; num? get outProvinceKilledWeight; num? get outProvinceKilledQuantity; num? get exportKilledWeight; num? get exportKilledQuantity; num? get totalCommitment; String? get commitmentType; num? get totalCommitmentQuantity; num? get totalFreeCommitmentQuantity; num? get totalFreeCommitmentWeight; num? get totalKilledWeight; num? get totalAverageKilledWeight; num? get requestLeftOver; num? get hall; String? get date; String? get predicateDate; String? get chickenBreed; num? get period; String? get allowHatching; String? get state; bool? get archive; bool? get violation; String? get message; Registrar? get registrar; List? get breed; num? get cityNumber; String? get cityName; num? get provinceNumber; String? get provinceName; LastChange? get lastChange; num? get chickenAge; num? get nowAge; LatestHatchingChange? get latestHatchingChange; String? get violationReport; String? get violationMessage; List? get violationImage; String? get violationReporter; String? get violationReportDate; String? get violationReportEditor; String? get violationReportEditDate; num? get totalLosses; num? get directLosses; String? get directLossesInputer; String? get directLossesDate; String? get directLossesEditor; String? get directLossesLastEditDate; String? get endPeriodLossesInputer; String? get endPeriodLossesDate; String? get endPeriodLossesEditor; String? get endPeriodLossesLastEditDate; String? get breedingUniqueId; String? get licenceNumber; bool? get temporaryTrash; bool? get temporaryDeleted; String? get firstDateInputArchive; String? get secondDateInputArchive; String? get inputArchiver; String? get outputArchiveDate; String? get outputArchiver; num? get barDifferenceRequestWeight; num? get barDifferenceRequestQuantity; String? get healthCertificate; num? get samasatDischargePercentage; String? get personTypeName; String? get interactTypeName; String? get unionTypeName; String? get certId; num? get increaseQuantity; String? get tenantFullname; String? get tenantNationalCode; String? get tenantMobile; String? get tenantCity; bool? get hasTenant; String? get archiveDate; String? get createdBy; String? get modifiedBy; + int? get id; Poultry? get poultry; ChainCompany? get chainCompany; num? get age; dynamic get inspectionLosses; VetFarm? get vetFarm; ActiveKill? get activeKill; KillingInfo? get killingInfo; FreeGovernmentalInfo? get freeGovernmentalInfo; ReportInfo? get reportInfo; String? get key; String? get createDate; String? get modifyDate; bool? get trash; bool? get hasChainCompany; int? get poultryIdForeignKey; int? get poultryHatchingIdKey; num? get quantity; num? get losses; num? get leftOver; num? get killedQuantity; num? get extraKilledQuantity; num? get governmentalKilledQuantity; num? get governmentalQuantity; num? get freeKilledQuantity; num? get freeQuantity; num? get chainKilledQuantity; num? get chainKilledWeight; num? get outProvinceKilledWeight; num? get outProvinceKilledQuantity; num? get exportKilledWeight; num? get exportKilledQuantity; num? get totalCommitment; String? get commitmentType; num? get totalCommitmentQuantity; num? get totalFreeCommitmentQuantity; num? get totalFreeCommitmentWeight; num? get totalKilledWeight; num? get totalAverageKilledWeight; num? get requestLeftOver; num? get hall; String? get date; String? get predicateDate; String? get chickenBreed; num? get period; String? get allowHatching; String? get state; bool? get archive; bool? get violation; String? get message; Registrar? get registrar; List? get breed; num? get cityNumber; String? get cityName; num? get provinceNumber; String? get provinceName; LastChange? get lastChange; num? get chickenAge; num? get nowAge; LatestHatchingChange? get latestHatchingChange; String? get violationReport; String? get violationMessage; List? get violationImage; String? get violationReporter; String? get violationReportDate; String? get violationReportEditor; String? get violationReportEditDate; num? get totalLosses; num? get directLosses; String? get directLossesInputer; String? get directLossesDate; String? get directLossesEditor; String? get directLossesLastEditDate; String? get endPeriodLossesInputer; String? get endPeriodLossesDate; String? get endPeriodLossesEditor; String? get endPeriodLossesLastEditDate; String? get breedingUniqueId; String? get licenceNumber; bool? get temporaryTrash; bool? get temporaryDeleted; String? get firstDateInputArchive; String? get secondDateInputArchive; String? get inputArchiver; String? get outputArchiveDate; String? get outputArchiver; num? get barDifferenceRequestWeight; num? get barDifferenceRequestQuantity; num? get totalDiseaseLosses; num? get totalFlockDestruction; num? get totalNormalFlockLosses; num? get totalForceMajeureLosses; num? get totalFireLosses; String? get healthCertificate; num? get samasatDischargePercentage; String? get personTypeName; String? get interactTypeName; String? get unionTypeName; String? get certId; num? get increaseQuantity; String? get tenantFullname; String? get tenantNationalCode; String? get tenantMobile; String? get tenantCity; bool? get hasTenant; String? get archiveDate; bool? get unknown; String? get createdBy; String? get modifiedBy; /// Create a copy of HatchingModel /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -28,16 +28,16 @@ $HatchingModelCopyWith get copyWith => _$HatchingModelCopyWithImp @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is HatchingModel&&(identical(other.id, id) || other.id == id)&&(identical(other.poultry, poultry) || other.poultry == poultry)&&(identical(other.chainCompany, chainCompany) || other.chainCompany == chainCompany)&&(identical(other.age, age) || other.age == age)&&const DeepCollectionEquality().equals(other.inspectionLosses, inspectionLosses)&&(identical(other.vetFarm, vetFarm) || other.vetFarm == vetFarm)&&(identical(other.activeKill, activeKill) || other.activeKill == activeKill)&&(identical(other.killingInfo, killingInfo) || other.killingInfo == killingInfo)&&(identical(other.freeGovernmentalInfo, freeGovernmentalInfo) || other.freeGovernmentalInfo == freeGovernmentalInfo)&&(identical(other.reportInfo, reportInfo) || other.reportInfo == reportInfo)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.hasChainCompany, hasChainCompany) || other.hasChainCompany == hasChainCompany)&&(identical(other.poultryIdForeignKey, poultryIdForeignKey) || other.poultryIdForeignKey == poultryIdForeignKey)&&(identical(other.poultryHatchingIdKey, poultryHatchingIdKey) || other.poultryHatchingIdKey == poultryHatchingIdKey)&&(identical(other.quantity, quantity) || other.quantity == quantity)&&(identical(other.losses, losses) || other.losses == losses)&&(identical(other.leftOver, leftOver) || other.leftOver == leftOver)&&(identical(other.killedQuantity, killedQuantity) || other.killedQuantity == killedQuantity)&&(identical(other.extraKilledQuantity, extraKilledQuantity) || other.extraKilledQuantity == extraKilledQuantity)&&(identical(other.governmentalKilledQuantity, governmentalKilledQuantity) || other.governmentalKilledQuantity == governmentalKilledQuantity)&&(identical(other.governmentalQuantity, governmentalQuantity) || other.governmentalQuantity == governmentalQuantity)&&(identical(other.freeKilledQuantity, freeKilledQuantity) || other.freeKilledQuantity == freeKilledQuantity)&&(identical(other.freeQuantity, freeQuantity) || other.freeQuantity == freeQuantity)&&(identical(other.chainKilledQuantity, chainKilledQuantity) || other.chainKilledQuantity == chainKilledQuantity)&&(identical(other.chainKilledWeight, chainKilledWeight) || other.chainKilledWeight == chainKilledWeight)&&(identical(other.outProvinceKilledWeight, outProvinceKilledWeight) || other.outProvinceKilledWeight == outProvinceKilledWeight)&&(identical(other.outProvinceKilledQuantity, outProvinceKilledQuantity) || other.outProvinceKilledQuantity == outProvinceKilledQuantity)&&(identical(other.exportKilledWeight, exportKilledWeight) || other.exportKilledWeight == exportKilledWeight)&&(identical(other.exportKilledQuantity, exportKilledQuantity) || other.exportKilledQuantity == exportKilledQuantity)&&(identical(other.totalCommitment, totalCommitment) || other.totalCommitment == totalCommitment)&&(identical(other.commitmentType, commitmentType) || other.commitmentType == commitmentType)&&(identical(other.totalCommitmentQuantity, totalCommitmentQuantity) || other.totalCommitmentQuantity == totalCommitmentQuantity)&&(identical(other.totalFreeCommitmentQuantity, totalFreeCommitmentQuantity) || other.totalFreeCommitmentQuantity == totalFreeCommitmentQuantity)&&(identical(other.totalFreeCommitmentWeight, totalFreeCommitmentWeight) || other.totalFreeCommitmentWeight == totalFreeCommitmentWeight)&&(identical(other.totalKilledWeight, totalKilledWeight) || other.totalKilledWeight == totalKilledWeight)&&(identical(other.totalAverageKilledWeight, totalAverageKilledWeight) || other.totalAverageKilledWeight == totalAverageKilledWeight)&&(identical(other.requestLeftOver, requestLeftOver) || other.requestLeftOver == requestLeftOver)&&(identical(other.hall, hall) || other.hall == hall)&&(identical(other.date, date) || other.date == date)&&(identical(other.predicateDate, predicateDate) || other.predicateDate == predicateDate)&&(identical(other.chickenBreed, chickenBreed) || other.chickenBreed == chickenBreed)&&(identical(other.period, period) || other.period == period)&&(identical(other.allowHatching, allowHatching) || other.allowHatching == allowHatching)&&(identical(other.state, state) || other.state == state)&&(identical(other.archive, archive) || other.archive == archive)&&(identical(other.violation, violation) || other.violation == violation)&&(identical(other.message, message) || other.message == message)&&(identical(other.registrar, registrar) || other.registrar == registrar)&&const DeepCollectionEquality().equals(other.breed, breed)&&(identical(other.cityNumber, cityNumber) || other.cityNumber == cityNumber)&&(identical(other.cityName, cityName) || other.cityName == cityName)&&(identical(other.provinceNumber, provinceNumber) || other.provinceNumber == provinceNumber)&&(identical(other.provinceName, provinceName) || other.provinceName == provinceName)&&(identical(other.lastChange, lastChange) || other.lastChange == lastChange)&&(identical(other.chickenAge, chickenAge) || other.chickenAge == chickenAge)&&(identical(other.nowAge, nowAge) || other.nowAge == nowAge)&&(identical(other.latestHatchingChange, latestHatchingChange) || other.latestHatchingChange == latestHatchingChange)&&(identical(other.violationReport, violationReport) || other.violationReport == violationReport)&&(identical(other.violationMessage, violationMessage) || other.violationMessage == violationMessage)&&const DeepCollectionEquality().equals(other.violationImage, violationImage)&&(identical(other.violationReporter, violationReporter) || other.violationReporter == violationReporter)&&(identical(other.violationReportDate, violationReportDate) || other.violationReportDate == violationReportDate)&&(identical(other.violationReportEditor, violationReportEditor) || other.violationReportEditor == violationReportEditor)&&(identical(other.violationReportEditDate, violationReportEditDate) || other.violationReportEditDate == violationReportEditDate)&&(identical(other.totalLosses, totalLosses) || other.totalLosses == totalLosses)&&(identical(other.directLosses, directLosses) || other.directLosses == directLosses)&&(identical(other.directLossesInputer, directLossesInputer) || other.directLossesInputer == directLossesInputer)&&(identical(other.directLossesDate, directLossesDate) || other.directLossesDate == directLossesDate)&&(identical(other.directLossesEditor, directLossesEditor) || other.directLossesEditor == directLossesEditor)&&(identical(other.directLossesLastEditDate, directLossesLastEditDate) || other.directLossesLastEditDate == directLossesLastEditDate)&&(identical(other.endPeriodLossesInputer, endPeriodLossesInputer) || other.endPeriodLossesInputer == endPeriodLossesInputer)&&(identical(other.endPeriodLossesDate, endPeriodLossesDate) || other.endPeriodLossesDate == endPeriodLossesDate)&&(identical(other.endPeriodLossesEditor, endPeriodLossesEditor) || other.endPeriodLossesEditor == endPeriodLossesEditor)&&(identical(other.endPeriodLossesLastEditDate, endPeriodLossesLastEditDate) || other.endPeriodLossesLastEditDate == endPeriodLossesLastEditDate)&&(identical(other.breedingUniqueId, breedingUniqueId) || other.breedingUniqueId == breedingUniqueId)&&(identical(other.licenceNumber, licenceNumber) || other.licenceNumber == licenceNumber)&&(identical(other.temporaryTrash, temporaryTrash) || other.temporaryTrash == temporaryTrash)&&(identical(other.temporaryDeleted, temporaryDeleted) || other.temporaryDeleted == temporaryDeleted)&&(identical(other.firstDateInputArchive, firstDateInputArchive) || other.firstDateInputArchive == firstDateInputArchive)&&(identical(other.secondDateInputArchive, secondDateInputArchive) || other.secondDateInputArchive == secondDateInputArchive)&&(identical(other.inputArchiver, inputArchiver) || other.inputArchiver == inputArchiver)&&(identical(other.outputArchiveDate, outputArchiveDate) || other.outputArchiveDate == outputArchiveDate)&&(identical(other.outputArchiver, outputArchiver) || other.outputArchiver == outputArchiver)&&(identical(other.barDifferenceRequestWeight, barDifferenceRequestWeight) || other.barDifferenceRequestWeight == barDifferenceRequestWeight)&&(identical(other.barDifferenceRequestQuantity, barDifferenceRequestQuantity) || other.barDifferenceRequestQuantity == barDifferenceRequestQuantity)&&(identical(other.healthCertificate, healthCertificate) || other.healthCertificate == healthCertificate)&&(identical(other.samasatDischargePercentage, samasatDischargePercentage) || other.samasatDischargePercentage == samasatDischargePercentage)&&(identical(other.personTypeName, personTypeName) || other.personTypeName == personTypeName)&&(identical(other.interactTypeName, interactTypeName) || other.interactTypeName == interactTypeName)&&(identical(other.unionTypeName, unionTypeName) || other.unionTypeName == unionTypeName)&&(identical(other.certId, certId) || other.certId == certId)&&(identical(other.increaseQuantity, increaseQuantity) || other.increaseQuantity == increaseQuantity)&&(identical(other.tenantFullname, tenantFullname) || other.tenantFullname == tenantFullname)&&(identical(other.tenantNationalCode, tenantNationalCode) || other.tenantNationalCode == tenantNationalCode)&&(identical(other.tenantMobile, tenantMobile) || other.tenantMobile == tenantMobile)&&(identical(other.tenantCity, tenantCity) || other.tenantCity == tenantCity)&&(identical(other.hasTenant, hasTenant) || other.hasTenant == hasTenant)&&(identical(other.archiveDate, archiveDate) || other.archiveDate == archiveDate)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is HatchingModel&&(identical(other.id, id) || other.id == id)&&(identical(other.poultry, poultry) || other.poultry == poultry)&&(identical(other.chainCompany, chainCompany) || other.chainCompany == chainCompany)&&(identical(other.age, age) || other.age == age)&&const DeepCollectionEquality().equals(other.inspectionLosses, inspectionLosses)&&(identical(other.vetFarm, vetFarm) || other.vetFarm == vetFarm)&&(identical(other.activeKill, activeKill) || other.activeKill == activeKill)&&(identical(other.killingInfo, killingInfo) || other.killingInfo == killingInfo)&&(identical(other.freeGovernmentalInfo, freeGovernmentalInfo) || other.freeGovernmentalInfo == freeGovernmentalInfo)&&(identical(other.reportInfo, reportInfo) || other.reportInfo == reportInfo)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.hasChainCompany, hasChainCompany) || other.hasChainCompany == hasChainCompany)&&(identical(other.poultryIdForeignKey, poultryIdForeignKey) || other.poultryIdForeignKey == poultryIdForeignKey)&&(identical(other.poultryHatchingIdKey, poultryHatchingIdKey) || other.poultryHatchingIdKey == poultryHatchingIdKey)&&(identical(other.quantity, quantity) || other.quantity == quantity)&&(identical(other.losses, losses) || other.losses == losses)&&(identical(other.leftOver, leftOver) || other.leftOver == leftOver)&&(identical(other.killedQuantity, killedQuantity) || other.killedQuantity == killedQuantity)&&(identical(other.extraKilledQuantity, extraKilledQuantity) || other.extraKilledQuantity == extraKilledQuantity)&&(identical(other.governmentalKilledQuantity, governmentalKilledQuantity) || other.governmentalKilledQuantity == governmentalKilledQuantity)&&(identical(other.governmentalQuantity, governmentalQuantity) || other.governmentalQuantity == governmentalQuantity)&&(identical(other.freeKilledQuantity, freeKilledQuantity) || other.freeKilledQuantity == freeKilledQuantity)&&(identical(other.freeQuantity, freeQuantity) || other.freeQuantity == freeQuantity)&&(identical(other.chainKilledQuantity, chainKilledQuantity) || other.chainKilledQuantity == chainKilledQuantity)&&(identical(other.chainKilledWeight, chainKilledWeight) || other.chainKilledWeight == chainKilledWeight)&&(identical(other.outProvinceKilledWeight, outProvinceKilledWeight) || other.outProvinceKilledWeight == outProvinceKilledWeight)&&(identical(other.outProvinceKilledQuantity, outProvinceKilledQuantity) || other.outProvinceKilledQuantity == outProvinceKilledQuantity)&&(identical(other.exportKilledWeight, exportKilledWeight) || other.exportKilledWeight == exportKilledWeight)&&(identical(other.exportKilledQuantity, exportKilledQuantity) || other.exportKilledQuantity == exportKilledQuantity)&&(identical(other.totalCommitment, totalCommitment) || other.totalCommitment == totalCommitment)&&(identical(other.commitmentType, commitmentType) || other.commitmentType == commitmentType)&&(identical(other.totalCommitmentQuantity, totalCommitmentQuantity) || other.totalCommitmentQuantity == totalCommitmentQuantity)&&(identical(other.totalFreeCommitmentQuantity, totalFreeCommitmentQuantity) || other.totalFreeCommitmentQuantity == totalFreeCommitmentQuantity)&&(identical(other.totalFreeCommitmentWeight, totalFreeCommitmentWeight) || other.totalFreeCommitmentWeight == totalFreeCommitmentWeight)&&(identical(other.totalKilledWeight, totalKilledWeight) || other.totalKilledWeight == totalKilledWeight)&&(identical(other.totalAverageKilledWeight, totalAverageKilledWeight) || other.totalAverageKilledWeight == totalAverageKilledWeight)&&(identical(other.requestLeftOver, requestLeftOver) || other.requestLeftOver == requestLeftOver)&&(identical(other.hall, hall) || other.hall == hall)&&(identical(other.date, date) || other.date == date)&&(identical(other.predicateDate, predicateDate) || other.predicateDate == predicateDate)&&(identical(other.chickenBreed, chickenBreed) || other.chickenBreed == chickenBreed)&&(identical(other.period, period) || other.period == period)&&(identical(other.allowHatching, allowHatching) || other.allowHatching == allowHatching)&&(identical(other.state, state) || other.state == state)&&(identical(other.archive, archive) || other.archive == archive)&&(identical(other.violation, violation) || other.violation == violation)&&(identical(other.message, message) || other.message == message)&&(identical(other.registrar, registrar) || other.registrar == registrar)&&const DeepCollectionEquality().equals(other.breed, breed)&&(identical(other.cityNumber, cityNumber) || other.cityNumber == cityNumber)&&(identical(other.cityName, cityName) || other.cityName == cityName)&&(identical(other.provinceNumber, provinceNumber) || other.provinceNumber == provinceNumber)&&(identical(other.provinceName, provinceName) || other.provinceName == provinceName)&&(identical(other.lastChange, lastChange) || other.lastChange == lastChange)&&(identical(other.chickenAge, chickenAge) || other.chickenAge == chickenAge)&&(identical(other.nowAge, nowAge) || other.nowAge == nowAge)&&(identical(other.latestHatchingChange, latestHatchingChange) || other.latestHatchingChange == latestHatchingChange)&&(identical(other.violationReport, violationReport) || other.violationReport == violationReport)&&(identical(other.violationMessage, violationMessage) || other.violationMessage == violationMessage)&&const DeepCollectionEquality().equals(other.violationImage, violationImage)&&(identical(other.violationReporter, violationReporter) || other.violationReporter == violationReporter)&&(identical(other.violationReportDate, violationReportDate) || other.violationReportDate == violationReportDate)&&(identical(other.violationReportEditor, violationReportEditor) || other.violationReportEditor == violationReportEditor)&&(identical(other.violationReportEditDate, violationReportEditDate) || other.violationReportEditDate == violationReportEditDate)&&(identical(other.totalLosses, totalLosses) || other.totalLosses == totalLosses)&&(identical(other.directLosses, directLosses) || other.directLosses == directLosses)&&(identical(other.directLossesInputer, directLossesInputer) || other.directLossesInputer == directLossesInputer)&&(identical(other.directLossesDate, directLossesDate) || other.directLossesDate == directLossesDate)&&(identical(other.directLossesEditor, directLossesEditor) || other.directLossesEditor == directLossesEditor)&&(identical(other.directLossesLastEditDate, directLossesLastEditDate) || other.directLossesLastEditDate == directLossesLastEditDate)&&(identical(other.endPeriodLossesInputer, endPeriodLossesInputer) || other.endPeriodLossesInputer == endPeriodLossesInputer)&&(identical(other.endPeriodLossesDate, endPeriodLossesDate) || other.endPeriodLossesDate == endPeriodLossesDate)&&(identical(other.endPeriodLossesEditor, endPeriodLossesEditor) || other.endPeriodLossesEditor == endPeriodLossesEditor)&&(identical(other.endPeriodLossesLastEditDate, endPeriodLossesLastEditDate) || other.endPeriodLossesLastEditDate == endPeriodLossesLastEditDate)&&(identical(other.breedingUniqueId, breedingUniqueId) || other.breedingUniqueId == breedingUniqueId)&&(identical(other.licenceNumber, licenceNumber) || other.licenceNumber == licenceNumber)&&(identical(other.temporaryTrash, temporaryTrash) || other.temporaryTrash == temporaryTrash)&&(identical(other.temporaryDeleted, temporaryDeleted) || other.temporaryDeleted == temporaryDeleted)&&(identical(other.firstDateInputArchive, firstDateInputArchive) || other.firstDateInputArchive == firstDateInputArchive)&&(identical(other.secondDateInputArchive, secondDateInputArchive) || other.secondDateInputArchive == secondDateInputArchive)&&(identical(other.inputArchiver, inputArchiver) || other.inputArchiver == inputArchiver)&&(identical(other.outputArchiveDate, outputArchiveDate) || other.outputArchiveDate == outputArchiveDate)&&(identical(other.outputArchiver, outputArchiver) || other.outputArchiver == outputArchiver)&&(identical(other.barDifferenceRequestWeight, barDifferenceRequestWeight) || other.barDifferenceRequestWeight == barDifferenceRequestWeight)&&(identical(other.barDifferenceRequestQuantity, barDifferenceRequestQuantity) || other.barDifferenceRequestQuantity == barDifferenceRequestQuantity)&&(identical(other.totalDiseaseLosses, totalDiseaseLosses) || other.totalDiseaseLosses == totalDiseaseLosses)&&(identical(other.totalFlockDestruction, totalFlockDestruction) || other.totalFlockDestruction == totalFlockDestruction)&&(identical(other.totalNormalFlockLosses, totalNormalFlockLosses) || other.totalNormalFlockLosses == totalNormalFlockLosses)&&(identical(other.totalForceMajeureLosses, totalForceMajeureLosses) || other.totalForceMajeureLosses == totalForceMajeureLosses)&&(identical(other.totalFireLosses, totalFireLosses) || other.totalFireLosses == totalFireLosses)&&(identical(other.healthCertificate, healthCertificate) || other.healthCertificate == healthCertificate)&&(identical(other.samasatDischargePercentage, samasatDischargePercentage) || other.samasatDischargePercentage == samasatDischargePercentage)&&(identical(other.personTypeName, personTypeName) || other.personTypeName == personTypeName)&&(identical(other.interactTypeName, interactTypeName) || other.interactTypeName == interactTypeName)&&(identical(other.unionTypeName, unionTypeName) || other.unionTypeName == unionTypeName)&&(identical(other.certId, certId) || other.certId == certId)&&(identical(other.increaseQuantity, increaseQuantity) || other.increaseQuantity == increaseQuantity)&&(identical(other.tenantFullname, tenantFullname) || other.tenantFullname == tenantFullname)&&(identical(other.tenantNationalCode, tenantNationalCode) || other.tenantNationalCode == tenantNationalCode)&&(identical(other.tenantMobile, tenantMobile) || other.tenantMobile == tenantMobile)&&(identical(other.tenantCity, tenantCity) || other.tenantCity == tenantCity)&&(identical(other.hasTenant, hasTenant) || other.hasTenant == hasTenant)&&(identical(other.archiveDate, archiveDate) || other.archiveDate == archiveDate)&&(identical(other.unknown, unknown) || other.unknown == unknown)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hashAll([runtimeType,id,poultry,chainCompany,age,const DeepCollectionEquality().hash(inspectionLosses),vetFarm,activeKill,killingInfo,freeGovernmentalInfo,reportInfo,key,createDate,modifyDate,trash,hasChainCompany,poultryIdForeignKey,poultryHatchingIdKey,quantity,losses,leftOver,killedQuantity,extraKilledQuantity,governmentalKilledQuantity,governmentalQuantity,freeKilledQuantity,freeQuantity,chainKilledQuantity,chainKilledWeight,outProvinceKilledWeight,outProvinceKilledQuantity,exportKilledWeight,exportKilledQuantity,totalCommitment,commitmentType,totalCommitmentQuantity,totalFreeCommitmentQuantity,totalFreeCommitmentWeight,totalKilledWeight,totalAverageKilledWeight,requestLeftOver,hall,date,predicateDate,chickenBreed,period,allowHatching,state,archive,violation,message,registrar,const DeepCollectionEquality().hash(breed),cityNumber,cityName,provinceNumber,provinceName,lastChange,chickenAge,nowAge,latestHatchingChange,violationReport,violationMessage,const DeepCollectionEquality().hash(violationImage),violationReporter,violationReportDate,violationReportEditor,violationReportEditDate,totalLosses,directLosses,directLossesInputer,directLossesDate,directLossesEditor,directLossesLastEditDate,endPeriodLossesInputer,endPeriodLossesDate,endPeriodLossesEditor,endPeriodLossesLastEditDate,breedingUniqueId,licenceNumber,temporaryTrash,temporaryDeleted,firstDateInputArchive,secondDateInputArchive,inputArchiver,outputArchiveDate,outputArchiver,barDifferenceRequestWeight,barDifferenceRequestQuantity,healthCertificate,samasatDischargePercentage,personTypeName,interactTypeName,unionTypeName,certId,increaseQuantity,tenantFullname,tenantNationalCode,tenantMobile,tenantCity,hasTenant,archiveDate,createdBy,modifiedBy]); +int get hashCode => Object.hashAll([runtimeType,id,poultry,chainCompany,age,const DeepCollectionEquality().hash(inspectionLosses),vetFarm,activeKill,killingInfo,freeGovernmentalInfo,reportInfo,key,createDate,modifyDate,trash,hasChainCompany,poultryIdForeignKey,poultryHatchingIdKey,quantity,losses,leftOver,killedQuantity,extraKilledQuantity,governmentalKilledQuantity,governmentalQuantity,freeKilledQuantity,freeQuantity,chainKilledQuantity,chainKilledWeight,outProvinceKilledWeight,outProvinceKilledQuantity,exportKilledWeight,exportKilledQuantity,totalCommitment,commitmentType,totalCommitmentQuantity,totalFreeCommitmentQuantity,totalFreeCommitmentWeight,totalKilledWeight,totalAverageKilledWeight,requestLeftOver,hall,date,predicateDate,chickenBreed,period,allowHatching,state,archive,violation,message,registrar,const DeepCollectionEquality().hash(breed),cityNumber,cityName,provinceNumber,provinceName,lastChange,chickenAge,nowAge,latestHatchingChange,violationReport,violationMessage,const DeepCollectionEquality().hash(violationImage),violationReporter,violationReportDate,violationReportEditor,violationReportEditDate,totalLosses,directLosses,directLossesInputer,directLossesDate,directLossesEditor,directLossesLastEditDate,endPeriodLossesInputer,endPeriodLossesDate,endPeriodLossesEditor,endPeriodLossesLastEditDate,breedingUniqueId,licenceNumber,temporaryTrash,temporaryDeleted,firstDateInputArchive,secondDateInputArchive,inputArchiver,outputArchiveDate,outputArchiver,barDifferenceRequestWeight,barDifferenceRequestQuantity,totalDiseaseLosses,totalFlockDestruction,totalNormalFlockLosses,totalForceMajeureLosses,totalFireLosses,healthCertificate,samasatDischargePercentage,personTypeName,interactTypeName,unionTypeName,certId,increaseQuantity,tenantFullname,tenantNationalCode,tenantMobile,tenantCity,hasTenant,archiveDate,unknown,createdBy,modifiedBy]); @override String toString() { - return 'HatchingModel(id: $id, poultry: $poultry, chainCompany: $chainCompany, age: $age, inspectionLosses: $inspectionLosses, vetFarm: $vetFarm, activeKill: $activeKill, killingInfo: $killingInfo, freeGovernmentalInfo: $freeGovernmentalInfo, reportInfo: $reportInfo, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, hasChainCompany: $hasChainCompany, poultryIdForeignKey: $poultryIdForeignKey, poultryHatchingIdKey: $poultryHatchingIdKey, quantity: $quantity, losses: $losses, leftOver: $leftOver, killedQuantity: $killedQuantity, extraKilledQuantity: $extraKilledQuantity, governmentalKilledQuantity: $governmentalKilledQuantity, governmentalQuantity: $governmentalQuantity, freeKilledQuantity: $freeKilledQuantity, freeQuantity: $freeQuantity, chainKilledQuantity: $chainKilledQuantity, chainKilledWeight: $chainKilledWeight, outProvinceKilledWeight: $outProvinceKilledWeight, outProvinceKilledQuantity: $outProvinceKilledQuantity, exportKilledWeight: $exportKilledWeight, exportKilledQuantity: $exportKilledQuantity, totalCommitment: $totalCommitment, commitmentType: $commitmentType, totalCommitmentQuantity: $totalCommitmentQuantity, totalFreeCommitmentQuantity: $totalFreeCommitmentQuantity, totalFreeCommitmentWeight: $totalFreeCommitmentWeight, totalKilledWeight: $totalKilledWeight, totalAverageKilledWeight: $totalAverageKilledWeight, requestLeftOver: $requestLeftOver, hall: $hall, date: $date, predicateDate: $predicateDate, chickenBreed: $chickenBreed, period: $period, allowHatching: $allowHatching, state: $state, archive: $archive, violation: $violation, message: $message, registrar: $registrar, breed: $breed, cityNumber: $cityNumber, cityName: $cityName, provinceNumber: $provinceNumber, provinceName: $provinceName, lastChange: $lastChange, chickenAge: $chickenAge, nowAge: $nowAge, latestHatchingChange: $latestHatchingChange, violationReport: $violationReport, violationMessage: $violationMessage, violationImage: $violationImage, violationReporter: $violationReporter, violationReportDate: $violationReportDate, violationReportEditor: $violationReportEditor, violationReportEditDate: $violationReportEditDate, totalLosses: $totalLosses, directLosses: $directLosses, directLossesInputer: $directLossesInputer, directLossesDate: $directLossesDate, directLossesEditor: $directLossesEditor, directLossesLastEditDate: $directLossesLastEditDate, endPeriodLossesInputer: $endPeriodLossesInputer, endPeriodLossesDate: $endPeriodLossesDate, endPeriodLossesEditor: $endPeriodLossesEditor, endPeriodLossesLastEditDate: $endPeriodLossesLastEditDate, breedingUniqueId: $breedingUniqueId, licenceNumber: $licenceNumber, temporaryTrash: $temporaryTrash, temporaryDeleted: $temporaryDeleted, firstDateInputArchive: $firstDateInputArchive, secondDateInputArchive: $secondDateInputArchive, inputArchiver: $inputArchiver, outputArchiveDate: $outputArchiveDate, outputArchiver: $outputArchiver, barDifferenceRequestWeight: $barDifferenceRequestWeight, barDifferenceRequestQuantity: $barDifferenceRequestQuantity, healthCertificate: $healthCertificate, samasatDischargePercentage: $samasatDischargePercentage, personTypeName: $personTypeName, interactTypeName: $interactTypeName, unionTypeName: $unionTypeName, certId: $certId, increaseQuantity: $increaseQuantity, tenantFullname: $tenantFullname, tenantNationalCode: $tenantNationalCode, tenantMobile: $tenantMobile, tenantCity: $tenantCity, hasTenant: $hasTenant, archiveDate: $archiveDate, createdBy: $createdBy, modifiedBy: $modifiedBy)'; + return 'HatchingModel(id: $id, poultry: $poultry, chainCompany: $chainCompany, age: $age, inspectionLosses: $inspectionLosses, vetFarm: $vetFarm, activeKill: $activeKill, killingInfo: $killingInfo, freeGovernmentalInfo: $freeGovernmentalInfo, reportInfo: $reportInfo, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, hasChainCompany: $hasChainCompany, poultryIdForeignKey: $poultryIdForeignKey, poultryHatchingIdKey: $poultryHatchingIdKey, quantity: $quantity, losses: $losses, leftOver: $leftOver, killedQuantity: $killedQuantity, extraKilledQuantity: $extraKilledQuantity, governmentalKilledQuantity: $governmentalKilledQuantity, governmentalQuantity: $governmentalQuantity, freeKilledQuantity: $freeKilledQuantity, freeQuantity: $freeQuantity, chainKilledQuantity: $chainKilledQuantity, chainKilledWeight: $chainKilledWeight, outProvinceKilledWeight: $outProvinceKilledWeight, outProvinceKilledQuantity: $outProvinceKilledQuantity, exportKilledWeight: $exportKilledWeight, exportKilledQuantity: $exportKilledQuantity, totalCommitment: $totalCommitment, commitmentType: $commitmentType, totalCommitmentQuantity: $totalCommitmentQuantity, totalFreeCommitmentQuantity: $totalFreeCommitmentQuantity, totalFreeCommitmentWeight: $totalFreeCommitmentWeight, totalKilledWeight: $totalKilledWeight, totalAverageKilledWeight: $totalAverageKilledWeight, requestLeftOver: $requestLeftOver, hall: $hall, date: $date, predicateDate: $predicateDate, chickenBreed: $chickenBreed, period: $period, allowHatching: $allowHatching, state: $state, archive: $archive, violation: $violation, message: $message, registrar: $registrar, breed: $breed, cityNumber: $cityNumber, cityName: $cityName, provinceNumber: $provinceNumber, provinceName: $provinceName, lastChange: $lastChange, chickenAge: $chickenAge, nowAge: $nowAge, latestHatchingChange: $latestHatchingChange, violationReport: $violationReport, violationMessage: $violationMessage, violationImage: $violationImage, violationReporter: $violationReporter, violationReportDate: $violationReportDate, violationReportEditor: $violationReportEditor, violationReportEditDate: $violationReportEditDate, totalLosses: $totalLosses, directLosses: $directLosses, directLossesInputer: $directLossesInputer, directLossesDate: $directLossesDate, directLossesEditor: $directLossesEditor, directLossesLastEditDate: $directLossesLastEditDate, endPeriodLossesInputer: $endPeriodLossesInputer, endPeriodLossesDate: $endPeriodLossesDate, endPeriodLossesEditor: $endPeriodLossesEditor, endPeriodLossesLastEditDate: $endPeriodLossesLastEditDate, breedingUniqueId: $breedingUniqueId, licenceNumber: $licenceNumber, temporaryTrash: $temporaryTrash, temporaryDeleted: $temporaryDeleted, firstDateInputArchive: $firstDateInputArchive, secondDateInputArchive: $secondDateInputArchive, inputArchiver: $inputArchiver, outputArchiveDate: $outputArchiveDate, outputArchiver: $outputArchiver, barDifferenceRequestWeight: $barDifferenceRequestWeight, barDifferenceRequestQuantity: $barDifferenceRequestQuantity, totalDiseaseLosses: $totalDiseaseLosses, totalFlockDestruction: $totalFlockDestruction, totalNormalFlockLosses: $totalNormalFlockLosses, totalForceMajeureLosses: $totalForceMajeureLosses, totalFireLosses: $totalFireLosses, healthCertificate: $healthCertificate, samasatDischargePercentage: $samasatDischargePercentage, personTypeName: $personTypeName, interactTypeName: $interactTypeName, unionTypeName: $unionTypeName, certId: $certId, increaseQuantity: $increaseQuantity, tenantFullname: $tenantFullname, tenantNationalCode: $tenantNationalCode, tenantMobile: $tenantMobile, tenantCity: $tenantCity, hasTenant: $hasTenant, archiveDate: $archiveDate, unknown: $unknown, createdBy: $createdBy, modifiedBy: $modifiedBy)'; } @@ -48,7 +48,7 @@ abstract mixin class $HatchingModelCopyWith<$Res> { factory $HatchingModelCopyWith(HatchingModel value, $Res Function(HatchingModel) _then) = _$HatchingModelCopyWithImpl; @useResult $Res call({ - int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, String? createdBy, String? modifiedBy + int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, num? totalDiseaseLosses, num? totalFlockDestruction, num? totalNormalFlockLosses, num? totalForceMajeureLosses, num? totalFireLosses, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, bool? unknown, String? createdBy, String? modifiedBy }); @@ -65,7 +65,7 @@ class _$HatchingModelCopyWithImpl<$Res> /// Create a copy of HatchingModel /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? poultry = freezed,Object? chainCompany = freezed,Object? age = freezed,Object? inspectionLosses = freezed,Object? vetFarm = freezed,Object? activeKill = freezed,Object? killingInfo = freezed,Object? freeGovernmentalInfo = freezed,Object? reportInfo = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? hasChainCompany = freezed,Object? poultryIdForeignKey = freezed,Object? poultryHatchingIdKey = freezed,Object? quantity = freezed,Object? losses = freezed,Object? leftOver = freezed,Object? killedQuantity = freezed,Object? extraKilledQuantity = freezed,Object? governmentalKilledQuantity = freezed,Object? governmentalQuantity = freezed,Object? freeKilledQuantity = freezed,Object? freeQuantity = freezed,Object? chainKilledQuantity = freezed,Object? chainKilledWeight = freezed,Object? outProvinceKilledWeight = freezed,Object? outProvinceKilledQuantity = freezed,Object? exportKilledWeight = freezed,Object? exportKilledQuantity = freezed,Object? totalCommitment = freezed,Object? commitmentType = freezed,Object? totalCommitmentQuantity = freezed,Object? totalFreeCommitmentQuantity = freezed,Object? totalFreeCommitmentWeight = freezed,Object? totalKilledWeight = freezed,Object? totalAverageKilledWeight = freezed,Object? requestLeftOver = freezed,Object? hall = freezed,Object? date = freezed,Object? predicateDate = freezed,Object? chickenBreed = freezed,Object? period = freezed,Object? allowHatching = freezed,Object? state = freezed,Object? archive = freezed,Object? violation = freezed,Object? message = freezed,Object? registrar = freezed,Object? breed = freezed,Object? cityNumber = freezed,Object? cityName = freezed,Object? provinceNumber = freezed,Object? provinceName = freezed,Object? lastChange = freezed,Object? chickenAge = freezed,Object? nowAge = freezed,Object? latestHatchingChange = freezed,Object? violationReport = freezed,Object? violationMessage = freezed,Object? violationImage = freezed,Object? violationReporter = freezed,Object? violationReportDate = freezed,Object? violationReportEditor = freezed,Object? violationReportEditDate = freezed,Object? totalLosses = freezed,Object? directLosses = freezed,Object? directLossesInputer = freezed,Object? directLossesDate = freezed,Object? directLossesEditor = freezed,Object? directLossesLastEditDate = freezed,Object? endPeriodLossesInputer = freezed,Object? endPeriodLossesDate = freezed,Object? endPeriodLossesEditor = freezed,Object? endPeriodLossesLastEditDate = freezed,Object? breedingUniqueId = freezed,Object? licenceNumber = freezed,Object? temporaryTrash = freezed,Object? temporaryDeleted = freezed,Object? firstDateInputArchive = freezed,Object? secondDateInputArchive = freezed,Object? inputArchiver = freezed,Object? outputArchiveDate = freezed,Object? outputArchiver = freezed,Object? barDifferenceRequestWeight = freezed,Object? barDifferenceRequestQuantity = freezed,Object? healthCertificate = freezed,Object? samasatDischargePercentage = freezed,Object? personTypeName = freezed,Object? interactTypeName = freezed,Object? unionTypeName = freezed,Object? certId = freezed,Object? increaseQuantity = freezed,Object? tenantFullname = freezed,Object? tenantNationalCode = freezed,Object? tenantMobile = freezed,Object? tenantCity = freezed,Object? hasTenant = freezed,Object? archiveDate = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? poultry = freezed,Object? chainCompany = freezed,Object? age = freezed,Object? inspectionLosses = freezed,Object? vetFarm = freezed,Object? activeKill = freezed,Object? killingInfo = freezed,Object? freeGovernmentalInfo = freezed,Object? reportInfo = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? hasChainCompany = freezed,Object? poultryIdForeignKey = freezed,Object? poultryHatchingIdKey = freezed,Object? quantity = freezed,Object? losses = freezed,Object? leftOver = freezed,Object? killedQuantity = freezed,Object? extraKilledQuantity = freezed,Object? governmentalKilledQuantity = freezed,Object? governmentalQuantity = freezed,Object? freeKilledQuantity = freezed,Object? freeQuantity = freezed,Object? chainKilledQuantity = freezed,Object? chainKilledWeight = freezed,Object? outProvinceKilledWeight = freezed,Object? outProvinceKilledQuantity = freezed,Object? exportKilledWeight = freezed,Object? exportKilledQuantity = freezed,Object? totalCommitment = freezed,Object? commitmentType = freezed,Object? totalCommitmentQuantity = freezed,Object? totalFreeCommitmentQuantity = freezed,Object? totalFreeCommitmentWeight = freezed,Object? totalKilledWeight = freezed,Object? totalAverageKilledWeight = freezed,Object? requestLeftOver = freezed,Object? hall = freezed,Object? date = freezed,Object? predicateDate = freezed,Object? chickenBreed = freezed,Object? period = freezed,Object? allowHatching = freezed,Object? state = freezed,Object? archive = freezed,Object? violation = freezed,Object? message = freezed,Object? registrar = freezed,Object? breed = freezed,Object? cityNumber = freezed,Object? cityName = freezed,Object? provinceNumber = freezed,Object? provinceName = freezed,Object? lastChange = freezed,Object? chickenAge = freezed,Object? nowAge = freezed,Object? latestHatchingChange = freezed,Object? violationReport = freezed,Object? violationMessage = freezed,Object? violationImage = freezed,Object? violationReporter = freezed,Object? violationReportDate = freezed,Object? violationReportEditor = freezed,Object? violationReportEditDate = freezed,Object? totalLosses = freezed,Object? directLosses = freezed,Object? directLossesInputer = freezed,Object? directLossesDate = freezed,Object? directLossesEditor = freezed,Object? directLossesLastEditDate = freezed,Object? endPeriodLossesInputer = freezed,Object? endPeriodLossesDate = freezed,Object? endPeriodLossesEditor = freezed,Object? endPeriodLossesLastEditDate = freezed,Object? breedingUniqueId = freezed,Object? licenceNumber = freezed,Object? temporaryTrash = freezed,Object? temporaryDeleted = freezed,Object? firstDateInputArchive = freezed,Object? secondDateInputArchive = freezed,Object? inputArchiver = freezed,Object? outputArchiveDate = freezed,Object? outputArchiver = freezed,Object? barDifferenceRequestWeight = freezed,Object? barDifferenceRequestQuantity = freezed,Object? totalDiseaseLosses = freezed,Object? totalFlockDestruction = freezed,Object? totalNormalFlockLosses = freezed,Object? totalForceMajeureLosses = freezed,Object? totalFireLosses = freezed,Object? healthCertificate = freezed,Object? samasatDischargePercentage = freezed,Object? personTypeName = freezed,Object? interactTypeName = freezed,Object? unionTypeName = freezed,Object? certId = freezed,Object? increaseQuantity = freezed,Object? tenantFullname = freezed,Object? tenantNationalCode = freezed,Object? tenantMobile = freezed,Object? tenantCity = freezed,Object? hasTenant = freezed,Object? archiveDate = freezed,Object? unknown = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,}) { return _then(_self.copyWith( id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable as int?,poultry: freezed == poultry ? _self.poultry : poultry // ignore: cast_nullable_to_non_nullable @@ -155,6 +155,11 @@ as String?,outputArchiveDate: freezed == outputArchiveDate ? _self.outputArchive as String?,outputArchiver: freezed == outputArchiver ? _self.outputArchiver : outputArchiver // ignore: cast_nullable_to_non_nullable as String?,barDifferenceRequestWeight: freezed == barDifferenceRequestWeight ? _self.barDifferenceRequestWeight : barDifferenceRequestWeight // ignore: cast_nullable_to_non_nullable as num?,barDifferenceRequestQuantity: freezed == barDifferenceRequestQuantity ? _self.barDifferenceRequestQuantity : barDifferenceRequestQuantity // ignore: cast_nullable_to_non_nullable +as num?,totalDiseaseLosses: freezed == totalDiseaseLosses ? _self.totalDiseaseLosses : totalDiseaseLosses // ignore: cast_nullable_to_non_nullable +as num?,totalFlockDestruction: freezed == totalFlockDestruction ? _self.totalFlockDestruction : totalFlockDestruction // ignore: cast_nullable_to_non_nullable +as num?,totalNormalFlockLosses: freezed == totalNormalFlockLosses ? _self.totalNormalFlockLosses : totalNormalFlockLosses // ignore: cast_nullable_to_non_nullable +as num?,totalForceMajeureLosses: freezed == totalForceMajeureLosses ? _self.totalForceMajeureLosses : totalForceMajeureLosses // ignore: cast_nullable_to_non_nullable +as num?,totalFireLosses: freezed == totalFireLosses ? _self.totalFireLosses : totalFireLosses // ignore: cast_nullable_to_non_nullable as num?,healthCertificate: freezed == healthCertificate ? _self.healthCertificate : healthCertificate // ignore: cast_nullable_to_non_nullable as String?,samasatDischargePercentage: freezed == samasatDischargePercentage ? _self.samasatDischargePercentage : samasatDischargePercentage // ignore: cast_nullable_to_non_nullable as num?,personTypeName: freezed == personTypeName ? _self.personTypeName : personTypeName // ignore: cast_nullable_to_non_nullable @@ -168,7 +173,8 @@ as String?,tenantMobile: freezed == tenantMobile ? _self.tenantMobile : tenantMo as String?,tenantCity: freezed == tenantCity ? _self.tenantCity : tenantCity // ignore: cast_nullable_to_non_nullable as String?,hasTenant: freezed == hasTenant ? _self.hasTenant : hasTenant // ignore: cast_nullable_to_non_nullable as bool?,archiveDate: freezed == archiveDate ? _self.archiveDate : archiveDate // ignore: cast_nullable_to_non_nullable -as String?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable +as String?,unknown: freezed == unknown ? _self.unknown : unknown // ignore: cast_nullable_to_non_nullable +as bool?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable as String?,modifiedBy: freezed == modifiedBy ? _self.modifiedBy : modifiedBy // ignore: cast_nullable_to_non_nullable as String?, )); @@ -375,10 +381,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, String? createdBy, String? modifiedBy)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, num? totalDiseaseLosses, num? totalFlockDestruction, num? totalNormalFlockLosses, num? totalForceMajeureLosses, num? totalFireLosses, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, bool? unknown, String? createdBy, String? modifiedBy)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _HatchingModel() when $default != null: -return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspectionLosses,_that.vetFarm,_that.activeKill,_that.killingInfo,_that.freeGovernmentalInfo,_that.reportInfo,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.hasChainCompany,_that.poultryIdForeignKey,_that.poultryHatchingIdKey,_that.quantity,_that.losses,_that.leftOver,_that.killedQuantity,_that.extraKilledQuantity,_that.governmentalKilledQuantity,_that.governmentalQuantity,_that.freeKilledQuantity,_that.freeQuantity,_that.chainKilledQuantity,_that.chainKilledWeight,_that.outProvinceKilledWeight,_that.outProvinceKilledQuantity,_that.exportKilledWeight,_that.exportKilledQuantity,_that.totalCommitment,_that.commitmentType,_that.totalCommitmentQuantity,_that.totalFreeCommitmentQuantity,_that.totalFreeCommitmentWeight,_that.totalKilledWeight,_that.totalAverageKilledWeight,_that.requestLeftOver,_that.hall,_that.date,_that.predicateDate,_that.chickenBreed,_that.period,_that.allowHatching,_that.state,_that.archive,_that.violation,_that.message,_that.registrar,_that.breed,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.lastChange,_that.chickenAge,_that.nowAge,_that.latestHatchingChange,_that.violationReport,_that.violationMessage,_that.violationImage,_that.violationReporter,_that.violationReportDate,_that.violationReportEditor,_that.violationReportEditDate,_that.totalLosses,_that.directLosses,_that.directLossesInputer,_that.directLossesDate,_that.directLossesEditor,_that.directLossesLastEditDate,_that.endPeriodLossesInputer,_that.endPeriodLossesDate,_that.endPeriodLossesEditor,_that.endPeriodLossesLastEditDate,_that.breedingUniqueId,_that.licenceNumber,_that.temporaryTrash,_that.temporaryDeleted,_that.firstDateInputArchive,_that.secondDateInputArchive,_that.inputArchiver,_that.outputArchiveDate,_that.outputArchiver,_that.barDifferenceRequestWeight,_that.barDifferenceRequestQuantity,_that.healthCertificate,_that.samasatDischargePercentage,_that.personTypeName,_that.interactTypeName,_that.unionTypeName,_that.certId,_that.increaseQuantity,_that.tenantFullname,_that.tenantNationalCode,_that.tenantMobile,_that.tenantCity,_that.hasTenant,_that.archiveDate,_that.createdBy,_that.modifiedBy);case _: +return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspectionLosses,_that.vetFarm,_that.activeKill,_that.killingInfo,_that.freeGovernmentalInfo,_that.reportInfo,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.hasChainCompany,_that.poultryIdForeignKey,_that.poultryHatchingIdKey,_that.quantity,_that.losses,_that.leftOver,_that.killedQuantity,_that.extraKilledQuantity,_that.governmentalKilledQuantity,_that.governmentalQuantity,_that.freeKilledQuantity,_that.freeQuantity,_that.chainKilledQuantity,_that.chainKilledWeight,_that.outProvinceKilledWeight,_that.outProvinceKilledQuantity,_that.exportKilledWeight,_that.exportKilledQuantity,_that.totalCommitment,_that.commitmentType,_that.totalCommitmentQuantity,_that.totalFreeCommitmentQuantity,_that.totalFreeCommitmentWeight,_that.totalKilledWeight,_that.totalAverageKilledWeight,_that.requestLeftOver,_that.hall,_that.date,_that.predicateDate,_that.chickenBreed,_that.period,_that.allowHatching,_that.state,_that.archive,_that.violation,_that.message,_that.registrar,_that.breed,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.lastChange,_that.chickenAge,_that.nowAge,_that.latestHatchingChange,_that.violationReport,_that.violationMessage,_that.violationImage,_that.violationReporter,_that.violationReportDate,_that.violationReportEditor,_that.violationReportEditDate,_that.totalLosses,_that.directLosses,_that.directLossesInputer,_that.directLossesDate,_that.directLossesEditor,_that.directLossesLastEditDate,_that.endPeriodLossesInputer,_that.endPeriodLossesDate,_that.endPeriodLossesEditor,_that.endPeriodLossesLastEditDate,_that.breedingUniqueId,_that.licenceNumber,_that.temporaryTrash,_that.temporaryDeleted,_that.firstDateInputArchive,_that.secondDateInputArchive,_that.inputArchiver,_that.outputArchiveDate,_that.outputArchiver,_that.barDifferenceRequestWeight,_that.barDifferenceRequestQuantity,_that.totalDiseaseLosses,_that.totalFlockDestruction,_that.totalNormalFlockLosses,_that.totalForceMajeureLosses,_that.totalFireLosses,_that.healthCertificate,_that.samasatDischargePercentage,_that.personTypeName,_that.interactTypeName,_that.unionTypeName,_that.certId,_that.increaseQuantity,_that.tenantFullname,_that.tenantNationalCode,_that.tenantMobile,_that.tenantCity,_that.hasTenant,_that.archiveDate,_that.unknown,_that.createdBy,_that.modifiedBy);case _: return orElse(); } @@ -396,10 +402,10 @@ return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspec /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, String? createdBy, String? modifiedBy) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, num? totalDiseaseLosses, num? totalFlockDestruction, num? totalNormalFlockLosses, num? totalForceMajeureLosses, num? totalFireLosses, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, bool? unknown, String? createdBy, String? modifiedBy) $default,) {final _that = this; switch (_that) { case _HatchingModel(): -return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspectionLosses,_that.vetFarm,_that.activeKill,_that.killingInfo,_that.freeGovernmentalInfo,_that.reportInfo,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.hasChainCompany,_that.poultryIdForeignKey,_that.poultryHatchingIdKey,_that.quantity,_that.losses,_that.leftOver,_that.killedQuantity,_that.extraKilledQuantity,_that.governmentalKilledQuantity,_that.governmentalQuantity,_that.freeKilledQuantity,_that.freeQuantity,_that.chainKilledQuantity,_that.chainKilledWeight,_that.outProvinceKilledWeight,_that.outProvinceKilledQuantity,_that.exportKilledWeight,_that.exportKilledQuantity,_that.totalCommitment,_that.commitmentType,_that.totalCommitmentQuantity,_that.totalFreeCommitmentQuantity,_that.totalFreeCommitmentWeight,_that.totalKilledWeight,_that.totalAverageKilledWeight,_that.requestLeftOver,_that.hall,_that.date,_that.predicateDate,_that.chickenBreed,_that.period,_that.allowHatching,_that.state,_that.archive,_that.violation,_that.message,_that.registrar,_that.breed,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.lastChange,_that.chickenAge,_that.nowAge,_that.latestHatchingChange,_that.violationReport,_that.violationMessage,_that.violationImage,_that.violationReporter,_that.violationReportDate,_that.violationReportEditor,_that.violationReportEditDate,_that.totalLosses,_that.directLosses,_that.directLossesInputer,_that.directLossesDate,_that.directLossesEditor,_that.directLossesLastEditDate,_that.endPeriodLossesInputer,_that.endPeriodLossesDate,_that.endPeriodLossesEditor,_that.endPeriodLossesLastEditDate,_that.breedingUniqueId,_that.licenceNumber,_that.temporaryTrash,_that.temporaryDeleted,_that.firstDateInputArchive,_that.secondDateInputArchive,_that.inputArchiver,_that.outputArchiveDate,_that.outputArchiver,_that.barDifferenceRequestWeight,_that.barDifferenceRequestQuantity,_that.healthCertificate,_that.samasatDischargePercentage,_that.personTypeName,_that.interactTypeName,_that.unionTypeName,_that.certId,_that.increaseQuantity,_that.tenantFullname,_that.tenantNationalCode,_that.tenantMobile,_that.tenantCity,_that.hasTenant,_that.archiveDate,_that.createdBy,_that.modifiedBy);case _: +return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspectionLosses,_that.vetFarm,_that.activeKill,_that.killingInfo,_that.freeGovernmentalInfo,_that.reportInfo,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.hasChainCompany,_that.poultryIdForeignKey,_that.poultryHatchingIdKey,_that.quantity,_that.losses,_that.leftOver,_that.killedQuantity,_that.extraKilledQuantity,_that.governmentalKilledQuantity,_that.governmentalQuantity,_that.freeKilledQuantity,_that.freeQuantity,_that.chainKilledQuantity,_that.chainKilledWeight,_that.outProvinceKilledWeight,_that.outProvinceKilledQuantity,_that.exportKilledWeight,_that.exportKilledQuantity,_that.totalCommitment,_that.commitmentType,_that.totalCommitmentQuantity,_that.totalFreeCommitmentQuantity,_that.totalFreeCommitmentWeight,_that.totalKilledWeight,_that.totalAverageKilledWeight,_that.requestLeftOver,_that.hall,_that.date,_that.predicateDate,_that.chickenBreed,_that.period,_that.allowHatching,_that.state,_that.archive,_that.violation,_that.message,_that.registrar,_that.breed,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.lastChange,_that.chickenAge,_that.nowAge,_that.latestHatchingChange,_that.violationReport,_that.violationMessage,_that.violationImage,_that.violationReporter,_that.violationReportDate,_that.violationReportEditor,_that.violationReportEditDate,_that.totalLosses,_that.directLosses,_that.directLossesInputer,_that.directLossesDate,_that.directLossesEditor,_that.directLossesLastEditDate,_that.endPeriodLossesInputer,_that.endPeriodLossesDate,_that.endPeriodLossesEditor,_that.endPeriodLossesLastEditDate,_that.breedingUniqueId,_that.licenceNumber,_that.temporaryTrash,_that.temporaryDeleted,_that.firstDateInputArchive,_that.secondDateInputArchive,_that.inputArchiver,_that.outputArchiveDate,_that.outputArchiver,_that.barDifferenceRequestWeight,_that.barDifferenceRequestQuantity,_that.totalDiseaseLosses,_that.totalFlockDestruction,_that.totalNormalFlockLosses,_that.totalForceMajeureLosses,_that.totalFireLosses,_that.healthCertificate,_that.samasatDischargePercentage,_that.personTypeName,_that.interactTypeName,_that.unionTypeName,_that.certId,_that.increaseQuantity,_that.tenantFullname,_that.tenantNationalCode,_that.tenantMobile,_that.tenantCity,_that.hasTenant,_that.archiveDate,_that.unknown,_that.createdBy,_that.modifiedBy);case _: throw StateError('Unexpected subclass'); } @@ -416,10 +422,10 @@ return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspec /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, String? createdBy, String? modifiedBy)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, num? totalDiseaseLosses, num? totalFlockDestruction, num? totalNormalFlockLosses, num? totalForceMajeureLosses, num? totalFireLosses, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, bool? unknown, String? createdBy, String? modifiedBy)? $default,) {final _that = this; switch (_that) { case _HatchingModel() when $default != null: -return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspectionLosses,_that.vetFarm,_that.activeKill,_that.killingInfo,_that.freeGovernmentalInfo,_that.reportInfo,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.hasChainCompany,_that.poultryIdForeignKey,_that.poultryHatchingIdKey,_that.quantity,_that.losses,_that.leftOver,_that.killedQuantity,_that.extraKilledQuantity,_that.governmentalKilledQuantity,_that.governmentalQuantity,_that.freeKilledQuantity,_that.freeQuantity,_that.chainKilledQuantity,_that.chainKilledWeight,_that.outProvinceKilledWeight,_that.outProvinceKilledQuantity,_that.exportKilledWeight,_that.exportKilledQuantity,_that.totalCommitment,_that.commitmentType,_that.totalCommitmentQuantity,_that.totalFreeCommitmentQuantity,_that.totalFreeCommitmentWeight,_that.totalKilledWeight,_that.totalAverageKilledWeight,_that.requestLeftOver,_that.hall,_that.date,_that.predicateDate,_that.chickenBreed,_that.period,_that.allowHatching,_that.state,_that.archive,_that.violation,_that.message,_that.registrar,_that.breed,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.lastChange,_that.chickenAge,_that.nowAge,_that.latestHatchingChange,_that.violationReport,_that.violationMessage,_that.violationImage,_that.violationReporter,_that.violationReportDate,_that.violationReportEditor,_that.violationReportEditDate,_that.totalLosses,_that.directLosses,_that.directLossesInputer,_that.directLossesDate,_that.directLossesEditor,_that.directLossesLastEditDate,_that.endPeriodLossesInputer,_that.endPeriodLossesDate,_that.endPeriodLossesEditor,_that.endPeriodLossesLastEditDate,_that.breedingUniqueId,_that.licenceNumber,_that.temporaryTrash,_that.temporaryDeleted,_that.firstDateInputArchive,_that.secondDateInputArchive,_that.inputArchiver,_that.outputArchiveDate,_that.outputArchiver,_that.barDifferenceRequestWeight,_that.barDifferenceRequestQuantity,_that.healthCertificate,_that.samasatDischargePercentage,_that.personTypeName,_that.interactTypeName,_that.unionTypeName,_that.certId,_that.increaseQuantity,_that.tenantFullname,_that.tenantNationalCode,_that.tenantMobile,_that.tenantCity,_that.hasTenant,_that.archiveDate,_that.createdBy,_that.modifiedBy);case _: +return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspectionLosses,_that.vetFarm,_that.activeKill,_that.killingInfo,_that.freeGovernmentalInfo,_that.reportInfo,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.hasChainCompany,_that.poultryIdForeignKey,_that.poultryHatchingIdKey,_that.quantity,_that.losses,_that.leftOver,_that.killedQuantity,_that.extraKilledQuantity,_that.governmentalKilledQuantity,_that.governmentalQuantity,_that.freeKilledQuantity,_that.freeQuantity,_that.chainKilledQuantity,_that.chainKilledWeight,_that.outProvinceKilledWeight,_that.outProvinceKilledQuantity,_that.exportKilledWeight,_that.exportKilledQuantity,_that.totalCommitment,_that.commitmentType,_that.totalCommitmentQuantity,_that.totalFreeCommitmentQuantity,_that.totalFreeCommitmentWeight,_that.totalKilledWeight,_that.totalAverageKilledWeight,_that.requestLeftOver,_that.hall,_that.date,_that.predicateDate,_that.chickenBreed,_that.period,_that.allowHatching,_that.state,_that.archive,_that.violation,_that.message,_that.registrar,_that.breed,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.lastChange,_that.chickenAge,_that.nowAge,_that.latestHatchingChange,_that.violationReport,_that.violationMessage,_that.violationImage,_that.violationReporter,_that.violationReportDate,_that.violationReportEditor,_that.violationReportEditDate,_that.totalLosses,_that.directLosses,_that.directLossesInputer,_that.directLossesDate,_that.directLossesEditor,_that.directLossesLastEditDate,_that.endPeriodLossesInputer,_that.endPeriodLossesDate,_that.endPeriodLossesEditor,_that.endPeriodLossesLastEditDate,_that.breedingUniqueId,_that.licenceNumber,_that.temporaryTrash,_that.temporaryDeleted,_that.firstDateInputArchive,_that.secondDateInputArchive,_that.inputArchiver,_that.outputArchiveDate,_that.outputArchiver,_that.barDifferenceRequestWeight,_that.barDifferenceRequestQuantity,_that.totalDiseaseLosses,_that.totalFlockDestruction,_that.totalNormalFlockLosses,_that.totalForceMajeureLosses,_that.totalFireLosses,_that.healthCertificate,_that.samasatDischargePercentage,_that.personTypeName,_that.interactTypeName,_that.unionTypeName,_that.certId,_that.increaseQuantity,_that.tenantFullname,_that.tenantNationalCode,_that.tenantMobile,_that.tenantCity,_that.hasTenant,_that.archiveDate,_that.unknown,_that.createdBy,_that.modifiedBy);case _: return null; } @@ -431,7 +437,7 @@ return $default(_that.id,_that.poultry,_that.chainCompany,_that.age,_that.inspec @JsonSerializable() class _HatchingModel implements HatchingModel { - const _HatchingModel({this.id, this.poultry, this.chainCompany, this.age, this.inspectionLosses, this.vetFarm, this.activeKill, this.killingInfo, this.freeGovernmentalInfo, this.reportInfo, this.key, this.createDate, this.modifyDate, this.trash, this.hasChainCompany, this.poultryIdForeignKey, this.poultryHatchingIdKey, this.quantity, this.losses, this.leftOver, this.killedQuantity, this.extraKilledQuantity, this.governmentalKilledQuantity, this.governmentalQuantity, this.freeKilledQuantity, this.freeQuantity, this.chainKilledQuantity, this.chainKilledWeight, this.outProvinceKilledWeight, this.outProvinceKilledQuantity, this.exportKilledWeight, this.exportKilledQuantity, this.totalCommitment, this.commitmentType, this.totalCommitmentQuantity, this.totalFreeCommitmentQuantity, this.totalFreeCommitmentWeight, this.totalKilledWeight, this.totalAverageKilledWeight, this.requestLeftOver, this.hall, this.date, this.predicateDate, this.chickenBreed, this.period, this.allowHatching, this.state, this.archive, this.violation, this.message, this.registrar, final List? breed, this.cityNumber, this.cityName, this.provinceNumber, this.provinceName, this.lastChange, this.chickenAge, this.nowAge, this.latestHatchingChange, this.violationReport, this.violationMessage, final List? violationImage, this.violationReporter, this.violationReportDate, this.violationReportEditor, this.violationReportEditDate, this.totalLosses, this.directLosses, this.directLossesInputer, this.directLossesDate, this.directLossesEditor, this.directLossesLastEditDate, this.endPeriodLossesInputer, this.endPeriodLossesDate, this.endPeriodLossesEditor, this.endPeriodLossesLastEditDate, this.breedingUniqueId, this.licenceNumber, this.temporaryTrash, this.temporaryDeleted, this.firstDateInputArchive, this.secondDateInputArchive, this.inputArchiver, this.outputArchiveDate, this.outputArchiver, this.barDifferenceRequestWeight, this.barDifferenceRequestQuantity, this.healthCertificate, this.samasatDischargePercentage, this.personTypeName, this.interactTypeName, this.unionTypeName, this.certId, this.increaseQuantity, this.tenantFullname, this.tenantNationalCode, this.tenantMobile, this.tenantCity, this.hasTenant, this.archiveDate, this.createdBy, this.modifiedBy}): _breed = breed,_violationImage = violationImage; + const _HatchingModel({this.id, this.poultry, this.chainCompany, this.age, this.inspectionLosses, this.vetFarm, this.activeKill, this.killingInfo, this.freeGovernmentalInfo, this.reportInfo, this.key, this.createDate, this.modifyDate, this.trash, this.hasChainCompany, this.poultryIdForeignKey, this.poultryHatchingIdKey, this.quantity, this.losses, this.leftOver, this.killedQuantity, this.extraKilledQuantity, this.governmentalKilledQuantity, this.governmentalQuantity, this.freeKilledQuantity, this.freeQuantity, this.chainKilledQuantity, this.chainKilledWeight, this.outProvinceKilledWeight, this.outProvinceKilledQuantity, this.exportKilledWeight, this.exportKilledQuantity, this.totalCommitment, this.commitmentType, this.totalCommitmentQuantity, this.totalFreeCommitmentQuantity, this.totalFreeCommitmentWeight, this.totalKilledWeight, this.totalAverageKilledWeight, this.requestLeftOver, this.hall, this.date, this.predicateDate, this.chickenBreed, this.period, this.allowHatching, this.state, this.archive, this.violation, this.message, this.registrar, final List? breed, this.cityNumber, this.cityName, this.provinceNumber, this.provinceName, this.lastChange, this.chickenAge, this.nowAge, this.latestHatchingChange, this.violationReport, this.violationMessage, final List? violationImage, this.violationReporter, this.violationReportDate, this.violationReportEditor, this.violationReportEditDate, this.totalLosses, this.directLosses, this.directLossesInputer, this.directLossesDate, this.directLossesEditor, this.directLossesLastEditDate, this.endPeriodLossesInputer, this.endPeriodLossesDate, this.endPeriodLossesEditor, this.endPeriodLossesLastEditDate, this.breedingUniqueId, this.licenceNumber, this.temporaryTrash, this.temporaryDeleted, this.firstDateInputArchive, this.secondDateInputArchive, this.inputArchiver, this.outputArchiveDate, this.outputArchiver, this.barDifferenceRequestWeight, this.barDifferenceRequestQuantity, this.totalDiseaseLosses, this.totalFlockDestruction, this.totalNormalFlockLosses, this.totalForceMajeureLosses, this.totalFireLosses, this.healthCertificate, this.samasatDischargePercentage, this.personTypeName, this.interactTypeName, this.unionTypeName, this.certId, this.increaseQuantity, this.tenantFullname, this.tenantNationalCode, this.tenantMobile, this.tenantCity, this.hasTenant, this.archiveDate, this.unknown, this.createdBy, this.modifiedBy}): _breed = breed,_violationImage = violationImage; factory _HatchingModel.fromJson(Map json) => _$HatchingModelFromJson(json); @override final int? id; @@ -538,6 +544,11 @@ class _HatchingModel implements HatchingModel { @override final String? outputArchiver; @override final num? barDifferenceRequestWeight; @override final num? barDifferenceRequestQuantity; +@override final num? totalDiseaseLosses; +@override final num? totalFlockDestruction; +@override final num? totalNormalFlockLosses; +@override final num? totalForceMajeureLosses; +@override final num? totalFireLosses; @override final String? healthCertificate; @override final num? samasatDischargePercentage; @override final String? personTypeName; @@ -551,6 +562,7 @@ class _HatchingModel implements HatchingModel { @override final String? tenantCity; @override final bool? hasTenant; @override final String? archiveDate; +@override final bool? unknown; @override final String? createdBy; @override final String? modifiedBy; @@ -567,16 +579,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _HatchingModel&&(identical(other.id, id) || other.id == id)&&(identical(other.poultry, poultry) || other.poultry == poultry)&&(identical(other.chainCompany, chainCompany) || other.chainCompany == chainCompany)&&(identical(other.age, age) || other.age == age)&&const DeepCollectionEquality().equals(other.inspectionLosses, inspectionLosses)&&(identical(other.vetFarm, vetFarm) || other.vetFarm == vetFarm)&&(identical(other.activeKill, activeKill) || other.activeKill == activeKill)&&(identical(other.killingInfo, killingInfo) || other.killingInfo == killingInfo)&&(identical(other.freeGovernmentalInfo, freeGovernmentalInfo) || other.freeGovernmentalInfo == freeGovernmentalInfo)&&(identical(other.reportInfo, reportInfo) || other.reportInfo == reportInfo)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.hasChainCompany, hasChainCompany) || other.hasChainCompany == hasChainCompany)&&(identical(other.poultryIdForeignKey, poultryIdForeignKey) || other.poultryIdForeignKey == poultryIdForeignKey)&&(identical(other.poultryHatchingIdKey, poultryHatchingIdKey) || other.poultryHatchingIdKey == poultryHatchingIdKey)&&(identical(other.quantity, quantity) || other.quantity == quantity)&&(identical(other.losses, losses) || other.losses == losses)&&(identical(other.leftOver, leftOver) || other.leftOver == leftOver)&&(identical(other.killedQuantity, killedQuantity) || other.killedQuantity == killedQuantity)&&(identical(other.extraKilledQuantity, extraKilledQuantity) || other.extraKilledQuantity == extraKilledQuantity)&&(identical(other.governmentalKilledQuantity, governmentalKilledQuantity) || other.governmentalKilledQuantity == governmentalKilledQuantity)&&(identical(other.governmentalQuantity, governmentalQuantity) || other.governmentalQuantity == governmentalQuantity)&&(identical(other.freeKilledQuantity, freeKilledQuantity) || other.freeKilledQuantity == freeKilledQuantity)&&(identical(other.freeQuantity, freeQuantity) || other.freeQuantity == freeQuantity)&&(identical(other.chainKilledQuantity, chainKilledQuantity) || other.chainKilledQuantity == chainKilledQuantity)&&(identical(other.chainKilledWeight, chainKilledWeight) || other.chainKilledWeight == chainKilledWeight)&&(identical(other.outProvinceKilledWeight, outProvinceKilledWeight) || other.outProvinceKilledWeight == outProvinceKilledWeight)&&(identical(other.outProvinceKilledQuantity, outProvinceKilledQuantity) || other.outProvinceKilledQuantity == outProvinceKilledQuantity)&&(identical(other.exportKilledWeight, exportKilledWeight) || other.exportKilledWeight == exportKilledWeight)&&(identical(other.exportKilledQuantity, exportKilledQuantity) || other.exportKilledQuantity == exportKilledQuantity)&&(identical(other.totalCommitment, totalCommitment) || other.totalCommitment == totalCommitment)&&(identical(other.commitmentType, commitmentType) || other.commitmentType == commitmentType)&&(identical(other.totalCommitmentQuantity, totalCommitmentQuantity) || other.totalCommitmentQuantity == totalCommitmentQuantity)&&(identical(other.totalFreeCommitmentQuantity, totalFreeCommitmentQuantity) || other.totalFreeCommitmentQuantity == totalFreeCommitmentQuantity)&&(identical(other.totalFreeCommitmentWeight, totalFreeCommitmentWeight) || other.totalFreeCommitmentWeight == totalFreeCommitmentWeight)&&(identical(other.totalKilledWeight, totalKilledWeight) || other.totalKilledWeight == totalKilledWeight)&&(identical(other.totalAverageKilledWeight, totalAverageKilledWeight) || other.totalAverageKilledWeight == totalAverageKilledWeight)&&(identical(other.requestLeftOver, requestLeftOver) || other.requestLeftOver == requestLeftOver)&&(identical(other.hall, hall) || other.hall == hall)&&(identical(other.date, date) || other.date == date)&&(identical(other.predicateDate, predicateDate) || other.predicateDate == predicateDate)&&(identical(other.chickenBreed, chickenBreed) || other.chickenBreed == chickenBreed)&&(identical(other.period, period) || other.period == period)&&(identical(other.allowHatching, allowHatching) || other.allowHatching == allowHatching)&&(identical(other.state, state) || other.state == state)&&(identical(other.archive, archive) || other.archive == archive)&&(identical(other.violation, violation) || other.violation == violation)&&(identical(other.message, message) || other.message == message)&&(identical(other.registrar, registrar) || other.registrar == registrar)&&const DeepCollectionEquality().equals(other._breed, _breed)&&(identical(other.cityNumber, cityNumber) || other.cityNumber == cityNumber)&&(identical(other.cityName, cityName) || other.cityName == cityName)&&(identical(other.provinceNumber, provinceNumber) || other.provinceNumber == provinceNumber)&&(identical(other.provinceName, provinceName) || other.provinceName == provinceName)&&(identical(other.lastChange, lastChange) || other.lastChange == lastChange)&&(identical(other.chickenAge, chickenAge) || other.chickenAge == chickenAge)&&(identical(other.nowAge, nowAge) || other.nowAge == nowAge)&&(identical(other.latestHatchingChange, latestHatchingChange) || other.latestHatchingChange == latestHatchingChange)&&(identical(other.violationReport, violationReport) || other.violationReport == violationReport)&&(identical(other.violationMessage, violationMessage) || other.violationMessage == violationMessage)&&const DeepCollectionEquality().equals(other._violationImage, _violationImage)&&(identical(other.violationReporter, violationReporter) || other.violationReporter == violationReporter)&&(identical(other.violationReportDate, violationReportDate) || other.violationReportDate == violationReportDate)&&(identical(other.violationReportEditor, violationReportEditor) || other.violationReportEditor == violationReportEditor)&&(identical(other.violationReportEditDate, violationReportEditDate) || other.violationReportEditDate == violationReportEditDate)&&(identical(other.totalLosses, totalLosses) || other.totalLosses == totalLosses)&&(identical(other.directLosses, directLosses) || other.directLosses == directLosses)&&(identical(other.directLossesInputer, directLossesInputer) || other.directLossesInputer == directLossesInputer)&&(identical(other.directLossesDate, directLossesDate) || other.directLossesDate == directLossesDate)&&(identical(other.directLossesEditor, directLossesEditor) || other.directLossesEditor == directLossesEditor)&&(identical(other.directLossesLastEditDate, directLossesLastEditDate) || other.directLossesLastEditDate == directLossesLastEditDate)&&(identical(other.endPeriodLossesInputer, endPeriodLossesInputer) || other.endPeriodLossesInputer == endPeriodLossesInputer)&&(identical(other.endPeriodLossesDate, endPeriodLossesDate) || other.endPeriodLossesDate == endPeriodLossesDate)&&(identical(other.endPeriodLossesEditor, endPeriodLossesEditor) || other.endPeriodLossesEditor == endPeriodLossesEditor)&&(identical(other.endPeriodLossesLastEditDate, endPeriodLossesLastEditDate) || other.endPeriodLossesLastEditDate == endPeriodLossesLastEditDate)&&(identical(other.breedingUniqueId, breedingUniqueId) || other.breedingUniqueId == breedingUniqueId)&&(identical(other.licenceNumber, licenceNumber) || other.licenceNumber == licenceNumber)&&(identical(other.temporaryTrash, temporaryTrash) || other.temporaryTrash == temporaryTrash)&&(identical(other.temporaryDeleted, temporaryDeleted) || other.temporaryDeleted == temporaryDeleted)&&(identical(other.firstDateInputArchive, firstDateInputArchive) || other.firstDateInputArchive == firstDateInputArchive)&&(identical(other.secondDateInputArchive, secondDateInputArchive) || other.secondDateInputArchive == secondDateInputArchive)&&(identical(other.inputArchiver, inputArchiver) || other.inputArchiver == inputArchiver)&&(identical(other.outputArchiveDate, outputArchiveDate) || other.outputArchiveDate == outputArchiveDate)&&(identical(other.outputArchiver, outputArchiver) || other.outputArchiver == outputArchiver)&&(identical(other.barDifferenceRequestWeight, barDifferenceRequestWeight) || other.barDifferenceRequestWeight == barDifferenceRequestWeight)&&(identical(other.barDifferenceRequestQuantity, barDifferenceRequestQuantity) || other.barDifferenceRequestQuantity == barDifferenceRequestQuantity)&&(identical(other.healthCertificate, healthCertificate) || other.healthCertificate == healthCertificate)&&(identical(other.samasatDischargePercentage, samasatDischargePercentage) || other.samasatDischargePercentage == samasatDischargePercentage)&&(identical(other.personTypeName, personTypeName) || other.personTypeName == personTypeName)&&(identical(other.interactTypeName, interactTypeName) || other.interactTypeName == interactTypeName)&&(identical(other.unionTypeName, unionTypeName) || other.unionTypeName == unionTypeName)&&(identical(other.certId, certId) || other.certId == certId)&&(identical(other.increaseQuantity, increaseQuantity) || other.increaseQuantity == increaseQuantity)&&(identical(other.tenantFullname, tenantFullname) || other.tenantFullname == tenantFullname)&&(identical(other.tenantNationalCode, tenantNationalCode) || other.tenantNationalCode == tenantNationalCode)&&(identical(other.tenantMobile, tenantMobile) || other.tenantMobile == tenantMobile)&&(identical(other.tenantCity, tenantCity) || other.tenantCity == tenantCity)&&(identical(other.hasTenant, hasTenant) || other.hasTenant == hasTenant)&&(identical(other.archiveDate, archiveDate) || other.archiveDate == archiveDate)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _HatchingModel&&(identical(other.id, id) || other.id == id)&&(identical(other.poultry, poultry) || other.poultry == poultry)&&(identical(other.chainCompany, chainCompany) || other.chainCompany == chainCompany)&&(identical(other.age, age) || other.age == age)&&const DeepCollectionEquality().equals(other.inspectionLosses, inspectionLosses)&&(identical(other.vetFarm, vetFarm) || other.vetFarm == vetFarm)&&(identical(other.activeKill, activeKill) || other.activeKill == activeKill)&&(identical(other.killingInfo, killingInfo) || other.killingInfo == killingInfo)&&(identical(other.freeGovernmentalInfo, freeGovernmentalInfo) || other.freeGovernmentalInfo == freeGovernmentalInfo)&&(identical(other.reportInfo, reportInfo) || other.reportInfo == reportInfo)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.hasChainCompany, hasChainCompany) || other.hasChainCompany == hasChainCompany)&&(identical(other.poultryIdForeignKey, poultryIdForeignKey) || other.poultryIdForeignKey == poultryIdForeignKey)&&(identical(other.poultryHatchingIdKey, poultryHatchingIdKey) || other.poultryHatchingIdKey == poultryHatchingIdKey)&&(identical(other.quantity, quantity) || other.quantity == quantity)&&(identical(other.losses, losses) || other.losses == losses)&&(identical(other.leftOver, leftOver) || other.leftOver == leftOver)&&(identical(other.killedQuantity, killedQuantity) || other.killedQuantity == killedQuantity)&&(identical(other.extraKilledQuantity, extraKilledQuantity) || other.extraKilledQuantity == extraKilledQuantity)&&(identical(other.governmentalKilledQuantity, governmentalKilledQuantity) || other.governmentalKilledQuantity == governmentalKilledQuantity)&&(identical(other.governmentalQuantity, governmentalQuantity) || other.governmentalQuantity == governmentalQuantity)&&(identical(other.freeKilledQuantity, freeKilledQuantity) || other.freeKilledQuantity == freeKilledQuantity)&&(identical(other.freeQuantity, freeQuantity) || other.freeQuantity == freeQuantity)&&(identical(other.chainKilledQuantity, chainKilledQuantity) || other.chainKilledQuantity == chainKilledQuantity)&&(identical(other.chainKilledWeight, chainKilledWeight) || other.chainKilledWeight == chainKilledWeight)&&(identical(other.outProvinceKilledWeight, outProvinceKilledWeight) || other.outProvinceKilledWeight == outProvinceKilledWeight)&&(identical(other.outProvinceKilledQuantity, outProvinceKilledQuantity) || other.outProvinceKilledQuantity == outProvinceKilledQuantity)&&(identical(other.exportKilledWeight, exportKilledWeight) || other.exportKilledWeight == exportKilledWeight)&&(identical(other.exportKilledQuantity, exportKilledQuantity) || other.exportKilledQuantity == exportKilledQuantity)&&(identical(other.totalCommitment, totalCommitment) || other.totalCommitment == totalCommitment)&&(identical(other.commitmentType, commitmentType) || other.commitmentType == commitmentType)&&(identical(other.totalCommitmentQuantity, totalCommitmentQuantity) || other.totalCommitmentQuantity == totalCommitmentQuantity)&&(identical(other.totalFreeCommitmentQuantity, totalFreeCommitmentQuantity) || other.totalFreeCommitmentQuantity == totalFreeCommitmentQuantity)&&(identical(other.totalFreeCommitmentWeight, totalFreeCommitmentWeight) || other.totalFreeCommitmentWeight == totalFreeCommitmentWeight)&&(identical(other.totalKilledWeight, totalKilledWeight) || other.totalKilledWeight == totalKilledWeight)&&(identical(other.totalAverageKilledWeight, totalAverageKilledWeight) || other.totalAverageKilledWeight == totalAverageKilledWeight)&&(identical(other.requestLeftOver, requestLeftOver) || other.requestLeftOver == requestLeftOver)&&(identical(other.hall, hall) || other.hall == hall)&&(identical(other.date, date) || other.date == date)&&(identical(other.predicateDate, predicateDate) || other.predicateDate == predicateDate)&&(identical(other.chickenBreed, chickenBreed) || other.chickenBreed == chickenBreed)&&(identical(other.period, period) || other.period == period)&&(identical(other.allowHatching, allowHatching) || other.allowHatching == allowHatching)&&(identical(other.state, state) || other.state == state)&&(identical(other.archive, archive) || other.archive == archive)&&(identical(other.violation, violation) || other.violation == violation)&&(identical(other.message, message) || other.message == message)&&(identical(other.registrar, registrar) || other.registrar == registrar)&&const DeepCollectionEquality().equals(other._breed, _breed)&&(identical(other.cityNumber, cityNumber) || other.cityNumber == cityNumber)&&(identical(other.cityName, cityName) || other.cityName == cityName)&&(identical(other.provinceNumber, provinceNumber) || other.provinceNumber == provinceNumber)&&(identical(other.provinceName, provinceName) || other.provinceName == provinceName)&&(identical(other.lastChange, lastChange) || other.lastChange == lastChange)&&(identical(other.chickenAge, chickenAge) || other.chickenAge == chickenAge)&&(identical(other.nowAge, nowAge) || other.nowAge == nowAge)&&(identical(other.latestHatchingChange, latestHatchingChange) || other.latestHatchingChange == latestHatchingChange)&&(identical(other.violationReport, violationReport) || other.violationReport == violationReport)&&(identical(other.violationMessage, violationMessage) || other.violationMessage == violationMessage)&&const DeepCollectionEquality().equals(other._violationImage, _violationImage)&&(identical(other.violationReporter, violationReporter) || other.violationReporter == violationReporter)&&(identical(other.violationReportDate, violationReportDate) || other.violationReportDate == violationReportDate)&&(identical(other.violationReportEditor, violationReportEditor) || other.violationReportEditor == violationReportEditor)&&(identical(other.violationReportEditDate, violationReportEditDate) || other.violationReportEditDate == violationReportEditDate)&&(identical(other.totalLosses, totalLosses) || other.totalLosses == totalLosses)&&(identical(other.directLosses, directLosses) || other.directLosses == directLosses)&&(identical(other.directLossesInputer, directLossesInputer) || other.directLossesInputer == directLossesInputer)&&(identical(other.directLossesDate, directLossesDate) || other.directLossesDate == directLossesDate)&&(identical(other.directLossesEditor, directLossesEditor) || other.directLossesEditor == directLossesEditor)&&(identical(other.directLossesLastEditDate, directLossesLastEditDate) || other.directLossesLastEditDate == directLossesLastEditDate)&&(identical(other.endPeriodLossesInputer, endPeriodLossesInputer) || other.endPeriodLossesInputer == endPeriodLossesInputer)&&(identical(other.endPeriodLossesDate, endPeriodLossesDate) || other.endPeriodLossesDate == endPeriodLossesDate)&&(identical(other.endPeriodLossesEditor, endPeriodLossesEditor) || other.endPeriodLossesEditor == endPeriodLossesEditor)&&(identical(other.endPeriodLossesLastEditDate, endPeriodLossesLastEditDate) || other.endPeriodLossesLastEditDate == endPeriodLossesLastEditDate)&&(identical(other.breedingUniqueId, breedingUniqueId) || other.breedingUniqueId == breedingUniqueId)&&(identical(other.licenceNumber, licenceNumber) || other.licenceNumber == licenceNumber)&&(identical(other.temporaryTrash, temporaryTrash) || other.temporaryTrash == temporaryTrash)&&(identical(other.temporaryDeleted, temporaryDeleted) || other.temporaryDeleted == temporaryDeleted)&&(identical(other.firstDateInputArchive, firstDateInputArchive) || other.firstDateInputArchive == firstDateInputArchive)&&(identical(other.secondDateInputArchive, secondDateInputArchive) || other.secondDateInputArchive == secondDateInputArchive)&&(identical(other.inputArchiver, inputArchiver) || other.inputArchiver == inputArchiver)&&(identical(other.outputArchiveDate, outputArchiveDate) || other.outputArchiveDate == outputArchiveDate)&&(identical(other.outputArchiver, outputArchiver) || other.outputArchiver == outputArchiver)&&(identical(other.barDifferenceRequestWeight, barDifferenceRequestWeight) || other.barDifferenceRequestWeight == barDifferenceRequestWeight)&&(identical(other.barDifferenceRequestQuantity, barDifferenceRequestQuantity) || other.barDifferenceRequestQuantity == barDifferenceRequestQuantity)&&(identical(other.totalDiseaseLosses, totalDiseaseLosses) || other.totalDiseaseLosses == totalDiseaseLosses)&&(identical(other.totalFlockDestruction, totalFlockDestruction) || other.totalFlockDestruction == totalFlockDestruction)&&(identical(other.totalNormalFlockLosses, totalNormalFlockLosses) || other.totalNormalFlockLosses == totalNormalFlockLosses)&&(identical(other.totalForceMajeureLosses, totalForceMajeureLosses) || other.totalForceMajeureLosses == totalForceMajeureLosses)&&(identical(other.totalFireLosses, totalFireLosses) || other.totalFireLosses == totalFireLosses)&&(identical(other.healthCertificate, healthCertificate) || other.healthCertificate == healthCertificate)&&(identical(other.samasatDischargePercentage, samasatDischargePercentage) || other.samasatDischargePercentage == samasatDischargePercentage)&&(identical(other.personTypeName, personTypeName) || other.personTypeName == personTypeName)&&(identical(other.interactTypeName, interactTypeName) || other.interactTypeName == interactTypeName)&&(identical(other.unionTypeName, unionTypeName) || other.unionTypeName == unionTypeName)&&(identical(other.certId, certId) || other.certId == certId)&&(identical(other.increaseQuantity, increaseQuantity) || other.increaseQuantity == increaseQuantity)&&(identical(other.tenantFullname, tenantFullname) || other.tenantFullname == tenantFullname)&&(identical(other.tenantNationalCode, tenantNationalCode) || other.tenantNationalCode == tenantNationalCode)&&(identical(other.tenantMobile, tenantMobile) || other.tenantMobile == tenantMobile)&&(identical(other.tenantCity, tenantCity) || other.tenantCity == tenantCity)&&(identical(other.hasTenant, hasTenant) || other.hasTenant == hasTenant)&&(identical(other.archiveDate, archiveDate) || other.archiveDate == archiveDate)&&(identical(other.unknown, unknown) || other.unknown == unknown)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hashAll([runtimeType,id,poultry,chainCompany,age,const DeepCollectionEquality().hash(inspectionLosses),vetFarm,activeKill,killingInfo,freeGovernmentalInfo,reportInfo,key,createDate,modifyDate,trash,hasChainCompany,poultryIdForeignKey,poultryHatchingIdKey,quantity,losses,leftOver,killedQuantity,extraKilledQuantity,governmentalKilledQuantity,governmentalQuantity,freeKilledQuantity,freeQuantity,chainKilledQuantity,chainKilledWeight,outProvinceKilledWeight,outProvinceKilledQuantity,exportKilledWeight,exportKilledQuantity,totalCommitment,commitmentType,totalCommitmentQuantity,totalFreeCommitmentQuantity,totalFreeCommitmentWeight,totalKilledWeight,totalAverageKilledWeight,requestLeftOver,hall,date,predicateDate,chickenBreed,period,allowHatching,state,archive,violation,message,registrar,const DeepCollectionEquality().hash(_breed),cityNumber,cityName,provinceNumber,provinceName,lastChange,chickenAge,nowAge,latestHatchingChange,violationReport,violationMessage,const DeepCollectionEquality().hash(_violationImage),violationReporter,violationReportDate,violationReportEditor,violationReportEditDate,totalLosses,directLosses,directLossesInputer,directLossesDate,directLossesEditor,directLossesLastEditDate,endPeriodLossesInputer,endPeriodLossesDate,endPeriodLossesEditor,endPeriodLossesLastEditDate,breedingUniqueId,licenceNumber,temporaryTrash,temporaryDeleted,firstDateInputArchive,secondDateInputArchive,inputArchiver,outputArchiveDate,outputArchiver,barDifferenceRequestWeight,barDifferenceRequestQuantity,healthCertificate,samasatDischargePercentage,personTypeName,interactTypeName,unionTypeName,certId,increaseQuantity,tenantFullname,tenantNationalCode,tenantMobile,tenantCity,hasTenant,archiveDate,createdBy,modifiedBy]); +int get hashCode => Object.hashAll([runtimeType,id,poultry,chainCompany,age,const DeepCollectionEquality().hash(inspectionLosses),vetFarm,activeKill,killingInfo,freeGovernmentalInfo,reportInfo,key,createDate,modifyDate,trash,hasChainCompany,poultryIdForeignKey,poultryHatchingIdKey,quantity,losses,leftOver,killedQuantity,extraKilledQuantity,governmentalKilledQuantity,governmentalQuantity,freeKilledQuantity,freeQuantity,chainKilledQuantity,chainKilledWeight,outProvinceKilledWeight,outProvinceKilledQuantity,exportKilledWeight,exportKilledQuantity,totalCommitment,commitmentType,totalCommitmentQuantity,totalFreeCommitmentQuantity,totalFreeCommitmentWeight,totalKilledWeight,totalAverageKilledWeight,requestLeftOver,hall,date,predicateDate,chickenBreed,period,allowHatching,state,archive,violation,message,registrar,const DeepCollectionEquality().hash(_breed),cityNumber,cityName,provinceNumber,provinceName,lastChange,chickenAge,nowAge,latestHatchingChange,violationReport,violationMessage,const DeepCollectionEquality().hash(_violationImage),violationReporter,violationReportDate,violationReportEditor,violationReportEditDate,totalLosses,directLosses,directLossesInputer,directLossesDate,directLossesEditor,directLossesLastEditDate,endPeriodLossesInputer,endPeriodLossesDate,endPeriodLossesEditor,endPeriodLossesLastEditDate,breedingUniqueId,licenceNumber,temporaryTrash,temporaryDeleted,firstDateInputArchive,secondDateInputArchive,inputArchiver,outputArchiveDate,outputArchiver,barDifferenceRequestWeight,barDifferenceRequestQuantity,totalDiseaseLosses,totalFlockDestruction,totalNormalFlockLosses,totalForceMajeureLosses,totalFireLosses,healthCertificate,samasatDischargePercentage,personTypeName,interactTypeName,unionTypeName,certId,increaseQuantity,tenantFullname,tenantNationalCode,tenantMobile,tenantCity,hasTenant,archiveDate,unknown,createdBy,modifiedBy]); @override String toString() { - return 'HatchingModel(id: $id, poultry: $poultry, chainCompany: $chainCompany, age: $age, inspectionLosses: $inspectionLosses, vetFarm: $vetFarm, activeKill: $activeKill, killingInfo: $killingInfo, freeGovernmentalInfo: $freeGovernmentalInfo, reportInfo: $reportInfo, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, hasChainCompany: $hasChainCompany, poultryIdForeignKey: $poultryIdForeignKey, poultryHatchingIdKey: $poultryHatchingIdKey, quantity: $quantity, losses: $losses, leftOver: $leftOver, killedQuantity: $killedQuantity, extraKilledQuantity: $extraKilledQuantity, governmentalKilledQuantity: $governmentalKilledQuantity, governmentalQuantity: $governmentalQuantity, freeKilledQuantity: $freeKilledQuantity, freeQuantity: $freeQuantity, chainKilledQuantity: $chainKilledQuantity, chainKilledWeight: $chainKilledWeight, outProvinceKilledWeight: $outProvinceKilledWeight, outProvinceKilledQuantity: $outProvinceKilledQuantity, exportKilledWeight: $exportKilledWeight, exportKilledQuantity: $exportKilledQuantity, totalCommitment: $totalCommitment, commitmentType: $commitmentType, totalCommitmentQuantity: $totalCommitmentQuantity, totalFreeCommitmentQuantity: $totalFreeCommitmentQuantity, totalFreeCommitmentWeight: $totalFreeCommitmentWeight, totalKilledWeight: $totalKilledWeight, totalAverageKilledWeight: $totalAverageKilledWeight, requestLeftOver: $requestLeftOver, hall: $hall, date: $date, predicateDate: $predicateDate, chickenBreed: $chickenBreed, period: $period, allowHatching: $allowHatching, state: $state, archive: $archive, violation: $violation, message: $message, registrar: $registrar, breed: $breed, cityNumber: $cityNumber, cityName: $cityName, provinceNumber: $provinceNumber, provinceName: $provinceName, lastChange: $lastChange, chickenAge: $chickenAge, nowAge: $nowAge, latestHatchingChange: $latestHatchingChange, violationReport: $violationReport, violationMessage: $violationMessage, violationImage: $violationImage, violationReporter: $violationReporter, violationReportDate: $violationReportDate, violationReportEditor: $violationReportEditor, violationReportEditDate: $violationReportEditDate, totalLosses: $totalLosses, directLosses: $directLosses, directLossesInputer: $directLossesInputer, directLossesDate: $directLossesDate, directLossesEditor: $directLossesEditor, directLossesLastEditDate: $directLossesLastEditDate, endPeriodLossesInputer: $endPeriodLossesInputer, endPeriodLossesDate: $endPeriodLossesDate, endPeriodLossesEditor: $endPeriodLossesEditor, endPeriodLossesLastEditDate: $endPeriodLossesLastEditDate, breedingUniqueId: $breedingUniqueId, licenceNumber: $licenceNumber, temporaryTrash: $temporaryTrash, temporaryDeleted: $temporaryDeleted, firstDateInputArchive: $firstDateInputArchive, secondDateInputArchive: $secondDateInputArchive, inputArchiver: $inputArchiver, outputArchiveDate: $outputArchiveDate, outputArchiver: $outputArchiver, barDifferenceRequestWeight: $barDifferenceRequestWeight, barDifferenceRequestQuantity: $barDifferenceRequestQuantity, healthCertificate: $healthCertificate, samasatDischargePercentage: $samasatDischargePercentage, personTypeName: $personTypeName, interactTypeName: $interactTypeName, unionTypeName: $unionTypeName, certId: $certId, increaseQuantity: $increaseQuantity, tenantFullname: $tenantFullname, tenantNationalCode: $tenantNationalCode, tenantMobile: $tenantMobile, tenantCity: $tenantCity, hasTenant: $hasTenant, archiveDate: $archiveDate, createdBy: $createdBy, modifiedBy: $modifiedBy)'; + return 'HatchingModel(id: $id, poultry: $poultry, chainCompany: $chainCompany, age: $age, inspectionLosses: $inspectionLosses, vetFarm: $vetFarm, activeKill: $activeKill, killingInfo: $killingInfo, freeGovernmentalInfo: $freeGovernmentalInfo, reportInfo: $reportInfo, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, hasChainCompany: $hasChainCompany, poultryIdForeignKey: $poultryIdForeignKey, poultryHatchingIdKey: $poultryHatchingIdKey, quantity: $quantity, losses: $losses, leftOver: $leftOver, killedQuantity: $killedQuantity, extraKilledQuantity: $extraKilledQuantity, governmentalKilledQuantity: $governmentalKilledQuantity, governmentalQuantity: $governmentalQuantity, freeKilledQuantity: $freeKilledQuantity, freeQuantity: $freeQuantity, chainKilledQuantity: $chainKilledQuantity, chainKilledWeight: $chainKilledWeight, outProvinceKilledWeight: $outProvinceKilledWeight, outProvinceKilledQuantity: $outProvinceKilledQuantity, exportKilledWeight: $exportKilledWeight, exportKilledQuantity: $exportKilledQuantity, totalCommitment: $totalCommitment, commitmentType: $commitmentType, totalCommitmentQuantity: $totalCommitmentQuantity, totalFreeCommitmentQuantity: $totalFreeCommitmentQuantity, totalFreeCommitmentWeight: $totalFreeCommitmentWeight, totalKilledWeight: $totalKilledWeight, totalAverageKilledWeight: $totalAverageKilledWeight, requestLeftOver: $requestLeftOver, hall: $hall, date: $date, predicateDate: $predicateDate, chickenBreed: $chickenBreed, period: $period, allowHatching: $allowHatching, state: $state, archive: $archive, violation: $violation, message: $message, registrar: $registrar, breed: $breed, cityNumber: $cityNumber, cityName: $cityName, provinceNumber: $provinceNumber, provinceName: $provinceName, lastChange: $lastChange, chickenAge: $chickenAge, nowAge: $nowAge, latestHatchingChange: $latestHatchingChange, violationReport: $violationReport, violationMessage: $violationMessage, violationImage: $violationImage, violationReporter: $violationReporter, violationReportDate: $violationReportDate, violationReportEditor: $violationReportEditor, violationReportEditDate: $violationReportEditDate, totalLosses: $totalLosses, directLosses: $directLosses, directLossesInputer: $directLossesInputer, directLossesDate: $directLossesDate, directLossesEditor: $directLossesEditor, directLossesLastEditDate: $directLossesLastEditDate, endPeriodLossesInputer: $endPeriodLossesInputer, endPeriodLossesDate: $endPeriodLossesDate, endPeriodLossesEditor: $endPeriodLossesEditor, endPeriodLossesLastEditDate: $endPeriodLossesLastEditDate, breedingUniqueId: $breedingUniqueId, licenceNumber: $licenceNumber, temporaryTrash: $temporaryTrash, temporaryDeleted: $temporaryDeleted, firstDateInputArchive: $firstDateInputArchive, secondDateInputArchive: $secondDateInputArchive, inputArchiver: $inputArchiver, outputArchiveDate: $outputArchiveDate, outputArchiver: $outputArchiver, barDifferenceRequestWeight: $barDifferenceRequestWeight, barDifferenceRequestQuantity: $barDifferenceRequestQuantity, totalDiseaseLosses: $totalDiseaseLosses, totalFlockDestruction: $totalFlockDestruction, totalNormalFlockLosses: $totalNormalFlockLosses, totalForceMajeureLosses: $totalForceMajeureLosses, totalFireLosses: $totalFireLosses, healthCertificate: $healthCertificate, samasatDischargePercentage: $samasatDischargePercentage, personTypeName: $personTypeName, interactTypeName: $interactTypeName, unionTypeName: $unionTypeName, certId: $certId, increaseQuantity: $increaseQuantity, tenantFullname: $tenantFullname, tenantNationalCode: $tenantNationalCode, tenantMobile: $tenantMobile, tenantCity: $tenantCity, hasTenant: $hasTenant, archiveDate: $archiveDate, unknown: $unknown, createdBy: $createdBy, modifiedBy: $modifiedBy)'; } @@ -587,7 +599,7 @@ abstract mixin class _$HatchingModelCopyWith<$Res> implements $HatchingModelCopy factory _$HatchingModelCopyWith(_HatchingModel value, $Res Function(_HatchingModel) _then) = __$HatchingModelCopyWithImpl; @override @useResult $Res call({ - int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, String? createdBy, String? modifiedBy + int? id, Poultry? poultry, ChainCompany? chainCompany, num? age, dynamic inspectionLosses, VetFarm? vetFarm, ActiveKill? activeKill, KillingInfo? killingInfo, FreeGovernmentalInfo? freeGovernmentalInfo, ReportInfo? reportInfo, String? key, String? createDate, String? modifyDate, bool? trash, bool? hasChainCompany, int? poultryIdForeignKey, int? poultryHatchingIdKey, num? quantity, num? losses, num? leftOver, num? killedQuantity, num? extraKilledQuantity, num? governmentalKilledQuantity, num? governmentalQuantity, num? freeKilledQuantity, num? freeQuantity, num? chainKilledQuantity, num? chainKilledWeight, num? outProvinceKilledWeight, num? outProvinceKilledQuantity, num? exportKilledWeight, num? exportKilledQuantity, num? totalCommitment, String? commitmentType, num? totalCommitmentQuantity, num? totalFreeCommitmentQuantity, num? totalFreeCommitmentWeight, num? totalKilledWeight, num? totalAverageKilledWeight, num? requestLeftOver, num? hall, String? date, String? predicateDate, String? chickenBreed, num? period, String? allowHatching, String? state, bool? archive, bool? violation, String? message, Registrar? registrar, List? breed, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, LastChange? lastChange, num? chickenAge, num? nowAge, LatestHatchingChange? latestHatchingChange, String? violationReport, String? violationMessage, List? violationImage, String? violationReporter, String? violationReportDate, String? violationReportEditor, String? violationReportEditDate, num? totalLosses, num? directLosses, String? directLossesInputer, String? directLossesDate, String? directLossesEditor, String? directLossesLastEditDate, String? endPeriodLossesInputer, String? endPeriodLossesDate, String? endPeriodLossesEditor, String? endPeriodLossesLastEditDate, String? breedingUniqueId, String? licenceNumber, bool? temporaryTrash, bool? temporaryDeleted, String? firstDateInputArchive, String? secondDateInputArchive, String? inputArchiver, String? outputArchiveDate, String? outputArchiver, num? barDifferenceRequestWeight, num? barDifferenceRequestQuantity, num? totalDiseaseLosses, num? totalFlockDestruction, num? totalNormalFlockLosses, num? totalForceMajeureLosses, num? totalFireLosses, String? healthCertificate, num? samasatDischargePercentage, String? personTypeName, String? interactTypeName, String? unionTypeName, String? certId, num? increaseQuantity, String? tenantFullname, String? tenantNationalCode, String? tenantMobile, String? tenantCity, bool? hasTenant, String? archiveDate, bool? unknown, String? createdBy, String? modifiedBy }); @@ -604,7 +616,7 @@ class __$HatchingModelCopyWithImpl<$Res> /// Create a copy of HatchingModel /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? poultry = freezed,Object? chainCompany = freezed,Object? age = freezed,Object? inspectionLosses = freezed,Object? vetFarm = freezed,Object? activeKill = freezed,Object? killingInfo = freezed,Object? freeGovernmentalInfo = freezed,Object? reportInfo = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? hasChainCompany = freezed,Object? poultryIdForeignKey = freezed,Object? poultryHatchingIdKey = freezed,Object? quantity = freezed,Object? losses = freezed,Object? leftOver = freezed,Object? killedQuantity = freezed,Object? extraKilledQuantity = freezed,Object? governmentalKilledQuantity = freezed,Object? governmentalQuantity = freezed,Object? freeKilledQuantity = freezed,Object? freeQuantity = freezed,Object? chainKilledQuantity = freezed,Object? chainKilledWeight = freezed,Object? outProvinceKilledWeight = freezed,Object? outProvinceKilledQuantity = freezed,Object? exportKilledWeight = freezed,Object? exportKilledQuantity = freezed,Object? totalCommitment = freezed,Object? commitmentType = freezed,Object? totalCommitmentQuantity = freezed,Object? totalFreeCommitmentQuantity = freezed,Object? totalFreeCommitmentWeight = freezed,Object? totalKilledWeight = freezed,Object? totalAverageKilledWeight = freezed,Object? requestLeftOver = freezed,Object? hall = freezed,Object? date = freezed,Object? predicateDate = freezed,Object? chickenBreed = freezed,Object? period = freezed,Object? allowHatching = freezed,Object? state = freezed,Object? archive = freezed,Object? violation = freezed,Object? message = freezed,Object? registrar = freezed,Object? breed = freezed,Object? cityNumber = freezed,Object? cityName = freezed,Object? provinceNumber = freezed,Object? provinceName = freezed,Object? lastChange = freezed,Object? chickenAge = freezed,Object? nowAge = freezed,Object? latestHatchingChange = freezed,Object? violationReport = freezed,Object? violationMessage = freezed,Object? violationImage = freezed,Object? violationReporter = freezed,Object? violationReportDate = freezed,Object? violationReportEditor = freezed,Object? violationReportEditDate = freezed,Object? totalLosses = freezed,Object? directLosses = freezed,Object? directLossesInputer = freezed,Object? directLossesDate = freezed,Object? directLossesEditor = freezed,Object? directLossesLastEditDate = freezed,Object? endPeriodLossesInputer = freezed,Object? endPeriodLossesDate = freezed,Object? endPeriodLossesEditor = freezed,Object? endPeriodLossesLastEditDate = freezed,Object? breedingUniqueId = freezed,Object? licenceNumber = freezed,Object? temporaryTrash = freezed,Object? temporaryDeleted = freezed,Object? firstDateInputArchive = freezed,Object? secondDateInputArchive = freezed,Object? inputArchiver = freezed,Object? outputArchiveDate = freezed,Object? outputArchiver = freezed,Object? barDifferenceRequestWeight = freezed,Object? barDifferenceRequestQuantity = freezed,Object? healthCertificate = freezed,Object? samasatDischargePercentage = freezed,Object? personTypeName = freezed,Object? interactTypeName = freezed,Object? unionTypeName = freezed,Object? certId = freezed,Object? increaseQuantity = freezed,Object? tenantFullname = freezed,Object? tenantNationalCode = freezed,Object? tenantMobile = freezed,Object? tenantCity = freezed,Object? hasTenant = freezed,Object? archiveDate = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? poultry = freezed,Object? chainCompany = freezed,Object? age = freezed,Object? inspectionLosses = freezed,Object? vetFarm = freezed,Object? activeKill = freezed,Object? killingInfo = freezed,Object? freeGovernmentalInfo = freezed,Object? reportInfo = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? hasChainCompany = freezed,Object? poultryIdForeignKey = freezed,Object? poultryHatchingIdKey = freezed,Object? quantity = freezed,Object? losses = freezed,Object? leftOver = freezed,Object? killedQuantity = freezed,Object? extraKilledQuantity = freezed,Object? governmentalKilledQuantity = freezed,Object? governmentalQuantity = freezed,Object? freeKilledQuantity = freezed,Object? freeQuantity = freezed,Object? chainKilledQuantity = freezed,Object? chainKilledWeight = freezed,Object? outProvinceKilledWeight = freezed,Object? outProvinceKilledQuantity = freezed,Object? exportKilledWeight = freezed,Object? exportKilledQuantity = freezed,Object? totalCommitment = freezed,Object? commitmentType = freezed,Object? totalCommitmentQuantity = freezed,Object? totalFreeCommitmentQuantity = freezed,Object? totalFreeCommitmentWeight = freezed,Object? totalKilledWeight = freezed,Object? totalAverageKilledWeight = freezed,Object? requestLeftOver = freezed,Object? hall = freezed,Object? date = freezed,Object? predicateDate = freezed,Object? chickenBreed = freezed,Object? period = freezed,Object? allowHatching = freezed,Object? state = freezed,Object? archive = freezed,Object? violation = freezed,Object? message = freezed,Object? registrar = freezed,Object? breed = freezed,Object? cityNumber = freezed,Object? cityName = freezed,Object? provinceNumber = freezed,Object? provinceName = freezed,Object? lastChange = freezed,Object? chickenAge = freezed,Object? nowAge = freezed,Object? latestHatchingChange = freezed,Object? violationReport = freezed,Object? violationMessage = freezed,Object? violationImage = freezed,Object? violationReporter = freezed,Object? violationReportDate = freezed,Object? violationReportEditor = freezed,Object? violationReportEditDate = freezed,Object? totalLosses = freezed,Object? directLosses = freezed,Object? directLossesInputer = freezed,Object? directLossesDate = freezed,Object? directLossesEditor = freezed,Object? directLossesLastEditDate = freezed,Object? endPeriodLossesInputer = freezed,Object? endPeriodLossesDate = freezed,Object? endPeriodLossesEditor = freezed,Object? endPeriodLossesLastEditDate = freezed,Object? breedingUniqueId = freezed,Object? licenceNumber = freezed,Object? temporaryTrash = freezed,Object? temporaryDeleted = freezed,Object? firstDateInputArchive = freezed,Object? secondDateInputArchive = freezed,Object? inputArchiver = freezed,Object? outputArchiveDate = freezed,Object? outputArchiver = freezed,Object? barDifferenceRequestWeight = freezed,Object? barDifferenceRequestQuantity = freezed,Object? totalDiseaseLosses = freezed,Object? totalFlockDestruction = freezed,Object? totalNormalFlockLosses = freezed,Object? totalForceMajeureLosses = freezed,Object? totalFireLosses = freezed,Object? healthCertificate = freezed,Object? samasatDischargePercentage = freezed,Object? personTypeName = freezed,Object? interactTypeName = freezed,Object? unionTypeName = freezed,Object? certId = freezed,Object? increaseQuantity = freezed,Object? tenantFullname = freezed,Object? tenantNationalCode = freezed,Object? tenantMobile = freezed,Object? tenantCity = freezed,Object? hasTenant = freezed,Object? archiveDate = freezed,Object? unknown = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,}) { return _then(_HatchingModel( id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable as int?,poultry: freezed == poultry ? _self.poultry : poultry // ignore: cast_nullable_to_non_nullable @@ -694,6 +706,11 @@ as String?,outputArchiveDate: freezed == outputArchiveDate ? _self.outputArchive as String?,outputArchiver: freezed == outputArchiver ? _self.outputArchiver : outputArchiver // ignore: cast_nullable_to_non_nullable as String?,barDifferenceRequestWeight: freezed == barDifferenceRequestWeight ? _self.barDifferenceRequestWeight : barDifferenceRequestWeight // ignore: cast_nullable_to_non_nullable as num?,barDifferenceRequestQuantity: freezed == barDifferenceRequestQuantity ? _self.barDifferenceRequestQuantity : barDifferenceRequestQuantity // ignore: cast_nullable_to_non_nullable +as num?,totalDiseaseLosses: freezed == totalDiseaseLosses ? _self.totalDiseaseLosses : totalDiseaseLosses // ignore: cast_nullable_to_non_nullable +as num?,totalFlockDestruction: freezed == totalFlockDestruction ? _self.totalFlockDestruction : totalFlockDestruction // ignore: cast_nullable_to_non_nullable +as num?,totalNormalFlockLosses: freezed == totalNormalFlockLosses ? _self.totalNormalFlockLosses : totalNormalFlockLosses // ignore: cast_nullable_to_non_nullable +as num?,totalForceMajeureLosses: freezed == totalForceMajeureLosses ? _self.totalForceMajeureLosses : totalForceMajeureLosses // ignore: cast_nullable_to_non_nullable +as num?,totalFireLosses: freezed == totalFireLosses ? _self.totalFireLosses : totalFireLosses // ignore: cast_nullable_to_non_nullable as num?,healthCertificate: freezed == healthCertificate ? _self.healthCertificate : healthCertificate // ignore: cast_nullable_to_non_nullable as String?,samasatDischargePercentage: freezed == samasatDischargePercentage ? _self.samasatDischargePercentage : samasatDischargePercentage // ignore: cast_nullable_to_non_nullable as num?,personTypeName: freezed == personTypeName ? _self.personTypeName : personTypeName // ignore: cast_nullable_to_non_nullable @@ -707,7 +724,8 @@ as String?,tenantMobile: freezed == tenantMobile ? _self.tenantMobile : tenantMo as String?,tenantCity: freezed == tenantCity ? _self.tenantCity : tenantCity // ignore: cast_nullable_to_non_nullable as String?,hasTenant: freezed == hasTenant ? _self.hasTenant : hasTenant // ignore: cast_nullable_to_non_nullable as bool?,archiveDate: freezed == archiveDate ? _self.archiveDate : archiveDate // ignore: cast_nullable_to_non_nullable -as String?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable +as String?,unknown: freezed == unknown ? _self.unknown : unknown // ignore: cast_nullable_to_non_nullable +as bool?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable as String?,modifiedBy: freezed == modifiedBy ? _self.modifiedBy : modifiedBy // ignore: cast_nullable_to_non_nullable as String?, )); @@ -840,7 +858,7 @@ $LatestHatchingChangeCopyWith<$Res>? get latestHatchingChange { /// @nodoc mixin _$Poultry { - int? get id; PoultryUser? get user; PoultryAddress? get address; String? get key; bool? get trash; int? get ownerIdForeignKey; int? get userIdForeignKey; int? get addressIdForeignKey; bool? get hasChainCompany; int? get userBankIdForeignKey; String? get cityOperator; String? get unitName; String? get gisCode; num? get operatingLicenceCapacity; num? get numberOfHalls; bool? get tenant; bool? get hasTenant; String? get personType; String? get economicCode; String? get systemCode; String? get epidemiologicalCode; String? get breedingUniqueId; num? get totalCapacity; String? get licenceNumber; String? get healthCertificateNumber; num? get numberOfRequests; String? get hatchingDate; String? get lastPartyDate; num? get numberOfIncubators; num? get herdAgeByDay; num? get herdAgeByWeek; num? get numberOfParty; String? get communicationType; String? get cooperative; String? get dateOfRegister; String? get unitStatus; bool? get active; dynamic get identityDocuments; String? get samasatUserCode; String? get baseOrder; String? get incubationDate; num? get walletAmount; num? get city; num? get cityNumber; String? get cityName; num? get provinceNumber; String? get provinceName; int? get walletIdForeignKey; int? get poultryIdKey; num? get lat; num? get long; String? get date; num? get killingAveAge; num? get activeLeftOver; num? get killingAveCount; num? get killingAveWeight; num? get killingLiveWeight; num? get killingCarcassesWeight; num? get killingLossWeightPercent; num? get realKillingAveWeight; num? get realKillingLiveWeight; num? get realKillingCarcassesWeight; num? get realKillingLossWeightPercent; int? get interestLicenseId; bool? get orderLimit; int? get owner; int? get userBankInfo; int? get wallet; + int? get id; PoultryUser? get user; PoultryAddress? get address; String? get key; bool? get trash; int? get ownerIdForeignKey; int? get userIdForeignKey; int? get addressIdForeignKey; bool? get hasChainCompany; int? get userBankIdForeignKey; String? get cityOperator; String? get unitName; String? get gisCode; num? get operatingLicenceCapacity; num? get numberOfHalls; bool? get tenant; bool? get hasTenant; String? get personType; String? get economicCode; String? get systemCode; String? get epidemiologicalCode; String? get breedingUniqueId; num? get totalCapacity; String? get licenceNumber; String? get healthCertificateNumber; num? get numberOfRequests; String? get hatchingDate; String? get lastPartyDate; num? get numberOfIncubators; num? get herdAgeByDay; num? get herdAgeByWeek; num? get numberOfParty; String? get communicationType; String? get cooperative; String? get dateOfRegister; String? get unitStatus; bool? get active; dynamic get identityDocuments; String? get samasatUserCode; String? get baseOrder; String? get incubationDate; num? get walletAmount; num? get city; num? get cityNumber; String? get cityName; num? get provinceNumber; String? get provinceName; int? get walletIdForeignKey; int? get poultryIdKey; num? get lat; num? get long; String? get date; num? get killingAveAge; num? get activeLeftOver; num? get killingAveCount; num? get killingAveWeight; num? get killingLiveWeight; num? get killingCarcassesWeight; num? get killingLossWeightPercent; num? get realKillingAveWeight; num? get realKillingLiveWeight; num? get realKillingCarcassesWeight; num? get realKillingLossWeightPercent; String? get interestLicenseId; bool? get orderLimit; int? get owner; int? get userBankInfo; int? get wallet; /// Create a copy of Poultry /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -873,7 +891,7 @@ abstract mixin class $PoultryCopyWith<$Res> { factory $PoultryCopyWith(Poultry value, $Res Function(Poultry) _then) = _$PoultryCopyWithImpl; @useResult $Res call({ - int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, int? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet + int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, String? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet }); @@ -956,7 +974,7 @@ as num?,realKillingLiveWeight: freezed == realKillingLiveWeight ? _self.realKill as num?,realKillingCarcassesWeight: freezed == realKillingCarcassesWeight ? _self.realKillingCarcassesWeight : realKillingCarcassesWeight // ignore: cast_nullable_to_non_nullable as num?,realKillingLossWeightPercent: freezed == realKillingLossWeightPercent ? _self.realKillingLossWeightPercent : realKillingLossWeightPercent // ignore: cast_nullable_to_non_nullable as num?,interestLicenseId: freezed == interestLicenseId ? _self.interestLicenseId : interestLicenseId // ignore: cast_nullable_to_non_nullable -as int?,orderLimit: freezed == orderLimit ? _self.orderLimit : orderLimit // ignore: cast_nullable_to_non_nullable +as String?,orderLimit: freezed == orderLimit ? _self.orderLimit : orderLimit // ignore: cast_nullable_to_non_nullable as bool?,owner: freezed == owner ? _self.owner : owner // ignore: cast_nullable_to_non_nullable as int?,userBankInfo: freezed == userBankInfo ? _self.userBankInfo : userBankInfo // ignore: cast_nullable_to_non_nullable as int?,wallet: freezed == wallet ? _self.wallet : wallet // ignore: cast_nullable_to_non_nullable @@ -1069,7 +1087,7 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, int? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, String? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _Poultry() when $default != null: return $default(_that.id,_that.user,_that.address,_that.key,_that.trash,_that.ownerIdForeignKey,_that.userIdForeignKey,_that.addressIdForeignKey,_that.hasChainCompany,_that.userBankIdForeignKey,_that.cityOperator,_that.unitName,_that.gisCode,_that.operatingLicenceCapacity,_that.numberOfHalls,_that.tenant,_that.hasTenant,_that.personType,_that.economicCode,_that.systemCode,_that.epidemiologicalCode,_that.breedingUniqueId,_that.totalCapacity,_that.licenceNumber,_that.healthCertificateNumber,_that.numberOfRequests,_that.hatchingDate,_that.lastPartyDate,_that.numberOfIncubators,_that.herdAgeByDay,_that.herdAgeByWeek,_that.numberOfParty,_that.communicationType,_that.cooperative,_that.dateOfRegister,_that.unitStatus,_that.active,_that.identityDocuments,_that.samasatUserCode,_that.baseOrder,_that.incubationDate,_that.walletAmount,_that.city,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.walletIdForeignKey,_that.poultryIdKey,_that.lat,_that.long,_that.date,_that.killingAveAge,_that.activeLeftOver,_that.killingAveCount,_that.killingAveWeight,_that.killingLiveWeight,_that.killingCarcassesWeight,_that.killingLossWeightPercent,_that.realKillingAveWeight,_that.realKillingLiveWeight,_that.realKillingCarcassesWeight,_that.realKillingLossWeightPercent,_that.interestLicenseId,_that.orderLimit,_that.owner,_that.userBankInfo,_that.wallet);case _: @@ -1090,7 +1108,7 @@ return $default(_that.id,_that.user,_that.address,_that.key,_that.trash,_that.ow /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, int? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, String? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet) $default,) {final _that = this; switch (_that) { case _Poultry(): return $default(_that.id,_that.user,_that.address,_that.key,_that.trash,_that.ownerIdForeignKey,_that.userIdForeignKey,_that.addressIdForeignKey,_that.hasChainCompany,_that.userBankIdForeignKey,_that.cityOperator,_that.unitName,_that.gisCode,_that.operatingLicenceCapacity,_that.numberOfHalls,_that.tenant,_that.hasTenant,_that.personType,_that.economicCode,_that.systemCode,_that.epidemiologicalCode,_that.breedingUniqueId,_that.totalCapacity,_that.licenceNumber,_that.healthCertificateNumber,_that.numberOfRequests,_that.hatchingDate,_that.lastPartyDate,_that.numberOfIncubators,_that.herdAgeByDay,_that.herdAgeByWeek,_that.numberOfParty,_that.communicationType,_that.cooperative,_that.dateOfRegister,_that.unitStatus,_that.active,_that.identityDocuments,_that.samasatUserCode,_that.baseOrder,_that.incubationDate,_that.walletAmount,_that.city,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.walletIdForeignKey,_that.poultryIdKey,_that.lat,_that.long,_that.date,_that.killingAveAge,_that.activeLeftOver,_that.killingAveCount,_that.killingAveWeight,_that.killingLiveWeight,_that.killingCarcassesWeight,_that.killingLossWeightPercent,_that.realKillingAveWeight,_that.realKillingLiveWeight,_that.realKillingCarcassesWeight,_that.realKillingLossWeightPercent,_that.interestLicenseId,_that.orderLimit,_that.owner,_that.userBankInfo,_that.wallet);case _: @@ -1110,7 +1128,7 @@ return $default(_that.id,_that.user,_that.address,_that.key,_that.trash,_that.ow /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, int? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, String? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet)? $default,) {final _that = this; switch (_that) { case _Poultry() when $default != null: return $default(_that.id,_that.user,_that.address,_that.key,_that.trash,_that.ownerIdForeignKey,_that.userIdForeignKey,_that.addressIdForeignKey,_that.hasChainCompany,_that.userBankIdForeignKey,_that.cityOperator,_that.unitName,_that.gisCode,_that.operatingLicenceCapacity,_that.numberOfHalls,_that.tenant,_that.hasTenant,_that.personType,_that.economicCode,_that.systemCode,_that.epidemiologicalCode,_that.breedingUniqueId,_that.totalCapacity,_that.licenceNumber,_that.healthCertificateNumber,_that.numberOfRequests,_that.hatchingDate,_that.lastPartyDate,_that.numberOfIncubators,_that.herdAgeByDay,_that.herdAgeByWeek,_that.numberOfParty,_that.communicationType,_that.cooperative,_that.dateOfRegister,_that.unitStatus,_that.active,_that.identityDocuments,_that.samasatUserCode,_that.baseOrder,_that.incubationDate,_that.walletAmount,_that.city,_that.cityNumber,_that.cityName,_that.provinceNumber,_that.provinceName,_that.walletIdForeignKey,_that.poultryIdKey,_that.lat,_that.long,_that.date,_that.killingAveAge,_that.activeLeftOver,_that.killingAveCount,_that.killingAveWeight,_that.killingLiveWeight,_that.killingCarcassesWeight,_that.killingLossWeightPercent,_that.realKillingAveWeight,_that.realKillingLiveWeight,_that.realKillingCarcassesWeight,_that.realKillingLossWeightPercent,_that.interestLicenseId,_that.orderLimit,_that.owner,_that.userBankInfo,_that.wallet);case _: @@ -1191,7 +1209,7 @@ class _Poultry implements Poultry { @override final num? realKillingLiveWeight; @override final num? realKillingCarcassesWeight; @override final num? realKillingLossWeightPercent; -@override final int? interestLicenseId; +@override final String? interestLicenseId; @override final bool? orderLimit; @override final int? owner; @override final int? userBankInfo; @@ -1230,7 +1248,7 @@ abstract mixin class _$PoultryCopyWith<$Res> implements $PoultryCopyWith<$Res> { factory _$PoultryCopyWith(_Poultry value, $Res Function(_Poultry) _then) = __$PoultryCopyWithImpl; @override @useResult $Res call({ - int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, int? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet + int? id, PoultryUser? user, PoultryAddress? address, String? key, bool? trash, int? ownerIdForeignKey, int? userIdForeignKey, int? addressIdForeignKey, bool? hasChainCompany, int? userBankIdForeignKey, String? cityOperator, String? unitName, String? gisCode, num? operatingLicenceCapacity, num? numberOfHalls, bool? tenant, bool? hasTenant, String? personType, String? economicCode, String? systemCode, String? epidemiologicalCode, String? breedingUniqueId, num? totalCapacity, String? licenceNumber, String? healthCertificateNumber, num? numberOfRequests, String? hatchingDate, String? lastPartyDate, num? numberOfIncubators, num? herdAgeByDay, num? herdAgeByWeek, num? numberOfParty, String? communicationType, String? cooperative, String? dateOfRegister, String? unitStatus, bool? active, dynamic identityDocuments, String? samasatUserCode, String? baseOrder, String? incubationDate, num? walletAmount, num? city, num? cityNumber, String? cityName, num? provinceNumber, String? provinceName, int? walletIdForeignKey, int? poultryIdKey, num? lat, num? long, String? date, num? killingAveAge, num? activeLeftOver, num? killingAveCount, num? killingAveWeight, num? killingLiveWeight, num? killingCarcassesWeight, num? killingLossWeightPercent, num? realKillingAveWeight, num? realKillingLiveWeight, num? realKillingCarcassesWeight, num? realKillingLossWeightPercent, String? interestLicenseId, bool? orderLimit, int? owner, int? userBankInfo, int? wallet }); @@ -1313,7 +1331,7 @@ as num?,realKillingLiveWeight: freezed == realKillingLiveWeight ? _self.realKill as num?,realKillingCarcassesWeight: freezed == realKillingCarcassesWeight ? _self.realKillingCarcassesWeight : realKillingCarcassesWeight // ignore: cast_nullable_to_non_nullable as num?,realKillingLossWeightPercent: freezed == realKillingLossWeightPercent ? _self.realKillingLossWeightPercent : realKillingLossWeightPercent // ignore: cast_nullable_to_non_nullable as num?,interestLicenseId: freezed == interestLicenseId ? _self.interestLicenseId : interestLicenseId // ignore: cast_nullable_to_non_nullable -as int?,orderLimit: freezed == orderLimit ? _self.orderLimit : orderLimit // ignore: cast_nullable_to_non_nullable +as String?,orderLimit: freezed == orderLimit ? _self.orderLimit : orderLimit // ignore: cast_nullable_to_non_nullable as bool?,owner: freezed == owner ? _self.owner : owner // ignore: cast_nullable_to_non_nullable as int?,userBankInfo: freezed == userBankInfo ? _self.userBankInfo : userBankInfo // ignore: cast_nullable_to_non_nullable as int?,wallet: freezed == wallet ? _self.wallet : wallet // ignore: cast_nullable_to_non_nullable diff --git a/packages/chicken/lib/data/models/response/hatching/hatching_models.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.g.dart similarity index 97% rename from packages/chicken/lib/data/models/response/hatching/hatching_models.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.g.dart index 11c2741..2d61411 100644 --- a/packages/chicken/lib/data/models/response/hatching/hatching_models.g.dart +++ b/packages/chicken/lib/features/poultry_science/data/model/response/hatching/hatching_models.g.dart @@ -126,6 +126,11 @@ _HatchingModel _$HatchingModelFromJson( outputArchiver: json['output_archiver'] as String?, barDifferenceRequestWeight: json['bar_difference_request_weight'] as num?, barDifferenceRequestQuantity: json['bar_difference_request_quantity'] as num?, + totalDiseaseLosses: json['total_disease_losses'] as num?, + totalFlockDestruction: json['total_flock_destruction'] as num?, + totalNormalFlockLosses: json['total_normal_flock_losses'] as num?, + totalForceMajeureLosses: json['total_force_majeure_losses'] as num?, + totalFireLosses: json['total_fire_losses'] as num?, healthCertificate: json['health_certificate'] as String?, samasatDischargePercentage: json['samasat_discharge_percentage'] as num?, personTypeName: json['person_type_name'] as String?, @@ -139,6 +144,7 @@ _HatchingModel _$HatchingModelFromJson( tenantCity: json['tenant_city'] as String?, hasTenant: json['has_tenant'] as bool?, archiveDate: json['archive_date'] as String?, + unknown: json['unknown'] as bool?, createdBy: json['created_by'] as String?, modifiedBy: json['modified_by'] as String?, ); @@ -233,6 +239,11 @@ Map _$HatchingModelToJson(_HatchingModel instance) => 'output_archiver': instance.outputArchiver, 'bar_difference_request_weight': instance.barDifferenceRequestWeight, 'bar_difference_request_quantity': instance.barDifferenceRequestQuantity, + 'total_disease_losses': instance.totalDiseaseLosses, + 'total_flock_destruction': instance.totalFlockDestruction, + 'total_normal_flock_losses': instance.totalNormalFlockLosses, + 'total_force_majeure_losses': instance.totalForceMajeureLosses, + 'total_fire_losses': instance.totalFireLosses, 'health_certificate': instance.healthCertificate, 'samasat_discharge_percentage': instance.samasatDischargePercentage, 'person_type_name': instance.personTypeName, @@ -246,6 +257,7 @@ Map _$HatchingModelToJson(_HatchingModel instance) => 'tenant_city': instance.tenantCity, 'has_tenant': instance.hasTenant, 'archive_date': instance.archiveDate, + 'unknown': instance.unknown, 'created_by': instance.createdBy, 'modified_by': instance.modifiedBy, }; @@ -319,7 +331,7 @@ _Poultry _$PoultryFromJson(Map json) => _Poultry( realKillingCarcassesWeight: json['real_killing_carcasses_weight'] as num?, realKillingLossWeightPercent: json['real_killing_loss_weight_percent'] as num?, - interestLicenseId: (json['interest_license_id'] as num?)?.toInt(), + interestLicenseId: json['interest_license_id'] as String?, orderLimit: json['order_limit'] as bool?, owner: (json['owner'] as num?)?.toInt(), userBankInfo: (json['user_bank_info'] as num?)?.toInt(), diff --git a/packages/chicken/lib/data/models/response/hatching_report/hatching_report.dart b/packages/chicken/lib/features/poultry_science/data/model/response/hatching_report/hatching_report.dart similarity index 100% rename from packages/chicken/lib/data/models/response/hatching_report/hatching_report.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/hatching_report/hatching_report.dart diff --git a/packages/chicken/lib/data/models/response/hatching_report/hatching_report.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/hatching_report/hatching_report.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/hatching_report/hatching_report.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/hatching_report/hatching_report.freezed.dart diff --git a/packages/chicken/lib/data/models/response/hatching_report/hatching_report.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/hatching_report/hatching_report.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/hatching_report/hatching_report.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/hatching_report/hatching_report.g.dart diff --git a/packages/chicken/lib/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart b/packages/chicken/lib/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart diff --git a/packages/chicken/lib/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.g.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_poultry/kill_house_poultry.dart b/packages/chicken/lib/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_poultry/kill_house_poultry.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_poultry/kill_house_poultry.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_poultry/kill_house_poultry.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.freezed.dart diff --git a/packages/chicken/lib/data/models/response/kill_house_poultry/kill_house_poultry.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_house_poultry/kill_house_poultry.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.g.dart diff --git a/packages/chicken/lib/data/models/response/kill_request_poultry/kill_request_poultry.dart b/packages/chicken/lib/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_request_poultry/kill_request_poultry.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart diff --git a/packages/chicken/lib/data/models/response/kill_request_poultry/kill_request_poultry.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_request_poultry/kill_request_poultry.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.freezed.dart diff --git a/packages/chicken/lib/data/models/response/kill_request_poultry/kill_request_poultry.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/kill_request_poultry/kill_request_poultry.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.g.dart diff --git a/packages/chicken/lib/data/models/poultry_export/poultry_export.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_export/poultry_export.dart similarity index 100% rename from packages/chicken/lib/data/models/poultry_export/poultry_export.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_export/poultry_export.dart diff --git a/packages/chicken/lib/data/models/poultry_export/poultry_export.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_export/poultry_export.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/poultry_export/poultry_export.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_export/poultry_export.freezed.dart diff --git a/packages/chicken/lib/data/models/poultry_export/poultry_export.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_export/poultry_export.g.dart similarity index 100% rename from packages/chicken/lib/data/models/poultry_export/poultry_export.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_export/poultry_export.g.dart diff --git a/packages/chicken/lib/data/models/response/poultry_farm/poultry_farm.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_farm/poultry_farm.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart diff --git a/packages/chicken/lib/data/models/response/poultry_farm/poultry_farm.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_farm/poultry_farm.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_farm/poultry_farm.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_farm/poultry_farm.freezed.dart diff --git a/packages/chicken/lib/data/models/response/poultry_farm/poultry_farm.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_farm/poultry_farm.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_farm/poultry_farm.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_farm/poultry_farm.g.dart diff --git a/packages/chicken/lib/data/models/response/poultry_hatching/poultry_hatching.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_hatching/poultry_hatching.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart diff --git a/packages/chicken/lib/data/models/response/poultry_hatching/poultry_hatching.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_hatching/poultry_hatching.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.freezed.dart diff --git a/packages/chicken/lib/data/models/response/poultry_hatching/poultry_hatching.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_hatching/poultry_hatching.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.g.dart diff --git a/packages/chicken/lib/data/models/response/poultry_order/poultry_order.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_order/poultry_order.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_order/poultry_order.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_order/poultry_order.dart diff --git a/packages/chicken/lib/data/models/response/poultry_order/poultry_order.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_order/poultry_order.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_order/poultry_order.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_order/poultry_order.freezed.dart diff --git a/packages/chicken/lib/data/models/response/poultry_order/poultry_order.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_order/poultry_order.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/poultry_order/poultry_order.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/poultry_order/poultry_order.g.dart diff --git a/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart new file mode 100644 index 0000000..fd7853c --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart @@ -0,0 +1,207 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; +import '../hatching/hatching_models.dart'; + +part 'poultry_science_report.freezed.dart'; +part 'poultry_science_report.g.dart'; + +@freezed +abstract class PoultryScienceReport with _$PoultryScienceReport { + const factory PoultryScienceReport({ + int? id, + PoultryScienceRef? poultryScience, + HatchingModel? hatching, + UserRef? user, + String? key, + String? createDate, + String? modifyDate, + bool? trash, + String? date, + String? image, + num? lat, + num? log, + String? reporterFullname, + String? reporterMobile, + String? reporterRole, + String? state, + num? realQuantityAi, + String? messageAi, + num? realQuantity, + String? message, + String? messageRegistererFullname, + String? messageRegistererMobile, + String? messageRegistererRole, + ReportInformation? reportInformation, + String? createdBy, + String? modifiedBy, + }) = _PoultryScienceReport; + + factory PoultryScienceReport.fromJson(Map json) => + _$PoultryScienceReportFromJson(json); +} + +@freezed +abstract class PoultryScienceRef with _$PoultryScienceRef { + const factory PoultryScienceRef({ + int? id, + UserWithCity? user, + String? key, + String? createDate, + String? modifyDate, + bool? trash, + String? engineeringCode, + String? createdBy, + String? modifiedBy, + List? poultry, + }) = _PoultryScienceRef; + + factory PoultryScienceRef.fromJson(Map json) => + _$PoultryScienceRefFromJson(json); +} + +@freezed +abstract class UserRef with _$UserRef { + const factory UserRef({String? fullname, String? mobile, CityRef? city}) = + _UserRef; + + factory UserRef.fromJson(Map json) => + _$UserRefFromJson(json); +} + +@freezed +abstract class UserWithCity with _$UserWithCity { + const factory UserWithCity({ + String? fullname, + String? mobile, + CityRef? city, + }) = _UserWithCity; + + factory UserWithCity.fromJson(Map json) => + _$UserWithCityFromJson(json); +} + +@freezed +abstract class ReportInformation with _$ReportInformation { + const factory ReportInformation({ + HrInfo? hr, + Casualties? casualties, + Facilities? facilities, + InputStatus? inputStatus, + String? inspectionNotes, + String? inspectionStatus, + TechnicalOfficer? technicalOfficer, + InfrastructureEnergy? infrastructureEnergy, + GeneralConditionHall? generalConditionHall, + }) = _ReportInformation; + + factory ReportInformation.fromJson(Map json) => + _$ReportInformationFromJson(json); +} + +@freezed +abstract class HrInfo with _$HrInfo { + const factory HrInfo({ + bool? trained, + String? contractStatus, + num? numberEmployed, + num? numberIndigenous, + num? numberNonIndigenous, + }) = _HrInfo; + + factory HrInfo.fromJson(Map json) => _$HrInfoFromJson(json); +} + +@freezed +abstract class Casualties with _$Casualties { + const factory Casualties({ + List? images, + String? typeDisease, + num? normalLosses, + bool? samplingDone, + String? typeSampling, + num? abnormalLosses, + String? sourceOfHatching, + String? causeAbnormalLosses, + }) = _Casualties; + + factory Casualties.fromJson(Map json) => + _$CasualtiesFromJson(json); +} + +@freezed +abstract class Facilities with _$Facilities { + const factory Facilities({ + String? date, + num? amount, + bool? hasFacilities, + String? repaymentStatus, + String? typeOfFacility, + String? requestFacilities, + }) = _Facilities; + + factory Facilities.fromJson(Map json) => + _$FacilitiesFromJson(json); +} + +@freezed +abstract class InputStatus with _$InputStatus { + const factory InputStatus({ + List? images, + String? gradeGrain, + String? companyName, + String? inputStatus, + String? trackingCode, + String? typeOfGrain, + String? inventoryUntilVisit, + String? inventoryInWarehouse, + }) = _InputStatus; + + factory InputStatus.fromJson(Map json) => + _$InputStatusFromJson(json); +} + +@freezed +abstract class TechnicalOfficer with _$TechnicalOfficer { + const factory TechnicalOfficer({ + String? technicalHealthOfficer, + String? technicalEngineeringOfficer, + }) = _TechnicalOfficer; + + factory TechnicalOfficer.fromJson(Map json) => + _$TechnicalOfficerFromJson(json); +} + +@freezed +abstract class InfrastructureEnergy with _$InfrastructureEnergy { + const factory InfrastructureEnergy({ + String? fuelType, + String? generatorType, + String? powerCutHour, + String? generatorCount, + String? generatorModel, + String? additionalNotes, + String? generatorCapacity, + String? powerCutDuration, + String? generatorPerformance, + bool? hasPowerCutHistory, + String? emergencyFuelInventory, + }) = _InfrastructureEnergy; + + factory InfrastructureEnergy.fromJson(Map json) => + _$InfrastructureEnergyFromJson(json); +} + +@freezed +abstract class GeneralConditionHall with _$GeneralConditionHall { + const factory GeneralConditionHall({ + List? images, + String? temperature, + String? bedCondition, + String? healthStatus, + String? ventilationStatus, + String? drinkingWaterSource, + String? drinkingWaterQuality, + }) = _GeneralConditionHall; + + factory GeneralConditionHall.fromJson(Map json) => + _$GeneralConditionHallFromJson(json); +} diff --git a/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.freezed.dart new file mode 100644 index 0000000..279ec34 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.freezed.dart @@ -0,0 +1,3796 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'poultry_science_report.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +// dart format off +T _$identity(T value) => value; + +/// @nodoc +mixin _$PoultryScienceReport { + + int? get id; PoultryScienceRef? get poultryScience; HatchingModel? get hatching; UserRef? get user; String? get key; String? get createDate; String? get modifyDate; bool? get trash; String? get date; String? get image; num? get lat; num? get log; String? get reporterFullname; String? get reporterMobile; String? get reporterRole; String? get state; num? get realQuantityAi; String? get messageAi; num? get realQuantity; String? get message; String? get messageRegistererFullname; String? get messageRegistererMobile; String? get messageRegistererRole; ReportInformation? get reportInformation; String? get createdBy; String? get modifiedBy; +/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$PoultryScienceReportCopyWith get copyWith => _$PoultryScienceReportCopyWithImpl(this as PoultryScienceReport, _$identity); + + /// Serializes this PoultryScienceReport to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PoultryScienceReport&&(identical(other.id, id) || other.id == id)&&(identical(other.poultryScience, poultryScience) || other.poultryScience == poultryScience)&&(identical(other.hatching, hatching) || other.hatching == hatching)&&(identical(other.user, user) || other.user == user)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.date, date) || other.date == date)&&(identical(other.image, image) || other.image == image)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.log, log) || other.log == log)&&(identical(other.reporterFullname, reporterFullname) || other.reporterFullname == reporterFullname)&&(identical(other.reporterMobile, reporterMobile) || other.reporterMobile == reporterMobile)&&(identical(other.reporterRole, reporterRole) || other.reporterRole == reporterRole)&&(identical(other.state, state) || other.state == state)&&(identical(other.realQuantityAi, realQuantityAi) || other.realQuantityAi == realQuantityAi)&&(identical(other.messageAi, messageAi) || other.messageAi == messageAi)&&(identical(other.realQuantity, realQuantity) || other.realQuantity == realQuantity)&&(identical(other.message, message) || other.message == message)&&(identical(other.messageRegistererFullname, messageRegistererFullname) || other.messageRegistererFullname == messageRegistererFullname)&&(identical(other.messageRegistererMobile, messageRegistererMobile) || other.messageRegistererMobile == messageRegistererMobile)&&(identical(other.messageRegistererRole, messageRegistererRole) || other.messageRegistererRole == messageRegistererRole)&&(identical(other.reportInformation, reportInformation) || other.reportInformation == reportInformation)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hashAll([runtimeType,id,poultryScience,hatching,user,key,createDate,modifyDate,trash,date,image,lat,log,reporterFullname,reporterMobile,reporterRole,state,realQuantityAi,messageAi,realQuantity,message,messageRegistererFullname,messageRegistererMobile,messageRegistererRole,reportInformation,createdBy,modifiedBy]); + +@override +String toString() { + return 'PoultryScienceReport(id: $id, poultryScience: $poultryScience, hatching: $hatching, user: $user, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, date: $date, image: $image, lat: $lat, log: $log, reporterFullname: $reporterFullname, reporterMobile: $reporterMobile, reporterRole: $reporterRole, state: $state, realQuantityAi: $realQuantityAi, messageAi: $messageAi, realQuantity: $realQuantity, message: $message, messageRegistererFullname: $messageRegistererFullname, messageRegistererMobile: $messageRegistererMobile, messageRegistererRole: $messageRegistererRole, reportInformation: $reportInformation, createdBy: $createdBy, modifiedBy: $modifiedBy)'; +} + + +} + +/// @nodoc +abstract mixin class $PoultryScienceReportCopyWith<$Res> { + factory $PoultryScienceReportCopyWith(PoultryScienceReport value, $Res Function(PoultryScienceReport) _then) = _$PoultryScienceReportCopyWithImpl; +@useResult +$Res call({ + int? id, PoultryScienceRef? poultryScience, HatchingModel? hatching, UserRef? user, String? key, String? createDate, String? modifyDate, bool? trash, String? date, String? image, num? lat, num? log, String? reporterFullname, String? reporterMobile, String? reporterRole, String? state, num? realQuantityAi, String? messageAi, num? realQuantity, String? message, String? messageRegistererFullname, String? messageRegistererMobile, String? messageRegistererRole, ReportInformation? reportInformation, String? createdBy, String? modifiedBy +}); + + +$PoultryScienceRefCopyWith<$Res>? get poultryScience;$HatchingModelCopyWith<$Res>? get hatching;$UserRefCopyWith<$Res>? get user;$ReportInformationCopyWith<$Res>? get reportInformation; + +} +/// @nodoc +class _$PoultryScienceReportCopyWithImpl<$Res> + implements $PoultryScienceReportCopyWith<$Res> { + _$PoultryScienceReportCopyWithImpl(this._self, this._then); + + final PoultryScienceReport _self; + final $Res Function(PoultryScienceReport) _then; + +/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? poultryScience = freezed,Object? hatching = freezed,Object? user = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? date = freezed,Object? image = freezed,Object? lat = freezed,Object? log = freezed,Object? reporterFullname = freezed,Object? reporterMobile = freezed,Object? reporterRole = freezed,Object? state = freezed,Object? realQuantityAi = freezed,Object? messageAi = freezed,Object? realQuantity = freezed,Object? message = freezed,Object? messageRegistererFullname = freezed,Object? messageRegistererMobile = freezed,Object? messageRegistererRole = freezed,Object? reportInformation = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,}) { + return _then(_self.copyWith( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int?,poultryScience: freezed == poultryScience ? _self.poultryScience : poultryScience // ignore: cast_nullable_to_non_nullable +as PoultryScienceRef?,hatching: freezed == hatching ? _self.hatching : hatching // ignore: cast_nullable_to_non_nullable +as HatchingModel?,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserRef?,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable +as String?,createDate: freezed == createDate ? _self.createDate : createDate // ignore: cast_nullable_to_non_nullable +as String?,modifyDate: freezed == modifyDate ? _self.modifyDate : modifyDate // ignore: cast_nullable_to_non_nullable +as String?,trash: freezed == trash ? _self.trash : trash // ignore: cast_nullable_to_non_nullable +as bool?,date: freezed == date ? _self.date : date // ignore: cast_nullable_to_non_nullable +as String?,image: freezed == image ? _self.image : image // ignore: cast_nullable_to_non_nullable +as String?,lat: freezed == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable +as num?,log: freezed == log ? _self.log : log // ignore: cast_nullable_to_non_nullable +as num?,reporterFullname: freezed == reporterFullname ? _self.reporterFullname : reporterFullname // ignore: cast_nullable_to_non_nullable +as String?,reporterMobile: freezed == reporterMobile ? _self.reporterMobile : reporterMobile // ignore: cast_nullable_to_non_nullable +as String?,reporterRole: freezed == reporterRole ? _self.reporterRole : reporterRole // ignore: cast_nullable_to_non_nullable +as String?,state: freezed == state ? _self.state : state // ignore: cast_nullable_to_non_nullable +as String?,realQuantityAi: freezed == realQuantityAi ? _self.realQuantityAi : realQuantityAi // ignore: cast_nullable_to_non_nullable +as num?,messageAi: freezed == messageAi ? _self.messageAi : messageAi // ignore: cast_nullable_to_non_nullable +as String?,realQuantity: freezed == realQuantity ? _self.realQuantity : realQuantity // ignore: cast_nullable_to_non_nullable +as num?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,messageRegistererFullname: freezed == messageRegistererFullname ? _self.messageRegistererFullname : messageRegistererFullname // ignore: cast_nullable_to_non_nullable +as String?,messageRegistererMobile: freezed == messageRegistererMobile ? _self.messageRegistererMobile : messageRegistererMobile // ignore: cast_nullable_to_non_nullable +as String?,messageRegistererRole: freezed == messageRegistererRole ? _self.messageRegistererRole : messageRegistererRole // ignore: cast_nullable_to_non_nullable +as String?,reportInformation: freezed == reportInformation ? _self.reportInformation : reportInformation // ignore: cast_nullable_to_non_nullable +as ReportInformation?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable +as String?,modifiedBy: freezed == modifiedBy ? _self.modifiedBy : modifiedBy // ignore: cast_nullable_to_non_nullable +as String?, + )); +} +/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$PoultryScienceRefCopyWith<$Res>? get poultryScience { + if (_self.poultryScience == null) { + return null; + } + + return $PoultryScienceRefCopyWith<$Res>(_self.poultryScience!, (value) { + return _then(_self.copyWith(poultryScience: value)); + }); +}/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$HatchingModelCopyWith<$Res>? get hatching { + if (_self.hatching == null) { + return null; + } + + return $HatchingModelCopyWith<$Res>(_self.hatching!, (value) { + return _then(_self.copyWith(hatching: value)); + }); +}/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserRefCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserRefCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +}/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$ReportInformationCopyWith<$Res>? get reportInformation { + if (_self.reportInformation == null) { + return null; + } + + return $ReportInformationCopyWith<$Res>(_self.reportInformation!, (value) { + return _then(_self.copyWith(reportInformation: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [PoultryScienceReport]. +extension PoultryScienceReportPatterns on PoultryScienceReport { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _PoultryScienceReport value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _PoultryScienceReport() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _PoultryScienceReport value) $default,){ +final _that = this; +switch (_that) { +case _PoultryScienceReport(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _PoultryScienceReport value)? $default,){ +final _that = this; +switch (_that) { +case _PoultryScienceReport() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( int? id, PoultryScienceRef? poultryScience, HatchingModel? hatching, UserRef? user, String? key, String? createDate, String? modifyDate, bool? trash, String? date, String? image, num? lat, num? log, String? reporterFullname, String? reporterMobile, String? reporterRole, String? state, num? realQuantityAi, String? messageAi, num? realQuantity, String? message, String? messageRegistererFullname, String? messageRegistererMobile, String? messageRegistererRole, ReportInformation? reportInformation, String? createdBy, String? modifiedBy)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _PoultryScienceReport() when $default != null: +return $default(_that.id,_that.poultryScience,_that.hatching,_that.user,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.date,_that.image,_that.lat,_that.log,_that.reporterFullname,_that.reporterMobile,_that.reporterRole,_that.state,_that.realQuantityAi,_that.messageAi,_that.realQuantity,_that.message,_that.messageRegistererFullname,_that.messageRegistererMobile,_that.messageRegistererRole,_that.reportInformation,_that.createdBy,_that.modifiedBy);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( int? id, PoultryScienceRef? poultryScience, HatchingModel? hatching, UserRef? user, String? key, String? createDate, String? modifyDate, bool? trash, String? date, String? image, num? lat, num? log, String? reporterFullname, String? reporterMobile, String? reporterRole, String? state, num? realQuantityAi, String? messageAi, num? realQuantity, String? message, String? messageRegistererFullname, String? messageRegistererMobile, String? messageRegistererRole, ReportInformation? reportInformation, String? createdBy, String? modifiedBy) $default,) {final _that = this; +switch (_that) { +case _PoultryScienceReport(): +return $default(_that.id,_that.poultryScience,_that.hatching,_that.user,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.date,_that.image,_that.lat,_that.log,_that.reporterFullname,_that.reporterMobile,_that.reporterRole,_that.state,_that.realQuantityAi,_that.messageAi,_that.realQuantity,_that.message,_that.messageRegistererFullname,_that.messageRegistererMobile,_that.messageRegistererRole,_that.reportInformation,_that.createdBy,_that.modifiedBy);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( int? id, PoultryScienceRef? poultryScience, HatchingModel? hatching, UserRef? user, String? key, String? createDate, String? modifyDate, bool? trash, String? date, String? image, num? lat, num? log, String? reporterFullname, String? reporterMobile, String? reporterRole, String? state, num? realQuantityAi, String? messageAi, num? realQuantity, String? message, String? messageRegistererFullname, String? messageRegistererMobile, String? messageRegistererRole, ReportInformation? reportInformation, String? createdBy, String? modifiedBy)? $default,) {final _that = this; +switch (_that) { +case _PoultryScienceReport() when $default != null: +return $default(_that.id,_that.poultryScience,_that.hatching,_that.user,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.date,_that.image,_that.lat,_that.log,_that.reporterFullname,_that.reporterMobile,_that.reporterRole,_that.state,_that.realQuantityAi,_that.messageAi,_that.realQuantity,_that.message,_that.messageRegistererFullname,_that.messageRegistererMobile,_that.messageRegistererRole,_that.reportInformation,_that.createdBy,_that.modifiedBy);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _PoultryScienceReport implements PoultryScienceReport { + const _PoultryScienceReport({this.id, this.poultryScience, this.hatching, this.user, this.key, this.createDate, this.modifyDate, this.trash, this.date, this.image, this.lat, this.log, this.reporterFullname, this.reporterMobile, this.reporterRole, this.state, this.realQuantityAi, this.messageAi, this.realQuantity, this.message, this.messageRegistererFullname, this.messageRegistererMobile, this.messageRegistererRole, this.reportInformation, this.createdBy, this.modifiedBy}); + factory _PoultryScienceReport.fromJson(Map json) => _$PoultryScienceReportFromJson(json); + +@override final int? id; +@override final PoultryScienceRef? poultryScience; +@override final HatchingModel? hatching; +@override final UserRef? user; +@override final String? key; +@override final String? createDate; +@override final String? modifyDate; +@override final bool? trash; +@override final String? date; +@override final String? image; +@override final num? lat; +@override final num? log; +@override final String? reporterFullname; +@override final String? reporterMobile; +@override final String? reporterRole; +@override final String? state; +@override final num? realQuantityAi; +@override final String? messageAi; +@override final num? realQuantity; +@override final String? message; +@override final String? messageRegistererFullname; +@override final String? messageRegistererMobile; +@override final String? messageRegistererRole; +@override final ReportInformation? reportInformation; +@override final String? createdBy; +@override final String? modifiedBy; + +/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$PoultryScienceReportCopyWith<_PoultryScienceReport> get copyWith => __$PoultryScienceReportCopyWithImpl<_PoultryScienceReport>(this, _$identity); + +@override +Map toJson() { + return _$PoultryScienceReportToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _PoultryScienceReport&&(identical(other.id, id) || other.id == id)&&(identical(other.poultryScience, poultryScience) || other.poultryScience == poultryScience)&&(identical(other.hatching, hatching) || other.hatching == hatching)&&(identical(other.user, user) || other.user == user)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.date, date) || other.date == date)&&(identical(other.image, image) || other.image == image)&&(identical(other.lat, lat) || other.lat == lat)&&(identical(other.log, log) || other.log == log)&&(identical(other.reporterFullname, reporterFullname) || other.reporterFullname == reporterFullname)&&(identical(other.reporterMobile, reporterMobile) || other.reporterMobile == reporterMobile)&&(identical(other.reporterRole, reporterRole) || other.reporterRole == reporterRole)&&(identical(other.state, state) || other.state == state)&&(identical(other.realQuantityAi, realQuantityAi) || other.realQuantityAi == realQuantityAi)&&(identical(other.messageAi, messageAi) || other.messageAi == messageAi)&&(identical(other.realQuantity, realQuantity) || other.realQuantity == realQuantity)&&(identical(other.message, message) || other.message == message)&&(identical(other.messageRegistererFullname, messageRegistererFullname) || other.messageRegistererFullname == messageRegistererFullname)&&(identical(other.messageRegistererMobile, messageRegistererMobile) || other.messageRegistererMobile == messageRegistererMobile)&&(identical(other.messageRegistererRole, messageRegistererRole) || other.messageRegistererRole == messageRegistererRole)&&(identical(other.reportInformation, reportInformation) || other.reportInformation == reportInformation)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hashAll([runtimeType,id,poultryScience,hatching,user,key,createDate,modifyDate,trash,date,image,lat,log,reporterFullname,reporterMobile,reporterRole,state,realQuantityAi,messageAi,realQuantity,message,messageRegistererFullname,messageRegistererMobile,messageRegistererRole,reportInformation,createdBy,modifiedBy]); + +@override +String toString() { + return 'PoultryScienceReport(id: $id, poultryScience: $poultryScience, hatching: $hatching, user: $user, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, date: $date, image: $image, lat: $lat, log: $log, reporterFullname: $reporterFullname, reporterMobile: $reporterMobile, reporterRole: $reporterRole, state: $state, realQuantityAi: $realQuantityAi, messageAi: $messageAi, realQuantity: $realQuantity, message: $message, messageRegistererFullname: $messageRegistererFullname, messageRegistererMobile: $messageRegistererMobile, messageRegistererRole: $messageRegistererRole, reportInformation: $reportInformation, createdBy: $createdBy, modifiedBy: $modifiedBy)'; +} + + +} + +/// @nodoc +abstract mixin class _$PoultryScienceReportCopyWith<$Res> implements $PoultryScienceReportCopyWith<$Res> { + factory _$PoultryScienceReportCopyWith(_PoultryScienceReport value, $Res Function(_PoultryScienceReport) _then) = __$PoultryScienceReportCopyWithImpl; +@override @useResult +$Res call({ + int? id, PoultryScienceRef? poultryScience, HatchingModel? hatching, UserRef? user, String? key, String? createDate, String? modifyDate, bool? trash, String? date, String? image, num? lat, num? log, String? reporterFullname, String? reporterMobile, String? reporterRole, String? state, num? realQuantityAi, String? messageAi, num? realQuantity, String? message, String? messageRegistererFullname, String? messageRegistererMobile, String? messageRegistererRole, ReportInformation? reportInformation, String? createdBy, String? modifiedBy +}); + + +@override $PoultryScienceRefCopyWith<$Res>? get poultryScience;@override $HatchingModelCopyWith<$Res>? get hatching;@override $UserRefCopyWith<$Res>? get user;@override $ReportInformationCopyWith<$Res>? get reportInformation; + +} +/// @nodoc +class __$PoultryScienceReportCopyWithImpl<$Res> + implements _$PoultryScienceReportCopyWith<$Res> { + __$PoultryScienceReportCopyWithImpl(this._self, this._then); + + final _PoultryScienceReport _self; + final $Res Function(_PoultryScienceReport) _then; + +/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? poultryScience = freezed,Object? hatching = freezed,Object? user = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? date = freezed,Object? image = freezed,Object? lat = freezed,Object? log = freezed,Object? reporterFullname = freezed,Object? reporterMobile = freezed,Object? reporterRole = freezed,Object? state = freezed,Object? realQuantityAi = freezed,Object? messageAi = freezed,Object? realQuantity = freezed,Object? message = freezed,Object? messageRegistererFullname = freezed,Object? messageRegistererMobile = freezed,Object? messageRegistererRole = freezed,Object? reportInformation = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,}) { + return _then(_PoultryScienceReport( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int?,poultryScience: freezed == poultryScience ? _self.poultryScience : poultryScience // ignore: cast_nullable_to_non_nullable +as PoultryScienceRef?,hatching: freezed == hatching ? _self.hatching : hatching // ignore: cast_nullable_to_non_nullable +as HatchingModel?,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserRef?,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable +as String?,createDate: freezed == createDate ? _self.createDate : createDate // ignore: cast_nullable_to_non_nullable +as String?,modifyDate: freezed == modifyDate ? _self.modifyDate : modifyDate // ignore: cast_nullable_to_non_nullable +as String?,trash: freezed == trash ? _self.trash : trash // ignore: cast_nullable_to_non_nullable +as bool?,date: freezed == date ? _self.date : date // ignore: cast_nullable_to_non_nullable +as String?,image: freezed == image ? _self.image : image // ignore: cast_nullable_to_non_nullable +as String?,lat: freezed == lat ? _self.lat : lat // ignore: cast_nullable_to_non_nullable +as num?,log: freezed == log ? _self.log : log // ignore: cast_nullable_to_non_nullable +as num?,reporterFullname: freezed == reporterFullname ? _self.reporterFullname : reporterFullname // ignore: cast_nullable_to_non_nullable +as String?,reporterMobile: freezed == reporterMobile ? _self.reporterMobile : reporterMobile // ignore: cast_nullable_to_non_nullable +as String?,reporterRole: freezed == reporterRole ? _self.reporterRole : reporterRole // ignore: cast_nullable_to_non_nullable +as String?,state: freezed == state ? _self.state : state // ignore: cast_nullable_to_non_nullable +as String?,realQuantityAi: freezed == realQuantityAi ? _self.realQuantityAi : realQuantityAi // ignore: cast_nullable_to_non_nullable +as num?,messageAi: freezed == messageAi ? _self.messageAi : messageAi // ignore: cast_nullable_to_non_nullable +as String?,realQuantity: freezed == realQuantity ? _self.realQuantity : realQuantity // ignore: cast_nullable_to_non_nullable +as num?,message: freezed == message ? _self.message : message // ignore: cast_nullable_to_non_nullable +as String?,messageRegistererFullname: freezed == messageRegistererFullname ? _self.messageRegistererFullname : messageRegistererFullname // ignore: cast_nullable_to_non_nullable +as String?,messageRegistererMobile: freezed == messageRegistererMobile ? _self.messageRegistererMobile : messageRegistererMobile // ignore: cast_nullable_to_non_nullable +as String?,messageRegistererRole: freezed == messageRegistererRole ? _self.messageRegistererRole : messageRegistererRole // ignore: cast_nullable_to_non_nullable +as String?,reportInformation: freezed == reportInformation ? _self.reportInformation : reportInformation // ignore: cast_nullable_to_non_nullable +as ReportInformation?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable +as String?,modifiedBy: freezed == modifiedBy ? _self.modifiedBy : modifiedBy // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$PoultryScienceRefCopyWith<$Res>? get poultryScience { + if (_self.poultryScience == null) { + return null; + } + + return $PoultryScienceRefCopyWith<$Res>(_self.poultryScience!, (value) { + return _then(_self.copyWith(poultryScience: value)); + }); +}/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$HatchingModelCopyWith<$Res>? get hatching { + if (_self.hatching == null) { + return null; + } + + return $HatchingModelCopyWith<$Res>(_self.hatching!, (value) { + return _then(_self.copyWith(hatching: value)); + }); +}/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserRefCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserRefCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +}/// Create a copy of PoultryScienceReport +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$ReportInformationCopyWith<$Res>? get reportInformation { + if (_self.reportInformation == null) { + return null; + } + + return $ReportInformationCopyWith<$Res>(_self.reportInformation!, (value) { + return _then(_self.copyWith(reportInformation: value)); + }); +} +} + + +/// @nodoc +mixin _$PoultryScienceRef { + + int? get id; UserWithCity? get user; String? get key; String? get createDate; String? get modifyDate; bool? get trash; String? get engineeringCode; String? get createdBy; String? get modifiedBy; List? get poultry; +/// Create a copy of PoultryScienceRef +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$PoultryScienceRefCopyWith get copyWith => _$PoultryScienceRefCopyWithImpl(this as PoultryScienceRef, _$identity); + + /// Serializes this PoultryScienceRef to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is PoultryScienceRef&&(identical(other.id, id) || other.id == id)&&(identical(other.user, user) || other.user == user)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.engineeringCode, engineeringCode) || other.engineeringCode == engineeringCode)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)&&const DeepCollectionEquality().equals(other.poultry, poultry)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,user,key,createDate,modifyDate,trash,engineeringCode,createdBy,modifiedBy,const DeepCollectionEquality().hash(poultry)); + +@override +String toString() { + return 'PoultryScienceRef(id: $id, user: $user, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, engineeringCode: $engineeringCode, createdBy: $createdBy, modifiedBy: $modifiedBy, poultry: $poultry)'; +} + + +} + +/// @nodoc +abstract mixin class $PoultryScienceRefCopyWith<$Res> { + factory $PoultryScienceRefCopyWith(PoultryScienceRef value, $Res Function(PoultryScienceRef) _then) = _$PoultryScienceRefCopyWithImpl; +@useResult +$Res call({ + int? id, UserWithCity? user, String? key, String? createDate, String? modifyDate, bool? trash, String? engineeringCode, String? createdBy, String? modifiedBy, List? poultry +}); + + +$UserWithCityCopyWith<$Res>? get user; + +} +/// @nodoc +class _$PoultryScienceRefCopyWithImpl<$Res> + implements $PoultryScienceRefCopyWith<$Res> { + _$PoultryScienceRefCopyWithImpl(this._self, this._then); + + final PoultryScienceRef _self; + final $Res Function(PoultryScienceRef) _then; + +/// Create a copy of PoultryScienceRef +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? id = freezed,Object? user = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? engineeringCode = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,Object? poultry = freezed,}) { + return _then(_self.copyWith( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int?,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserWithCity?,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable +as String?,createDate: freezed == createDate ? _self.createDate : createDate // ignore: cast_nullable_to_non_nullable +as String?,modifyDate: freezed == modifyDate ? _self.modifyDate : modifyDate // ignore: cast_nullable_to_non_nullable +as String?,trash: freezed == trash ? _self.trash : trash // ignore: cast_nullable_to_non_nullable +as bool?,engineeringCode: freezed == engineeringCode ? _self.engineeringCode : engineeringCode // ignore: cast_nullable_to_non_nullable +as String?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable +as String?,modifiedBy: freezed == modifiedBy ? _self.modifiedBy : modifiedBy // ignore: cast_nullable_to_non_nullable +as String?,poultry: freezed == poultry ? _self.poultry : poultry // ignore: cast_nullable_to_non_nullable +as List?, + )); +} +/// Create a copy of PoultryScienceRef +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserWithCityCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserWithCityCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [PoultryScienceRef]. +extension PoultryScienceRefPatterns on PoultryScienceRef { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _PoultryScienceRef value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _PoultryScienceRef() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _PoultryScienceRef value) $default,){ +final _that = this; +switch (_that) { +case _PoultryScienceRef(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _PoultryScienceRef value)? $default,){ +final _that = this; +switch (_that) { +case _PoultryScienceRef() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( int? id, UserWithCity? user, String? key, String? createDate, String? modifyDate, bool? trash, String? engineeringCode, String? createdBy, String? modifiedBy, List? poultry)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _PoultryScienceRef() when $default != null: +return $default(_that.id,_that.user,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.engineeringCode,_that.createdBy,_that.modifiedBy,_that.poultry);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( int? id, UserWithCity? user, String? key, String? createDate, String? modifyDate, bool? trash, String? engineeringCode, String? createdBy, String? modifiedBy, List? poultry) $default,) {final _that = this; +switch (_that) { +case _PoultryScienceRef(): +return $default(_that.id,_that.user,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.engineeringCode,_that.createdBy,_that.modifiedBy,_that.poultry);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( int? id, UserWithCity? user, String? key, String? createDate, String? modifyDate, bool? trash, String? engineeringCode, String? createdBy, String? modifiedBy, List? poultry)? $default,) {final _that = this; +switch (_that) { +case _PoultryScienceRef() when $default != null: +return $default(_that.id,_that.user,_that.key,_that.createDate,_that.modifyDate,_that.trash,_that.engineeringCode,_that.createdBy,_that.modifiedBy,_that.poultry);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _PoultryScienceRef implements PoultryScienceRef { + const _PoultryScienceRef({this.id, this.user, this.key, this.createDate, this.modifyDate, this.trash, this.engineeringCode, this.createdBy, this.modifiedBy, final List? poultry}): _poultry = poultry; + factory _PoultryScienceRef.fromJson(Map json) => _$PoultryScienceRefFromJson(json); + +@override final int? id; +@override final UserWithCity? user; +@override final String? key; +@override final String? createDate; +@override final String? modifyDate; +@override final bool? trash; +@override final String? engineeringCode; +@override final String? createdBy; +@override final String? modifiedBy; + final List? _poultry; +@override List? get poultry { + final value = _poultry; + if (value == null) return null; + if (_poultry is EqualUnmodifiableListView) return _poultry; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); +} + + +/// Create a copy of PoultryScienceRef +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$PoultryScienceRefCopyWith<_PoultryScienceRef> get copyWith => __$PoultryScienceRefCopyWithImpl<_PoultryScienceRef>(this, _$identity); + +@override +Map toJson() { + return _$PoultryScienceRefToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _PoultryScienceRef&&(identical(other.id, id) || other.id == id)&&(identical(other.user, user) || other.user == user)&&(identical(other.key, key) || other.key == key)&&(identical(other.createDate, createDate) || other.createDate == createDate)&&(identical(other.modifyDate, modifyDate) || other.modifyDate == modifyDate)&&(identical(other.trash, trash) || other.trash == trash)&&(identical(other.engineeringCode, engineeringCode) || other.engineeringCode == engineeringCode)&&(identical(other.createdBy, createdBy) || other.createdBy == createdBy)&&(identical(other.modifiedBy, modifiedBy) || other.modifiedBy == modifiedBy)&&const DeepCollectionEquality().equals(other._poultry, _poultry)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,id,user,key,createDate,modifyDate,trash,engineeringCode,createdBy,modifiedBy,const DeepCollectionEquality().hash(_poultry)); + +@override +String toString() { + return 'PoultryScienceRef(id: $id, user: $user, key: $key, createDate: $createDate, modifyDate: $modifyDate, trash: $trash, engineeringCode: $engineeringCode, createdBy: $createdBy, modifiedBy: $modifiedBy, poultry: $poultry)'; +} + + +} + +/// @nodoc +abstract mixin class _$PoultryScienceRefCopyWith<$Res> implements $PoultryScienceRefCopyWith<$Res> { + factory _$PoultryScienceRefCopyWith(_PoultryScienceRef value, $Res Function(_PoultryScienceRef) _then) = __$PoultryScienceRefCopyWithImpl; +@override @useResult +$Res call({ + int? id, UserWithCity? user, String? key, String? createDate, String? modifyDate, bool? trash, String? engineeringCode, String? createdBy, String? modifiedBy, List? poultry +}); + + +@override $UserWithCityCopyWith<$Res>? get user; + +} +/// @nodoc +class __$PoultryScienceRefCopyWithImpl<$Res> + implements _$PoultryScienceRefCopyWith<$Res> { + __$PoultryScienceRefCopyWithImpl(this._self, this._then); + + final _PoultryScienceRef _self; + final $Res Function(_PoultryScienceRef) _then; + +/// Create a copy of PoultryScienceRef +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? id = freezed,Object? user = freezed,Object? key = freezed,Object? createDate = freezed,Object? modifyDate = freezed,Object? trash = freezed,Object? engineeringCode = freezed,Object? createdBy = freezed,Object? modifiedBy = freezed,Object? poultry = freezed,}) { + return _then(_PoultryScienceRef( +id: freezed == id ? _self.id : id // ignore: cast_nullable_to_non_nullable +as int?,user: freezed == user ? _self.user : user // ignore: cast_nullable_to_non_nullable +as UserWithCity?,key: freezed == key ? _self.key : key // ignore: cast_nullable_to_non_nullable +as String?,createDate: freezed == createDate ? _self.createDate : createDate // ignore: cast_nullable_to_non_nullable +as String?,modifyDate: freezed == modifyDate ? _self.modifyDate : modifyDate // ignore: cast_nullable_to_non_nullable +as String?,trash: freezed == trash ? _self.trash : trash // ignore: cast_nullable_to_non_nullable +as bool?,engineeringCode: freezed == engineeringCode ? _self.engineeringCode : engineeringCode // ignore: cast_nullable_to_non_nullable +as String?,createdBy: freezed == createdBy ? _self.createdBy : createdBy // ignore: cast_nullable_to_non_nullable +as String?,modifiedBy: freezed == modifiedBy ? _self.modifiedBy : modifiedBy // ignore: cast_nullable_to_non_nullable +as String?,poultry: freezed == poultry ? _self._poultry : poultry // ignore: cast_nullable_to_non_nullable +as List?, + )); +} + +/// Create a copy of PoultryScienceRef +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$UserWithCityCopyWith<$Res>? get user { + if (_self.user == null) { + return null; + } + + return $UserWithCityCopyWith<$Res>(_self.user!, (value) { + return _then(_self.copyWith(user: value)); + }); +} +} + + +/// @nodoc +mixin _$UserRef { + + String? get fullname; String? get mobile; CityRef? get city; +/// Create a copy of UserRef +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$UserRefCopyWith get copyWith => _$UserRefCopyWithImpl(this as UserRef, _$identity); + + /// Serializes this UserRef to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is UserRef&&(identical(other.fullname, fullname) || other.fullname == fullname)&&(identical(other.mobile, mobile) || other.mobile == mobile)&&(identical(other.city, city) || other.city == city)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,fullname,mobile,city); + +@override +String toString() { + return 'UserRef(fullname: $fullname, mobile: $mobile, city: $city)'; +} + + +} + +/// @nodoc +abstract mixin class $UserRefCopyWith<$Res> { + factory $UserRefCopyWith(UserRef value, $Res Function(UserRef) _then) = _$UserRefCopyWithImpl; +@useResult +$Res call({ + String? fullname, String? mobile, CityRef? city +}); + + +$CityRefCopyWith<$Res>? get city; + +} +/// @nodoc +class _$UserRefCopyWithImpl<$Res> + implements $UserRefCopyWith<$Res> { + _$UserRefCopyWithImpl(this._self, this._then); + + final UserRef _self; + final $Res Function(UserRef) _then; + +/// Create a copy of UserRef +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? fullname = freezed,Object? mobile = freezed,Object? city = freezed,}) { + return _then(_self.copyWith( +fullname: freezed == fullname ? _self.fullname : fullname // ignore: cast_nullable_to_non_nullable +as String?,mobile: freezed == mobile ? _self.mobile : mobile // ignore: cast_nullable_to_non_nullable +as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable +as CityRef?, + )); +} +/// Create a copy of UserRef +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$CityRefCopyWith<$Res>? get city { + if (_self.city == null) { + return null; + } + + return $CityRefCopyWith<$Res>(_self.city!, (value) { + return _then(_self.copyWith(city: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [UserRef]. +extension UserRefPatterns on UserRef { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _UserRef value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _UserRef() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _UserRef value) $default,){ +final _that = this; +switch (_that) { +case _UserRef(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _UserRef value)? $default,){ +final _that = this; +switch (_that) { +case _UserRef() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String? fullname, String? mobile, CityRef? city)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _UserRef() when $default != null: +return $default(_that.fullname,_that.mobile,_that.city);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String? fullname, String? mobile, CityRef? city) $default,) {final _that = this; +switch (_that) { +case _UserRef(): +return $default(_that.fullname,_that.mobile,_that.city);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? fullname, String? mobile, CityRef? city)? $default,) {final _that = this; +switch (_that) { +case _UserRef() when $default != null: +return $default(_that.fullname,_that.mobile,_that.city);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _UserRef implements UserRef { + const _UserRef({this.fullname, this.mobile, this.city}); + factory _UserRef.fromJson(Map json) => _$UserRefFromJson(json); + +@override final String? fullname; +@override final String? mobile; +@override final CityRef? city; + +/// Create a copy of UserRef +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$UserRefCopyWith<_UserRef> get copyWith => __$UserRefCopyWithImpl<_UserRef>(this, _$identity); + +@override +Map toJson() { + return _$UserRefToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _UserRef&&(identical(other.fullname, fullname) || other.fullname == fullname)&&(identical(other.mobile, mobile) || other.mobile == mobile)&&(identical(other.city, city) || other.city == city)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,fullname,mobile,city); + +@override +String toString() { + return 'UserRef(fullname: $fullname, mobile: $mobile, city: $city)'; +} + + +} + +/// @nodoc +abstract mixin class _$UserRefCopyWith<$Res> implements $UserRefCopyWith<$Res> { + factory _$UserRefCopyWith(_UserRef value, $Res Function(_UserRef) _then) = __$UserRefCopyWithImpl; +@override @useResult +$Res call({ + String? fullname, String? mobile, CityRef? city +}); + + +@override $CityRefCopyWith<$Res>? get city; + +} +/// @nodoc +class __$UserRefCopyWithImpl<$Res> + implements _$UserRefCopyWith<$Res> { + __$UserRefCopyWithImpl(this._self, this._then); + + final _UserRef _self; + final $Res Function(_UserRef) _then; + +/// Create a copy of UserRef +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? fullname = freezed,Object? mobile = freezed,Object? city = freezed,}) { + return _then(_UserRef( +fullname: freezed == fullname ? _self.fullname : fullname // ignore: cast_nullable_to_non_nullable +as String?,mobile: freezed == mobile ? _self.mobile : mobile // ignore: cast_nullable_to_non_nullable +as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable +as CityRef?, + )); +} + +/// Create a copy of UserRef +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$CityRefCopyWith<$Res>? get city { + if (_self.city == null) { + return null; + } + + return $CityRefCopyWith<$Res>(_self.city!, (value) { + return _then(_self.copyWith(city: value)); + }); +} +} + + +/// @nodoc +mixin _$UserWithCity { + + String? get fullname; String? get mobile; CityRef? get city; +/// Create a copy of UserWithCity +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$UserWithCityCopyWith get copyWith => _$UserWithCityCopyWithImpl(this as UserWithCity, _$identity); + + /// Serializes this UserWithCity to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is UserWithCity&&(identical(other.fullname, fullname) || other.fullname == fullname)&&(identical(other.mobile, mobile) || other.mobile == mobile)&&(identical(other.city, city) || other.city == city)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,fullname,mobile,city); + +@override +String toString() { + return 'UserWithCity(fullname: $fullname, mobile: $mobile, city: $city)'; +} + + +} + +/// @nodoc +abstract mixin class $UserWithCityCopyWith<$Res> { + factory $UserWithCityCopyWith(UserWithCity value, $Res Function(UserWithCity) _then) = _$UserWithCityCopyWithImpl; +@useResult +$Res call({ + String? fullname, String? mobile, CityRef? city +}); + + +$CityRefCopyWith<$Res>? get city; + +} +/// @nodoc +class _$UserWithCityCopyWithImpl<$Res> + implements $UserWithCityCopyWith<$Res> { + _$UserWithCityCopyWithImpl(this._self, this._then); + + final UserWithCity _self; + final $Res Function(UserWithCity) _then; + +/// Create a copy of UserWithCity +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? fullname = freezed,Object? mobile = freezed,Object? city = freezed,}) { + return _then(_self.copyWith( +fullname: freezed == fullname ? _self.fullname : fullname // ignore: cast_nullable_to_non_nullable +as String?,mobile: freezed == mobile ? _self.mobile : mobile // ignore: cast_nullable_to_non_nullable +as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable +as CityRef?, + )); +} +/// Create a copy of UserWithCity +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$CityRefCopyWith<$Res>? get city { + if (_self.city == null) { + return null; + } + + return $CityRefCopyWith<$Res>(_self.city!, (value) { + return _then(_self.copyWith(city: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [UserWithCity]. +extension UserWithCityPatterns on UserWithCity { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _UserWithCity value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _UserWithCity() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _UserWithCity value) $default,){ +final _that = this; +switch (_that) { +case _UserWithCity(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _UserWithCity value)? $default,){ +final _that = this; +switch (_that) { +case _UserWithCity() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String? fullname, String? mobile, CityRef? city)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _UserWithCity() when $default != null: +return $default(_that.fullname,_that.mobile,_that.city);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String? fullname, String? mobile, CityRef? city) $default,) {final _that = this; +switch (_that) { +case _UserWithCity(): +return $default(_that.fullname,_that.mobile,_that.city);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? fullname, String? mobile, CityRef? city)? $default,) {final _that = this; +switch (_that) { +case _UserWithCity() when $default != null: +return $default(_that.fullname,_that.mobile,_that.city);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _UserWithCity implements UserWithCity { + const _UserWithCity({this.fullname, this.mobile, this.city}); + factory _UserWithCity.fromJson(Map json) => _$UserWithCityFromJson(json); + +@override final String? fullname; +@override final String? mobile; +@override final CityRef? city; + +/// Create a copy of UserWithCity +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$UserWithCityCopyWith<_UserWithCity> get copyWith => __$UserWithCityCopyWithImpl<_UserWithCity>(this, _$identity); + +@override +Map toJson() { + return _$UserWithCityToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _UserWithCity&&(identical(other.fullname, fullname) || other.fullname == fullname)&&(identical(other.mobile, mobile) || other.mobile == mobile)&&(identical(other.city, city) || other.city == city)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,fullname,mobile,city); + +@override +String toString() { + return 'UserWithCity(fullname: $fullname, mobile: $mobile, city: $city)'; +} + + +} + +/// @nodoc +abstract mixin class _$UserWithCityCopyWith<$Res> implements $UserWithCityCopyWith<$Res> { + factory _$UserWithCityCopyWith(_UserWithCity value, $Res Function(_UserWithCity) _then) = __$UserWithCityCopyWithImpl; +@override @useResult +$Res call({ + String? fullname, String? mobile, CityRef? city +}); + + +@override $CityRefCopyWith<$Res>? get city; + +} +/// @nodoc +class __$UserWithCityCopyWithImpl<$Res> + implements _$UserWithCityCopyWith<$Res> { + __$UserWithCityCopyWithImpl(this._self, this._then); + + final _UserWithCity _self; + final $Res Function(_UserWithCity) _then; + +/// Create a copy of UserWithCity +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? fullname = freezed,Object? mobile = freezed,Object? city = freezed,}) { + return _then(_UserWithCity( +fullname: freezed == fullname ? _self.fullname : fullname // ignore: cast_nullable_to_non_nullable +as String?,mobile: freezed == mobile ? _self.mobile : mobile // ignore: cast_nullable_to_non_nullable +as String?,city: freezed == city ? _self.city : city // ignore: cast_nullable_to_non_nullable +as CityRef?, + )); +} + +/// Create a copy of UserWithCity +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$CityRefCopyWith<$Res>? get city { + if (_self.city == null) { + return null; + } + + return $CityRefCopyWith<$Res>(_self.city!, (value) { + return _then(_self.copyWith(city: value)); + }); +} +} + + +/// @nodoc +mixin _$ReportInformation { + + HrInfo? get hr; Casualties? get casualties; Facilities? get facilities; InputStatus? get inputStatus; String? get inspectionNotes; String? get inspectionStatus; TechnicalOfficer? get technicalOfficer; InfrastructureEnergy? get infrastructureEnergy; GeneralConditionHall? get generalConditionHall; +/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$ReportInformationCopyWith get copyWith => _$ReportInformationCopyWithImpl(this as ReportInformation, _$identity); + + /// Serializes this ReportInformation to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is ReportInformation&&(identical(other.hr, hr) || other.hr == hr)&&(identical(other.casualties, casualties) || other.casualties == casualties)&&(identical(other.facilities, facilities) || other.facilities == facilities)&&(identical(other.inputStatus, inputStatus) || other.inputStatus == inputStatus)&&(identical(other.inspectionNotes, inspectionNotes) || other.inspectionNotes == inspectionNotes)&&(identical(other.inspectionStatus, inspectionStatus) || other.inspectionStatus == inspectionStatus)&&(identical(other.technicalOfficer, technicalOfficer) || other.technicalOfficer == technicalOfficer)&&(identical(other.infrastructureEnergy, infrastructureEnergy) || other.infrastructureEnergy == infrastructureEnergy)&&(identical(other.generalConditionHall, generalConditionHall) || other.generalConditionHall == generalConditionHall)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,hr,casualties,facilities,inputStatus,inspectionNotes,inspectionStatus,technicalOfficer,infrastructureEnergy,generalConditionHall); + +@override +String toString() { + return 'ReportInformation(hr: $hr, casualties: $casualties, facilities: $facilities, inputStatus: $inputStatus, inspectionNotes: $inspectionNotes, inspectionStatus: $inspectionStatus, technicalOfficer: $technicalOfficer, infrastructureEnergy: $infrastructureEnergy, generalConditionHall: $generalConditionHall)'; +} + + +} + +/// @nodoc +abstract mixin class $ReportInformationCopyWith<$Res> { + factory $ReportInformationCopyWith(ReportInformation value, $Res Function(ReportInformation) _then) = _$ReportInformationCopyWithImpl; +@useResult +$Res call({ + HrInfo? hr, Casualties? casualties, Facilities? facilities, InputStatus? inputStatus, String? inspectionNotes, String? inspectionStatus, TechnicalOfficer? technicalOfficer, InfrastructureEnergy? infrastructureEnergy, GeneralConditionHall? generalConditionHall +}); + + +$HrInfoCopyWith<$Res>? get hr;$CasualtiesCopyWith<$Res>? get casualties;$FacilitiesCopyWith<$Res>? get facilities;$InputStatusCopyWith<$Res>? get inputStatus;$TechnicalOfficerCopyWith<$Res>? get technicalOfficer;$InfrastructureEnergyCopyWith<$Res>? get infrastructureEnergy;$GeneralConditionHallCopyWith<$Res>? get generalConditionHall; + +} +/// @nodoc +class _$ReportInformationCopyWithImpl<$Res> + implements $ReportInformationCopyWith<$Res> { + _$ReportInformationCopyWithImpl(this._self, this._then); + + final ReportInformation _self; + final $Res Function(ReportInformation) _then; + +/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? hr = freezed,Object? casualties = freezed,Object? facilities = freezed,Object? inputStatus = freezed,Object? inspectionNotes = freezed,Object? inspectionStatus = freezed,Object? technicalOfficer = freezed,Object? infrastructureEnergy = freezed,Object? generalConditionHall = freezed,}) { + return _then(_self.copyWith( +hr: freezed == hr ? _self.hr : hr // ignore: cast_nullable_to_non_nullable +as HrInfo?,casualties: freezed == casualties ? _self.casualties : casualties // ignore: cast_nullable_to_non_nullable +as Casualties?,facilities: freezed == facilities ? _self.facilities : facilities // ignore: cast_nullable_to_non_nullable +as Facilities?,inputStatus: freezed == inputStatus ? _self.inputStatus : inputStatus // ignore: cast_nullable_to_non_nullable +as InputStatus?,inspectionNotes: freezed == inspectionNotes ? _self.inspectionNotes : inspectionNotes // ignore: cast_nullable_to_non_nullable +as String?,inspectionStatus: freezed == inspectionStatus ? _self.inspectionStatus : inspectionStatus // ignore: cast_nullable_to_non_nullable +as String?,technicalOfficer: freezed == technicalOfficer ? _self.technicalOfficer : technicalOfficer // ignore: cast_nullable_to_non_nullable +as TechnicalOfficer?,infrastructureEnergy: freezed == infrastructureEnergy ? _self.infrastructureEnergy : infrastructureEnergy // ignore: cast_nullable_to_non_nullable +as InfrastructureEnergy?,generalConditionHall: freezed == generalConditionHall ? _self.generalConditionHall : generalConditionHall // ignore: cast_nullable_to_non_nullable +as GeneralConditionHall?, + )); +} +/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$HrInfoCopyWith<$Res>? get hr { + if (_self.hr == null) { + return null; + } + + return $HrInfoCopyWith<$Res>(_self.hr!, (value) { + return _then(_self.copyWith(hr: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$CasualtiesCopyWith<$Res>? get casualties { + if (_self.casualties == null) { + return null; + } + + return $CasualtiesCopyWith<$Res>(_self.casualties!, (value) { + return _then(_self.copyWith(casualties: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$FacilitiesCopyWith<$Res>? get facilities { + if (_self.facilities == null) { + return null; + } + + return $FacilitiesCopyWith<$Res>(_self.facilities!, (value) { + return _then(_self.copyWith(facilities: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$InputStatusCopyWith<$Res>? get inputStatus { + if (_self.inputStatus == null) { + return null; + } + + return $InputStatusCopyWith<$Res>(_self.inputStatus!, (value) { + return _then(_self.copyWith(inputStatus: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$TechnicalOfficerCopyWith<$Res>? get technicalOfficer { + if (_self.technicalOfficer == null) { + return null; + } + + return $TechnicalOfficerCopyWith<$Res>(_self.technicalOfficer!, (value) { + return _then(_self.copyWith(technicalOfficer: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$InfrastructureEnergyCopyWith<$Res>? get infrastructureEnergy { + if (_self.infrastructureEnergy == null) { + return null; + } + + return $InfrastructureEnergyCopyWith<$Res>(_self.infrastructureEnergy!, (value) { + return _then(_self.copyWith(infrastructureEnergy: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$GeneralConditionHallCopyWith<$Res>? get generalConditionHall { + if (_self.generalConditionHall == null) { + return null; + } + + return $GeneralConditionHallCopyWith<$Res>(_self.generalConditionHall!, (value) { + return _then(_self.copyWith(generalConditionHall: value)); + }); +} +} + + +/// Adds pattern-matching-related methods to [ReportInformation]. +extension ReportInformationPatterns on ReportInformation { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _ReportInformation value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _ReportInformation() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _ReportInformation value) $default,){ +final _that = this; +switch (_that) { +case _ReportInformation(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _ReportInformation value)? $default,){ +final _that = this; +switch (_that) { +case _ReportInformation() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( HrInfo? hr, Casualties? casualties, Facilities? facilities, InputStatus? inputStatus, String? inspectionNotes, String? inspectionStatus, TechnicalOfficer? technicalOfficer, InfrastructureEnergy? infrastructureEnergy, GeneralConditionHall? generalConditionHall)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _ReportInformation() when $default != null: +return $default(_that.hr,_that.casualties,_that.facilities,_that.inputStatus,_that.inspectionNotes,_that.inspectionStatus,_that.technicalOfficer,_that.infrastructureEnergy,_that.generalConditionHall);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( HrInfo? hr, Casualties? casualties, Facilities? facilities, InputStatus? inputStatus, String? inspectionNotes, String? inspectionStatus, TechnicalOfficer? technicalOfficer, InfrastructureEnergy? infrastructureEnergy, GeneralConditionHall? generalConditionHall) $default,) {final _that = this; +switch (_that) { +case _ReportInformation(): +return $default(_that.hr,_that.casualties,_that.facilities,_that.inputStatus,_that.inspectionNotes,_that.inspectionStatus,_that.technicalOfficer,_that.infrastructureEnergy,_that.generalConditionHall);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( HrInfo? hr, Casualties? casualties, Facilities? facilities, InputStatus? inputStatus, String? inspectionNotes, String? inspectionStatus, TechnicalOfficer? technicalOfficer, InfrastructureEnergy? infrastructureEnergy, GeneralConditionHall? generalConditionHall)? $default,) {final _that = this; +switch (_that) { +case _ReportInformation() when $default != null: +return $default(_that.hr,_that.casualties,_that.facilities,_that.inputStatus,_that.inspectionNotes,_that.inspectionStatus,_that.technicalOfficer,_that.infrastructureEnergy,_that.generalConditionHall);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _ReportInformation implements ReportInformation { + const _ReportInformation({this.hr, this.casualties, this.facilities, this.inputStatus, this.inspectionNotes, this.inspectionStatus, this.technicalOfficer, this.infrastructureEnergy, this.generalConditionHall}); + factory _ReportInformation.fromJson(Map json) => _$ReportInformationFromJson(json); + +@override final HrInfo? hr; +@override final Casualties? casualties; +@override final Facilities? facilities; +@override final InputStatus? inputStatus; +@override final String? inspectionNotes; +@override final String? inspectionStatus; +@override final TechnicalOfficer? technicalOfficer; +@override final InfrastructureEnergy? infrastructureEnergy; +@override final GeneralConditionHall? generalConditionHall; + +/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$ReportInformationCopyWith<_ReportInformation> get copyWith => __$ReportInformationCopyWithImpl<_ReportInformation>(this, _$identity); + +@override +Map toJson() { + return _$ReportInformationToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _ReportInformation&&(identical(other.hr, hr) || other.hr == hr)&&(identical(other.casualties, casualties) || other.casualties == casualties)&&(identical(other.facilities, facilities) || other.facilities == facilities)&&(identical(other.inputStatus, inputStatus) || other.inputStatus == inputStatus)&&(identical(other.inspectionNotes, inspectionNotes) || other.inspectionNotes == inspectionNotes)&&(identical(other.inspectionStatus, inspectionStatus) || other.inspectionStatus == inspectionStatus)&&(identical(other.technicalOfficer, technicalOfficer) || other.technicalOfficer == technicalOfficer)&&(identical(other.infrastructureEnergy, infrastructureEnergy) || other.infrastructureEnergy == infrastructureEnergy)&&(identical(other.generalConditionHall, generalConditionHall) || other.generalConditionHall == generalConditionHall)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,hr,casualties,facilities,inputStatus,inspectionNotes,inspectionStatus,technicalOfficer,infrastructureEnergy,generalConditionHall); + +@override +String toString() { + return 'ReportInformation(hr: $hr, casualties: $casualties, facilities: $facilities, inputStatus: $inputStatus, inspectionNotes: $inspectionNotes, inspectionStatus: $inspectionStatus, technicalOfficer: $technicalOfficer, infrastructureEnergy: $infrastructureEnergy, generalConditionHall: $generalConditionHall)'; +} + + +} + +/// @nodoc +abstract mixin class _$ReportInformationCopyWith<$Res> implements $ReportInformationCopyWith<$Res> { + factory _$ReportInformationCopyWith(_ReportInformation value, $Res Function(_ReportInformation) _then) = __$ReportInformationCopyWithImpl; +@override @useResult +$Res call({ + HrInfo? hr, Casualties? casualties, Facilities? facilities, InputStatus? inputStatus, String? inspectionNotes, String? inspectionStatus, TechnicalOfficer? technicalOfficer, InfrastructureEnergy? infrastructureEnergy, GeneralConditionHall? generalConditionHall +}); + + +@override $HrInfoCopyWith<$Res>? get hr;@override $CasualtiesCopyWith<$Res>? get casualties;@override $FacilitiesCopyWith<$Res>? get facilities;@override $InputStatusCopyWith<$Res>? get inputStatus;@override $TechnicalOfficerCopyWith<$Res>? get technicalOfficer;@override $InfrastructureEnergyCopyWith<$Res>? get infrastructureEnergy;@override $GeneralConditionHallCopyWith<$Res>? get generalConditionHall; + +} +/// @nodoc +class __$ReportInformationCopyWithImpl<$Res> + implements _$ReportInformationCopyWith<$Res> { + __$ReportInformationCopyWithImpl(this._self, this._then); + + final _ReportInformation _self; + final $Res Function(_ReportInformation) _then; + +/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? hr = freezed,Object? casualties = freezed,Object? facilities = freezed,Object? inputStatus = freezed,Object? inspectionNotes = freezed,Object? inspectionStatus = freezed,Object? technicalOfficer = freezed,Object? infrastructureEnergy = freezed,Object? generalConditionHall = freezed,}) { + return _then(_ReportInformation( +hr: freezed == hr ? _self.hr : hr // ignore: cast_nullable_to_non_nullable +as HrInfo?,casualties: freezed == casualties ? _self.casualties : casualties // ignore: cast_nullable_to_non_nullable +as Casualties?,facilities: freezed == facilities ? _self.facilities : facilities // ignore: cast_nullable_to_non_nullable +as Facilities?,inputStatus: freezed == inputStatus ? _self.inputStatus : inputStatus // ignore: cast_nullable_to_non_nullable +as InputStatus?,inspectionNotes: freezed == inspectionNotes ? _self.inspectionNotes : inspectionNotes // ignore: cast_nullable_to_non_nullable +as String?,inspectionStatus: freezed == inspectionStatus ? _self.inspectionStatus : inspectionStatus // ignore: cast_nullable_to_non_nullable +as String?,technicalOfficer: freezed == technicalOfficer ? _self.technicalOfficer : technicalOfficer // ignore: cast_nullable_to_non_nullable +as TechnicalOfficer?,infrastructureEnergy: freezed == infrastructureEnergy ? _self.infrastructureEnergy : infrastructureEnergy // ignore: cast_nullable_to_non_nullable +as InfrastructureEnergy?,generalConditionHall: freezed == generalConditionHall ? _self.generalConditionHall : generalConditionHall // ignore: cast_nullable_to_non_nullable +as GeneralConditionHall?, + )); +} + +/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$HrInfoCopyWith<$Res>? get hr { + if (_self.hr == null) { + return null; + } + + return $HrInfoCopyWith<$Res>(_self.hr!, (value) { + return _then(_self.copyWith(hr: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$CasualtiesCopyWith<$Res>? get casualties { + if (_self.casualties == null) { + return null; + } + + return $CasualtiesCopyWith<$Res>(_self.casualties!, (value) { + return _then(_self.copyWith(casualties: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$FacilitiesCopyWith<$Res>? get facilities { + if (_self.facilities == null) { + return null; + } + + return $FacilitiesCopyWith<$Res>(_self.facilities!, (value) { + return _then(_self.copyWith(facilities: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$InputStatusCopyWith<$Res>? get inputStatus { + if (_self.inputStatus == null) { + return null; + } + + return $InputStatusCopyWith<$Res>(_self.inputStatus!, (value) { + return _then(_self.copyWith(inputStatus: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$TechnicalOfficerCopyWith<$Res>? get technicalOfficer { + if (_self.technicalOfficer == null) { + return null; + } + + return $TechnicalOfficerCopyWith<$Res>(_self.technicalOfficer!, (value) { + return _then(_self.copyWith(technicalOfficer: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$InfrastructureEnergyCopyWith<$Res>? get infrastructureEnergy { + if (_self.infrastructureEnergy == null) { + return null; + } + + return $InfrastructureEnergyCopyWith<$Res>(_self.infrastructureEnergy!, (value) { + return _then(_self.copyWith(infrastructureEnergy: value)); + }); +}/// Create a copy of ReportInformation +/// with the given fields replaced by the non-null parameter values. +@override +@pragma('vm:prefer-inline') +$GeneralConditionHallCopyWith<$Res>? get generalConditionHall { + if (_self.generalConditionHall == null) { + return null; + } + + return $GeneralConditionHallCopyWith<$Res>(_self.generalConditionHall!, (value) { + return _then(_self.copyWith(generalConditionHall: value)); + }); +} +} + + +/// @nodoc +mixin _$HrInfo { + + bool? get trained; String? get contractStatus; num? get numberEmployed; num? get numberIndigenous; num? get numberNonIndigenous; +/// Create a copy of HrInfo +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$HrInfoCopyWith get copyWith => _$HrInfoCopyWithImpl(this as HrInfo, _$identity); + + /// Serializes this HrInfo to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is HrInfo&&(identical(other.trained, trained) || other.trained == trained)&&(identical(other.contractStatus, contractStatus) || other.contractStatus == contractStatus)&&(identical(other.numberEmployed, numberEmployed) || other.numberEmployed == numberEmployed)&&(identical(other.numberIndigenous, numberIndigenous) || other.numberIndigenous == numberIndigenous)&&(identical(other.numberNonIndigenous, numberNonIndigenous) || other.numberNonIndigenous == numberNonIndigenous)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,trained,contractStatus,numberEmployed,numberIndigenous,numberNonIndigenous); + +@override +String toString() { + return 'HrInfo(trained: $trained, contractStatus: $contractStatus, numberEmployed: $numberEmployed, numberIndigenous: $numberIndigenous, numberNonIndigenous: $numberNonIndigenous)'; +} + + +} + +/// @nodoc +abstract mixin class $HrInfoCopyWith<$Res> { + factory $HrInfoCopyWith(HrInfo value, $Res Function(HrInfo) _then) = _$HrInfoCopyWithImpl; +@useResult +$Res call({ + bool? trained, String? contractStatus, num? numberEmployed, num? numberIndigenous, num? numberNonIndigenous +}); + + + + +} +/// @nodoc +class _$HrInfoCopyWithImpl<$Res> + implements $HrInfoCopyWith<$Res> { + _$HrInfoCopyWithImpl(this._self, this._then); + + final HrInfo _self; + final $Res Function(HrInfo) _then; + +/// Create a copy of HrInfo +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? trained = freezed,Object? contractStatus = freezed,Object? numberEmployed = freezed,Object? numberIndigenous = freezed,Object? numberNonIndigenous = freezed,}) { + return _then(_self.copyWith( +trained: freezed == trained ? _self.trained : trained // ignore: cast_nullable_to_non_nullable +as bool?,contractStatus: freezed == contractStatus ? _self.contractStatus : contractStatus // ignore: cast_nullable_to_non_nullable +as String?,numberEmployed: freezed == numberEmployed ? _self.numberEmployed : numberEmployed // ignore: cast_nullable_to_non_nullable +as num?,numberIndigenous: freezed == numberIndigenous ? _self.numberIndigenous : numberIndigenous // ignore: cast_nullable_to_non_nullable +as num?,numberNonIndigenous: freezed == numberNonIndigenous ? _self.numberNonIndigenous : numberNonIndigenous // ignore: cast_nullable_to_non_nullable +as num?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [HrInfo]. +extension HrInfoPatterns on HrInfo { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _HrInfo value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _HrInfo() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _HrInfo value) $default,){ +final _that = this; +switch (_that) { +case _HrInfo(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _HrInfo value)? $default,){ +final _that = this; +switch (_that) { +case _HrInfo() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( bool? trained, String? contractStatus, num? numberEmployed, num? numberIndigenous, num? numberNonIndigenous)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _HrInfo() when $default != null: +return $default(_that.trained,_that.contractStatus,_that.numberEmployed,_that.numberIndigenous,_that.numberNonIndigenous);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( bool? trained, String? contractStatus, num? numberEmployed, num? numberIndigenous, num? numberNonIndigenous) $default,) {final _that = this; +switch (_that) { +case _HrInfo(): +return $default(_that.trained,_that.contractStatus,_that.numberEmployed,_that.numberIndigenous,_that.numberNonIndigenous);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool? trained, String? contractStatus, num? numberEmployed, num? numberIndigenous, num? numberNonIndigenous)? $default,) {final _that = this; +switch (_that) { +case _HrInfo() when $default != null: +return $default(_that.trained,_that.contractStatus,_that.numberEmployed,_that.numberIndigenous,_that.numberNonIndigenous);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _HrInfo implements HrInfo { + const _HrInfo({this.trained, this.contractStatus, this.numberEmployed, this.numberIndigenous, this.numberNonIndigenous}); + factory _HrInfo.fromJson(Map json) => _$HrInfoFromJson(json); + +@override final bool? trained; +@override final String? contractStatus; +@override final num? numberEmployed; +@override final num? numberIndigenous; +@override final num? numberNonIndigenous; + +/// Create a copy of HrInfo +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$HrInfoCopyWith<_HrInfo> get copyWith => __$HrInfoCopyWithImpl<_HrInfo>(this, _$identity); + +@override +Map toJson() { + return _$HrInfoToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _HrInfo&&(identical(other.trained, trained) || other.trained == trained)&&(identical(other.contractStatus, contractStatus) || other.contractStatus == contractStatus)&&(identical(other.numberEmployed, numberEmployed) || other.numberEmployed == numberEmployed)&&(identical(other.numberIndigenous, numberIndigenous) || other.numberIndigenous == numberIndigenous)&&(identical(other.numberNonIndigenous, numberNonIndigenous) || other.numberNonIndigenous == numberNonIndigenous)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,trained,contractStatus,numberEmployed,numberIndigenous,numberNonIndigenous); + +@override +String toString() { + return 'HrInfo(trained: $trained, contractStatus: $contractStatus, numberEmployed: $numberEmployed, numberIndigenous: $numberIndigenous, numberNonIndigenous: $numberNonIndigenous)'; +} + + +} + +/// @nodoc +abstract mixin class _$HrInfoCopyWith<$Res> implements $HrInfoCopyWith<$Res> { + factory _$HrInfoCopyWith(_HrInfo value, $Res Function(_HrInfo) _then) = __$HrInfoCopyWithImpl; +@override @useResult +$Res call({ + bool? trained, String? contractStatus, num? numberEmployed, num? numberIndigenous, num? numberNonIndigenous +}); + + + + +} +/// @nodoc +class __$HrInfoCopyWithImpl<$Res> + implements _$HrInfoCopyWith<$Res> { + __$HrInfoCopyWithImpl(this._self, this._then); + + final _HrInfo _self; + final $Res Function(_HrInfo) _then; + +/// Create a copy of HrInfo +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? trained = freezed,Object? contractStatus = freezed,Object? numberEmployed = freezed,Object? numberIndigenous = freezed,Object? numberNonIndigenous = freezed,}) { + return _then(_HrInfo( +trained: freezed == trained ? _self.trained : trained // ignore: cast_nullable_to_non_nullable +as bool?,contractStatus: freezed == contractStatus ? _self.contractStatus : contractStatus // ignore: cast_nullable_to_non_nullable +as String?,numberEmployed: freezed == numberEmployed ? _self.numberEmployed : numberEmployed // ignore: cast_nullable_to_non_nullable +as num?,numberIndigenous: freezed == numberIndigenous ? _self.numberIndigenous : numberIndigenous // ignore: cast_nullable_to_non_nullable +as num?,numberNonIndigenous: freezed == numberNonIndigenous ? _self.numberNonIndigenous : numberNonIndigenous // ignore: cast_nullable_to_non_nullable +as num?, + )); +} + + +} + + +/// @nodoc +mixin _$Casualties { + + List? get images; String? get typeDisease; num? get normalLosses; bool? get samplingDone; String? get typeSampling; num? get abnormalLosses; String? get sourceOfHatching; String? get causeAbnormalLosses; +/// Create a copy of Casualties +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$CasualtiesCopyWith get copyWith => _$CasualtiesCopyWithImpl(this as Casualties, _$identity); + + /// Serializes this Casualties to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is Casualties&&const DeepCollectionEquality().equals(other.images, images)&&(identical(other.typeDisease, typeDisease) || other.typeDisease == typeDisease)&&(identical(other.normalLosses, normalLosses) || other.normalLosses == normalLosses)&&(identical(other.samplingDone, samplingDone) || other.samplingDone == samplingDone)&&(identical(other.typeSampling, typeSampling) || other.typeSampling == typeSampling)&&(identical(other.abnormalLosses, abnormalLosses) || other.abnormalLosses == abnormalLosses)&&(identical(other.sourceOfHatching, sourceOfHatching) || other.sourceOfHatching == sourceOfHatching)&&(identical(other.causeAbnormalLosses, causeAbnormalLosses) || other.causeAbnormalLosses == causeAbnormalLosses)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(images),typeDisease,normalLosses,samplingDone,typeSampling,abnormalLosses,sourceOfHatching,causeAbnormalLosses); + +@override +String toString() { + return 'Casualties(images: $images, typeDisease: $typeDisease, normalLosses: $normalLosses, samplingDone: $samplingDone, typeSampling: $typeSampling, abnormalLosses: $abnormalLosses, sourceOfHatching: $sourceOfHatching, causeAbnormalLosses: $causeAbnormalLosses)'; +} + + +} + +/// @nodoc +abstract mixin class $CasualtiesCopyWith<$Res> { + factory $CasualtiesCopyWith(Casualties value, $Res Function(Casualties) _then) = _$CasualtiesCopyWithImpl; +@useResult +$Res call({ + List? images, String? typeDisease, num? normalLosses, bool? samplingDone, String? typeSampling, num? abnormalLosses, String? sourceOfHatching, String? causeAbnormalLosses +}); + + + + +} +/// @nodoc +class _$CasualtiesCopyWithImpl<$Res> + implements $CasualtiesCopyWith<$Res> { + _$CasualtiesCopyWithImpl(this._self, this._then); + + final Casualties _self; + final $Res Function(Casualties) _then; + +/// Create a copy of Casualties +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? images = freezed,Object? typeDisease = freezed,Object? normalLosses = freezed,Object? samplingDone = freezed,Object? typeSampling = freezed,Object? abnormalLosses = freezed,Object? sourceOfHatching = freezed,Object? causeAbnormalLosses = freezed,}) { + return _then(_self.copyWith( +images: freezed == images ? _self.images : images // ignore: cast_nullable_to_non_nullable +as List?,typeDisease: freezed == typeDisease ? _self.typeDisease : typeDisease // ignore: cast_nullable_to_non_nullable +as String?,normalLosses: freezed == normalLosses ? _self.normalLosses : normalLosses // ignore: cast_nullable_to_non_nullable +as num?,samplingDone: freezed == samplingDone ? _self.samplingDone : samplingDone // ignore: cast_nullable_to_non_nullable +as bool?,typeSampling: freezed == typeSampling ? _self.typeSampling : typeSampling // ignore: cast_nullable_to_non_nullable +as String?,abnormalLosses: freezed == abnormalLosses ? _self.abnormalLosses : abnormalLosses // ignore: cast_nullable_to_non_nullable +as num?,sourceOfHatching: freezed == sourceOfHatching ? _self.sourceOfHatching : sourceOfHatching // ignore: cast_nullable_to_non_nullable +as String?,causeAbnormalLosses: freezed == causeAbnormalLosses ? _self.causeAbnormalLosses : causeAbnormalLosses // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [Casualties]. +extension CasualtiesPatterns on Casualties { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _Casualties value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _Casualties() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _Casualties value) $default,){ +final _that = this; +switch (_that) { +case _Casualties(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _Casualties value)? $default,){ +final _that = this; +switch (_that) { +case _Casualties() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( List? images, String? typeDisease, num? normalLosses, bool? samplingDone, String? typeSampling, num? abnormalLosses, String? sourceOfHatching, String? causeAbnormalLosses)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _Casualties() when $default != null: +return $default(_that.images,_that.typeDisease,_that.normalLosses,_that.samplingDone,_that.typeSampling,_that.abnormalLosses,_that.sourceOfHatching,_that.causeAbnormalLosses);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( List? images, String? typeDisease, num? normalLosses, bool? samplingDone, String? typeSampling, num? abnormalLosses, String? sourceOfHatching, String? causeAbnormalLosses) $default,) {final _that = this; +switch (_that) { +case _Casualties(): +return $default(_that.images,_that.typeDisease,_that.normalLosses,_that.samplingDone,_that.typeSampling,_that.abnormalLosses,_that.sourceOfHatching,_that.causeAbnormalLosses);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( List? images, String? typeDisease, num? normalLosses, bool? samplingDone, String? typeSampling, num? abnormalLosses, String? sourceOfHatching, String? causeAbnormalLosses)? $default,) {final _that = this; +switch (_that) { +case _Casualties() when $default != null: +return $default(_that.images,_that.typeDisease,_that.normalLosses,_that.samplingDone,_that.typeSampling,_that.abnormalLosses,_that.sourceOfHatching,_that.causeAbnormalLosses);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _Casualties implements Casualties { + const _Casualties({final List? images, this.typeDisease, this.normalLosses, this.samplingDone, this.typeSampling, this.abnormalLosses, this.sourceOfHatching, this.causeAbnormalLosses}): _images = images; + factory _Casualties.fromJson(Map json) => _$CasualtiesFromJson(json); + + final List? _images; +@override List? get images { + final value = _images; + if (value == null) return null; + if (_images is EqualUnmodifiableListView) return _images; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); +} + +@override final String? typeDisease; +@override final num? normalLosses; +@override final bool? samplingDone; +@override final String? typeSampling; +@override final num? abnormalLosses; +@override final String? sourceOfHatching; +@override final String? causeAbnormalLosses; + +/// Create a copy of Casualties +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$CasualtiesCopyWith<_Casualties> get copyWith => __$CasualtiesCopyWithImpl<_Casualties>(this, _$identity); + +@override +Map toJson() { + return _$CasualtiesToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Casualties&&const DeepCollectionEquality().equals(other._images, _images)&&(identical(other.typeDisease, typeDisease) || other.typeDisease == typeDisease)&&(identical(other.normalLosses, normalLosses) || other.normalLosses == normalLosses)&&(identical(other.samplingDone, samplingDone) || other.samplingDone == samplingDone)&&(identical(other.typeSampling, typeSampling) || other.typeSampling == typeSampling)&&(identical(other.abnormalLosses, abnormalLosses) || other.abnormalLosses == abnormalLosses)&&(identical(other.sourceOfHatching, sourceOfHatching) || other.sourceOfHatching == sourceOfHatching)&&(identical(other.causeAbnormalLosses, causeAbnormalLosses) || other.causeAbnormalLosses == causeAbnormalLosses)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_images),typeDisease,normalLosses,samplingDone,typeSampling,abnormalLosses,sourceOfHatching,causeAbnormalLosses); + +@override +String toString() { + return 'Casualties(images: $images, typeDisease: $typeDisease, normalLosses: $normalLosses, samplingDone: $samplingDone, typeSampling: $typeSampling, abnormalLosses: $abnormalLosses, sourceOfHatching: $sourceOfHatching, causeAbnormalLosses: $causeAbnormalLosses)'; +} + + +} + +/// @nodoc +abstract mixin class _$CasualtiesCopyWith<$Res> implements $CasualtiesCopyWith<$Res> { + factory _$CasualtiesCopyWith(_Casualties value, $Res Function(_Casualties) _then) = __$CasualtiesCopyWithImpl; +@override @useResult +$Res call({ + List? images, String? typeDisease, num? normalLosses, bool? samplingDone, String? typeSampling, num? abnormalLosses, String? sourceOfHatching, String? causeAbnormalLosses +}); + + + + +} +/// @nodoc +class __$CasualtiesCopyWithImpl<$Res> + implements _$CasualtiesCopyWith<$Res> { + __$CasualtiesCopyWithImpl(this._self, this._then); + + final _Casualties _self; + final $Res Function(_Casualties) _then; + +/// Create a copy of Casualties +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? images = freezed,Object? typeDisease = freezed,Object? normalLosses = freezed,Object? samplingDone = freezed,Object? typeSampling = freezed,Object? abnormalLosses = freezed,Object? sourceOfHatching = freezed,Object? causeAbnormalLosses = freezed,}) { + return _then(_Casualties( +images: freezed == images ? _self._images : images // ignore: cast_nullable_to_non_nullable +as List?,typeDisease: freezed == typeDisease ? _self.typeDisease : typeDisease // ignore: cast_nullable_to_non_nullable +as String?,normalLosses: freezed == normalLosses ? _self.normalLosses : normalLosses // ignore: cast_nullable_to_non_nullable +as num?,samplingDone: freezed == samplingDone ? _self.samplingDone : samplingDone // ignore: cast_nullable_to_non_nullable +as bool?,typeSampling: freezed == typeSampling ? _self.typeSampling : typeSampling // ignore: cast_nullable_to_non_nullable +as String?,abnormalLosses: freezed == abnormalLosses ? _self.abnormalLosses : abnormalLosses // ignore: cast_nullable_to_non_nullable +as num?,sourceOfHatching: freezed == sourceOfHatching ? _self.sourceOfHatching : sourceOfHatching // ignore: cast_nullable_to_non_nullable +as String?,causeAbnormalLosses: freezed == causeAbnormalLosses ? _self.causeAbnormalLosses : causeAbnormalLosses // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + + +/// @nodoc +mixin _$Facilities { + + String? get date; num? get amount; bool? get hasFacilities; String? get repaymentStatus; String? get typeOfFacility; String? get requestFacilities; +/// Create a copy of Facilities +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$FacilitiesCopyWith get copyWith => _$FacilitiesCopyWithImpl(this as Facilities, _$identity); + + /// Serializes this Facilities to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is Facilities&&(identical(other.date, date) || other.date == date)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.hasFacilities, hasFacilities) || other.hasFacilities == hasFacilities)&&(identical(other.repaymentStatus, repaymentStatus) || other.repaymentStatus == repaymentStatus)&&(identical(other.typeOfFacility, typeOfFacility) || other.typeOfFacility == typeOfFacility)&&(identical(other.requestFacilities, requestFacilities) || other.requestFacilities == requestFacilities)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,date,amount,hasFacilities,repaymentStatus,typeOfFacility,requestFacilities); + +@override +String toString() { + return 'Facilities(date: $date, amount: $amount, hasFacilities: $hasFacilities, repaymentStatus: $repaymentStatus, typeOfFacility: $typeOfFacility, requestFacilities: $requestFacilities)'; +} + + +} + +/// @nodoc +abstract mixin class $FacilitiesCopyWith<$Res> { + factory $FacilitiesCopyWith(Facilities value, $Res Function(Facilities) _then) = _$FacilitiesCopyWithImpl; +@useResult +$Res call({ + String? date, num? amount, bool? hasFacilities, String? repaymentStatus, String? typeOfFacility, String? requestFacilities +}); + + + + +} +/// @nodoc +class _$FacilitiesCopyWithImpl<$Res> + implements $FacilitiesCopyWith<$Res> { + _$FacilitiesCopyWithImpl(this._self, this._then); + + final Facilities _self; + final $Res Function(Facilities) _then; + +/// Create a copy of Facilities +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? date = freezed,Object? amount = freezed,Object? hasFacilities = freezed,Object? repaymentStatus = freezed,Object? typeOfFacility = freezed,Object? requestFacilities = freezed,}) { + return _then(_self.copyWith( +date: freezed == date ? _self.date : date // ignore: cast_nullable_to_non_nullable +as String?,amount: freezed == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable +as num?,hasFacilities: freezed == hasFacilities ? _self.hasFacilities : hasFacilities // ignore: cast_nullable_to_non_nullable +as bool?,repaymentStatus: freezed == repaymentStatus ? _self.repaymentStatus : repaymentStatus // ignore: cast_nullable_to_non_nullable +as String?,typeOfFacility: freezed == typeOfFacility ? _self.typeOfFacility : typeOfFacility // ignore: cast_nullable_to_non_nullable +as String?,requestFacilities: freezed == requestFacilities ? _self.requestFacilities : requestFacilities // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [Facilities]. +extension FacilitiesPatterns on Facilities { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _Facilities value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _Facilities() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _Facilities value) $default,){ +final _that = this; +switch (_that) { +case _Facilities(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _Facilities value)? $default,){ +final _that = this; +switch (_that) { +case _Facilities() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String? date, num? amount, bool? hasFacilities, String? repaymentStatus, String? typeOfFacility, String? requestFacilities)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _Facilities() when $default != null: +return $default(_that.date,_that.amount,_that.hasFacilities,_that.repaymentStatus,_that.typeOfFacility,_that.requestFacilities);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String? date, num? amount, bool? hasFacilities, String? repaymentStatus, String? typeOfFacility, String? requestFacilities) $default,) {final _that = this; +switch (_that) { +case _Facilities(): +return $default(_that.date,_that.amount,_that.hasFacilities,_that.repaymentStatus,_that.typeOfFacility,_that.requestFacilities);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? date, num? amount, bool? hasFacilities, String? repaymentStatus, String? typeOfFacility, String? requestFacilities)? $default,) {final _that = this; +switch (_that) { +case _Facilities() when $default != null: +return $default(_that.date,_that.amount,_that.hasFacilities,_that.repaymentStatus,_that.typeOfFacility,_that.requestFacilities);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _Facilities implements Facilities { + const _Facilities({this.date, this.amount, this.hasFacilities, this.repaymentStatus, this.typeOfFacility, this.requestFacilities}); + factory _Facilities.fromJson(Map json) => _$FacilitiesFromJson(json); + +@override final String? date; +@override final num? amount; +@override final bool? hasFacilities; +@override final String? repaymentStatus; +@override final String? typeOfFacility; +@override final String? requestFacilities; + +/// Create a copy of Facilities +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$FacilitiesCopyWith<_Facilities> get copyWith => __$FacilitiesCopyWithImpl<_Facilities>(this, _$identity); + +@override +Map toJson() { + return _$FacilitiesToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Facilities&&(identical(other.date, date) || other.date == date)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.hasFacilities, hasFacilities) || other.hasFacilities == hasFacilities)&&(identical(other.repaymentStatus, repaymentStatus) || other.repaymentStatus == repaymentStatus)&&(identical(other.typeOfFacility, typeOfFacility) || other.typeOfFacility == typeOfFacility)&&(identical(other.requestFacilities, requestFacilities) || other.requestFacilities == requestFacilities)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,date,amount,hasFacilities,repaymentStatus,typeOfFacility,requestFacilities); + +@override +String toString() { + return 'Facilities(date: $date, amount: $amount, hasFacilities: $hasFacilities, repaymentStatus: $repaymentStatus, typeOfFacility: $typeOfFacility, requestFacilities: $requestFacilities)'; +} + + +} + +/// @nodoc +abstract mixin class _$FacilitiesCopyWith<$Res> implements $FacilitiesCopyWith<$Res> { + factory _$FacilitiesCopyWith(_Facilities value, $Res Function(_Facilities) _then) = __$FacilitiesCopyWithImpl; +@override @useResult +$Res call({ + String? date, num? amount, bool? hasFacilities, String? repaymentStatus, String? typeOfFacility, String? requestFacilities +}); + + + + +} +/// @nodoc +class __$FacilitiesCopyWithImpl<$Res> + implements _$FacilitiesCopyWith<$Res> { + __$FacilitiesCopyWithImpl(this._self, this._then); + + final _Facilities _self; + final $Res Function(_Facilities) _then; + +/// Create a copy of Facilities +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? date = freezed,Object? amount = freezed,Object? hasFacilities = freezed,Object? repaymentStatus = freezed,Object? typeOfFacility = freezed,Object? requestFacilities = freezed,}) { + return _then(_Facilities( +date: freezed == date ? _self.date : date // ignore: cast_nullable_to_non_nullable +as String?,amount: freezed == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable +as num?,hasFacilities: freezed == hasFacilities ? _self.hasFacilities : hasFacilities // ignore: cast_nullable_to_non_nullable +as bool?,repaymentStatus: freezed == repaymentStatus ? _self.repaymentStatus : repaymentStatus // ignore: cast_nullable_to_non_nullable +as String?,typeOfFacility: freezed == typeOfFacility ? _self.typeOfFacility : typeOfFacility // ignore: cast_nullable_to_non_nullable +as String?,requestFacilities: freezed == requestFacilities ? _self.requestFacilities : requestFacilities // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + + +/// @nodoc +mixin _$InputStatus { + + List? get images; String? get gradeGrain; String? get companyName; String? get inputStatus; String? get trackingCode; String? get typeOfGrain; String? get inventoryUntilVisit; String? get inventoryInWarehouse; +/// Create a copy of InputStatus +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$InputStatusCopyWith get copyWith => _$InputStatusCopyWithImpl(this as InputStatus, _$identity); + + /// Serializes this InputStatus to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is InputStatus&&const DeepCollectionEquality().equals(other.images, images)&&(identical(other.gradeGrain, gradeGrain) || other.gradeGrain == gradeGrain)&&(identical(other.companyName, companyName) || other.companyName == companyName)&&(identical(other.inputStatus, inputStatus) || other.inputStatus == inputStatus)&&(identical(other.trackingCode, trackingCode) || other.trackingCode == trackingCode)&&(identical(other.typeOfGrain, typeOfGrain) || other.typeOfGrain == typeOfGrain)&&(identical(other.inventoryUntilVisit, inventoryUntilVisit) || other.inventoryUntilVisit == inventoryUntilVisit)&&(identical(other.inventoryInWarehouse, inventoryInWarehouse) || other.inventoryInWarehouse == inventoryInWarehouse)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(images),gradeGrain,companyName,inputStatus,trackingCode,typeOfGrain,inventoryUntilVisit,inventoryInWarehouse); + +@override +String toString() { + return 'InputStatus(images: $images, gradeGrain: $gradeGrain, companyName: $companyName, inputStatus: $inputStatus, trackingCode: $trackingCode, typeOfGrain: $typeOfGrain, inventoryUntilVisit: $inventoryUntilVisit, inventoryInWarehouse: $inventoryInWarehouse)'; +} + + +} + +/// @nodoc +abstract mixin class $InputStatusCopyWith<$Res> { + factory $InputStatusCopyWith(InputStatus value, $Res Function(InputStatus) _then) = _$InputStatusCopyWithImpl; +@useResult +$Res call({ + List? images, String? gradeGrain, String? companyName, String? inputStatus, String? trackingCode, String? typeOfGrain, String? inventoryUntilVisit, String? inventoryInWarehouse +}); + + + + +} +/// @nodoc +class _$InputStatusCopyWithImpl<$Res> + implements $InputStatusCopyWith<$Res> { + _$InputStatusCopyWithImpl(this._self, this._then); + + final InputStatus _self; + final $Res Function(InputStatus) _then; + +/// Create a copy of InputStatus +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? images = freezed,Object? gradeGrain = freezed,Object? companyName = freezed,Object? inputStatus = freezed,Object? trackingCode = freezed,Object? typeOfGrain = freezed,Object? inventoryUntilVisit = freezed,Object? inventoryInWarehouse = freezed,}) { + return _then(_self.copyWith( +images: freezed == images ? _self.images : images // ignore: cast_nullable_to_non_nullable +as List?,gradeGrain: freezed == gradeGrain ? _self.gradeGrain : gradeGrain // ignore: cast_nullable_to_non_nullable +as String?,companyName: freezed == companyName ? _self.companyName : companyName // ignore: cast_nullable_to_non_nullable +as String?,inputStatus: freezed == inputStatus ? _self.inputStatus : inputStatus // ignore: cast_nullable_to_non_nullable +as String?,trackingCode: freezed == trackingCode ? _self.trackingCode : trackingCode // ignore: cast_nullable_to_non_nullable +as String?,typeOfGrain: freezed == typeOfGrain ? _self.typeOfGrain : typeOfGrain // ignore: cast_nullable_to_non_nullable +as String?,inventoryUntilVisit: freezed == inventoryUntilVisit ? _self.inventoryUntilVisit : inventoryUntilVisit // ignore: cast_nullable_to_non_nullable +as String?,inventoryInWarehouse: freezed == inventoryInWarehouse ? _self.inventoryInWarehouse : inventoryInWarehouse // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [InputStatus]. +extension InputStatusPatterns on InputStatus { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _InputStatus value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _InputStatus() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _InputStatus value) $default,){ +final _that = this; +switch (_that) { +case _InputStatus(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _InputStatus value)? $default,){ +final _that = this; +switch (_that) { +case _InputStatus() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( List? images, String? gradeGrain, String? companyName, String? inputStatus, String? trackingCode, String? typeOfGrain, String? inventoryUntilVisit, String? inventoryInWarehouse)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _InputStatus() when $default != null: +return $default(_that.images,_that.gradeGrain,_that.companyName,_that.inputStatus,_that.trackingCode,_that.typeOfGrain,_that.inventoryUntilVisit,_that.inventoryInWarehouse);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( List? images, String? gradeGrain, String? companyName, String? inputStatus, String? trackingCode, String? typeOfGrain, String? inventoryUntilVisit, String? inventoryInWarehouse) $default,) {final _that = this; +switch (_that) { +case _InputStatus(): +return $default(_that.images,_that.gradeGrain,_that.companyName,_that.inputStatus,_that.trackingCode,_that.typeOfGrain,_that.inventoryUntilVisit,_that.inventoryInWarehouse);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( List? images, String? gradeGrain, String? companyName, String? inputStatus, String? trackingCode, String? typeOfGrain, String? inventoryUntilVisit, String? inventoryInWarehouse)? $default,) {final _that = this; +switch (_that) { +case _InputStatus() when $default != null: +return $default(_that.images,_that.gradeGrain,_that.companyName,_that.inputStatus,_that.trackingCode,_that.typeOfGrain,_that.inventoryUntilVisit,_that.inventoryInWarehouse);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _InputStatus implements InputStatus { + const _InputStatus({final List? images, this.gradeGrain, this.companyName, this.inputStatus, this.trackingCode, this.typeOfGrain, this.inventoryUntilVisit, this.inventoryInWarehouse}): _images = images; + factory _InputStatus.fromJson(Map json) => _$InputStatusFromJson(json); + + final List? _images; +@override List? get images { + final value = _images; + if (value == null) return null; + if (_images is EqualUnmodifiableListView) return _images; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); +} + +@override final String? gradeGrain; +@override final String? companyName; +@override final String? inputStatus; +@override final String? trackingCode; +@override final String? typeOfGrain; +@override final String? inventoryUntilVisit; +@override final String? inventoryInWarehouse; + +/// Create a copy of InputStatus +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$InputStatusCopyWith<_InputStatus> get copyWith => __$InputStatusCopyWithImpl<_InputStatus>(this, _$identity); + +@override +Map toJson() { + return _$InputStatusToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _InputStatus&&const DeepCollectionEquality().equals(other._images, _images)&&(identical(other.gradeGrain, gradeGrain) || other.gradeGrain == gradeGrain)&&(identical(other.companyName, companyName) || other.companyName == companyName)&&(identical(other.inputStatus, inputStatus) || other.inputStatus == inputStatus)&&(identical(other.trackingCode, trackingCode) || other.trackingCode == trackingCode)&&(identical(other.typeOfGrain, typeOfGrain) || other.typeOfGrain == typeOfGrain)&&(identical(other.inventoryUntilVisit, inventoryUntilVisit) || other.inventoryUntilVisit == inventoryUntilVisit)&&(identical(other.inventoryInWarehouse, inventoryInWarehouse) || other.inventoryInWarehouse == inventoryInWarehouse)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_images),gradeGrain,companyName,inputStatus,trackingCode,typeOfGrain,inventoryUntilVisit,inventoryInWarehouse); + +@override +String toString() { + return 'InputStatus(images: $images, gradeGrain: $gradeGrain, companyName: $companyName, inputStatus: $inputStatus, trackingCode: $trackingCode, typeOfGrain: $typeOfGrain, inventoryUntilVisit: $inventoryUntilVisit, inventoryInWarehouse: $inventoryInWarehouse)'; +} + + +} + +/// @nodoc +abstract mixin class _$InputStatusCopyWith<$Res> implements $InputStatusCopyWith<$Res> { + factory _$InputStatusCopyWith(_InputStatus value, $Res Function(_InputStatus) _then) = __$InputStatusCopyWithImpl; +@override @useResult +$Res call({ + List? images, String? gradeGrain, String? companyName, String? inputStatus, String? trackingCode, String? typeOfGrain, String? inventoryUntilVisit, String? inventoryInWarehouse +}); + + + + +} +/// @nodoc +class __$InputStatusCopyWithImpl<$Res> + implements _$InputStatusCopyWith<$Res> { + __$InputStatusCopyWithImpl(this._self, this._then); + + final _InputStatus _self; + final $Res Function(_InputStatus) _then; + +/// Create a copy of InputStatus +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? images = freezed,Object? gradeGrain = freezed,Object? companyName = freezed,Object? inputStatus = freezed,Object? trackingCode = freezed,Object? typeOfGrain = freezed,Object? inventoryUntilVisit = freezed,Object? inventoryInWarehouse = freezed,}) { + return _then(_InputStatus( +images: freezed == images ? _self._images : images // ignore: cast_nullable_to_non_nullable +as List?,gradeGrain: freezed == gradeGrain ? _self.gradeGrain : gradeGrain // ignore: cast_nullable_to_non_nullable +as String?,companyName: freezed == companyName ? _self.companyName : companyName // ignore: cast_nullable_to_non_nullable +as String?,inputStatus: freezed == inputStatus ? _self.inputStatus : inputStatus // ignore: cast_nullable_to_non_nullable +as String?,trackingCode: freezed == trackingCode ? _self.trackingCode : trackingCode // ignore: cast_nullable_to_non_nullable +as String?,typeOfGrain: freezed == typeOfGrain ? _self.typeOfGrain : typeOfGrain // ignore: cast_nullable_to_non_nullable +as String?,inventoryUntilVisit: freezed == inventoryUntilVisit ? _self.inventoryUntilVisit : inventoryUntilVisit // ignore: cast_nullable_to_non_nullable +as String?,inventoryInWarehouse: freezed == inventoryInWarehouse ? _self.inventoryInWarehouse : inventoryInWarehouse // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + + +/// @nodoc +mixin _$TechnicalOfficer { + + String? get technicalHealthOfficer; String? get technicalEngineeringOfficer; +/// Create a copy of TechnicalOfficer +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$TechnicalOfficerCopyWith get copyWith => _$TechnicalOfficerCopyWithImpl(this as TechnicalOfficer, _$identity); + + /// Serializes this TechnicalOfficer to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is TechnicalOfficer&&(identical(other.technicalHealthOfficer, technicalHealthOfficer) || other.technicalHealthOfficer == technicalHealthOfficer)&&(identical(other.technicalEngineeringOfficer, technicalEngineeringOfficer) || other.technicalEngineeringOfficer == technicalEngineeringOfficer)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,technicalHealthOfficer,technicalEngineeringOfficer); + +@override +String toString() { + return 'TechnicalOfficer(technicalHealthOfficer: $technicalHealthOfficer, technicalEngineeringOfficer: $technicalEngineeringOfficer)'; +} + + +} + +/// @nodoc +abstract mixin class $TechnicalOfficerCopyWith<$Res> { + factory $TechnicalOfficerCopyWith(TechnicalOfficer value, $Res Function(TechnicalOfficer) _then) = _$TechnicalOfficerCopyWithImpl; +@useResult +$Res call({ + String? technicalHealthOfficer, String? technicalEngineeringOfficer +}); + + + + +} +/// @nodoc +class _$TechnicalOfficerCopyWithImpl<$Res> + implements $TechnicalOfficerCopyWith<$Res> { + _$TechnicalOfficerCopyWithImpl(this._self, this._then); + + final TechnicalOfficer _self; + final $Res Function(TechnicalOfficer) _then; + +/// Create a copy of TechnicalOfficer +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? technicalHealthOfficer = freezed,Object? technicalEngineeringOfficer = freezed,}) { + return _then(_self.copyWith( +technicalHealthOfficer: freezed == technicalHealthOfficer ? _self.technicalHealthOfficer : technicalHealthOfficer // ignore: cast_nullable_to_non_nullable +as String?,technicalEngineeringOfficer: freezed == technicalEngineeringOfficer ? _self.technicalEngineeringOfficer : technicalEngineeringOfficer // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [TechnicalOfficer]. +extension TechnicalOfficerPatterns on TechnicalOfficer { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _TechnicalOfficer value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _TechnicalOfficer() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _TechnicalOfficer value) $default,){ +final _that = this; +switch (_that) { +case _TechnicalOfficer(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _TechnicalOfficer value)? $default,){ +final _that = this; +switch (_that) { +case _TechnicalOfficer() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String? technicalHealthOfficer, String? technicalEngineeringOfficer)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _TechnicalOfficer() when $default != null: +return $default(_that.technicalHealthOfficer,_that.technicalEngineeringOfficer);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String? technicalHealthOfficer, String? technicalEngineeringOfficer) $default,) {final _that = this; +switch (_that) { +case _TechnicalOfficer(): +return $default(_that.technicalHealthOfficer,_that.technicalEngineeringOfficer);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? technicalHealthOfficer, String? technicalEngineeringOfficer)? $default,) {final _that = this; +switch (_that) { +case _TechnicalOfficer() when $default != null: +return $default(_that.technicalHealthOfficer,_that.technicalEngineeringOfficer);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _TechnicalOfficer implements TechnicalOfficer { + const _TechnicalOfficer({this.technicalHealthOfficer, this.technicalEngineeringOfficer}); + factory _TechnicalOfficer.fromJson(Map json) => _$TechnicalOfficerFromJson(json); + +@override final String? technicalHealthOfficer; +@override final String? technicalEngineeringOfficer; + +/// Create a copy of TechnicalOfficer +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$TechnicalOfficerCopyWith<_TechnicalOfficer> get copyWith => __$TechnicalOfficerCopyWithImpl<_TechnicalOfficer>(this, _$identity); + +@override +Map toJson() { + return _$TechnicalOfficerToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _TechnicalOfficer&&(identical(other.technicalHealthOfficer, technicalHealthOfficer) || other.technicalHealthOfficer == technicalHealthOfficer)&&(identical(other.technicalEngineeringOfficer, technicalEngineeringOfficer) || other.technicalEngineeringOfficer == technicalEngineeringOfficer)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,technicalHealthOfficer,technicalEngineeringOfficer); + +@override +String toString() { + return 'TechnicalOfficer(technicalHealthOfficer: $technicalHealthOfficer, technicalEngineeringOfficer: $technicalEngineeringOfficer)'; +} + + +} + +/// @nodoc +abstract mixin class _$TechnicalOfficerCopyWith<$Res> implements $TechnicalOfficerCopyWith<$Res> { + factory _$TechnicalOfficerCopyWith(_TechnicalOfficer value, $Res Function(_TechnicalOfficer) _then) = __$TechnicalOfficerCopyWithImpl; +@override @useResult +$Res call({ + String? technicalHealthOfficer, String? technicalEngineeringOfficer +}); + + + + +} +/// @nodoc +class __$TechnicalOfficerCopyWithImpl<$Res> + implements _$TechnicalOfficerCopyWith<$Res> { + __$TechnicalOfficerCopyWithImpl(this._self, this._then); + + final _TechnicalOfficer _self; + final $Res Function(_TechnicalOfficer) _then; + +/// Create a copy of TechnicalOfficer +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? technicalHealthOfficer = freezed,Object? technicalEngineeringOfficer = freezed,}) { + return _then(_TechnicalOfficer( +technicalHealthOfficer: freezed == technicalHealthOfficer ? _self.technicalHealthOfficer : technicalHealthOfficer // ignore: cast_nullable_to_non_nullable +as String?,technicalEngineeringOfficer: freezed == technicalEngineeringOfficer ? _self.technicalEngineeringOfficer : technicalEngineeringOfficer // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + + +/// @nodoc +mixin _$InfrastructureEnergy { + + String? get fuelType; String? get generatorType; String? get powerCutHour; String? get generatorCount; String? get generatorModel; String? get additionalNotes; String? get generatorCapacity; String? get powerCutDuration; String? get generatorPerformance; bool? get hasPowerCutHistory; String? get emergencyFuelInventory; +/// Create a copy of InfrastructureEnergy +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$InfrastructureEnergyCopyWith get copyWith => _$InfrastructureEnergyCopyWithImpl(this as InfrastructureEnergy, _$identity); + + /// Serializes this InfrastructureEnergy to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is InfrastructureEnergy&&(identical(other.fuelType, fuelType) || other.fuelType == fuelType)&&(identical(other.generatorType, generatorType) || other.generatorType == generatorType)&&(identical(other.powerCutHour, powerCutHour) || other.powerCutHour == powerCutHour)&&(identical(other.generatorCount, generatorCount) || other.generatorCount == generatorCount)&&(identical(other.generatorModel, generatorModel) || other.generatorModel == generatorModel)&&(identical(other.additionalNotes, additionalNotes) || other.additionalNotes == additionalNotes)&&(identical(other.generatorCapacity, generatorCapacity) || other.generatorCapacity == generatorCapacity)&&(identical(other.powerCutDuration, powerCutDuration) || other.powerCutDuration == powerCutDuration)&&(identical(other.generatorPerformance, generatorPerformance) || other.generatorPerformance == generatorPerformance)&&(identical(other.hasPowerCutHistory, hasPowerCutHistory) || other.hasPowerCutHistory == hasPowerCutHistory)&&(identical(other.emergencyFuelInventory, emergencyFuelInventory) || other.emergencyFuelInventory == emergencyFuelInventory)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,fuelType,generatorType,powerCutHour,generatorCount,generatorModel,additionalNotes,generatorCapacity,powerCutDuration,generatorPerformance,hasPowerCutHistory,emergencyFuelInventory); + +@override +String toString() { + return 'InfrastructureEnergy(fuelType: $fuelType, generatorType: $generatorType, powerCutHour: $powerCutHour, generatorCount: $generatorCount, generatorModel: $generatorModel, additionalNotes: $additionalNotes, generatorCapacity: $generatorCapacity, powerCutDuration: $powerCutDuration, generatorPerformance: $generatorPerformance, hasPowerCutHistory: $hasPowerCutHistory, emergencyFuelInventory: $emergencyFuelInventory)'; +} + + +} + +/// @nodoc +abstract mixin class $InfrastructureEnergyCopyWith<$Res> { + factory $InfrastructureEnergyCopyWith(InfrastructureEnergy value, $Res Function(InfrastructureEnergy) _then) = _$InfrastructureEnergyCopyWithImpl; +@useResult +$Res call({ + String? fuelType, String? generatorType, String? powerCutHour, String? generatorCount, String? generatorModel, String? additionalNotes, String? generatorCapacity, String? powerCutDuration, String? generatorPerformance, bool? hasPowerCutHistory, String? emergencyFuelInventory +}); + + + + +} +/// @nodoc +class _$InfrastructureEnergyCopyWithImpl<$Res> + implements $InfrastructureEnergyCopyWith<$Res> { + _$InfrastructureEnergyCopyWithImpl(this._self, this._then); + + final InfrastructureEnergy _self; + final $Res Function(InfrastructureEnergy) _then; + +/// Create a copy of InfrastructureEnergy +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? fuelType = freezed,Object? generatorType = freezed,Object? powerCutHour = freezed,Object? generatorCount = freezed,Object? generatorModel = freezed,Object? additionalNotes = freezed,Object? generatorCapacity = freezed,Object? powerCutDuration = freezed,Object? generatorPerformance = freezed,Object? hasPowerCutHistory = freezed,Object? emergencyFuelInventory = freezed,}) { + return _then(_self.copyWith( +fuelType: freezed == fuelType ? _self.fuelType : fuelType // ignore: cast_nullable_to_non_nullable +as String?,generatorType: freezed == generatorType ? _self.generatorType : generatorType // ignore: cast_nullable_to_non_nullable +as String?,powerCutHour: freezed == powerCutHour ? _self.powerCutHour : powerCutHour // ignore: cast_nullable_to_non_nullable +as String?,generatorCount: freezed == generatorCount ? _self.generatorCount : generatorCount // ignore: cast_nullable_to_non_nullable +as String?,generatorModel: freezed == generatorModel ? _self.generatorModel : generatorModel // ignore: cast_nullable_to_non_nullable +as String?,additionalNotes: freezed == additionalNotes ? _self.additionalNotes : additionalNotes // ignore: cast_nullable_to_non_nullable +as String?,generatorCapacity: freezed == generatorCapacity ? _self.generatorCapacity : generatorCapacity // ignore: cast_nullable_to_non_nullable +as String?,powerCutDuration: freezed == powerCutDuration ? _self.powerCutDuration : powerCutDuration // ignore: cast_nullable_to_non_nullable +as String?,generatorPerformance: freezed == generatorPerformance ? _self.generatorPerformance : generatorPerformance // ignore: cast_nullable_to_non_nullable +as String?,hasPowerCutHistory: freezed == hasPowerCutHistory ? _self.hasPowerCutHistory : hasPowerCutHistory // ignore: cast_nullable_to_non_nullable +as bool?,emergencyFuelInventory: freezed == emergencyFuelInventory ? _self.emergencyFuelInventory : emergencyFuelInventory // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [InfrastructureEnergy]. +extension InfrastructureEnergyPatterns on InfrastructureEnergy { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _InfrastructureEnergy value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _InfrastructureEnergy() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _InfrastructureEnergy value) $default,){ +final _that = this; +switch (_that) { +case _InfrastructureEnergy(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _InfrastructureEnergy value)? $default,){ +final _that = this; +switch (_that) { +case _InfrastructureEnergy() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( String? fuelType, String? generatorType, String? powerCutHour, String? generatorCount, String? generatorModel, String? additionalNotes, String? generatorCapacity, String? powerCutDuration, String? generatorPerformance, bool? hasPowerCutHistory, String? emergencyFuelInventory)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _InfrastructureEnergy() when $default != null: +return $default(_that.fuelType,_that.generatorType,_that.powerCutHour,_that.generatorCount,_that.generatorModel,_that.additionalNotes,_that.generatorCapacity,_that.powerCutDuration,_that.generatorPerformance,_that.hasPowerCutHistory,_that.emergencyFuelInventory);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( String? fuelType, String? generatorType, String? powerCutHour, String? generatorCount, String? generatorModel, String? additionalNotes, String? generatorCapacity, String? powerCutDuration, String? generatorPerformance, bool? hasPowerCutHistory, String? emergencyFuelInventory) $default,) {final _that = this; +switch (_that) { +case _InfrastructureEnergy(): +return $default(_that.fuelType,_that.generatorType,_that.powerCutHour,_that.generatorCount,_that.generatorModel,_that.additionalNotes,_that.generatorCapacity,_that.powerCutDuration,_that.generatorPerformance,_that.hasPowerCutHistory,_that.emergencyFuelInventory);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String? fuelType, String? generatorType, String? powerCutHour, String? generatorCount, String? generatorModel, String? additionalNotes, String? generatorCapacity, String? powerCutDuration, String? generatorPerformance, bool? hasPowerCutHistory, String? emergencyFuelInventory)? $default,) {final _that = this; +switch (_that) { +case _InfrastructureEnergy() when $default != null: +return $default(_that.fuelType,_that.generatorType,_that.powerCutHour,_that.generatorCount,_that.generatorModel,_that.additionalNotes,_that.generatorCapacity,_that.powerCutDuration,_that.generatorPerformance,_that.hasPowerCutHistory,_that.emergencyFuelInventory);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _InfrastructureEnergy implements InfrastructureEnergy { + const _InfrastructureEnergy({this.fuelType, this.generatorType, this.powerCutHour, this.generatorCount, this.generatorModel, this.additionalNotes, this.generatorCapacity, this.powerCutDuration, this.generatorPerformance, this.hasPowerCutHistory, this.emergencyFuelInventory}); + factory _InfrastructureEnergy.fromJson(Map json) => _$InfrastructureEnergyFromJson(json); + +@override final String? fuelType; +@override final String? generatorType; +@override final String? powerCutHour; +@override final String? generatorCount; +@override final String? generatorModel; +@override final String? additionalNotes; +@override final String? generatorCapacity; +@override final String? powerCutDuration; +@override final String? generatorPerformance; +@override final bool? hasPowerCutHistory; +@override final String? emergencyFuelInventory; + +/// Create a copy of InfrastructureEnergy +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$InfrastructureEnergyCopyWith<_InfrastructureEnergy> get copyWith => __$InfrastructureEnergyCopyWithImpl<_InfrastructureEnergy>(this, _$identity); + +@override +Map toJson() { + return _$InfrastructureEnergyToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _InfrastructureEnergy&&(identical(other.fuelType, fuelType) || other.fuelType == fuelType)&&(identical(other.generatorType, generatorType) || other.generatorType == generatorType)&&(identical(other.powerCutHour, powerCutHour) || other.powerCutHour == powerCutHour)&&(identical(other.generatorCount, generatorCount) || other.generatorCount == generatorCount)&&(identical(other.generatorModel, generatorModel) || other.generatorModel == generatorModel)&&(identical(other.additionalNotes, additionalNotes) || other.additionalNotes == additionalNotes)&&(identical(other.generatorCapacity, generatorCapacity) || other.generatorCapacity == generatorCapacity)&&(identical(other.powerCutDuration, powerCutDuration) || other.powerCutDuration == powerCutDuration)&&(identical(other.generatorPerformance, generatorPerformance) || other.generatorPerformance == generatorPerformance)&&(identical(other.hasPowerCutHistory, hasPowerCutHistory) || other.hasPowerCutHistory == hasPowerCutHistory)&&(identical(other.emergencyFuelInventory, emergencyFuelInventory) || other.emergencyFuelInventory == emergencyFuelInventory)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,fuelType,generatorType,powerCutHour,generatorCount,generatorModel,additionalNotes,generatorCapacity,powerCutDuration,generatorPerformance,hasPowerCutHistory,emergencyFuelInventory); + +@override +String toString() { + return 'InfrastructureEnergy(fuelType: $fuelType, generatorType: $generatorType, powerCutHour: $powerCutHour, generatorCount: $generatorCount, generatorModel: $generatorModel, additionalNotes: $additionalNotes, generatorCapacity: $generatorCapacity, powerCutDuration: $powerCutDuration, generatorPerformance: $generatorPerformance, hasPowerCutHistory: $hasPowerCutHistory, emergencyFuelInventory: $emergencyFuelInventory)'; +} + + +} + +/// @nodoc +abstract mixin class _$InfrastructureEnergyCopyWith<$Res> implements $InfrastructureEnergyCopyWith<$Res> { + factory _$InfrastructureEnergyCopyWith(_InfrastructureEnergy value, $Res Function(_InfrastructureEnergy) _then) = __$InfrastructureEnergyCopyWithImpl; +@override @useResult +$Res call({ + String? fuelType, String? generatorType, String? powerCutHour, String? generatorCount, String? generatorModel, String? additionalNotes, String? generatorCapacity, String? powerCutDuration, String? generatorPerformance, bool? hasPowerCutHistory, String? emergencyFuelInventory +}); + + + + +} +/// @nodoc +class __$InfrastructureEnergyCopyWithImpl<$Res> + implements _$InfrastructureEnergyCopyWith<$Res> { + __$InfrastructureEnergyCopyWithImpl(this._self, this._then); + + final _InfrastructureEnergy _self; + final $Res Function(_InfrastructureEnergy) _then; + +/// Create a copy of InfrastructureEnergy +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? fuelType = freezed,Object? generatorType = freezed,Object? powerCutHour = freezed,Object? generatorCount = freezed,Object? generatorModel = freezed,Object? additionalNotes = freezed,Object? generatorCapacity = freezed,Object? powerCutDuration = freezed,Object? generatorPerformance = freezed,Object? hasPowerCutHistory = freezed,Object? emergencyFuelInventory = freezed,}) { + return _then(_InfrastructureEnergy( +fuelType: freezed == fuelType ? _self.fuelType : fuelType // ignore: cast_nullable_to_non_nullable +as String?,generatorType: freezed == generatorType ? _self.generatorType : generatorType // ignore: cast_nullable_to_non_nullable +as String?,powerCutHour: freezed == powerCutHour ? _self.powerCutHour : powerCutHour // ignore: cast_nullable_to_non_nullable +as String?,generatorCount: freezed == generatorCount ? _self.generatorCount : generatorCount // ignore: cast_nullable_to_non_nullable +as String?,generatorModel: freezed == generatorModel ? _self.generatorModel : generatorModel // ignore: cast_nullable_to_non_nullable +as String?,additionalNotes: freezed == additionalNotes ? _self.additionalNotes : additionalNotes // ignore: cast_nullable_to_non_nullable +as String?,generatorCapacity: freezed == generatorCapacity ? _self.generatorCapacity : generatorCapacity // ignore: cast_nullable_to_non_nullable +as String?,powerCutDuration: freezed == powerCutDuration ? _self.powerCutDuration : powerCutDuration // ignore: cast_nullable_to_non_nullable +as String?,generatorPerformance: freezed == generatorPerformance ? _self.generatorPerformance : generatorPerformance // ignore: cast_nullable_to_non_nullable +as String?,hasPowerCutHistory: freezed == hasPowerCutHistory ? _self.hasPowerCutHistory : hasPowerCutHistory // ignore: cast_nullable_to_non_nullable +as bool?,emergencyFuelInventory: freezed == emergencyFuelInventory ? _self.emergencyFuelInventory : emergencyFuelInventory // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + + +/// @nodoc +mixin _$GeneralConditionHall { + + List? get images; String? get temperature; String? get bedCondition; String? get healthStatus; String? get ventilationStatus; String? get drinkingWaterSource; String? get drinkingWaterQuality; +/// Create a copy of GeneralConditionHall +/// with the given fields replaced by the non-null parameter values. +@JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +$GeneralConditionHallCopyWith get copyWith => _$GeneralConditionHallCopyWithImpl(this as GeneralConditionHall, _$identity); + + /// Serializes this GeneralConditionHall to a JSON map. + Map toJson(); + + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is GeneralConditionHall&&const DeepCollectionEquality().equals(other.images, images)&&(identical(other.temperature, temperature) || other.temperature == temperature)&&(identical(other.bedCondition, bedCondition) || other.bedCondition == bedCondition)&&(identical(other.healthStatus, healthStatus) || other.healthStatus == healthStatus)&&(identical(other.ventilationStatus, ventilationStatus) || other.ventilationStatus == ventilationStatus)&&(identical(other.drinkingWaterSource, drinkingWaterSource) || other.drinkingWaterSource == drinkingWaterSource)&&(identical(other.drinkingWaterQuality, drinkingWaterQuality) || other.drinkingWaterQuality == drinkingWaterQuality)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(images),temperature,bedCondition,healthStatus,ventilationStatus,drinkingWaterSource,drinkingWaterQuality); + +@override +String toString() { + return 'GeneralConditionHall(images: $images, temperature: $temperature, bedCondition: $bedCondition, healthStatus: $healthStatus, ventilationStatus: $ventilationStatus, drinkingWaterSource: $drinkingWaterSource, drinkingWaterQuality: $drinkingWaterQuality)'; +} + + +} + +/// @nodoc +abstract mixin class $GeneralConditionHallCopyWith<$Res> { + factory $GeneralConditionHallCopyWith(GeneralConditionHall value, $Res Function(GeneralConditionHall) _then) = _$GeneralConditionHallCopyWithImpl; +@useResult +$Res call({ + List? images, String? temperature, String? bedCondition, String? healthStatus, String? ventilationStatus, String? drinkingWaterSource, String? drinkingWaterQuality +}); + + + + +} +/// @nodoc +class _$GeneralConditionHallCopyWithImpl<$Res> + implements $GeneralConditionHallCopyWith<$Res> { + _$GeneralConditionHallCopyWithImpl(this._self, this._then); + + final GeneralConditionHall _self; + final $Res Function(GeneralConditionHall) _then; + +/// Create a copy of GeneralConditionHall +/// with the given fields replaced by the non-null parameter values. +@pragma('vm:prefer-inline') @override $Res call({Object? images = freezed,Object? temperature = freezed,Object? bedCondition = freezed,Object? healthStatus = freezed,Object? ventilationStatus = freezed,Object? drinkingWaterSource = freezed,Object? drinkingWaterQuality = freezed,}) { + return _then(_self.copyWith( +images: freezed == images ? _self.images : images // ignore: cast_nullable_to_non_nullable +as List?,temperature: freezed == temperature ? _self.temperature : temperature // ignore: cast_nullable_to_non_nullable +as String?,bedCondition: freezed == bedCondition ? _self.bedCondition : bedCondition // ignore: cast_nullable_to_non_nullable +as String?,healthStatus: freezed == healthStatus ? _self.healthStatus : healthStatus // ignore: cast_nullable_to_non_nullable +as String?,ventilationStatus: freezed == ventilationStatus ? _self.ventilationStatus : ventilationStatus // ignore: cast_nullable_to_non_nullable +as String?,drinkingWaterSource: freezed == drinkingWaterSource ? _self.drinkingWaterSource : drinkingWaterSource // ignore: cast_nullable_to_non_nullable +as String?,drinkingWaterQuality: freezed == drinkingWaterQuality ? _self.drinkingWaterQuality : drinkingWaterQuality // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + +} + + +/// Adds pattern-matching-related methods to [GeneralConditionHall]. +extension GeneralConditionHallPatterns on GeneralConditionHall { +/// A variant of `map` that fallback to returning `orElse`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeMap(TResult Function( _GeneralConditionHall value)? $default,{required TResult orElse(),}){ +final _that = this; +switch (_that) { +case _GeneralConditionHall() when $default != null: +return $default(_that);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// Callbacks receives the raw object, upcasted. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case final Subclass2 value: +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult map(TResult Function( _GeneralConditionHall value) $default,){ +final _that = this; +switch (_that) { +case _GeneralConditionHall(): +return $default(_that);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `map` that fallback to returning `null`. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case final Subclass value: +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? mapOrNull(TResult? Function( _GeneralConditionHall value)? $default,){ +final _that = this; +switch (_that) { +case _GeneralConditionHall() when $default != null: +return $default(_that);case _: + return null; + +} +} +/// A variant of `when` that fallback to an `orElse` callback. +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return orElse(); +/// } +/// ``` + +@optionalTypeArgs TResult maybeWhen(TResult Function( List? images, String? temperature, String? bedCondition, String? healthStatus, String? ventilationStatus, String? drinkingWaterSource, String? drinkingWaterQuality)? $default,{required TResult orElse(),}) {final _that = this; +switch (_that) { +case _GeneralConditionHall() when $default != null: +return $default(_that.images,_that.temperature,_that.bedCondition,_that.healthStatus,_that.ventilationStatus,_that.drinkingWaterSource,_that.drinkingWaterQuality);case _: + return orElse(); + +} +} +/// A `switch`-like method, using callbacks. +/// +/// As opposed to `map`, this offers destructuring. +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case Subclass2(:final field2): +/// return ...; +/// } +/// ``` + +@optionalTypeArgs TResult when(TResult Function( List? images, String? temperature, String? bedCondition, String? healthStatus, String? ventilationStatus, String? drinkingWaterSource, String? drinkingWaterQuality) $default,) {final _that = this; +switch (_that) { +case _GeneralConditionHall(): +return $default(_that.images,_that.temperature,_that.bedCondition,_that.healthStatus,_that.ventilationStatus,_that.drinkingWaterSource,_that.drinkingWaterQuality);case _: + throw StateError('Unexpected subclass'); + +} +} +/// A variant of `when` that fallback to returning `null` +/// +/// It is equivalent to doing: +/// ```dart +/// switch (sealedClass) { +/// case Subclass(:final field): +/// return ...; +/// case _: +/// return null; +/// } +/// ``` + +@optionalTypeArgs TResult? whenOrNull(TResult? Function( List? images, String? temperature, String? bedCondition, String? healthStatus, String? ventilationStatus, String? drinkingWaterSource, String? drinkingWaterQuality)? $default,) {final _that = this; +switch (_that) { +case _GeneralConditionHall() when $default != null: +return $default(_that.images,_that.temperature,_that.bedCondition,_that.healthStatus,_that.ventilationStatus,_that.drinkingWaterSource,_that.drinkingWaterQuality);case _: + return null; + +} +} + +} + +/// @nodoc +@JsonSerializable() + +class _GeneralConditionHall implements GeneralConditionHall { + const _GeneralConditionHall({final List? images, this.temperature, this.bedCondition, this.healthStatus, this.ventilationStatus, this.drinkingWaterSource, this.drinkingWaterQuality}): _images = images; + factory _GeneralConditionHall.fromJson(Map json) => _$GeneralConditionHallFromJson(json); + + final List? _images; +@override List? get images { + final value = _images; + if (value == null) return null; + if (_images is EqualUnmodifiableListView) return _images; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(value); +} + +@override final String? temperature; +@override final String? bedCondition; +@override final String? healthStatus; +@override final String? ventilationStatus; +@override final String? drinkingWaterSource; +@override final String? drinkingWaterQuality; + +/// Create a copy of GeneralConditionHall +/// with the given fields replaced by the non-null parameter values. +@override @JsonKey(includeFromJson: false, includeToJson: false) +@pragma('vm:prefer-inline') +_$GeneralConditionHallCopyWith<_GeneralConditionHall> get copyWith => __$GeneralConditionHallCopyWithImpl<_GeneralConditionHall>(this, _$identity); + +@override +Map toJson() { + return _$GeneralConditionHallToJson(this, ); +} + +@override +bool operator ==(Object other) { + return identical(this, other) || (other.runtimeType == runtimeType&&other is _GeneralConditionHall&&const DeepCollectionEquality().equals(other._images, _images)&&(identical(other.temperature, temperature) || other.temperature == temperature)&&(identical(other.bedCondition, bedCondition) || other.bedCondition == bedCondition)&&(identical(other.healthStatus, healthStatus) || other.healthStatus == healthStatus)&&(identical(other.ventilationStatus, ventilationStatus) || other.ventilationStatus == ventilationStatus)&&(identical(other.drinkingWaterSource, drinkingWaterSource) || other.drinkingWaterSource == drinkingWaterSource)&&(identical(other.drinkingWaterQuality, drinkingWaterQuality) || other.drinkingWaterQuality == drinkingWaterQuality)); +} + +@JsonKey(includeFromJson: false, includeToJson: false) +@override +int get hashCode => Object.hash(runtimeType,const DeepCollectionEquality().hash(_images),temperature,bedCondition,healthStatus,ventilationStatus,drinkingWaterSource,drinkingWaterQuality); + +@override +String toString() { + return 'GeneralConditionHall(images: $images, temperature: $temperature, bedCondition: $bedCondition, healthStatus: $healthStatus, ventilationStatus: $ventilationStatus, drinkingWaterSource: $drinkingWaterSource, drinkingWaterQuality: $drinkingWaterQuality)'; +} + + +} + +/// @nodoc +abstract mixin class _$GeneralConditionHallCopyWith<$Res> implements $GeneralConditionHallCopyWith<$Res> { + factory _$GeneralConditionHallCopyWith(_GeneralConditionHall value, $Res Function(_GeneralConditionHall) _then) = __$GeneralConditionHallCopyWithImpl; +@override @useResult +$Res call({ + List? images, String? temperature, String? bedCondition, String? healthStatus, String? ventilationStatus, String? drinkingWaterSource, String? drinkingWaterQuality +}); + + + + +} +/// @nodoc +class __$GeneralConditionHallCopyWithImpl<$Res> + implements _$GeneralConditionHallCopyWith<$Res> { + __$GeneralConditionHallCopyWithImpl(this._self, this._then); + + final _GeneralConditionHall _self; + final $Res Function(_GeneralConditionHall) _then; + +/// Create a copy of GeneralConditionHall +/// with the given fields replaced by the non-null parameter values. +@override @pragma('vm:prefer-inline') $Res call({Object? images = freezed,Object? temperature = freezed,Object? bedCondition = freezed,Object? healthStatus = freezed,Object? ventilationStatus = freezed,Object? drinkingWaterSource = freezed,Object? drinkingWaterQuality = freezed,}) { + return _then(_GeneralConditionHall( +images: freezed == images ? _self._images : images // ignore: cast_nullable_to_non_nullable +as List?,temperature: freezed == temperature ? _self.temperature : temperature // ignore: cast_nullable_to_non_nullable +as String?,bedCondition: freezed == bedCondition ? _self.bedCondition : bedCondition // ignore: cast_nullable_to_non_nullable +as String?,healthStatus: freezed == healthStatus ? _self.healthStatus : healthStatus // ignore: cast_nullable_to_non_nullable +as String?,ventilationStatus: freezed == ventilationStatus ? _self.ventilationStatus : ventilationStatus // ignore: cast_nullable_to_non_nullable +as String?,drinkingWaterSource: freezed == drinkingWaterSource ? _self.drinkingWaterSource : drinkingWaterSource // ignore: cast_nullable_to_non_nullable +as String?,drinkingWaterQuality: freezed == drinkingWaterQuality ? _self.drinkingWaterQuality : drinkingWaterQuality // ignore: cast_nullable_to_non_nullable +as String?, + )); +} + + +} + +// dart format on diff --git a/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.g.dart new file mode 100644 index 0000000..c772d69 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.g.dart @@ -0,0 +1,339 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'poultry_science_report.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_PoultryScienceReport _$PoultryScienceReportFromJson( + Map json, +) => _PoultryScienceReport( + id: (json['id'] as num?)?.toInt(), + poultryScience: json['poultry_science'] == null + ? null + : PoultryScienceRef.fromJson( + json['poultry_science'] as Map, + ), + hatching: json['hatching'] == null + ? null + : HatchingModel.fromJson(json['hatching'] as Map), + user: json['user'] == null + ? null + : UserRef.fromJson(json['user'] as Map), + key: json['key'] as String?, + createDate: json['create_date'] as String?, + modifyDate: json['modify_date'] as String?, + trash: json['trash'] as bool?, + date: json['date'] as String?, + image: json['image'] as String?, + lat: json['lat'] as num?, + log: json['log'] as num?, + reporterFullname: json['reporter_fullname'] as String?, + reporterMobile: json['reporter_mobile'] as String?, + reporterRole: json['reporter_role'] as String?, + state: json['state'] as String?, + realQuantityAi: json['real_quantity_ai'] as num?, + messageAi: json['message_ai'] as String?, + realQuantity: json['real_quantity'] as num?, + message: json['message'] as String?, + messageRegistererFullname: json['message_registerer_fullname'] as String?, + messageRegistererMobile: json['message_registerer_mobile'] as String?, + messageRegistererRole: json['message_registerer_role'] as String?, + reportInformation: json['report_information'] == null + ? null + : ReportInformation.fromJson( + json['report_information'] as Map, + ), + createdBy: json['created_by'] as String?, + modifiedBy: json['modified_by'] as String?, +); + +Map _$PoultryScienceReportToJson( + _PoultryScienceReport instance, +) => { + 'id': instance.id, + 'poultry_science': instance.poultryScience, + 'hatching': instance.hatching, + 'user': instance.user, + 'key': instance.key, + 'create_date': instance.createDate, + 'modify_date': instance.modifyDate, + 'trash': instance.trash, + 'date': instance.date, + 'image': instance.image, + 'lat': instance.lat, + 'log': instance.log, + 'reporter_fullname': instance.reporterFullname, + 'reporter_mobile': instance.reporterMobile, + 'reporter_role': instance.reporterRole, + 'state': instance.state, + 'real_quantity_ai': instance.realQuantityAi, + 'message_ai': instance.messageAi, + 'real_quantity': instance.realQuantity, + 'message': instance.message, + 'message_registerer_fullname': instance.messageRegistererFullname, + 'message_registerer_mobile': instance.messageRegistererMobile, + 'message_registerer_role': instance.messageRegistererRole, + 'report_information': instance.reportInformation, + 'created_by': instance.createdBy, + 'modified_by': instance.modifiedBy, +}; + +_PoultryScienceRef _$PoultryScienceRefFromJson(Map json) => + _PoultryScienceRef( + id: (json['id'] as num?)?.toInt(), + user: json['user'] == null + ? null + : UserWithCity.fromJson(json['user'] as Map), + key: json['key'] as String?, + createDate: json['create_date'] as String?, + modifyDate: json['modify_date'] as String?, + trash: json['trash'] as bool?, + engineeringCode: json['engineering_code'] as String?, + createdBy: json['created_by'] as String?, + modifiedBy: json['modified_by'] as String?, + poultry: (json['poultry'] as List?) + ?.map((e) => (e as num).toInt()) + .toList(), + ); + +Map _$PoultryScienceRefToJson(_PoultryScienceRef instance) => + { + 'id': instance.id, + 'user': instance.user, + 'key': instance.key, + 'create_date': instance.createDate, + 'modify_date': instance.modifyDate, + 'trash': instance.trash, + 'engineering_code': instance.engineeringCode, + 'created_by': instance.createdBy, + 'modified_by': instance.modifiedBy, + 'poultry': instance.poultry, + }; + +_UserRef _$UserRefFromJson(Map json) => _UserRef( + fullname: json['fullname'] as String?, + mobile: json['mobile'] as String?, + city: json['city'] == null + ? null + : CityRef.fromJson(json['city'] as Map), +); + +Map _$UserRefToJson(_UserRef instance) => { + 'fullname': instance.fullname, + 'mobile': instance.mobile, + 'city': instance.city, +}; + +_UserWithCity _$UserWithCityFromJson(Map json) => + _UserWithCity( + fullname: json['fullname'] as String?, + mobile: json['mobile'] as String?, + city: json['city'] == null + ? null + : CityRef.fromJson(json['city'] as Map), + ); + +Map _$UserWithCityToJson(_UserWithCity instance) => + { + 'fullname': instance.fullname, + 'mobile': instance.mobile, + 'city': instance.city, + }; + +_ReportInformation _$ReportInformationFromJson(Map json) => + _ReportInformation( + hr: json['hr'] == null + ? null + : HrInfo.fromJson(json['hr'] as Map), + casualties: json['casualties'] == null + ? null + : Casualties.fromJson(json['casualties'] as Map), + facilities: json['facilities'] == null + ? null + : Facilities.fromJson(json['facilities'] as Map), + inputStatus: json['input_status'] == null + ? null + : InputStatus.fromJson(json['input_status'] as Map), + inspectionNotes: json['inspection_notes'] as String?, + inspectionStatus: json['inspection_status'] as String?, + technicalOfficer: json['technical_officer'] == null + ? null + : TechnicalOfficer.fromJson( + json['technical_officer'] as Map, + ), + infrastructureEnergy: json['infrastructure_energy'] == null + ? null + : InfrastructureEnergy.fromJson( + json['infrastructure_energy'] as Map, + ), + generalConditionHall: json['general_condition_hall'] == null + ? null + : GeneralConditionHall.fromJson( + json['general_condition_hall'] as Map, + ), + ); + +Map _$ReportInformationToJson(_ReportInformation instance) => + { + 'hr': instance.hr, + 'casualties': instance.casualties, + 'facilities': instance.facilities, + 'input_status': instance.inputStatus, + 'inspection_notes': instance.inspectionNotes, + 'inspection_status': instance.inspectionStatus, + 'technical_officer': instance.technicalOfficer, + 'infrastructure_energy': instance.infrastructureEnergy, + 'general_condition_hall': instance.generalConditionHall, + }; + +_HrInfo _$HrInfoFromJson(Map json) => _HrInfo( + trained: json['trained'] as bool?, + contractStatus: json['contract_status'] as String?, + numberEmployed: json['number_employed'] as num?, + numberIndigenous: json['number_indigenous'] as num?, + numberNonIndigenous: json['number_non_indigenous'] as num?, +); + +Map _$HrInfoToJson(_HrInfo instance) => { + 'trained': instance.trained, + 'contract_status': instance.contractStatus, + 'number_employed': instance.numberEmployed, + 'number_indigenous': instance.numberIndigenous, + 'number_non_indigenous': instance.numberNonIndigenous, +}; + +_Casualties _$CasualtiesFromJson(Map json) => _Casualties( + images: (json['images'] as List?)?.map((e) => e as String).toList(), + typeDisease: json['type_disease'] as String?, + normalLosses: json['normal_losses'] as num?, + samplingDone: json['sampling_done'] as bool?, + typeSampling: json['type_sampling'] as String?, + abnormalLosses: json['abnormal_losses'] as num?, + sourceOfHatching: json['source_of_hatching'] as String?, + causeAbnormalLosses: json['cause_abnormal_losses'] as String?, +); + +Map _$CasualtiesToJson(_Casualties instance) => + { + 'images': instance.images, + 'type_disease': instance.typeDisease, + 'normal_losses': instance.normalLosses, + 'sampling_done': instance.samplingDone, + 'type_sampling': instance.typeSampling, + 'abnormal_losses': instance.abnormalLosses, + 'source_of_hatching': instance.sourceOfHatching, + 'cause_abnormal_losses': instance.causeAbnormalLosses, + }; + +_Facilities _$FacilitiesFromJson(Map json) => _Facilities( + date: json['date'] as String?, + amount: json['amount'] as num?, + hasFacilities: json['has_facilities'] as bool?, + repaymentStatus: json['repayment_status'] as String?, + typeOfFacility: json['type_of_facility'] as String?, + requestFacilities: json['request_facilities'] as String?, +); + +Map _$FacilitiesToJson(_Facilities instance) => + { + 'date': instance.date, + 'amount': instance.amount, + 'has_facilities': instance.hasFacilities, + 'repayment_status': instance.repaymentStatus, + 'type_of_facility': instance.typeOfFacility, + 'request_facilities': instance.requestFacilities, + }; + +_InputStatus _$InputStatusFromJson(Map json) => _InputStatus( + images: (json['images'] as List?)?.map((e) => e as String).toList(), + gradeGrain: json['grade_grain'] as String?, + companyName: json['company_name'] as String?, + inputStatus: json['input_status'] as String?, + trackingCode: json['tracking_code'] as String?, + typeOfGrain: json['type_of_grain'] as String?, + inventoryUntilVisit: json['inventory_until_visit'] as String?, + inventoryInWarehouse: json['inventory_in_warehouse'] as String?, +); + +Map _$InputStatusToJson(_InputStatus instance) => + { + 'images': instance.images, + 'grade_grain': instance.gradeGrain, + 'company_name': instance.companyName, + 'input_status': instance.inputStatus, + 'tracking_code': instance.trackingCode, + 'type_of_grain': instance.typeOfGrain, + 'inventory_until_visit': instance.inventoryUntilVisit, + 'inventory_in_warehouse': instance.inventoryInWarehouse, + }; + +_TechnicalOfficer _$TechnicalOfficerFromJson(Map json) => + _TechnicalOfficer( + technicalHealthOfficer: json['technical_health_officer'] as String?, + technicalEngineeringOfficer: + json['technical_engineering_officer'] as String?, + ); + +Map _$TechnicalOfficerToJson(_TechnicalOfficer instance) => + { + 'technical_health_officer': instance.technicalHealthOfficer, + 'technical_engineering_officer': instance.technicalEngineeringOfficer, + }; + +_InfrastructureEnergy _$InfrastructureEnergyFromJson( + Map json, +) => _InfrastructureEnergy( + fuelType: json['fuel_type'] as String?, + generatorType: json['generator_type'] as String?, + powerCutHour: json['power_cut_hour'] as String?, + generatorCount: json['generator_count'] as String?, + generatorModel: json['generator_model'] as String?, + additionalNotes: json['additional_notes'] as String?, + generatorCapacity: json['generator_capacity'] as String?, + powerCutDuration: json['power_cut_duration'] as String?, + generatorPerformance: json['generator_performance'] as String?, + hasPowerCutHistory: json['has_power_cut_history'] as bool?, + emergencyFuelInventory: json['emergency_fuel_inventory'] as String?, +); + +Map _$InfrastructureEnergyToJson( + _InfrastructureEnergy instance, +) => { + 'fuel_type': instance.fuelType, + 'generator_type': instance.generatorType, + 'power_cut_hour': instance.powerCutHour, + 'generator_count': instance.generatorCount, + 'generator_model': instance.generatorModel, + 'additional_notes': instance.additionalNotes, + 'generator_capacity': instance.generatorCapacity, + 'power_cut_duration': instance.powerCutDuration, + 'generator_performance': instance.generatorPerformance, + 'has_power_cut_history': instance.hasPowerCutHistory, + 'emergency_fuel_inventory': instance.emergencyFuelInventory, +}; + +_GeneralConditionHall _$GeneralConditionHallFromJson( + Map json, +) => _GeneralConditionHall( + images: (json['images'] as List?)?.map((e) => e as String).toList(), + temperature: json['temperature'] as String?, + bedCondition: json['bed_condition'] as String?, + healthStatus: json['health_status'] as String?, + ventilationStatus: json['ventilation_status'] as String?, + drinkingWaterSource: json['drinking_water_source'] as String?, + drinkingWaterQuality: json['drinking_water_quality'] as String?, +); + +Map _$GeneralConditionHallToJson( + _GeneralConditionHall instance, +) => { + 'images': instance.images, + 'temperature': instance.temperature, + 'bed_condition': instance.bedCondition, + 'health_status': instance.healthStatus, + 'ventilation_status': instance.ventilationStatus, + 'drinking_water_source': instance.drinkingWaterSource, + 'drinking_water_quality': instance.drinkingWaterQuality, +}; diff --git a/packages/chicken/lib/data/models/response/sell_for_freezing/sell_for_freezing.dart b/packages/chicken/lib/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart similarity index 100% rename from packages/chicken/lib/data/models/response/sell_for_freezing/sell_for_freezing.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart diff --git a/packages/chicken/lib/data/models/response/sell_for_freezing/sell_for_freezing.freezed.dart b/packages/chicken/lib/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/sell_for_freezing/sell_for_freezing.freezed.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.freezed.dart diff --git a/packages/chicken/lib/data/models/response/sell_for_freezing/sell_for_freezing.g.dart b/packages/chicken/lib/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/sell_for_freezing/sell_for_freezing.g.dart rename to packages/chicken/lib/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.g.dart diff --git a/packages/chicken/lib/features/poultry_science/data/repositories/poultry_science_repository.dart b/packages/chicken/lib/features/poultry_science/data/repositories/poultry_science_repository.dart new file mode 100644 index 0000000..a3f7709 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/repositories/poultry_science_repository.dart @@ -0,0 +1,109 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/approved_price/approved_price.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_export/poultry_export.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/kill_registration/kill_registration.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class PoultryScienceRepository { + Future getHomePoultry({ + required String token, + required String type, + }); + + Future?> getHatchingPoultry({ + required String token, + Map? queryParameters, + }); + + Future submitPoultryScienceReport({ + required String token, + required FormData data, + ProgressCallback? onSendProgress, + }); + + Future?> getHatchingPoultryReport({ + required String token, + Map? queryParameters, + }); + + Future?> getPoultryScienceFarmList({ + required String token, + Map? queryParameters, + }); + + Future getApprovedPrice({ + required String token, + Map? queryParameters, + }); + + Future?> getAllPoultry({ + required String token, + Map? queryParameters, + }); + + Future getSellForFreezing({ + required String token, + Map? queryParameters, + }); + + Future getPoultryExport({ + required String token, + Map? queryParameters, + }); + + Future?> getUserPoultry({ + required String token, + Map? queryParameters, + }); + + Future?> getPoultryHatching({ + required String token, + Map? queryParameters, + }); + + Future?> getKillHouseList({ + required String token, + Map? queryParameters, + }); + + Future submitKillRegistration({ + required String token, + required KillRegistrationRequest request, + }); + + Future?> getPoultryOderList({ + required String token, + Map? queryParameters, + }); + + Future deletePoultryOder({ + required String token, + required String orderId, + }); + + Future?> uploadImages({ + required String token, + required List images, + }); + + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/poultry_science/data/repositories/poultry_science_repository_impl.dart b/packages/chicken/lib/features/poultry_science/data/repositories/poultry_science_repository_impl.dart new file mode 100644 index 0000000..88a5518 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/data/repositories/poultry_science_repository_impl.dart @@ -0,0 +1,212 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/approved_price/approved_price.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_export/poultry_export.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/kill_registration/kill_registration.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/datasources/remote/poultry_science_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class PoultryScienceRepositoryImpl implements PoultryScienceRepository { + final PoultryScienceRemoteDataSource _dataSource; + + PoultryScienceRepositoryImpl(this._dataSource); + + @override + Future getHomePoultry({ + required String token, + required String type, + }) async { + return await _dataSource.getHomePoultryScience(token: token, type: type); + } + + @override + Future?> getHatchingPoultry({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getHatchingPoultry( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitPoultryScienceReport({ + required String token, + required FormData data, + ProgressCallback? onSendProgress, + }) async { + return await _dataSource.submitPoultryScienceReport( + token: token, + data: data, + onSendProgress: onSendProgress, + ); + } + + @override + Future?> getHatchingPoultryReport({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getPoultryScienceReport( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future?> getPoultryScienceFarmList({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getPoultryScienceFarmList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future getApprovedPrice({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getApprovedPrice( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future?> getAllPoultry({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getAllPoultry( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future getSellForFreezing({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getSellForFreezing( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future getPoultryExport({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getPoultryExport( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future?> getUserPoultry({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getUserPoultry( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future?> getPoultryHatching({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getPoultryHatching( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future?> getKillHouseList({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getKillHouseList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitKillRegistration({ + required String token, + required KillRegistrationRequest request, + }) async { + return await _dataSource.submitKillRegistration( + token: token, + request: request, + ); + } + + @override + Future?> getPoultryOderList({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getPoultryOderList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future deletePoultryOder({ + required String token, + required String orderId, + }) async { + return await _dataSource.deletePoultryOder(token: token, orderId: orderId); + } + + @override + Future?> uploadImages({ + required String token, + required List images, + }) async { + return await _dataSource.uploadImages(token: token, images: images); + } + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _dataSource.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _dataSource.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/poultry_science/farm/logic.dart b/packages/chicken/lib/features/poultry_science/farm/logic.dart index 389cd6a..932f84a 100644 --- a/packages/chicken/lib/features/poultry_science/farm/logic.dart +++ b/packages/chicken/lib/features/poultry_science/farm/logic.dart @@ -1,14 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; -import 'package:rasadyar_chicken/features/poultry_science/home/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class FarmLogic extends GetxController { List routes = ['اقدام', 'فارم ها']; PoultryScienceRootLogic rootLogic = Get.find(); BasePageLogic baseLogic = Get.find(); - final PoultryScienceHomeLogic _homeLogic = Get.find(); + final PoultryScienceHomeLogic _homeLogic = + Get.find(); RxList tagInfo = [ InformationTagData( labelTitle: 'کل فارم ها', @@ -75,17 +77,18 @@ class FarmLogic extends GetxController { farmList.value = Resource>.loading(); } await safeCall( - call: () async => await rootLogic.poultryRepository.getPoultryScienceFarmList( - token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams( - queryParams: {'type': 'farm'}, - role: 'PoultryScience', - pageSize: 50, - search: 'filter', - value: '', - page: currentPage.value, - ), - ), + call: () async => + await rootLogic.poultryRepository.getPoultryScienceFarmList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'farm'}, + role: 'PoultryScience', + pageSize: 50, + search: 'filter', + value: '', + page: currentPage.value, + ), + ), onSuccess: (res) { if ((res?.count ?? 0) == 0) { farmList.value = Resource>.empty(); @@ -95,7 +98,10 @@ class FarmLogic extends GetxController { count: res?.count ?? 0, next: res?.next, previous: res?.previous, - results: [...(farmList.value.data?.results ?? []), ...?res?.results], + results: [ + ...(farmList.value.data?.results ?? []), + ...?res?.results, + ], ), ); } diff --git a/packages/chicken/lib/features/poultry_science/farm/view.dart b/packages/chicken/lib/features/poultry_science/farm/view.dart index 8292434..95bbc82 100644 --- a/packages/chicken/lib/features/poultry_science/farm/view.dart +++ b/packages/chicken/lib/features/poultry_science/farm/view.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; @@ -28,7 +28,7 @@ class FarmPage extends GetView { controller.getFarmList(); }, routes: controller.routes, - backId: poultryFirstKey, + backId: poultryScienceActionKey, child: Column(children: [firstTagInformation(), farmListWidget()]), ); } @@ -76,7 +76,6 @@ class FarmPage extends GetView { itemCount: data.value.data?.results?.length ?? 0, separatorBuilder: (context, index) => SizedBox(height: 8.h), onLoadMore: () async => controller.getFarmList(true), - ); }, controller.farmList), ); @@ -85,7 +84,10 @@ class FarmPage extends GetView { Container itemListExpandedWidget(PoultryFarm item) { return Container( padding: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), child: Column( spacing: 8, children: [ @@ -134,10 +136,19 @@ class FarmPage extends GetView { ), ), - buildRow(title: 'مالک/ تلفن', value: '${item.user?.fullname} (${item.user?.mobile})'), + buildRow( + title: 'مالک/ تلفن', + value: '${item.user?.fullname} (${item.user?.mobile})', + ), buildRow(title: 'شناسه یکتا', value: item.breedingUniqueId ?? 'N/A'), - buildRow(title: 'کد اپیدمیولوژیک', value: item.epidemiologicalCode ?? 'N/A'), - buildRow(title: 'کد بهداشتی', value: item.healthCertificateNumber ?? 'N/A'), + buildRow( + title: 'کد اپیدمیولوژیک', + value: item.epidemiologicalCode ?? 'N/A', + ), + buildRow( + title: 'کد بهداشتی', + value: item.healthCertificateNumber ?? 'N/A', + ), buildRow( title: 'دامپزشک فارم', value: '${item.vetFarm?.fullName} (${item.vetFarm?.mobile ?? '-'})', diff --git a/packages/chicken/lib/features/poultry_science/genocide/logic.dart b/packages/chicken/lib/features/poultry_science/genocide/logic.dart index ee6ba89..200d228 100644 --- a/packages/chicken/lib/features/poultry_science/genocide/logic.dart +++ b/packages/chicken/lib/features/poultry_science/genocide/logic.dart @@ -1,6 +1,7 @@ -import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; -import 'package:rasadyar_chicken/features/poultry_science/killing_registration/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/killing_registration/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class GenocideLogic extends GetxController { @@ -44,7 +45,8 @@ class GenocideLogic extends GetxController { if (loadingMore) { isLoadingMore.value = true; } else { - poultryOrderList.value = Resource>.loading(); + poultryOrderList.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -69,20 +71,25 @@ class GenocideLogic extends GetxController { onSuccess: (res) async { await Future.delayed(Duration(milliseconds: 500)); if ((res?.count ?? 0) == 0) { - poultryOrderList.value = Resource>.empty(); + poultryOrderList.value = + Resource>.empty(); } else { if (loadingMore) { - poultryOrderList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(poultryOrderList.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + poultryOrderList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(poultryOrderList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); } else { - - poultryOrderList.value = Resource>.success(res!); + poultryOrderList.value = + Resource>.success(res!); } } }, @@ -134,10 +141,8 @@ class GenocideLogic extends GetxController { } } - Future onRefresh() async { currentPage.value = 1; await getPoultryOrderList(); - } } diff --git a/packages/chicken/lib/features/poultry_science/genocide/view.dart b/packages/chicken/lib/features/poultry_science/genocide/view.dart index 5bbd158..0b05473 100644 --- a/packages/chicken/lib/features/poultry_science/genocide/view.dart +++ b/packages/chicken/lib/features/poultry_science/genocide/view.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; -import 'package:rasadyar_chicken/features/poultry_science/killing_registration/view.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/killing_registration/view.dart'; + import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; @@ -22,7 +24,7 @@ class GenocidePage extends GetView { controller.searchedValue.value = data; controller.getPoultryOrderList(); }, - backId: poultryFirstKey, + backId: poultryScienceActionKey, onFilterTap: () { Get.bottomSheet( isScrollControlled: true, @@ -81,7 +83,6 @@ class GenocidePage extends GetView { itemCount: data.value.data?.results?.length ?? 0, separatorBuilder: (context, index) => SizedBox(height: 8.h), onLoadMore: () async => controller.getPoultryOrderList(true), - ); }, controller.poultryOrderList); } @@ -89,7 +90,10 @@ class GenocidePage extends GetView { Container itemListExpandedWidget(PoultryOrder item) { return Container( padding: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), child: Column( spacing: 8, children: [ @@ -151,8 +155,14 @@ class GenocidePage extends GetView { buildRow(title: 'نوع کشتار ', value: controller.getKillType(item)), buildRow(title: 'درخواست', value: controller.getRequestType(item)), - buildRow(title: 'میانگین وزنی', value: '${(item.indexWeight)} (کیلوگرم)'), - buildRow(title: 'قیمت مرغدار', value: '${item.amount.separatedByComma} (ریال)'), + buildRow( + title: 'میانگین وزنی', + value: '${(item.indexWeight)} (کیلوگرم)', + ), + buildRow( + title: 'قیمت مرغدار', + value: '${item.amount.separatedByComma} (ریال)', + ), buildRow( title: 'مانده در سالن ', value: '${item.hatching?.leftOver.separatedByComma ?? 0} (قطعه)', @@ -169,7 +179,10 @@ class GenocidePage extends GetView { icon: Assets.vec.trashSvg.svg( width: 16.w, height: 16.h, - colorFilter: ColorFilter.mode(AppColor.error, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + AppColor.error, + BlendMode.srcIn, + ), ), textStyle: AppFonts.yekan16Bold.copyWith(color: AppColor.error), borderColor: AppColor.error, diff --git a/packages/chicken/lib/features/poultry_science/home/logic.dart b/packages/chicken/lib/features/poultry_science/home/logic.dart index b3c2bd8..3253521 100644 --- a/packages/chicken/lib/features/poultry_science/home/logic.dart +++ b/packages/chicken/lib/features/poultry_science/home/logic.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/presentation/widget/custom/information_card_widget.dart'; @@ -158,7 +159,8 @@ class PoultryScienceHomeLogic extends GetxController { ); case 'حجم کشتار شده': return tag.copyWith( - value: result.hatchingKilledQuantity?.separatedByCommaFa ?? '0', + value: + result.hatchingKilledQuantity?.separatedByCommaFa ?? '0', isLoading: false, ); default: diff --git a/packages/chicken/lib/features/poultry_science/home/view.dart b/packages/chicken/lib/features/poultry_science/home/view.dart index 9b77cf7..d44d041 100644 --- a/packages/chicken/lib/features/poultry_science/home/view.dart +++ b/packages/chicken/lib/features/poultry_science/home/view.dart @@ -1,6 +1,6 @@ import 'package:flutter/cupertino.dart' hide LinearGradient; import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_core/core.dart'; @@ -34,13 +34,18 @@ class PoultryScienceHomePage extends GetView { decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), - border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), + border: Border.all( + width: 0.50, + color: const Color(0xFFA9A9A9), + ), ), child: ObxValue((data) { return AnimatedSize( duration: Duration(milliseconds: 300), - child: data.value ? mainItemWidget() : mainItemWidgetExpanded(), + child: data.value + ? mainItemWidget() + : mainItemWidgetExpanded(), ); }, controller.isExpanded), ), @@ -52,7 +57,10 @@ class PoultryScienceHomePage extends GetView { decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), - border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), + border: Border.all( + width: 0.50, + color: const Color(0xFFA9A9A9), + ), ), padding: EdgeInsets.symmetric(horizontal: 8), child: Row( @@ -61,12 +69,17 @@ class PoultryScienceHomePage extends GetView { Assets.vec.chicken2Svg.svg( width: 16.w, height: 16.h, - colorFilter: ColorFilter.mode(AppColor.blueDark, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + AppColor.blueDark, + BlendMode.srcIn, + ), ), Text( 'اطلاعات فارم‌ها', textAlign: TextAlign.right, - style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.iconColor, + ), ), ], ), @@ -88,7 +101,11 @@ class PoultryScienceHomePage extends GetView { padding: const EdgeInsets.all(8.0), child: Column( mainAxisSize: MainAxisSize.min, - children: [SizedBox(height: 8), firstTagInformation(), secondTagInformation()], + children: [ + SizedBox(height: 8), + firstTagInformation(), + secondTagInformation(), + ], ), ); } @@ -136,7 +153,11 @@ class PoultryScienceHomePage extends GetView { firstTagInformation(), Row( children: [ - Text('اطلاعات جوجه‌ریزی', textAlign: TextAlign.right, style: AppFonts.yekan16), + Text( + 'اطلاعات جوجه‌ریزی', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), ], ), secondTagInformation(), @@ -237,7 +258,10 @@ class PoultryScienceHomePage extends GetView { onTap: () async { controller.rootLogic.currentPage.value = 0; - Get.toNamed(ChickenRoutes.inspectionPoultryScience, id: poultryFirstKey); + Get.toNamed( + PoultryScienceRoutes.inspectionPoultryScience, + id: poultryFirstKey, + ); }, ), @@ -250,7 +274,10 @@ class PoultryScienceHomePage extends GetView { textColor: AppColor.textColor, onTap: () async { controller.rootLogic.currentPage.value = 0; - Get.toNamed(ChickenRoutes.genocidePoultryScience, id: poultryFirstKey); + Get.toNamed( + PoultryScienceRoutes.genocidePoultryScience, + id: poultryFirstKey, + ); }, ), widelyUsed( @@ -262,7 +289,10 @@ class PoultryScienceHomePage extends GetView { isOnEdit: false, onTap: () async { controller.rootLogic.currentPage.value = 0; - Get.toNamed(ChickenRoutes.farmPoultryScience, id: poultryFirstKey); + Get.toNamed( + PoultryScienceRoutes.farmPoultryScience, + id: poultryFirstKey, + ); }, ), @@ -275,7 +305,10 @@ class PoultryScienceHomePage extends GetView { textColor: AppColor.textColor, onTap: () async { controller.rootLogic.currentPage.value = 0; - Get.toNamed(ChickenRoutes.activeHatchingPoultryScience, id: poultryFirstKey); + Get.toNamed( + PoultryScienceRoutes.activeHatchingPoultryScience, + id: poultryFirstKey, + ); }, ), ], @@ -291,7 +324,11 @@ class PoultryScienceHomePage extends GetView { borderRadius: BorderRadius.circular(8), border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), ), - child: Text('پر کاربردها', textAlign: TextAlign.right, style: AppFonts.yekan16), + child: Text( + 'پر کاربردها', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), ), ), ], @@ -324,19 +361,26 @@ class PoultryScienceHomePage extends GetView { padding: EdgeInsets.all(4), decoration: ShapeDecoration( color: cardColor ?? Color(0xFFBECDFF), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), ), child: Container( width: 40, height: 40, decoration: ShapeDecoration( color: labelColor ?? AppColor.blueNormal, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), ), child: SvgGenImage.vec(iconPath).svg( width: 24, height: 24, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), fit: BoxFit.cover, ), ), @@ -349,7 +393,9 @@ class PoultryScienceHomePage extends GetView { padding: EdgeInsets.all(4), decoration: ShapeDecoration( color: Colors.white60, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), ), ), ), @@ -369,9 +415,16 @@ class PoultryScienceHomePage extends GetView { child: Container( width: 16, height: 16, - decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.white), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, + ), alignment: Alignment.center, - child: Icon(CupertinoIcons.minus, color: AppColor.error, size: 15), + child: Icon( + CupertinoIcons.minus, + color: AppColor.error, + size: 15, + ), ), ), ), @@ -382,7 +435,9 @@ class PoultryScienceHomePage extends GetView { ), Text( title, - style: AppFonts.yekan10Bold.copyWith(color: textColor ?? AppColor.blueNormal), + style: AppFonts.yekan10Bold.copyWith( + color: textColor ?? AppColor.blueNormal, + ), ), ], ), diff --git a/packages/chicken/lib/features/poultry_science/inspection/logic.dart b/packages/chicken/lib/features/poultry_science/inspection/logic.dart index 9fbdd78..8aeab88 100644 --- a/packages/chicken/lib/features/poultry_science/inspection/logic.dart +++ b/packages/chicken/lib/features/poultry_science/inspection/logic.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class InspectionPoultryScienceLogic extends GetxController { @@ -14,7 +15,10 @@ class InspectionPoultryScienceLogic extends GetxController { PoultryScienceRootLogic rootLogic = Get.find(); - Rx currentLocation = LatLng(34.798315281272544, 48.51479142983491).obs; + Rx currentLocation = LatLng( + 34.798315281272544, + 48.51479142983491, + ).obs; final RxBool isLoadingMoreAllocationsMade = false.obs; RxInt currentPage = 1.obs; @@ -104,7 +108,10 @@ class InspectionPoultryScienceLogic extends GetxController { count: res?.count ?? 0, next: res?.next, previous: res?.previous, - results: [...(hatchingList.value.data?.results ?? []), ...(res?.results ?? [])], + results: [ + ...(hatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], ), ); } @@ -116,7 +123,8 @@ class InspectionPoultryScienceLogic extends GetxController { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { - hatchingReportList.value = Resource>.loading(); + hatchingReportList.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -126,30 +134,36 @@ class InspectionPoultryScienceLogic extends GetxController { } safeCall( - call: () async => await rootLogic.poultryRepository.getHatchingPoultryReport( - token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams( - role: 'PoultryScience', - pageSize: 50, - search: 'filter', - value: searchedValue.value, - fromDate: fromDateFilter.value.toDateTime(), - toDate: toDateFilter.value.toDateTime(), - page: currentPage.value, - ), - ), + call: () async => + await rootLogic.poultryRepository.getHatchingPoultryReport( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'PoultryScience', + pageSize: 50, + search: 'filter', + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + page: currentPage.value, + ), + ), onSuccess: (res) { if ((res?.count ?? 0) == 0) { - hatchingReportList.value = Resource>.empty(); + hatchingReportList.value = + Resource>.empty(); } else { - hatchingReportList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(hatchingReportList.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + hatchingReportList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(hatchingReportList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); } }, ); @@ -175,7 +189,10 @@ class InspectionPoultryScienceLogic extends GetxController { isOnUpload.value = true; final tmpFiles = await Future.wait( - pickedImages.map((element) => MultipartFile.fromFile(element.path, filename: element.name)), + pickedImages.map( + (element) => + MultipartFile.fromFile(element.path, filename: element.name), + ), ); var data = FormData.fromMap({ @@ -186,13 +203,17 @@ class InspectionPoultryScienceLogic extends GetxController { }); safeCall( - call: () async => await rootLogic.poultryRepository.submitPoultryScienceReport( - token: rootLogic.tokenService.accessToken.value!, - data: data, - onSendProgress: (sent, total) { - presentUpload.value = calculateUploadProgress(sent: sent, total: total); - }, - ), + call: () async => + await rootLogic.poultryRepository.submitPoultryScienceReport( + token: rootLogic.tokenService.accessToken.value!, + data: data, + onSendProgress: (sent, total) { + presentUpload.value = calculateUploadProgress( + sent: sent, + total: total, + ); + }, + ), onSuccess: (res) { closeBottomSheet(); clearImages(); @@ -204,7 +225,9 @@ class InspectionPoultryScienceLogic extends GetxController { clearImages(); isOnUpload.value = false; - await Future.delayed(const Duration(seconds: 4)).then((value) => closeBottomSheet()); + await Future.delayed( + const Duration(seconds: 4), + ).then((value) => closeBottomSheet()); }, showError: true, ); diff --git a/packages/chicken/lib/features/poultry_science/inspection/view.dart b/packages/chicken/lib/features/poultry_science/inspection/view.dart index 07149c4..0ceb1a4 100644 --- a/packages/chicken/lib/features/poultry_science/inspection/view.dart +++ b/packages/chicken/lib/features/poultry_science/inspection/view.dart @@ -1,8 +1,8 @@ import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_core/core.dart'; @@ -23,7 +23,7 @@ class InspectionPoultrySciencePage extends GetView controller.setSearchValue(data), - backId: poultryFirstKey, + backId: poultryScienceActionKey, routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), child: Column( children: [ diff --git a/packages/chicken/lib/features/poultry_science/killing_registration/logic.dart b/packages/chicken/lib/features/poultry_science/killing_registration/logic.dart index a5704a0..62620c6 100644 --- a/packages/chicken/lib/features/poultry_science/killing_registration/logic.dart +++ b/packages/chicken/lib/features/poultry_science/killing_registration/logic.dart @@ -1,14 +1,15 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart'; -import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; -import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; -import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart'; -import 'package:rasadyar_chicken/features/poultry_science/genocide/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_export/poultry_export.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/kill_registration/kill_registration.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/approved_price/approved_price.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/genocide/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class KillingRegistrationLogic extends GetxController { @@ -26,7 +27,9 @@ class KillingRegistrationLogic extends GetxController { TextEditingController quantityKillsController = TextEditingController(); RxBool quantityKillsIsCompleted = false.obs; - TextEditingController quantityLoseController = TextEditingController(text: 0.toString()); + TextEditingController quantityLoseController = TextEditingController( + text: 0.toString(), + ); TextEditingController averageWeightKillsController = TextEditingController(); RxBool averageWeightKillsIsCompleted = false.obs; TextEditingController priceFreeSaleController = TextEditingController(); @@ -40,25 +43,23 @@ class KillingRegistrationLogic extends GetxController { RxBool isFreeSale = false.obs; //step 1 - Rx>> allPoultryList = Resource>.loading().obs; + Rx>> allPoultryList = + Resource>.loading().obs; Rxn selectedPoultry = Rxn(); //step 2 - Rx>> poultryList = Resource>.success( - [], - ).obs; + Rx>> poultryList = + Resource>.success([]).obs; Rxn selectedKillRequestPoultry = Rxn(); //step 3 - Rx>> poultryHatchingList = Resource>.success( - [], - ).obs; + Rx>> poultryHatchingList = + Resource>.success([]).obs; Rxn selectedPoultryHatching = Rxn(); //step 5 - Rx>> killHouseList = Resource>.success( - [], - ).obs; + Rx>> killHouseList = + Resource>.success([]).obs; Rxn selectedKillHouse = Rxn(); @override @@ -82,7 +83,12 @@ class KillingRegistrationLogic extends GetxController { }); everAll( - [selectedPoultry, selectedKillRequestPoultry, selectedPoultryHatching, selectedKillHouse], + [ + selectedPoultry, + selectedKillRequestPoultry, + selectedPoultryHatching, + selectedKillHouse, + ], (callback) { checkSubmitButton(); }, @@ -104,12 +110,15 @@ class KillingRegistrationLogic extends GetxController { void priceListener() { quantityKillsController.addListener(() { - quantityKillsIsCompleted.value = quantityKillsController.text.trim().isNotEmpty; + quantityKillsIsCompleted.value = quantityKillsController.text + .trim() + .isNotEmpty; if (averageWeightKillsController.text.isNotEmpty && quantityKillsController.text.trim().isNotEmpty) { generatedApprovedPrice.value = calculateApprovedPrice().toInt(); - priceFreeSaleController.text = generatedApprovedPrice.value.separatedByComma; + priceFreeSaleController.text = + generatedApprovedPrice.value.separatedByComma; checkSubmitButton(); } else { @@ -120,12 +129,15 @@ class KillingRegistrationLogic extends GetxController { }); averageWeightKillsController.addListener(() { - averageWeightKillsIsCompleted.value = averageWeightKillsController.text.trim().isNotEmpty; + averageWeightKillsIsCompleted.value = averageWeightKillsController.text + .trim() + .isNotEmpty; if (averageWeightKillsController.text.trim().isNotEmpty && quantityKillsController.text.trim().isNotEmpty) { generatedApprovedPrice.value = calculateApprovedPrice().toInt(); - priceFreeSaleController.text = generatedApprovedPrice.value.separatedByComma; + priceFreeSaleController.text = + generatedApprovedPrice.value.separatedByComma; checkSubmitButton(); } else { generatedApprovedPrice.value = 0; @@ -177,7 +189,9 @@ class KillingRegistrationLogic extends GetxController { await safeCall( call: () async => await rootLogic.poultryRepository.getAllPoultry( token: tokenService.accessToken.value ?? '', - queryParameters: buildRawQueryParams(role: gService.getRole(Module.chicken)), + queryParameters: buildRawQueryParams( + role: gService.getRole(Module.chicken), + ), ), onSuccess: (result) { if (result != null) { @@ -185,7 +199,9 @@ class KillingRegistrationLogic extends GetxController { } }, onError: (error, stackTrace) { - allPoultryList.value = Resource>.error('$error -- $stackTrace'); + allPoultryList.value = Resource>.error( + '$error -- $stackTrace', + ); }, ); } @@ -230,11 +246,15 @@ class KillingRegistrationLogic extends GetxController { ), onSuccess: (result) { if (result != null) { - poultryList.value = Resource>.success(result); + poultryList.value = Resource>.success( + result, + ); } }, onError: (error, stackTrace) { - poultryList.value = Resource>.error('$error -- $stackTrace'); + poultryList.value = Resource>.error( + '$error -- $stackTrace', + ); }, ); } @@ -250,11 +270,15 @@ class KillingRegistrationLogic extends GetxController { ), onSuccess: (result) { if (result != null) { - poultryHatchingList.value = Resource>.success(result); + poultryHatchingList.value = Resource>.success( + result, + ); } }, onError: (error, stackTrace) { - poultryHatchingList.value = Resource>.error('$error -- $stackTrace'); + poultryHatchingList.value = Resource>.error( + '$error -- $stackTrace', + ); }, ); } @@ -265,16 +289,23 @@ class KillingRegistrationLogic extends GetxController { call: () async => await rootLogic.poultryRepository.getKillHouseList( token: tokenService.accessToken.value ?? '', queryParameters: buildRawQueryParams( - queryParams: {'show_poultry': '', 'date': DateTime.now().formattedDashedGregorian}, + queryParams: { + 'show_poultry': '', + 'date': DateTime.now().formattedDashedGregorian, + }, ), ), onSuccess: (result) { if (result != null) { - killHouseList.value = Resource>.success(result); + killHouseList.value = Resource>.success( + result, + ); } }, onError: (error, stackTrace) { - killHouseList.value = Resource>.error('$error -- $stackTrace'); + killHouseList.value = Resource>.error( + '$error -- $stackTrace', + ); }, ); } @@ -311,7 +342,11 @@ class KillingRegistrationLogic extends GetxController { selectedPoultryHatching.value != null && quantityKillsController.text.isNotEmpty && averageWeightKillsController.text.isNotEmpty && - ((selectedKillRequestPoultry.value?.provinceAllowChooseKillHouse?.mandatory ?? false) + ((selectedKillRequestPoultry + .value + ?.provinceAllowChooseKillHouse + ?.mandatory ?? + false) ? selectedKillHouse.value != null : true); } @@ -352,10 +387,11 @@ class KillingRegistrationLogic extends GetxController { ); await safeCall( - call: () async => await rootLogic.poultryRepository.submitKillRegistration( - token: tokenService.accessToken.value ?? '', - request: registrationRequest, - ), + call: () async => + await rootLogic.poultryRepository.submitKillRegistration( + token: tokenService.accessToken.value ?? '', + request: registrationRequest, + ), onSuccess: (result) async { defaultShowSuccessMessage( 'ثبت با موفقیت انجام شد', diff --git a/packages/chicken/lib/features/poultry_science/killing_registration/view.dart b/packages/chicken/lib/features/poultry_science/killing_registration/view.dart index 1a6067d..a7a3cac 100644 --- a/packages/chicken/lib/features/poultry_science/killing_registration/view.dart +++ b/packages/chicken/lib/features/poultry_science/killing_registration/view.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; import 'package:rasadyar_core/core.dart'; import 'logic.dart'; diff --git a/packages/chicken/lib/features/poultry_science/poultry_action/logic.dart b/packages/chicken/lib/features/poultry_science/poultry_action/logic.dart index 09235e3..9db46d1 100644 --- a/packages/chicken/lib/features/poultry_science/poultry_action/logic.dart +++ b/packages/chicken/lib/features/poultry_science/poultry_action/logic.dart @@ -1,3 +1,4 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_core/core.dart'; @@ -6,35 +7,39 @@ class PoultryActionItem { final String route; final String icon; - PoultryActionItem({required this.title, required this.route, required this.icon}); + PoultryActionItem({ + required this.title, + required this.route, + required this.icon, + }); } class PoultryActionLogic extends GetxController { RxList items = [ PoultryActionItem( title: "بازرسی", - route: ChickenRoutes.inspectionPoultryScience, + route: PoultryScienceRoutes.inspectionPoultryScience, icon: Assets.vec.chickenInspectionSvg.path, ), PoultryActionItem( title: "ثبت کشتار", - route: ChickenRoutes.genocidePoultryScience, + route: PoultryScienceRoutes.genocidePoultryScience, icon: Assets.vec.registerKillSvg.path, ), PoultryActionItem( title: "فارم ها", - route: ChickenRoutes.farmPoultryScience, + route: PoultryScienceRoutes.farmPoultryScience, icon: Assets.vec.farmsSvg.path, ), PoultryActionItem( title: "جوجه ریزی فعال", - route: ChickenRoutes.activeHatchingPoultryScience, + route: PoultryScienceRoutes.activeHatchingPoultryScience, icon: Assets.vec.activeFramSvg.path, ), PoultryActionItem( title: "بازرسی مزارع طیور", - route: ChickenRoutes.poultryFarmInspectionHome, + route: PoultryScienceRoutes.newInspectionPoultryScience, icon: Assets.vec.activeFramSvg.path, ), ].obs; diff --git a/packages/chicken/lib/features/poultry_science/poultry_action/view.dart b/packages/chicken/lib/features/poultry_science/poultry_action/view.dart index 066a9c9..4d07228 100644 --- a/packages/chicken/lib/features/poultry_science/poultry_action/view.dart +++ b/packages/chicken/lib/features/poultry_science/poultry_action/view.dart @@ -10,7 +10,12 @@ class PoultryActionPage extends GetView { @override Widget build(BuildContext context) { - return ChickenBasePage(isBase: true, hasNews: true, hasNotification: true, child: gridWidget()); + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); } Widget gridWidget() { @@ -31,7 +36,7 @@ class PoultryActionPage extends GetView { title: item.title, vecIcon: item.icon, onTap: () async { - Get.toNamed(item.route, id: poultryFirstKey); + Get.toNamed(item.route, id: poultryScienceActionKey); }, ); }, diff --git a/packages/chicken/lib/features/poultry_science/poultry_science.dart b/packages/chicken/lib/features/poultry_science/poultry_science.dart new file mode 100644 index 0000000..8670542 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/poultry_science.dart @@ -0,0 +1,3 @@ +export 'data/di/poultry_science_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..3d08fcb --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,100 @@ +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/active_hatching/logic.dart +import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; +======== +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/logic.dart +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + PoultryScienceRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'PoultryScience', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..467cfad --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/active_hatching/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: poultryScienceActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/farm/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/farm/logic.dart new file mode 100644 index 0000000..8c5a0c1 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/farm/logic.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/farm/logic.dart +import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/home/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/farm/logic.dart +import 'package:rasadyar_core/core.dart'; + +class FarmLogic extends GetxController { + List routes = ['اقدام', 'فارم ها']; + PoultryScienceRootLogic rootLogic = Get.find(); + BasePageLogic baseLogic = Get.find(); + final PoultryScienceHomeLogic _homeLogic = + Get.find(); + RxList tagInfo = [ + InformationTagData( + labelTitle: 'کل فارم ها', + isLoading: true, + labelVecIcon: Assets.vec.cubeScanSvg.path, + iconColor: AppColor.blueNormalOld, + valueBgColor: Colors.white, + labelGradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [AppColor.blueLight, Colors.white], + ), + ), + InformationTagData( + labelTitle: 'حجم جوجه ریزی', + unit: 'قطعه', + isLoading: true, + labelVecIcon: Assets.vec.cubeCardSvg.path, + blendMode: BlendMode.dst, + valueBgColor: Colors.white, + labelGradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [AppColor.greenLightHover, Colors.white], + ), + ), + ].obs; + Rx>> farmList = + Resource>.loading().obs; + + RxInt currentPage = 1.obs; + final RxBool isLoadingMoreList = false.obs; + RxInt expandedIndex = RxInt(-1); + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onReady() { + super.onReady(); + tagInfo[0] = tagInfo[0].copyWith( + isLoading: false, + value: _homeLogic.tagInfo['first']!.first.value, + ); + tagInfo[1] = tagInfo[1].copyWith( + isLoading: false, + value: _homeLogic.tagInfo['second']!.first.value, + ); + + getFarmList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getFarmList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + farmList.value = Resource>.loading(); + } + await safeCall( + call: () async => + await rootLogic.poultryRepository.getPoultryScienceFarmList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'farm'}, + role: 'PoultryScience', + pageSize: 50, + search: 'filter', + value: '', + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + farmList.value = Resource>.empty(); + } else { + farmList.value = Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(farmList.value.data?.results ?? []), + ...?res?.results, + ], + ), + ); + } + }, + onError: (error, stackTrace) {}, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + farmList.value = Resource>.loading(); + await getFarmList(); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/farm/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/farm/view.dart new file mode 100644 index 0000000..95bbc82 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/farm/view.dart @@ -0,0 +1,261 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_farm/poultry_farm.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class FarmPage extends GetView { + const FarmPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasFilter: false, + hasSearch: true, + onRefresh: controller.onRefresh, + onFilterTap: () { + Get.bottomSheet( + isScrollControlled: true, + backgroundColor: Colors.transparent, + filterBottomSheet(), + ); + }, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getFarmList(); + }, + routes: controller.routes, + backId: poultryScienceActionKey, + child: Column(children: [firstTagInformation(), farmListWidget()]), + ); + } + + Widget firstTagInformation() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 20.w), + child: Row( + spacing: 8, + children: List.generate( + data.length, + (index) => Expanded(child: InformationTag(data: data[index])), + ), + ), + ); + }, controller.tagInfo), + ); + } + + Widget farmListWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.cubeScanSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getFarmList(true), + ); + }, controller.farmList), + ); + } + + Container itemListExpandedWidget(PoultryFarm item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.unitName ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + '${item.address?.province?.name} / ${item.address?.city?.name}', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + ), + ], + ), + 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: [ + Text( + 'تعاونی : ${item.cityOperator ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + + Text( + ' تعداد سالن : ${item.numberOfHalls}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'مالک/ تلفن', + value: '${item.user?.fullname} (${item.user?.mobile})', + ), + buildRow(title: 'شناسه یکتا', value: item.breedingUniqueId ?? 'N/A'), + buildRow( + title: 'کد اپیدمیولوژیک', + value: item.epidemiologicalCode ?? 'N/A', + ), + buildRow( + title: 'کد بهداشتی', + value: item.healthCertificateNumber ?? 'N/A', + ), + buildRow( + title: 'دامپزشک فارم', + value: '${item.vetFarm?.fullName} (${item.vetFarm?.mobile ?? '-'})', + ), + buildUnitRow( + title: 'ظرفیت فارم', + value: item.totalCapacity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'جوجه ریزی فعال (تعداد دوره) ', + value: + '${(item.hatchingInfo?.activeHatching ?? false) ? 'دارد' : 'ندارد'} (${item.hatchingInfo?.period ?? 0})', + ), + + /* buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false ? 'ارسال تصویر جوجه ریزی فارم ' : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark, + ), + ),*/ + /* Visibility( + visible: (item.reportInfo?.image == false), + child: RElevated( + text: 'ثبت بازرسی', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + cameraBottomSheet(item.id!); + }, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ),*/ + ], + ), + ); + } + + Widget itemListWidget(PoultryFarm item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 3, + children: [ + Text( + item.unitName ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'شناسه یکتا: ${item.breedingUniqueId}', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + '${item.address?.province?.name}/${item.address?.city?.name}', + textAlign: TextAlign.left, + + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } + + Widget filterBottomSheet() => filterBottomSheetWidget( + fromDate: controller.fromDateFilter, + onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali, + toDate: controller.toDateFilter, + onChangedToDate: (jalali) => controller.toDateFilter.value = jalali, + onSubmit: () => controller.getFarmList(), + ); +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/genocide/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/genocide/logic.dart new file mode 100644 index 0000000..7a252ef --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/genocide/logic.dart @@ -0,0 +1,153 @@ +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/genocide/logic.dart +import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/killing_registration/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/killing_registration/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/genocide/logic.dart +import 'package:rasadyar_core/core.dart'; + +class GenocideLogic extends GetxController { + List routesName = ['اقدام', 'درخواست کشتارها']; + var tokenService = Get.find(); + BaseLogic baseLogic = Get.find(); + var gService = Get.find(); + var rootLogic = Get.find(); + var killRegistration = Get.find(); + + Rx>> poultryOrderList = + Resource>.loading().obs; + + RxInt expandedIndex = RxInt(-1); + final RxInt currentPage = 1.obs; + + final RxBool isLoadingMore = false.obs; + + final RxBool isLoadingDelete = false.obs; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + /* final RxBool isLoadingMoreAllocationsMade = false.obs; + final RxBool isOnLoadingSubmitOrEdit = false.obs;*/ + + @override + void onReady() { + super.onReady(); + getPoultryOrderList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getPoultryOrderList([bool loadingMore = false]) async { + if (loadingMore) { + isLoadingMore.value = true; + } else { + poultryOrderList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + await safeCall( + call: () async => await rootLogic.poultryRepository.getPoultryOderList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + pageSize: 20, + page: currentPage.value, + search: 'filter', + role: gService.getRole(Module.chicken), + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + queryParams: {'today': null}, + ), + ), + onSuccess: (res) async { + await Future.delayed(Duration(milliseconds: 500)); + if ((res?.count ?? 0) == 0) { + poultryOrderList.value = + Resource>.empty(); + } else { + if (loadingMore) { + poultryOrderList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(poultryOrderList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } else { + poultryOrderList.value = + Resource>.success(res!); + } + } + }, + ); + } + + Future deletePoultryOrder(int id) async { + toggleExpanded(-1); + await safeCall( + call: () async => await rootLogic.poultryRepository.deletePoultryOder( + token: rootLogic.tokenService.accessToken.value!, + orderId: id.toString(), + ), + onSuccess: (_) { + defaultShowSuccessMessage('درخواست با موفقیت حذف شد'); + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + String getRequestType(PoultryOrder item) { + if (item.market ?? false) { + return 'پنل معاملات'; + } else if (item.union ?? false) { + return 'اتحادیه'; + } else { + return 'خرید مستقیم'; + } + } + + String getKillType(PoultryOrder item) { + if (item.export ?? false) { + return 'صادرات'; + } else if (item.freezing ?? false) { + return 'انجماد'; + } else { + return 'عادی'; + } + } + + String getState(PoultryOrder item) { + if (item.stateProcess == 'pending') { + return 'در انتظار تایید'; + } else { + return 'تایید شده'; + } + } + + Future onRefresh() async { + currentPage.value = 1; + await getPoultryOrderList(); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/genocide/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/genocide/view.dart new file mode 100644 index 0000000..e8a8faa --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/genocide/view.dart @@ -0,0 +1,313 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/genocide/view.dart +import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/killing_registration/view.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_order/poultry_order.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/killing_registration/view.dart'; + +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/genocide/view.dart +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class GenocidePage extends GetView { + const GenocidePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + hasSearch: true, + hasFilter: true, + onRefresh: controller.onRefresh, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getPoultryOrderList(); + }, + backId: poultryScienceActionKey, + onFilterTap: () { + Get.bottomSheet( + isScrollControlled: true, + backgroundColor: Colors.transparent, + filterBottomSheet(), + ); + }, + child: Stack( + fit: StackFit.expand, + children: [ + Positioned.fill(child: poultryOrderListWidget()), + Positioned( + bottom: 130, + right: 16, + child: RFab.add( + onPressed: () { + Get.bottomSheet( + isScrollControlled: true, + backgroundColor: Colors.transparent, + killRegistrationBottomSheet(), + ).whenComplete(() { + controller.killRegistration.clearAllFields(); + controller.killRegistration.onReady(); + }); + }, + ), + ), + ], + ), + ); + } + + //region List and Items + Widget poultryOrderListWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.timerSvg.path, + labelIconColor: AppColor.yellowNormal2, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getPoultryOrderList(true), + ); + }, controller.poultryOrderList); + } + + Container itemListExpandedWidget(PoultryOrder item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.unitName ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + '${item.poultry?.address?.province?.name} / ${item.poultry?.address?.city?.name}', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + ), + ], + ), + 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: [ + Text( + 'سن مرغ:${item.hatching?.age ?? '-'} (روز)', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + + Text( + item.sendDate?.formattedJalaliDate ?? '-', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + + Text( + 'تعداد:${item.quantity.separatedByComma} (قطعه)', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow(title: 'کد سفارش', value: '${item.orderCode} '), + buildRow( + title: 'نوع فروش', + value: (item.freeSaleInProvince ?? false) ? 'آزاد' : 'دولتی ', + ), + buildRow(title: 'نوع کشتار ', value: controller.getKillType(item)), + buildRow(title: 'درخواست', value: controller.getRequestType(item)), + + buildRow( + title: 'میانگین وزنی', + value: '${(item.indexWeight)} (کیلوگرم)', + ), + buildRow( + title: 'قیمت مرغدار', + value: '${item.amount.separatedByComma} (ریال)', + ), + buildRow( + title: 'مانده در سالن ', + value: '${item.hatching?.leftOver.separatedByComma ?? 0} (قطعه)', + ), + buildRow(title: ' وضعیت', value: controller.getState(item)), + + Visibility( + visible: item.stateProcess == 'pending', + child: ObxValue((data) { + return ROutlinedElevatedIcon( + height: 40.h, + width: Get.width, + text: 'حذف', + icon: Assets.vec.trashSvg.svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode( + AppColor.error, + BlendMode.srcIn, + ), + ), + textStyle: AppFonts.yekan16Bold.copyWith(color: AppColor.error), + borderColor: AppColor.error, + foregroundColor: AppColor.error, + pressedBackgroundColor: AppColor.error, + onPressed: data.value + ? null + : () => _buildDeleteDialog( + onConfirm: () async { + Get.back(); + await controller.deletePoultryOrder(item.id!); + controller.getPoultryOrderList(); + }, + ), + ); + }, controller.isLoadingDelete), + ), + ], + ), + ); + } + + Widget itemListWidget(PoultryOrder item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 3, + children: [ + Text( + item.poultry?.unitName ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.sendDate?.formattedJalaliDate ?? '-', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'کد سفارش : ${item.orderCode ?? '-'}', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + 'تعداد:${item.quantity.separatedByComma} (قطعه)', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } + + //endregion + + //region other widgets + void _buildDeleteDialog({required VoidCallback onConfirm}) { + Get.defaultDialog( + title: 'حذف درخواست کشتار', + middleText: 'آیا از حذف این درخواست کشتار مطمئن هستید؟', + confirm: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: AppColor.error, + foregroundColor: Colors.white, + ), + onPressed: onConfirm, + child: Text('بله'), + ), + cancel: ElevatedButton( + onPressed: () { + Get.back(); + }, + child: Text('خیر'), + ), + ); + } + + Widget filterBottomSheet() => filterBottomSheetWidget( + fromDate: controller.fromDateFilter, + onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali, + toDate: controller.toDateFilter, + onChangedToDate: (jalali) => controller.toDateFilter.value = jalali, + onSubmit: () => controller.getPoultryOrderList(), + ); + + //endregion + + //region kill registration bottom sheet + Widget killRegistrationBottomSheet() { + return BaseBottomSheet( + height: Get.height * 0.9, + bgColor: Color(0x66E4E4E4), + child: KillingRegistrationPage(), + ); + } + + //endregion +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/home/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/home/logic.dart new file mode 100644 index 0000000..46e12dc --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/home/logic.dart @@ -0,0 +1,196 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/home/logic.dart +import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart'; +import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/home_poultry_science/home_poultry_science_model.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/home/logic.dart +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_core/presentation/widget/custom/information_card_widget.dart'; + +class PoultryScienceHomeLogic extends GetxController { + PoultryScienceRootLogic rootLogic = Get.find(); + Rxn homeInformation = Rxn(); + RxBool isExpanded = false.obs; + RxMap> tagInfo = RxMap({ + 'first': [ + InformationTagData( + labelTitle: 'کل فارم ها', + isLoading: true, + labelVecIcon: Assets.vec.cubeScanSvg.path, + iconColor: AppColor.blueFlashing, + blendMode: BlendMode.srcOut, + valueBgColor: Colors.white, + labelGradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [AppColor.blueLight, Colors.white], + ), + ), + InformationTagData( + labelTitle: 'تعداد جوجه ریزی', + isLoading: true, + labelVecIcon: Assets.vec.cubeCardSvg.path, + blendMode: BlendMode.dst, + valueBgColor: Colors.white, + labelGradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [AppColor.greenLightHover, Colors.white], + ), + ), + ], + 'second': [ + InformationTagData( + labelTitle: 'حجم جوجه ریزی', + unit: 'قطعه', + isLoading: true, + labelVecIcon: Assets.vec.hashtagSvg.path, + iconColor: const Color(0xFF6C5D60), + labelBgColor: const Color(0xFFDDC0C7), + valueBgColor: const Color(0xFFEDDCE0), + ), + InformationTagData( + labelTitle: 'مانده در سالن', + unit: 'قطعه', + isLoading: true, + labelVecIcon: Assets.vec.homeHashtagSvg.path, + labelBgColor: const Color(0xFFAFCBFF), + valueBgColor: const Color(0xFFCEDFFF), + ), + ], + 'third': [ + InformationTagData( + labelTitle: 'تلفات', + unit: 'قطعه', + isLoading: true, + labelVecIcon: Assets.vec.boxRemoveSvg.path, + + iconColor: const Color(0xFF426060), + labelBgColor: const Color(0xFFA5D1D2), + valueBgColor: const Color(0xFFC7DFE0), + ), + InformationTagData( + labelTitle: 'حجم کشتار شده', + unit: 'قطعه', + isLoading: true, + labelVecIcon: Assets.vec.closeSquareFilledSvg.path, + blendMode: BlendMode.dst, + labelBgColor: Color(0xFFC8B8D1), + valueBgColor: Color(0xFFDAD4DD), + ), + ], + }); + + RxList ageCardData = [ + InformationCardData( + labelTitle: 'بیشترین سن جوجه ریزی', + isLoading: true, + unit: 'روز', + labelVecIcon: Assets.vec.homeTrendUpSvg.path, + iconColor: const Color.fromRGBO(85, 97, 93, 1), + cardBgColor: const Color(0xFFE6FAF5), + labelBgColor: const Color(0xFFB0EFDF), + ), + InformationCardData( + labelTitle: 'کمترین سن جوجه ریزی', + isLoading: true, + unit: 'روز', + labelVecIcon: Assets.vec.homeTrendDownSvg.path, + iconColor: const Color(0xFF6F6164), + cardBgColor: const Color(0xFFEDDCE0), + labelBgColor: const Color(0xFFE0BCC5), + ), + ].obs; + + @override + void onReady() { + super.onReady(); + getHomePoultryHatching(); + } + + Future getHomePoultryHatching() async { + await safeCall( + call: () async => await rootLogic.poultryRepository.getHomePoultry( + token: rootLogic.tokenService.accessToken.value!, + type: 'home', + ), + onSuccess: (result) { + if (result != null) { + homeInformation.value = result; + tagInfo['first'] = tagInfo['first']!.map((tag) { + if (tag.labelTitle == 'کل فارم ها') { + return tag.copyWith( + value: result.farmCount?.separatedByCommaFa ?? '0', + isLoading: false, + ); + } + if (tag.labelTitle == 'تعداد جوجه ریزی') { + return tag.copyWith( + value: result.hatchingCount?.separatedByCommaFa ?? '0', + isLoading: false, + ); + } + return tag; + }).toList(); + + // second + tagInfo['second'] = tagInfo['second']!.map((tag) { + switch (tag.labelTitle) { + case 'حجم جوجه ریزی': + return tag.copyWith( + value: result.hatchingQuantity?.separatedByCommaFa ?? '0', + isLoading: false, + ); + case 'مانده در سالن': + return tag.copyWith( + value: result.hatchingLeftOver?.separatedByCommaFa ?? '0', + isLoading: false, + ); + default: + return tag; + } + }).toList(); + + // third + tagInfo['third'] = tagInfo['third']!.map((tag) { + switch (tag.labelTitle) { + case 'تلفات': + return tag.copyWith( + value: result.hatchingLosses?.separatedByCommaFa ?? '0', + isLoading: false, + ); + case 'حجم کشتار شده': + return tag.copyWith( + value: + result.hatchingKilledQuantity?.separatedByCommaFa ?? '0', + isLoading: false, + ); + default: + return tag; + } + }).toList(); + + ageCardData.value = ageCardData.map((element) { + switch (element.labelTitle) { + case 'کمترین سن جوجه ریزی': + return element.copyWith( + value: result.hatchingMinAge?.separatedByCommaFa ?? '0', + isLoading: false, + ); + case 'بیشترین سن جوجه ریزی': + return element.copyWith( + value: result.hatchingMaxAge?.separatedByCommaFa ?? '0', + isLoading: false, + ); + default: + return element; + } + }).toList(); + } + }, + onError: (error, stackTrace) {}, + ); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/home/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/home/view.dart new file mode 100644 index 0000000..d44d041 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/home/view.dart @@ -0,0 +1,448 @@ +import 'package:flutter/cupertino.dart' hide LinearGradient; +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_core/presentation/widget/custom/information_card_widget.dart'; + +import 'logic.dart'; + +class PoultryScienceHomePage extends GetView { + const PoultryScienceHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNotification: true, + hasNews: true, + scrollable: true, + + child: Column( + children: [ + SizedBox(height: 18.h), + InkWell( + onTap: () { + controller.isExpanded.value = !controller.isExpanded.value; + }, + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + margin: EdgeInsetsGeometry.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all( + width: 0.50, + color: const Color(0xFFA9A9A9), + ), + ), + + child: ObxValue((data) { + return AnimatedSize( + duration: Duration(milliseconds: 300), + child: data.value + ? mainItemWidget() + : mainItemWidgetExpanded(), + ); + }, controller.isExpanded), + ), + Positioned( + top: -10, + right: 20, + child: Container( + height: 32.h, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all( + width: 0.50, + color: const Color(0xFFA9A9A9), + ), + ), + padding: EdgeInsets.symmetric(horizontal: 8), + child: Row( + spacing: 8, + children: [ + Assets.vec.chicken2Svg.svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode( + AppColor.blueDark, + BlendMode.srcIn, + ), + ), + Text( + 'اطلاعات فارم‌ها', + textAlign: TextAlign.right, + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ], + ), + ), + ), + ], + ), + ), + SizedBox(height: 10), + widelyWidget(), + SizedBox(height: 20), + ], + ), + ); + } + + Padding mainItemWidget() { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 8), + firstTagInformation(), + secondTagInformation(), + ], + ), + ); + } + + Padding mainItemWidgetExpanded() { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 8), + /* Row( + spacing: 8, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + width: 40, + height: 40, + decoration: ShapeDecoration( + shape: RoundedRectangleBorder( + side: BorderSide(width: 0.25, color: const Color(0xFFB0B0B0)), + borderRadius: BorderRadius.circular(4), + ), + ), + child: Assets.images.liveChicken.image( + width: 40.w, + height: 40.h, + fit: BoxFit.cover, + ), + ), + Text( + 'فارم ها', + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkActive), + ), + Spacer(), + AnimatedRotation( + turns: 180, + duration: Duration(milliseconds: 3000), + child: Icon(CupertinoIcons.chevron_up, size: 18), + ), + ], + ),*/ + SizedBox(height: 8), + firstTagInformation(), + Row( + children: [ + Text( + 'اطلاعات جوجه‌ریزی', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), + ], + ), + secondTagInformation(), + thirdTagInformation(), + ageCardInformation(), + ], + ), + ); + } + + Widget firstTagInformation() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + List? items = data['first']!; + return Row( + spacing: 8, + children: List.generate( + items.length, + (index) => Expanded(child: InformationTag(data: items[index])), + ), + ); + }, controller.tagInfo), + ); + } + + Widget secondTagInformation() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + List? items = data['second']!; + return Row( + spacing: 8, + children: List.generate( + items.length, + (index) => Expanded(child: InformationTag(data: items[index])), + ), + ); + }, controller.tagInfo), + ); + } + + Widget thirdTagInformation() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + List? items = data['third']!; + return Row( + spacing: 8, + children: List.generate( + items.length, + (index) => Expanded(child: InformationTag(data: items[index])), + ), + ); + }, controller.tagInfo), + ); + } + + Widget ageCardInformation() { + return Padding( + padding: EdgeInsets.fromLTRB(30.w, 8, 30.w, 13), + child: ObxValue((data) { + return Row( + spacing: 8, + children: List.generate( + data.length, + (index) => Expanded(child: InformationCard(data: data[index])), + ), + ); + }, controller.ageCardData), + ); + } + + //region Widely Used Widget + Widget widelyWidget() { + return Container( + margin: EdgeInsetsGeometry.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), + ), + child: Stack( + clipBehavior: Clip.none, + children: [ + Padding( + padding: EdgeInsets.fromLTRB(12.w, 24.h, 12.w, 16.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + widelyUsed( + title: 'بازرسی', + iconPath: Assets.vec.cubeSearchSvg.path, + isOnEdit: false, + cardColor: AppColor.greenLightActive, + labelColor: AppColor.greenNormal, + textColor: AppColor.textColor, + onTap: () async { + controller.rootLogic.currentPage.value = 0; + + Get.toNamed( + PoultryScienceRoutes.inspectionPoultryScience, + id: poultryFirstKey, + ); + }, + ), + + widelyUsed( + title: 'ثبت کشتار', + iconPath: Assets.vec.noteRemoveSvg.path, + isOnEdit: false, + cardColor: AppColor.blueLightActive, + labelColor: AppColor.blueNormalOld, + textColor: AppColor.textColor, + onTap: () async { + controller.rootLogic.currentPage.value = 0; + Get.toNamed( + PoultryScienceRoutes.genocidePoultryScience, + id: poultryFirstKey, + ); + }, + ), + widelyUsed( + title: 'فارم ها', + iconPath: Assets.vec.cubeScanSvg.path, + cardColor: Color(0xFFFFCFA3), + labelColor: Color(0xFFF68D2B), + textColor: AppColor.textColor, + isOnEdit: false, + onTap: () async { + controller.rootLogic.currentPage.value = 0; + Get.toNamed( + PoultryScienceRoutes.farmPoultryScience, + id: poultryFirstKey, + ); + }, + ), + + widelyUsed( + title: 'جوجه‌ریزی فعال', + iconPath: Assets.vec.boxTickSvg.path, + isOnEdit: false, + cardColor: Color(0xFFD9BEFF), + labelColor: Color(0xFF9757FF), + textColor: AppColor.textColor, + onTap: () async { + controller.rootLogic.currentPage.value = 0; + Get.toNamed( + PoultryScienceRoutes.activeHatchingPoultryScience, + id: poultryFirstKey, + ); + }, + ), + ], + ), + ), + Positioned( + top: -17, + right: 11, + child: Container( + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), + ), + child: Text( + 'پر کاربردها', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), + ), + ), + ], + ), + ); + } + + Widget widelyUsed({ + required String title, + required String iconPath, + required VoidCallback onTap, + required bool isOnEdit, + Color? cardColor, + Color? labelColor, + Color? textColor, + }) { + return GestureDetector( + onTap: !isOnEdit ? onTap : null, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + spacing: 4, + children: [ + Stack( + clipBehavior: Clip.none, + children: [ + Container( + width: 48, + height: 48, + padding: EdgeInsets.all(4), + decoration: ShapeDecoration( + color: cardColor ?? Color(0xFFBECDFF), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: Container( + width: 40, + height: 40, + decoration: ShapeDecoration( + color: labelColor ?? AppColor.blueNormal, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: SvgGenImage.vec(iconPath).svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), + fit: BoxFit.cover, + ), + ), + ), + Visibility( + visible: isOnEdit, + child: Container( + width: 48, + height: 48, + padding: EdgeInsets.all(4), + decoration: ShapeDecoration( + color: Colors.white60, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + + Visibility( + visible: isOnEdit, + child: Positioned( + top: -15, + left: -12, + child: SizedBox( + width: 32.w, + height: 32.h, + child: GestureDetector( + onTap: () {}, + behavior: HitTestBehavior.translucent, + child: Center( + child: Container( + width: 16, + height: 16, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, + ), + alignment: Alignment.center, + child: Icon( + CupertinoIcons.minus, + color: AppColor.error, + size: 15, + ), + ), + ), + ), + ), + ), + ), + ], + ), + Text( + title, + style: AppFonts.yekan10Bold.copyWith( + color: textColor ?? AppColor.blueNormal, + ), + ), + ], + ), + ); + } + + //endregion +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/inspection/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/inspection/logic.dart new file mode 100644 index 0000000..75fc4b7 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/inspection/logic.dart @@ -0,0 +1,294 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/inspection/logic.dart +import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/inspection/logic.dart +import 'package:rasadyar_core/core.dart'; + +class InspectionPoultryScienceLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + Rx>> hatchingList = + Resource>.loading().obs; + + Rx>> hatchingReportList = + Resource>.loading().obs; + + PoultryScienceRootLogic rootLogic = Get.find(); + + Rx currentLocation = LatLng( + 34.798315281272544, + 48.51479142983491, + ).obs; + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + getHatchingReport(); + + checkLocationPermission(request: true); + + ever(pickedImages, (callback) { + _multiPartPickedImages.clear(); + for (var element in pickedImages) { + _multiPartPickedImages.add( + MultipartFile.fromFileSync(element.path, filename: element.name), + ); + } + }); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + hatchingList.value = Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await rootLogic.poultryRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching', 'report': true}, + role: 'PoultryScience', + search: 'filter', + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + hatchingList.value = Resource>.empty(); + } else { + hatchingList.value = Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(hatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future getHatchingReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + hatchingReportList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.poultryRepository.getHatchingPoultryReport( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'PoultryScience', + pageSize: 50, + search: 'filter', + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + hatchingReportList.value = + Resource>.empty(); + } else { + hatchingReportList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(hatchingReportList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void clearImages() { + pickedImages.clear(); + } + + Future submitInspectionReport({required int id}) async { + isOnUpload.value = true; + + final tmpFiles = await Future.wait( + pickedImages.map( + (element) => + MultipartFile.fromFile(element.path, filename: element.name), + ), + ); + + var data = FormData.fromMap({ + 'file': tmpFiles, + 'hatching_id': id.toString(), + 'lat': currentLocation.value.latitude.toString(), + 'log': currentLocation.value.longitude.toString(), + }); + + safeCall( + call: () async => + await rootLogic.poultryRepository.submitPoultryScienceReport( + token: rootLogic.tokenService.accessToken.value!, + data: data, + onSendProgress: (sent, total) { + presentUpload.value = calculateUploadProgress( + sent: sent, + total: total, + ); + }, + ), + onSuccess: (res) { + closeBottomSheet(); + clearImages(); + getHatchingList(); + getHatchingReport(); + isOnUpload.value = false; + }, + onError: (error, stackTrace) async { + clearImages(); + isOnUpload.value = false; + + await Future.delayed( + const Duration(seconds: 4), + ).then((value) => closeBottomSheet()); + }, + showError: true, + ); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + String getStatus(HatchingReport item) { + if (item.state == 'accepted') { + return 'تکمیل شده'; + } else if (item.state == 'rejected') { + return 'رد شده'; + } else { + return 'در حال بررسی'; + } + } + + Color getStatusColor(HatchingReport item) { + if (item.state == 'accepted') { + return AppColor.greenNormal; + } else if (item.state == 'rejected') { + return AppColor.redNormal; + } else { + return AppColor.yellowNormal; + } + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + final isReporter = selectedSegmentIndex.value == 1; + if (isReporter) { + getHatchingReport(); + } else { + getHatchingList(); + } + } + + Future onRefresh() async { + currentPage.value = 1; + + await Future.wait([getHatchingList(), getHatchingReport()]); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/inspection/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/inspection/view.dart new file mode 100644 index 0000000..0ceb1a4 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/inspection/view.dart @@ -0,0 +1,699 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching_report/hatching_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class InspectionPoultrySciencePage extends GetView { + const InspectionPoultrySciencePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: poultryScienceActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column( + children: [ + SizedBox(height: 50, child: segmentWidget()), + ObxValue((data) { + return data.value == 0 ? hatchingWidget() : reportWidget(); + }, controller.selectedSegmentIndex), + ], + ), + ); + } + + Widget hatchingWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: item.reportInfo?.image == false + ? Assets.vec.timerSvg.path + : Assets.vec.checkSquareSvg.path, + labelIconColor: item.reportInfo?.image == false + ? AppColor.yellowNormal2 + : AppColor.mediumGreyDarkHover, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.hatchingList), + ); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن ${item.age} (روزه)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow(title: 'شماره مجوز جوجه ریزی', value: item.licenceNumber ?? 'N/A'), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow(title: 'تلفات', value: item.losses.separatedByCommaFa, unit: '(قطعه)'), + buildRow( + title: 'دامپزشک فارم', + value: '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false ? 'ارسال تصویر جوجه ریزی فارم ' : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) ? AppColor.greenNormal : AppColor.redDark, + ), + ), + Visibility( + visible: (item.reportInfo?.image == false), + child: RElevated( + text: 'ثبت بازرسی', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + cameraBottomSheet(item.id!); + }, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ), + ], + ), + ); + } + + void cameraBottomSheet(int id) { + Get.bottomSheet( + isDismissible: false, + isScrollControlled: false, + BaseBottomSheet( + height: 350.h, + child: Column( + children: [ + ObxValue((data) { + return GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + mainAxisSpacing: 8, + crossAxisSpacing: 8, + childAspectRatio: 1, + ), + shrinkWrap: true, + itemCount: controller.pickedImages.length + 1, + itemBuilder: (context, index) { + if (index + 1 < 7 && index == data.length) { + return GestureDetector( + onTap: () async { + await controller.pickImages(); + }, + child: Container( + width: 80.h, + height: 80.h, + decoration: BoxDecoration( + color: AppColor.lightGreyNormal, + borderRadius: BorderRadius.circular(8.r), + ), + child: Center( + child: Icon( + Icons.add_a_photo, + color: AppColor.lightGreyDarker, + size: 32.h, + ), + ), + ), + ); + } else { + return Container( + width: 80.h, + height: 80.h, + decoration: BoxDecoration( + color: AppColor.lightGreyNormal, + borderRadius: BorderRadius.circular(8.r), + ), + child: Stack( + children: [ + Positioned.fill( + child: Image.file(File(data[index].path), fit: BoxFit.cover), + ), + + Positioned( + top: 4, + left: 4, + child: GestureDetector( + onTap: () { + controller.removeImage(index); + }, + child: Container( + width: 24.w, + height: 24.h, + clipBehavior: Clip.antiAlias, + padding: EdgeInsets.all(4), + decoration: ShapeDecoration( + color: Colors.white.withValues(alpha: 0.80), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + ), + child: Assets.vec.trashSvg.svg( + width: 8.w, + height: 8.h, + colorFilter: ColorFilter.mode( + AppColor.redNormal, + BlendMode.srcIn, + ), + ), + ), + ), + ), + ], + ), + ); + } + }, + ); + }, controller.pickedImages), + + SizedBox(height: 35.h), + Text( + 'حداقل ۲ تصویر برای ثبت بازرسی لازم است', + style: AppFonts.yekan12.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 8.h), + Row( + spacing: 16, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Obx(() { + return RElevated( + height: 40.h, + text: 'ارسال', + backgroundColor: AppColor.greenNormal, + progress: controller.presentUpload.value, + isLoading: controller.isOnUpload.value, + enabled: controller.pickedImages.length >= 2, + onPressed: () async { + controller.submitInspectionReport(id: id); + }, + ); + }), + ObxValue((data) { + return RElevated( + height: 40.h, + text: 'انصراف', + backgroundColor: AppColor.redNormal, + enabled: !data.value, + onPressed: () { + if (!data.value) { + controller.clearImages(); + Get.back(); + } + }, + ); + }, controller.isOnUpload), + ], + ), + SizedBox(height: 8.h), + ], + ), + ), + ).whenComplete(() { + controller.pickedImages.clear(); + }); + } + + Padding segmentWidget() { + return Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), + child: Row( + children: [ + Expanded( + child: RSegment( + children: ['بازرسی', 'بایگانی'], + selectedIndex: 0, + borderColor: const Color(0xFFB4B4B4), + selectedBorderColor: AppColor.blueNormal, + selectedBackgroundColor: AppColor.blueLight, + onSegmentSelected: (index) => controller.selectedSegmentIndex.value = index, + backgroundColor: AppColor.whiteGreyNormal, + ), + ), + ], + ), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: item.state == 'rejected' ? AppColor.redLight : AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingReport(true), + ); + }, controller.hatchingReportList), + ); + } + + Widget itemListExpandedWidgetReport(HatchingReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.hatching?.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.hatching?.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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('نژاد:', style: AppFonts.yekan14.copyWith(color: AppColor.textColor)), + Text( + item.hatching?.chickenBreed ?? 'N/A', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + Text( + ' سن ${item.hatching?.chickenAge} (روزه)', + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.hatching?.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow(title: 'شماره مجوز جوجه ریزی', value: item.hatching?.licenceNumber ?? 'N/A'), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.hatching?.quantity.separatedByCommaFa ?? 'N/A', + + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.hatching?.leftOver.separatedByCommaFa ?? 'N/A', + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.hatching?.losses.separatedByCommaFa ?? 'N/A', + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.hatching?.vetFarm?.vetFarmFullName}(${item.hatching?.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith(color: controller.getStatusColor(item)), + valueStyle: AppFonts.yekan14.copyWith(color: controller.getStatusColor(item)), + ), + + if (item.state == 'accepted') ...{ + Visibility( + visible: item.realQuantityAi != null, + child: buildRow( + title: 'تعداد تاییده هوش مصنوعی', + value: item.realQuantityAi.separatedByComma, + ), + ), + Visibility( + visible: item.realQuantity != null, + child: buildRow( + title: 'تعداد تاییده', + value: item.realQuantity.separatedByComma, + ), + ), + }, + + if (item.state == 'rejected') ...{ + Visibility( + visible: item.messageAi != null, + child: buildRow(title: 'پیام هوش مصنوعی', value: item.messageAi ?? '-'), + ), + Visibility( + visible: item.message != null, + child: buildRow(title: 'پیام', value: item.message ?? '-'), + ), + Visibility( + visible: item.messageRegistererFullname != null, + child: buildRow( + title: 'ثبت کننده گزارش', + value: item.messageRegistererFullname ?? '-', + ), + ), + Visibility( + visible: item.messageRegistererMobile != null, + child: buildRow( + title: 'موبایل کننده گزارش', + value: item.messageRegistererMobile ?? '-', + ), + ), + Visibility( + visible: item.messageRegistererRole != null, + child: buildRow(title: 'نقش کننده گزارش', value: item.messageRegistererRole ?? '-'), + ), + }, + + SizedBox( + height: 140.h, + child: GridView.builder( + shrinkWrap: true, + itemCount: item.image?.length ?? 0, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 10, + crossAxisSpacing: 10, + ), + itemBuilder: (context, index) => Container( + height: 100.h, + clipBehavior: Clip.hardEdge, + child: Image.network( + item.image?[index] ?? '', + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Padding( + padding: EdgeInsetsGeometry.all(80), + + child: CircularProgressIndicator( + color: AppColor.blueDark, + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + (loadingProgress.expectedTotalBytes ?? 1) + : null, + ), + ); + }, + ), + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8.r)), + ), + ), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } + + Row itemListWidgetReport(HatchingReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + item.hatching?.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.hatching?.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.hatching?.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.hatching?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + final isReporter = controller.selectedSegmentIndex.value == 0; + if (isReporter) { + controller.getHatchingReport(); + } else { + controller.getHatchingList(); + } + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/killing_registration/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/killing_registration/logic.dart new file mode 100644 index 0000000..1d3059d --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/killing_registration/logic.dart @@ -0,0 +1,462 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/killing_registration/logic.dart +import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart'; +import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; +import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart'; +import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/genocide/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_export/poultry_export.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/kill_registration/kill_registration.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/approved_price/approved_price.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/sell_for_freezing/sell_for_freezing.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/genocide/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/killing_registration/logic.dart +import 'package:rasadyar_core/core.dart'; + +class KillingRegistrationLogic extends GetxController { + List routes = ['اقدام', 'درخواست کشتارها', 'ثبت کشتار']; + var tokenService = Get.find(); + var gService = Get.find(); + var rootLogic = Get.find(); + GlobalKey formKey = GlobalKey(); + + Rxn approvedPrice = Rxn(); + Rx killsDate = Jalali.now().obs; + + Rxn sellForFreezing = Rxn(); + Rxn poultryExport = Rxn(); + + TextEditingController quantityKillsController = TextEditingController(); + RxBool quantityKillsIsCompleted = false.obs; + TextEditingController quantityLoseController = TextEditingController( + text: 0.toString(), + ); + TextEditingController averageWeightKillsController = TextEditingController(); + RxBool averageWeightKillsIsCompleted = false.obs; + TextEditingController priceFreeSaleController = TextEditingController(); + + RxInt generatedApprovedPrice = 0.obs; + RxBool isOnSubmitLoading = false.obs; + + RxBool isExportSelected = false.obs; + RxBool isFreezedSelected = false.obs; + RxBool isMarketSelected = false.obs; + RxBool isFreeSale = false.obs; + + //step 1 + Rx>> allPoultryList = + Resource>.loading().obs; + Rxn selectedPoultry = Rxn(); + + //step 2 + Rx>> poultryList = + Resource>.success([]).obs; + Rxn selectedKillRequestPoultry = Rxn(); + + //step 3 + Rx>> poultryHatchingList = + Resource>.success([]).obs; + Rxn selectedPoultryHatching = Rxn(); + + //step 5 + Rx>> killHouseList = + Resource>.success([]).obs; + Rxn selectedKillHouse = Rxn(); + + @override + void onReady() { + super.onReady(); + + getApprovedPrice(); + + getAllPoultryList(); + + getSellForFreezing(); + + getPoultryExport(); + + priceListener(); + + ever(selectedKillRequestPoultry, (callback) { + if (callback?.provinceAllowChooseKillHouse?.allowState ?? false) { + getKillHouseList(); + } + }); + + everAll( + [ + selectedPoultry, + selectedKillRequestPoultry, + selectedPoultryHatching, + selectedKillHouse, + ], + (callback) { + checkSubmitButton(); + }, + ); + } + + @override + void onClose() { + super.onClose(); + quantityKillsController.dispose(); + quantityLoseController.dispose(); + averageWeightKillsController.dispose(); + priceFreeSaleController.dispose(); + clearSelectedStep1(); + clearSelectedStep2(); + selectedKillHouse.value = null; + killHouseList.value = Resource>.success([]); + } + + void priceListener() { + quantityKillsController.addListener(() { + quantityKillsIsCompleted.value = quantityKillsController.text + .trim() + .isNotEmpty; + + if (averageWeightKillsController.text.isNotEmpty && + quantityKillsController.text.trim().isNotEmpty) { + generatedApprovedPrice.value = calculateApprovedPrice().toInt(); + priceFreeSaleController.text = + generatedApprovedPrice.value.separatedByComma; + + checkSubmitButton(); + } else { + generatedApprovedPrice.value = 0; + priceFreeSaleController.text = '0'; + checkSubmitButton(); + } + }); + + averageWeightKillsController.addListener(() { + averageWeightKillsIsCompleted.value = averageWeightKillsController.text + .trim() + .isNotEmpty; + + if (averageWeightKillsController.text.trim().isNotEmpty && + quantityKillsController.text.trim().isNotEmpty) { + generatedApprovedPrice.value = calculateApprovedPrice().toInt(); + priceFreeSaleController.text = + generatedApprovedPrice.value.separatedByComma; + checkSubmitButton(); + } else { + generatedApprovedPrice.value = 0; + priceFreeSaleController.text = '0'; + checkSubmitButton(); + } + }); + + priceFreeSaleController.addListener(() { + final text = priceFreeSaleController.text; + if (text.isNotEmpty) { + generatedApprovedPrice.value = int.parse(text.replaceAll(',', '')); + } else { + generatedApprovedPrice.value = 0; + } + checkSubmitButton(); + }); + } + + void clearSelectedStep1() { + selectedPoultry.value = null; + selectedKillRequestPoultry.value = null; + selectedPoultryHatching.value = null; + poultryList.value = Resource>.success([]); + poultryHatchingList.value = Resource>.success([]); + } + + void clearSelectedStep2() { + selectedKillRequestPoultry.value = null; + selectedPoultryHatching.value = null; + poultryHatchingList.value = Resource>.success([]); + } + + Future getApprovedPrice() async { + await safeCall( + call: () async => await rootLogic.poultryRepository.getApprovedPrice( + token: tokenService.accessToken.value ?? '', + ), + onSuccess: (result) { + if (result != null) { + approvedPrice.value = result; + } + }, + onError: (error, stackTrace) {}, + ); + } + + Future getAllPoultryList() async { + await safeCall( + call: () async => await rootLogic.poultryRepository.getAllPoultry( + token: tokenService.accessToken.value ?? '', + queryParameters: buildRawQueryParams( + role: gService.getRole(Module.chicken), + ), + ), + onSuccess: (result) { + if (result != null) { + allPoultryList.value = Resource>.success(result); + } + }, + onError: (error, stackTrace) { + allPoultryList.value = Resource>.error( + '$error -- $stackTrace', + ); + }, + ); + } + + Future getSellForFreezing() async { + await safeCall( + call: () async => await rootLogic.poultryRepository.getSellForFreezing( + token: tokenService.accessToken.value ?? '', + ), + onSuccess: (result) { + if (result != null) { + sellForFreezing.value = result; + } + }, + onError: (error, stackTrace) {}, + ); + } + + Future getPoultryExport() async { + await safeCall( + call: () async => await rootLogic.poultryRepository.getPoultryExport( + token: tokenService.accessToken.value ?? '', + ), + onSuccess: (result) { + if (result != null) { + poultryExport.value = result; + } + }, + onError: (error, stackTrace) {}, + ); + } + + Future getUserPoultryList() async { + poultryList.value = Resource>.loading(); + await safeCall( + call: () async => await rootLogic.poultryRepository.getUserPoultry( + token: tokenService.accessToken.value ?? '', + queryParameters: buildQueryParams( + value: selectedPoultry.value?.user?.mobile, + queryParams: {'type': 'filter'}, + ), + ), + onSuccess: (result) { + if (result != null) { + poultryList.value = Resource>.success( + result, + ); + } + }, + onError: (error, stackTrace) { + poultryList.value = Resource>.error( + '$error -- $stackTrace', + ); + }, + ); + } + + Future getPoultryHatchingList() async { + poultryHatchingList.value = Resource>.loading(); + await safeCall( + call: () async => await rootLogic.poultryRepository.getPoultryHatching( + token: tokenService.accessToken.value ?? '', + queryParameters: buildRawQueryParams( + queryParams: {'key': selectedKillRequestPoultry.value?.key}, + ), + ), + onSuccess: (result) { + if (result != null) { + poultryHatchingList.value = Resource>.success( + result, + ); + } + }, + onError: (error, stackTrace) { + poultryHatchingList.value = Resource>.error( + '$error -- $stackTrace', + ); + }, + ); + } + + Future getKillHouseList() async { + killHouseList.value = Resource>.loading(); + await safeCall( + call: () async => await rootLogic.poultryRepository.getKillHouseList( + token: tokenService.accessToken.value ?? '', + queryParameters: buildRawQueryParams( + queryParams: { + 'show_poultry': '', + 'date': DateTime.now().formattedDashedGregorian, + }, + ), + ), + onSuccess: (result) { + if (result != null) { + killHouseList.value = Resource>.success( + result, + ); + } + }, + onError: (error, stackTrace) { + killHouseList.value = Resource>.error( + '$error -- $stackTrace', + ); + }, + ); + } + + double calculateApprovedPrice() { + final inputWeight = double.parse(averageWeightKillsController.text) * 1000; + final lowestWeight = approvedPrice.value?.lowestWeight ?? 0; + final highestWeight = approvedPrice.value?.highestWeight ?? 0; + final lowestPrice = approvedPrice.value?.lowestPrice ?? 0; + final highestPrice = approvedPrice.value?.highestPrice ?? 0; + + if (inputWeight <= lowestWeight) { + return lowestPrice; + } else if (inputWeight >= highestWeight) { + return highestPrice; + } else { + final diffWeight = highestWeight - lowestWeight; + final diffPrice = highestPrice - lowestPrice; + final fraction = diffPrice / diffWeight; + final diffFromMinWeight = inputWeight - lowestWeight; + return diffFromMinWeight * fraction + lowestPrice; + } + } + + void changeSaleType() { + isFreeSale.value = !isFreeSale.value; + generatedApprovedPrice.value = calculateApprovedPrice().toInt(); + } + + void checkSubmitButton() { + isOnSubmitLoading.value = + selectedPoultry.value != null && + selectedKillRequestPoultry.value != null && + selectedPoultryHatching.value != null && + quantityKillsController.text.isNotEmpty && + averageWeightKillsController.text.isNotEmpty && + ((selectedKillRequestPoultry + .value + ?.provinceAllowChooseKillHouse + ?.mandatory ?? + false) + ? selectedKillHouse.value != null + : true); + } + + Future submitKillRegistration() async { + isOnSubmitLoading.value = false; + if (!formKey.currentState!.validate()) { + return; + } + + dLog(double.parse(averageWeightKillsController.text)); + KillRegistrationRequest registrationRequest = KillRegistrationRequest( + indexWeight: double.parse(averageWeightKillsController.text), + amount: generatedApprovedPrice.value, + approvedPrice: approvedPrice.value?.approved ?? false, + auctionList: [], + cash: true, + chickenBreed: selectedPoultryHatching.value?.chickenBreed, + confirmPoultryMobile: selectedPoultry.value?.user?.mobile, + credit: false, + export: isExportSelected.value, + financialOperation: "outside-system", + freeSaleInProvince: isMarketSelected.value, + freezing: isFreezedSelected.value, + killHouseList: [ + if (selectedKillHouse.value != null) + '${selectedKillHouse.value?.name}(${selectedKillHouse.value?.fullname})', + ], + killReqKey: selectedKillHouse.value?.killReqKey, + losses: quantityLoseController.text, + market: isMarketSelected.value, + operatorKey: "", + poultryHatchingKey: selectedPoultryHatching.value?.key, + poultryKey: selectedPoultry.value?.key, + quantity: int.parse(quantityKillsController.text.clearComma), + role: gService.getRole(Module.chicken), + sendDate: killsDate.value.toDateTime().formattedDashedGregorian, + ); + + await safeCall( + call: () async => + await rootLogic.poultryRepository.submitKillRegistration( + token: tokenService.accessToken.value ?? '', + request: registrationRequest, + ), + onSuccess: (result) async { + defaultShowSuccessMessage( + 'ثبت با موفقیت انجام شد', + durationInSeconds: 2, + onDismissed: () async { + Get.find().getPoultryOrderList(); + Future.delayed(Duration(milliseconds: 300), () { + Get.back(); + }); + Get.find().getPoultryOrderList(); + }, + ); + }, + onError: (error, stackTrace) {}, + ); + } + + void clearAllFields() { + // ریست فرم + formKey.currentState?.reset(); + + // ریست Rxn ها + approvedPrice.value = null; + sellForFreezing.value = null; + poultryExport.value = null; + selectedPoultry.value = null; + selectedKillRequestPoultry.value = null; + selectedPoultryHatching.value = null; + selectedKillHouse.value = null; + + // ریست Rx ها + killsDate.value = Jalali.now(); + generatedApprovedPrice.value = 0; + isOnSubmitLoading.value = false; + isExportSelected.value = false; + isFreezedSelected.value = false; + isMarketSelected.value = false; + isFreeSale.value = false; + + // ریست TextEditingController ها + quantityKillsController.clear(); + quantityLoseController.text = '0'; + averageWeightKillsController.clear(); + priceFreeSaleController.clear(); + + // ریست RxBool ها + quantityKillsIsCompleted.value = false; + averageWeightKillsIsCompleted.value = false; + + // ریست Resource لیست‌ها + allPoultryList.value = Resource>.loading(); + poultryList.value = Resource>.success([]); + poultryHatchingList.value = Resource>.success([]); + killHouseList.value = Resource>.success([]); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/killing_registration/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/killing_registration/view.dart new file mode 100644 index 0000000..a7a3cac --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/killing_registration/view.dart @@ -0,0 +1,587 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/all_poultry/all_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_house_poultry/kill_house_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/kill_request_poultry/kill_request_poultry.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_hatching/poultry_hatching.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class KillingRegistrationPage extends GetView { + const KillingRegistrationPage({super.key}); + + @override + Widget build(BuildContext context) { + return Form( + key: controller.formKey, + child: Column( + children: [ + poultryFarmWidget(), + poultryUserListWidget(), + poultryHatchingWidget(), + ObxValue((data) { + return Visibility( + visible: controller.selectedPoultryHatching.value != null, + child: Column( + children: [ + informationWidget(), + killDateWidget( + date: controller.killsDate, + onChanged: (Jalali jalali) { + controller.killsDate.value = jalali; + }, + ), + quantityKillsWidget(), + ], + ), + ); + }, controller.selectedPoultryHatching), + ObxValue((data) { + return Visibility( + visible: data.value, + child: Column(children: [averageWeightKillsWidget()]), + ); + }, controller.quantityKillsIsCompleted), + + ObxValue((data) { + return Visibility( + visible: data.value, + child: Column( + children: [ + saleTypeWidget(), + priceWidget(), + buyerListWidget(), + slaughterhouseSelectedWidget(), + submitButtonWidget(), + ], + ), + ); + }, controller.averageWeightKillsIsCompleted), + ], + ), + ); + } + + Widget poultryFarmWidget() { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h), + child: ObxValue((data) { + return ResourceOverlayDropdown( + items: data.value, + background: Colors.white, + onChanged: (value) { + controller.clearSelectedStep1(); + controller.selectedPoultry.value = value; + controller.getUserPoultryList(); + }, + selectedItem: controller.selectedPoultry.value, + itemBuilder: (item) => labelPoultryWidget(item), + labelBuilder: (item) => labelPoultryWidget(item), + ); + }, controller.allPoultryList), + ); + } + + Widget labelPoultryWidget(AllPoultry? item) { + if (item == null) { + return Row( + children: [ + Assets.vec.farmSvg.svg( + width: 28.w, + height: 28.h, + colorFilter: const ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn), + ), + SizedBox(width: 4.w), + Text('انتخاب مرغداری', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)), + ], + ); + } else { + return Text('${item.unitName} (${item.address?.city?.name})', maxLines: 2); + } + } + + Widget poultryUserListWidget() { + return ObxValue((data) { + if (data.value == null) { + return SizedBox.shrink(); + } + return Padding( + padding: EdgeInsets.symmetric(horizontal: 8.w), + child: ObxValue((data) { + return ResourceOverlayDropdown( + items: data.value, + background: Colors.white, + onChanged: (value) { + controller.clearSelectedStep2(); + controller.selectedKillRequestPoultry.value = value; + controller.getPoultryHatchingList(); + }, + selectedItem: controller.selectedKillRequestPoultry.value, + itemBuilder: (item) => labelPoultryUser(item), + labelBuilder: (item) => labelPoultryUser(item), + ); + }, controller.poultryList), + ); + }, controller.selectedPoultry); + } + + Widget labelPoultryUser(KillRequestPoultry? item) { + if (item == null) { + return Row( + children: [ + Assets.vec.chickenHouseSvg.svg( + width: 28.w, + height: 28.h, + colorFilter: const ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn), + ), + SizedBox(width: 6.w), + Text('محل پرورش', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)), + ], + ); + } else { + return Text(item.unitName ?? '-'); + } + } + + Widget poultryHatchingWidget() { + return ObxValue((data) { + if (data.value == null) { + return SizedBox.shrink(); + } + return Padding( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h), + child: ObxValue((data) { + return ResourceOverlayDropdown( + items: data.value, + background: Colors.white, + onChanged: (value) { + controller.selectedPoultryHatching.value = value; + }, + selectedItem: controller.selectedPoultryHatching.value, + itemBuilder: (item) => labelPoultryHatching(item), + labelBuilder: (item) => labelPoultryHatching(item), + ); + }, controller.poultryHatchingList), + ); + }, controller.selectedKillRequestPoultry); + } + + Widget labelPoultryHatching(PoultryHatching? item) { + if (item == null) { + return Row( + children: [ + Assets.vec.calendarSvg.svg( + width: 28.w, + height: 28.h, + colorFilter: const ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn), + ), + SizedBox(width: 6.w), + Text('دوره جوجه ریزی', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)), + ], + ); + } else { + return Text( + ' دوره ${item.period} سالن ${item.hall} نژاد ${item.chickenBreed} باقیمانده ${item.leftOver} قطعه ', + ); + } + } + + Widget informationWidget() { + return Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + margin: EdgeInsets.fromLTRB(8.w, 0, 8.w, 10.h), + padding: EdgeInsets.all(7), + child: ObxValue( + (data) => Column( + spacing: 8, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 4), + child: Text( + 'اطلاعات مرغداری', + textAlign: TextAlign.right, + style: AppFonts.yekan14Bold.copyWith(color: AppColor.blueNormal), + ), + ), + + Container( + decoration: ShapeDecoration( + color: const Color(0xFFEAEFFF), + shape: RoundedRectangleBorder( + side: BorderSide(width: 1, color: const Color(0xFFE0E7FF)), + borderRadius: BorderRadius.circular(8), + ), + ), + padding: EdgeInsets.all(4), + child: buildUnitRow( + title: 'تعداد جوجه ریزی', + value: data.value?.quantity.separatedByCommaFa, + unit: 'قطعه', + ), + ), + + buildUnitRow( + title: 'تلفات', + value: data.value?.losses.separatedByCommaFa, + unit: 'قطعه', + padding: EdgeInsetsGeometry.symmetric(horizontal: 4), + ), + buildUnitRow( + title: 'باقیمانده', + value: data.value?.leftOver.separatedByCommaFa, + unit: 'قطعه', + padding: EdgeInsetsGeometry.symmetric(horizontal: 4), + ), + buildUnitRow( + title: 'سن جوجه', + value: data.value?.chickenAge.separatedByCommaFa, + unit: 'روز', + padding: EdgeInsetsGeometry.symmetric(horizontal: 4), + ), + buildUnitRow( + title: 'مجوز فروش آزاد', + value: + data.value?.freeGovernmentalInfo?.totalFreeCommitmentQuantity.separatedByCommaFa, + unit: 'قطعه', + padding: EdgeInsetsGeometry.symmetric(horizontal: 4), + ), + buildUnitRow( + title: 'مانده فروش آزاد', + value: data + .value + ?.freeGovernmentalInfo + ?.leftTotalFreeCommitmentQuantity + .separatedByCommaFa, + unit: 'قطعه', + padding: EdgeInsetsGeometry.symmetric(horizontal: 4), + ), + buildUnitRow( + title: 'تلفن مرغدار', + value: data.value?.poultry?.userprofile?.mobile, + unit: '', + padding: EdgeInsetsGeometry.symmetric(horizontal: 4), + ), + ], + ), + controller.selectedPoultryHatching, + ), + ); + } + + Widget killDateWidget({required Rx date, required Function(Jalali jalali) onChanged}) { + return GestureDetector( + onTap: () { + Get.bottomSheet(modalDatePicker(onDateSelected: (value) => onChanged(value))); + }, + child: Container( + height: 40, + margin: EdgeInsets.symmetric(horizontal: 8.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.darkGreyLight), + ), + 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.yekan14.copyWith(color: AppColor.bgDark)), + Spacer(), + ObxValue((data) { + return Text( + date.value.formatCompactDate(), + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark), + ); + }, date), + ], + ), + ), + ); + } + + Widget quantityKillsWidget() { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h), + child: RTextField( + label: 'تعداد کشتار (قطعه)', + filled: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'تعداد کشتار را وارد کنید'; + } + final count = double.tryParse(value.replaceAll(',', '')); + if (controller.isFreeSale.value) { + if (count! > + (controller + .selectedPoultryHatching + .value + ?.freeGovernmentalInfo + ?.leftTotalFreeCommitmentQuantity ?? + 0)) { + return 'مجوز فروش آزاد شما کافی نیست'; + } + } else { + if (count! > (controller.selectedPoultryHatching.value?.leftOver ?? 0)) { + return 'تعداد کشتار نباید بیشتر از باقیمانده جوجه ریزی باشد'; + } + } + return null; + }, + textInputAction: TextInputAction.next, + filledColor: Colors.white, + keyboardType: TextInputType.number, + inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + controller: controller.quantityKillsController, + ), + ); + } + + Widget averageWeightKillsWidget() { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 8.w), + child: RTextField( + label: 'میانگین وزن (کیلوگرم)', + filled: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'میانگین وزن را وارد کنید'; + } + final weight = double.tryParse(value.replaceAll(',', '')); + if (weight == null || weight <= 0) { + return 'میانگین وزن باید عددی بزرگتر از صفر باشد'; + } else if (weight > + (controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.toWeight ?? + 10000) || + weight < + (controller + .selectedPoultryHatching + .value + ?.managementHatchingAgeRange + ?.fromWeight ?? + -10000)) { + return 'میانگین وزن باید بین ${controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.fromWeight} تا ${controller.selectedPoultryHatching.value?.managementHatchingAgeRange?.toWeight} کیلوگرم باشد'; + } + return null; + }, + filledColor: Colors.white, + keyboardType: TextInputType.number, + inputFormatters: [FirstDigitDecimalFormatter()], + controller: controller.averageWeightKillsController, + ), + ); + } + + Widget saleTypeWidget() { + return Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 10.h), + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h), + child: ObxValue((data) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 4, + children: [ + Text( + 'نوع فروش', + textAlign: TextAlign.center, + style: AppFonts.yekan14Bold.copyWith(color: AppColor.blueNormal), + ), + RadioGroup( + groupValue: data.value ? 1 : 0, + onChanged: (value) { + controller.changeSaleType(); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Radio(value: 0, activeColor: AppColor.blueNormal), + Text('دولتی', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)), + Spacer(), + Radio(value: 1, activeColor: AppColor.blueNormal), + Text('آزاد', style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark)), + ], + ), + ), + ], + ); + }, controller.isFreeSale), + ); + } + + Widget priceWidget() { + return ObxValue((data) { + if (!data.value) { + return Container( + height: 40.h, + margin: EdgeInsets.symmetric(horizontal: 8.w), + decoration: BoxDecoration( + color: AppColor.greenLight, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1.w, color: AppColor.whiteNormalHover), + ), + padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 4.h), + child: Row( + spacing: 8, + children: [ + Text('قیمت مصوب', style: AppFonts.yekan14.copyWith(color: AppColor.textColor)), + Spacer(), + + ObxValue((data) { + return Text( + ' ${data.value.separatedByCommaFa} ریال', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ); + }, controller.generatedApprovedPrice), + ], + ), + ); + } else { + return Padding( + padding: EdgeInsets.fromLTRB(8.w, 0, 8.w, 0), + child: RTextField( + label: 'قیمت پیشنهادی (ریال)', + validator: (value) { + if (value == null || value.isEmpty) { + return 'قیمت پیشنهادی را وارد کنید'; + } + final price = double.tryParse(value.replaceAll(',', '')); + + if (price == null || price <= 0) { + return 'قیمت پیشنهادی باید عددی بزرگتر از صفر باشد'; + } + return null; + }, + filled: true, + borderColor: AppColor.whiteNormalHover, + filledColor: AppColor.accent1, + keyboardType: TextInputType.number, + inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + controller: controller.priceFreeSaleController, + ), + ); + } + }, controller.isFreeSale); + } + + Widget buyerListWidget() { + return Padding( + padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 8.w), + child: ObxValue((data) { + return Visibility( + visible: data.value?.provinceAllowChooseKillHouse?.allowState ?? false, + child: ObxValue((data) { + return ResourceOverlayDropdown( + items: data.value, + background: Colors.white, + onChanged: (value) { + controller.selectedKillHouse.value = value; + }, + selectedItem: controller.selectedKillHouse.value, + itemBuilder: (item) => Text(buildKillHouseLabel(item)), + labelBuilder: (item) => Text(buildKillHouseLabel(item)), + ); + }, controller.killHouseList), + ); + }, controller.selectedKillRequestPoultry), + ); + } + + String buildKillHouseLabel(KillHousePoultry? item) { + if (item == null) { + return 'خریدار/ظرفیت باقیمانده'; + } else { + return '${item.name} / ${item.quantitySum} قطعه '; + } + } + + Widget slaughterhouseSelectedWidget() { + return Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + margin: EdgeInsets.symmetric(horizontal: 8.w), + padding: EdgeInsets.symmetric(horizontal: 8.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 8.h), + Text('عملیات کشتار', style: AppFonts.yekan14Bold.copyWith(color: AppColor.blueNormal)), + SizedBox(height: 8.h), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ObxValue((data) { + return Visibility( + visible: data.value?.permission ?? false, + child: ObxValue( + (data) => TitleCheckBox( + title: ' انجماد', + onChanged: (_) { + controller.isFreezedSelected.value = !controller.isFreezedSelected.value; + }, + isSelected: data.value, + ), + controller.isFreezedSelected, + ), + ); + }, controller.sellForFreezing), + + ObxValue((data) { + return TitleCheckBox( + title: 'پنل معاملات', + onChanged: (_) { + controller.isMarketSelected.value = !controller.isMarketSelected.value; + }, + isSelected: data.value, + ); + }, controller.isMarketSelected), + + ObxValue((data) { + return Visibility( + visible: data.value?.allow ?? false, + child: ObxValue((data) { + return TitleCheckBox( + title: 'صادرات', + isSelected: data.value, + onChanged: (_) { + controller.isExportSelected.value = !controller.isExportSelected.value; + }, + ); + }, controller.isExportSelected), + ); + }, controller.poultryExport), + ], + ), + SizedBox(height: 8.h), + ], + ), + ); + } + + Widget submitButtonWidget() { + return ObxValue((data) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 12.h), + child: RElevated( + enabled: data.value, + height: 45.h, + isFullWidth: true, + disabledBackgroundColor: AppColor.greenDarkHover, + backgroundColor: AppColor.greenNormal, + textStyle: AppFonts.yekan16Bold.copyWith(color: Colors.white), + onPressed: () { + controller.submitKillRegistration(); + }, + text: 'ثبت کشتار', + ), + ); + }, controller.isOnSubmitLoading); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..c919674 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionPoultryScienceLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + PoultryScienceRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.poultryRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'PoultryScience', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..b3cf427 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1135 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPoultrySciencePage + extends GetView { + const NewInspectionPoultrySciencePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: poultryScienceActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart new file mode 100644 index 0000000..9db46d1 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/logic.dart @@ -0,0 +1,46 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class PoultryActionItem { + final String title; + final String route; + final String icon; + + PoultryActionItem({ + required this.title, + required this.route, + required this.icon, + }); +} + +class PoultryActionLogic extends GetxController { + RxList items = [ + PoultryActionItem( + title: "بازرسی", + route: PoultryScienceRoutes.inspectionPoultryScience, + icon: Assets.vec.chickenInspectionSvg.path, + ), + PoultryActionItem( + title: "ثبت کشتار", + route: PoultryScienceRoutes.genocidePoultryScience, + icon: Assets.vec.registerKillSvg.path, + ), + PoultryActionItem( + title: "فارم ها", + route: PoultryScienceRoutes.farmPoultryScience, + icon: Assets.vec.farmsSvg.path, + ), + PoultryActionItem( + title: "جوجه ریزی فعال", + route: PoultryScienceRoutes.activeHatchingPoultryScience, + icon: Assets.vec.activeFramSvg.path, + ), + + PoultryActionItem( + title: "بازرسی مزارع طیور", + route: PoultryScienceRoutes.newInspectionPoultryScience, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/view.dart new file mode 100644 index 0000000..4d07228 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/poultry_action/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class PoultryActionPage extends GetView { + PoultryActionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: poultryScienceActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/root/logic.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/root/logic.dart new file mode 100644 index 0000000..11a6a1b --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/root/logic.dart @@ -0,0 +1,110 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/poultry_science/root/logic.dart +import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/common/profile/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/home/view.dart'; +======== +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +>>>>>>>> develop:packages/chicken/lib/features/poultry_science/presentation/pages/root/logic.dart +import 'package:rasadyar_chicken/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class PoultryScienceRootLogic extends GetxController { + var tokenService = Get.find(); + + late PoultryScienceRepository poultryRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 1.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(poultryScienceActionKey), + onGenerateRoute: (settings) { + final page = ChickenPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => ChickenPages.pages.firstWhere( + (e) => e.name == PoultryScienceRoutes.actionPoultryScience, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + PoultryScienceHomePage(), + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + poultryRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + int getNestedKey() { + switch (currentPage.value) { + case 0: + return poultryFirstKey; + case 1: + return poultrySecondKey; + case 2: + return poultryThirdKey; + default: + return poultryFirstKey; + } + } + + void popBackTaped() async { + final nestedKeyId = getNestedKey(); + GlobalKey? currentNestedKey = Get.nestedKey(nestedKeyId); + + if (currentNestedKey?.currentState?.canPop() == true) { + Get.back(id: nestedKeyId); + } else { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/pages/root/view.dart b/packages/chicken/lib/features/poultry_science/presentation/pages/root/view.dart new file mode 100644 index 0000000..05bb7ee --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/pages/root/view.dart @@ -0,0 +1,71 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class PoultryScienceRootPage extends GetView { + const PoultryScienceRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + RBottomNavigationItem( + label: 'عملیات', + icon: Assets.vec.settingSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + poultryScienceActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + poultryScienceActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + + controller.changePage(1); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 2, + onTap: () { + Get.nestedKey( + poultryScienceActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + + controller.changePage(2); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/routes/pages.dart b/packages/chicken/lib/features/poultry_science/presentation/routes/pages.dart new file mode 100644 index 0000000..786422e --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/routes/pages.dart @@ -0,0 +1,127 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/farm/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/farm/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/genocide/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/genocide/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/inspection/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/inspection/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/killing_registration/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/killing_registration/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/poultry_action/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/poultry_action/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_core/core.dart'; + +class PoultrySciencePages { + PoultrySciencePages._(); + + static List get pages => [ + GetPage( + name: PoultryScienceRoutes.initPoultryScience, + page: () => PoultryScienceRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => PoultryScienceRootLogic()); + Get.lazyPut(() => PoultryScienceHomeLogic()); + Get.lazyPut(() => PoultryActionLogic()); + }), + ], + ), + GetPage( + name: PoultryScienceRoutes.inspectionPoultryScience, + page: () => InspectionPoultrySciencePage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => InspectionPoultryScienceLogic()); + }), + ], + ), + GetPage( + name: PoultryScienceRoutes.newInspectionPoultryScience, + page: () => NewInspectionPoultrySciencePage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionPoultryScienceLogic()); + }), + ], + ), + GetPage( + name: PoultryScienceRoutes.actionPoultryScience, + page: () => PoultryActionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => PoultryActionLogic()); + }), + ], + ), + GetPage( + name: PoultryScienceRoutes.farmPoultryScience, + page: () => FarmPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + + BindingsBuilder(() { + Get.lazyPut(() => FarmLogic()); + Get.lazyPut(() => PoultryScienceHomeLogic()); + Get.lazyPut(() => PoultryScienceRootLogic()); + }), + ], + ), + GetPage( + name: PoultryScienceRoutes.activeHatchingPoultryScience, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic(), fenix: true); + Get.lazyPut(() => PoultryScienceRootLogic()); + }), + ], + ), + GetPage( + name: PoultryScienceRoutes.genocidePoultryScience, + page: () => GenocidePage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => GenocideLogic()); + Get.lazyPut(() => PoultryScienceRootLogic()); + Get.lazyPut(() => KillingRegistrationLogic(), fenix: true); + }), + ], + ), + GetPage( + name: PoultryScienceRoutes.killingRegistrationPoultryScience, + page: () => KillingRegistrationPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => KillingRegistrationLogic()); + Get.lazyPut(() => GenocideLogic()); + Get.lazyPut(() => PoultryScienceRootLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/routes/routes.dart b/packages/chicken/lib/features/poultry_science/presentation/routes/routes.dart new file mode 100644 index 0000000..cea4063 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/routes/routes.dart @@ -0,0 +1,14 @@ +sealed class PoultryScienceRoutes { + PoultryScienceRoutes._(); + + static const _base = '/chicken/poultryScience'; + static const initPoultryScience = '$_base/'; + static const actionPoultryScience = '$_base/action'; + static const inspectionPoultryScience = '$_base/inspection'; + static const newInspectionPoultryScience = '$_base/newInspection'; + static const farmPoultryScience = '$_base/farm'; + static const activeHatchingPoultryScience = '$_base/activeHatching'; + static const genocidePoultryScience = '$_base/genocidePoultryScience'; + static const killingRegistrationPoultryScience = + '$genocidePoultryScience/KillingRegistration'; +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart new file mode 100644 index 0000000..0ccdc56 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; + +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_core/core.dart'; + +Widget farmInfoWidget({ + required CreateInspectionBottomSheetLogic controller, + required String title, + required Widget child, + EdgeInsets? padding, +}) { + return Stack( + clipBehavior: Clip.none, + children: [ + Positioned.fill( + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: AppColor.mediumGrey), + ), + + padding: + padding ?? EdgeInsets.symmetric(horizontal: 12.w, vertical: 11.h), + child: child, + ), + ), + Positioned( + top: -17, + right: 7, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: AppColor.mediumGrey), + ), + child: Text( + title, + style: AppFonts.yekan14.copyWith(color: AppColor.iconColor), + ), + ), + ), + ], + ); +} + +Widget cardInfo({required Widget child, EdgeInsets? padding}) { + return Container( + width: Get.width, + padding: padding ?? EdgeInsets.symmetric(horizontal: 12.w, vertical: 14.h), + decoration: BoxDecoration( + color: AppColor.bgLight, + + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.blackLight), + ), + child: child, + ); +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart new file mode 100644 index 0000000..92163aa --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart @@ -0,0 +1,302 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_core/core.dart'; +import 'step1_page.dart'; +import 'step2_page.dart'; +import 'step3_page.dart'; +import 'step4_page.dart'; +import 'step5_page.dart'; + +class CreateInspectionBottomSheet + extends GetWidget { + CreateInspectionBottomSheet({super.key}); + + List get pages => [ + step1Page(controller), + step2Page(controller), + step3Page(controller), + step4Page(controller), + step5Page(controller), + ]; + + @override + Widget build(BuildContext context) { + return BaseBottomSheet( + height: Get.height, + rootChild: Column( + children: [ + ObxValue((data) { + return stepper(activeStep: data.value); + }, controller.activeStepperIndex), + Expanded( + child: PageView.builder( + physics: const NeverScrollableScrollPhysics(), + reverse: true, + controller: controller.pageController, + itemBuilder: (context, index) => pages[index], + ), + ), + + ObxValue((data) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Row( + spacing: 16, + children: [ + Expanded( + child: ObxValue((data) { + return RElevated( + height: 40.h, + enabled: + data.value && !controller.isUploadingImages.value, + backgroundColor: AppColor.greenNormal, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (controller.isUploadingImages.value) + SizedBox( + width: 16.w, + height: 16.h, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.white, + ), + ), + ) + else + Icon(Icons.arrow_back_ios, color: Colors.white), + SizedBox(width: 8.w), + Text( + controller.isUploadingImages.value + ? 'در حال آپلود...' + : (controller.activeStepperIndex.value < 4) + ? 'ادامه' + : 'ثبت', + ), + ], + ), + onPressed: () { + if (controller.activeStepperIndex.value < 4) { + controller.activeStepperIndex.value++; + } else { + controller.submitInspection(); + } + }, + ); + }, controller.nextStepButtonEnabled), + ), + Expanded( + child: ROutlinedElevated( + borderColor: AppColor.error, + height: 40.h, + child: Text('برگشت'), + enabled: + controller.activeStepperIndex.value > 0 && + !controller.isUploadingImages.value, + onPressed: () { + if (controller.activeStepperIndex.value > 0) { + controller.activeStepperIndex.value--; + } + }, + ), + ), + ], + ), + ); + }, controller.activeStepperIndex), + + // نمایش وضعیت آپلود + Obx(() { + if (controller.isUploadingImages.value) { + return Container( + padding: EdgeInsets.all(16), + margin: EdgeInsets.all(16), + decoration: BoxDecoration( + color: AppColor.whiteNormalActive, + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 4, + offset: Offset(0, 2), + ), + ], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + controller.uploadStatusMessage.value, + style: AppFonts.yekan14, + textAlign: TextAlign.center, + ), + SizedBox(height: 12.h), + LinearProgressIndicator( + value: controller.uploadProgress.value, + backgroundColor: AppColor.whiteNormalActive, + valueColor: AlwaysStoppedAnimation( + AppColor.greenNormal, + ), + ), + SizedBox(height: 8.h), + Text( + '${(controller.uploadProgress.value * 100).toInt()}%', + style: AppFonts.yekan12.copyWith( + color: AppColor.iconColor, + ), + ), + ], + ), + ); + } + return SizedBox.shrink(); + }), + ], + ), + ); + } +} + +class stepper extends StatelessWidget { + const stepper({super.key, required this.activeStep}); + final int activeStep; + + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.ltr, + child: SizedBox( + height: 24, + width: Get.width, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 0 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '1', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 0 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 1 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 1 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '2', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 1 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 2 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 2 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '3', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 2 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 3 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 3 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '4', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 3 ? Colors.white : AppColor.iconColor, + ), + ), + ), + Expanded( + child: Divider( + color: activeStep >= 4 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + thickness: 8, + ), + ), + Container( + alignment: Alignment.center, + decoration: BoxDecoration( + color: activeStep >= 4 + ? AppColor.greenNormalHover + : AppColor.whiteNormalActive, + shape: BoxShape.circle, + ), + width: 24.w, + height: 24.h, + child: Text( + '5', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith( + color: activeStep >= 3 ? Colors.white : AppColor.iconColor, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart new file mode 100644 index 0000000..c1bec90 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart @@ -0,0 +1,985 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class CreateInspectionBottomSheetLogic extends GetxController + with GetSingleTickerProviderStateMixin { + HatchingModel? hatchingModel; + + PoultryScienceRepository repository = diChicken + .get(); + + TokenStorageService tokenStorageService = Get.find(); + var gService = Get.find(); + RxInt selectedSegmentIndex = 0.obs; + + RxInt expandedIndex = RxInt(-1); + + late TabController tabController; + + RxInt selectedTabIndex = 0.obs; + + RxInt activeStepperIndex = 0.obs; + + PageController pageController = PageController(initialPage: 0); + + RxBool nextStepButtonEnabled = false.obs; + + RxInt casualtiesInformationHeight = 315.obs; + + SubmitInspectionResponse? submitInspectionResponse; + + // Upload states + RxBool isUploadingImages = false.obs; + RxString uploadStatusMessage = ''.obs; + RxDouble uploadProgress = 0.0.obs; + + //step1 + + TextEditingController unitNameController = TextEditingController(); + TextEditingController breedingUniqueIdController = TextEditingController(); + TextEditingController healthLicenseController = TextEditingController(); + TextEditingController tenantStatusController = TextEditingController(); + TextEditingController tenantNameController = TextEditingController(); + TextEditingController tenantNationalIdController = TextEditingController(); + TextEditingController tenantPhoneNumberController = TextEditingController(); + TextEditingController ownerNameController = TextEditingController(); + TextEditingController ownerNationalCodeController = TextEditingController(); + TextEditingController ownerPhoneNumberController = TextEditingController(); + TextEditingController totalCapacityController = TextEditingController(); + + //-------------------------------- + + TextEditingController hatchingDateController = TextEditingController(); + TextEditingController visitDateController = TextEditingController(); + TextEditingController hatchingCountController = TextEditingController(); + TextEditingController hatchingAverageWeightController = + TextEditingController(); + TextEditingController hatchingBreedController = TextEditingController(); + + //step2 + Resource> causeOfUnusualCasualtiesList = Resource.success([ + 'بیماری', + 'قطعی برق', + 'استرس گرمایی', + 'مشکلات دان', + 'کیفیت جوجه', + 'سایر (شرح…)', + ]); + RxnString causeOfUnusualCasualties = RxnString(); + RxBool isOthercauseOfUnusualCasualties = false.obs; + TextEditingController otherCauseOfUnusualCasualtiesController = + TextEditingController(); + + Resource> typeOfDiseaseList = Resource.success([ + 'آنفلوانزا', + 'نیوکاسل', + 'IB', + 'عفونت‌های باکتریایی', + 'مشکلات گوارشی', + 'سایر (شرح)', + ]); + RxnString typeOfDisease = RxnString(); + RxBool isOtherTypeOfDiseaseSelected = false.obs; + TextEditingController otherTypeOfDiseaseController = TextEditingController(); + + RxList pultryImagesUrls = RxList(); + RImagePickerController pultryImagesController = RImagePickerController(); + RxList pultryImages = RxList(); + + TextEditingController hatchingTemperatureController = TextEditingController(); + TextEditingController waterHardnessController = TextEditingController(); + + TextEditingController normalLossesController = TextEditingController(); + TextEditingController abnormalLossesController = TextEditingController(); + TextEditingController sourceOfHatchingController = TextEditingController(); + + RxBool samplingDone = false.obs; + TextEditingController technicalHealthOfficerNameController = + TextEditingController(); + TextEditingController technicalEngineeringOfficerNameController = + TextEditingController(); + + RxInt sanitaryConditionOfTheHallIndex = (-1).obs; + RxInt ventilationStatusIndex = (-1).obs; + RxnString sanitaryConditionOfTheHall = RxnString(); + RxnString ventilationStatus = RxnString(); + + RxInt beddingStatusIndex = (-1).obs; + RxnString beddingStatus = RxnString(); + RxInt waterQualityIndex = (-1).obs; + RxnString waterQuality = RxnString(); + RxInt fuelTypeIndex = (-1).obs; + + RxInt sampleTypeIndex = (-1).obs; + RxnString sampleType = RxnString(); + + //step3 + + Resource> inputStatusList = Resource.success([ + 'وابسته', + 'مستقل', + ]); + RxnString inputStatus = RxnString(); + TextEditingController companyNameController = TextEditingController(); + TextEditingController trackingCodeController = TextEditingController(); + + Resource> typeOfGrainList = Resource.success([ + 'آردی', + 'پلت', + 'کرامبل و اکسترود ', + 'مش ', + 'پوره و وال', + ]); + RxnString typeOfGrain = RxnString(); + + TextEditingController inputInventoryInWarehouseController = + TextEditingController(); + TextEditingController inputInventoryUntilVisitController = + TextEditingController(); + + TextEditingController generatorTypeController = TextEditingController(); + TextEditingController generatorModelController = TextEditingController(); + TextEditingController generatorCountController = TextEditingController(); + TextEditingController generatorCapacityController = TextEditingController(); + TextEditingController emergencyFuelInventoryController = + TextEditingController(); + TextEditingController powerCutDurationController = TextEditingController(); + TextEditingController powerCutHourController = TextEditingController(); + TextEditingController additionalNotesController = TextEditingController(); + RxnString fuelType = RxnString(); + RxBool powerCutHistory = false.obs; + + RxInt grainQualityInputIndex = (-1).obs; + RxnString grainQualityInput = RxnString(); + RxInt generatorOperatingStatusIndex = (-1).obs; + RxnString generatorOperatingStatus = RxnString(); + RxInt workerContractStatusIndex = (-1).obs; + RxnString workerContractStatus = RxnString(); + RxInt newBeneficiaryRequestIndex = (-1).obs; + RxBool trainingStatus = false.obs; + RxnString newBeneficiaryRequest = RxnString(); + RxBool overdueStatus = false.obs; + RxBool hasFacilities = false.obs; + TextEditingController paymentYearController = TextEditingController(); + Rx selectedPaymentYear = Jalali.now().obs; + + //step3 - worker fields + TextEditingController employedWorkersCountController = + TextEditingController(); + TextEditingController nativeWorkersCountController = TextEditingController(); + TextEditingController nonNativeWorkersCountController = + TextEditingController(); + + TextEditingController activeFacilityController = TextEditingController(); + TextEditingController facilityTypeController = TextEditingController(); + TextEditingController facilityAmountController = TextEditingController(); + + //step4 + + TextEditingController facilityYearController = TextEditingController(); + Rx selectedFacilityYear = Jalali.now().obs; + + RxInt inspectorConclusionIndex = (-1).obs; + RxnString inspectorConclusion = RxnString(); + + TextEditingController inspectorConclusionDescriptionController = + TextEditingController(); + + RxList hallImagesUrls = RxList(); + RImagePickerController hallImagesController = RImagePickerController(); + RxList hallImages = RxList(); + + RxList inputWarehouseImagesUrls = RxList(); + RImagePickerController inputWarehouseImagesController = + RImagePickerController(); + RxList inputWarehouseImages = RxList(); + + RxList lossesImagesUrls = RxList(); + RImagePickerController lossesImagesController = RImagePickerController(); + RxList lossesImages = RxList(); + + //location + Rxn currentLocation = Rxn(); + RxBool isLoadingLocation = false.obs; + + @override + void onReady() { + super.onReady(); + activeStepperIndex.listen((value) { + pageController.animateToPage( + value, + duration: Duration(milliseconds: 300), + curve: Curves.linear, + ); + }); + setUpPultryImagesListener(); + setUpHallImagesListener(); + setUpInputWarehouseImagesListener(); + setUpLossesImagesListener(); + initData(); + setUpNextButtonListeners(); + } + + @override + void onClose() { + resetAllData(); + super.onClose(); + } + + void resetAllData() { + // Reset stepper and navigation + activeStepperIndex.value = 0; + selectedTabIndex.value = 0; + selectedSegmentIndex.value = 0; + expandedIndex.value = -1; + nextStepButtonEnabled.value = false; + casualtiesInformationHeight.value = 310; + + // Reset upload states + isUploadingImages.value = false; + uploadStatusMessage.value = ''; + uploadProgress.value = 0.0; + + // Reset location + currentLocation.value = null; + isLoadingLocation.value = false; + + // Clear all TextEditingControllers - Step 1 + unitNameController.clear(); + breedingUniqueIdController.clear(); + healthLicenseController.clear(); + tenantStatusController.clear(); + tenantNameController.clear(); + tenantNationalIdController.clear(); + tenantPhoneNumberController.clear(); + ownerNameController.clear(); + ownerNationalCodeController.clear(); + ownerPhoneNumberController.clear(); + totalCapacityController.clear(); + + // Clear Step 1 additional fields + hatchingDateController.clear(); + visitDateController.clear(); + hatchingCountController.clear(); + hatchingAverageWeightController.clear(); + hatchingBreedController.clear(); + + // Clear Step 2 fields + causeOfUnusualCasualties.value = null; + isOthercauseOfUnusualCasualties.value = false; + otherCauseOfUnusualCasualtiesController.clear(); + typeOfDisease.value = null; + isOtherTypeOfDiseaseSelected.value = false; + otherTypeOfDiseaseController.clear(); + hatchingTemperatureController.clear(); + waterHardnessController.clear(); + normalLossesController.clear(); + abnormalLossesController.clear(); + sourceOfHatchingController.clear(); + samplingDone.value = false; + technicalHealthOfficerNameController.clear(); + technicalEngineeringOfficerNameController.clear(); + + // Reset Step 2 selection indices + sanitaryConditionOfTheHallIndex.value = -1; + ventilationStatusIndex.value = -1; + beddingStatusIndex.value = -1; + waterQualityIndex.value = -1; + sampleTypeIndex.value = -1; + sanitaryConditionOfTheHall.value = null; + ventilationStatus.value = null; + beddingStatus.value = null; + waterQuality.value = null; + sampleType.value = null; + + // Clear Step 3 fields + inputStatus.value = null; + companyNameController.clear(); + trackingCodeController.clear(); + typeOfGrain.value = null; + inputInventoryInWarehouseController.clear(); + inputInventoryUntilVisitController.clear(); + generatorTypeController.clear(); + generatorModelController.clear(); + generatorCountController.clear(); + generatorCapacityController.clear(); + emergencyFuelInventoryController.clear(); + powerCutDurationController.clear(); + powerCutHourController.clear(); + additionalNotesController.clear(); + fuelType.value = null; + powerCutHistory.value = false; + + // Reset Step 3 selection indices + grainQualityInputIndex.value = -1; + generatorOperatingStatusIndex.value = -1; + workerContractStatusIndex.value = -1; + newBeneficiaryRequestIndex.value = -1; + grainQualityInput.value = null; + generatorOperatingStatus.value = null; + workerContractStatus.value = null; + newBeneficiaryRequest.value = null; + trainingStatus.value = false; + overdueStatus.value = false; + hasFacilities.value = false; + + // Clear Step 3 worker fields + employedWorkersCountController.clear(); + nativeWorkersCountController.clear(); + nonNativeWorkersCountController.clear(); + activeFacilityController.clear(); + facilityTypeController.clear(); + facilityAmountController.clear(); + paymentYearController.clear(); + selectedPaymentYear.value = Jalali.now(); + + // Clear Step 4 fields + facilityYearController.clear(); + selectedFacilityYear.value = Jalali.now(); + inspectorConclusionIndex.value = -1; + inspectorConclusion.value = null; + inspectorConclusionDescriptionController.clear(); + + // Clear all images + pultryImagesController.disposeCameraController(); + pultryImagesUrls.clear(); + hallImages.clear(); + hallImagesUrls.clear(); + inputWarehouseImages.clear(); + inputWarehouseImagesUrls.clear(); + lossesImages.clear(); + lossesImagesUrls.clear(); + + // Reset fuel type index + fuelTypeIndex.value = -1; + + // Reset submitInspectionResponse + submitInspectionResponse = null; + + // Reset hatching model + hatchingModel = null; + + // Reset page controller + if (pageController.hasClients) { + pageController.jumpToPage(0); + } + } + + void initData() { + // Reset critical values before initializing + currentLocation.value = null; + nextStepButtonEnabled.value = false; + activeStepperIndex.value = 0; + selectedTabIndex.value = 0; + isLoadingLocation.value = false; + + submitInspectionResponse = SubmitInspectionResponse( + generalConditionHall: GeneralConditionHall(), + casualties: Casualties(), + technicalOfficer: TechnicalOfficer(), + inputStatus: InputStatus(), + infrastructureEnergy: InfrastructureEnergy(), + hr: Hr(), + facilities: Facilities(), + ); + + submitInspectionResponse?.poultryHatchingId = hatchingModel?.id; + + submitInspectionResponse?.role = gService.getRole(Module.chicken); + + unitNameController.text = + hatchingModel?.poultry?.unitName ?? 'واحد مرغداری نامشخص'; + + breedingUniqueIdController.text = + hatchingModel?.poultry?.breedingUniqueId ?? 'کد یکتا/شناسه واحد نامشخص'; + + healthLicenseController.text = + hatchingModel?.poultry?.healthCertificateNumber ?? + 'پروانه بهداشتی ندارد '; + + tenantStatusController.text = (hatchingModel?.poultry?.hasTenant == true) + ? 'دارد' + : 'ندارد'; + + if (hatchingModel?.poultry?.hasTenant == true) { + tenantNameController.text = + hatchingModel?.tenantFullname ?? 'نام مستاجر نامشخص'; + tenantNationalIdController.text = + hatchingModel?.tenantNationalCode ?? 'کد ملی مستاجر نامشخص'; + tenantPhoneNumberController.text = + hatchingModel?.tenantMobile ?? 'شماره تماس مستاجر نامشخص'; + } + + ownerNameController.text = + hatchingModel?.poultry?.user?.fullname ?? 'مالک واحد مرغداری نامشخص'; + ownerNationalCodeController.text = + hatchingModel?.chainCompany?.user?.nationalId ?? + 'کد ملی مالک واحد مرغداری نامشخص'; + ownerPhoneNumberController.text = + hatchingModel?.poultry?.user?.mobile ?? + 'شماره تماس مالک واحد مرغداری نامشخص'; + totalCapacityController.text = + hatchingModel?.poultry?.totalCapacity?.toString() ?? + 'ظرفیت اسمی سالن‌ها نامشخص'; + + hatchingDateController.text = + hatchingModel?.date?.toJalali.formatCompactDate() ?? + 'تاریخ جوجه ریزی نامشخص'; + hatchingCountController.text = + hatchingModel?.quantity?.separatedByComma ?? 'تعداد جوجه ریزی نامشخص'; + + hatchingBreedController.text = + hatchingModel?.chickenBreed ?? 'نوع نژاد نامشخص'; + + visitDateController.text = Jalali.now().formatCompactDate(); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setHatchingModel(HatchingModel hatchingModel) { + // Reset all data before setting new hatching model + resetAllData(); + this.hatchingModel = hatchingModel; + initData(); + } + + void changeSegmentIndex(int index) { + if (index == selectedSegmentIndex.value) { + return; + } + expandedIndex.value = -1; + selectedSegmentIndex.value = index; + } + + void changeTab(int index) { + if (index == selectedTabIndex.value) { + return; + } + selectedTabIndex.value = index; + } + + void clearForm() { + unitNameController.clear(); + activeStepperIndex.value = 0; + selectedTabIndex.value = 0; + } + + void setSanitaryConditionOfTheHallIndex(int index, String item) { + sanitaryConditionOfTheHall.value = item; + submitInspectionResponse?.generalConditionHall?.healthStatus = item; + + sanitaryConditionOfTheHallIndex.value = + index == sanitaryConditionOfTheHallIndex.value ? -1 : index; + } + + void setFuelTypeIndex(int index, String item) { + fuelType.value = item; + fuelTypeIndex.value = index == fuelTypeIndex.value ? -1 : index; + } + + void setVentilationStatusIndex(int index, String item) { + ventilationStatus.value = item; + submitInspectionResponse?.generalConditionHall?.ventilationStatus = item; + ventilationStatusIndex.value = index == ventilationStatusIndex.value + ? -1 + : index; + } + + void setBeddingStatusIndex(int index, String item) { + beddingStatus.value = item; + submitInspectionResponse?.generalConditionHall?.bedCondition = item; + beddingStatusIndex.value = index == beddingStatusIndex.value ? -1 : index; + } + + void setWaterQualityIndex(int index, String item) { + waterQuality.value = item; + submitInspectionResponse?.generalConditionHall?.drinkingWaterSource = item; + waterQualityIndex.value = index == waterQualityIndex.value ? -1 : index; + } + + void setSampleTypeIndex(int index, String item) { + sampleType.value = item; + submitInspectionResponse?.casualties?.typeSampling = item; + sampleTypeIndex.value = index == sampleTypeIndex.value ? -1 : index; + } + + void setGrainQualityInput(int index, String item) { + grainQualityInput.value = item; + submitInspectionResponse?.inputStatus?.gradeGrain = item; + grainQualityInputIndex.value = index == grainQualityInputIndex.value + ? -1 + : index; + } + + void setGeneratorOperatingStatusIndex(int index, String item) { + generatorOperatingStatus.value = item; + submitInspectionResponse?.infrastructureEnergy?.generatorPerformance = item; + generatorOperatingStatusIndex.value = + index == generatorOperatingStatusIndex.value ? -1 : index; + } + + void setWorkerContractStatusIndex(int index, String item) { + workerContractStatus.value = item; + submitInspectionResponse?.hr?.contractStatus = item; + workerContractStatusIndex.value = index == workerContractStatusIndex.value + ? -1 + : index; + } + + void setNewBeneficiaryRequestIndex(int index) { + newBeneficiaryRequestIndex.value = index == newBeneficiaryRequestIndex.value + ? -1 + : index; + } + + void setInspectorConclusionIndex(int index, String item) { + inspectorConclusion.value = item; + submitInspectionResponse?.inspectionStatus = item; + inspectorConclusionIndex.value = index == inspectorConclusionIndex.value + ? -1 + : index; + } + + Future getCurrentLocation() async { + isLoadingLocation.value = true; + + try { + final hasPermission = await checkLocationPermission(request: true); + if (!hasPermission) { + throw Exception('دسترسی به موقعیت مکانی داده نشده است'); + } + + // Get current location + final latLng = await determineCurrentLatLng(); + currentLocation.value = latLng; + isLoadingLocation.value = false; + + submitInspectionResponse?.lat = latLng.latitude.toString(); + submitInspectionResponse?.log = latLng.longitude.toString(); + + setUpNextButtonListeners(); + } catch (e) { + isLoadingLocation.value = false; + currentLocation.value = null; + nextStepButtonEnabled.value = false; + } + } + + void setUpNextButtonListeners() { + if (activeStepperIndex.value == 0) { + nextStepButtonEnabled.value = currentLocation.value != null; + } else { + nextStepButtonEnabled.value = false; + } + } + + Future?> uploadImageBatch(List images) async { + if (images.isEmpty) return []; + + List? result; + await safeCall( + call: () async { + final urls = await repository.uploadImages( + token: tokenStorageService.accessToken.value ?? '', + images: images, + ); + return urls; + }, + onSuccess: (urls) { + result = urls; + }, + onError: (error, stackTrace) { + result = null; + }, + showError: false, // خطاها در uploadAllImages مدیریت می‌شوند + ); + + return result; + } + + Future uploadAllImages() async { + isUploadingImages.value = true; + uploadProgress.value = 0.0; + uploadStatusMessage.value = 'در حال آپلود عکس‌ها...'; + + try { + int totalImages = 0; + int uploadedCount = 0; + + // شمارش کل عکس‌ها + totalImages = + hallImages.length + + inputWarehouseImages.length + + lossesImages.length + + pultryImagesController.capturedImages.length; + + if (totalImages == 0) { + isUploadingImages.value = false; + return true; + } + + // آپلود عکس‌های سالن + if (hallImages.isNotEmpty) { + uploadStatusMessage.value = 'در حال آپلود عکس‌های سالن...'; + final hallImageFiles = hallImages.toList(); + final hallUrls = await uploadImageBatch(hallImageFiles); + + if (hallUrls != null && hallUrls.isNotEmpty) { + submitInspectionResponse?.generalConditionHall?.images = hallUrls; + uploadedCount += hallImageFiles.length; + uploadProgress.value = uploadedCount / totalImages; + } else { + throw Exception('خطا در آپلود عکس‌های سالن'); + } + } + + // آپلود عکس‌های انبار دان + if (inputWarehouseImages.isNotEmpty) { + uploadStatusMessage.value = 'در حال آپلود عکس‌های انبار دان...'; + final inputImageFiles = inputWarehouseImages.toList(); + final inputUrls = await uploadImageBatch(inputImageFiles); + + if (inputUrls != null && inputUrls.isNotEmpty) { + submitInspectionResponse?.inputStatus?.images = inputUrls; + uploadedCount += inputImageFiles.length; + uploadProgress.value = uploadedCount / totalImages; + } else { + throw Exception('خطا در آپلود عکس‌های انبار دان'); + } + } + + // آپلود عکس‌های تلفات + if (lossesImages.isNotEmpty) { + uploadStatusMessage.value = 'در حال آپلود عکس‌های تلفات...'; + final lossesImageFiles = lossesImages.toList(); + final lossesUrls = await uploadImageBatch(lossesImageFiles); + + if (lossesUrls != null && lossesUrls.isNotEmpty) { + submitInspectionResponse?.casualties?.images = lossesUrls; + uploadedCount += lossesImageFiles.length; + uploadProgress.value = uploadedCount / totalImages; + } else { + throw Exception('خطا در آپلود عکس‌های تلفات'); + } + } + + // آپلود عکس‌های مرغداری + if (pultryImagesController.capturedImages.isNotEmpty) { + uploadStatusMessage.value = 'در حال آپلود عکس‌های مرغداری...'; + final poultryImageFiles = pultryImagesController.capturedImages + .toList(); + final poultryUrls = await uploadImageBatch(poultryImageFiles); + + if (poultryUrls != null && poultryUrls.isNotEmpty) { + // اگر فیلد جداگانه‌ای برای عکس‌های مرغداری نداریم، به generalConditionHall اضافه می‌کنیم + submitInspectionResponse?.generalConditionHall?.images ??= []; + submitInspectionResponse?.generalConditionHall?.images?.addAll( + poultryUrls, + ); + uploadedCount += poultryImageFiles.length; + uploadProgress.value = uploadedCount / totalImages; + } else { + throw Exception('خطا در آپلود عکس‌های مرغداری'); + } + } + + uploadProgress.value = 1.0; + uploadStatusMessage.value = 'آپلود عکس‌ها با موفقیت انجام شد'; + isUploadingImages.value = false; + return true; + } catch (e) { + isUploadingImages.value = false; + uploadStatusMessage.value = 'خطا در آپلود عکس‌ها: ${e.toString()}'; + Get.snackbar( + 'خطا', + 'خطا در آپلود عکس‌ها: ${e.toString()}', + snackPosition: SnackPosition.TOP, + backgroundColor: Colors.red, + colorText: Colors.white, + ); + return false; + } + } + + void removeImage(RxList images, String imagePath) { + images.removeWhere((element) => element.path == imagePath); + } + + void setTypeOfDiseaseIndex(String item) { + if (isOtherTypeOfDiseaseSelected.value && item != 'سایر (شرح)') { + casualtiesInformationHeight.value = + casualtiesInformationHeight.value - 50; + } + typeOfDisease.value = item; + isOtherTypeOfDiseaseSelected.value = item == 'سایر (شرح)'; + if (isOtherTypeOfDiseaseSelected.value && item == 'سایر (شرح)') { + casualtiesInformationHeight.value = + casualtiesInformationHeight.value + 50; + } + } + + void setCauseOfUnusualCasualtiesIndex(String item) { + if (isOthercauseOfUnusualCasualties.value && item != 'سایر (شرح…)') { + casualtiesInformationHeight.value = + casualtiesInformationHeight.value - 50; + } + causeOfUnusualCasualties.value = item; + isOthercauseOfUnusualCasualties.value = item == 'سایر (شرح…)'; + if (item == 'سایر (شرح…)') { + casualtiesInformationHeight.value = + casualtiesInformationHeight.value + 50; + } + } + + void setSamplingDone(String value) { + if (samplingDone.value && value != 'انجام شد') { + casualtiesInformationHeight.value = + casualtiesInformationHeight.value - 80; + } + samplingDone.value = value == 'انجام شد'; + submitInspectionResponse?.casualties?.samplingDone = samplingDone.value; + if (value == 'انجام شد') { + casualtiesInformationHeight.value = + casualtiesInformationHeight.value + 80; + } + } + + void setInputStatus(String item) { + inputStatus.value = item; + submitInspectionResponse?.inputStatus?.inputStatus = item; + } + + void setTypeOfGrain(String item) { + typeOfGrain.value = item; + submitInspectionResponse?.inputStatus?.typeOfGrain = item; + } + + void setFuelType(String item) { + fuelType.value = item; + submitInspectionResponse?.infrastructureEnergy?.fuelType = item; + } + + void setPowerCutHistory(String item) { + powerCutHistory.value = item == 'دارد'; + submitInspectionResponse?.infrastructureEnergy?.hasPowerCutHistory = + powerCutHistory.value; + } + + void setTrainingStatus(String item) { + trainingStatus.value = item == 'بله'; + submitInspectionResponse?.hr?.trained = item == 'بله'; + submitInspectionResponse?.hr?.trained = trainingStatus.value; + } + + void setNewBeneficiaryRequest(String item) { + newBeneficiaryRequest.value = item; + submitInspectionResponse?.facilities?.requestFacilities = + newBeneficiaryRequest.value; + } + + void setHasFacilities(String item) { + hasFacilities.value = item == 'دارد'; + submitInspectionResponse?.facilities?.hasFacilities = hasFacilities.value; + } + + void setOverdueStatus(String item) { + overdueStatus.value = item == 'دارای معوقه'; + submitInspectionResponse?.facilities?.repaymentStatus = item; + } + + void showPaymentYearDatePicker() { + Get.bottomSheet( + modalDatePicker( + initialDate: selectedPaymentYear.value, + onDateSelected: (value) { + selectedPaymentYear.value = value; + paymentYearController.text = value.formatCompactDate(); + }, + ), + ); + } + + void showFacilityYearDatePicker() { + Get.bottomSheet( + modalDatePicker( + initialDate: selectedFacilityYear.value, + onDateSelected: (value) { + selectedFacilityYear.value = value; + facilityYearController.text = value.formatCompactDate(); + Get.back(); + }, + ), + ); + } + + void removeHallImage(XFile key) { + hallImages.remove(key); + } + + void removeLossesImage(XFile key) { + lossesImages.remove(key); + } + + Future submitInspection() async { + // ابتدا عکس‌ها را آپلود می‌کنیم + final imagesUploaded = await uploadAllImages(); + if (!imagesUploaded) { + return; // اگر آپلود عکس‌ها ناموفق بود، متوقف می‌شویم + } + + // پر کردن داده‌های فرم + submitInspectionResponse?.generalConditionHall?.temperature = + hatchingTemperatureController.text; + submitInspectionResponse?.generalConditionHall?.drinkingWaterQuality = + waterQuality.value; + submitInspectionResponse?.casualties?.abnormalLosses = int.tryParse( + abnormalLossesController.text.clearComma, + ); + submitInspectionResponse?.casualties?.normalLosses = int.tryParse( + normalLossesController.text.clearComma, + ); + + if (isOthercauseOfUnusualCasualties.value) { + submitInspectionResponse?.casualties?.causeAbnormalLosses = + otherCauseOfUnusualCasualtiesController.text; + } else { + submitInspectionResponse?.casualties?.causeAbnormalLosses = + causeOfUnusualCasualties.value; + } + + if (isOtherTypeOfDiseaseSelected.value) { + submitInspectionResponse?.casualties?.typeDisease = + otherTypeOfDiseaseController.text; + } else { + submitInspectionResponse?.casualties?.typeDisease = typeOfDisease.value; + } + + submitInspectionResponse?.technicalOfficer?.technicalHealthOfficer = + technicalHealthOfficerNameController.text; + submitInspectionResponse?.technicalOfficer?.technicalEngineeringOfficer = + technicalEngineeringOfficerNameController.text; + + if (inputStatus.value == 'وابسته') { + submitInspectionResponse?.inputStatus?.companyName = + companyNameController.text; + } else { + submitInspectionResponse?.inputStatus?.trackingCode = + trackingCodeController.text; + } + + submitInspectionResponse?.inputStatus?.inventoryUntilVisit = + inputInventoryUntilVisitController.text; + submitInspectionResponse?.inputStatus?.inventoryInWarehouse = + inputInventoryInWarehouseController.text; + + submitInspectionResponse?.infrastructureEnergy?.generatorType = + generatorTypeController.text; + submitInspectionResponse?.infrastructureEnergy?.generatorModel = + generatorModelController.text; + submitInspectionResponse?.infrastructureEnergy?.generatorCount = + generatorCountController.text; + submitInspectionResponse?.infrastructureEnergy?.generatorCapacity = + generatorCapacityController.text; + submitInspectionResponse?.infrastructureEnergy?.emergencyFuelInventory = + emergencyFuelInventoryController.text; + submitInspectionResponse?.infrastructureEnergy?.powerCutDuration = + powerCutDurationController.text; + submitInspectionResponse?.infrastructureEnergy?.powerCutHour = + powerCutHourController.text; + submitInspectionResponse?.infrastructureEnergy?.additionalNotes = + additionalNotesController.text; + + submitInspectionResponse?.hr?.numberEmployed = int.tryParse( + employedWorkersCountController.text.clearComma, + ); + submitInspectionResponse?.hr?.numberIndigenous = int.tryParse( + nativeWorkersCountController.text.clearComma, + ); + submitInspectionResponse?.hr?.numberNonIndigenous = int.tryParse( + nonNativeWorkersCountController.text.clearComma, + ); + + submitInspectionResponse?.inspectionNotes = + inspectorConclusionDescriptionController.text; + + await safeCall( + call: () async { + await repository.submitInspection( + token: tokenStorageService.accessToken.value ?? '', + request: submitInspectionResponse!, + ); + }, + onSuccess: (result) { + Get.back(); + + Future.delayed(Duration(seconds: 2), () { + Get.snackbar( + 'موفق', + 'بازرسی با موفقیت ثبت شد', + snackPosition: SnackPosition.TOP, + backgroundColor: Colors.green, + colorText: Colors.white, + ); + }); + }, + onError: (error, stackTrace) { + Get.snackbar( + 'خطا', + 'خطا در ثبت بازرسی: ${error.toString()}', + snackPosition: SnackPosition.TOP, + backgroundColor: Colors.red, + colorText: Colors.white, + ); + }, + showError: true, + ); + } + + void setUpPultryImagesListener() { + pultryImagesController.addListener(() { + if (pultryImagesController.capturedImages.isNotEmpty) { + WidgetsBinding.instance.addPostFrameCallback((_) { + pultryImages.assignAll(pultryImagesController.capturedImages); + }); + } + }); + } + + void setUpHallImagesListener() { + hallImagesController.addListener(() { + if (hallImagesController.capturedImages.isNotEmpty) { + WidgetsBinding.instance.addPostFrameCallback((_) { + hallImages.assignAll(hallImagesController.capturedImages); + }); + } + }); + } + + void setUpInputWarehouseImagesListener() { + inputWarehouseImagesController.addListener(() { + if (inputWarehouseImagesController.capturedImages.isNotEmpty) { + WidgetsBinding.instance.addPostFrameCallback((_) { + inputWarehouseImages.assignAll( + inputWarehouseImagesController.capturedImages, + ); + }); + } + }); + } + + void setUpLossesImagesListener() { + lossesImagesController.addListener(() { + if (lossesImagesController.capturedImages.isNotEmpty) { + WidgetsBinding.instance.addPostFrameCallback((_) { + lossesImages.assignAll(lossesImagesController.capturedImages); + }); + } + }); + } +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step1_page.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step1_page.dart new file mode 100644 index 0000000..c8883a2 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step1_page.dart @@ -0,0 +1,249 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_core/core.dart'; + +Widget step1Page(CreateInspectionBottomSheetLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 25.h), + + Container( + height: controller.tenantStatusController.text == 'دارد' + ? 605.h + : 470.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'اطلاعات پایه واحد', + child: basicUnitInformation(controller), + ), + ), + + SizedBox(height: 30.h), + + Container( + height: 280.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'اطلاعات جوجه ریزی', + child: hatchingInformation(controller), + ), + ), + SizedBox(height: 16.h), + ], + ), + ); +} + +Column basicUnitInformation(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.unitNameController, + label: 'نام واحد مرغداری', + filled: true, + filledColor: AppColor.bgLight, + readonly: true, + ), + + RTextField( + controller: controller.breedingUniqueIdController, + label: 'کد یکتا / شناسه واحد', + filled: true, + readonly: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.healthLicenseController, + label: 'پروانه بهداشتی', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.tenantStatusController, + label: 'وضعیت مستاجر', + filled: true, + filledColor: AppColor.bgLight, + ), + + Visibility( + child: controller.tenantStatusController.text == 'دارد' + ? Column( + spacing: 10, + children: [ + RTextField( + controller: controller.tenantNameController, + label: 'نام مستاجر', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.tenantNationalIdController, + label: 'کد ملی مستاجر', + filled: true, + filledColor: AppColor.bgLight, + ), + + RTextField( + controller: controller.tenantPhoneNumberController, + label: 'شماره تماس مستاجر', + filled: true, + filledColor: AppColor.bgLight, + ), + ], + ) + : SizedBox.shrink(), + ), + RTextField( + controller: controller.ownerNationalCodeController, + label: 'کد ملی بهره‌بردار', + filled: true, + readonly: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.ownerPhoneNumberController, + label: 'شماره تماس بهره‌بردار', + filled: true, + readonly: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.totalCapacityController, + label: 'ظرفیت اسمی سالن‌ها', + filled: true, + filledColor: AppColor.bgLight, + ), + + Obx( + () => RElevated( + isFullWidth: true, + height: 40.h, + enabled: !controller.isLoadingLocation.value, + + backgroundColor: AppColor.greenNormal, + onPressed: controller.isLoadingLocation.value + ? null + : () => controller.getCurrentLocation(), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + if (controller.isLoadingLocation.value) + SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation(Colors.white), + ), + ) + else + Icon(Icons.my_location_rounded, color: Colors.white, size: 24), + Text( + controller.currentLocation.value == null + ? 'دریافت موقعیت جغرافیایی' + : 'موقعیت جغرافیایی دریافت شد', + + style: AppFonts.yekan14.copyWith(color: Colors.white), + ), + ], + ), + ), + ), + + ObxValue((data) { + return Visibility( + visible: data.value != null, + child: Row( + spacing: 8, + children: [ + Icon(Icons.gps_fixed, color: AppColor.greenNormal, size: 24), + Text( + 'موقعیت جغرافیایی دریافت شد', + style: AppFonts.yekan12.copyWith(color: AppColor.greenNormal), + ), + ], + ), + ); + }, controller.currentLocation), + ], + ); +} + +Column hatchingInformation(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.hatchingDateController, + label: 'تاریخ جوجه ریزی', + filled: true, + filledColor: AppColor.bgLight, + readonly: true, + ), + + RTextField( + controller: controller.visitDateController, + label: 'تاریخ بازدید', + filled: true, + filledColor: AppColor.bgLight, + readonly: true, + ), + + RTextField( + controller: controller.hatchingCountController, + label: 'تعداد جوجه‌ریزی اولیه', + filled: true, + filledColor: AppColor.bgLight, + readonly: true, + ), + + /* ResourceOverlayDropdown( + items: Resource.success(['سرابی', 'پژدر', 'روتوایلر', 'دیگر']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نوع نژاد'), + ), */ + + /* RTextField( + controller: controller.unitNameController, + label: 'گرید جوجه', + filled: true, + filledColor: AppColor.bgLight, + readonly: true, + ), */ + RTextField( + controller: controller.hatchingBreedController, + label: 'نوع نژاد', + filled: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.hatchingAverageWeightController, + label: 'میانگین وزن جوجه', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart new file mode 100644 index 0000000..d4b1e73 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart @@ -0,0 +1,647 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'create_inspection_bottom_sheet_logic.dart'; + +Widget step2Page(CreateInspectionBottomSheetLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 35.h), + + Container( + height: 630.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'وضعیت عمومی سالن', + child: generalConditionOfTheHall(controller), + ), + ), + + SizedBox(height: 30.h), + + ObxValue((data) { + return Container( + height: data.value.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'تلفات', + child: casualtiesInformation(controller), + ), + ); + }, controller.casualtiesInformationHeight), + SizedBox(height: 24.h), + + Container( + height: 130.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'مسئول فنی ', + child: diseasesAndHealthInformation(controller), + ), + ), + ], + ), + ); +} + +Widget generalConditionOfTheHall(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox.shrink(), + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + spacing: 8, + children: [ + ObxValue((data) { + return Row( + children: data + .map( + (entry) => Stack( + children: [ + Container( + height: 80.h, + width: 80.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.file( + File(entry.path), + fit: BoxFit.cover, + ), + ), + ), + // Delete button + Positioned( + top: 4, + left: 4, + child: GestureDetector( + onTap: () => controller.removeImage( + controller.hallImages, + entry.path, + ), + child: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + child: Icon( + Icons.close, + color: Colors.white, + size: 16, + ), + ), + ), + ), + + // Upload indicator + ], + ), + ) + .toList(), + ); + }, controller.pultryImages), + + // Add image button + GestureDetector( + onTap: () async { + Get.to( + () => RImagePicker( + controller: controller.pultryImagesController, + ), + fullscreenDialog: true, + transition: Transition.fade, + duration: Duration(milliseconds: 300), + ); + }, + child: Container( + height: 80.h, + width: 80.w, + margin: EdgeInsets.only(left: 8.h), + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg( + width: 36, + height: 36, + ), + ), + ), + ], + ), + ), + + Text( + 'تعداد موجود فعلی', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت بهداشتی سالن', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + spacing: 8, + children: [ + Expanded( + child: containerChips( + selectedIndex: data.value, + index: 0, + label: 'عالی', + onTap: (index) => controller + .setSanitaryConditionOfTheHallIndex(index, 'عالی'), + ), + ), + Expanded( + child: containerChips( + selectedIndex: data.value, + index: 1, + label: 'خوب', + onTap: (index) => controller + .setSanitaryConditionOfTheHallIndex(index, 'خوب'), + ), + ), + Expanded( + child: containerChips( + selectedIndex: data.value, + index: 2, + label: 'متوسط', + onTap: (index) => controller + .setSanitaryConditionOfTheHallIndex(index, 'متوسط'), + ), + ), + Expanded( + child: containerChips( + selectedIndex: data.value, + index: 3, + label: 'ضعیف', + onTap: (index) => controller + .setSanitaryConditionOfTheHallIndex(index, 'ضعیف'), + ), + ), + ], + ); + }, controller.sanitaryConditionOfTheHallIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت تهویه', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Expanded( + child: containerChips( + onTap: (index) => + controller.setVentilationStatusIndex(index, 'عالی'), + selectedIndex: data.value, + index: 0, + label: 'عالی', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setVentilationStatusIndex(index, 'خوب'), + selectedIndex: data.value, + index: 1, + label: 'خوب', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setVentilationStatusIndex(index, 'متوسط'), + selectedIndex: data.value, + index: 2, + label: 'متوسط', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setVentilationStatusIndex(index, 'ضعیف'), + selectedIndex: data.value, + index: 3, + label: 'ضعیف', + ), + ), + ], + ); + }, controller.ventilationStatusIndex), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت بستر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + spacing: 8, + children: [ + Expanded( + child: containerChips( + onTap: (index) => + controller.setBeddingStatusIndex(index, 'خشک'), + selectedIndex: data.value, + index: 0, + label: 'خشک', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setBeddingStatusIndex(index, 'نیمه‌مرطوب'), + selectedIndex: data.value, + index: 1, + label: 'نیمه‌مرطوب', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setBeddingStatusIndex(index, 'مرطوب'), + selectedIndex: data.value, + index: 2, + label: 'مرطوب', + ), + ), + ], + ); + }, controller.beddingStatusIndex), + ], + ), + ), + + RTextField( + controller: controller.hatchingTemperatureController, + label: 'دمای سالن', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + minLines: 1, + keyboardType: TextInputType.number, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + ' آب مصرفی', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + Expanded( + child: containerChips( + onTap: (index) => + controller.setWaterQualityIndex(index, 'چاه'), + selectedIndex: data.value, + index: 0, + label: 'چاه', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setWaterQualityIndex(index, 'شهری'), + selectedIndex: data.value, + index: 1, + label: 'شهری', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setWaterQualityIndex(index, 'تصفیه‌شده'), + selectedIndex: data.value, + index: 2, + label: 'تصفیه‌شده', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setWaterQualityIndex(index, 'حمل تانکر'), + selectedIndex: data.value, + index: 3, + label: 'حمل تانکر', + ), + ), + ], + ); + }, controller.waterQualityIndex), + ], + ), + ), + RTextField( + controller: controller.waterHardnessController, + label: 'درصد سختی آب (PPM)', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + minLines: 1, + keyboardType: TextInputType.numberWithOptions(decimal: true), + ), + ], + ); +} + +ChoiceChip formChips({ + required int selectedIndex, + required int index, + required String label, + required Function(int) onTap, +}) { + return ChoiceChip( + selectedColor: AppColor.green1Normal, + labelStyle: index == selectedIndex + ? AppFonts.yekan14Bold.copyWith(color: Colors.white) + : AppFonts.yekan14.copyWith(color: AppColor.textColor), + surfaceTintColor: Colors.white, + checkmarkColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: index == selectedIndex + ? BorderSide.none + : BorderSide(width: 1, color: AppColor.blackLightHover), + ), + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6), + + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + label: Text(label), + selected: index == selectedIndex, + onSelected: (value) => onTap(index), + ); +} + +Column casualtiesInformation(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.normalLossesController, + label: 'تعداد تلفات عادی دوره', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + maxLines: 1, + minLines: 1, + ), + + RTextField( + controller: controller.abnormalLossesController, + label: 'تلفات غیرعادی', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + maxLines: 1, + minLines: 1, + ), + + ResourceOverlayDropdown( + items: controller.causeOfUnusualCasualtiesList, + onChanged: (item) => controller.setCauseOfUnusualCasualtiesIndex(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'علت تلفات غیرعادی'), + ), + + ObxValue((data) { + return Visibility( + visible: data.value, + child: RTextField( + controller: controller.otherCauseOfUnusualCasualtiesController, + label: 'علت تلفات غیرعادی', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + minLines: 1, + ), + ); + }, controller.isOthercauseOfUnusualCasualties), + + ResourceOverlayDropdown( + items: controller.typeOfDiseaseList, + onChanged: (item) => controller.setTypeOfDiseaseIndex(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => + Text(selected ?? 'نوع بیماری تشخیص داده‌شده / مشکوک'), + ), + + ObxValue((data) { + return Visibility( + visible: data.value, + child: RTextField( + controller: controller.otherTypeOfDiseaseController, + label: 'نوع بیماری', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + minLines: 1, + ), + ); + }, controller.isOtherTypeOfDiseaseSelected), + + ResourceOverlayDropdown( + items: Resource.success(['انجام شد', 'انجام نشد']), + onChanged: (item) => controller.setSamplingDone(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نمونه‌برداری انجام‌شده'), + ), + + ObxValue((data) { + return Visibility( + visible: data.value, + child: cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'نوع نمونه', + style: AppFonts.yekan14Bold.copyWith( + color: AppColor.textColor2, + ), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Expanded( + child: containerChips( + onTap: (index) => + controller.setSampleTypeIndex(index, 'لاشه'), + selectedIndex: data.value, + index: 0, + label: 'لاشه', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setSampleTypeIndex(index, 'آب'), + selectedIndex: data.value, + index: 1, + label: 'آب', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setSampleTypeIndex(index, 'دانه'), + selectedIndex: data.value, + index: 2, + label: 'دانه', + ), + ), + ], + ); + }, controller.sampleTypeIndex), + ], + ), + ), + ); + }, controller.samplingDone), + ], + ); +} + +Column diseasesAndHealthInformation( + CreateInspectionBottomSheetLogic controller, +) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.technicalHealthOfficerNameController, + label: 'نام مسئول فنی بهداشتی', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + ), + + RTextField( + controller: controller.technicalEngineeringOfficerNameController, + label: 'نام مسئول فنی نظام مهندسی', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + ), + ], + ); +} + +GestureDetector containerChips({ + required int selectedIndex, + required int index, + required String label, + required Function(int) onTap, +}) { + return GestureDetector( + onTap: () => onTap(index), + child: Container( + height: 24.h, + decoration: BoxDecoration( + color: index == selectedIndex + ? AppColor.green1Normal + : AppColor.whiteGreyNormal, + borderRadius: BorderRadius.circular(8), + border: index == selectedIndex + ? Border.fromBorderSide(BorderSide.none) + : Border.all(width: 1, color: AppColor.blackLightHover), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 5, + children: [ + if (index == selectedIndex) + Icon(Icons.check, color: Colors.white, size: 16), + Text( + label, + style: index == selectedIndex + ? AppFonts.yekan14Bold.copyWith(color: Colors.white) + : AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + ); +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step3_page.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step3_page.dart new file mode 100644 index 0000000..762e3ea --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step3_page.dart @@ -0,0 +1,516 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'create_inspection_bottom_sheet_logic.dart'; + +Widget step3Page(CreateInspectionBottomSheetLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 35.h), + + Container( + height: 370.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'نهاده و خوراک', + child: agriculturalInput(controller), + ), + ), + + SizedBox(height: 30.h), + + Container( + height: 625.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'زیرساخت و انرژی', + child: infrastructureAndEnergy(controller), + ), + ), + SizedBox(height: 24.h), + + Container( + height: 320.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'نیروی انسانی', + child: humanResources(controller), + ), + ), + SizedBox(height: 24.h), + + Container( + height: 335.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'تسهیلات و حمایت‌ها', + child: facilitiesAndSupport(controller), + ), + ), + SizedBox(height: 24.h), + ], + ), + ); +} + +Column infrastructureAndEnergy(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + RTextField( + controller: controller.generatorTypeController, + label: 'نوع ژنراتور', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + ), + RTextField( + controller: controller.generatorModelController, + label: 'مدل ژنراتور', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + ), + RTextField( + controller: controller.generatorCountController, + label: 'تعداد ژنراتور', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + keyboardType: TextInputType.number, + ), + + ResourceOverlayDropdown( + items: Resource.success(['گازوئیل', 'نفت گاز']), + + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نوع سوخت'), + onChanged: (item) => controller.setFuelType(item), + ), + + RTextField( + controller: controller.generatorCapacityController, + label: 'ظرفیت (KVA)', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت عملکرد ژنراتور', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + Expanded( + child: containerChips( + onTap: (index) => controller + .setGeneratorOperatingStatusIndex(index, 'سالم'), + selectedIndex: data.value, + index: 0, + label: 'سالم', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => controller + .setGeneratorOperatingStatusIndex(index, 'نیمه‌سالم'), + selectedIndex: data.value, + index: 1, + label: 'نیمه‌سالم', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => controller + .setGeneratorOperatingStatusIndex(index, 'معیوب'), + selectedIndex: data.value, + index: 2, + label: 'معیوب', + ), + ), + ], + ); + }, controller.generatorOperatingStatusIndex), + ], + ), + ), + + RTextField( + controller: controller.emergencyFuelInventoryController, + label: 'میزان موجودی سوخت اضطراری (لیتر)', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + ResourceOverlayDropdown( + items: Resource.success(['ندارد', 'دارد']), + onChanged: (item) => controller.setPowerCutHistory(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => + Text(selected ?? 'سابقه قطعی برق دوره جاری'), + ), + + RTextField( + controller: controller.powerCutDurationController, + label: 'مدت قطعی', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + RTextField( + controller: controller.powerCutHourController, + label: 'ساعت قطعی', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + RTextField( + controller: controller.additionalNotesController, + label: 'توضیحات تکمیلی', + filled: true, + maxLines: 5, + minLines: 5, + filledColor: AppColor.bgLight, + ), + ], + ); +} + +Column agriculturalInput(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox.shrink(), + + ResourceOverlayDropdown( + items: controller.inputStatusList, + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'وضعیت نهاده'), + onChanged: (item) => controller.setInputStatus(item), + ), + + ObxValue((data) { + if (data.value == 'وابسته') { + return RTextField( + controller: controller.companyNameController, + label: 'نام کارخانه', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + ); + } else { + return RTextField( + controller: controller.trackingCodeController, + label: 'شناسه خرید یا کد پیگیری', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + ); + } + }, controller.inputStatus), + + RTextField( + controller: controller.inputInventoryUntilVisitController, + label: 'موجودی نهاده مصرفی تا روز بازدید (کیلوگرم)', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + ResourceOverlayDropdown( + items: controller.typeOfGrainList, + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'نوع دان'), + onChanged: (item) => controller.setTypeOfGrain(item), + ), + + RTextField( + controller: controller.inputInventoryInWarehouseController, + label: 'موجودی نهاده موجود در انبار (کیلوگرم)', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'کیفیت دانه', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 10, + children: [ + Expanded( + child: containerChips( + onTap: (index) => + controller.setGrainQualityInput(index, 'متوسط'), + selectedIndex: data.value, + index: 0, + label: 'خوب', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setGrainQualityInput(index, 'خوب'), + selectedIndex: data.value, + index: 1, + label: 'متوسط', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => + controller.setGrainQualityInput(index, 'ضعیف'), + selectedIndex: data.value, + index: 2, + label: 'ضعیف', + ), + ), + ], + ); + }, controller.grainQualityInputIndex), + ], + ), + ), + ], + ); +} + +Column humanResources(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + RTextField( + controller: controller.employedWorkersCountController, + label: 'تعداد افراد شاغل', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + RTextField( + controller: controller.nativeWorkersCountController, + label: 'تعداد افراد بومی', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + RTextField( + controller: controller.nonNativeWorkersCountController, + label: 'تعداد افراد غیر بومی', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت قرارداد کارگران', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Expanded( + child: containerChips( + onTap: (index) => controller.setWorkerContractStatusIndex( + index, + 'دائم', + ), + selectedIndex: data.value, + index: 0, + label: 'دائم', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => controller.setWorkerContractStatusIndex( + index, + 'موقت', + ), + selectedIndex: data.value, + index: 1, + label: 'موقت', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => controller.setWorkerContractStatusIndex( + index, + 'روزمزدی', + ), + selectedIndex: data.value, + index: 2, + label: 'روزمزدی', + ), + ), + ], + ); + }, controller.workerContractStatusIndex), + ], + ), + ), + + ResourceOverlayDropdown( + items: Resource.success(['بله', 'خیر']), + onChanged: (item) => controller.setTrainingStatus(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => + Text(selected ?? 'آموزش‌دیده در حوزه بهداشت و امنیت زیستی'), + ), + ], + ); +} + +Column facilitiesAndSupport(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + ResourceOverlayDropdown( + items: Resource.success(['دارد', 'ندارد']), + onChanged: (item) => controller.setHasFacilities(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? ' تسهیلات دریافتی فعال'), + ), + + RTextField( + controller: controller.facilityTypeController, + label: 'نوع تسهیلات', + filled: true, + filledColor: AppColor.bgLight, + maxLines: 1, + ), + + RTextField( + controller: controller.facilityAmountController, + label: 'مبلغ', + filled: true, + filledColor: AppColor.bgLight, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + maxLines: 1, + ), + RTextField( + controller: controller.paymentYearController, + label: 'سال دریافت', + filled: true, + readonly: true, + onTap: () => controller.showPaymentYearDatePicker(), + filledColor: AppColor.bgLight, + maxLines: 1, + ), + + ResourceOverlayDropdown( + items: Resource.success(['دارای معوقه', 'منظم']), + onChanged: (item) => controller.setOverdueStatus(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'وضعیت بازپرداخت'), + ), + + ResourceOverlayDropdown( + items: Resource.success(['نهاده', 'تسهیلات', 'واکسن', 'تجهیزات']), + onChanged: (item) => controller.setNewBeneficiaryRequest(item), + itemBuilder: (item) => Text(item), + labelBuilder: (selected) => Text(selected ?? 'درخواست جدید بهره بردار'), + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step4_page.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step4_page.dart new file mode 100644 index 0000000..c038e59 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step4_page.dart @@ -0,0 +1,450 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/card_info.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step2_page.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'create_inspection_bottom_sheet_logic.dart'; + +Widget step4Page(CreateInspectionBottomSheetLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(height: 35.h), + + Container( + height: 455.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'مستندات', + child: documents(controller), + ), + ), + + SizedBox(height: 30.h), + + Container( + height: 235.h, + clipBehavior: Clip.none, + width: Get.width, + child: farmInfoWidget( + controller: controller, + title: 'جمع‌بندی بازرس', + child: inspectorConclusion(controller), + ), + ), + SizedBox(height: 24.h), + ], + ), + ); +} + +Column documents(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + SizedBox(height: 10.h), + Obx( + () => SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + spacing: 8, + children: [ + ...controller.hallImages.map( + (entry) => Stack( + children: [ + Container( + height: 80.h, + width: 80.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.file( + File(entry.path), + fit: BoxFit.cover, + ), + ), + ), + // Delete button + Positioned( + top: 4, + left: 4, + child: GestureDetector( + onTap: () => controller.removeImage( + controller.hallImages, + entry.path, + ), + child: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + child: Icon( + Icons.close, + color: Colors.white, + size: 16, + ), + ), + ), + ), + + // Upload indicator + ], + ), + ), + // Add image button + GestureDetector( + onTap: () => Get.to( + () => RImagePicker( + controller: controller.hallImagesController, + ), + fullscreenDialog: true, + transition: Transition.fade, + duration: Duration(milliseconds: 300), + ), + + child: Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg( + width: 36, + height: 36, + ), + ), + ), + ], + ), + ), + ), + + RichText( + text: TextSpan( + children: [ + TextSpan( + text: 'ثبت عکس سالن (حداقل ۳ زاویه) ', + style: AppFonts.yekan14.copyWith( + color: AppColor.textColorLight, + ), + ), + TextSpan( + text: '*', + style: AppFonts.yekan14.copyWith(color: Colors.red), + ), + ], + ), + ), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Obx( + () => SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + spacing: 8, + children: [ + ...controller.inputWarehouseImages.map( + (entry) => Stack( + children: [ + Container( + height: 80.h, + width: 80.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.file( + File(entry.path), + fit: BoxFit.cover, + ), + ), + ), + // Delete button + Positioned( + top: 4, + left: 4, + child: GestureDetector( + onTap: () => controller.removeImage( + controller.inputWarehouseImages, + entry.path, + ), + child: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + child: Icon( + Icons.close, + color: Colors.white, + size: 16, + ), + ), + ), + ), + ], + ), + ), + // Add image button + GestureDetector( + onTap: () => Get.to( + () => RImagePicker( + controller: controller.inputWarehouseImagesController, + ), + fullscreenDialog: true, + transition: Transition.fade, + duration: Duration(milliseconds: 300), + ), + child: Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg( + width: 36, + height: 36, + ), + ), + ), + ], + ), + ), + ), + + Text( + 'ثبت عکس انبار نهاده‌ها', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ], + ), + ), + + cardInfo( + padding: EdgeInsets.fromLTRB(0, 12, 12, 6), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Obx( + () => SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + spacing: 8, + children: [ + ...controller.lossesImages.map( + (entry) => Stack( + children: [ + Container( + height: 80.h, + width: 80.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Image.file( + File(entry.path), + fit: BoxFit.cover, + ), + ), + ), + // Delete button + Positioned( + top: 4, + left: 4, + child: GestureDetector( + onTap: () => controller.removeImage( + controller.lossesImages, + entry.path, + ), + child: Container( + width: 24, + height: 24, + decoration: BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + child: Icon( + Icons.close, + color: Colors.white, + size: 16, + ), + ), + ), + ), + ], + ), + ), + // Add image button + GestureDetector( + onTap: () => Get.to( + () => RImagePicker( + controller: controller.lossesImagesController, + ), + fullscreenDialog: true, + transition: Transition.fade, + duration: Duration(milliseconds: 300), + ), + child: Container( + height: 80.h, + width: 80.w, + padding: EdgeInsets.all(22), + decoration: BoxDecoration( + color: Color(0xFFE9E9E9), + border: Border.all( + width: 1, + color: AppColor.blackLightHover, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.galleryAddSvg.svg( + width: 36, + height: 36, + ), + ), + ), + ], + ), + ), + ), + + Text( + 'ثبت عکس تلفات', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ], + ), + ), + ], + ); +} + +Column inspectorConclusion(CreateInspectionBottomSheetLogic controller) { + return Column( + spacing: 10, + children: [ + SizedBox(height: 1.h), + + cardInfo( + padding: EdgeInsets.fromLTRB(12, 12, 12, 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 9, + children: [ + Text( + 'وضعیت کلی واحد', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor2), + ), + + ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Expanded( + child: containerChips( + onTap: (index) => controller.setInspectorConclusionIndex( + index, + 'تایید شده', + ), + selectedIndex: data.value, + index: 0, + label: 'تایید شده', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => controller.setInspectorConclusionIndex( + index, + 'نیازمند اصلاح', + ), + selectedIndex: data.value, + index: 1, + label: 'نیازمند اصلاح', + ), + ), + Expanded( + child: containerChips( + onTap: (index) => controller.setInspectorConclusionIndex( + index, + 'پرریسک', + ), + selectedIndex: data.value, + index: 2, + label: 'پرریسک', + ), + ), + ], + ); + }, controller.inspectorConclusionIndex), + ], + ), + ), + + RTextField( + height: 100.h, + controller: controller.inspectorConclusionDescriptionController, + hintText: 'توصیه‌ها / اخطارها / اقدامات اصلاحی ...', + hintStyle: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + maxLines: 5, + minLines: 5, + filled: true, + filledColor: AppColor.bgLight, + ), + ], + ); +} diff --git a/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step5_page.dart b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step5_page.dart new file mode 100644 index 0000000..4bc8be2 --- /dev/null +++ b/packages/chicken/lib/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/step5_page.dart @@ -0,0 +1,898 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_core/core.dart'; + +Widget step5Page(CreateInspectionBottomSheetLogic controller) { + return SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: detailsWidget(controller), + ); +} + +Widget detailsWidget(CreateInspectionBottomSheetLogic controller) { + return Column( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ObxValue((data) { + return tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + controller.selectedTabIndex.value, + (index) => controller.changeTab(index), + ); + }, controller.selectedTabIndex), + ObxValue((data) { + switch (data.value) { + case 0: + return generalInfoTable(controller); + case 1: + return generalConditionHallTable(controller); + case 2: + return casualtiesTable(controller); + case 3: + return technicalOfficerTable(controller); + case 4: + return inputStatusTable(controller); + case 5: + return infrastructureEnergyTable(controller); + case 6: + return hrTable(controller); + case 7: + return facilitiesTable(controller); + default: + return generalInfoTable(controller); + } + }, controller.selectedTabIndex), + ], + ), + ], + ); +} + +Widget generalInfoTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نام واحد مرغداری', + value: controller.unitNameController.text, + ), + rTableRow( + title: 'کد یکتا / شناسه واحد', + value: controller.breedingUniqueIdController.text, + ), + rTableRow( + title: 'پروانه بهداشتی', + value: controller.healthLicenseController.text, + ), + rTableRow( + title: 'وضعیت مستاجر', + value: controller.tenantStatusController.text, + ), + if (controller.hatchingModel?.poultry?.hasTenant == true) ...[ + rTableRow( + title: 'نام مستاجر', + value: controller.tenantNameController.text, + ), + rTableRow( + title: 'کد ملی مستاجر', + value: controller.tenantNationalIdController.text, + ), + rTableRow( + title: 'شماره تماس مستاجر', + value: controller.tenantPhoneNumberController.text, + ), + ], + rTableRow( + title: 'نام مالک', + value: controller.ownerNameController.text, + ), + rTableRow( + title: 'کد ملی مالک', + value: controller.ownerNationalCodeController.text, + ), + rTableRow( + title: 'شماره تماس مالک', + value: controller.ownerPhoneNumberController.text, + ), + rTableRow( + title: 'ظرفیت اسمی', + value: controller.totalCapacityController.text, + ), + rTableRow( + title: 'تاریخ جوجه‌ریزی', + value: controller.hatchingDateController.text, + ), + rTableRow( + title: 'تاریخ بازدید', + value: controller.visitDateController.text, + ), + rTableRow( + title: 'تعداد جوجه‌ریزی', + value: controller.hatchingCountController.text, + ), + rTableRow( + title: 'نژاد', + value: controller.hatchingBreedController.text, + ), + if (controller.currentLocation.value != null) + rTableRow( + title: 'موقعیت مکانی', + value: + '${controller.currentLocation.value!.latitude.toStringAsFixed(6)}, ${controller.currentLocation.value!.longitude.toStringAsFixed(6)}', + ), + rTableRow( + title: 'وضعیت بازرسی', + value: controller.inspectorConclusion.value ?? '-', + ), + if (controller + .inspectorConclusionDescriptionController + .text + .isNotEmpty) + rTableRow( + title: 'یادداشت بازرسی', + value: controller.inspectorConclusionDescriptionController.text, + ), + ], + ), + ), + ], + ); +} + +Widget generalConditionHallTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت سلامت', + value: controller.sanitaryConditionOfTheHall.value ?? '-', + ), + rTableRow( + title: 'وضعیت تهویه', + value: controller.ventilationStatus.value ?? '-', + ), + rTableRow( + title: 'وضعیت بستر', + value: controller.beddingStatus.value ?? '-', + ), + rTableRow( + title: 'دما', + value: controller.hatchingTemperatureController.text.isNotEmpty + ? controller.hatchingTemperatureController.text + : '-', + ), + rTableRow( + title: 'منبع آب آشامیدنی', + value: controller.waterQuality.value ?? '-', + ), + rTableRow( + title: 'سختی آب', + value: controller.waterHardnessController.text.isNotEmpty + ? controller.waterHardnessController.text + : '-', + ), + ], + ), + ), + Obx(() { + if (controller.hallImages.isEmpty) return SizedBox.shrink(); + return Column( + children: [ + SizedBox(height: 16), + Row( + children: [ + Text( + 'تصاویر سالن', + style: AppFonts.yekan14Bold.copyWith( + color: AppColor.textColor, + ), + ), + ], + ), + SizedBox(height: 10), + _buildLocalImagesList(controller.hallImages), + ], + ); + }), + ], + ); +} + +Widget casualtiesTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'تلفات عادی', + value: controller.normalLossesController.text.isNotEmpty + ? controller.normalLossesController.text + : '-', + ), + rTableRow( + title: 'تلفات غیرعادی', + value: controller.abnormalLossesController.text.isNotEmpty + ? controller.abnormalLossesController.text + : '-', + ), + rTableRow( + title: 'منبع جوجه‌ریزی', + value: controller.sourceOfHatchingController.text.isNotEmpty + ? controller.sourceOfHatchingController.text + : '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: controller.isOthercauseOfUnusualCasualties.value + ? controller.otherCauseOfUnusualCasualtiesController.text + : (controller.causeOfUnusualCasualties.value ?? '-'), + ), + rTableRow( + title: 'نوع بیماری', + value: controller.isOtherTypeOfDiseaseSelected.value + ? controller.otherTypeOfDiseaseController.text + : (controller.typeOfDisease.value ?? '-'), + ), + rTableRow( + title: 'نمونه‌برداری', + value: controller.samplingDone.value ? 'انجام شده' : 'انجام نشده', + ), + if (controller.samplingDone.value) + rTableRow( + title: 'نوع نمونه‌برداری', + value: controller.sampleType.value ?? '-', + ), + ], + ), + ), + Obx(() { + if (controller.lossesImages.isEmpty) return SizedBox.shrink(); + return Column( + children: [ + SizedBox(height: 16), + Row( + children: [ + Text( + 'تصاویر تلفات', + style: AppFonts.yekan14Bold.copyWith( + color: AppColor.textColor, + ), + ), + ], + ), + SizedBox(height: 10), + _buildLocalImagesList(controller.lossesImages), + ], + ); + }), + ], + ); +} + +Widget technicalOfficerTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: + controller + .technicalHealthOfficerNameController + .text + .isNotEmpty + ? controller.technicalHealthOfficerNameController.text + : '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: + controller + .technicalEngineeringOfficerNameController + .text + .isNotEmpty + ? controller.technicalEngineeringOfficerNameController.text + : '-', + ), + ], + ), + ), + ], + ); +} + +Widget inputStatusTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: controller.inputStatus.value ?? '-', + ), + if (controller.inputStatus.value == 'وابسته') + rTableRow( + title: 'نام شرکت', + value: controller.companyNameController.text.isNotEmpty + ? controller.companyNameController.text + : '-', + ) + else + rTableRow( + title: 'کد پیگیری', + value: controller.trackingCodeController.text.isNotEmpty + ? controller.trackingCodeController.text + : '-', + ), + rTableRow( + title: 'نوع دانه', + value: controller.typeOfGrain.value ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: + controller.inputInventoryInWarehouseController.text.isNotEmpty + ? controller.inputInventoryInWarehouseController.text + : '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: + controller.inputInventoryUntilVisitController.text.isNotEmpty + ? controller.inputInventoryUntilVisitController.text + : '-', + ), + rTableRow( + title: 'درجه دانه', + value: controller.grainQualityInput.value ?? '-', + ), + ], + ), + ), + Obx(() { + if (controller.inputWarehouseImages.isEmpty) return SizedBox.shrink(); + return Column( + children: [ + SizedBox(height: 16), + Row( + children: [ + Text( + 'تصاویر انبار نهاده', + style: AppFonts.yekan14Bold.copyWith( + color: AppColor.textColor, + ), + ), + ], + ), + SizedBox(height: 10), + _buildLocalImagesList(controller.inputWarehouseImages), + ], + ); + }), + ], + ); +} + +Widget infrastructureEnergyTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: controller.generatorTypeController.text.isNotEmpty + ? controller.generatorTypeController.text + : '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: controller.generatorModelController.text.isNotEmpty + ? controller.generatorModelController.text + : '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: controller.generatorCountController.text.isNotEmpty + ? controller.generatorCountController.text + : '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: controller.generatorCapacityController.text.isNotEmpty + ? controller.generatorCapacityController.text + : '-', + ), + rTableRow( + title: 'نوع سوخت', + value: controller.fuelType.value ?? '-', + ), + rTableRow( + title: 'عملکرد ژنراتور', + value: controller.generatorOperatingStatus.value ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: controller.emergencyFuelInventoryController.text.isNotEmpty + ? controller.emergencyFuelInventoryController.text + : '-', + ), + rTableRow( + title: 'سابقه قطع برق', + value: controller.powerCutHistory.value ? 'دارد' : 'ندارد', + ), + if (controller.powerCutHistory.value) ...[ + rTableRow( + title: 'مدت قطع برق', + value: controller.powerCutDurationController.text.isNotEmpty + ? controller.powerCutDurationController.text + : '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: controller.powerCutHourController.text.isNotEmpty + ? controller.powerCutHourController.text + : '-', + ), + ], + if (controller.additionalNotesController.text.isNotEmpty) + rTableRow( + title: 'یادداشت اضافی', + value: controller.additionalNotesController.text, + ), + ], + ), + ), + ], + ); +} + +Widget hrTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'تعداد شاغلین', + value: controller.employedWorkersCountController.text.isNotEmpty + ? controller.employedWorkersCountController.text + : '-', + ), + rTableRow( + title: 'تعداد بومی', + value: controller.nativeWorkersCountController.text.isNotEmpty + ? controller.nativeWorkersCountController.text + : '-', + ), + rTableRow( + title: 'تعداد غیربومی', + value: controller.nonNativeWorkersCountController.text.isNotEmpty + ? controller.nonNativeWorkersCountController.text + : '-', + ), + rTableRow( + title: 'وضعیت قرارداد', + value: controller.workerContractStatus.value ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: controller.trainingStatus.value ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); +} + +Widget facilitiesTable(CreateInspectionBottomSheetLogic controller) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: controller.hasFacilities.value ? 'بله' : 'خیر', + ), + if (controller.hasFacilities.value) ...[ + rTableRow( + title: 'نوع تسهیلات', + value: controller.facilityTypeController.text.isNotEmpty + ? controller.facilityTypeController.text + : '-', + ), + rTableRow( + title: 'مبلغ', + value: controller.facilityAmountController.text.isNotEmpty + ? controller.facilityAmountController.text + : '-', + ), + rTableRow( + title: 'تاریخ', + value: controller.facilityYearController.text.isNotEmpty + ? controller.facilityYearController.text + : '-', + ), + rTableRow( + title: 'وضعیت بازپرداخت', + value: controller.overdueStatus.value + ? 'دارای معوقه' + : 'بدون معوقه', + ), + ], + rTableRow( + title: 'درخواست تسهیلات', + value: controller.newBeneficiaryRequest.value ?? '-', + ), + ], + ), + ), + ], + ); +} + +Widget _buildLocalImagesList(RxList images) { + return SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: images.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => _showLocalImageDialog(images, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: FileImage(File(images[index].path)), + ), + ), + ), + ), + ), + ); +} + +void _showLocalImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.file( + File(images[index].path), + fit: BoxFit.contain, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); +} + +Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); +} + +Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, +) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 11), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); +} diff --git a/packages/chicken/lib/features/poultry_science/root/logic.dart b/packages/chicken/lib/features/poultry_science/root/logic.dart index 84d39b6..2742ba3 100644 --- a/packages/chicken/lib/features/poultry_science/root/logic.dart +++ b/packages/chicken/lib/features/poultry_science/root/logic.dart @@ -1,11 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:rasadyar_chicken/data/di/chicken_di.dart'; -import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository.dart'; -import 'package:rasadyar_chicken/features/common/profile/view.dart'; -import 'package:rasadyar_chicken/features/poultry_science/home/view.dart'; += +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; import 'package:rasadyar_chicken/presentation/routes/pages.dart'; -import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -24,13 +25,13 @@ class PoultryScienceRootLogic extends GetxController { RxInt currentPage = 1.obs; final pages = [ - Navigator( - key: Get.nestedKey(poultryFirstKey), + Navigator( + key: Get.nestedKey(poultryScienceActionKey), onGenerateRoute: (settings) { final page = ChickenPages.pages.firstWhere( (e) => e.name == settings.name, orElse: () => ChickenPages.pages.firstWhere( - (e) => e.name == ChickenRoutes.actionPoultryScience, + (e) => e.name == PoultryScienceRoutes.actionPoultryScience, ), ); @@ -39,8 +40,6 @@ class PoultryScienceRootLogic extends GetxController { ), PoultryScienceHomePage(), ProfilePage(), - - ]; @override @@ -49,7 +48,6 @@ class PoultryScienceRootLogic extends GetxController { poultryRepository = diChicken.get(); } - void toggleExpanded(int index) { if (homeExpandedList.keys.contains(index)) { homeExpandedList.remove(index); @@ -81,7 +79,7 @@ class PoultryScienceRootLogic extends GetxController { } } - void popBackTaped() async{ + void popBackTaped() async { final nestedKeyId = getNestedKey(); GlobalKey? currentNestedKey = Get.nestedKey(nestedKeyId); diff --git a/packages/chicken/lib/features/poultry_science/root/view.dart b/packages/chicken/lib/features/poultry_science/root/view.dart index 01ca6c8..05bb7ee 100644 --- a/packages/chicken/lib/features/poultry_science/root/view.dart +++ b/packages/chicken/lib/features/poultry_science/root/view.dart @@ -30,11 +30,9 @@ class PoultryScienceRootPage extends GetView { isSelected: controller.currentPage.value == 0, onTap: () { Get.nestedKey( - poultrySecondKey, - )?.currentState?.popUntil((route) => route.isFirst); - Get.nestedKey( - poultryFirstKey, + poultryScienceActionKey, )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); }, ), @@ -44,11 +42,9 @@ class PoultryScienceRootPage extends GetView { isSelected: controller.currentPage.value == 1, onTap: () { Get.nestedKey( - poultryFirstKey, - )?.currentState?.popUntil((route) => route.isFirst); - Get.nestedKey( - poultryThirdKey, + poultryScienceActionKey, )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); }, ), @@ -58,11 +54,9 @@ class PoultryScienceRootPage extends GetView { isSelected: controller.currentPage.value == 2, onTap: () { Get.nestedKey( - poultryFirstKey, - )?.currentState?.popUntil((route) => route.isFirst); - Get.nestedKey( - poultrySecondKey, + poultryScienceActionKey, )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(2); }, ), diff --git a/packages/chicken/lib/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source.dart b/packages/chicken/lib/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source.dart new file mode 100644 index 0000000..6577584 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class ProvinceInspectorRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source_impl.dart b/packages/chicken/lib/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source_impl.dart new file mode 100644 index 0000000..e07a69e --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source_impl.dart @@ -0,0 +1,40 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceInspectorRemoteDataSourceImpl + implements ProvinceInspectorRemoteDataSource { + final DioRemote _httpClient; + + ProvinceInspectorRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} diff --git a/packages/chicken/lib/features/province_inspector/data/di/province_inspector_di.dart b/packages/chicken/lib/features/province_inspector/data/di/province_inspector_di.dart new file mode 100644 index 0000000..e7e332d --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/data/di/province_inspector_di.dart @@ -0,0 +1,36 @@ +import 'package:rasadyar_chicken/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/repositories/province_inspector_repository.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/repositories/province_inspector_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for province_inspector feature +Future setupProvinceInspectorDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => ProvinceInspectorRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => ProvinceInspectorRepositoryImpl(di.get()), + ); +} + +/// Re-register province_inspector dependencies (used when base URL changes) +Future reRegisterProvinceInspectorDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => ProvinceInspectorRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => ProvinceInspectorRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/province_inspector/data/repositories/province_inspector_repository.dart b/packages/chicken/lib/features/province_inspector/data/repositories/province_inspector_repository.dart new file mode 100644 index 0000000..2c68b3d --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/data/repositories/province_inspector_repository.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class ProvinceInspectorRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/province_inspector/data/repositories/province_inspector_repository_impl.dart b/packages/chicken/lib/features/province_inspector/data/repositories/province_inspector_repository_impl.dart new file mode 100644 index 0000000..98b23e4 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/data/repositories/province_inspector_repository_impl.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/datasources/remote/province_inspector_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/repositories/province_inspector_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceInspectorRepositoryImpl implements ProvinceInspectorRepository { + final ProvinceInspectorRemoteDataSource _remote; + + ProvinceInspectorRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..0a014aa --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,95 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + ProvinceInspectorRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'ProvinceInspector', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..4fa0611 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/active_hatching/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: provinceInspectorActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart new file mode 100644 index 0000000..5400e75 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/home/logic.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/province_inspector/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceInspectorActionItem { + final String title; + final String route; + final String icon; + + ProvinceInspectorActionItem({ + required this.title, + required this.route, + required this.icon, + }); +} + +class ProvinceInspectorHomeLogic extends GetxController { + RxList items = [ + ProvinceInspectorActionItem( + title: "جوجه ریزی فعال", + route: ProvinceInspectorRoutes.activeHatchingProvinceInspector, + icon: Assets.vec.activeFramSvg.path, + ), + ProvinceInspectorActionItem( + title: "بازرسی مزارع طیور", + route: ProvinceInspectorRoutes.newInspectionProvinceInspector, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/home/view.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/home/view.dart new file mode 100644 index 0000000..39eaaad --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/home/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class ProvinceInspectorHomePage extends GetView { + ProvinceInspectorHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: provinceInspectorActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..92f10c5 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + ProvinceInspectorRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.provinceInspectorRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'ProvinceInspector', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..38ee5ff --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: provinceInspectorActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/root/logic.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/root/logic.dart new file mode 100644 index 0000000..48419f1 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/root/logic.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/province_inspector/data/repositories/province_inspector_repository.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class ProvinceInspectorRootLogic extends GetxController { + var tokenService = Get.find(); + + late ProvinceInspectorRepository provinceInspectorRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(provinceInspectorActionKey), + onGenerateRoute: (settings) { + final page = ProvinceInspectorPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => ProvinceInspectorPages.pages.firstWhere( + (e) => e.name == ProvinceInspectorRoutes.homeProvinceInspector, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + provinceInspectorRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/pages/root/view.dart b/packages/chicken/lib/features/province_inspector/presentation/pages/root/view.dart new file mode 100644 index 0000000..2cf1265 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/pages/root/view.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class ProvinceInspectorRootPage extends GetView { + const ProvinceInspectorRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + provinceInspectorActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + provinceInspectorActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/routes/pages.dart b/packages/chicken/lib/features/province_inspector/presentation/routes/pages.dart new file mode 100644 index 0000000..c0ee230 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/routes/pages.dart @@ -0,0 +1,65 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/province_inspector/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceInspectorPages { + ProvinceInspectorPages._(); + + static List get pages => [ + GetPage( + name: ProvinceInspectorRoutes.initProvinceInspector, + page: () => ProvinceInspectorRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => ProvinceInspectorRootLogic()); + Get.lazyPut(() => ProvinceInspectorHomeLogic()); + }), + ], + ), + GetPage( + name: ProvinceInspectorRoutes.homeProvinceInspector, + page: () => ProvinceInspectorHomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(ProvinceInspectorHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + GetPage( + name: ProvinceInspectorRoutes.activeHatchingProvinceInspector, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: ProvinceInspectorRoutes.newInspectionProvinceInspector, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/province_inspector/presentation/routes/routes.dart b/packages/chicken/lib/features/province_inspector/presentation/routes/routes.dart new file mode 100644 index 0000000..02aae60 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/presentation/routes/routes.dart @@ -0,0 +1,10 @@ +sealed class ProvinceInspectorRoutes { + ProvinceInspectorRoutes._(); + + static const _base = '/chicken/provinceInspector'; + static const initProvinceInspector = '$_base/'; + static const homeProvinceInspector = '$_base/home'; + static const actionProvinceInspector = '$_base/action'; + static const activeHatchingProvinceInspector = '$_base/activeHatching'; + static const newInspectionProvinceInspector = '$_base/newInspection'; +} diff --git a/packages/chicken/lib/features/province_inspector/province_inspector.dart b/packages/chicken/lib/features/province_inspector/province_inspector.dart new file mode 100644 index 0000000..7f103b9 --- /dev/null +++ b/packages/chicken/lib/features/province_inspector/province_inspector.dart @@ -0,0 +1,3 @@ +export 'data/di/province_inspector_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/province_operator/data/datasources/remote/province_operator_remote_data_source.dart b/packages/chicken/lib/features/province_operator/data/datasources/remote/province_operator_remote_data_source.dart new file mode 100644 index 0000000..99b5d81 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/data/datasources/remote/province_operator_remote_data_source.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class ProvinceOperatorRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/province_operator/data/datasources/remote/province_operator_remote_data_source_impl.dart b/packages/chicken/lib/features/province_operator/data/datasources/remote/province_operator_remote_data_source_impl.dart new file mode 100644 index 0000000..dbdb5fa --- /dev/null +++ b/packages/chicken/lib/features/province_operator/data/datasources/remote/province_operator_remote_data_source_impl.dart @@ -0,0 +1,40 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/datasources/remote/province_operator_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceOperatorRemoteDataSourceImpl + implements ProvinceOperatorRemoteDataSource { + final DioRemote _httpClient; + + ProvinceOperatorRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} diff --git a/packages/chicken/lib/features/province_operator/data/di/province_operator_di.dart b/packages/chicken/lib/features/province_operator/data/di/province_operator_di.dart new file mode 100644 index 0000000..3da913e --- /dev/null +++ b/packages/chicken/lib/features/province_operator/data/di/province_operator_di.dart @@ -0,0 +1,46 @@ +import 'package:rasadyar_chicken/features/province_operator/data/datasources/remote/province_operator_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/datasources/remote/province_operator_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/repositories/province_operator_repository.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/repositories/province_operator_repository_impl.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for province_operator feature +Future setupProvinceOperatorDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => ProvinceOperatorRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => ProvinceOperatorRepositoryImpl( + di.get(), + ), + ); + + // Use PoultryScienceRepository for shared functionality + if (!di.isRegistered()) { + // PoultryScienceRepository should already be registered, but just in case + } +} + +/// Re-register province_operator dependencies (used when base URL changes) +Future reRegisterProvinceOperatorDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => ProvinceOperatorRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => ProvinceOperatorRepositoryImpl( + di.get(), + ), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/province_operator/data/repositories/province_operator_repository.dart b/packages/chicken/lib/features/province_operator/data/repositories/province_operator_repository.dart new file mode 100644 index 0000000..0affc82 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/data/repositories/province_operator_repository.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class ProvinceOperatorRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/province_operator/data/repositories/province_operator_repository_impl.dart b/packages/chicken/lib/features/province_operator/data/repositories/province_operator_repository_impl.dart new file mode 100644 index 0000000..84359d3 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/data/repositories/province_operator_repository_impl.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/datasources/remote/province_operator_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/repositories/province_operator_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceOperatorRepositoryImpl implements ProvinceOperatorRepository { + final ProvinceOperatorRemoteDataSource _remote; + + ProvinceOperatorRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..45e9cf7 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,95 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + ProvinceOperatorRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'ProvinceOperator', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..950ecaa --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/active_hatching/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: provinceOperatorActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart new file mode 100644 index 0000000..778e68f --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/home/logic.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/province_operator/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceOperatorHomeItem { + final String title; + final String route; + final String icon; + + ProvinceOperatorHomeItem({ + required this.title, + required this.route, + required this.icon, + }); +} + +class ProvinceOperatorHomeLogic extends GetxController { + RxList items = [ + ProvinceOperatorHomeItem( + title: "جوجه ریزی فعال", + route: ProvinceOperatorRoutes.activeHatchingProvinceOperator, + icon: Assets.vec.activeFramSvg.path, + ), + ProvinceOperatorHomeItem( + title: "بازرسی مزارع طیور", + route: ProvinceOperatorRoutes.newInspectionProvinceOperator, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/home/view.dart b/packages/chicken/lib/features/province_operator/presentation/pages/home/view.dart new file mode 100644 index 0000000..1e52884 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/home/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class ProvinceOperatorHomePage extends GetView { + ProvinceOperatorHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: provinceOperatorActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/province_operator/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..3909ea3 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + ProvinceOperatorRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.provinceOperatorRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'ProvinceOperator', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/province_operator/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..00ee4f6 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: provinceOperatorActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/root/logic.dart b/packages/chicken/lib/features/province_operator/presentation/pages/root/logic.dart new file mode 100644 index 0000000..0f9f14a --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/root/logic.dart @@ -0,0 +1,83 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/province_operator/data/repositories/province_operator_repository.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class ProvinceOperatorRootLogic extends GetxController { + var tokenService = Get.find(); + + late ProvinceOperatorRepository provinceOperatorRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(provinceOperatorActionKey), + onGenerateRoute: (settings) { + final page = ProvinceOperatorPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => ProvinceOperatorPages.pages.firstWhere( + (e) => e.name == ProvinceOperatorRoutes.homeProvinceOperator, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + provinceOperatorRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/pages/root/view.dart b/packages/chicken/lib/features/province_operator/presentation/pages/root/view.dart new file mode 100644 index 0000000..90b8f2b --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/pages/root/view.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class ProvinceOperatorRootPage extends GetView { + const ProvinceOperatorRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + + + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + provinceOperatorActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + provinceOperatorActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/province_operator/presentation/routes/pages.dart b/packages/chicken/lib/features/province_operator/presentation/routes/pages.dart new file mode 100644 index 0000000..d0faa29 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/routes/pages.dart @@ -0,0 +1,82 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/province_operator/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceOperatorPages { + ProvinceOperatorPages._(); + + static List get pages => [ + GetPage( + name: ProvinceOperatorRoutes.initProvinceOperator, + page: () => ProvinceOperatorRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => ProvinceOperatorRootLogic()); + Get.lazyPut(() => ProvinceOperatorHomeLogic()); + }), + ], + ), + GetPage( + name: ProvinceOperatorRoutes.homeProvinceOperator, + page: () => ProvinceOperatorHomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => ProvinceOperatorRootLogic()); + Get.lazyPut(() => ProvinceOperatorHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + GetPage( + name: ProvinceOperatorRoutes.actionProvinceOperator, + page: () => ProvinceOperatorHomePage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ProvinceOperatorRootLogic()); + Get.lazyPut(() => ProvinceOperatorHomeLogic()); + }), + ], + ), + GetPage( + name: ProvinceOperatorRoutes.activeHatchingProvinceOperator, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ProvinceOperatorRootLogic(),fenix: true); + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: ProvinceOperatorRoutes.newInspectionProvinceOperator, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ProvinceOperatorRootLogic()); + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/province_operator/presentation/routes/routes.dart b/packages/chicken/lib/features/province_operator/presentation/routes/routes.dart new file mode 100644 index 0000000..be47597 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/presentation/routes/routes.dart @@ -0,0 +1,10 @@ +sealed class ProvinceOperatorRoutes { + ProvinceOperatorRoutes._(); + + static const _base = '/chicken/provinceOperator'; + static const initProvinceOperator = '$_base/'; + static const homeProvinceOperator = '$_base/home'; + static const actionProvinceOperator = '$_base/action'; + static const activeHatchingProvinceOperator = '$_base/activeHatching'; + static const newInspectionProvinceOperator = '$_base/newInspection'; +} diff --git a/packages/chicken/lib/features/province_operator/province_operator.dart b/packages/chicken/lib/features/province_operator/province_operator.dart new file mode 100644 index 0000000..28e0af1 --- /dev/null +++ b/packages/chicken/lib/features/province_operator/province_operator.dart @@ -0,0 +1,3 @@ +export 'data/di/province_operator_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source.dart b/packages/chicken/lib/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source.dart new file mode 100644 index 0000000..f42a0fb --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class ProvinceSupervisorRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source_impl.dart b/packages/chicken/lib/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source_impl.dart new file mode 100644 index 0000000..9133bee --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source_impl.dart @@ -0,0 +1,40 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceSupervisorRemoteDataSourceImpl + implements ProvinceSupervisorRemoteDataSource { + final DioRemote _httpClient; + + ProvinceSupervisorRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} diff --git a/packages/chicken/lib/features/province_supervisor/data/di/province_supervisor_di.dart b/packages/chicken/lib/features/province_supervisor/data/di/province_supervisor_di.dart new file mode 100644 index 0000000..7b9b87e --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/data/di/province_supervisor_di.dart @@ -0,0 +1,40 @@ +import 'package:rasadyar_chicken/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/repositories/province_supervisor_repository.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/repositories/province_supervisor_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for province_supervisor feature +Future setupProvinceSupervisorDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => ProvinceSupervisorRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => ProvinceSupervisorRepositoryImpl( + di.get()), + ); +} + +/// Re-register province_supervisor dependencies (used when base URL changes) +Future reRegisterProvinceSupervisorDI( + GetIt di, DioRemote dioRemote) async { + await reRegister( + di, () => ProvinceSupervisorRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => ProvinceSupervisorRepositoryImpl( + di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/province_supervisor/data/repositories/province_supervisor_repository.dart b/packages/chicken/lib/features/province_supervisor/data/repositories/province_supervisor_repository.dart new file mode 100644 index 0000000..4961278 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/data/repositories/province_supervisor_repository.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class ProvinceSupervisorRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/province_supervisor/data/repositories/province_supervisor_repository_impl.dart b/packages/chicken/lib/features/province_supervisor/data/repositories/province_supervisor_repository_impl.dart new file mode 100644 index 0000000..0a2a420 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/data/repositories/province_supervisor_repository_impl.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/datasources/remote/province_supervisor_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/repositories/province_supervisor_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceSupervisorRepositoryImpl implements ProvinceSupervisorRepository { + final ProvinceSupervisorRemoteDataSource _remote; + + ProvinceSupervisorRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..f9ba29f --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,97 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/root/logic.dart'; + +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + ProvinceSupervisorRootLogic rootLogic = + Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'ProvinceSupervisor', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..28553c4 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/active_hatching/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: provinceOperatorActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart new file mode 100644 index 0000000..61d4abe --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/logic.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/province_supervisor/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceSupervisorActionItem { + final String title; + final String route; + final String icon; + + ProvinceSupervisorActionItem({ + required this.title, + required this.route, + required this.icon, + }); +} + +class ProvinceSupervisorHomeLogic extends GetxController { + RxList items = [ + ProvinceSupervisorActionItem( + title: "جوجه ریزی فعال", + route: ProvinceSupervisorRoutes.activeHatchingProvinceSupervisor, + icon: Assets.vec.activeFramSvg.path, + ), + ProvinceSupervisorActionItem( + title: "بازرسی مزارع طیور", + route: ProvinceSupervisorRoutes.newInspectionProvinceSupervisor, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/home/view.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/view.dart new file mode 100644 index 0000000..ce8bb6b --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/home/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class ProvinceSupervisorHomePage extends GetView { + ProvinceSupervisorHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: provinceSupervisorActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..c93deb0 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,160 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + ProvinceSupervisorRootLogic rootLogic = + Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.provinceSupervisorRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'ProvinceSupervisor', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..e07d0ba --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: provinceSupervisorActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/root/logic.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/root/logic.dart new file mode 100644 index 0000000..642f191 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/root/logic.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/data/repositories/province_supervisor_repository.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class ProvinceSupervisorRootLogic extends GetxController { + var tokenService = Get.find(); + + late ProvinceSupervisorRepository provinceSupervisorRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(provinceSupervisorActionKey), + onGenerateRoute: (settings) { + final page = ProvinceSupervisorPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => ProvinceSupervisorPages.pages.firstWhere( + (e) => e.name == ProvinceSupervisorRoutes.homeProvinceSupervisor, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + provinceSupervisorRepository = diChicken + .get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/pages/root/view.dart b/packages/chicken/lib/features/province_supervisor/presentation/pages/root/view.dart new file mode 100644 index 0000000..95b26d0 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/pages/root/view.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class ProvinceSupervisorRootPage extends GetView { + const ProvinceSupervisorRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + provinceSupervisorActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + provinceSupervisorActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/routes/pages.dart b/packages/chicken/lib/features/province_supervisor/presentation/routes/pages.dart new file mode 100644 index 0000000..9212626 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/routes/pages.dart @@ -0,0 +1,68 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ProvinceSupervisorPages { + ProvinceSupervisorPages._(); + + static List get pages => [ + GetPage( + name: ProvinceSupervisorRoutes.initProvinceSupervisor, + page: () => ProvinceSupervisorRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => ProvinceSupervisorRootLogic()); + Get.lazyPut(() => ProvinceSupervisorHomeLogic()); + }), + ], + ), + GetPage( + name: ProvinceSupervisorRoutes.homeProvinceSupervisor, + page: () => ProvinceSupervisorHomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(ProvinceSupervisorHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + + GetPage( + name: ProvinceSupervisorRoutes.activeHatchingProvinceSupervisor, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ProvinceSupervisorRootLogic(), fenix: true); + Get.lazyPut(() => ActiveHatchingLogic()); + + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: ProvinceSupervisorRoutes.newInspectionProvinceSupervisor, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/province_supervisor/presentation/routes/routes.dart b/packages/chicken/lib/features/province_supervisor/presentation/routes/routes.dart new file mode 100644 index 0000000..547f355 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/presentation/routes/routes.dart @@ -0,0 +1,10 @@ +sealed class ProvinceSupervisorRoutes { + ProvinceSupervisorRoutes._(); + + static const _base = '/chicken/provinceSupervisor'; + static const initProvinceSupervisor = '$_base/'; + static const homeProvinceSupervisor = '$_base/home'; + static const actionProvinceSupervisor = '$_base/action'; + static const activeHatchingProvinceSupervisor = '$_base/activeHatching'; + static const newInspectionProvinceSupervisor = '$_base/newInspection'; +} diff --git a/packages/chicken/lib/features/province_supervisor/province_supervisor.dart b/packages/chicken/lib/features/province_supervisor/province_supervisor.dart new file mode 100644 index 0000000..3824e90 --- /dev/null +++ b/packages/chicken/lib/features/province_supervisor/province_supervisor.dart @@ -0,0 +1,3 @@ +export 'data/di/province_supervisor_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/steward/buy/view.dart b/packages/chicken/lib/features/steward/buy/view.dart index b25e79f..5e2b372 100644 --- a/packages/chicken/lib/features/steward/buy/view.dart +++ b/packages/chicken/lib/features/steward/buy/view.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_core/core.dart'; @@ -30,7 +30,10 @@ class BuyPage extends GetView { end: AlignmentGeometry.bottomRight, ), onTap: () { - Get.toNamed(ChickenRoutes.buysInProvinceSteward, id: stewardFirstKey); + Get.toNamed( + StewardRoutes.buysInProvinceSteward, + id: stewardFirstKey, + ); }, ), GlassMorphismCardIcon( @@ -43,7 +46,10 @@ class BuyPage extends GetView { end: AlignmentGeometry.bottomRight, ), onTap: () { - Get.toNamed(ChickenRoutes.buysOutOfProvinceSteward, id: stewardFirstKey); + Get.toNamed( + StewardRoutes.buysOutOfProvinceSteward, + id: stewardFirstKey, + ); }, ), ], diff --git a/packages/chicken/lib/features/steward/buy_in_province/logic.dart b/packages/chicken/lib/features/steward/buy_in_province/logic.dart index 9e88adb..12e6337 100644 --- a/packages/chicken/lib/features/steward/buy_in_province/logic.dart +++ b/packages/chicken/lib/features/steward/buy_in_province/logic.dart @@ -1,7 +1,8 @@ -import 'package:rasadyar_chicken/features/steward/buy/logic.dart'; -import 'package:rasadyar_chicken/features/steward/buy_in_province_all/logic.dart'; -import 'package:rasadyar_chicken/features/steward/buy_in_province_waiting/logic.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_all/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_waiting/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class BuyInProvinceLogic extends GetxController { diff --git a/packages/chicken/lib/features/steward/buy_in_province/view.dart b/packages/chicken/lib/features/steward/buy_in_province/view.dart index 9a718ff..3408ff2 100644 --- a/packages/chicken/lib/features/steward/buy_in_province/view.dart +++ b/packages/chicken/lib/features/steward/buy_in_province/view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/features/steward/buy_in_province_all/view.dart'; -import 'package:rasadyar_chicken/features/steward/buy_in_province_waiting/view.dart'; += +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_all/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_waiting/view.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart'; diff --git a/packages/chicken/lib/features/steward/buy_in_province_all/logic.dart b/packages/chicken/lib/features/steward/buy_in_province_all/logic.dart index f301043..b8984bb 100644 --- a/packages/chicken/lib/features/steward/buy_in_province_all/logic.dart +++ b/packages/chicken/lib/features/steward/buy_in_province_all/logic.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_allocation/steward_allocation_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class BuyInProvinceAllLogic extends GetxController { @@ -33,7 +34,11 @@ class BuyInProvinceAllLogic extends GetxController { @override void onReady() { - debounce(searchedValue, (callback) => getAllArrivals(), time: Duration(milliseconds: 2000)); + debounce( + searchedValue, + (callback) => getAllArrivals(), + time: Duration(milliseconds: 2000), + ); super.onReady(); ever(approvedWithOtpCode, (callback) { if (callback == false) { @@ -42,13 +47,12 @@ class BuyInProvinceAllLogic extends GetxController { }); } - - Future getAllArrivals([bool isLoadingMore = false]) async { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { - allProduct.value = Resource>.loading(); + allProduct.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -58,7 +62,7 @@ class BuyInProvinceAllLogic extends GetxController { } safeCall( - call: () async => await rootLogic.chickenRepository.getWaitingArrivals( + call: () async => await rootLogic.stewardRepository.getWaitingArrivals( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( queryParams: {'type': 'all'}, @@ -74,16 +78,21 @@ class BuyInProvinceAllLogic extends GetxController { onSuccess: (res) async { await Future.delayed(Duration(milliseconds: 200)); if ((res?.count ?? 0) == 0) { - allProduct.value = Resource>.empty(); + allProduct.value = + Resource>.empty(); } else { - allProduct.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(allProduct.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + allProduct.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(allProduct.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); } }, ); @@ -105,7 +114,7 @@ class BuyInProvinceAllLogic extends GetxController { safeCall( showError: true, - call: () async => await rootLogic.chickenRepository.setSateForArrivals( + call: () async => await rootLogic.stewardRepository.setSateForArrivals( token: rootLogic.tokenService.accessToken.value!, request: request, ), @@ -128,7 +137,7 @@ class BuyInProvinceAllLogic extends GetxController { request.removeWhere((key, value) => value == null); safeCall( - call: () async => await rootLogic.chickenRepository.setSateForArrivals( + call: () async => await rootLogic.stewardRepository.setSateForArrivals( token: rootLogic.tokenService.accessToken.value!, request: request, ), diff --git a/packages/chicken/lib/features/steward/buy_in_province_all/view.dart b/packages/chicken/lib/features/steward/buy_in_province_all/view.dart index 609ee56..9717a4b 100644 --- a/packages/chicken/lib/features/steward/buy_in_province_all/view.dart +++ b/packages/chicken/lib/features/steward/buy_in_province_all/view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -84,14 +84,19 @@ class BuyInProvinceAllPage extends GetView { child: Assets.vec.hotChickenSvg.svg( width: 24, height: 24, - colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + AppColor.blueNormal, + BlendMode.srcIn, + ), ), ), Text( item.weightOfCarcasses?.separatedByCommaFa.addKg ?? 'N/A', textAlign: TextAlign.left, textDirection: TextDirection.ltr, - style: AppFonts.yekan12Bold.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan12Bold.copyWith( + color: AppColor.blueNormal, + ), ), ], ), @@ -119,7 +124,10 @@ class BuyInProvinceAllPage extends GetView { Container itemListExpandedWidget(WaitingArrivalModel item) { return Container( padding: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), child: Column( spacing: 8, children: [ @@ -138,10 +146,15 @@ class BuyInProvinceAllPage extends GetView { style: AppFonts.yekan10.copyWith(color: AppColor.darkGreyDark), ), SizedBox(width: 7), - SvgGenImage.vec(controller.getVecPathItem(item.receiverState)).svg( + SvgGenImage.vec( + controller.getVecPathItem(item.receiverState), + ).svg( width: 16.w, height: 16.h, - colorFilter: ColorFilter.mode(AppColor.darkGreyDark, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + AppColor.darkGreyDark, + BlendMode.srcIn, + ), ), ], ), @@ -163,12 +176,16 @@ class BuyInProvinceAllPage extends GetView { children: [ Text( item.date?.toJalali.formatter.wN ?? 'N/A', - style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + style: AppFonts.yekan14.copyWith( + color: AppColor.textColor, + ), ), Text( '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'N/A'}', - style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), ), ], ), @@ -186,13 +203,19 @@ class BuyInProvinceAllPage extends GetView { ), ), - buildRow(title: 'مشخصات فروشنده', value: item.toSteward?.user?.fullname ?? 'N/A'), + buildRow( + title: 'مشخصات فروشنده', + value: item.toSteward?.user?.fullname ?? 'N/A', + ), buildRow( title: 'تلفن فروشنده', value: item.toSteward?.user?.mobile ?? 'N/A', valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), ), - buildRow(title: 'نوع تخصیص', value: item.allocationType?.faAllocationType ?? 'N/A'), + buildRow( + title: 'نوع تخصیص', + value: item.allocationType?.faAllocationType ?? 'N/A', + ), buildRow(title: ' سهمیه', value: item.quota?.faTitle ?? 'N/A'), buildRow(title: 'محصول', value: item.product?.name ?? 'N/A'), buildRow( @@ -203,7 +226,9 @@ class BuyInProvinceAllPage extends GetView { buildRow( title: 'قیمت هر کیلوگرم', titleLabel: (item.approvedPriceStatus ?? false) ? 'مصوب' : 'آزاد', - titleLabelStyle: AppFonts.yekan14Bold.copyWith(color: AppColor.greenNormal), + titleLabelStyle: AppFonts.yekan14Bold.copyWith( + color: AppColor.greenNormal, + ), value: item.amount?.separatedByCommaFa ?? 'N/A', valueLabel: 'ریال', ), @@ -240,7 +265,9 @@ class BuyInProvinceAllPage extends GetView { }, controller.isLoadingConfirmMap), ROutlinedElevated( text: 'رد', - textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal), + textStyle: AppFonts.yekan20.copyWith( + color: AppColor.redNormal, + ), width: 150.w, height: 40.h, onPressed: () { @@ -285,25 +312,37 @@ class BuyInProvinceAllPage extends GetView { label: 'وزن(کیلوگرم)', controller: controller.weightController, keyboardType: TextInputType.number, - inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], ), SizedBox(height: 16.h), RTextField( label: 'حجم(قطعه)', controller: controller.countController, keyboardType: TextInputType.number, - inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], ), SizedBox(height: 16.h), RTextField( label: 'افت وزن(کیلوگرم)', controller: controller.lossController, keyboardType: TextInputType.number, - inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], ), SizedBox(height: 16.h), - Text('تایید ', style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor)), + Text( + 'تایید ', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor), + ), ObxValue((data) { return Column( children: [ @@ -373,7 +412,12 @@ class BuyInProvinceAllPage extends GetView { child: Row( children: [ Radio(value: value), - Text(label, style: textStyle ?? AppFonts.yekan16.copyWith(color: AppColor.textColor)), + Text( + label, + style: + textStyle ?? + AppFonts.yekan16.copyWith(color: AppColor.textColor), + ), ], ), ); diff --git a/packages/chicken/lib/features/steward/buy_in_province_waiting/logic.dart b/packages/chicken/lib/features/steward/buy_in_province_waiting/logic.dart index 01b9d4e..b6c6389 100644 --- a/packages/chicken/lib/features/steward/buy_in_province_waiting/logic.dart +++ b/packages/chicken/lib/features/steward/buy_in_province_waiting/logic.dart @@ -1,9 +1,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_allocation/steward_allocation_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -48,8 +49,6 @@ class BuyInProvinceWaitingLogic extends GetxController { }); } - - void setSearchValue(String? data) { searchedValue.value = data?.trim(); } @@ -58,7 +57,8 @@ class BuyInProvinceWaitingLogic extends GetxController { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { - waitingProduct.value = Resource>.loading(); + waitingProduct.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -68,7 +68,7 @@ class BuyInProvinceWaitingLogic extends GetxController { } safeCall( - call: () async => await rootLogic.chickenRepository.getWaitingArrivals( + call: () async => await rootLogic.stewardRepository.getWaitingArrivals( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( queryParams: {'type': 'not_entered'}, @@ -84,16 +84,21 @@ class BuyInProvinceWaitingLogic extends GetxController { onSuccess: (res) async { await Future.delayed(Duration(milliseconds: 200)); if ((res?.count ?? 0) == 0) { - waitingProduct.value = Resource>.empty(); + waitingProduct.value = + Resource>.empty(); } else { - waitingProduct.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(waitingProduct.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + waitingProduct.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(waitingProduct.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); flashingFabBgColor(); } }, @@ -118,7 +123,7 @@ class BuyInProvinceWaitingLogic extends GetxController { safeCall( showError: true, showSuccess: true, - call: () async => await rootLogic.chickenRepository.setSateForArrivals( + call: () async => await rootLogic.stewardRepository.setSateForArrivals( token: rootLogic.tokenService.accessToken.value!, request: request, ), @@ -147,7 +152,7 @@ class BuyInProvinceWaitingLogic extends GetxController { request.removeWhere((key, value) => value == null); safeCall( - call: () async => await rootLogic.chickenRepository.setSateForArrivals( + call: () async => await rootLogic.stewardRepository.setSateForArrivals( token: rootLogic.tokenService.accessToken.value!, request: request, ), diff --git a/packages/chicken/lib/features/steward/buy_in_province_waiting/view.dart b/packages/chicken/lib/features/steward/buy_in_province_waiting/view.dart index 8e4b76b..4e7a294 100644 --- a/packages/chicken/lib/features/steward/buy_in_province_waiting/view.dart +++ b/packages/chicken/lib/features/steward/buy_in_province_waiting/view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -88,14 +88,19 @@ class BuyInProvinceWaitingPage extends GetView { child: Assets.vec.hotChickenSvg.svg( width: 24, height: 24, - colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + AppColor.blueNormal, + BlendMode.srcIn, + ), ), ), Text( item.weightOfCarcasses?.separatedByCommaFa.addKg ?? 'ندارد', textAlign: TextAlign.left, textDirection: TextDirection.ltr, - style: AppFonts.yekan12Bold.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan12Bold.copyWith( + color: AppColor.blueNormal, + ), ), ], ), @@ -130,7 +135,10 @@ class BuyInProvinceWaitingPage extends GetView { Container itemListExpandedWidget(WaitingArrivalModel item) { return Container( padding: EdgeInsets.symmetric(horizontal: 8), - decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), child: Column( spacing: 8, children: [ @@ -170,12 +178,16 @@ class BuyInProvinceWaitingPage extends GetView { children: [ Text( item.date?.toJalali.formatter.wN ?? 'ندارد', - style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + style: AppFonts.yekan14.copyWith( + color: AppColor.textColor, + ), ), Text( '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}', - style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), ), ], ), @@ -204,9 +216,15 @@ class BuyInProvinceWaitingPage extends GetView { '${controller.rootLogic.isKillHouse(item) ? item.killHouse?.killHouseOperator?.user?.mobile : item.steward?.user?.mobile} ', valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), ), - buildRow(title: 'نوع تخصیص', value: item.allocationType?.faAllocationType ?? 'ندارد'), + buildRow( + title: 'نوع تخصیص', + value: item.allocationType?.faAllocationType ?? 'ندارد', + ), buildRow(title: ' سهمیه', value: item.quota?.faTitle ?? 'ندارد'), - buildRow(title: 'نوع فروش', value: item.saleType == "governmental" ? 'دولتی' : 'آزاد'), + buildRow( + title: 'نوع فروش', + value: item.saleType == "governmental" ? 'دولتی' : 'آزاد', + ), buildRow(title: 'محصول', value: item.product?.name ?? 'ندارد'), buildRow( title: 'تاریخ تولید گوشت', @@ -219,11 +237,16 @@ class BuyInProvinceWaitingPage extends GetView { buildRow( title: 'قیمت هر کیلوگرم', titleLabel: (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد', - titleLabelStyle: AppFonts.yekan14Bold.copyWith(color: AppColor.greenNormal), + titleLabelStyle: AppFonts.yekan14Bold.copyWith( + color: AppColor.greenNormal, + ), value: '${item.amount?.separatedByCommaFa} ریال', ), - buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByCommaFa} ریال'), + buildRow( + title: 'قیمت کل', + value: '${item.totalAmount?.separatedByCommaFa} ریال', + ), Row( mainAxisAlignment: MainAxisAlignment.center, @@ -236,7 +259,10 @@ class BuyInProvinceWaitingPage extends GetView { height: 40.h, isLoading: data[item.key!] ?? false, onPressed: () async { - await Get.bottomSheet(conformationBottomSheet(item), isScrollControlled: true); + await Get.bottomSheet( + conformationBottomSheet(item), + isScrollControlled: true, + ); }, textStyle: AppFonts.yekan20.copyWith(color: Colors.white), backgroundColor: AppColor.greenNormal, @@ -276,25 +302,37 @@ class BuyInProvinceWaitingPage extends GetView { label: 'وزن(کیلوگرم)', controller: controller.weightController, keyboardType: TextInputType.number, - inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], ), SizedBox(height: 16.h), RTextField( label: 'حجم(قطعه)', controller: controller.countController, keyboardType: TextInputType.number, - inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], ), SizedBox(height: 16.h), RTextField( label: 'افت وزن(کیلوگرم)', controller: controller.lossController, keyboardType: TextInputType.number, - inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], ), SizedBox(height: 16.h), - Text('تایید ', style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor)), + Text( + 'تایید ', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor), + ), ObxValue((data) { return Column( children: [ @@ -365,7 +403,12 @@ class BuyInProvinceWaitingPage extends GetView { child: Row( children: [ Radio(value: value), - Text(label, style: textStyle ?? AppFonts.yekan16.copyWith(color: AppColor.textColor)), + Text( + label, + style: + textStyle ?? + AppFonts.yekan16.copyWith(color: AppColor.textColor), + ), ], ), ); diff --git a/packages/chicken/lib/features/steward/buy_out_of_province/logic.dart b/packages/chicken/lib/features/steward/buy_out_of_province/logic.dart index 82be7b4..3ec8dbb 100644 --- a/packages/chicken/lib/features/steward/buy_out_of_province/logic.dart +++ b/packages/chicken/lib/features/steward/buy_out_of_province/logic.dart @@ -1,11 +1,12 @@ import 'package:flutter/cupertino.dart'; -import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart'; -import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; -import 'package:rasadyar_chicken/features/steward/buy/logic.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -84,11 +85,14 @@ class BuyOutOfProvinceLogic extends GetxController { searchedValue.value = data?.trim(); } - Future getStewardPurchaseOutOfProvince([bool isLoadingMore = false]) async { + Future getStewardPurchaseOutOfProvince([ + bool isLoadingMore = false, + ]) async { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { - purchaseOutOfProvinceList.value = Resource>.loading(); + purchaseOutOfProvinceList.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -97,34 +101,37 @@ class BuyOutOfProvinceLogic extends GetxController { currentPage.value = 1; // Reset to first page if search value is set } await safeCall( - call: () => rootLogic.chickenRepository.getStewardPurchasesOutSideOfTheProvince( - 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(), - ), - ), + call: () => + rootLogic.stewardRepository.getStewardPurchasesOutSideOfTheProvince( + 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: (res) async { await Future.delayed(Duration(milliseconds: 500)); if ((res?.count ?? 0) == 0) { - purchaseOutOfProvinceList.value = Resource>.empty(); + purchaseOutOfProvinceList.value = + Resource>.empty(); } else { - purchaseOutOfProvinceList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [ - ...(purchaseOutOfProvinceList.value.data?.results ?? []), - ...(res?.results ?? []), - ], - ), - ); + purchaseOutOfProvinceList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(purchaseOutOfProvinceList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); } }, ); @@ -132,8 +139,9 @@ class BuyOutOfProvinceLogic extends GetxController { Future getCites() async { await safeCall( - call: () => - rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''), + call: () => rootLogic.commonRepository.getCity( + provinceName: selectedProvince.value?.name ?? '', + ), onSuccess: (result) { if (result != null && result.isNotEmpty) { cites.value = result; @@ -202,10 +210,11 @@ class BuyOutOfProvinceLogic extends GetxController { date: DateTime.now().formattedYHMS, distributionType: 'App', ); - await rootLogic.chickenRepository.createStewardPurchasesOutSideOfTheProvince( - token: rootLogic.tokenService.accessToken.value!, - body: createStewardFreeBar, - ); + await rootLogic.stewardRepository + .createStewardPurchasesOutSideOfTheProvince( + token: rootLogic.tokenService.accessToken.value!, + body: createStewardFreeBar, + ); }, onSuccess: (result) { getStewardPurchaseOutOfProvince(); @@ -267,10 +276,11 @@ class BuyOutOfProvinceLogic extends GetxController { await safeCall( showError: true, - call: () => rootLogic.chickenRepository.editStewardPurchasesOutSideOfTheProvince( - token: rootLogic.tokenService.accessToken.value!, - body: edit, - ), + call: () => + rootLogic.stewardRepository.editStewardPurchasesOutSideOfTheProvince( + token: rootLogic.tokenService.accessToken.value!, + body: edit, + ), onSuccess: (result) { onRefresh(); rootLogic.onRefresh(); @@ -281,10 +291,11 @@ class BuyOutOfProvinceLogic extends GetxController { Future deleteStewardPurchaseOutOfProvince(String key) async { await safeCall( - call: () => rootLogic.chickenRepository.deleteStewardPurchasesOutSideOfTheProvince( - token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildRawQueryParams(queryParams: {'key': key}), - ), + call: () => rootLogic.stewardRepository + .deleteStewardPurchasesOutSideOfTheProvince( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildRawQueryParams(queryParams: {'key': key}), + ), ); } diff --git a/packages/chicken/lib/features/steward/buy_out_of_province/view.dart b/packages/chicken/lib/features/steward/buy_out_of_province/view.dart index 9ae5182..e2aa24f 100644 --- a/packages/chicken/lib/features/steward/buy_out_of_province/view.dart +++ b/packages/chicken/lib/features/steward/buy_out_of_province/view.dart @@ -3,9 +3,9 @@ import 'dart:io'; import 'package:flutter/cupertino.dart' hide Image; 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/roles_products/roles_products.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart'; diff --git a/packages/chicken/lib/features/steward/data/datasources/remote/steward_remote_data_source.dart b/packages/chicken/lib/features/steward/data/datasources/remote/steward_remote_data_source.dart new file mode 100644 index 0000000..26ab0c6 --- /dev/null +++ b/packages/chicken/lib/features/steward/data/datasources/remote/steward_remote_data_source.dart @@ -0,0 +1,138 @@ +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/imported_loads_model/imported_loads_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_core/data/model/pagination_model/pagination_model.dart'; + +abstract class StewardRemoteDataSource { + Future?> getWaitingArrivals({ + required String token, + Map? queryParameters, + }); + + Future setSateForArrivals({ + required String token, + required Map request, + }); + + Future?> getImportedLoadsModel({ + required String token, + Map? queryParameters, + }); + + Future?> getAllocatedMade({ + required String token, + Map? queryParameters, + }); + + Future confirmAllocation({ + required String token, + required Map allocation, + }); + + Future denyAllocation({ + required String token, + required String allocationToken, + }); + + Future confirmAllAllocation({ + required String token, + required List allocationTokens, + }); + + Future postSubmitStewardAllocation({ + required String token, + required SubmitStewardAllocation request, + }); + + Future deleteStewardAllocation({ + required String token, + Map? queryParameters, + }); + + Future updateStewardAllocation({ + required String token, + required ConformAllocation request, + }); + + Future getStewardDashboard({ + required String token, + required String stratDate, + required String endDate, + }); + + Future getDashboardKillHouseFreeBar({ + required String token, + required String stratDate, + required String endDate, + }); + + Future?> + getStewardPurchasesOutSideOfTheProvince({ + required String token, + Map? queryParameters, + }); + + Future createStewardPurchasesOutSideOfTheProvince({ + required String token, + required CreateStewardFreeBar body, + }); + + Future deleteStewardPurchasesOutSideOfTheProvince({ + required String token, + Map? queryParameters, + }); + + Future editStewardPurchasesOutSideOfTheProvince({ + required String token, + Map? queryParameters, + }); + + Future?> + getOutProvinceCarcassesBuyer({ + required String token, + Map? queryParameters, + }); + + Future createOutProvinceCarcassesBuyer({ + required String token, + required OutProvinceCarcassesBuyer body, + }); + + Future?> getStewardFreeSaleBar({ + required String token, + Map? queryParameters, + }); + + Future createOutProvinceStewardFreeBar({ + required String token, + required StewardFreeSaleBarRequest body, + }); + + Future updateOutProvinceStewardFreeBar({ + required String token, + required StewardFreeSaleBarRequest body, + }); + + Future deleteOutProvinceStewardFreeBar({ + required String token, + required String key, + }); + + Future getStewardSalesInfoDashboard({ + required String token, + Map? queryParameters, + }); + + Future getStewardRemainWeight({required String token}); +} diff --git a/packages/chicken/lib/data/data_source/remote/chicken/chicken_remote_imp.dart b/packages/chicken/lib/features/steward/data/datasources/remote/steward_remote_data_source_impl.dart similarity index 53% rename from packages/chicken/lib/data/data_source/remote/chicken/chicken_remote_imp.dart rename to packages/chicken/lib/features/steward/data/datasources/remote/steward_remote_data_source_impl.dart index 96885b3..54ceab5 100644 --- a/packages/chicken/lib/data/data_source/remote/chicken/chicken_remote_imp.dart +++ b/packages/chicken/lib/features/steward/data/datasources/remote/steward_remote_data_source_impl.dart @@ -1,63 +1,25 @@ -import 'package:rasadyar_chicken/data/models/request/change_password/change_password_request_model.dart'; -import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart'; -import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; -import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart'; -import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; -import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart'; -import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; -import 'package:rasadyar_chicken/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; -import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/imported_loads_model/imported_loads_model.dart'; -import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.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/segmentation_model/segmentation_model.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile/user_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart' - hide ProductModel; -import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_chicken/features/steward/data/datasources/remote/steward_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/imported_loads_model/imported_loads_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_core/data/model/pagination_model/pagination_model.dart'; +import 'package:rasadyar_core/infrastructure/remote/dio_remote.dart'; -import 'chicken_remote.dart'; - -class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource { +class StewardRemoteDataSourceImpl implements StewardRemoteDataSource { final DioRemote _httpClient; - ChickenRemoteDatasourceImp(this._httpClient); - - @override - Future getKillHouseDistributionInfo({ - required String token, - }) async { - var res = await _httpClient.get( - '/kill-house-distribution-info/?role=Steward', - headers: {'Authorization': 'Bearer $token'}, - fromJson: KillHouseDistributionInfo.fromJson, - ); - - return res.data; - } - - @override - Future getGeneralBarInformation({ - required String token, - Map? queryParameters, - }) async { - var res = await _httpClient.get( - '/bars_for_kill_house_dashboard/', - queryParameters: queryParameters, - headers: {'Authorization': 'Bearer $token'}, - fromJson: BarInformation.fromJson, - ); - return res.data; - } + StewardRemoteDataSourceImpl(this._httpClient); @override Future?> getWaitingArrivals({ @@ -157,50 +119,6 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource { ); } - @override - Future?> getRolesProducts({ - required String token, - CancelToken? cancelToken, - Map? queryParameters, - }) async { - var res = await _httpClient.get( - '/roles-products/', - headers: {'Authorization': 'Bearer $token'}, - cancelToken: cancelToken, - queryParameters: queryParameters, - fromJsonList: (json) => json - .map((item) => ProductModel.fromJson(item as Map)) - .toList(), - ); - return res.data; - } - - @override - Future?> getGuilds({ - required String token, - Map? queryParameters, - }) async { - var res = await _httpClient.get( - '/guilds/', - queryParameters: queryParameters, - headers: {'Authorization': 'Bearer $token'}, - fromJsonList: (json) => json - .map((item) => GuildModel.fromJson(item as Map)) - .toList(), - ); - return res.data; - } - - @override - Future getProfile({required String token}) async { - var res = await _httpClient.get( - '/guilds/0/?profile', - headers: {'Authorization': 'Bearer $token'}, - fromJson: GuildProfile.fromJson, - ); - return res.data; - } - @override Future postSubmitStewardAllocation({ required String token, @@ -283,39 +201,6 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource { return res.data; } - @override - Future?> getCity({ - required String provinceName, - }) async { - var res = await _httpClient.get( - '/iran_city/', - queryParameters: {'name': provinceName}, - fromJsonList: (json) => json - .map( - (item) => - IranProvinceCityModel.fromJson(item as Map), - ) - .toList(), - ); - return res.data; - } - - @override - Future?> getProvince({ - CancelToken? cancelToken, - }) async { - var res = await _httpClient.get( - '/iran_province/', - fromJsonList: (json) => json - .map( - (item) => - IranProvinceCityModel.fromJson(item as Map), - ) - .toList(), - ); - return res.data; - } - @override Future createStewardPurchasesOutSideOfTheProvince({ required String token, @@ -443,109 +328,6 @@ class ChickenRemoteDatasourceImp implements ChickenRemoteDatasource { ); } - @override - Future getUserProfile({required String token}) async { - var res = await _httpClient.get( - '/system_user_profile/?self-profile', - headers: {'Authorization': 'Bearer $token'}, - fromJson: (json) => UserProfile.fromJson(json), - ); - - return res.data; - } - - @override - Future updateUserProfile({ - required String token, - required UserProfile userProfile, - }) async { - await _httpClient.put( - '/system_user_profile/0/', - headers: {'Authorization': 'Bearer $token'}, - data: userProfile.toJson()..removeWhere((key, value) => value == null), - ); - } - - @override - Future updatePassword({ - required String token, - required ChangePasswordRequestModel model, - }) async { - await _httpClient.post( - '/api/change_password/', - headers: {'Authorization': 'Bearer $token'}, - data: model.toJson()..removeWhere((key, value) => value == null), - ); - } - - @override - Future?> getSegmentation({ - required String token, - Map? queryParameters, - }) async { - var res = await _httpClient.get( - '/app-segmentation/', - queryParameters: queryParameters, - headers: {'Authorization': 'Bearer $token'}, - fromJson: (json) => PaginationModel.fromJson( - json, - (json) => SegmentationModel.fromJson(json as Map), - ), - ); - 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( - '/app-segmentation/0/', - data: model.toJson()..removeWhere((key, value) => value == null), - headers: {'Authorization': 'Bearer $token'}, - ); - } - - @override - Future 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; - } - - @override - Future getBroadcastPrice({required String token}) async { - var res = await _httpClient.get( - '/broadcast-price/', - headers: {'Authorization': 'Bearer $token'}, - - fromJson: (json) => BroadcastPrice.fromJson(json), - ); - - return res.data; - } - @override Future getStewardSalesInfoDashboard({ required String token, diff --git a/packages/chicken/lib/features/steward/data/di/steward_di.dart b/packages/chicken/lib/features/steward/data/di/steward_di.dart new file mode 100644 index 0000000..eda06f6 --- /dev/null +++ b/packages/chicken/lib/features/steward/data/di/steward_di.dart @@ -0,0 +1,36 @@ +import 'package:rasadyar_chicken/features/steward/data/datasources/remote/steward_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/steward/data/datasources/remote/steward_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/steward/data/repositories/steward_repository.dart'; +import 'package:rasadyar_chicken/features/steward/data/repositories/steward_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for steward feature +Future setupStewardDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => StewardRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => StewardRepositoryImpl(di.get()), + ); +} + +/// Re-register steward dependencies (used when base URL changes) +Future reRegisterStewardDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => StewardRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => StewardRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/data/models/request/conform_allocation/conform_allocation.dart b/packages/chicken/lib/features/steward/data/model/request/conform_allocation/conform_allocation.dart similarity index 100% rename from packages/chicken/lib/data/models/request/conform_allocation/conform_allocation.dart rename to packages/chicken/lib/features/steward/data/model/request/conform_allocation/conform_allocation.dart diff --git a/packages/chicken/lib/data/models/request/conform_allocation/conform_allocation.freezed.dart b/packages/chicken/lib/features/steward/data/model/request/conform_allocation/conform_allocation.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/conform_allocation/conform_allocation.freezed.dart rename to packages/chicken/lib/features/steward/data/model/request/conform_allocation/conform_allocation.freezed.dart diff --git a/packages/chicken/lib/data/models/request/conform_allocation/conform_allocation.g.dart b/packages/chicken/lib/features/steward/data/model/request/conform_allocation/conform_allocation.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/conform_allocation/conform_allocation.g.dart rename to packages/chicken/lib/features/steward/data/model/request/conform_allocation/conform_allocation.g.dart diff --git a/packages/chicken/lib/data/models/request/create_steward_free_bar/create_steward_free_bar.dart b/packages/chicken/lib/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart similarity index 100% rename from packages/chicken/lib/data/models/request/create_steward_free_bar/create_steward_free_bar.dart rename to packages/chicken/lib/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart diff --git a/packages/chicken/lib/data/models/request/create_steward_free_bar/create_steward_free_bar.freezed.dart b/packages/chicken/lib/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/create_steward_free_bar/create_steward_free_bar.freezed.dart rename to packages/chicken/lib/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.freezed.dart diff --git a/packages/chicken/lib/data/models/request/create_steward_free_bar/create_steward_free_bar.g.dart b/packages/chicken/lib/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/create_steward_free_bar/create_steward_free_bar.g.dart rename to packages/chicken/lib/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.g.dart diff --git a/packages/chicken/lib/data/models/request/steward_allocation/steward_allocation_request.dart b/packages/chicken/lib/features/steward/data/model/request/steward_allocation/steward_allocation_request.dart similarity index 100% rename from packages/chicken/lib/data/models/request/steward_allocation/steward_allocation_request.dart rename to packages/chicken/lib/features/steward/data/model/request/steward_allocation/steward_allocation_request.dart diff --git a/packages/chicken/lib/data/models/request/steward_allocation/steward_allocation_request.freezed.dart b/packages/chicken/lib/features/steward/data/model/request/steward_allocation/steward_allocation_request.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/steward_allocation/steward_allocation_request.freezed.dart rename to packages/chicken/lib/features/steward/data/model/request/steward_allocation/steward_allocation_request.freezed.dart diff --git a/packages/chicken/lib/data/models/request/steward_allocation/steward_allocation_request.g.dart b/packages/chicken/lib/features/steward/data/model/request/steward_allocation/steward_allocation_request.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/steward_allocation/steward_allocation_request.g.dart rename to packages/chicken/lib/features/steward/data/model/request/steward_allocation/steward_allocation_request.g.dart diff --git a/packages/chicken/lib/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart b/packages/chicken/lib/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart similarity index 100% rename from packages/chicken/lib/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.dart rename to packages/chicken/lib/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart diff --git a/packages/chicken/lib/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.freezed.dart b/packages/chicken/lib/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.freezed.dart rename to packages/chicken/lib/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.freezed.dart diff --git a/packages/chicken/lib/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.g.dart b/packages/chicken/lib/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/steward_free_sale_bar/steward_free_sale_bar_request.g.dart rename to packages/chicken/lib/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.g.dart diff --git a/packages/chicken/lib/data/models/request/submit_steward_allocation/submit_steward_allocation.dart b/packages/chicken/lib/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart similarity index 100% rename from packages/chicken/lib/data/models/request/submit_steward_allocation/submit_steward_allocation.dart rename to packages/chicken/lib/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart diff --git a/packages/chicken/lib/data/models/request/submit_steward_allocation/submit_steward_allocation.freezed.dart b/packages/chicken/lib/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/request/submit_steward_allocation/submit_steward_allocation.freezed.dart rename to packages/chicken/lib/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.freezed.dart diff --git a/packages/chicken/lib/data/models/request/submit_steward_allocation/submit_steward_allocation.g.dart b/packages/chicken/lib/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.g.dart similarity index 100% rename from packages/chicken/lib/data/models/request/submit_steward_allocation/submit_steward_allocation.g.dart rename to packages/chicken/lib/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.g.dart diff --git a/packages/chicken/lib/data/models/response/allocated_made/allocated_made.dart b/packages/chicken/lib/features/steward/data/model/response/allocated_made/allocated_made.dart similarity index 100% rename from packages/chicken/lib/data/models/response/allocated_made/allocated_made.dart rename to packages/chicken/lib/features/steward/data/model/response/allocated_made/allocated_made.dart diff --git a/packages/chicken/lib/data/models/response/allocated_made/allocated_made.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/allocated_made/allocated_made.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/allocated_made/allocated_made.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/allocated_made/allocated_made.freezed.dart diff --git a/packages/chicken/lib/data/models/response/allocated_made/allocated_made.g.dart b/packages/chicken/lib/features/steward/data/model/response/allocated_made/allocated_made.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/allocated_made/allocated_made.g.dart rename to packages/chicken/lib/features/steward/data/model/response/allocated_made/allocated_made.g.dart diff --git a/packages/chicken/lib/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart b/packages/chicken/lib/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart similarity index 100% rename from packages/chicken/lib/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart rename to packages/chicken/lib/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart diff --git a/packages/chicken/lib/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.freezed.dart diff --git a/packages/chicken/lib/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.g.dart b/packages/chicken/lib/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.g.dart rename to packages/chicken/lib/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.g.dart diff --git a/packages/chicken/lib/data/models/response/imported_loads_model/imported_loads_model.dart b/packages/chicken/lib/features/steward/data/model/response/imported_loads_model/imported_loads_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/imported_loads_model/imported_loads_model.dart rename to packages/chicken/lib/features/steward/data/model/response/imported_loads_model/imported_loads_model.dart diff --git a/packages/chicken/lib/data/models/response/imported_loads_model/imported_loads_model.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/imported_loads_model/imported_loads_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/imported_loads_model/imported_loads_model.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/imported_loads_model/imported_loads_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/imported_loads_model/imported_loads_model.g.dart b/packages/chicken/lib/features/steward/data/model/response/imported_loads_model/imported_loads_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/imported_loads_model/imported_loads_model.g.dart rename to packages/chicken/lib/features/steward/data/model/response/imported_loads_model/imported_loads_model.g.dart diff --git a/packages/chicken/lib/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart b/packages/chicken/lib/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart similarity index 100% rename from packages/chicken/lib/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart rename to packages/chicken/lib/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart diff --git a/packages/chicken/lib/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.freezed.dart diff --git a/packages/chicken/lib/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.g.dart b/packages/chicken/lib/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/out_province_carcasses_buyer/out_province_carcasses_buyer.g.dart rename to packages/chicken/lib/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.g.dart diff --git a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.dart b/packages/chicken/lib/features/steward/data/model/response/segmentation_model/segmentation_model.dart similarity index 100% rename from packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.dart rename to packages/chicken/lib/features/steward/data/model/response/segmentation_model/segmentation_model.dart diff --git a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/segmentation_model/segmentation_model.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/segmentation_model/segmentation_model.freezed.dart diff --git a/packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.g.dart b/packages/chicken/lib/features/steward/data/model/response/segmentation_model/segmentation_model.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/segmentation_model/segmentation_model.g.dart rename to packages/chicken/lib/features/steward/data/model/response/segmentation_model/segmentation_model.g.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_bar/steward_free_bar.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_bar/steward_free_bar.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_bar/steward_free_bar.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_bar/steward_free_bar.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_bar/steward_free_bar.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_bar/steward_free_bar.freezed.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_bar/steward_free_bar.g.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_bar/steward_free_bar.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_bar/steward_free_bar.g.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_bar/steward_free_bar.g.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.freezed.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.g.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.g.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.g.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_sale_bar/steward_free_sale_bar.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_sale_bar/steward_free_sale_bar.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_sale_bar/steward_free_sale_bar.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.freezed.dart diff --git a/packages/chicken/lib/data/models/response/steward_free_sale_bar/steward_free_sale_bar.g.dart b/packages/chicken/lib/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_free_sale_bar/steward_free_sale_bar.g.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.g.dart diff --git a/packages/chicken/lib/data/models/response/steward_remain_weight/steward_remain_weight.dart b/packages/chicken/lib/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_remain_weight/steward_remain_weight.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart diff --git a/packages/chicken/lib/data/models/response/steward_remain_weight/steward_remain_weight.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_remain_weight/steward_remain_weight.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.freezed.dart diff --git a/packages/chicken/lib/data/models/response/steward_remain_weight/steward_remain_weight.g.dart b/packages/chicken/lib/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_remain_weight/steward_remain_weight.g.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.g.dart diff --git a/packages/chicken/lib/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart b/packages/chicken/lib/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart diff --git a/packages/chicken/lib/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.freezed.dart diff --git a/packages/chicken/lib/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.g.dart b/packages/chicken/lib/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.g.dart rename to packages/chicken/lib/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.g.dart diff --git a/packages/chicken/lib/data/models/response/waiting_arrival/waiting_arrival.dart b/packages/chicken/lib/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart similarity index 100% rename from packages/chicken/lib/data/models/response/waiting_arrival/waiting_arrival.dart rename to packages/chicken/lib/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart diff --git a/packages/chicken/lib/data/models/response/waiting_arrival/waiting_arrival.freezed.dart b/packages/chicken/lib/features/steward/data/model/response/waiting_arrival/waiting_arrival.freezed.dart similarity index 100% rename from packages/chicken/lib/data/models/response/waiting_arrival/waiting_arrival.freezed.dart rename to packages/chicken/lib/features/steward/data/model/response/waiting_arrival/waiting_arrival.freezed.dart diff --git a/packages/chicken/lib/data/models/response/waiting_arrival/waiting_arrival.g.dart b/packages/chicken/lib/features/steward/data/model/response/waiting_arrival/waiting_arrival.g.dart similarity index 100% rename from packages/chicken/lib/data/models/response/waiting_arrival/waiting_arrival.g.dart rename to packages/chicken/lib/features/steward/data/model/response/waiting_arrival/waiting_arrival.g.dart diff --git a/packages/chicken/lib/features/steward/data/repositories/steward_repository.dart b/packages/chicken/lib/features/steward/data/repositories/steward_repository.dart new file mode 100644 index 0000000..c0f175c --- /dev/null +++ b/packages/chicken/lib/features/steward/data/repositories/steward_repository.dart @@ -0,0 +1,140 @@ +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/imported_loads_model/imported_loads_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; + + +import 'package:rasadyar_core/core.dart'; + +abstract class StewardRepository { + Future?> getWaitingArrivals({ + required String token, + Map? queryParameters, + }); + + Future setSateForArrivals({ + required String token, + required Map request, + }); + + Future?> getImportedLoadsModel({ + required String token, + Map? queryParameters, + }); + + Future?> getAllocatedMade({ + required String token, + Map? queryParameters, + }); + + Future confirmAllocation({ + required String token, + required Map allocation, + }); + + Future denyAllocation({ + required String token, + required String allocationToken, + }); + + Future confirmAllAllocation({ + required String token, + required List allocationTokens, + }); + + Future postSubmitStewardAllocation({ + required String token, + required SubmitStewardAllocation request, + }); + + Future deleteStewardAllocation({ + required String token, + Map? queryParameters, + }); + + Future updateStewardAllocation({ + required String token, + required ConformAllocation request, + }); + + Future getStewardDashboard({ + required String token, + required String stratDate, + required String endDate, + }); + + Future getDashboardKillHouseFreeBar({ + required String token, + required String stratDate, + required String endDate, + }); + + Future?> + getStewardPurchasesOutSideOfTheProvince({ + required String token, + Map? queryParameters, + }); + + Future createStewardPurchasesOutSideOfTheProvince({ + required String token, + required CreateStewardFreeBar body, + }); + + Future editStewardPurchasesOutSideOfTheProvince({ + required String token, + required CreateStewardFreeBar body, + }); + + Future deleteStewardPurchasesOutSideOfTheProvince({ + required String token, + Map? queryParameters, + }); + + Future?> + getOutProvinceCarcassesBuyer({ + required String token, + Map? queryParameters, + }); + + Future createOutProvinceCarcassesBuyer({ + required String token, + required OutProvinceCarcassesBuyer body, + }); + + Future?> getStewardFreeSaleBar({ + required String token, + Map? queryParameters, + }); + + Future createOutProvinceStewardFreeBar({ + required String token, + required StewardFreeSaleBarRequest body, + }); + + Future updateOutProvinceStewardFreeBar({ + required String token, + required StewardFreeSaleBarRequest body, + }); + + Future deleteOutProvinceStewardFreeBar({ + required String token, + required String key, + }); + + Future getStewardSalesInfoDashboard({ + required String token, + Map? queryParameters, + }); + + Future getStewardRemainWeight({required String token}); +} diff --git a/packages/chicken/lib/features/steward/data/repositories/steward_repository_impl.dart b/packages/chicken/lib/features/steward/data/repositories/steward_repository_impl.dart new file mode 100644 index 0000000..cf20797 --- /dev/null +++ b/packages/chicken/lib/features/steward/data/repositories/steward_repository_impl.dart @@ -0,0 +1,287 @@ +import 'package:rasadyar_chicken/features/steward/data/datasources/remote/steward_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/dashboard_kill_house_free_bar/dashboard_kill_house_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/imported_loads_model/imported_loads_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/data/repositories/steward_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class StewardRepositoryImpl implements StewardRepository { + final StewardRemoteDataSource _remote; + + StewardRepositoryImpl(this._remote); + + @override + Future?> getWaitingArrivals({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getWaitingArrivals( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future setSateForArrivals({ + required String token, + required Map request, + }) async { + return await _remote.setSateForArrivals(token: token, request: request); + } + + @override + Future?> getImportedLoadsModel({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getImportedLoadsModel( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future?> getAllocatedMade({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getAllocatedMade( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future confirmAllocation({ + required String token, + required Map allocation, + }) async { + return await _remote.confirmAllocation( + token: token, + allocation: allocation, + ); + } + + @override + Future denyAllocation({ + required String token, + required String allocationToken, + }) async { + return await _remote.denyAllocation( + token: token, + allocationToken: allocationToken, + ); + } + + @override + Future confirmAllAllocation({ + required String token, + required List allocationTokens, + }) async { + return await _remote.confirmAllAllocation( + token: token, + allocationTokens: allocationTokens, + ); + } + + @override + Future postSubmitStewardAllocation({ + required String token, + required SubmitStewardAllocation request, + }) async { + return await _remote.postSubmitStewardAllocation( + token: token, + request: request, + ); + } + + @override + Future deleteStewardAllocation({ + required String token, + Map? queryParameters, + }) async { + return await _remote.deleteStewardAllocation( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future updateStewardAllocation({ + required String token, + required ConformAllocation request, + }) async { + return await _remote.updateStewardAllocation( + token: token, + request: request, + ); + } + + @override + Future getStewardDashboard({ + required String token, + required String stratDate, + required String endDate, + }) async { + return await _remote.getStewardDashboard( + token: token, + stratDate: stratDate, + endDate: endDate, + ); + } + + @override + Future getDashboardKillHouseFreeBar({ + required String token, + required String stratDate, + required String endDate, + }) async { + return await _remote.getDashboardKillHouseFreeBar( + token: token, + stratDate: stratDate, + endDate: endDate, + ); + } + + @override + Future?> + getStewardPurchasesOutSideOfTheProvince({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getStewardPurchasesOutSideOfTheProvince( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future createStewardPurchasesOutSideOfTheProvince({ + required String token, + required CreateStewardFreeBar body, + }) async { + return await _remote.createStewardPurchasesOutSideOfTheProvince( + token: token, + body: body, + ); + } + + @override + Future editStewardPurchasesOutSideOfTheProvince({ + required String token, + required CreateStewardFreeBar body, + }) async { + return await _remote.editStewardPurchasesOutSideOfTheProvince( + token: token, + queryParameters: body.toJson() + ..removeWhere((key, value) => value == null), + ); + } + + @override + Future deleteStewardPurchasesOutSideOfTheProvince({ + required String token, + Map? queryParameters, + }) async { + return await _remote.deleteStewardPurchasesOutSideOfTheProvince( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future?> + getOutProvinceCarcassesBuyer({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getOutProvinceCarcassesBuyer( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future createOutProvinceCarcassesBuyer({ + required String token, + required OutProvinceCarcassesBuyer body, + }) async { + return await _remote.createOutProvinceCarcassesBuyer( + token: token, + body: body, + ); + } + + @override + Future?> getStewardFreeSaleBar({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getStewardFreeSaleBar( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future createOutProvinceStewardFreeBar({ + required String token, + required StewardFreeSaleBarRequest body, + }) async { + return await _remote.createOutProvinceStewardFreeBar( + token: token, + body: body, + ); + } + + @override + Future updateOutProvinceStewardFreeBar({ + required String token, + required StewardFreeSaleBarRequest body, + }) async { + return await _remote.updateOutProvinceStewardFreeBar( + token: token, + body: body, + ); + } + + @override + Future deleteOutProvinceStewardFreeBar({ + required String token, + required String key, + }) async { + return await _remote.deleteOutProvinceStewardFreeBar( + token: token, + key: key, + ); + } + + @override + Future getStewardSalesInfoDashboard({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getStewardSalesInfoDashboard( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future getStewardRemainWeight({ + required String token, + }) async { + return await _remote.getStewardRemainWeight(token: token); + } +} diff --git a/packages/chicken/lib/features/steward/home/logic.dart b/packages/chicken/lib/features/steward/home/logic.dart index 5f56fe6..dfb28e6 100644 --- a/packages/chicken/lib/features/steward/home/logic.dart +++ b/packages/chicken/lib/features/steward/home/logic.dart @@ -1,12 +1,13 @@ -import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/bar_information/bar_information.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; import 'package:rasadyar_chicken/features/steward/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class HomeLogic extends GetxController { StewardRootLogic rootLogic = Get.find(); RxnInt totalWeightTodayBars = RxnInt(); - Rxn killHouseDistributionInfo = Rxn(); + Rxn killHouseDistributionInfo = + Rxn(); Rxn barInformation = Rxn(); RxList> inventoryItems = [ @@ -34,7 +35,6 @@ class HomeLogic extends GetxController { void onReady() { super.onReady(); refreshData(); - } Future refreshData() async { @@ -49,10 +49,11 @@ class HomeLogic extends GetxController { Future getGeneralBarsInformation() async { await safeCall( - call: () async => await rootLogic.chickenRepository.getGeneralBarInformation( - token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams(role: 'Steward'), - ), + call: () async => + await rootLogic.commonRepository.getGeneralBarInformation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams(role: 'Steward'), + ), onSuccess: (result) { if (result != null) { barInformation.value = result; @@ -64,14 +65,15 @@ class HomeLogic extends GetxController { Future getTodayBars() async { await safeCall( - call: () async => await rootLogic.chickenRepository.getGeneralBarInformation( - token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams( - fromDate: DateTime.now(), - toDate: DateTime.now(), - role: 'Steward', - ), - ), + call: () async => + await rootLogic.commonRepository.getGeneralBarInformation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + fromDate: DateTime.now(), + toDate: DateTime.now(), + role: 'Steward', + ), + ), onSuccess: (result) { if (result != null) { totalWeightTodayBars.value = result.totalBarsWeight?.toInt(); @@ -83,9 +85,10 @@ class HomeLogic extends GetxController { Future getDistributionInformation() async { await safeCall( - call: () async => await rootLogic.chickenRepository.getKillHouseDistributionInfo( - token: rootLogic.tokenService.accessToken.value!, - ), + call: () async => + await rootLogic.commonRepository.getKillHouseDistributionInfo( + token: rootLogic.tokenService.accessToken.value!, + ), onSuccess: (result) { if (result != null) { killHouseDistributionInfo.value = result; diff --git a/packages/chicken/lib/features/steward/home/view.dart b/packages/chicken/lib/features/steward/home/view.dart index 8cc6555..32c4d81 100644 --- a/packages/chicken/lib/features/steward/home/view.dart +++ b/packages/chicken/lib/features/steward/home/view.dart @@ -1,7 +1,8 @@ import 'package:flutter/cupertino.dart' hide LinearGradient; import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; -import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; += +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/steward/widely_used/view.dart'; import 'package:rasadyar_core/core.dart'; @@ -75,7 +76,10 @@ class HomePage extends GetView { AnimatedRotation( turns: 180, duration: Duration(milliseconds: 3000), - child: Icon(CupertinoIcons.chevron_up, size: 18), + child: Icon( + CupertinoIcons.chevron_up, + size: 18, + ), ), ], ), @@ -99,7 +103,9 @@ class HomePage extends GetView { Row( spacing: 8, mainAxisAlignment: MainAxisAlignment.end, - children: [Icon(CupertinoIcons.chevron_down, size: 18)], + children: [ + Icon(CupertinoIcons.chevron_down, size: 18), + ], ), _todayShipmentWidget(), _todayShipmentWidget2(), @@ -127,12 +133,17 @@ class HomePage extends GetView { Assets.vec.chicken2Svg.svg( width: 24.w, height: 24.h, - colorFilter: ColorFilter.mode(AppColor.blueDark, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + AppColor.blueDark, + BlendMode.srcIn, + ), ), Text( 'اطلاعات مرغ گرم', textAlign: TextAlign.right, - style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.iconColor, + ), ), ], ), @@ -151,7 +162,11 @@ class HomePage extends GetView { Row( children: [ SizedBox(width: 5.w), - Text('اطلاعات پخش', textAlign: TextAlign.right, style: AppFonts.yekan16), + Text( + 'اطلاعات پخش', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), ], ), SizedBox(height: 8.h), @@ -164,7 +179,8 @@ class HomePage extends GetView { title: 'وزن دولتی', titleBgColor: const Color(0xFFB8E7DC), valueBgColor: const Color(0xFFE6FAF5), - value: data.value?.totalGovernmentalInputWeight.separatedByComma, + value: + data.value?.totalGovernmentalInputWeight.separatedByComma, ), ), Expanded( @@ -178,7 +194,10 @@ class HomePage extends GetView { Expanded( child: broadcastItem( title: 'فروش دولتی', - value: data.value?.totalGovernmentalOutputWeight.separatedByComma, + value: data + .value + ?.totalGovernmentalOutputWeight + .separatedByComma, titleBgColor: const Color(0xFFEBC4CE), valueBgColor: const Color(0xFFEDDCE0), ), @@ -202,7 +221,10 @@ class HomePage extends GetView { Expanded( child: broadcastItem( title: 'مانده دولتی', - value: data.value?.totalGovernmentalRemainWeight.separatedByComma, + value: data + .value + ?.totalGovernmentalRemainWeight + .separatedByComma, titleBgColor: const Color(0xFFB8E7DC), valueBgColor: const Color(0xFFE6FAF5), ), @@ -218,7 +240,10 @@ class HomePage extends GetView { Expanded( child: broadcastItem( title: 'فروش خارج استان', - value: data.value?.totalStewardFreeSaleBarCarcassesWeight.separatedByComma, + value: data + .value + ?.totalStewardFreeSaleBarCarcassesWeight + .separatedByComma, titleBgColor: const Color(0xFFEBC4CE), valueBgColor: const Color(0xFFEDDCE0), ), @@ -242,7 +267,8 @@ class HomePage extends GetView { child: _informationIconCard( title: 'توزیع داخل استان', isLoading: data.value == null, - description: data.value?.freeSalesWeight.separatedByCommaFa ?? '0', + description: + data.value?.freeSalesWeight.separatedByCommaFa ?? '0', iconPath: Assets.vec.truckSvg.path, iconColor: const Color.fromRGBO(85, 97, 93, 1), bgDescriptionColor: const Color(0xFFE6FAF5), @@ -253,7 +279,9 @@ class HomePage extends GetView { child: _informationIconCard( title: 'توزیع خارج استان', isLoading: data.value == null, - description: data.value?.stewardAllocationsWeight.separatedByCommaFa ?? '0', + description: + data.value?.stewardAllocationsWeight.separatedByCommaFa ?? + '0', iconPath: Assets.vec.truckFastSvg.path, iconColor: Color(0xFF647379), bgDescriptionColor: const Color(0xFFEAEFFF), @@ -302,7 +330,9 @@ class HomePage extends GetView { child: _informationLabelCard( title: 'خارج استان', isLoading: data.value == null, - description: data.value?.freeBuyingCarcassesWeight.separatedByCommaFa ?? '0', + description: + data.value?.freeBuyingCarcassesWeight.separatedByCommaFa ?? + '0', iconPath: Assets.vec.cubeSearchSvg.path, iconColor: Color(0xFF2D5FFF), bgLabelColor: const Color(0xFFAFCBFF), @@ -326,7 +356,8 @@ class HomePage extends GetView { child: _informationLabelCard( title: 'مانده انبار', isLoading: data.value == null, - description: data.value?.totalRemainWeight.separatedByCommaFa ?? '0', + description: + data.value?.totalRemainWeight.separatedByCommaFa ?? '0', iconPath: Assets.vec.cubeSearchSvg.path, bgDescriptionColor: const Color(0xFFEAEFFF), bgLabelColor: const Color(0xFFBDD4FF), @@ -337,7 +368,8 @@ class HomePage extends GetView { child: _informationLabelCard( title: 'توزیع شده', isLoading: data.value == null, - description: data.value?.realAllocatedWeight.separatedByCommaFa ?? '0', + description: + data.value?.realAllocatedWeight.separatedByCommaFa ?? '0', iconPath: Assets.vec.cubeRotateSvg.path, iconColor: Color(0xFF5C4D64), bgLabelColor: Color(0xFFC8B8D1), @@ -375,7 +407,10 @@ class HomePage extends GetView { child: Assets.vec.cubeScanSvg.svg( width: 12.w, height: 12.h, - colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), + colorFilter: const ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), ), ), bgDescriptionColor: Colors.white, @@ -395,7 +430,8 @@ class HomePage extends GetView { title: 'درانتظار', borderColor: const Color(0xFF9758FF), isLoading: data.value == null, - description: data.value?.totalNotEnteredBars.separatedByCommaFa ?? '0', + description: + data.value?.totalNotEnteredBars.separatedByCommaFa ?? '0', unit: '(${data.value?.totalNotEnteredKillHouseRequestsWeight.separatedByCommaFa})\nکیلوگرم', icon: Container( @@ -409,7 +445,10 @@ class HomePage extends GetView { child: Assets.vec.cubeCardFreeSvg.svg( width: 12.w, height: 12.h, - colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn), + colorFilter: const ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), ), ), bgDescriptionColor: Colors.white, @@ -437,7 +476,12 @@ class HomePage extends GetView { child: _informationLabelCard( title: 'مانده دولتی', isLoading: data.value == null, - description: data.value?.totalGovernmentalRemainWeight?.separatedByCommaFa ?? '0', + description: + data + .value + ?.totalGovernmentalRemainWeight + ?.separatedByCommaFa ?? + '0', iconPath: Assets.vec.cubeCardGovermentSvg.path, iconColor: AppColor.textColor, bgDescriptionColor: const Color(0xFFF5ECEE), @@ -448,7 +492,8 @@ class HomePage extends GetView { child: _informationLabelCard( title: 'مانده آزاد', isLoading: data.value == null, - description: data.value?.totalFreeRemainWeight.separatedByCommaFa ?? '0', + description: + data.value?.totalFreeRemainWeight.separatedByCommaFa ?? '0', unit: 'کیلوگرم', iconPath: Assets.vec.cubeCardFreeSvg.path, iconColor: AppColor.textColor, @@ -496,7 +541,10 @@ class HomePage extends GetView { ), Divider(), - inventoryListItem(title: 'کل فروش', value: model.realAllocatedWeight?.separatedByComma), + inventoryListItem( + title: 'کل فروش', + value: model.realAllocatedWeight?.separatedByComma, + ), Divider(), inventoryListItem( title: 'مانده انبار', @@ -515,14 +563,25 @@ class HomePage extends GetView { children: [ Text( title, - style: AppFonts.yekan14.copyWith(color: const Color(0xFF353535), height: 1.2), + style: AppFonts.yekan14.copyWith( + color: const Color(0xFF353535), + height: 1.2, + ), ), Spacer(), value == null ? Center(child: CupertinoActivityIndicator()) - : Text(value, style: AppFonts.yekan14.copyWith(color: const Color(0xFF353535))), + : Text( + value, + style: AppFonts.yekan14.copyWith( + color: const Color(0xFF353535), + ), + ), SizedBox(width: 20.w), - Text('کیلوگرم', style: AppFonts.yekan10.copyWith(color: const Color(0xFF353535))), + Text( + 'کیلوگرم', + style: AppFonts.yekan10.copyWith(color: const Color(0xFF353535)), + ), ], ), ); @@ -546,7 +605,9 @@ class HomePage extends GetView { height: 65.h, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), - border: borderColor != null ? Border.all(width: 1, color: borderColor) : null, + border: borderColor != null + ? Border.all(width: 1, color: borderColor) + : null, ), clipBehavior: Clip.hardEdge, child: Row( @@ -605,12 +666,16 @@ class HomePage extends GetView { Text( description, textAlign: TextAlign.right, - style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive), + style: AppFonts.yekan16.copyWith( + color: AppColor.mediumGreyDarkActive, + ), ), Text( unit, textAlign: TextAlign.center, - style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive), + style: AppFonts.yekan12.copyWith( + color: AppColor.mediumGreyDarkActive, + ), ), ], ), @@ -656,7 +721,9 @@ class HomePage extends GetView { Text( title, textAlign: TextAlign.right, - style: AppFonts.yekan14.copyWith(color: AppColor.mediumGreyDarkActive), + style: AppFonts.yekan14.copyWith( + color: AppColor.mediumGreyDarkActive, + ), ), isLoading @@ -664,12 +731,16 @@ class HomePage extends GetView { : Text( description, textAlign: TextAlign.right, - style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive), + style: AppFonts.yekan16.copyWith( + color: AppColor.mediumGreyDarkActive, + ), ), Text( unit, textAlign: TextAlign.center, - style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive), + style: AppFonts.yekan12.copyWith( + color: AppColor.mediumGreyDarkActive, + ), ), ], ), @@ -729,8 +800,14 @@ class HomePage extends GetView { 'کل ورودی به انبار (کیلوگرم)', model.totalFreeBarsCarcassesWeight.toString(), ), - buildRow('کل فروش (کیلوگرم)', model.realAllocatedWeight.toString()), - buildRow('مانده انبار (کیلوگرم)', model.totalRemainWeight.toString()), + buildRow( + 'کل فروش (کیلوگرم)', + model.realAllocatedWeight.toString(), + ), + buildRow( + 'مانده انبار (کیلوگرم)', + model.totalRemainWeight.toString(), + ), ], ), ), @@ -749,7 +826,9 @@ class HomePage extends GetView { child: Text( title, textAlign: TextAlign.right, - style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDarkHover, + ), ), ), Flexible( @@ -757,7 +836,9 @@ class HomePage extends GetView { child: Text( value, textAlign: TextAlign.center, - style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDarkHover, + ), ), ), ], @@ -783,7 +864,9 @@ class HomePage extends GetView { Text( 'اطلاعات ارسالی', textAlign: TextAlign.right, - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), ), const SizedBox(height: 12), buildRow( @@ -816,7 +899,10 @@ class HomePage extends GetView { return Container( height: height?.h ?? 73.h, clipBehavior: Clip.hardEdge, - decoration: BoxDecoration(color: valueBgColor, borderRadius: BorderRadius.circular(8)), + decoration: BoxDecoration( + color: valueBgColor, + borderRadius: BorderRadius.circular(8), + ), child: Column( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -829,7 +915,9 @@ class HomePage extends GetView { Text( title ?? 'بدون تیتر', textAlign: TextAlign.center, - style: titleStyle ?? AppFonts.yekan12.copyWith(color: const Color(0xFF3E3E3E)), + style: + titleStyle ?? + AppFonts.yekan12.copyWith(color: const Color(0xFF3E3E3E)), ), ], ), @@ -842,7 +930,9 @@ class HomePage extends GetView { child: Text( value, textAlign: TextAlign.right, - style: valueStyle ?? AppFonts.yekan14.copyWith(color: AppColor.textColor), + style: + valueStyle ?? + AppFonts.yekan14.copyWith(color: AppColor.textColor), ), ) : Center(child: CupertinoActivityIndicator()), @@ -850,7 +940,9 @@ class HomePage extends GetView { Text( unit ?? 'کیلوگرم', textAlign: TextAlign.center, - style: unitStyle ?? AppFonts.yekan10.copyWith(color: Color(0xFF717171)), + style: + unitStyle ?? + AppFonts.yekan10.copyWith(color: Color(0xFF717171)), ), SizedBox(height: 4.h), ], @@ -902,19 +994,29 @@ class HomePage extends GetView { Row( children: [ SizedBox(width: 5.w), - Text('تعهدات', textAlign: TextAlign.right, style: AppFonts.yekan16), + Text( + 'تعهدات', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), ], ), commitmentsItemList( title: 'تعهد دولتی توزیع داخل استان', - value: data.value?.totalCommitmentSellingInProvinceGovernmentalWeight.separatedByComma, + value: data + .value + ?.totalCommitmentSellingInProvinceGovernmentalWeight + .separatedByComma, labelColor: const Color(0xFFB9E8DC), bgColor: const Color(0xFFF3F9F8), ), commitmentsItemList( title: 'توزیع دولتی داخل استان', - value: data.value?.totalSellingInProvinceGovernmentalWeight.separatedByComma, + value: data + .value + ?.totalSellingInProvinceGovernmentalWeight + .separatedByComma, labelColor: const Color(0xFFC3D4F3), bgColor: const Color(0xFFECF3FF), ), @@ -929,19 +1031,26 @@ class HomePage extends GetView { ), commitmentsItemList( title: 'تعهد آزاد توزیع داخل استان', - value: data.value?.totalCommitmentSellingInProvinceFreeWeight.separatedByComma, + value: data + .value + ?.totalCommitmentSellingInProvinceFreeWeight + .separatedByComma, labelColor: const Color(0xFFC7DADA), bgColor: const Color(0xFFE5F7F7), ), commitmentsItemList( title: 'توزیع آزاد داخل استان', - value: data.value?.totalSellingInProvinceFreeWeight.separatedByComma, + value: + data.value?.totalSellingInProvinceFreeWeight.separatedByComma, labelColor: const Color(0xFFE0D6ED), bgColor: const Color(0xFFF5EDFF), ), commitmentsItemList( title: 'باقیمانده تعهد آزاد توزیع داخل استان', - value: data.value?.totalCommitmentSellingInProvinceFreeRemainWeight.separatedByComma, + value: data + .value + ?.totalCommitmentSellingInProvinceFreeRemainWeight + .separatedByComma, labelColor: const Color(0xFFEBC5CE), bgColor: const Color(0xFFFFF1F4), ), @@ -986,7 +1095,9 @@ class HomePage extends GetView { : Text( value, textAlign: TextAlign.right, - style: AppFonts.yekan16.copyWith(color: AppColor.textColor), + style: AppFonts.yekan16.copyWith( + color: AppColor.textColor, + ), ), SizedBox(width: 8.w), diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/buy/logic.dart new file mode 100644 index 0000000..61ae021 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy/logic.dart @@ -0,0 +1,36 @@ +import 'package:flutter/services.dart'; +import 'package:rasadyar_core/core.dart'; + +class BuyLogic extends GetxController { + List routesName = ['خرید']; + DateTime? _lastBackPressed; + + + @override + void onReady() { + fLog('BuyLogic onReady'); + super.onReady(); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + } + + void onPopScopTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy/view.dart b/packages/chicken/lib/features/steward/presentation/pages/buy/view.dart new file mode 100644 index 0000000..5e2b372 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy/view.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class BuyPage extends GetView { + const BuyPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + isBase: true, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 21.w, + children: [ + GlassMorphismCardIcon( + title: 'خرید داخل استان', + vecIcon: Assets.vec.map1Svg.path, + gradient: LinearGradient( + colors: [Color(0xFF00E096), Color(0xFF007D5E)], + stops: [0.0, 0.95], + begin: AlignmentGeometry.topLeft, + end: AlignmentGeometry.bottomRight, + ), + onTap: () { + Get.toNamed( + StewardRoutes.buysInProvinceSteward, + id: stewardFirstKey, + ); + }, + ), + GlassMorphismCardIcon( + title: 'خرید خارج استان', + vecIcon: Assets.vec.buyOutProvinceSvg.path, + gradient: LinearGradient( + colors: [Color(0xFF00E096), Color(0xFF007D5E)], + stops: [0.0, 0.95], + begin: AlignmentGeometry.topLeft, + end: AlignmentGeometry.bottomRight, + ), + onTap: () { + Get.toNamed( + StewardRoutes.buysOutOfProvinceSteward, + id: stewardFirstKey, + ); + }, + ), + ], + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_in_province/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province/logic.dart new file mode 100644 index 0000000..55e13f6 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province/logic.dart @@ -0,0 +1,96 @@ +<<<<<<<< HEAD:packages/chicken/lib/features/steward/buy_in_province/logic.dart +import 'package:rasadyar_chicken/features/steward/buy/logic.dart'; +import 'package:rasadyar_chicken/features/steward/buy_in_province_all/logic.dart'; +import 'package:rasadyar_chicken/features/steward/buy_in_province_waiting/logic.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_all/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_waiting/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/buy_in_province/logic.dart +import 'package:rasadyar_core/core.dart'; + +class BuyInProvinceLogic extends GetxController { + RxList routesName = RxList(); + RxList isExpandedList = [].obs; + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + StewardRootLogic rootLogic = Get.find(); + + BuyLogic get buyLogic => Get.find(); + RxInt selectedSegmentIndex = 0.obs; + + BuyInProvinceAllLogic buyAllLogic = Get.find(); + BuyInProvinceWaitingLogic buyWaitingLogic = Get.find(); + + @override + void onInit() { + super.onInit(); + routesName.value = [...buyLogic.routesName, 'داخل استان'].toList(); + routesName.add(selectedSegmentIndex.value == 0 ? 'در انتظار' : 'کل خریدها'); + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'در انتظار' : 'کل خریدها'); + }); + + ever(fromDateFilter, (callback) => _setFromDateFilter(callback)); + ever(toDateFilter, (callback) => _setToDateFilter(callback)); + } + + @override + void onReady() { + fLog('BuyInProvinceLogic onReady'); + super.onReady(); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + } + + void _setFromDateFilter(Jalali jalali) { + final isWaiting = selectedSegmentIndex.value == 0; + if (isWaiting) { + buyWaitingLogic.fromDateFilter.value = fromDateFilter.value; + } else { + buyAllLogic.fromDateFilter.value = fromDateFilter.value; + } + } + + void _setToDateFilter(Jalali jalali) { + final isWaiting = selectedSegmentIndex.value == 0; + if (isWaiting) { + buyWaitingLogic.toDateFilter.value = fromDateFilter.value; + } else { + buyAllLogic.toDateFilter.value = fromDateFilter.value; + } + } + + Future submitFilter() async { + final isWaiting = selectedSegmentIndex.value == 0; + if (isWaiting) { + buyWaitingLogic.getWaitingArrivals(); + } else { + buyAllLogic.getAllArrivals(); + } + } + + void setSearchValue(String? data) { + searchedValue.value = data?.trim(); + final isWaiting = selectedSegmentIndex.value == 0; + if (isWaiting) { + buyWaitingLogic.searchedValue.value = searchedValue.value; + } else { + buyAllLogic.searchedValue.value = searchedValue.value; + } + } + + Future onRefresh() async { + await rootLogic.onRefresh(); + await Future.wait([buyWaitingLogic.getWaitingArrivals(), buyAllLogic.getAllArrivals()]); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_in_province/view.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province/view.dart new file mode 100644 index 0000000..817ce5c --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province/view.dart @@ -0,0 +1,153 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/buy_in_province/view.dart +import 'package:rasadyar_chicken/features/steward/buy_in_province_all/view.dart'; +import 'package:rasadyar_chicken/features/steward/buy_in_province_waiting/view.dart'; +======== +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_all/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_waiting/view.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/buy_in_province/view.dart +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class BuyInProvincePage extends GetView { + const BuyInProvincePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + onSearchChanged: (data) => controller.setSearchValue(data), + hasBack: true, + backId: stewardFirstKey, + + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + child: Column( + children: [ + Obx(() { + var list = [ + InventoryItemData( + title: 'موجودی انبار', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalRemainWeight + ?.separatedByCommaFa, + color: const Color(0xFFEAFBFC), + ), + InventoryItemData( + title: 'مانده دولتی', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalGovernmentalRemainWeight + ?.separatedByCommaFa, + + color: const Color(0xFFF5ECEE), + ), + InventoryItemData( + title: 'مانده آزاد', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalFreeRemainWeight + ?.separatedByCommaFa, + + color: const Color(0xFFF1E7FF), + ), + ]; + + return InventoryWidget(inventoryModel: list); + }), + + segmentWidget(), + ObxValue((index) { + return Expanded( + child: index.value == 0 + ? BuyInProvinceWaitingPage() + : BuyInProvinceAllPage(), + ); + }, controller.selectedSegmentIndex), + ], + ), + ); + } + + Padding segmentWidget() { + return Padding( + padding: const EdgeInsets.fromLTRB(8, 0, 8, 8), + child: Row( + children: [ + Expanded( + child: RSegment( + children: ['در انتظار', 'کل خریدها'], + selectedIndex: 0, + borderColor: const Color(0xFFB4B4B4), + selectedBorderColor: AppColor.blueNormal, + selectedBackgroundColor: AppColor.blueLight, + onSegmentSelected: (index) => + controller.selectedSegmentIndex.value = index, + backgroundColor: AppColor.whiteGreyNormal, + ), + ), + ], + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + + RElevated( + text: 'اعمال فیلتر', + + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.submitFilter(); + Get.back(); + }, + height: 40, + ), + SizedBox(height: 16), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_all/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_all/logic.dart new file mode 100644 index 0000000..ae5faff --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_all/logic.dart @@ -0,0 +1,194 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/buy_in_province_all/logic.dart +import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart'; +import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_allocation/steward_allocation_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/buy_in_province_all/logic.dart +import 'package:rasadyar_core/core.dart'; + +class BuyInProvinceAllLogic extends GetxController { + RxInt isExpandedListIndex = (-1).obs; + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + RxMap isLoadingConfirmMap = RxMap(); + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + + StewardRootLogic rootLogic = Get.find(); + + Rx>> allProduct = + Resource>.loading().obs; + + TextEditingController weightController = TextEditingController(); + TextEditingController countController = TextEditingController(); + TextEditingController lossController = TextEditingController(); + TextEditingController approvedWithOtpController = TextEditingController(); + + RxBool approvedWithOtpCode = false.obs; + + @override + void onInit() { + super.onInit(); + getAllArrivals(); + } + + @override + void onReady() { + debounce( + searchedValue, + (callback) => getAllArrivals(), + time: Duration(milliseconds: 2000), + ); + super.onReady(); + ever(approvedWithOtpCode, (callback) { + if (callback == false) { + approvedWithOtpController.clear(); + } + }); + } + + Future getAllArrivals([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + allProduct.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await rootLogic.stewardRepository.getWaitingArrivals( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'all'}, + pageSize: 20, + page: currentPage.value, + search: 'filter', + role: 'Steward', + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + ), + ), + onSuccess: (res) async { + await Future.delayed(Duration(milliseconds: 200)); + if ((res?.count ?? 0) == 0) { + allProduct.value = + Resource>.empty(); + } else { + allProduct.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(allProduct.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future acceptEntries(WaitingArrivalModel model) async { + var request = StewardAllocationRequest( + allocationKey: model.key, + checkAllocation: true, + state: 'accepted', + receiverRealNumberOfCarcasses: model.realNumberOfCarcasses ?? 0, + receiverRealWeightOfCarcasses: model.realWeightOfCarcasses?.toInt() ?? 0, + registrationCode: approvedWithOtpCode.value + ? int.parse(approvedWithOtpController.text) + : null, + weightLossOfCarcasses: model.weightLossOfCarcasses?.toInt() ?? 0, + ).toJson(); + request.removeWhere((key, value) => value == null); + + safeCall( + showError: true, + call: () async => await rootLogic.stewardRepository.setSateForArrivals( + token: rootLogic.tokenService.accessToken.value!, + request: request, + ), + onSuccess: (result) { + getAllArrivals(); + rootLogic.onRefresh(); + clearApprovedController(); + toggleExpansion(); + Get.back(); + }, + ); + } + + Future denyEntries(WaitingArrivalModel model) async { + var request = StewardAllocationRequest( + allocationKey: model.key, + checkAllocation: true, + state: 'rejected', + ).toJson(); + request.removeWhere((key, value) => value == null); + + safeCall( + call: () async => await rootLogic.stewardRepository.setSateForArrivals( + token: rootLogic.tokenService.accessToken.value!, + request: request, + ), + onError: (error, stackTrace) { + eLog(error); + }, + onSuccess: (result) { + getAllArrivals(); + rootLogic.onRefresh(); + }, + ); + } + + String getVecPathItem(String? item) { + switch (item) { + case 'pending': + return Assets.vec.timerSvg.path; + case 'accepted': + return Assets.vec.checkSquareSvg.path; + case 'rejected': + return Assets.vec.closeCircleSvg.path; + default: + return Assets.vec.timerSvg.path; + } + } + + void clearApprovedController() { + weightController.clear(); + countController.clear(); + lossController.clear(); + approvedWithOtpController.clear(); + approvedWithOtpCode.value = false; + } + + void toggleExpansion({int? index}) { + if (isExpandedListIndex.value == index || index == null) { + isExpandedListIndex.value = -1; + } else { + isExpandedListIndex.value = index; + } + } + + Color getLabelColor(String? receiverState) { + if (receiverState == 'pending') { + return AppColor.yellowNormal2; + } + return AppColor.mediumGreyDarkHover; + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_all/view.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_all/view.dart new file mode 100644 index 0000000..9717a4b --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_all/view.dart @@ -0,0 +1,425 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class BuyInProvinceAllPage extends GetView { + const BuyInProvinceAllPage({super.key}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value == index, + onTap: () => controller.toggleExpansion(index: index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: getLabelColor(item.receiverState), + labelIcon: controller.getVecPathItem(item.receiverState), + labelIconColor: controller.getLabelColor(item.receiverState), + ); + }, controller.isExpandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getAllArrivals(true), + ); + }, controller.allProduct), + ); + } + + Row itemListWidget(WaitingArrivalModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.toSteward?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.date?.formattedJalaliDate ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 6, + children: [ + Visibility( + visible: item.product?.name?.contains('مرغ گرم') ?? false, + child: Assets.vec.hotChickenSvg.svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode( + AppColor.blueNormal, + BlendMode.srcIn, + ), + ), + ), + Text( + item.weightOfCarcasses?.separatedByCommaFa.addKg ?? 'N/A', + textAlign: TextAlign.left, + textDirection: TextDirection.ltr, + style: AppFonts.yekan12Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + + Text( + item.toSteward?.guildsName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } + + Container itemListExpandedWidget(WaitingArrivalModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.toSteward?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + Text( + item.receiverState?.faItem ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.darkGreyDark), + ), + SizedBox(width: 7), + SvgGenImage.vec( + controller.getVecPathItem(item.receiverState), + ).svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode( + AppColor.darkGreyDark, + BlendMode.srcIn, + ), + ), + ], + ), + 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( + item.date?.toJalali.formatter.wN ?? 'N/A', + style: AppFonts.yekan14.copyWith( + color: AppColor.textColor, + ), + ), + + Text( + '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'N/A'}', + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + + Text( + '${item.date?.toJalali.formatter.y}', + style: AppFonts.yekan20.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'مشخصات فروشنده', + value: item.toSteward?.user?.fullname ?? 'N/A', + ), + buildRow( + title: 'تلفن فروشنده', + value: item.toSteward?.user?.mobile ?? 'N/A', + valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + buildRow( + title: 'نوع تخصیص', + value: item.allocationType?.faAllocationType ?? 'N/A', + ), + buildRow(title: ' سهمیه', value: item.quota?.faTitle ?? 'N/A'), + buildRow(title: 'محصول', value: item.product?.name ?? 'N/A'), + buildRow( + title: 'وزن خریداری شده', + value: item.weightOfCarcasses?.separatedByCommaFa ?? 'N/A', + valueLabel: 'کیلوگرم', + ), + buildRow( + title: 'قیمت هر کیلوگرم', + titleLabel: (item.approvedPriceStatus ?? false) ? 'مصوب' : 'آزاد', + titleLabelStyle: AppFonts.yekan14Bold.copyWith( + color: AppColor.greenNormal, + ), + value: item.amount?.separatedByCommaFa ?? 'N/A', + valueLabel: 'ریال', + ), + buildRow( + title: 'قیمت کل', + value: item.totalAmount?.separatedByCommaFa ?? 'N/A', + valueLabel: 'ریال', + ), + + Visibility( + visible: item.receiverState == 'pending', + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + ObxValue((data) { + return RElevated( + text: 'تایید', + width: 150.w, + height: 40.h, + isLoading: data[item.key!] ?? false, + onPressed: () async { + await Get.bottomSheet( + conformationBottomSheet(item), + isScrollControlled: true, + ).then((value) { + Get.back(); + controller.clearApprovedController(); + }); + }, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ); + }, controller.isLoadingConfirmMap), + ROutlinedElevated( + text: 'رد', + textStyle: AppFonts.yekan20.copyWith( + color: AppColor.redNormal, + ), + width: 150.w, + height: 40.h, + onPressed: () { + buildWarningDialog( + title: 'اخطار', + middleText: 'آیا از رد شدن این مورد اطمینان دارید؟', + onConfirm: () => controller.denyEntries(item), + onRefresh: () => controller.getAllArrivals(), + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ), + ], + ), + ); + } + + Color getLabelColor(String? item) { + switch (item) { + case 'pending': + return AppColor.blueLight; + case 'accepted': + return AppColor.greenLightHover; + case 'rejected': + return AppColor.redLightHover; + default: + return AppColor.blueLight; + } + } + + Widget conformationBottomSheet(WaitingArrivalModel item) { + controller.weightController.text = item.weightOfCarcasses.separatedByComma; + return BaseBottomSheet( + height: 430.h, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + RTextField( + label: 'وزن(کیلوگرم)', + controller: controller.weightController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + SizedBox(height: 16.h), + RTextField( + label: 'حجم(قطعه)', + controller: controller.countController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + SizedBox(height: 16.h), + RTextField( + label: 'افت وزن(کیلوگرم)', + controller: controller.lossController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + SizedBox(height: 16.h), + + Text( + 'تایید ', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor), + ), + ObxValue((data) { + return Column( + children: [ + RadioGroup( + groupValue: data.value, + onChanged: (value) { + controller.approvedWithOtpCode.value = value ?? false; + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + radioRow( + value: true, + label: ' با کد احراز', + onTap: () { + controller.approvedWithOtpCode.value = true; + }, + ), + radioRow( + value: false, + label: 'بدون کد احراز', + onTap: () { + controller.approvedWithOtpCode.value = false; + }, + ), + ], + ), + ), + Visibility( + child: RTextField( + controller: controller.approvedWithOtpController, + label: 'کد احراز', + keyboardType: TextInputType.number, + ), + visible: data.value, + ), + ], + ); + }, controller.approvedWithOtpCode), + SizedBox(height: 30.h), + ObxValue((data) { + return RElevated( + enabled: controller.approvedWithOtpCode.value + ? controller.approvedWithOtpController.text.isNotEmpty + : true, + text: 'تایید', + onPressed: () async { + await controller.acceptEntries(item); + }, + isFullWidth: true, + ); + }, controller.approvedWithOtpCode), + SizedBox(height: 20.h), + ], + ), + ); + } + + Widget radioRow({ + required bool value, + required String label, + TextStyle? textStyle, + GestureTapCallback? onTap, + }) { + return GestureDetector( + onTap: onTap, + child: Row( + children: [ + Radio(value: value), + Text( + label, + style: + textStyle ?? + AppFonts.yekan16.copyWith(color: AppColor.textColor), + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_waiting/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_waiting/logic.dart new file mode 100644 index 0000000..c3c651c --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_waiting/logic.dart @@ -0,0 +1,199 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/buy_in_province_waiting/logic.dart +import 'package:rasadyar_chicken/data/models/request/steward_allocation/steward_allocation_request.dart'; +import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_allocation/steward_allocation_request.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/buy_in_province_waiting/logic.dart +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class BuyInProvinceWaitingLogic extends GetxController { + RxInt isExpandedListIndex = (-1).obs; + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + RxMap isLoadingConfirmMap = RxMap(); + Rx bgConfirmAllColor = AppColor.blueNormal.obs; + RxInt currentPage = 1.obs; + final RxBool isLoadingMoreAllocationsMade = false.obs; + StewardRootLogic rootLogic = Get.find(); + RxBool isButtonConfirm = false.obs; + + Rx>> waitingProduct = + Resource>.loading().obs; + + TextEditingController weightController = TextEditingController(); + TextEditingController countController = TextEditingController(); + TextEditingController lossController = TextEditingController(); + TextEditingController approvedWithOtpController = TextEditingController(); + + RxBool approvedWithOtpCode = false.obs; + + @override + void onInit() { + super.onInit(); + debounce( + searchedValue, + (callback) => getWaitingArrivals(), + time: Duration(milliseconds: timeDebounce), + ); + } + + @override + void onReady() { + super.onReady(); + getWaitingArrivals(); + approvedWithOtpController.addListener(() { + isButtonConfirm.value = approvedWithOtpController.text.trim().length > 4; + }); + } + + void setSearchValue(String? data) { + searchedValue.value = data?.trim(); + } + + Future getWaitingArrivals([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + waitingProduct.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await rootLogic.stewardRepository.getWaitingArrivals( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'not_entered'}, + pageSize: 20, + page: currentPage.value, + search: 'filter', + role: 'Steward', + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + ), + ), + onSuccess: (res) async { + await Future.delayed(Duration(milliseconds: 200)); + if ((res?.count ?? 0) == 0) { + waitingProduct.value = + Resource>.empty(); + } else { + waitingProduct.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(waitingProduct.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + flashingFabBgColor(); + } + }, + ); + } + + Future acceptEntries(WaitingArrivalModel model) async { + var request = StewardAllocationRequest( + allocationKey: model.key, + checkAllocation: true, + state: 'accepted', + receiverRealNumberOfCarcasses: model.realNumberOfCarcasses ?? 0, + receiverRealWeightOfCarcasses: model.realWeightOfCarcasses?.toInt() ?? 0, + registrationCode: approvedWithOtpCode.value + ? int.parse(approvedWithOtpController.text.trim()) + : null, + weightLossOfCarcasses: model.weightLossOfCarcasses?.toInt() ?? 0, + stewardCheckAllocation: true, + ).toJson(); + request.removeWhere((key, value) => value == null); + + safeCall( + showError: true, + showSuccess: true, + call: () async => await rootLogic.stewardRepository.setSateForArrivals( + token: rootLogic.tokenService.accessToken.value!, + request: request, + ), + onError: (error, stackTrace) { + eLog(error); + }, + onSuccess: (result) { + getWaitingArrivals(); + rootLogic.onRefresh(); + clearApprovedController(); + toggleExpansion(); + Future.delayed(Duration(seconds: 3), () { + Get.back(); + Get.back(); + }); + }, + ); + } + + Future denyEntries(WaitingArrivalModel model) async { + var request = StewardAllocationRequest( + allocationKey: model.key, + checkAllocation: true, + state: 'rejected', + ).toJson(); + request.removeWhere((key, value) => value == null); + + safeCall( + call: () async => await rootLogic.stewardRepository.setSateForArrivals( + token: rootLogic.tokenService.accessToken.value!, + request: request, + ), + onError: (error, stackTrace) { + eLog(error); + }, + onSuccess: (result) { + getWaitingArrivals(); + rootLogic.onRefresh(); + }, + ); + } + + void flashingFabBgColor() { + Timer.periodic(Duration(seconds: 2), (timer) { + if (bgConfirmAllColor.value == AppColor.blueNormal) { + bgConfirmAllColor.value = AppColor.blueLightHover; + } else { + bgConfirmAllColor.value = AppColor.blueNormal; + } + }); + } + + void clearApprovedController() { + weightController.clear(); + countController.clear(); + lossController.clear(); + approvedWithOtpController.clear(); + approvedWithOtpCode.value = false; + } + + void toggleExpansion({int? index}) { + if (isExpandedListIndex.value == index || index == null) { + isExpandedListIndex.value = -1; + } else { + isExpandedListIndex.value = index; + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_waiting/view.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_waiting/view.dart new file mode 100644 index 0000000..4e7a294 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_in_province_waiting/view.dart @@ -0,0 +1,416 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart'; +import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class BuyInProvinceWaitingPage extends GetView { + const BuyInProvinceWaitingPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: controller.isExpandedListIndex.value == index, + onTap: () => controller.toggleExpansion(index: index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.timerSvg.path, + labelIconColor: AppColor.yellowNormal2, + ); + }, controller.isExpandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getWaitingArrivals(true), + ); + }, controller.waitingProduct), + ), + ); + } + + Row itemListWidget(WaitingArrivalModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + '${controller.rootLogic.isKillHouse(item) ? 'کشتارگاه' : 'مباشر'} ${controller.rootLogic.isKillHouse(item) ? item.killHouse?.name : item.steward?.user?.fullname} ', + textAlign: TextAlign.start, + overflow: TextOverflow.ellipsis, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.date?.formattedJalaliDate ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 6, + children: [ + Visibility( + visible: item.product?.name?.contains('مرغ گرم') ?? false, + child: Assets.vec.hotChickenSvg.svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode( + AppColor.blueNormal, + BlendMode.srcIn, + ), + ), + ), + Text( + item.weightOfCarcasses?.separatedByCommaFa.addKg ?? 'ندارد', + textAlign: TextAlign.left, + textDirection: TextDirection.ltr, + style: AppFonts.yekan12Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + Text( + '${item.amount?.separatedByCommaFa} ریال', + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 3, + children: [ + Text( + (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد', + style: AppFonts.yekan12Bold.copyWith( + color: (item.approvedPriceStatus ?? false) + ? AppColor.blueNormal + : AppColor.greenNormal, + ), + ), + ], + ), + ), + ], + ); + } + + Container itemListExpandedWidget(WaitingArrivalModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + '${controller.rootLogic.isKillHouse(item) ? item.killHouse?.name : item.steward?.user?.fullname} ', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + Text( + 'در انتظار', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.darkGreyDark), + ), + SizedBox(width: 7), + Assets.vec.clockSvg.svg(width: 16.w, height: 16.h), + ], + ), + 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( + item.date?.toJalali.formatter.wN ?? 'ندارد', + style: AppFonts.yekan14.copyWith( + color: AppColor.textColor, + ), + ), + + Text( + '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + + Text( + '${item.date?.toJalali.formatter.y}', + style: AppFonts.yekan20.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'مشخصات فروشنده', + value: + '${controller.rootLogic.isKillHouse(item) ? item.killHouse?.killHouseOperator?.user?.fullname : item.steward?.user?.fullname} ', + ), + buildRow( + title: 'تلفن فروشنده', + value: + '${controller.rootLogic.isKillHouse(item) ? item.killHouse?.killHouseOperator?.user?.mobile : item.steward?.user?.mobile} ', + valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + buildRow( + title: 'نوع تخصیص', + value: item.allocationType?.faAllocationType ?? 'ندارد', + ), + buildRow(title: ' سهمیه', value: item.quota?.faTitle ?? 'ندارد'), + buildRow( + title: 'نوع فروش', + value: item.saleType == "governmental" ? 'دولتی' : 'آزاد', + ), + buildRow(title: 'محصول', value: item.product?.name ?? 'ندارد'), + buildRow( + title: 'تاریخ تولید گوشت', + value: item.productionDate?.toJalali.toJalaliDateTime() ?? 'ندارد', + ), + buildRow( + title: 'وزن خریداری شده', + value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم', + ), + buildRow( + title: 'قیمت هر کیلوگرم', + titleLabel: (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد', + titleLabelStyle: AppFonts.yekan14Bold.copyWith( + color: AppColor.greenNormal, + ), + value: '${item.amount?.separatedByCommaFa} ریال', + ), + + buildRow( + title: 'قیمت کل', + value: '${item.totalAmount?.separatedByCommaFa} ریال', + ), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + ObxValue((data) { + return RElevated( + text: 'تایید', + width: 150.w, + height: 40.h, + isLoading: data[item.key!] ?? false, + onPressed: () async { + await Get.bottomSheet( + conformationBottomSheet(item), + isScrollControlled: true, + ); + }, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ); + }, controller.isLoadingConfirmMap), + ROutlinedElevated( + text: 'رد', + textStyle: AppFonts.yekan20.copyWith(color: AppColor.redNormal), + width: 150.w, + height: 40.h, + onPressed: () { + buildWarningDialog( + title: 'اخطار', + middleText: 'آیا از رد شدن این مورد اطمینان دارید؟', + onConfirm: () => controller.denyEntries(item), + onRefresh: () => controller.getWaitingArrivals(), + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ], + ), + ); + } + + Widget conformationBottomSheet(WaitingArrivalModel item) { + controller.weightController.text = item.weightOfCarcasses.separatedByComma; + return BaseBottomSheet( + height: 450.h, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 10), + RTextField( + label: 'وزن(کیلوگرم)', + controller: controller.weightController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + SizedBox(height: 16.h), + RTextField( + label: 'حجم(قطعه)', + controller: controller.countController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + SizedBox(height: 16.h), + RTextField( + label: 'افت وزن(کیلوگرم)', + controller: controller.lossController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + SizedBox(height: 16.h), + + Text( + 'تایید ', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.textColor), + ), + ObxValue((data) { + return Column( + children: [ + RadioGroup( + groupValue: data.value, + onChanged: (value) { + controller.approvedWithOtpCode.value = value ?? false; + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + radioRow( + value: true, + label: ' با کد احراز', + onTap: () { + controller.approvedWithOtpCode.value = true; + }, + ), + radioRow( + value: false, + label: 'بدون کد احراز', + onTap: () { + controller.approvedWithOtpCode.value = false; + }, + ), + ], + ), + ), + Visibility( + child: RTextField( + controller: controller.approvedWithOtpController, + label: 'کد احراز', + keyboardType: TextInputType.number, + maxLength: 5, + ), + visible: data.value, + ), + ], + ); + }, controller.approvedWithOtpCode), + SizedBox(height: 30.h), + Obx(() { + return RElevated( + enabled: controller.approvedWithOtpCode.value + ? controller.isButtonConfirm.value + : true, + text: 'تایید', + onPressed: () async { + await controller.acceptEntries(item); + }, + isFullWidth: true, + ); + }), + SizedBox(height: 20.h), + ], + ), + ); + } + + Widget radioRow({ + required bool value, + required String label, + TextStyle? textStyle, + GestureTapCallback? onTap, + }) { + return GestureDetector( + onTap: onTap, + child: Row( + children: [ + Radio(value: value), + Text( + label, + style: + textStyle ?? + AppFonts.yekan16.copyWith(color: AppColor.textColor), + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_out_of_province/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_out_of_province/logic.dart new file mode 100644 index 0000000..4e97f88 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_out_of_province/logic.dart @@ -0,0 +1,324 @@ +import 'package:flutter/cupertino.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/buy_out_of_province/logic.dart +import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart'; +import 'package:rasadyar_chicken/data/models/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/buy/logic.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/request/create_steward_free_bar/create_steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/buy_out_of_province/logic.dart +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class BuyOutOfProvinceLogic extends GetxController { + late List routesName; + RxBool isSubmitButtonEnabled = false.obs; + RxInt expandedListIndex = (-1).obs; + + final RxInt currentPage = 1.obs; + final RxBool isLoadingMoreAllocationsMade = false.obs; + final RxBool isOnLoadingSubmitOrEdit = false.obs; + + //TODO add this to Di + ImagePicker imagePicker = ImagePicker(); + + Rx>> purchaseOutOfProvinceList = + Resource>.loading().obs; + Rxn selectedProduct = Rxn(); + + RxList cites = [].obs; + Rxn selectedProvince = Rxn(); + Rxn selectedCity = Rxn(); + Rxn selectedImage = Rxn(); + final RxnString _base64Image = RxnString(); + RxnString editImageUrl = RxnString(); + RxnString editFreeBarKey = RxnString(); + + StewardRootLogic rootLogic = Get.find(); + + BuyLogic buyLogic = Get.find(); + + SaleLogic outOfTheProvinceLogic = Get.find(); + + GlobalKey formKey = GlobalKey(); + TextEditingController sellerNameController = TextEditingController(); + TextEditingController sellerPhoneController = TextEditingController(); + TextEditingController carcassWeightController = TextEditingController(); + TextEditingController carcassCountController = TextEditingController(); + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + routesName = [...buyLogic.routesName, 'خارج استان'].toList(); + } + + @override + void onReady() { + super.onReady(); + getStewardPurchaseOutOfProvince(); + selectedProvince.listen((p0) => getCites()); + + selectedProduct.value = rootLogic.rolesProductsModel.first; + setupListeners(); + + debounce( + searchedValue, + (callback) => getStewardPurchaseOutOfProvince(), + time: Duration(milliseconds: timeDebounce), + ); + } + + @override + void onClose() { + sellerNameController.dispose(); + sellerPhoneController.dispose(); + carcassWeightController.dispose(); + + super.onClose(); + } + + void setSearchValue(String? data) { + searchedValue.value = data?.trim(); + } + + Future getStewardPurchaseOutOfProvince([ + bool isLoadingMore = false, + ]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + purchaseOutOfProvinceList.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: () => + rootLogic.stewardRepository.getStewardPurchasesOutSideOfTheProvince( + 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: (res) async { + await Future.delayed(Duration(milliseconds: 500)); + if ((res?.count ?? 0) == 0) { + purchaseOutOfProvinceList.value = + Resource>.empty(); + } else { + purchaseOutOfProvinceList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(purchaseOutOfProvinceList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future getCites() async { + await safeCall( + call: () => rootLogic.commonRepository.getCity( + provinceName: selectedProvince.value?.name ?? '', + ), + onSuccess: (result) { + if (result != null && result.isNotEmpty) { + cites.value = result; + } + }, + ); + } + + void setupListeners() { + sellerNameController.addListener(() { + checkFormValid(); + if (!isSubmitButtonEnabled.value) { + isSubmitButtonEnabled.value = !isSubmitButtonEnabled.value; + } + }); + sellerPhoneController.addListener(checkFormValid); + carcassWeightController.addListener(checkFormValid); + carcassCountController.addListener(checkFormValid); + + ever(selectedProvince, (_) => checkFormValid()); + ever(selectedCity, (_) => checkFormValid()); + ever(selectedProduct, (_) => checkFormValid()); + ever(selectedImage, (data) async { + checkFormValid(); + if (data?.path != null) { + _base64Image.value = await convertImageToBase64(data!.path); + } + }); + } + + void checkFormValid() { + isSubmitButtonEnabled.value = + sellerNameController.text.isNotEmpty && + sellerPhoneController.text.isNotEmpty && + carcassWeightController.text.isNotEmpty && + carcassCountController.text.isNotEmpty && + selectedProvince.value != null && + selectedCity.value != null && + selectedProduct.value != null && + (selectedImage.value != null || editImageUrl.value != null); + + if (isSubmitButtonEnabled.value) { + isOnLoadingSubmitOrEdit.value = false; + } + } + + Future createStewardPurchaseOutOfProvince() async { + bool res = false; + isOnLoadingSubmitOrEdit.value = true; + if (!(formKey.currentState?.validate() ?? false)) { + isOnLoadingSubmitOrEdit.value = false; + return res; + } + await safeCall( + showError: true, + call: () async { + CreateStewardFreeBar createStewardFreeBar = CreateStewardFreeBar( + productKey: selectedProduct.value!.key, + killHouseName: sellerNameController.text, + killHouseMobile: sellerPhoneController.text, + province: selectedProvince.value!.name, + city: selectedCity.value!.name, + weightOfCarcasses: int.parse(carcassWeightController.text.clearComma), + numberOfCarcasses: int.parse(carcassCountController.text.clearComma), + barImage: _base64Image.value, + date: DateTime.now().formattedYHMS, + distributionType: 'App', + ); + await rootLogic.stewardRepository + .createStewardPurchasesOutSideOfTheProvince( + token: rootLogic.tokenService.accessToken.value!, + body: createStewardFreeBar, + ); + }, + onSuccess: (result) { + getStewardPurchaseOutOfProvince(); + resetSubmitForm(); + toggleExpansion(); + res = true; + }, + ); + isOnLoadingSubmitOrEdit.value = false; + return res; + } + + void resetSubmitForm() { + sellerNameController.clear(); + sellerPhoneController.clear(); + carcassWeightController.clear(); + carcassCountController.clear(); + selectedProvince.value = null; + selectedCity.value = null; + selectedImage.value = null; + _base64Image.value = null; + editImageUrl.value = null; + + isSubmitButtonEnabled.value = false; + } + + void setEditData(StewardFreeBar item) async { + editImageUrl.value = item.barImage; + sellerNameController.text = item.killHouseName ?? ''; + sellerPhoneController.text = item.killHouseMobile ?? ''; + carcassWeightController.text = item.weightOfCarcasses.separatedByComma; + carcassCountController.text = item.numberOfCarcasses.separatedByComma; + editFreeBarKey.value = item.key; + selectedProvince.value = IranProvinceCityModel(name: item.province); + selectedCity.value = IranProvinceCityModel(name: item.city); + selectedProduct.value = rootLogic.rolesProductsModel.firstWhere( + (element) => element.key == item.product!.key, + ); + + isSubmitButtonEnabled.value = true; + } + + Future editStewardPurchaseOutOfProvince() async { + CreateStewardFreeBar edit = CreateStewardFreeBar( + productKey: selectedProduct.value!.key, + key: editFreeBarKey.value, + killHouseName: sellerNameController.text, + killHouseMobile: sellerPhoneController.text, + province: selectedProvince.value!.name, + city: selectedCity.value!.name, + weightOfCarcasses: int.parse(carcassWeightController.text.clearComma), + numberOfCarcasses: int.parse(carcassCountController.text.clearComma), + date: DateTime.now().formattedYHMS, + ); + + if (_base64Image.value != null) { + edit = edit.copyWith(barImage: _base64Image.value); + } + + await safeCall( + showError: true, + call: () => + rootLogic.stewardRepository.editStewardPurchasesOutSideOfTheProvince( + token: rootLogic.tokenService.accessToken.value!, + body: edit, + ), + onSuccess: (result) { + onRefresh(); + rootLogic.onRefresh(); + toggleExpansion(); + }, + ); + } + + Future deleteStewardPurchaseOutOfProvince(String key) async { + await safeCall( + call: () => rootLogic.stewardRepository + .deleteStewardPurchasesOutSideOfTheProvince( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildRawQueryParams(queryParams: {'key': key}), + ), + ); + } + + Future onRefresh() async { + currentPage.value = 1; + await rootLogic.onRefresh(); + await getStewardPurchaseOutOfProvince(); + } + + void toggleExpansion({int? index}) { + if (expandedListIndex.value == index || index == null) { + expandedListIndex.value = -1; + } else { + expandedListIndex.value = index; + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/buy_out_of_province/view.dart b/packages/chicken/lib/features/steward/presentation/pages/buy_out_of_province/view.dart new file mode 100644 index 0000000..e2aa24f --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/buy_out_of_province/view.dart @@ -0,0 +1,673 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart' hide Image; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar/steward_free_bar.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart'; + +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class BuyOutOfProvincePage extends GetView { + const BuyOutOfProvincePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + backId: stewardFirstKey, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + + child: Stack( + children: [ + Positioned.fill( + child: Column( + children: [ + Obx(() { + var list = [ + InventoryItemData( + title: 'موجودی انبار', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalRemainWeight + ?.separatedByCommaFa, + color: const Color(0xFFEAFBFC), + ), + InventoryItemData( + title: 'مانده دولتی', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalGovernmentalRemainWeight + ?.separatedByCommaFa, + + color: const Color(0xFFF5ECEE), + ), + InventoryItemData( + title: 'مانده آزاد', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalFreeRemainWeight + ?.separatedByCommaFa, + + color: const Color(0xFFF1E7FF), + ), + ]; + + return InventoryWidget(inventoryModel: list); + }), + + ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value == index, + onTap: () => controller.toggleExpansion(index: index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.truckFastOutlinedSvg.path, + ); + }, controller.expandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getStewardPurchaseOutOfProvince(true), + ); + }, controller.purchaseOutOfProvinceList), + ], + ), + ), + Positioned( + right: 5, + bottom: 95, + child: RFab.add( + onPressed: () { + Get.bottomSheet( + addPurchasedInformationBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).whenComplete(() { + controller.resetSubmitForm(); + }); + }, + ), + ), + ], + ), + ); + } + + Container itemListExpandedWidget(StewardFreeBar item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + '${item.province}-${item.city}', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + ], + ), + 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( + item.date?.toJalali.formatter.wN ?? 'ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + ], + ), + + Text( + '${item.date?.toJalali.formatter.y}', + style: AppFonts.yekan20.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow(title: 'مشخصات فروشنده', value: item.killHouseName ?? 'ندارد'), + + buildRow( + title: 'تلفن فروشنده', + value: item.killHouseMobile ?? 'ندارد', + valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + buildRow(title: 'محصول', value: item.product?.name ?? 'ندارد'), + buildRow( + title: 'وزن خریداری شده', + value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم', + ), + buildRow( + title: 'حجم خریداری شده', + value: '${item.numberOfCarcasses?.separatedByCommaFa} قطعه', + ), + buildRowOnTapped( + title: 'مشاهده بارنامه', + titleStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + valueWidget: Assets.vec.clipboardEyeSvg.svg( + width: 20, + height: 24, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + onTap: () { + Get.bottomSheet( + BaseBottomSheet( + height: 400, + child: Column( + spacing: 16, + children: [ + Text( + 'بارنامه', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + + Image.network( + item.barImage ?? '', + fit: BoxFit.cover, + height: 300, + errorBuilder: (context, error, stackTrace) { + eLog(error.toString()); + return Center(child: Text('خطایی پیش آمده!')); + }, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return CupertinoActivityIndicator(); + }, + ), + ], + ), + ), + ); + }, + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + RElevated( + text: 'ویرایش', + width: 150.w, + height: 40.h, + onPressed: () { + controller.setEditData(item); + Get.bottomSheet( + addPurchasedInformationBottomSheet(true), + isScrollControlled: true, + ).whenComplete(() { + controller.resetSubmitForm(); + }); + }, + 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: () => controller.deleteStewardPurchaseOutOfProvince(item.key!), + onRefresh: () async { + controller.rootLogic.onRefresh(); + controller.onRefresh(); + controller.toggleExpansion(); + }, + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ], + ), + ); + } + + Row itemListWidget(StewardFreeBar item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.killHouseName ?? 'ندارد', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.date?.formattedJalaliDate ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 3, + children: [ + Visibility( + visible: item.product?.name?.contains('مرغ گرم') ?? false, + child: Assets.vec.hotChickenSvg.svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + Text( + '${item.weightOfCarcasses?.separatedByCommaFa}kg', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + + SizedBox(height: 2), + Text( + '${item.numberOfCarcasses.separatedByComma} ${'قطعه'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 3, + children: [ + Text( + '${item.province}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + '${item.city}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + ], + ); + } + + Widget addPurchasedInformationBottomSheet([bool isOnEdit = false]) { + return BaseBottomSheet( + child: Form( + key: controller.formKey, + child: Column( + spacing: 8, + 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: [_provinceWidget(), _cityWidget()]), + ), + + 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.sellerNameController, + label: 'نام فروشنده', + borderColor: AppColor.darkGreyLight, + filled: true, + filledColor: AppColor.bgLight, + ), + RTextField( + controller: controller.sellerPhoneController, + label: 'تلفن فروشنده', + keyboardType: TextInputType.phone, + borderColor: AppColor.darkGreyLight, + maxLength: 11, + filled: true, + filledColor: AppColor.bgLight, + validator: (value) { + if (value == null || value.isEmpty) { + return 'لطفاً شماره موبایل را وارد کنید'; + } + String cleaned = value.replaceAll(',', ''); + if (cleaned.length != 11) { + return 'شماره موبایل باید ۱۱ رقم باشد'; + } + if (!cleaned.startsWith('09')) { + return 'شماره موبایل باید با 09 شروع شود'; + } + return null; + }, + ), + + UnitTextField( + controller: controller.carcassWeightController, + hint: 'وزن', + unit: 'کیلوگرم', + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + + UnitTextField( + controller: controller.carcassCountController, + hint: 'حجم', + unit: 'قطعه', + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + ), + ], + ), + ), + _imageCarcasesWidget(isOnEdit), + submitButtonWidget(isOnEdit), + SizedBox(), + ], + ), + ), + ); + } + + Widget submitButtonWidget(bool isOnEdit) { + return Obx(() { + return RElevated( + text: isOnEdit ? 'ویرایش' : 'ثبت', + width: Get.width, + backgroundColor: AppColor.greenNormal, + isLoading: controller.isOnLoadingSubmitOrEdit.value, + enabled: controller.isSubmitButtonEnabled.value, + onPressed: isOnEdit + ? () async { + await controller.editStewardPurchaseOutOfProvince(); + Get.back(); + } + : () async { + var res = await controller.createStewardPurchaseOutOfProvince(); + if (res) { + Get.back(); + } + }, + height: 40, + ); + }); + } + + Widget _productDropDown() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rootLogic.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.separatedByCommaFa ?? 0}', + ), + ], + ), + ); + }); + } + + Widget _provinceWidget() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rootLogic.provinces, + onChanged: (value) { + controller.selectedProvince.value = value; + }, + selectedItem: controller.selectedProvince.value, + itemBuilder: (item) => Text( + item.name ?? 'بدون نام', + style: AppFonts.yekan14.copyWith(color: AppColor.lightGreyDarker), + ), + labelBuilder: (item) => item?.name != null + ? Text(item!.name!, style: AppFonts.yekan14.copyWith(color: AppColor.textColor)) + : Text( + 'انتخاب استان', + style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight), + ), + ); + }); + } + + Widget _cityWidget() { + return ObxValue((data) { + return OverlayDropdownWidget( + items: data, + onChanged: (value) { + controller.selectedCity.value = value; + }, + selectedItem: controller.selectedCity.value, + itemBuilder: (item) => Text( + item.name ?? 'بدون نام', + style: AppFonts.yekan14.copyWith(color: AppColor.lightGreyDarker), + ), + labelBuilder: (item) => item?.name != null + ? Text(item!.name!, style: AppFonts.yekan14.copyWith(color: AppColor.textColor)) + : Text('انتخاب شهر', style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight)), + ); + }, controller.cites); + } + + SizedBox _imageCarcasesWidget(bool isOnEdit) { + return SizedBox( + width: Get.width, + height: 370, + child: Card( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Column( + spacing: 8, + children: [ + Text('بارنامه', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)), + Expanded( + child: ObxValue((data) { + return Container( + width: Get.width, + height: 270, + decoration: BoxDecoration( + color: AppColor.lightGreyNormal, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.blackLight), + ), + child: Center( + child: isOnEdit + ? Image.network(controller.editImageUrl.value ?? '') + : data.value == null + ? Padding( + padding: const EdgeInsets.fromLTRB(30, 10, 10, 30), + child: Assets.vec.placeHolderSvg.svg(width: 200.w, height: 150.h), + ) + : Image.file(File(data.value!.path), fit: BoxFit.cover), + ), + ); + }, controller.selectedImage), + ), + + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + RElevated( + text: 'گالری', + width: 150.w, + height: 40.h, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + onPressed: () async { + controller.selectedImage.value = await controller.imagePicker.pickImage( + source: ImageSource.gallery, + imageQuality: 60, + maxWidth: 1080, + maxHeight: 720, + ); + }, + ), + SizedBox(width: 16), + ROutlinedElevated( + text: 'دوربین', + width: 150.w, + height: 40.h, + textStyle: AppFonts.yekan20.copyWith(color: AppColor.blueNormal), + onPressed: () async { + controller.selectedImage.value = await controller.imagePicker.pickImage( + source: ImageSource.camera, + imageQuality: 60, + maxWidth: 1080, + maxHeight: 720, + ); + }, + ), + ], + ), + ], + ), + ), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getStewardPurchaseOutOfProvince(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/home/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/home/logic.dart new file mode 100644 index 0000000..0b0b02c --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/home/logic.dart @@ -0,0 +1,106 @@ +<<<<<<<< HEAD:packages/chicken/lib/features/steward/home/logic.dart +import 'package:rasadyar_chicken/data/models/response/bar_information/bar_information.dart'; +import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/response/bar_information/bar_information.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/home/logic.dart +import 'package:rasadyar_core/core.dart'; + +class HomeLogic extends GetxController { + StewardRootLogic rootLogic = Get.find(); + RxnInt totalWeightTodayBars = RxnInt(); + Rxn killHouseDistributionInfo = + Rxn(); + Rxn barInformation = Rxn(); + + RxList> inventoryItems = [ + {'خریدهای دولتی داخل استان': null}, + {'خریدهای آزاد داخل استان': null}, + {'وزن خریدهای خارج استان': null}, + {'کل ورودی به انبار': null}, + {'کل فروش': null}, + {'مانده انبار': null}, + ].obs; + + RxList> broadcastItems = [ + {'وزن دولتی': '2،225،256'}, + {'وزن آزاد': '2،225،256'}, + {'فروش دولتی': '2،225،256'}, + {'فروش آزاد': '2،225،256'}, + {'توزیع داخل استان': '2،225،256'}, + {'توزیع خارج استان': '2،225،256'}, + {'قطعه بندی': '2،225،256'}, + ].obs; + + RxBool isExpanded = false.obs; + + @override + void onReady() { + super.onReady(); + refreshData(); + } + + Future refreshData() async { + await Future.wait([ + getGeneralBarsInformation(), + getTodayBars(), + getDistributionInformation(), + rootLogic.getRolesProducts(), + rootLogic.getRolesProduct(), + ]); + } + + Future getGeneralBarsInformation() async { + await safeCall( + call: () async => + await rootLogic.commonRepository.getGeneralBarInformation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams(role: 'Steward'), + ), + onSuccess: (result) { + if (result != null) { + barInformation.value = result; + } + }, + onError: (error, stackTrace) {}, + ); + } + + Future getTodayBars() async { + await safeCall( + call: () async => + await rootLogic.commonRepository.getGeneralBarInformation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + fromDate: DateTime.now(), + toDate: DateTime.now(), + role: 'Steward', + ), + ), + onSuccess: (result) { + if (result != null) { + totalWeightTodayBars.value = result.totalBarsWeight?.toInt(); + } + }, + onError: (error, stackTrace) {}, + ); + } + + Future getDistributionInformation() async { + await safeCall( + call: () async => + await rootLogic.commonRepository.getKillHouseDistributionInfo( + token: rootLogic.tokenService.accessToken.value!, + ), + onSuccess: (result) { + if (result != null) { + killHouseDistributionInfo.value = result; + } + }, + onError: (error, stackTrace) {}, + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/home/view.dart b/packages/chicken/lib/features/steward/presentation/pages/home/view.dart new file mode 100644 index 0000000..b8b1148 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/home/view.dart @@ -0,0 +1,1121 @@ +import 'package:flutter/cupertino.dart' hide LinearGradient; +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/home/view.dart +import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/home/view.dart +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/steward/widely_used/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class HomePage extends GetView { + const HomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + scrollable: true, + isBase: true, + onRefresh: controller.refreshData, + child: SingleChildScrollView( + padding: EdgeInsets.only(bottom: 100.h), + child: Column( + children: [ + SizedBox(height: 18.h), + mainInformation(), + SizedBox(height: 8.h), + WidelyUsedWidget(), + ], + ), + ), + ); + } + + Widget buildColumn(Widget widget, String title) { + return Container( + height: 70.h, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [widget, Text(title)], + ), + ); + } + + InkWell mainInformation() { + return InkWell( + onTap: () { + controller.isExpanded.value = !controller.isExpanded.value; + }, + + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + margin: EdgeInsetsGeometry.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), + ), + + child: ObxValue((data) { + return AnimatedSize( + duration: Duration(milliseconds: 300), + child: data.value + ? Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + spacing: 8, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + AnimatedRotation( + turns: 180, + duration: Duration(milliseconds: 3000), + child: Icon( + CupertinoIcons.chevron_up, + size: 18, + ), + ), + ], + ), + SizedBox(height: 8), + _todayShipmentWidget(), + _todayShipmentWidget2(), + _inventoryWidget(), + _inventoryListWidget(), + SizedBox(height: 8), + broadCastList(), + SizedBox(height: 8), + commitmentsList(), + ], + ), + ) + : Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + spacing: 8, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Icon(CupertinoIcons.chevron_down, size: 18), + ], + ), + _todayShipmentWidget(), + _todayShipmentWidget2(), + _inventoryWidget(), + ], + ), + ), + ); + }, controller.isExpanded), + ), + Positioned( + top: -10, + right: 20, + child: Container( + height: 32.h, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), + ), + padding: EdgeInsets.symmetric(horizontal: 8), + child: Row( + spacing: 8, + children: [ + Assets.vec.chicken2Svg.svg( + width: 24.w, + height: 24.h, + colorFilter: ColorFilter.mode( + AppColor.blueDark, + BlendMode.srcIn, + ), + ), + Text( + 'اطلاعات مرغ گرم', + textAlign: TextAlign.right, + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + //todo + Widget broadCastList() { + return ObxValue((data) { + return Column( + children: [ + Row( + children: [ + SizedBox(width: 5.w), + Text( + 'اطلاعات پخش', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), + ], + ), + SizedBox(height: 8.h), + Row( + spacing: 8, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: broadcastItem( + title: 'وزن دولتی', + titleBgColor: const Color(0xFFB8E7DC), + valueBgColor: const Color(0xFFE6FAF5), + value: + data.value?.totalGovernmentalInputWeight.separatedByComma, + ), + ), + Expanded( + child: broadcastItem( + title: 'وزن آزاد', + value: data.value?.totalFreeInputWeight.separatedByComma, + titleBgColor: const Color(0xFFDDE2F0), + valueBgColor: const Color(0xFFEAEFFF), + ), + ), + Expanded( + child: broadcastItem( + title: 'فروش دولتی', + value: data + .value + ?.totalGovernmentalOutputWeight + .separatedByComma, + titleBgColor: const Color(0xFFEBC4CE), + valueBgColor: const Color(0xFFEDDCE0), + ), + ), + Expanded( + child: broadcastItem( + title: 'فروش آزاد', + value: data.value?.totalFreeOutputWeight.separatedByComma, + titleBgColor: const Color(0xFFC2D3F2), + valueBgColor: const Color(0xFFECF2FF), + ), + ), + ], + ), + + SizedBox(height: 8.h), + Row( + spacing: 8, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: broadcastItem( + title: 'مانده دولتی', + value: data + .value + ?.totalGovernmentalRemainWeight + .separatedByComma, + titleBgColor: const Color(0xFFB8E7DC), + valueBgColor: const Color(0xFFE6FAF5), + ), + ), + Expanded( + child: broadcastItem( + title: 'مانده آزاد', + value: data.value?.totalFreeRemainWeight.separatedByComma, + titleBgColor: const Color(0xFFDDE2F0), + valueBgColor: const Color(0xFFEAEFFF), + ), + ), + Expanded( + child: broadcastItem( + title: 'فروش خارج استان', + value: data + .value + ?.totalStewardFreeSaleBarCarcassesWeight + .separatedByComma, + titleBgColor: const Color(0xFFEBC4CE), + valueBgColor: const Color(0xFFEDDCE0), + ), + ), + ], + ), + ], + ); + }, controller.rootLogic.stewardSalesInfoDashboard); + } + + Widget distributionInformationWidget() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + return Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Expanded( + child: _informationIconCard( + title: 'توزیع داخل استان', + isLoading: data.value == null, + description: + data.value?.freeSalesWeight.separatedByCommaFa ?? '0', + iconPath: Assets.vec.truckSvg.path, + iconColor: const Color.fromRGBO(85, 97, 93, 1), + bgDescriptionColor: const Color(0xFFE6FAF5), + bgLabelColor: const Color(0xFFB0EFDF), + ), + ), + Expanded( + child: _informationIconCard( + title: 'توزیع خارج استان', + isLoading: data.value == null, + description: + data.value?.stewardAllocationsWeight.separatedByCommaFa ?? + '0', + iconPath: Assets.vec.truckFastSvg.path, + iconColor: Color(0xFF647379), + bgDescriptionColor: const Color(0xFFEAEFFF), + bgLabelColor: const Color(0xFFD4DEFF), + ), + ), + Expanded( + child: _informationIconCard( + title: 'قطعه بندی', + description: '2،225،256', + iconPath: Assets.vec.convertCubeSvg.path, + iconColor: const Color(0xFF6F6164), + bgDescriptionColor: const Color(0xFFEDDCE0), + bgLabelColor: const Color(0xFFE0BCC5), + ), + ), + ], + ); + }, controller.killHouseDistributionInfo), + ); + } + + Widget _informationShipment() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 8, 0, 13), + child: ObxValue((data) { + return Row( + spacing: 8, + children: [ + Expanded( + child: _informationLabelCard( + title: 'داخل استان', + isLoading: data.value == null, + description: data.value != null + ? ((data.value?.provinceGovernmentalCarcassesWeight ?? 0) + + (data.value?.provinceFreeCarcassesWeight ?? 0)) + .separatedByCommaFa + : '0', + iconPath: Assets.vec.cubeSvg.path, + iconColor: const Color(0xFF6C5D60), + bgDescriptionColor: const Color(0xFFEDDCE0), + bgLabelColor: const Color(0xFFDDC0C7), + ), + ), + Expanded( + child: _informationLabelCard( + title: 'خارج استان', + isLoading: data.value == null, + description: + data.value?.freeBuyingCarcassesWeight.separatedByCommaFa ?? + '0', + iconPath: Assets.vec.cubeSearchSvg.path, + iconColor: Color(0xFF2D5FFF), + bgLabelColor: const Color(0xFFAFCBFF), + bgDescriptionColor: const Color(0xFFCEDFFF), + ), + ), + ], + ); + }, controller.rootLogic.inventoryModel), + ); + } + + Widget _inventoryWidget() { + return ObxValue((data) { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 13), + child: Row( + spacing: 8, + children: [ + Expanded( + child: _informationLabelCard( + title: 'مانده انبار', + isLoading: data.value == null, + description: + data.value?.totalRemainWeight.separatedByCommaFa ?? '0', + iconPath: Assets.vec.cubeSearchSvg.path, + bgDescriptionColor: const Color(0xFFEAEFFF), + bgLabelColor: const Color(0xFFBDD4FF), + iconColor: AppColor.textColor, + ), + ), + Expanded( + child: _informationLabelCard( + title: 'توزیع شده', + isLoading: data.value == null, + description: + data.value?.realAllocatedWeight.separatedByCommaFa ?? '0', + iconPath: Assets.vec.cubeRotateSvg.path, + iconColor: Color(0xFF5C4D64), + bgLabelColor: Color(0xFFC8B8D1), + bgDescriptionColor: Color(0xFFDAD4DD), + ), + ), + ], + ), + ); + }, controller.rootLogic.inventoryModel); + } + + Widget _todayShipmentWidget() { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 13), + child: Row( + spacing: 8, + children: [ + Expanded( + child: ObxValue( + (data) => _informationLabelCard( + title: 'بارهای امروز', + titleColor: AppColor.textColor, + borderColor: Color(0xFFFFAE00), + isLoading: data.value == null, + description: data.value?.separatedByCommaFa ?? '0', + icon: Container( + width: 24.w, + height: 24.h, + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: const Color(0xFFFFAE00), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.cubeScanSvg.svg( + width: 12.w, + height: 12.h, + colorFilter: const ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), + ), + ), + bgDescriptionColor: Colors.white, + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [const Color(0xFFFFD883), const Color(0xFFFFFBF1)], + ), + ), + controller.totalWeightTodayBars, + ), + ), + + Expanded( + child: ObxValue((data) { + return _informationLabelCard( + title: 'درانتظار', + borderColor: const Color(0xFF9758FF), + isLoading: data.value == null, + description: + data.value?.totalNotEnteredBars.separatedByCommaFa ?? '0', + unit: + '(${data.value?.totalNotEnteredKillHouseRequestsWeight.separatedByCommaFa})\nکیلوگرم', + icon: Container( + width: 24.w, + height: 24.h, + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: const Color(0xFF9758FF), + borderRadius: BorderRadius.circular(8), + ), + child: Assets.vec.cubeCardFreeSvg.svg( + width: 12.w, + height: 12.h, + colorFilter: const ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), + ), + ), + bgDescriptionColor: Colors.white, + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [const Color(0xFFD8C1FF), const Color(0xFFFBF9FF)], + ), + ); + }, controller.barInformation), + ), + ], + ), + ); + } + + Widget _todayShipmentWidget2() { + return ObxValue((data) { + return Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 13), + child: Row( + spacing: 8, + children: [ + Expanded( + child: _informationLabelCard( + title: 'مانده دولتی', + isLoading: data.value == null, + description: + data + .value + ?.totalGovernmentalRemainWeight + ?.separatedByCommaFa ?? + '0', + iconPath: Assets.vec.cubeCardGovermentSvg.path, + iconColor: AppColor.textColor, + bgDescriptionColor: const Color(0xFFF5ECEE), + bgLabelColor: const Color(0xFFDEC1C7), + ), + ), + Expanded( + child: _informationLabelCard( + title: 'مانده آزاد', + isLoading: data.value == null, + description: + data.value?.totalFreeRemainWeight.separatedByCommaFa ?? '0', + unit: 'کیلوگرم', + iconPath: Assets.vec.cubeCardFreeSvg.path, + iconColor: AppColor.textColor, + bgDescriptionColor: const Color(0xFFD0ECED), + bgLabelColor: const Color(0xFFA5D1D2), + ), + ), + ], + ), + ); + }, controller.rootLogic.stewardSalesInfoDashboard); + } + + Widget _inventoryListWidget() { + return ObxValue((data) { + var model = data[0]; + return Container( + padding: EdgeInsets.fromLTRB(16.w, 0, 11.w, 0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + color: const Color(0xB2EDF1FF), + ), + alignment: Alignment.center, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + inventoryListItem( + title: 'خریدهای دولتی داخل استان', + value: model.receiveGovernmentalCarcassesWeight.separatedByComma, + ), + Divider(), + inventoryListItem( + title: 'خریدهای آزاد داخل استان', + value: model.receiveFreeCarcassesWeight?.separatedByComma, + ), + Divider(), + inventoryListItem( + title: 'وزن خریدهای خارج استان', + value: model.freeBuyingCarcassesWeight?.separatedByComma, + ), + Divider(), + inventoryListItem( + title: 'کل ورودی به انبار', + value: model.totalCarcassesWeight?.separatedByComma, + ), + Divider(), + + inventoryListItem( + title: 'کل فروش', + value: model.realAllocatedWeight?.separatedByComma, + ), + Divider(), + inventoryListItem( + title: 'مانده انبار', + value: model.totalRemainWeight?.separatedByComma, + ), + ], + ), + ); + }, controller.rootLogic.rolesProductsModel); + } + + Widget inventoryListItem({required String title, required String? value}) { + return Container( + height: 45.h, + child: Row( + children: [ + Text( + title, + style: AppFonts.yekan14.copyWith( + color: const Color(0xFF353535), + height: 1.2, + ), + ), + Spacer(), + value == null + ? Center(child: CupertinoActivityIndicator()) + : Text( + value, + style: AppFonts.yekan14.copyWith( + color: const Color(0xFF353535), + ), + ), + SizedBox(width: 20.w), + Text( + 'کیلوگرم', + style: AppFonts.yekan10.copyWith(color: const Color(0xFF353535)), + ), + ], + ), + ); + } + + Container _informationLabelCard({ + required String title, + required String description, + required Color bgDescriptionColor, + String? iconPath, + Widget? icon, + Color? borderColor, + String unit = 'کیلوگرم', + bool isLoading = false, + Color? iconColor, + Color? titleColor, + Color? bgLabelColor, + LinearGradient? gradient, + }) { + return Container( + height: 65.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: borderColor != null + ? Border.all(width: 1, color: borderColor) + : null, + ), + clipBehavior: Clip.hardEdge, + child: Row( + children: [ + // Left side with icon and title + Expanded( + child: Container( + height: 82, + decoration: BoxDecoration( + color: gradient == null ? bgLabelColor : null, + borderRadius: BorderRadius.only( + topRight: Radius.circular(8), + bottomRight: Radius.circular(8), + ), + gradient: gradient, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 5, + children: [ + icon ?? + SvgGenImage.vec(iconPath!).svg( + width: 24.w, + height: 24.h, + colorFilter: iconColor != null + ? ColorFilter.mode(iconColor, BlendMode.srcIn) + : null, + ), + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith( + color: titleColor ?? AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + // Right side with description and unit + Expanded( + child: Container( + decoration: BoxDecoration( + color: bgDescriptionColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(8), + ), + ), + child: isLoading + ? Center(child: CupertinoActivityIndicator()) + : Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + description, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + Text( + unit, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Container _informationIconCard({ + required String title, + required String description, + String unit = 'کیلوگرم', + bool isLoading = false, + required String iconPath, + required Color iconColor, + required Color bgDescriptionColor, + required Color bgLabelColor, + }) { + return Container( + height: 110, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)), + clipBehavior: Clip.hardEdge, + child: Stack( + alignment: Alignment.topCenter, + children: [ + Positioned( + bottom: 0, + right: 0, + left: 0, + child: Container( + height: 91, + decoration: BoxDecoration( + color: bgDescriptionColor, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.25, color: const Color(0xFFB4B4B4)), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + + isLoading + ? Center(child: CupertinoActivityIndicator()) + : Text( + description, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + Text( + unit, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + Positioned( + top: 0, + child: Container( + width: 32, + height: 32, + decoration: ShapeDecoration( + color: bgLabelColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + side: BorderSide(width: 0.25, color: const Color(0xFFD5D5D5)), + ), + ), + child: Center( + child: SvgGenImage.vec(iconPath).svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn), + ), + ), + ), + ), + ], + ), + ); + } + + Widget inventoryItem({ + required bool isExpanded, + required int index, + required ProductModel 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(), + ), + ], + ), + ), + ], + ); + } + + 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: 1, + child: Text( + value, + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDarkHover, + ), + ), + ), + ], + ), + ); + } + + Widget broadcastInformationWidget(KillHouseDistributionInfo? model) { + return Container( + height: 140, + margin: const EdgeInsets.all(8), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.blueNormal, width: 1), + ), + child: model != null + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 10, + children: [ + Text( + 'اطلاعات ارسالی', + textAlign: TextAlign.right, + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + const SizedBox(height: 12), + buildRow( + 'فروش و توزیع داخل استان (کیلوگرم)', + model.stewardAllocationsWeight!.toInt().toString(), + ), + buildRow( + 'فروش و توزیع خارج استان (کیلوگرم)', + model.freeSalesWeight!.toInt().toString(), + ), + ], + ) + : const Center(child: CircularProgressIndicator()), + ); + } + + Widget broadcastItem({ + int? width, + int? height, + String? title, + String? value, + String? unit, + Color? titleBgColor, + Color? valueBgColor, + Color? unitBgColor, + TextStyle? titleStyle, + TextStyle? valueStyle, + TextStyle? unitStyle, + }) { + return Container( + height: height?.h ?? 73.h, + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: valueBgColor, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + padding: EdgeInsets.symmetric(vertical: 4.h), + decoration: BoxDecoration(color: titleBgColor), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + title ?? 'بدون تیتر', + textAlign: TextAlign.center, + style: + titleStyle ?? + AppFonts.yekan12.copyWith(color: const Color(0xFF3E3E3E)), + ), + ], + ), + ), + SizedBox(height: 4), + + (value != null) + ? Padding( + padding: const EdgeInsets.symmetric(horizontal: 11.0), + child: Text( + value, + textAlign: TextAlign.right, + style: + valueStyle ?? + AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ) + : Center(child: CupertinoActivityIndicator()), + + Text( + unit ?? 'کیلوگرم', + textAlign: TextAlign.center, + style: + unitStyle ?? + AppFonts.yekan10.copyWith(color: Color(0xFF717171)), + ), + SizedBox(height: 4.h), + ], + ), + ); + } + + Widget cardWidget({ + required String title, + required String iconPath, + required VoidCallback onTap, + }) { + return Container( + width: Get.width / 4, + height: 130, + child: GestureDetector( + onTap: onTap, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide(width: 1, color: AppColor.blueNormal), + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgGenImage(iconPath).svg(width: 50, height: 50), + SizedBox(height: 4), + Text( + title, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + ), + ), + ); + } + + Widget commitmentsList() { + return ObxValue((data) { + return Column( + spacing: 2.h, + children: [ + Row( + children: [ + SizedBox(width: 5.w), + Text( + 'تعهدات', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), + ], + ), + + commitmentsItemList( + title: 'تعهد دولتی توزیع داخل استان', + value: data + .value + ?.totalCommitmentSellingInProvinceGovernmentalWeight + .separatedByComma, + labelColor: const Color(0xFFB9E8DC), + bgColor: const Color(0xFFF3F9F8), + ), + commitmentsItemList( + title: 'توزیع دولتی داخل استان', + value: data + .value + ?.totalSellingInProvinceGovernmentalWeight + .separatedByComma, + labelColor: const Color(0xFFC3D4F3), + bgColor: const Color(0xFFECF3FF), + ), + commitmentsItemList( + title: 'باقیمانده تعهد دولتی توزیع داخل استان', + value: data + .value + ?.totalCommitmentSellingInProvinceGovernmentalRemainWeight + .separatedByComma, + labelColor: const Color(0xFFEBC5CE), + bgColor: const Color(0xFFFFF1F4), + ), + commitmentsItemList( + title: 'تعهد آزاد توزیع داخل استان', + value: data + .value + ?.totalCommitmentSellingInProvinceFreeWeight + .separatedByComma, + labelColor: const Color(0xFFC7DADA), + bgColor: const Color(0xFFE5F7F7), + ), + commitmentsItemList( + title: 'توزیع آزاد داخل استان', + value: + data.value?.totalSellingInProvinceFreeWeight.separatedByComma, + labelColor: const Color(0xFFE0D6ED), + bgColor: const Color(0xFFF5EDFF), + ), + commitmentsItemList( + title: 'باقیمانده تعهد آزاد توزیع داخل استان', + value: data + .value + ?.totalCommitmentSellingInProvinceFreeRemainWeight + .separatedByComma, + labelColor: const Color(0xFFEBC5CE), + bgColor: const Color(0xFFFFF1F4), + ), + ], + ); + }, controller.rootLogic.stewardSalesInfoDashboard); + } + + Container commitmentsItemList({ + required String title, + required String? value, + required Color labelColor, + required Color bgColor, + }) { + return Container( + width: Get.width, + child: Row( + children: [ + Container(height: 48.h, width: 4.w, color: labelColor), + Expanded( + child: Container( + height: 48.h, + padding: EdgeInsets.symmetric(horizontal: 14.w), + decoration: BoxDecoration( + color: bgColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(8), + ), + ), + child: Row( + children: [ + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan12.copyWith(color: AppColor.textColor), + ), + Spacer(), + + value == null + ? Center(child: CupertinoActivityIndicator()) + : Text( + value, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith( + color: AppColor.textColor, + ), + ), + SizedBox(width: 8.w), + + Text( + 'کیلوگرم', + textAlign: TextAlign.right, + style: AppFonts.yekan10.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/root/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/root/logic.dart new file mode 100644 index 0000000..25b475b --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/root/logic.dart @@ -0,0 +1,313 @@ +import 'dart:async'; + +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/local/chicken_local.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/root/logic.dart +import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.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_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; +import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart' + hide ProductModel; +import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart'; +import 'package:rasadyar_chicken/features/common/profile/view.dart'; +import 'package:rasadyar_chicken/features/steward/buy/view.dart'; +import 'package:rasadyar_chicken/features/steward/home/view.dart'; +import 'package:rasadyar_chicken/features/steward/sale/view.dart'; +import 'package:rasadyar_chicken/features/steward/segmentation/view.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart' + hide ProductModel; +import 'package:rasadyar_chicken/features/common/data/repositories/common/common_repository.dart'; +import 'package:rasadyar_chicken/features/steward/data/repositories/steward_repository.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/segmentation/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/root/logic.dart +import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class StewardRootLogic extends GetxController { + DateTime? _lastBackPressed; + RxInt currentPage = 2.obs; + List pages = [ + BuyPage(), + SalePage(), + HomePage(), + SegmentationPage(), + ProfilePage(), + ]; + + final defaultRoutes = { +<<<<<<<< HEAD:packages/chicken/lib/features/steward/root/logic.dart + 0: ChickenRoutes.buySteward, + 1: ChickenRoutes.saleSteward, +======== + 0: StewardRoutes.buySteward, + 1: StewardRoutes.saleSteward, +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/root/logic.dart + }; + RxList rolesProductsModel = RxList(); + Rxn widelyUsedList = Rxn(); + Rxn stewardSalesInfoDashboard = + Rxn(); + Rxn stewardRemainWeight = Rxn(); + + late DioRemote dioRemote; + var tokenService = Get.find(); + late CommonRepository commonRepository; + late StewardRepository stewardRepository; + late ChickenLocalDataSource localDatasource; + + RxList errorLocationType = RxList(); + RxMap inventoryExpandedList = RxMap(); + Rxn inventoryModel = Rxn(); + RxList provinces = [].obs; + + // Cancel tokens for API calls + CancelToken? _inventoryCancelToken; + CancelToken? _provincesCancelToken; + + @override + void onInit() { + super.onInit(); + localDatasource = diChicken.get(); + commonRepository = diChicken.get(); + stewardRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + + if (provinces.isEmpty) { + getProvinces(); + } + if (inventoryModel.value == null) { + getRolesProduct(); + } + if (rolesProductsModel.isEmpty) { + getRolesProducts(); + } + getStewardSaleDashboard(); + getStewardRemainWeightData(); + + if (widelyUsedList.value?.hasInit != true) { + //TODO + localDatasource.initWidleyUsed().then( + (value) => localDatasource.getAllWidely(), + ); + } + } + + @override + void onClose() { + // Cancel any ongoing requests when controller is disposed + _inventoryCancelToken?.cancel(); + _provincesCancelToken?.cancel(); + super.onClose(); + } + + Future onRefresh() async { + await Future.wait([ + getRolesProduct(), + getRolesProducts(), + getStewardSaleDashboard(), + getStewardRemainWeightData(), + getProvinces(), + getStewardRemainWeightData(), + ]); + } + + void toggleExpanded(int index) { + if (inventoryExpandedList.keys.contains(index)) { + inventoryExpandedList.remove(index); + } else { + inventoryExpandedList[index] = false; + } + } + + Future getRolesProduct() async { + // Cancel previous request if still running + _inventoryCancelToken?.cancel(); + _inventoryCancelToken = CancelToken(); + +<<<<<<<< HEAD:packages/chicken/lib/features/steward/root/logic.dart + await safeCall?>( + call: () async => await chickenRepository.getRolesProducts( +======== + await safeCall?>( + call: () async => await commonRepository.getInventory( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/root/logic.dart + token: tokenService.accessToken.value!, + cancelToken: _inventoryCancelToken, + queryParameters: buildRawQueryParams(role: 'Steward'), + ), + onSuccess: (result) { + if (result != null) { + inventoryModel.value = result.first; + } + }, + onError: (error, stackTrace) { + if (error is DioException && error.type == DioExceptionType.cancel) { + // Request was cancelled, ignore the error + return; + } + }, + ); + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + Future getProvinces() async { + // Cancel previous request if still running + _provincesCancelToken?.cancel(); + _provincesCancelToken = CancelToken(); + + try { +<<<<<<<< HEAD:packages/chicken/lib/features/steward/root/logic.dart + final res = await chickenRepository.getProvince( +======== + final res = await commonRepository.getProvince( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/root/logic.dart + cancelToken: _provincesCancelToken, + ); + if (res != null) { + provinces.clear(); + provinces.value = res; + } + } catch (e) { + if (e is DioException && e.type == DioExceptionType.cancel) { + // Request was cancelled, ignore the error + return; + } + provinces.clear(); + } + } + + Future getRolesProducts() async { + safeCall( +<<<<<<<< HEAD:packages/chicken/lib/features/steward/root/logic.dart + call: () async => await chickenRepository.getRolesProducts( + token: tokenService.accessToken.value!, + queryParameters: buildQueryParams(role: 'Steward'), +======== + call: () async => await commonRepository.getRolesProducts( + token: tokenService.accessToken.value!, +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/root/logic.dart + ), + onSuccess: (result) { + if (result != null) { + rolesProductsModel.value = result; + } + }, + onError: (error, stacktrace) {}, + ); + } + + Future getStewardSaleDashboard() async { + safeCall( + call: () async => await stewardRepository.getStewardSalesInfoDashboard( + token: tokenService.accessToken.value!, + queryParameters: buildRawQueryParams(role: 'Steward'), + ), + onSuccess: (result) { + if (result != null) { + stewardSalesInfoDashboard.value = result; + } + }, + onError: (error, stacktrace) {}, + ); + } + + Future getStewardRemainWeightData() async { + safeCall( +<<<<<<<< HEAD:packages/chicken/lib/features/steward/root/logic.dart + call: () async => await chickenRepository.getStewardRemainWeight( +======== + call: () async => await stewardRepository.getStewardRemainWeight( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/root/logic.dart + token: tokenService.accessToken.value!, + ), + onSuccess: (result) { + if (result != null) { + stewardRemainWeight.value = result; + } + }, + onError: (error, stacktrace) {}, + ); + } + + int getNestedKey() { + switch (currentPage.value) { + case 0: + return stewardFirstKey; + case 1: + return stewardSecondKey; + case 2: + return stewardThirdKey; + + case 3: + return stewardFourthKey; + + case 4: + return stewardFourthKey; + + default: + return stewardThirdKey; + } + } + + void onPopScopTaped() async { + final nestedKeyId = getNestedKey(); + GlobalKey? currentNestedKey = Get.nestedKey(nestedKeyId); + + if (currentNestedKey?.currentState?.canPop() == true) { + iLog(currentNestedKey?.currentState?.canPop()); + iLog(currentNestedKey?.currentContext); + currentNestedKey?.currentState?.popUntil((route) => route.isFirst); + } else { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } + } + + bool isKillHouse(WaitingArrivalModel model) => + model.allocationType?.split("_")[0].toLowerCase() == "killhouse"; +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/root/view.dart b/packages/chicken/lib/features/steward/presentation/pages/root/view.dart new file mode 100644 index 0000000..a696b90 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/root/view.dart @@ -0,0 +1,697 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/chicken.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/root/view.dart +import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/root/view.dart +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class StewardRootPage extends GetView { + StewardRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ObxValue((data) { + return ChickenBasePage( + isFullScreen: true, + isBase: true, + onPopScopTaped: controller.onPopScopTaped, + child: Stack( + children: [ + IndexedStack( + children: [ + Navigator( + key: Get.nestedKey(stewardFirstKey), + onGenerateRoute: (settings) { + final page = ChickenPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => ChickenPages.pages.firstWhere( + (e) => e.name == StewardRoutes.buySteward, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + Navigator( + key: Get.nestedKey(stewardSecondKey), + onGenerateRoute: (settings) { + final page = ChickenPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => ChickenPages.pages.firstWhere( + (e) => e.name == StewardRoutes.saleSteward, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + Navigator( + key: Get.nestedKey(stewardThirdKey), + onGenerateRoute: (settings) => + GetPageRoute(page: () => controller.pages[2]), + ), + Navigator( + key: Get.nestedKey(stewardFourthKey), + onGenerateRoute: (settings) => + GetPageRoute(page: () => controller.pages[3]), + ), + Navigator( + key: Get.nestedKey(stewardFifthKey), + onGenerateRoute: (settings) => + GetPageRoute(page: () => controller.pages[4]), + ), + ], + index: data.value, + ), + Positioned( + bottom: 0, + right: 0, + left: 0, + child: RBottomNavigation( + items: [ + RBottomNavigationItem( + label: 'خرید', + icon: Assets.vec.buySvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + stewardFirstKey, + )?.currentState?.popUntil((route) => route.isFirst); + Get.nestedKey( + stewardSecondKey, + )?.currentState?.popUntil((route) => route.isFirst); + + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'فروش', + icon: Assets.vec.saleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + stewardFirstKey, + )?.currentState?.popUntil((route) => route.isFirst); + Get.nestedKey( + stewardSecondKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 2, + onTap: () { + Get.nestedKey( + stewardSecondKey, + )?.currentState?.popUntil((route) => route.isFirst); + Get.nestedKey( + stewardFirstKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(2); + }, + ), + RBottomNavigationItem( + label: 'قطعه بندی', + icon: Assets.vec.convertCubeSvg.path, + isSelected: controller.currentPage.value == 3, + onTap: () { + Get.nestedKey( + stewardSecondKey, + )?.currentState?.popUntil((route) => route.isFirst); + Get.nestedKey( + stewardFirstKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(3); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 4, + onTap: () { + Get.nestedKey( + stewardSecondKey, + )?.currentState?.popUntil((route) => route.isFirst); + Get.nestedKey( + stewardFirstKey, + )?.currentState?.popUntil((route) => route.isFirst); + + controller.changePage(4); + }, + ), + ], + ), + ), + ], + ), + ); + }, controller.currentPage); + } + + Container _todayShipmentWidget() { + return Container( + height: 70, + width: Get.width / 2, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + clipBehavior: Clip.hardEdge, + child: Row( + children: [ + Expanded( + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [const Color(0xFFEAEFFF), Colors.white], + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Assets.icons.cubeScan.svg(width: 30.w, height: 30), + Text( + 'بارهای امروز', + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + ), + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + '2،225،256', + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith(color: AppColor.textColor), + ), + Text( + 'کیلوگرم', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + ], + ), + ); + } + + Container _informationLabelCard({ + required String title, + required String description, + String unit = 'کیلوگرم', + required String iconPath, + required Color iconColor, + required Color bgDescriptionColor, + required Color bgLabelColor, + }) { + return Container( + height: 82, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)), + clipBehavior: Clip.hardEdge, + child: Row( + children: [ + // Left side with icon and title + Expanded( + child: Container( + height: 82, + decoration: BoxDecoration( + color: bgLabelColor, + borderRadius: BorderRadius.only( + topRight: Radius.circular(8), + bottomRight: Radius.circular(8), + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + SvgGenImage.vec(iconPath).svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn), + ), + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + // Right side with description and unit + Expanded( + child: Container( + decoration: BoxDecoration( + color: bgDescriptionColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(8), + ), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + description, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + Text( + unit, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Container _informationIconCard({ + required String title, + required String description, + String unit = 'کیلوگرم', + required String iconPath, + required Color iconColor, + required Color bgDescriptionColor, + required Color bgLabelColor, + }) { + return Container( + height: 110, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)), + clipBehavior: Clip.hardEdge, + child: Stack( + alignment: Alignment.topCenter, + children: [ + Positioned( + bottom: 0, + right: 0, + left: 0, + child: Container( + height: 91, + decoration: BoxDecoration( + color: bgDescriptionColor, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 0.25, color: const Color(0xFFB4B4B4)), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + Text( + description, + textAlign: TextAlign.right, + style: AppFonts.yekan16.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + Text( + unit, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + Positioned( + top: 0, + child: Container( + width: 32, + height: 32, + decoration: ShapeDecoration( + color: bgLabelColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + side: BorderSide(width: 0.25, color: const Color(0xFFD5D5D5)), + ), + ), + child: Center( + child: SvgGenImage.vec(iconPath).svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn), + ), + ), + ), + ), + ], + ), + ); + } + + Widget widelyUsed({ + required String title, + required String iconPath, + required VoidCallback onTap, + }) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + spacing: 4, + children: [ + Container( + width: 48, + height: 48, + padding: EdgeInsets.all(4), + decoration: ShapeDecoration( + color: const Color(0xFFBECDFF), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: Container( + width: 40, + height: 40, + decoration: ShapeDecoration( + color: AppColor.blueNormal, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: SvgGenImage.vec(iconPath).svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), + fit: BoxFit.cover, + ), + ), + ), + Text( + title, + style: AppFonts.yekan10.copyWith(color: AppColor.blueNormal), + ), + ], + ); + } + + Widget addWidelyUsed({required VoidCallback onTap}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + spacing: 4, + children: [ + Container( + width: 48, + height: 48, + padding: EdgeInsets.all(4), + decoration: ShapeDecoration( + color: const Color(0xFFD9F7F0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: Assets.vec.messageAddSvg.svg( + width: 40, + height: 40, + colorFilter: ColorFilter.mode( + AppColor.greenNormal, + BlendMode.srcIn, + ), + fit: BoxFit.cover, + ), + ), + Text( + 'افزودن', + style: AppFonts.yekan10.copyWith(color: AppColor.greenDarkHover), + ), + ], + ); + } + + /*Column oldPage() { + return Column( + children: [ + inventoryWidget(), + ObxValue((data) => broadcastInformationWidget(data.value), controller.killHouseDistributionInfo), + SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + cardWidget( + title: 'ورود به انبار', + iconPath: Assets.icons.whareHouse.path, + onTap: () { + Get.toNamed(ChickenRoutes.enteringTheWarehouse); + }, + ), + cardWidget( + title: 'فروش داخل استان', + iconPath: Assets.icons.inside.path, + onTap: () { + Get.toNamed(ChickenRoutes.salesInProvince); + }, + ), + cardWidget( + title: 'فروش خارج استان', + iconPath: Assets.icons.outside.path, + onTap: () { + Get.toNamed(ChickenRoutes.salesOutOfProvince); + }, + ), + ], + ), + ), + ], + ); + } + + 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, + physics: const NeverScrollableScrollPhysics(), + itemCount: controller.inventoryList.length, + separatorBuilder: (context, index) => const SizedBox(height: 8), + itemBuilder: (context, index) { + return ObxValue((expand) { + return GestureDetector( + onTap: () { + controller.toggleExpanded(index); + }, + behavior: HitTestBehavior.opaque, + child: AnimatedContainer( + onEnd: () { + controller.inventoryExpandedList[index] = !controller.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) ? 250 : 80, + child: inventoryItem( + isExpanded: expand.keys.contains(index) && expand[index]!, + index: index, + model: controller.inventoryList[index], + ), + ), + ); + }, controller.inventoryExpandedList); + }, + ), + controller.inventoryList, + ), + ], + ), + ); + } + + Widget inventoryItem({required bool isExpanded, required int index, required ProductModel 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()), + ], + ), + ), + ], + ); + }*/ + + 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: 1, + child: Text( + value, + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDarkHover, + ), + ), + ), + ], + ), + ); + } + + Widget broadcastInformationWidget(KillHouseDistributionInfo? model) { + return Container( + height: 140, + margin: const EdgeInsets.all(8), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.blueNormal, width: 1), + ), + child: model != null + ? Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 10, + children: [ + Text( + 'اطلاعات ارسالی', + textAlign: TextAlign.right, + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + const SizedBox(height: 12), + buildRow( + 'فروش و توزیع داخل استان (کیلوگرم)', + model.stewardAllocationsWeight!.toInt().toString(), + ), + buildRow( + 'فروش و توزیع خارج استان (کیلوگرم)', + model.freeSalesWeight!.toInt().toString(), + ), + ], + ) + : const Center(child: CircularProgressIndicator()), + ); + } + + Widget cardWidget({ + required String title, + required String iconPath, + required VoidCallback onTap, + }) { + return Container( + width: Get.width / 4, + height: 130, + child: GestureDetector( + onTap: onTap, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide(width: 1, color: AppColor.blueNormal), + ), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgGenImage(iconPath).svg(width: 50, height: 50), + SizedBox(height: 4), + Text( + title, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sale/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/sale/logic.dart new file mode 100644 index 0000000..37fe444 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sale/logic.dart @@ -0,0 +1,149 @@ +import 'package:flutter/services.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/sale/logic.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/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sale/logic.dart +import 'package:rasadyar_core/core.dart'; + +class SaleLogic extends GetxController { + Rxn?> allocatedMadeModel = + Rxn?>(); + + RxList guildsModel = [].obs; + + Rxn stewardFreeDashboard = + Rxn(); + + StewardRootLogic rootLogic = Get.find(); + + List routesName = ['فروش']; + DateTime? _lastBackPressed; + + @override + void onReady() { + super.onReady(); + getStewardDashBord(); + } + + Future getAllocatedMade() async { + safeCall( + call: () async => await rootLogic.stewardRepository.getAllocatedMade( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + page: 1, + pageSize: 20, + search: 'filter', + role: 'Steward', + ), + ), + onSuccess: (result) { + if (result != null) { + allocatedMadeModel.value = result.results; + } + }, + onError: (error, stacktrace) {}, + ); + } + + void checkVerfication() {} + + void confirmAllocation(ConformAllocation allocation) { + safeCall( + call: () async => await rootLogic.stewardRepository.confirmAllocation( + token: rootLogic.tokenService.accessToken.value!, + allocation: allocation.toJson(), + ), + onSuccess: (result) { + getAllocatedMade(); + }, + onError: (error, stacktrace) {}, + ); + } + + void denyAllocation(String token) { + safeCall( + call: () async => await rootLogic.stewardRepository.denyAllocation( + token: rootLogic.tokenService.accessToken.value!, + allocationToken: token, + ), + onSuccess: (result) { + getAllocatedMade(); + }, + onError: (error, stacktrace) {}, + ); + } + + Future confirmAllAllocations() async { + safeCall( + call: () async => await rootLogic.stewardRepository.confirmAllAllocation( + token: rootLogic.tokenService.accessToken.value!, + allocationTokens: + allocatedMadeModel.value?.map((e) => e.key!).toList() ?? [], + ), + onSuccess: (result) { + getAllocatedMade(); + }, + onError: (error, stacktrace) {}, + ); + } + + Future getGuilds() async {} + + Future addSale() async {} + + void setSelectedGuild(GuildModel value) {} + + void setSelectedProduct(ProductModel value) {} + + Future getStewardDashBord() async { + safeCall( + call: () async => await rootLogic.stewardRepository.getStewardDashboard( + token: rootLogic.tokenService.accessToken.value!, + stratDate: DateTime.now().formattedDashedGregorian, + endDate: DateTime.now().formattedDashedGregorian, + ), + onSuccess: (result) { + if (result != null) { + stewardFreeDashboard.value = result; + } + }, + onError: (error, stacktrace) {}, + ); + } + + Future submitAllocation() async {} + + @override + void dispose() { + rootLogic.inventoryExpandedList.clear(); + super.dispose(); + } + + void onPopScopTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sale/view.dart b/packages/chicken/lib/features/steward/presentation/pages/sale/view.dart new file mode 100644 index 0000000..b0ccdbe --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sale/view.dart @@ -0,0 +1,207 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class SalePage extends GetView { + SalePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + isBase: true, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 21, + children: [ + GlassMorphismCardIcon( + title: 'فروش داخل استان', + vecIcon: Assets.vec.map2Svg.path, + onTap: () { + Get.toNamed( + StewardRoutes.salesInProvinceSteward, + id: stewardSecondKey, + ); + }, + ), + GlassMorphismCardIcon( + title: 'فروش خارج استان', + vecIcon: Assets.vec.saleOutProvinceSvg.path, + onTap: () { + Get.toNamed( + StewardRoutes.salesOutOfProvinceSteward, + id: stewardSecondKey, + ); + }, + ), + ], + ), + ], + ), + ); + } + + Widget addSaleOutOfTheProvinceBottomSheet() { + return BaseBottomSheet( + child: Column( + children: [ + const SizedBox(height: 20), + Align( + alignment: Alignment.centerRight, + child: Text( + 'ثبت فروش خارج استان', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + ), + SizedBox(height: 4), + RElevated(text: 'ثبت توزیع/ فروش', onPressed: () {}), + ], + ), + ); + } + + Widget _typeOuterInfoCard({ + required String title, + required String iconPath, + required Color foregroundColor, + VoidCallback? onTap, + }) { + return InkWell( + onTap: onTap, + child: Container( + height: 180, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: foregroundColor), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + Positioned( + top: -41, + child: SvgGenImage.vec(iconPath).svg( + width: 45, + height: 45, + colorFilter: ColorFilter.mode( + foregroundColor, + BlendMode.srcIn, + ), + ), + ), + + Assets.vec.shoppingBasketSvg.svg( + width: 55, + height: 60, + colorFilter: ColorFilter.mode( + foregroundColor, + BlendMode.srcIn, + ), + fit: BoxFit.cover, + ), + ], + ), + const SizedBox(height: 15), + + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan16Bold.copyWith(color: foregroundColor), + ), + ], + ), + ), + ); + } + + Widget summaryOfInformation(StewardFreeBarDashboard? model) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + children: [ + Text( + 'خلاصه اطلاعات', + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + ), + Container( + height: 140, + margin: const EdgeInsets.all(8), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.blueNormal, width: 1), + ), + child: model == null + ? const Center(child: CircularProgressIndicator()) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 10, + children: [ + const SizedBox(height: 12), + buildRow( + 'تعداد کل بارها', + model.totalQuantity?.toString() ?? '0', + ), + buildRow('تعداد کل', model.totalBars?.toString() ?? '0'), + buildRow( + 'وزن کل (کیلوگرم)', + model.totalWeight?.toString() ?? '0', + ), + ], + ), + ), + ], + ); + } + + 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, + ), + ), + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart new file mode 100644 index 0000000..942bd81 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart @@ -0,0 +1,607 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart +import 'package:rasadyar_chicken/data/models/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/data/models/request/submit_steward_allocation/submit_steward_allocation.dart'; +import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart'; +import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/data/models/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/kill_house/warehouse_and_distribution/root/logic.dart'; +import 'package:rasadyar_chicken/features/kill_house/warehouse_and_distribution/sale/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/request/submit_steward_allocation/submit_steward_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild_profile/guild_profile.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart +import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class WarehouseAndDistributionSalesInProvinceLogic extends GetxController { + WarehouseAndDistributionRootLogic rootLogic = Get.find(); + WarehouseAndDistributionSaleLogic saleLogic = Get.find(); + RxnString searchedValue = RxnString(); + RxInt expandedListIndex = (-1).obs; + RxList routesName = RxList(); + Rx bgConfirmAllColor = AppColor.blueNormal.obs; + final RxBool isLoadingMoreAllocationsMade = false.obs; + Timer? _flashingTimer; + + Rx>> allocatedList = + Resource>.loading().obs; + + RxList rolesProductsModel = RxList(); + + RxList guildsModel = [].obs; + + GlobalKey formKey = GlobalKey(); + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + Rxn selectedProductModel = Rxn(); + Rxn selectedGuildModel = Rxn(); + Rxn guildProfile = Rxn(); + RxInt saleType = 1.obs; + RxInt priceType = 2.obs; + RxInt quotaType = 1.obs; + RxInt weight = 0.obs; + RxInt pricePerKilo = 0.obs; + RxInt totalCost = 0.obs; + RxBool isValid = false.obs; + final weightController = TextEditingController(); + final pricePerKiloController = TextEditingController(); + final totalCostController = TextEditingController(); + + final ScrollController scrollControllerAllocationsMade = ScrollController(); + final RxInt currentPage = 1.obs; + final RxBool addPageAllocationsMade = false.obs; + final RxBool hasMoreDataAllocationsMade = true.obs; + + Rxn broadcastPrice = Rxn(); + Rxn selectedAllocationModelForUpdate = + Rxn(); + SubmitStewardAllocation? tmpStewardAllocation; + + Rxn productionDate = Rxn(null); + Rxn remainingStock = Rxn(null); + Map freeProductionDateData = {}; + Map governmentalProductionDateData = {}; + + @override + void onInit() { + super.onInit(); + routesName.value = [...saleLogic.routesName, 'داخل استان'].toList(); + getAllocatedMade(); + getRolesProducts(); + getGuilds(); + getGuildProfile(); + getBroadcastPrice(); + ever(saleType, (callback) { + getGuilds(); + }); + + ever(quotaType, (_) { + remainingStock.value = null; + productionDate.value = null; + }); + + debounce(weight, time: Duration(milliseconds: 110), (callback) { + totalCost.value = callback * pricePerKilo.value; + }); + + debounce(pricePerKilo, time: Duration(milliseconds: 100), (callback) { + totalCost.value = callback * weight.value; + }); + + totalCost.listen((data) { + totalCostController.text = data.toString().separatedByComma; + + isValid.value = + weight.value > 0 && + pricePerKilo.value > 0 && + totalCost.value > 0 && + selectedProductModel.value != null && + selectedGuildModel.value != null; + }); + everAll([ + totalCost, + weight, + pricePerKilo, + totalCost, + selectedProductModel, + selectedGuildModel, + productionDate, + ], (callback) => checkVerification()); + + scrollControllerAllocationsMade.addListener(() { + if (scrollControllerAllocationsMade.position.pixels >= + scrollControllerAllocationsMade.position.maxScrollExtent - 100) { + addPageAllocationsMade.value = true; + getAllocatedMade(); + } + }); + + debounce( + searchedValue, + (callback) => getAllocatedMade(), + time: Duration(milliseconds: timeDebounce), + ); + + _updateGovernmentalProductionDateData(); + _updateFreeProductionDateData(); + /* ever(rootLogic.stewardRemainWeight, (callback) { + _updateGovernmentalProductionDateData(); + _updateFreeProductionDateData(); + }); */ + } + + void _updateGovernmentalProductionDateData() { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* List dates = rootLogic.stewardRemainWeight.value?.governmental ?? []; +======== + List dates = + rootLogic.stewardRemainWeight.value?.governmental ?? []; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + governmentalProductionDateData = { + for (var element in dates) + element.day.toString().toJalali.formatCompactDate(): DayData( + value: element.amount?.toInt(), + ), + }; */ + } + + void _updateFreeProductionDateData() { + /* var dates = rootLogic.stewardRemainWeight.value?.free ?? []; + freeProductionDateData = { + for (var element in dates) + element.day.toString().toJalali.formatCompactDate(): DayData( + value: element.amount?.toInt(), + ), + }; */ + } + + Future getAllocatedMade([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + allocatedList.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 + } + +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.getAllocatedMade( +======== + safeCall( + call: () async => await rootLogic.stewardRepository.getAllocatedMade( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + page: currentPage.value, + pageSize: 20, + search: 'filter', + role: 'Steward', + value: searchedValue.value, + fromDate: fromDateFilter.value.toDateTime(), + toDate: toDateFilter.value.toDateTime(), + ), + ), + onSuccess: (res) async { + await Future.delayed(Duration(milliseconds: 200)); + if ((res?.count ?? 0) == 0) { + allocatedList.value = + Resource>.empty(); + } else { + allocatedList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: isLoadingMore + ? [ + ...(allocatedList.value.data?.results ?? []), + ...(res?.results ?? []), + ] + : res?.results ?? [], + ), + ); + isLoadingMoreAllocationsMade.value = false; + if ((allocatedList.value.data?.results?.length ?? 0) > 1) { + flashingFabBgColor(); + } + } + }, + onError: (error, stacktrace) { + isLoadingMoreAllocationsMade.value = false; + }, + ); */ + + } + + void checkVerification() { + var hasWeight = quotaType.value == 1 + ? weight.value <= + (governmentalProductionDateData[productionDate.value + ?.formatCompactDate()] + ?.value ?? + 0) + : weight.value <= + (freeProductionDateData[productionDate.value?.formatCompactDate()] + ?.value ?? + 0); + + isValid.value = + weight.value > 0 && + pricePerKilo.value > 0 && + totalCost.value > 0 && + hasWeight && + selectedProductModel.value != null && + selectedGuildModel.value != null; + } + + void confirmAllocation(ConformAllocation allocation) { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.confirmAllocation( +======== + safeCall( + call: () async => await rootLogic.stewardRepository.confirmAllocation( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + allocation: allocation.toJson(), + ), + onSuccess: (result) { + getAllocatedMade(); + }, + onError: (error, stacktrace) {}, + ); */ + } + + void denyAllocation(String token) { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.denyAllocation( +======== + safeCall( + call: () async => await rootLogic.stewardRepository.denyAllocation( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + allocationToken: token, + ), + onSuccess: (result) { + getAllocatedMade(); + }, + onError: (error, stacktrace) {}, + ); */ + } + + Future confirmAllAllocations() async { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.confirmAllAllocation( +======== + safeCall( + call: () async => await rootLogic.stewardRepository.confirmAllAllocation( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + allocationTokens: + allocatedList.value.data?.results?.map((e) => e.key!).toList() ?? + [], + ), + onSuccess: (result) { + getAllocatedMade(); + }, + onError: (error, stacktrace) {}, + ); */ + } + + Future getRolesProducts() async { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.getRolesProducts( +======== + safeCall( + call: () async => await rootLogic.commonRepository.getRolesProducts( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + role: 'Steward', + ), + onSuccess: (result) { + if (result != null) { + rolesProductsModel.value = result; + selectedProductModel.value = result.first; + } + }, + onError: (error, stacktrace) {}, + ); */ + } + + Future getGuilds() async { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.getGuilds( +======== + safeCall( + call: () async => await rootLogic.commonRepository.getGuilds( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + //queryParams: {'free': saleType.value == 2 ? true : false}, + queryParams: {'all': true}, + role: 'Steward', + ), + ), + onSuccess: (result) { + if (result != null) { + guildsModel.clear(); + guildsModel.addAll(result); + } + }, + onError: (error, stacktrace) {}, + ); */ + } + + Future addSale() async {} + + void setSelectedGuild(GuildModel value) { + selectedGuildModel.value = value; + update(); + } + + void setSelectedProduct(ProductModel value) { + selectedProductModel.value = value; + update(); + } + + Future getGuildProfile() async { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* await safeCall( + call: () async => await rootLogic.chickenRepository.getProfile( +======== + await safeCall( + call: () async => await rootLogic.commonRepository.getProfile( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + ), + onError: (error, stackTrace) {}, + onSuccess: (result) { + guildProfile.value = result; + }, + ); */ + } + + void setSubmitData() { + tmpStewardAllocation = SubmitStewardAllocation( + approvedPriceStatus: priceType.value == 1, + allocationType: + '${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", + amount: pricePerKilo.value, + totalAmount: totalCost.value, + weightOfCarcasses: weight.value, + sellType: saleType.value == 2 ? "free" : 'exclusive', + numberOfCarcasses: 0, + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, + quota: quotaType.value == 1 ? 'governmental' : 'free', + guildKey: selectedGuildModel.value?.key, + productKey: selectedProductModel.value?.key, + date: DateTime.now().formattedDashedGregorian, + type: "manual", + ); + } + + Future submitAllocation() async { + setSubmitData(); + + /* safeCall( + showError: true, + call: () async => + await rootLogic.stewardRepository.postSubmitStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + request: tmpStewardAllocation!, + ), + + onSuccess: (result) { + clearForm(); + onRefresh(); + rootLogic.onRefresh(); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("ثبت موفق بود"), + ); + Get.back(); + }, + onError: (error, stackTrace) {}, + ); */ + } + + Future deleteAllocation(AllocatedMadeModel model) async { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.deleteStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: {'steward_allocation_key': model.key}, + ), +======== + safeCall( + call: () async => + await rootLogic.stewardRepository.deleteStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: {'steward_allocation_key': model.key}, + ), +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + + onSuccess: (result) { + getAllocatedMade(); + }, + onError: (error, stackTrace) {}, + ); */ + } + + @override + void dispose() { + rootLogic.inventoryExpandedList.clear(); + stopFlashing(); + super.dispose(); + } + + void setEditData(AllocatedMadeModel item) { + selectedAllocationModelForUpdate.value = item; + selectedProductModel.value = rolesProductsModel.first; + selectedGuildModel.value = GuildModel(guildsName: 'tst'); + weight.value = item.weightOfCarcasses ?? 0; + pricePerKilo.value = item.amount ?? 0; + totalCost.value = item.totalAmount ?? 0; + weightController.text = weight.value.toString().separatedByComma; + pricePerKiloController.text = pricePerKilo.value + .toString() + .separatedByComma; + totalCostController.text = totalCost.value.toString().separatedByComma; + isValid.value = true; + productionDate.value = item.productionDate.toJalali; + } + + void clearForm() { + selectedGuildModel.value = null; + weight.value = 0; + totalCost.value = 0; + weightController.clear(); + if (broadcastPrice.value?.active == false) { + pricePerKilo.value = 0; + pricePerKiloController.clear(); + } + totalCostController.clear(); + isValid.value = false; + productionDate.value = null; + quotaType.value = 1; + priceType.value = 2; + saleType.value = 2; + } + + Future updateAllocation() async { + ConformAllocation updatedAllocationModel = ConformAllocation( + allocation_key: selectedAllocationModelForUpdate.value?.key, + amount: pricePerKilo.value, + total_amount: totalCost.value, + number_of_carcasses: 0, + weight_of_carcasses: weight.value, + ); + + /* safeCall( + showError: true, + call: () async => + await rootLogic.stewardRepository.updateStewardAllocation( + token: rootLogic.tokenService.accessToken.value!, + request: updatedAllocationModel, + ), + + onSuccess: (result) { + clearForm(); + onRefresh(); + rootLogic.onRefresh(); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("ویرایش موفق بود"), + ); + Get.back(); + }, + onError: (error, stackTrace) {}, + ); */ + } + + void setSearchValue(String? data) { + searchedValue.value = data?.trim(); + } + + void flashingFabBgColor() { + _flashingTimer?.cancel(); + + _flashingTimer = Timer.periodic(Duration(seconds: 2), (timer) { + if (bgConfirmAllColor.value == AppColor.blueNormal) { + bgConfirmAllColor.value = AppColor.blueLightHover; + } else { + bgConfirmAllColor.value = AppColor.blueNormal; + } + }); + } + + void stopFlashing() { + _flashingTimer?.cancel(); + _flashingTimer = null; + bgConfirmAllColor.value = AppColor.blueNormal; // بازگرداندن به رنگ پیش‌فرض + } + + Steward? getBuyerInformation(AllocatedMadeModel model) { + if (model.allocationType?.buyerIsGuild ?? false) { + return model.toGuilds; + } else { + return model.steward; + } + } + + Future getBroadcastPrice() async { +<<<<<<<< HEAD:packages/chicken/lib/features/kill_house/warehouse_and_distribution/sales_in_province/logic.dart + /* safeCall( + call: () async => await rootLogic.chickenRepository.getBroadcastPrice( +======== + safeCall( + call: () async => await rootLogic.commonRepository.getBroadcastPrice( +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/logic.dart + token: rootLogic.tokenService.accessToken.value!, + ), + onSuccess: (result) { + broadcastPrice.value = result; + if (broadcastPrice.value?.active == true) { + pricePerKilo.value = broadcastPrice.value?.stewardPrice ?? 0; + pricePerKiloController.text = pricePerKilo.value + .toString() + .separatedByComma; + priceType.value = 2; + } + }, + onError: (error, stacktrace) {}, + ); */ + } + + Future onRefresh() async { + toggleExpansion(); + currentPage.value = 1; + hasMoreDataAllocationsMade.value = true; + await Future.wait([ + getAllocatedMade(), + getRolesProducts(), + rootLogic.onRefresh(), + ]); + } + + void toggleExpansion({int? index}) { + if (expandedListIndex.value == index || index == null) { + expandedListIndex.value = -1; + } else { + expandedListIndex.value = index; + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/view.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/view.dart new file mode 100644 index 0000000..b07cc81 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/view.dart @@ -0,0 +1,532 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/sales_in_province/view.dart +import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/steward/sales_in_province/widgets/cu_sale_in_provience.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_in_province/widgets/cu_sale_in_provience.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/view.dart +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/inventory/inventory_widget.dart'; + +import 'package:rasadyar_core/core.dart' hide modalDatePicker; + +import 'logic.dart'; + +class SalesInProvincePage extends GetView { + SalesInProvincePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + backId: stewardSecondKey, + onSearchChanged: (data) => controller.setSearchValue(data), + onRefresh: controller.onRefresh, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + child: Stack( + children: [ + Positioned.fill( + child: Column( + children: [ + Obx(() { + var list = [ + InventoryItemData( + title: 'موجودی انبار', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalRemainWeight + ?.separatedByCommaFa, + color: const Color(0xFFEAFBFC), + ), + InventoryItemData( + title: 'مانده دولتی', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalGovernmentalRemainWeight + ?.separatedByCommaFa, + + color: const Color(0xFFF5ECEE), + ), + InventoryItemData( + title: 'مانده آزاد', + value: controller + .rootLogic + .inventoryModel + .value + ?.totalFreeRemainWeight + ?.separatedByCommaFa, + + color: const Color(0xFFF1E7FF), + ), + ]; + + return InventoryWidget(inventoryModel: list); + }), + + Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + isPaginating: controller.isLoadingMoreAllocationsMade.value, + onLoadMore: () async { + controller.currentPage.value++; + await controller.getAllocatedMade(true); + }, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value == index, + onTap: () => controller.toggleExpansion(index: index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item, index), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.timerSvg.path, + labelIconColor: item.registrationCode == null + ? AppColor.darkGreyDark + : AppColor.error, + ); + }, controller.expandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.allocatedList), + ), + ], + ), + ), + Positioned( + right: 5, + bottom: 95, + child: SizedBox( + width: Get.width - 30, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + RFab.add( + onPressed: () { + Get.bottomSheet( + addOrEditBottomSheet(controller), + isScrollControlled: true, + backgroundColor: Colors.transparent, + ).whenComplete(() { + controller.clearForm(); + }); + }, + ), + + ObxValue((data) { + return Visibility( + visible: (data.value.data?.results?.length ?? 0) > 1, + child: AnimatedFab( + onPressed: () async { + Get.defaultDialog( + title: 'تایید یکجا', + middleText: 'آیا از تایید تمامی تخصیص ها اطمینان دارید؟', + confirm: ElevatedButton( + onPressed: () async { + await controller.confirmAllAllocations(); + controller.getAllocatedMade(); + controller.rootLogic.getRolesProduct(); + Get.back(); + }, + child: Text('تایید'), + style: ElevatedButton.styleFrom( + backgroundColor: AppColor.blueNormal, + foregroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + ), + cancel: OutlinedButton( + style: OutlinedButton.styleFrom( + foregroundColor: AppColor.error, + enableFeedback: true, + side: BorderSide(color: AppColor.error, width: 1), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + onPressed: () { + Get.back(); + }, + child: Text('لغو'), + ), + ); + }, + message: 'تایید یکجا', + icon: Assets.vec.clipboardTaskSvg.svg(width: 40.w, height: 40.h), + backgroundColor: controller.bgConfirmAllColor.value, + ), + ); + }, controller.allocatedList), + ], + ), + ), + ), + ], + ), + ); + } + + Row itemListWidget(AllocatedMadeModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + controller.getBuyerInformation(item)?.user?.fullname ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + + SizedBox(height: 2), + Text( + item.createDate?.formattedJalaliDate ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + spacing: 6, + children: [ + Visibility( + visible: item.product?.name?.contains('مرغ گرم') ?? false, + child: Assets.vec.hotChickenSvg.svg( + width: 24, + height: 24, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + Text( + item.weightOfCarcasses!.separatedByCommaFa.addKg, + textAlign: TextAlign.left, + textDirection: TextDirection.ltr, + style: AppFonts.yekan12Bold.copyWith(color: AppColor.blueNormal), + ), + ], + ), + SizedBox(height: 2), + Text( + item.amount.separatedByCommaFa.addReal, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.darkGreyDark), + ), + ], + ), + ), + + SizedBox(width: 8), + + Expanded( + flex: 2, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + item.approvedPriceStatus == true + ? 'دولتی' + : item.approvedPriceStatus == false + ? 'آزاد' + : '-', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith( + color: item.approvedPriceStatus == true + ? AppColor.blueNormal + : AppColor.greenNormal, + ), + ), + ], + ), + ), + + SizedBox(width: 8), + ], + ); + } + + Container itemListExpandedWidget(AllocatedMadeModel item, int index) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + controller.getBuyerInformation(item)?.user?.fullname ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + Text( + item.registrationCode == null ? 'در انتظار' : 'در انتظار تایید خریدار', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith( + color: item.registrationCode == null ? AppColor.darkGreyDark : AppColor.error, + ), + ), + SizedBox(width: 7), + Assets.vec.clockSvg.svg( + width: 16.w, + height: 16.h, + colorFilter: ColorFilter.mode( + item.registrationCode == null ? AppColor.darkGreyDark : AppColor.error, + BlendMode.srcIn, + ), + ), + ], + ), + 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( + item.date?.toJalali.formatter.wN ?? 'ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + ], + ), + + Text( + '${item.date?.toJalali.formatter.y}', + style: AppFonts.yekan20.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + buildRow( + title: 'تلفن خریدار', + value: controller.getBuyerInformation(item)?.user?.mobile ?? 'ندارد', + valueStyle: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + buildRow(title: 'محصول', value: item.product?.name ?? 'ندارد'), + + buildRow( + title: 'تاریخ تولید گوشت', + value: item.productionDate?.toJalali.formatCompactDate() ?? 'ندارد', + ), + + buildRow(title: 'نوع تخصیص', value: item.allocationType?.faAllocationType ?? 'ندارد'), + buildRow( + title: 'نوع فروش', + value: (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد', + ), + buildRow(title: 'نوع انبار', value: (item.quota == 'governmental') ? 'دولتی' : 'آزاد'), + + buildRow( + title: 'وزن خریداری شده', + value: '${item.weightOfCarcasses?.separatedByCommaFa} کیلوگرم', + ), + buildRow( + title: 'افت وزن(کیلوگرم)', + value: item.weightLossOfCarcasses?.toInt().toString() ?? 'ندارد', + ), + buildRow( + title: 'قیمت هر کیلوگرم', + titleLabel: (item.approvedPriceStatus ?? false) ? 'دولتی' : 'آزاد', + titleLabelStyle: AppFonts.yekan14Bold.copyWith( + color: (item.approvedPriceStatus ?? false) + ? AppColor.blueNormal + : AppColor.greenNormal, + ), + value: '${item.amount?.separatedByCommaFa} ریال', + ), + buildRow(title: 'قیمت کل', value: '${item.totalAmount?.separatedByCommaFa} ریال'), + + buildRow(title: 'کداحراز', value: item.registrationCode?.toString() ?? 'ندارد'), + buildRow( + title: 'وضعیت کد احراز', + value: item.systemRegistrationCode == true ? "ارسال شده" : "ارسال نشده", + ), + + Visibility( + visible: item.registrationCode == null, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + RElevated( + text: 'ویرایش', + width: 150.w, + height: 40.h, + onPressed: () { + controller.setEditData(item); + Get.bottomSheet( + addOrEditBottomSheet(controller, isEditMode: true), + isScrollControlled: true, + backgroundColor: Colors.transparent, + ).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.toggleExpansion(index: index); + + await controller.deleteAllocation(item); + }, + onRefresh: controller.onRefresh, + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ), + ], + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text('فیلترها', style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal)), + Row( + spacing: 8, + children: [ + Expanded( + child: timeFilterWidget( + controller: controller, + date: controller.fromDateFilter, + onChanged: (jalali) => controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: timeFilterWidget( + controller: controller, + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getAllocatedMade(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } + + GestureDetector timeFilterWidget({ + required SalesInProvinceLogic controller, + isFrom = true, + required Rx date, + required Function(Jalali jalali) onChanged, + }) { + return GestureDetector( + onTap: () { + Get.bottomSheet(modalDatePicker((value) => onChanged(value))); + }, + child: Container( + height: 35, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.blueNormal), + ), + padding: EdgeInsets.symmetric(horizontal: 11, vertical: 4), + child: Row( + spacing: 8, + children: [ + Assets.vec.calendarSvg.svg( + width: 24, + height: 24, + colorFilter: const ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + Text( + isFrom ? 'از' : 'تا', + style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal), + ), + Expanded( + child: ObxValue((data) { + return Text( + date.value.formatCompactDate(), + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.lightGreyNormalActive), + ); + }, date), + ), + ], + ), + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/widgets/cu_sale_in_provience.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/widgets/cu_sale_in_provience.dart new file mode 100644 index 0000000..afca3b8 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_in_province/widgets/cu_sale_in_provience.dart @@ -0,0 +1,520 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/sales_in_province/widgets/cu_sale_in_provience.dart +import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/sales_in_province/logic.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_in_province/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_in_province/widgets/cu_sale_in_provience.dart +import 'package:rasadyar_core/core.dart'; + +Widget addOrEditBottomSheet(SalesInProvinceLogic controller, {bool isEditMode = false}) { + return BaseBottomSheet( + height: Get.height * (isEditMode ? 0.60 : 0.75), + child: Form( + key: controller.formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '${isEditMode ? 'ویرایش' : 'ثبت'} توزیع/ فروش', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + const SizedBox(height: 12), + productDropDown(controller), + const SizedBox(height: 12), + + 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: [ + const SizedBox(height: 8), + ObxValue((data) { + return RTextField( + controller: TextEditingController(), + filledColor: AppColor.bgLight, + filled: true, + label: 'تاریخ', + onTap: () { + Get.bottomSheet( + modalDatePicker((value) { + controller.fromDateFilter.value = value; + controller.fromDateFilter.refresh(); + }), + ); + }, + borderColor: AppColor.darkGreyLight, + initText: (data.value).formatCompactDate(), + ); + }, controller.fromDateFilter), + Visibility( + visible: isEditMode == false, + child: Container( + height: 50.h, + clipBehavior: Clip.none, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Stack( + fit: StackFit.expand, + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Positioned( + child: Container(color: Colors.white, child: Text("انبار")), + top: -10, + right: 8, + ), + Obx(() { + return RadioGroup( + groupValue: controller.quotaType.value, + onChanged: (value) { + controller.quotaType.value = value ?? 0; + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + controller.quotaType.value = 1; + }, + child: Row( + children: [ + Radio(value: 1), + Text('دولتی', style: AppFonts.yekan14), + ], + ), + ), + ), + + Expanded( + child: GestureDetector( + onTap: () { + controller.quotaType.value = 2; + }, + child: Row( + children: [ + Radio(value: 2), + Text('آزاد', style: AppFonts.yekan14), + ], + ), + ), + ), + ], + ), + ); + }), + ], + ), + ), + ), + + Obx(() { + return MonthlyDataCalendar( + label: 'تاریخ تولید گوشت', + selectedDate: controller.productionDate.value?.formatCompactDate(), + onDateSelect: (value) { + controller.productionDate.value = value.date; + controller.remainingStock.value = value.remainingStock; + }, + dayData: controller.quotaType.value == 1 + ? controller.governmentalProductionDateData + : controller.freeProductionDateData, + ); + }), + + Visibility(visible: isEditMode == false, child: guildsDropDown(controller)), + + RTextField( + controller: controller.weightController, + keyboardType: TextInputType.number, + autoValidateMode: AutovalidateMode.onUserInteraction, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + validator: (value) { + if ((int.tryParse(value?.clearComma ?? '0') ?? 0) > + (controller.remainingStock.value ?? 0)) { + return 'وزن تخصیصی بیشتر از موجودی انبار است'; + } + return null; + }, + onChanged: (p0) { + controller.weight.value = int.tryParse(p0.clearComma) ?? 0; + }, + label: 'وزن لاشه (کیلوگرم)', + ), + + Visibility( + visible: isEditMode == false, + child: Container( + height: 58.h, + clipBehavior: Clip.none, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Stack( + fit: StackFit.expand, + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Positioned( + child: Container(color: Colors.white, child: Text("فروش")), + top: -10, + right: 8, + ), + Obx(() { + return RadioGroup( + groupValue: controller.priceType.value, + onChanged: (value) { + controller.priceType.value = value!; + }, + child: Row( + children: [ + Expanded( + child: GestureDetector( + onTap: (controller.broadcastPrice.value?.active ?? false) + ? () { + controller.priceType.value = 1; + } + : null, + child: Row( + children: [ + Radio( + value: 1, + enabled: controller.broadcastPrice.value?.active ?? false, + ), + Text( + 'قیمت مصوب', + style: AppFonts.yekan14.copyWith( + color: + (controller.broadcastPrice.value?.active ?? false) + ? AppColor.textColor + : AppColor.labelTextColor, + ), + ), + ], + ), + ), + ), + + Expanded( + child: GestureDetector( + onTap: () { + controller.priceType.value = 2; + }, + child: Row( + children: [ + Radio(value: 2), + Text('قیمت آزاد', style: AppFonts.yekan14), + ], + ), + ), + ), + ], + ), + ); + }), + ], + ), + ), + ), + + ObxValue((data) { + return RTextField( + variant: RTextFieldVariant.noBorder, + controller: controller.pricePerKiloController, + borderColor: AppColor.darkGreyLight, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + filledColor: AppColor.bgLight, + filled: true, + readonly: data.value == 1, + onChanged: (p0) { + controller.pricePerKilo.value = int.tryParse(p0.clearComma) ?? 0; + }, + keyboardType: TextInputType.number, + label: 'قیمت هر کیلو (ريال)', + ); + }, controller.priceType), + + RTextField( + variant: RTextFieldVariant.noBorder, + enabled: false, + keyboardType: TextInputType.number, + filledColor: AppColor.bgLight, + filled: true, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + controller: controller.totalCostController, + label: 'هزینه کل (ريال)', + ), + ], + ), + ), + + SizedBox(height: 12.h), + ObxValue((data) { + return RElevated( + text: isEditMode ? 'ویرایش' : 'ثبت', + isFullWidth: true, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + height: 40, + enabled: data.value, + onPressed: isEditMode + ? () async { + await controller.updateAllocation(); + Get.back(); + } + : () async { + await controller.submitAllocation(); + Get.back(); + }, + ); + }, controller.isValid), + const SizedBox(height: 20), + ], + ), + ), + ); +} + +Widget guildsDropDown(SalesInProvinceLogic controller) { + return Obx(() { + final item = controller.selectedGuildModel.value; + + return SearchableDropdown( + onChanged: (value) { + controller.selectedGuildModel.value = value; + }, + selectedItem: [?item], + singleSelect: false, + items: controller.guildsModel, + hintText: 'انتخاب مباشر/صنف', + itemBuilder: (item) => Text( + item.user != null + ? '${item.steward == true ? 'مباشر' : 'صنف'} ${item.user!.fullname} (${item.user!.mobile})' + : 'بدون نام', + ), + multiLabelBuilder: (item) => Container( + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight), + ), + padding: EdgeInsets.all(4), + child: Row( + children: [ + Text( + item?.user != null + ? '${item?.steward == true ? 'مباشر' : 'صنف'} ${item?.user!.fullname}' + : 'بدون نام', + style: AppFonts.yekan14, + ), + SizedBox(width: 4.w), + Icon(Icons.close, size: 16, color: AppColor.labelTextColor), + ], + ), + ), + onSearch: (query) async { + return Future.microtask(() { + return RxList( + controller.guildsModel + .where((element) => element.user?.fullname?.contains(query) ?? false) + .toList(), + ); + }); + }, + ); + }); +} + +Widget productDropDown(SalesInProvinceLogic controller) { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rolesProductsModel, + height: 56, + hasDropIcon: false, + background: Colors.white, + onChanged: (value) { + controller.selectedProductModel.value = value; + }, + selectedItem: controller.selectedProductModel.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(), + + ObxValue((data) { + return Visibility(visible: data.value != null, child: Text('موجودی: $data')); + }, controller.remainingStock), + ], + ), + ); + }); +} + +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(), + minimumDate: Jalali.now().add(days: -1), + maximumDate: Jalali.now(), + mode: PersianCupertinoDatePickerMode.date, + onDateTimeChanged: (dateTime) { + tempPickedDate = dateTime; + }, + ), + ), + ), + ], + ), + ); +} + +Widget show2StepAddBottomSheet(SalesInProvinceLogic controller) { + return BaseBottomSheet( + height: Get.height * .39, + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'تاریخ ثبت', + value: controller.tmpStewardAllocation?.date?.formattedJalaliDate ?? 'ندارد', + ), + buildRow( + title: 'نام و نام خانوادگی خریدار', + value: + controller.guildsModel + .firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey) + .user + ?.fullname ?? + 'ندارد', + ), + buildRow( + title: 'شماره خریدار', + value: + controller.guildsModel + .firstWhere((p0) => p0.key == controller.tmpStewardAllocation?.guildKey) + .user + ?.mobile ?? + 'ندارد', + ), + + buildRow( + title: 'قیمت هر کیلو', + value: '${controller.tmpStewardAllocation?.amount.separatedByCommaFa ?? 0} ریال ', + ), + buildRow( + title: 'وزن تخصیصی', + value: + '${controller.tmpStewardAllocation?.weightOfCarcasses?.toInt().separatedByCommaFa ?? 0} کیلوگرم', + ), + buildRow( + title: 'قیمت کل', + value: '${controller.tmpStewardAllocation?.totalAmount.separatedByCommaFa ?? 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 + ..back() + ..back(); + }, + ), + ), + ], + ), + ], + ), + ); +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/logic.dart new file mode 100644 index 0000000..92071cd --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/logic.dart @@ -0,0 +1,418 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/sales_out_of_province/logic.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/broadcast_price/broadcast_price.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/data/models/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sales_out_of_province_buyers/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sales_out_of_province_sales_list/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_sales_list/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/logic.dart +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class SalesOutOfProvinceLogic extends GetxController { + StewardRootLogic rootLogic = Get.find(); + + SaleLogic saleLogic = Get.find(); + + SalesOutOfProvinceSalesListLogic saleListLogic = + Get.find(); + + SalesOutOfProvinceBuyersLogic buyerLogic = + Get.find(); + + RxBool isExpanded = false.obs; + RxInt currentPage = 1.obs; + RxBool isSaleSubmitButtonEnabled = false.obs; + RxInt expandedListIndex = (-1).obs; + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + RxList routesName = RxList(); + RxBool isLoadingMoreAllocationsMade = false.obs; + Rxn selectedCity = Rxn(); + Rxn broadcastPrice = Rxn(); + GlobalKey formKey = GlobalKey(); + TextEditingController quarantineCodeController = TextEditingController(); + TextEditingController saleWeightController = TextEditingController(); + TextEditingController saleCountController = TextEditingController(); + TextEditingController pricePerKiloController = TextEditingController(); + TextEditingController totalCostController = TextEditingController(); + TextEditingController otpCodeSell = TextEditingController(); + Rx saleDate = Jalali.now().obs; + String? key; + RxInt pricePerKilo = 0.obs; + RxInt totalCost = 0.obs; + RxInt weight = 0.obs; + RxString otpCode = ''.obs; + + Rx>> salesList = + Resource>.loading().obs; + + Rxn selectedProduct = Rxn(); + Rxn selectedBuyer = Rxn(); + + RxInt saleType = 2.obs; + RxInt quotaType = 1.obs; + Rxn productionDate = Rxn(); + Rxn remainingStock = Rxn(null); + Map freeProductionDateData = {}; + Map governmentalProductionDateData = {}; + + @override + void onInit() { + super.onInit(); + routesName.value = [...saleLogic.routesName, 'خارج استان'].toList(); + } + + @override + void onReady() { + super.onReady(); + getOutProvinceSales(); + getBroadcastPrice(); + selectedProduct.value = rootLogic.rolesProductsModel.first; + debounce( + searchedValue, + (callback) => getOutProvinceSales(), + time: Duration(milliseconds: timeDebounce), + ); + setupListeners(); + + _updateGovernmentalProductionDateData(); + _updateFreeProductionDateData(); + ever(rootLogic.stewardRemainWeight, (callback) { + _updateGovernmentalProductionDateData(); + _updateFreeProductionDateData(); + }); + ever(quotaType, (_) { + remainingStock.value = null; + productionDate.value = null; + }); + debounce(pricePerKilo, time: Duration(milliseconds: 100), (callback) { + totalCost.value = callback * (weight.value); + }); + + ever(totalCost, (callback) { + totalCostController.text = callback.separatedByComma; + }); + } + + void _updateGovernmentalProductionDateData() { + List dates = + rootLogic.stewardRemainWeight.value?.governmental ?? []; + governmentalProductionDateData = { + for (var element in dates) + element.day.toString().toJalali.formatCompactDate(): DayData( + value: element.amount?.toInt(), + ), + }; + } + + void _updateFreeProductionDateData() { + var dates = rootLogic.stewardRemainWeight.value?.free ?? []; + freeProductionDateData = { + for (var element in dates) + element.day.toString().toJalali.formatCompactDate(): DayData( + value: element.amount?.toInt(), + ), + }; + } + + void setSearchValue(String? value) { + searchedValue.value = value?.trim(); + } + + void submitFilter() { + fromDateFilter.value = fromDateFilter.value; + toDateFilter.value = toDateFilter.value; + getOutProvinceSales(); + } + + Future getOutProvinceSales([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + salesList.value = Resource>.loading(); + } + await safeCall( + call: () => rootLogic.stewardRepository.getStewardFreeSaleBar( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + pageSize: 20, + page: currentPage.value, + 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>.empty(); + } else { + salesList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(salesList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + + isLoadingMoreAllocationsMade.value = false; + } + }, + ); + } + + void setupListeners() { + saleWeightController.addListener(checkSalesFormValid); + quarantineCodeController.addListener(checkSalesFormValid); + saleWeightController.addListener(() { + checkSalesFormValid(); + weight.value = int.parse(saleWeightController.text.clearComma); + var res = (weight / selectedProduct.value!.weightAverage!.toInt()) + .round(); + saleCountController.text = res.separatedByComma; + }); + ever(selectedBuyer, (_) => checkSalesFormValid); + ever(selectedProduct, (_) => checkSalesFormValid); + ever(saleDate, (_) => checkSalesFormValid()); + } + + void checkSalesFormValid() { + isSaleSubmitButtonEnabled.value = + saleDate.value.toString().isNotEmpty && + selectedProduct.value != null && + selectedBuyer.value != null && + saleWeightController.text.isNotEmpty && + quarantineCodeController.text.isNotEmpty; + } + + 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 = buyerLogic.buyerList.value.data?.results?.firstWhere( + (element) => element.key == item.buyer?.key, + ); + selectedProduct.value = rootLogic.rolesProductsModel.first; + key = item.key; + saleType.value = item.saleType == 'free' ? 2 : 1; + quotaType.value = item.quota == 'governmental' ? 1 : 2; + isSaleSubmitButtonEnabled.value = true; + productionDate.value = item.productionDate.toJalali; + pricePerKiloController.text = pricePerKilo.value + .toString() + .separatedByComma; + totalCostController.text = totalCost.value.toString().separatedByComma; + } + + Future deleteStewardPurchaseOutOfProvince(String key) async { + await safeCall( + call: () => rootLogic.stewardRepository.deleteOutProvinceStewardFreeBar( + token: rootLogic.tokenService.accessToken.value!, + key: key, + ), + ); + } + + Future createSale() async { + bool res = false; + StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest( + buyerKey: selectedBuyer.value?.key, + numberOfCarcasses: int.tryParse(saleCountController.text.clearComma), + weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma), + date: saleDate.value.toDateTime().formattedDashedGregorian, + clearanceCode: quarantineCodeController.text, + productKey: selectedProduct.value?.key, + saleType: saleType.value == 2 ? 'free' : 'exclusive', + quota: quotaType.value == 1 ? 'governmental' : 'free', +<<<<<<<< HEAD:packages/chicken/lib/features/steward/sales_out_of_province/logic.dart + productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, + distributionType: 'App', + ); +======== + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, + ); +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/logic.dart + await safeCall( + showError: true, + call: () => rootLogic.stewardRepository.createOutProvinceStewardFreeBar( + token: rootLogic.tokenService.accessToken.value!, + body: requestBody, + ), + onSuccess: (_) { + res = true; + onRefresh(); + rootLogic.onRefresh(); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("عملیات با موفقیت انجام شد"), + ); + Get.back(); + }, + ); + return res; + } + + void clearSaleForm() { + quarantineCodeController.clear(); + saleWeightController.clear(); + saleDate.value = Jalali.now(); + productionDate.value = null; + saleType.value = 2; + quotaType.value = 2; + selectedBuyer.value = null; + } + + Future editSale() async { + bool res = false; + StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest( + numberOfCarcasses: int.tryParse(saleCountController.text.clearComma), + weightOfCarcasses: int.tryParse(saleWeightController.text.clearComma), + date: saleDate.value.toDateTime().formattedDashedGregorian, + clearanceCode: quarantineCodeController.text, + saleType: saleType.value == 2 ? 'free' : 'exclusive', + quota: quotaType.value == 1 ? 'governmental' : 'free', + key: key, + ); + await safeCall( + call: () => rootLogic.stewardRepository.updateOutProvinceStewardFreeBar( + token: rootLogic.tokenService.accessToken.value!, + body: requestBody, + ), + onSuccess: (_) { + res = true; + onRefresh(); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("عملیات با موفقیت انجام شد"), + ); + Get.back(); + }, + ); + return res; + } + + Future sendSaleOtpCode(StewardFreeSaleBar item) async { + StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest( + buyerKey: item.buyer?.key, + buyerName: item.buyer?.fullname, + buyerMobile: item.buyer?.mobile, + numberOfCarcasses: item.numberOfCarcasses, + weightOfCarcasses: item.weightOfCarcasses?.toInt(), + date: item.date, + clearanceCode: item.clearanceCode, + registerCode: otpCode.value, + saleType: item.saleType, + quota: item.quota, + role: "Steward", + key: item.key, + city: item.city, + province: item.province, + ); + await safeCall( + showError: true, + call: () => rootLogic.stewardRepository.updateOutProvinceStewardFreeBar( + token: rootLogic.tokenService.accessToken.value!, + body: requestBody, + ), + onSuccess: (_) { + onRefresh(); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("عملیات با موفقیت انجام شد"), + ); + Get.back(); + }, + ); + } + + void resetSubmitForm() { + selectedCity.value = null; + + key = null; + } + + Future onRefresh() async { + toggleExpansion(); + currentPage.value = 1; + resetSubmitForm(); + clearSaleForm(); + await rootLogic.onRefresh(); + await getOutProvinceSales(); + } + + void toggleExpansion({int? index}) { + if (expandedListIndex.value == index || index == null) { + expandedListIndex.value = -1; + } else { + expandedListIndex.value = index; + } + } + + Future getBroadcastPrice() async { + safeCall( + call: () async => await rootLogic.commonRepository.getBroadcastPrice( + token: rootLogic.tokenService.accessToken.value!, + ), + onSuccess: (result) { + broadcastPrice.value = result; + }, + onError: (error, stacktrace) {}, + ); + } + + void setSaleDate(Jalali value) { + saleDate.value = value; + saleDate.refresh(); + dateErrorDialog(); + } + + void setProductionDate(DayInfo value) { + productionDate.value = value.date; + remainingStock.value = value.remainingStock; + dateErrorDialog(); + } + + void dateErrorDialog() { + if ((productionDate.value?.distanceTo(saleDate.value) ?? 0) >= 1) { + saleDate.value = Jalali.now(); + Future.delayed( + Duration(milliseconds: 300), + () => defaultShowErrorMessage( + "تاریخ تولید نمی تواند قبل از تاریخ فروش باشد", + ), + ); + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/view.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/view.dart new file mode 100644 index 0000000..76e4675 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province/view.dart @@ -0,0 +1,1001 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/string_utils.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/inventory/inventory_widget.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class WarehouseAndDistributionSalesOutOfProvincePage extends GetView { + const WarehouseAndDistributionSalesOutOfProvincePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + backId: stewardSecondKey, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + child: Stack( + children: [ + Positioned.fill( + child: Column( + children: [ + // inventoryWidget(controller.rootLogic), + + ObxValue((data) { + return RPaginatedListView( + onLoadMore: () async => + controller.getOutProvinceSales(true), + 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 ExpandableListItem2( + selected: val.value == index, + onTap: () => controller.toggleExpansion(index: index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item, index), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.timerSvg.path, + ); + }, controller.expandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.salesList), + ], + ), + ), + Positioned( + right: 5, + left: 0, + bottom: 95, + child: Row( + children: [ + RFab.add( + onPressed: () { + Get.bottomSheet( + addOrEditSaleBottomSheet(), + isScrollControlled: true, + ).then((value) { + controller.clearSaleForm(); + }); + }, + ), + Spacer(), + RFab( + icon: Icon( + CupertinoIcons.person_add_solid, + color: Colors.white, + size: 35.w, + ), + backgroundColor: AppColor.blueNormal, + onPressed: () { + Get.toNamed( + StewardRoutes.salesOutOfProvinceBuyerSteward, + id: stewardSecondKey, + ); + }, + ), + SizedBox(width: 25), + ], + ), + ), + ], + ), + ); + } + + Widget filterBottomSheet() => filterBottomSheetWidget( + fromDate: controller.fromDateFilter, + onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali, + toDate: controller.toDateFilter, + onChangedToDate: (jalali) => controller.toDateFilter.value = jalali, + onSubmit: () => controller.submitFilter(), + ); + + Row itemListWidget(StewardFreeSaleBar item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 12), + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + item.date?.formattedJalaliDate ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + + Text( + item.weightOfCarcasses!.separatedByCommaFa.addKg, + textAlign: TextAlign.center, + textDirection: TextDirection.ltr, + style: AppFonts.yekan12Bold.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + SizedBox(width: 4), + Expanded( + flex: 5, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + item.buyer?.fullname ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + + SizedBox(height: 2), + Text( + item.buyer?.mobile ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + SizedBox(width: 4), + Expanded( + flex: 4, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Text( + item.buyer?.province ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.buyer?.city ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + ], + ); + } + + Container itemListExpandedWidget(StewardFreeSaleBar item, int index) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + '${item.province} - ${item.city}', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + ], + ), + 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( + item.date?.toJalali.formatter.wN ?? 'ندارد', + style: AppFonts.yekan14.copyWith( + color: AppColor.textColor, + ), + ), + + Text( + '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + + Text( + '${item.date?.toJalali.formatter.y}', + style: AppFonts.yekan20.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + buildRow( + title: 'مشخصات خریدار', + value: item.buyer?.fullname ?? 'ندارد', + ), + buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'ندارد'), + buildRow(title: 'نام واحد', value: item.buyer?.unitName ?? 'ندارد'), + buildRow( + title: 'وزن لاشه ', + value: '${item.weightOfCarcasses?.separatedByCommaFa}', + valueLabel: 'کیلوگرم', + ), + buildRow( + title: 'حجم تقریبی لاشه ', + value: '${item.numberOfCarcasses?.separatedByCommaFa}', + valueLabel: 'قطعه', + ), + buildRow( + title: 'تاریخ تولید گوشت', + value: item.productionDate?.toJalali.formatCompactDate() ?? 'ندارد', + ), + buildRow(title: 'انبار فروش', value: '${item.quota?.faTitle}'), + buildRow( + title: 'کد قرنطینه ', + value: item.clearanceCode ?? 'بدون کد', + ), + + buildRow( + title: 'حجم تقریبی لاشه ', + value: '${item.numberOfCarcasses?.separatedByCommaFa}', + valueLabel: 'قطعه', + ), + + item.registerCode == null + ? Row( + children: [ + Text( + 'کد احراز', + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDarkHover, + ), + ), + Spacer(), + RElevated( + width: 95.w, + height: 20.h, + textStyle: AppFonts.yekan12, + backgroundColor: AppColor.blueDarkHover, + text: 'ارسال کد', + onPressed: () { + Get.bottomSheet(bottomSendOtpSheetSellCode(item)).then(( + value, + ) { + controller.otpCode.value = ''; + controller.otpCodeSell.clear(); + }); + }, + ), + ], + ) + : buildRow(title: 'کد احراز ', value: '${item.registerCode}'), + buildRow( + title: 'کد قرنطینه ', + value: item.clearanceCode ?? 'بدون کد', + ), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + RElevated( + text: 'ویرایش', + width: 150.w, + height: 40.h, + onPressed: () { + controller.setEditDataSales(item); + Get.bottomSheet( + addOrEditSaleBottomSheet(true), + isScrollControlled: true, + ).whenComplete(() { + controller.resetSubmitForm(); + }); + }, + 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.toggleExpansion(); + controller.deleteStewardPurchaseOutOfProvince(item.key!); + }, + onRefresh: () async { + controller.onRefresh(); + }, + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ], + ), + ); + } + + Widget addOrEditSaleBottomSheet([bool isOnEdit = false]) { + return BaseBottomSheet( + height: 670.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: [ + ObxValue((data) { + return RTextField( + controller: TextEditingController(), + filledColor: AppColor.bgLight, + filled: true, + label: 'تاریخ', + onTap: () { + Get.bottomSheet( + modalDatePicker( + (value) => controller.setSaleDate(value), + ), + ); + }, + borderColor: AppColor.darkGreyLight, + initText: data.value.formatCompactDate(), + ); + }, controller.saleDate), + Visibility( + visible: isOnEdit == false, + child: Container( + height: 50.h, + clipBehavior: Clip.none, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: AppColor.darkGreyLight, + width: 1, + ), + ), + child: Stack( + fit: StackFit.expand, + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Positioned( + child: Container( + color: Colors.white, + child: Text("انبار"), + ), + top: -10, + right: 8, + ), + Obx(() { + return RadioGroup( + groupValue: controller.quotaType.value, + onChanged: (value) { + controller.quotaType.value = value ?? 0; + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + controller.quotaType.value = 1; + }, + child: Row( + children: [ + Radio(value: 1), + Text( + 'دولتی', + style: AppFonts.yekan14, + ), + ], + ), + ), + ), + + Expanded( + child: GestureDetector( + onTap: () { + controller.quotaType.value = 2; + }, + child: Row( + children: [ + Radio(value: 2), + Text( + 'آزاد', + style: AppFonts.yekan14, + ), + ], + ), + ), + ), + ], + ), + ); + }), + ], + ), + ), + ), + + Obx(() { + return MonthlyDataCalendar( + label: 'تاریخ تولید گوشت', + selectedDate: controller.productionDate.value + ?.formatCompactDate(), + onDateSelect: (value) { + controller.setProductionDate(value); + }, + dayData: controller.quotaType.value == 1 + ? controller.governmentalProductionDateData + : controller.freeProductionDateData, + ); + }), + + Visibility( + visible: isOnEdit == false, + child: _buyerWidget(), + ), + + RTextField( + controller: controller.saleWeightController, + label: 'وزن لاشه (کیلوگرم)', + keyboardType: TextInputType.number, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + autoValidateMode: AutovalidateMode.onUserInteraction, + filled: true, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + + validator: (value) { + if ((int.tryParse(value?.clearComma ?? '0') ?? 0) > + (controller.remainingStock.value ?? 0)) { + return 'وزن تخصیصی بیشتر از موجودی انبار است'; + } + return null; + }, + ), + + RTextField( + controller: controller.saleCountController, + label: 'حجم تقریبی(قطعه)', + keyboardType: TextInputType.number, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + variant: RTextFieldVariant.noBorder, + filled: true, + enabled: false, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + + validator: (value) { + if ((int.tryParse(value?.clearComma ?? '0') ?? 0) > + (controller.remainingStock.value ?? 0)) { + return 'وزن تخصیصی بیشتر از موجودی انبار است'; + } + return null; + }, + ), + + Visibility( + visible: isOnEdit == false, + child: Container( + height: 58.h, + clipBehavior: Clip.none, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: AppColor.darkGreyLight, + width: 1, + ), + ), + child: Stack( + fit: StackFit.expand, + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Positioned( + child: Container( + color: Colors.white, + child: Text("فروش"), + ), + top: -10, + right: 8, + ), + Obx(() { + return RadioGroup( + groupValue: controller.saleType.value, + onChanged: (value) { + controller.saleType.value = 2; + }, + child: Row( + children: [ + Expanded( + child: GestureDetector( + onTap: + (controller + .broadcastPrice + .value + ?.active ?? + false) + ? () { + controller.saleType.value = 2; + } + : null, + child: Row( + children: [ + Radio( + value: 1, + enabled: + controller + .broadcastPrice + .value + ?.active ?? + false, + ), + Text( + 'قیمت مصوب', + style: AppFonts.yekan14.copyWith( + color: + (controller + .broadcastPrice + .value + ?.active ?? + false) + ? AppColor.textColor + : AppColor.labelTextColor, + ), + ), + ], + ), + ), + ), + + Expanded( + child: GestureDetector( + onTap: () { + controller.saleType.value = 2; + }, + child: Row( + children: [ + Radio(value: 2), + Text( + 'قیمت آزاد', + style: AppFonts.yekan14, + ), + ], + ), + ), + ), + ], + ), + ); + }), + ], + ), + ), + ), + + ObxValue((data) { + return RTextField( + variant: RTextFieldVariant.noBorder, + controller: controller.pricePerKiloController, + borderColor: AppColor.darkGreyLight, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + filledColor: AppColor.bgLight, + filled: true, + readonly: data.value == 1, + onChanged: (p0) { + controller.pricePerKilo.value = + int.tryParse(p0.clearComma) ?? 0; + }, + keyboardType: TextInputType.number, + label: 'قیمت هر کیلو (ريال)', + ); + }, controller.saleType), + + RTextField( + variant: RTextFieldVariant.noBorder, + enabled: false, + keyboardType: TextInputType.number, + filledColor: AppColor.bgLight, + filled: true, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + controller: controller.totalCostController, + label: 'هزینه کل (ريال)', + ), + + RTextField( + controller: controller.quarantineCodeController, + label: 'کد قرنطینه', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + 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 { + isOnEdit + ? await controller.editSale() + : await controller.createSale(); + } + : null, + height: 40, + ); + }, controller.isSaleSubmitButtonEnabled); + } + + Widget _buyerWidget() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.buyerLogic.buyerList.value.data?.results ?? [], + onChanged: (value) { + controller.selectedBuyer.value = value; + }, + selectedItem: controller.selectedBuyer.value, + itemBuilder: (item) => Text(item.buyer?.fullname ?? 'بدون نام'), + labelBuilder: (item) => Text(item?.buyer?.fullname ?? 'انتخاب خریدار'), + ); + }); + } + + /* Widget _productDropDown() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rootLogic.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(), + ObxValue((data) { + return Visibility( + visible: data.value != null, + child: Text('موجودی: $data'), + ); + }, controller.remainingStock), + ], + ), + ); + }); + } + + GestureDetector timeFilterWidget({ + isFrom = true, + String? title, + required Rx date, + required Function(Jalali jalali) onChanged, + }) { + return GestureDetector( + onTap: () { + Get.bottomSheet(modalDatePicker((value) => onChanged(value))); + }, + child: Container( + height: 40, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.darkGreyLight), + ), + 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( + title ?? 'تاریخ', + 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 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: controller.saleDate.value, + mode: PersianCupertinoDatePickerMode.date, + onDateTimeChanged: (dateTime) { + tempPickedDate = dateTime; + }, + ), + ), + ), + ], + ), + ); + } + + Container _informationLabelCard({ + required String title, + required String description, + required String iconPath, + required Color bgDescriptionColor, + Color? borderColor, + String unit = 'KG', + bool isLoading = false, + Color? iconColor, + Color? titleColor, + Color? bgLabelColor, + LinearGradient? gradient, + }) { + return Container( + height: 40.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: borderColor != null + ? Border.all(width: 1, color: borderColor) + : null, + ), + clipBehavior: Clip.hardEdge, + child: Row( + children: [ + // Left side with icon and title + Expanded( + child: Container( + height: 82, + decoration: BoxDecoration( + color: gradient == null ? bgLabelColor : null, + borderRadius: BorderRadius.only( + topRight: Radius.circular(8), + bottomRight: Radius.circular(8), + ), + gradient: gradient, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + SvgGenImage.vec(iconPath).svg( + width: 24, + height: 24, + colorFilter: iconColor != null + ? ColorFilter.mode(iconColor, BlendMode.srcIn) + : null, + ), + Text( + title, + textAlign: TextAlign.right, + style: AppFonts.yekan14.copyWith( + color: titleColor ?? AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + // Right side with description and unit + Expanded( + child: Container( + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: bgDescriptionColor, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(8), + ), + ), + child: isLoading + ? Center(child: CupertinoActivityIndicator()) + : Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + description, + textAlign: TextAlign.left, + maxLines: 1, + textDirection: TextDirection.ltr, + overflow: TextOverflow.ellipsis, + style: AppFonts.yekan14.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + Text( + unit, + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith( + color: AppColor.mediumGreyDarkActive, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + Widget bottomSendOtpSheetSellCode(StewardFreeSaleBar item) { + return BaseBottomSheet( + height: 190.h, + child: Column( + children: [ + SizedBox(height: 12), + RTextField( + controller: controller.otpCodeSell, + onChanged: (data) => controller.otpCode.value = data, + label: 'کد احراز', + ), + SizedBox(height: 12), + RElevated( + onPressed: () { + controller.sendSaleOtpCode(item); + }, + isFullWidth: true, + text: "ارسال کد", + ), + SizedBox(height: 12), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart new file mode 100644 index 0000000..27b0ffd --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart @@ -0,0 +1,244 @@ +import 'package:flutter/material.dart'; + +<<<<<<<< HEAD:packages/chicken/lib/features/steward/sales_out_of_province_buyers/logic.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/features/steward/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sales_out_of_province/logic.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class SalesOutOfProvinceBuyersLogic extends GetxController { + StewardRootLogic rootLogic = Get.find(); + + SaleLogic get saleLogic => Get.find(); + + SalesOutOfProvinceLogic get saleOutOfProvince => + Get.find(); + + RxInt currentPage = 1.obs; + RxInt expandedListIndex = (-1).obs; + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + RxBool isLoadingMoreAllocationsMade = false.obs; + RxBool isBuyerSubmitButtonEnabled = false.obs; + + RxList cites = [].obs; + Rxn selectedProvince = Rxn(); + Rxn selectedCity = Rxn(); + + GlobalKey formKey = GlobalKey(); + TextEditingController buyerNameController = TextEditingController(); + TextEditingController buyerLastNameController = TextEditingController(); + TextEditingController buyerPhoneController = TextEditingController(); + TextEditingController buyerUnitNameController = TextEditingController(); + String? key; + + Rx>> buyerList = + Resource>.loading().obs; + + RxList routesName = RxList(); + + @override + void onInit() { + super.onInit(); + routesName.value = [...saleLogic.routesName, 'خریداران'].toList(); + getOutProvinceCarcassesBuyer(); + } + + @override + void onReady() { + super.onReady(); + + selectedProvince.listen((p0) => getCites()); + + debounce( + searchedValue, + (callback) => getOutProvinceCarcassesBuyer(), + time: Duration(milliseconds: timeDebounce), + ); + + setupListeners(); + } + + @override + void onClose() { + buyerNameController.dispose(); + buyerLastNameController.dispose(); + buyerPhoneController.dispose(); + buyerUnitNameController.dispose(); + selectedCity.value = null; + selectedProvince.value = null; + + super.onClose(); + } + + Future getOutProvinceCarcassesBuyer([ + bool isLoadingMore = false, + ]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + buyerList.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: () => rootLogic.stewardRepository.getOutProvinceCarcassesBuyer( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + pageSize: 20, + page: currentPage.value, + state: 'buyer-list', + search: 'filter', + role: 'Steward', + value: searchedValue.value ?? '', + ), + ), + onError: (error, stackTrace) => + isLoadingMoreAllocationsMade.value = false, + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + buyerList.value = + Resource>.empty(); + } else { + buyerList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(buyerList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + + isLoadingMoreAllocationsMade.value = false; + } + }, + ); + } + + void resetSubmitForm() { + buyerNameController.clear(); + buyerLastNameController.clear(); + buyerPhoneController.clear(); + buyerUnitNameController.clear(); + selectedProvince.value = null; + selectedCity.value = null; + } + + Future getCites() async { + await safeCall( + call: () => rootLogic.commonRepository.getCity( + provinceName: selectedProvince.value?.name ?? '', + ), + onSuccess: (result) { + if (result != null && result.isNotEmpty) { + cites.value = result; + } + }, + ); + } + + void setupListeners() { + buyerNameController.addListener(checkBuyerFormValid); + buyerLastNameController.addListener(checkBuyerFormValid); + buyerPhoneController.addListener(checkBuyerFormValid); + buyerUnitNameController.addListener(checkBuyerFormValid); + ever(selectedProvince, (_) => checkBuyerFormValid()); + ever(selectedCity, (_) => checkBuyerFormValid()); + } + + void checkBuyerFormValid() { + isBuyerSubmitButtonEnabled.value = + buyerNameController.text.isNotEmpty && + buyerLastNameController.text.isNotEmpty && + buyerPhoneController.text.isNotEmpty && + buyerUnitNameController.text.isNotEmpty && + selectedProvince.value != null && + selectedCity.value != null; + } + + Future createBuyer() async { + bool res = false; + if (!(formKey.currentState?.validate() ?? false)) { + return res; + } + await safeCall( + call: () async { + OutProvinceCarcassesBuyer buyer = OutProvinceCarcassesBuyer( + province: selectedProvince.value!.name, + city: selectedCity.value!.name, + firstName: buyerNameController.text, + lastName: buyerLastNameController.text, + unitName: buyerUnitNameController.text, + mobile: buyerPhoneController.text, + role: 'Steward', + ); + await rootLogic.stewardRepository.createOutProvinceCarcassesBuyer( + token: rootLogic.tokenService.accessToken.value!, + body: buyer, + ); + }, + onSuccess: (result) { + getOutProvinceCarcassesBuyer(); + resetSubmitForm(); + res = true; + }, + ); + return res; + } + + 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); + isBuyerSubmitButtonEnabled.value = true; + } + + void setSearchValue(String? value) { + searchedValue.value = value?.trim(); + } + + void submitFilter() { + fromDateFilter.value = fromDateFilter.value; + toDateFilter.value = toDateFilter.value; + getOutProvinceCarcassesBuyer(); + } + + Future onRefresh() async { + currentPage.value = 1; + await rootLogic.onRefresh(); + await getOutProvinceCarcassesBuyer(); + } + + void toggleExpansion({int? index}) { + if (expandedListIndex.value == index || index == null) { + expandedListIndex.value = -1; + } else { + expandedListIndex.value = index; + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_buyers/view.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_buyers/view.dart new file mode 100644 index 0000000..bbd8051 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_buyers/view.dart @@ -0,0 +1,350 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class SalesOutOfProvinceBuyersPage extends GetView { + const SalesOutOfProvinceBuyersPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + backId: stewardSecondKey, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + filteringWidget: filterBottomSheet(), + child: Stack( + children: [ + Positioned.fill( + child: Column( + children: [ + Container( + width: Get.width, + height: 39, + margin: EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: AppColor.greenLight, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.textColor, width: 0.5), + ), + alignment: Alignment.center, + child: Text( + 'لیست خریداران خارج از استان', + style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkHover), + ), + ), + + Expanded( + child: ObxValue((data) { + return RPaginatedListView( + onLoadMore: () async => controller.getOutProvinceCarcassesBuyer(true), + 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 ExpandableListItem2( + selected: val.value == index, + onTap: () => controller.toggleExpansion(index: index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.userRaduisSvg.path, + ); + }, controller.expandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.buyerList), + ), + ], + ), + ), + Positioned( + bottom: 100, + child: RFab.add( + onPressed: () { + Get.bottomSheet( + addOrEditBuyerBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).whenComplete(() => controller.resetSubmitForm()); + }, + ), + ), + ], + ), + ); + } + + Widget addOrEditBuyerBottomSheet([bool isOnEdit = false]) { + return BaseBottomSheet( + height: 600, + child: SingleChildScrollView( + child: Form( + key: controller.formKey, + child: Column( + spacing: 8, + children: [ + Text( + isOnEdit ? 'ویرایش خریدار' : 'افزودن خریدار', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + + 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: [_provinceWidget(), _cityWidget()]), + ), + + 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.buyerNameController, + label: 'نام خریدار', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + ), + RTextField( + controller: controller.buyerLastNameController, + label: 'نام خانوادگی خریدار', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + ), + RTextField( + controller: controller.buyerPhoneController, + label: 'تلفن خریدار', + keyboardType: TextInputType.phone, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + maxLength: 11, + validator: (value) { + if (value == null || value.isEmpty) { + return 'لطفاً شماره موبایل را وارد کنید'; + } + // حذف کاماها برای اعتبارسنجی + String cleaned = value.replaceAll(',', ''); + if (cleaned.length != 11) { + return 'شماره موبایل باید ۱۱ رقم باشد'; + } + if (!cleaned.startsWith('09')) { + return 'شماره موبایل باید با 09 شروع شود'; + } + return null; + }, + ), + RTextField( + controller: controller.buyerUnitNameController, + label: 'نام واحد', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + ), + + 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 = await controller.createBuyer(); + if (res) { + Get.back(); + } + } + : null, + height: 40, + ); + }, controller.isBuyerSubmitButtonEnabled); + } + + Widget _provinceWidget() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rootLogic.provinces, + onChanged: (value) { + controller.selectedProvince.value = value; + print('Selected Product: ${value.name}'); + }, + selectedItem: controller.selectedProvince.value, + itemBuilder: (item) => Text(item.name ?? 'بدون نام'), + labelBuilder: (item) => Text(item?.name ?? 'انتخاب استان'), + ); + }); + } + + Widget _cityWidget() { + return ObxValue((data) { + return OverlayDropdownWidget( + items: data, + onChanged: (value) { + controller.selectedCity.value = value; + print('Selected Product: ${value.name}'); + }, + selectedItem: controller.selectedCity.value, + itemBuilder: (item) => Text(item.name ?? 'بدون نام'), + labelBuilder: (item) => Text(item?.name ?? 'انتخاب شهر'), + ); + }, controller.cites); + } + + Padding itemListWidget(OutProvinceCarcassesBuyer item) { + return Padding( + padding: const EdgeInsets.only(right: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 8), + + Expanded( + flex: 2, + 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?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + + Expanded( + flex: 2, + child: Text( + '${item.unitName}', + 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.darkGreyDark), + ), + ), + ], + ), + ); + } + + Container itemListExpandedWidget(OutProvinceCarcassesBuyer item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(8)), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + '${item.province}-${item.city}', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + + SizedBox(), + ], + ), + + buildRow(title: 'مشخصات خریدار', value: item.fullname ?? 'N/A'), + buildRow(title: 'نام واحد', value: item.unitName ?? 'N/A'), + buildRow( + title: 'تعداد درخواست ها', + value: '${item.requestsInfo?.numberOfRequests.separatedByCommaFa}', + ), + buildRow( + title: 'حجم تقریبی', + value: '${item.requestsInfo?.totalQuantity.separatedByCommaFa}', + valueLabel: 'قطعه', + ), + buildRow( + title: 'وزن', + value: '${item.requestsInfo?.totalWeight.separatedByCommaFa}', + valueLabel: 'کیلوگرم', + ), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + RElevated( + text: 'ویرایش', + width: 150.w, + height: 40.h, + onPressed: () { + controller.setEditDataBuyer(item); + Get.bottomSheet( + addOrEditBuyerBottomSheet(true), + isScrollControlled: true, + ).whenComplete(() => controller.resetSubmitForm()); + }, + textStyle: AppFonts.yekan20.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ], + ), + ); + } + + Widget filterBottomSheet() => filterBottomSheetWidget( + fromDate: controller.fromDateFilter, + onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali, + toDate: controller.toDateFilter, + onChangedToDate: (jalali) => controller.toDateFilter.value = jalali, + onSubmit: () => controller.submitFilter(), + ); +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_sales_list/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_sales_list/logic.dart new file mode 100644 index 0000000..b4b6581 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_sales_list/logic.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/sales_out_of_province_sales_list/logic.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/features/steward/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/sales_out_of_province_buyers/logic.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_sales_list/logic.dart +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class SalesOutOfProvinceSalesListLogic extends GetxController { + StewardRootLogic rootLogic = Get.find(); + + SaleLogic saleLogic = Get.find(); + + SalesOutOfProvinceBuyersLogic buyerLogic = + Get.find(); + + RxInt selectedSegmentIndex = 0.obs; + RxBool isExpanded = false.obs; + RxInt currentPage = 1.obs; + RxBool isSaleSubmitButtonEnabled = false.obs; + RxInt expandedListIndex = (-1).obs; + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + RxList routesName = RxList(); + RxBool isLoadingMoreAllocationsMade = false.obs; + Rxn selectedCity = Rxn(); + + //TODO add this to Di + ImagePicker imagePicker = ImagePicker(); + + RxInt saleType = 1.obs; + RxInt quotaType = 1.obs; + + GlobalKey formKey = GlobalKey(); + TextEditingController quarantineCodeController = TextEditingController(); + TextEditingController saleWeightController = TextEditingController(); + TextEditingController saleCountController = TextEditingController(); + Rx saleDate = Jalali.now().obs; + String? key; + + Rx>> salesList = + Resource>.loading().obs; + + Rxn selectedProduct = Rxn(); + Rxn selectedBuyer = Rxn(); + + @override + void onInit() { + super.onInit(); + getOutProvinceSales(); + } + + @override + void onReady() { + super.onReady(); + + selectedProduct.value = rootLogic.rolesProductsModel.first; + debounce( + searchedValue, + (callback) => getOutProvinceSales(), + time: Duration(milliseconds: timeDebounce), + ); + } + + @override + void onClose() { + // TODO: implement onClose + super.onClose(); + } + + Future getOutProvinceSales([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + salesList.value = Resource>.loading(); + } + await safeCall( + call: () => rootLogic.stewardRepository.getStewardFreeSaleBar( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + pageSize: 20, + page: currentPage.value, + 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>.empty(); + } else { + salesList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(salesList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + + isLoadingMoreAllocationsMade.value = false; + } + }, + ); + } + + void setupListeners() { + quarantineCodeController.addListener(checkSalesFormValid); + ever(selectedBuyer, (_) => checkSalesFormValid); + ever(selectedProduct, (_) => checkSalesFormValid); + ever(saleDate, (_) => checkSalesFormValid()); + } + + void checkSalesFormValid() { + isSaleSubmitButtonEnabled.value = + saleDate.value.toString().isNotEmpty && + selectedProduct.value != null && + selectedBuyer.value != null && + saleWeightController.text.isNotEmpty && + quarantineCodeController.text.isNotEmpty; + } + + 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 = buyerLogic.buyerList.value.data?.results?.firstWhere( + (element) => element.key == item.buyer?.key, + ); + selectedProduct.value = rootLogic.rolesProductsModel.first; + key = item.key; + isSaleSubmitButtonEnabled.value = true; + } + + Future deleteStewardPurchaseOutOfProvince(String key) async { + //todo + /* await safeCall( + call: () => rootLogic.commonRepository + .editStewardPurchasesOutSideOfTheProvince( + token: rootLogic.tokenService.accessToken.value!, + stewardFreeBarKey: key, + ), + );*/ + } + + Future createSale() async { + bool res = false; + var tmpWight = int.tryParse(saleWeightController.text.clearComma); + var tmpCount = (tmpWight! / selectedProduct.value!.weightAverage!).round(); + + StewardFreeSaleBarRequest requestBody = StewardFreeSaleBarRequest( + buyerKey: selectedBuyer.value?.key, + numberOfCarcasses: tmpCount, + weightOfCarcasses: tmpWight, + date: saleDate.value.toDateTime().formattedDashedGregorian, + clearanceCode: quarantineCodeController.text, + productKey: selectedProduct.value?.key, + ); + await safeCall( + call: () => rootLogic.stewardRepository.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; + } + + Future 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.stewardRepository.updateOutProvinceStewardFreeBar( + token: rootLogic.tokenService.accessToken.value!, + body: requestBody, + ), + onSuccess: (_) { + res = true; + }, + ); + return res; + } + + void resetSubmitForm() { + selectedCity.value = null; + selectedProduct.value = null; + key = null; + } + + void toggleExpansion({int? index}) { + if (expandedListIndex.value == index || index == null) { + expandedListIndex.value = -1; + } else { + expandedListIndex.value = index; + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_sales_list/view.dart b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_sales_list/view.dart new file mode 100644 index 0000000..7f37994 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/sales_out_of_province_sales_list/view.dart @@ -0,0 +1,529 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class SalesOutOfProvinceSalesListPage + extends GetView { + const SalesOutOfProvinceSalesListPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: ObxValue((data) { + return RPaginatedListView( + onLoadMore: () async => controller.getOutProvinceSales(true), + + 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 ExpandableListItem2( + selected: val.value == index, + onTap: () => controller.toggleExpansion(), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item, index), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.timerSvg.path, + labelIconColor: AppColor.yellowNormal2, + ); + }, controller.expandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.salesList), + floatingActionButton: Row( + children: [ + RFab.add( + onPressed: () { + Get.bottomSheet( + addOrEditSaleBottomSheet(), + ignoreSafeArea: false, + isScrollControlled: true, + ).whenComplete(() { + controller.clearSaleForm(); + }); + }, + ), + Spacer(), + RFab( + icon: Icon( + CupertinoIcons.person_add_solid, + color: Colors.white, + size: 35.w, + ), + backgroundColor: AppColor.blueNormal, + onPressed: () { + Get.toNamed(StewardRoutes.salesOutOfProvinceBuyerSteward, id: 1); + }, + ), + SizedBox(width: 25), + ], + ), + floatingActionButtonLocation: FloatingActionButtonLocation.startFloat, + ); + } + + Row itemListWidget(StewardFreeSaleBar item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 12), + Expanded( + flex: 3, + child: Text( + item.date?.formattedJalaliDate ?? 'ندارد', + 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 ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + + SizedBox(height: 2), + Text( + item.buyer?.mobile ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + SizedBox(width: 4), + Expanded( + flex: 4, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 8, + children: [ + Text( + item.buyer?.unitName ?? 'ندارد', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + '${item.weightOfCarcasses?.separatedByCommaFa ?? 0}KG', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + ], + ); + } + + Container itemListExpandedWidget(StewardFreeSaleBar item, int index) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + '${item.province}-${item.city}', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + ], + ), + 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( + item.date?.toJalali.formatter.wN ?? 'ندارد', + style: AppFonts.yekan14.copyWith( + color: AppColor.textColor, + ), + ), + + Text( + '${item.date?.toJalali.formatter.d} ${item.date?.toJalali.formatter.mN ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith( + color: AppColor.blueNormal, + ), + ), + ], + ), + + Text( + '${item.date?.toJalali.formatter.y}', + style: AppFonts.yekan20.copyWith(color: AppColor.textColor), + ), + + Text( + '${item.date?.toJalali.formatter.tHH}:${item.date?.toJalali.formatter.tMM ?? 'ندارد'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + buildRow( + title: 'مشخصات خریدار', + value: item.buyer?.fullname ?? 'ندارد', + ), + buildRow(title: 'تلفن خریدار', value: item.buyer?.mobile ?? 'ندارد'), + buildRow(title: 'نام واحد', value: item.buyer?.unitName ?? 'ندارد'), + buildRow( + title: 'وزن لاشه', + value: '${item.weightOfCarcasses?.separatedByCommaFa}', + ), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + RElevated( + text: 'ویرایش', + width: 150.w, + height: 40.h, + onPressed: () { + controller.setEditDataSales(item); + Get.bottomSheet( + addOrEditSaleBottomSheet(true), + isScrollControlled: true, + ).whenComplete(() { + controller.resetSubmitForm(); + }); + }, + 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.toggleExpansion(); + controller.deleteStewardPurchaseOutOfProvince(item.key!); + }, + onRefresh: () => controller.getOutProvinceSales(), + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ], + ), + ); + } + + Widget addOrEditSaleBottomSheet([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: [ + Row( + spacing: 8, + children: [ + Expanded( + child: timeFilterWidget( + date: controller.saleDate, + onChanged: (jalali) => + controller.saleDate.value = jalali, + ), + ), + ], + ), + _buyerWidget(), + RTextField( + controller: controller.saleWeightController, + label: 'وزن لاشه', + keyboardType: TextInputType.number, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + + validator: (value) { + if (value == null) { + return 'لطفاً وزن لاشه را وارد کنید'; + } + return null; + }, + ), + RTextField( + controller: controller.saleCountController, + label: 'حجم تقریبی(قطعه)', + keyboardType: TextInputType.number, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + SeparatorInputFormatter(), + ], + + validator: (value) { + if (value == null) { + return 'لطفاً وزن لاشه را وارد کنید'; + } + return null; + }, + ), + + RTextField( + controller: controller.quarantineCodeController, + label: 'کد قرنطینه', + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + 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.editSale() + : await controller.createSale(); + if (res) { + controller.getOutProvinceSales(); + controller.clearSaleForm(); + Get.back(); + } + } + : null, + height: 40, + ); + }, controller.isSaleSubmitButtonEnabled); + } + + Widget _buyerWidget() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.buyerLogic.buyerList.value.data?.results ?? [], + onChanged: (value) { + controller.selectedBuyer.value = value; + }, + selectedItem: controller.selectedBuyer.value, + itemBuilder: (item) => Text(item.buyer?.fullname ?? 'بدون نام'), + labelBuilder: (item) => Text(item?.buyer?.fullname ?? 'انتخاب خریدار'), + ); + }); + } + + Widget _productDropDown() { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rootLogic.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.separatedByCommaFa ?? 0}', + ), + ], + ), + ); + }); + } + + GestureDetector timeFilterWidget({ + isFrom = true, + required Rx date, + required Function(Jalali jalali) onChanged, + }) { + return GestureDetector( + onTap: () { + Get.bottomSheet(modalDatePicker((value) => onChanged(value))); + }, + child: Container( + height: 40, + decoration: BoxDecoration( + color: AppColor.bgLight, + borderRadius: BorderRadius.circular(8), + border: Border.all(width: 1, color: AppColor.darkGreyLight), + ), + 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 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: controller.saleDate.value, + mode: PersianCupertinoDatePickerMode.date, + onDateTimeChanged: (dateTime) { + tempPickedDate = dateTime; + }, + ), + ), + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/segmentation/logic.dart b/packages/chicken/lib/features/steward/presentation/pages/segmentation/logic.dart new file mode 100644 index 0000000..843603e --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/segmentation/logic.dart @@ -0,0 +1,336 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/segmentation/logic.dart +import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/data/models/response/guild/guild_model.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/data/models/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/segmentation/logic.dart +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +class SegmentationLogic extends GetxController { + StewardRootLogic rootLogic = Get.find(); + + RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + + late List routesName; + RxInt selectedSegmentIndex = 0.obs; + RxBool isExpanded = false.obs; + + RxInt expandedListIndex = (-1).obs; + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + RxInt segmentType = 1.obs; + RxInt priceType = 2.obs; + RxInt quotaType = 2.obs; + GlobalKey formKey = GlobalKey(); + TextEditingController weightController = TextEditingController(text: '0'); + RxBool isSubmitButtonEnabled = false.obs; + Rxn selectedGuildModel = Rxn(); + Rxn selectedProduct = Rxn(); + Rxn selectedSegment = Rxn(); + Rxn broadcastPrice = Rxn(); + Rx>> segmentationList = + Resource>.loading().obs; + + RxList guildsModel = [].obs; + Rx saleDate = Jalali.now().obs; + RxInt weight = 0.obs; + Rxn productionDate = Rxn(null); + Rxn remainingStock = Rxn(null); + Map freeProductionDateData = {}; + Map governmentalProductionDateData = {}; + + @override + void onInit() { + super.onInit(); + routesName = ['قطعه‌بندی'].toList(); + once( + rootLogic.rolesProductsModel, + (callback) => selectedProduct.value = callback.first, + ); + getAllSegmentation(); + getGuilds(); + + ever(quotaType, (_) { + remainingStock.value = null; + productionDate.value = null; + }); + _updateGovernmentalProductionDateData(); + _updateFreeProductionDateData(); + ever(rootLogic.stewardRemainWeight, (callback) { + _updateGovernmentalProductionDateData(); + _updateFreeProductionDateData(); + }); + } + + void _updateGovernmentalProductionDateData() { + List dates = + rootLogic.stewardRemainWeight.value?.governmental ?? []; + governmentalProductionDateData = { + for (var element in dates) + element.day.toString().toJalali.formatCompactDate(): DayData( + value: element.amount?.toInt(), + ), + }; + } + + void _updateFreeProductionDateData() { + var dates = rootLogic.stewardRemainWeight.value?.free ?? []; + freeProductionDateData = { + for (var element in dates) + element.day.toString().toJalali.formatCompactDate(): DayData( + value: element.amount?.toInt(), + ), + }; + } + + @override + void onReady() { + super.onReady(); + setUpListener(); + } + + void setSearchValue(String? value) { + searchedValue.value = value?.trim(); + } + + void setUpListener() { + debounce( + searchedValue, + (callback) => getAllSegmentation(), + time: Duration(milliseconds: timeDebounce), + ); + + everAll([selectedSegment, quotaType, priceType], (_) { + validateForm(); + }); + + weightController.addListener(() => validateForm()); + } + + void setEditData(SegmentationModel item) { + selectedSegment.value = item; + weightController.text = item.weight.toString(); + } + + void clearForm() { + weightController.text = '0'; + selectedSegment.value = null; + selectedGuildModel.value = null; + productionDate.value = null; + segmentType.value = 1; + priceType.value = 2; + quotaType.value = 1; + remainingStock.value = null; + } + + void validateForm() { + var weight = int.tryParse(weightController.text.trim().clearComma) ?? 0; + var hasWeight = (remainingStock.value ?? 0) > weight; + isSubmitButtonEnabled.value = + selectedProduct.value != null && + weightController.text.isNotEmpty && + hasWeight && + productionDate.value != null && + weight > 0 && + (segmentType.value == 1 || + (segmentType.value == 2 && selectedGuildModel.value != null)); + } + + 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( + showError: true, + call: () async => await rootLogic.commonRepository.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( + showError: true, + showSuccess: true, + call: () => rootLogic.commonRepository.deleteSegmentation( + token: rootLogic.tokenService.accessToken.value!, + key: key, + ), + ); + } + + Future editSegment() async { + var res = true; + safeCall( + showError: true, + call: () async => await rootLogic.commonRepository.editSegmentation( + token: rootLogic.tokenService.accessToken.value!, + model: SegmentationModel( + key: selectedSegment.value?.key, + weight: int.tryParse(weightController.text.clearComma) ?? 0, + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, + ), + ), + onSuccess: (result) { + res = true; + onRefresh(); + }, + onError: (error, stacktrace) { + res = false; + }, + ); + return res; + } + + Future createSegment() async { + var res = true; + SegmentationModel segmentationModel = SegmentationModel( + productKey: selectedProduct.value?.key, + weight: int.tryParse(weightController.text.clearComma) ?? 0, + saleType: priceType.value == 1 ? 'governmental' : 'free', + quota: quotaType.value == 1 ? 'governmental' : 'free', + distributionType: 'App', + productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, + ); + if (segmentType.value == 2) { + segmentationModel = segmentationModel.copyWith( + guildKey: selectedGuildModel.value?.key, + ); + } + segmentationModel = segmentationModel.copyWith( + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, + ); + await safeCall( + showError: true, + call: () async => await rootLogic.commonRepository.createSegmentation( + token: rootLogic.tokenService.accessToken.value!, + model: segmentationModel, + ), + onSuccess: (result) async { + res = true; + isSubmitButtonEnabled.value = false; + onRefresh(); + Future.delayed( + Duration(seconds: 1), + () => defaultShowSuccessMessage("قطعه‌بندی با موفقیت ثبت شد!"), + ); + Get.back(); + }, + onError: (error, stacktrace) { + res = false; + }, + ); + return res; + } + + Future getGuilds() async { + safeCall( + call: () async => await rootLogic.commonRepository.getGuilds( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'all': true}, + role: 'Steward', + ), + ), + onSuccess: (result) { + if (result != null) { + guildsModel.clear(); + guildsModel.addAll(result); + } + }, + onError: (error, stacktrace) {}, + ); + } + + Future onRefresh() async { + toggleExpansion(); + currentPage.value = 1; + await rootLogic.onRefresh(); + await getAllSegmentation(); + await getBroadcastPrice(); + _updateFreeProductionDateData(); + _updateGovernmentalProductionDateData(); + } + + Future getBroadcastPrice() async { + safeCall( + call: () async => await rootLogic.commonRepository.getBroadcastPrice( + token: rootLogic.tokenService.accessToken.value!, + ), + onSuccess: (result) { + broadcastPrice.value = result; + if (broadcastPrice.value?.active == true) { + priceType.value = 2; + } + }, + onError: (error, stacktrace) {}, + ); + } + + void toggleExpansion({int? index}) { + if (expandedListIndex.value == index || index == null) { + expandedListIndex.value = -1; + } else { + expandedListIndex.value = index; + } + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/segmentation/view.dart b/packages/chicken/lib/features/steward/presentation/pages/segmentation/view.dart new file mode 100644 index 0000000..3197de6 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/segmentation/view.dart @@ -0,0 +1,290 @@ +import 'package:flutter/material.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/segmentation/view.dart +import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/steward/segmentation/widgets/cu_bottom_sheet.dart'; +======== +import 'package:rasadyar_chicken/features/steward/data/model/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/segmentation/widgets/cu_bottom_sheet.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/segmentation/view.dart +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class SegmentationPage extends GetView { + final today = Jalali.now(); + final oneDayAgo = Jalali.now().addDays(-1); + final twoDaysAgo = Jalali.now().addDays(-2); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + routes: controller.routesName, + onSearchChanged: (data) => controller.setSearchValue(data), + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + hasBack: false, + child: Stack( + children: [ + Positioned.fill( + child: ObxValue((data) { + return RPaginatedListView( + onLoadMore: () async => controller.getAllSegmentation(true), + 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 ExpandableListItem2( + selected: val.value == index, + onTap: () => controller.toggleExpansion(index: index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item, index), + labelColor: AppColor.blueLight, + labelIconColor: AppColor.customGrey, + labelIcon: Assets.vec.convertCubeSvg.path, + ); + }, controller.expandedListIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + ); + }, controller.segmentationList), + ), + Positioned( + right: 10, + bottom: 90.h, + child: RFab.add( + onPressed: () { + Get.bottomSheet( + addOrEditBottomSheet(controller), + isScrollControlled: true, + ignoreSafeArea: false, + ).whenComplete(() { + controller.clearForm(); + //defaultShowSuccessMessage('با موفقیت ثبت شد'); + }); + }, + ), + ), + ], + ), + ); + } + + Widget filterBottomSheet() => filterBottomSheetWidget( + fromDate: controller.fromDateFilter, + onChangedFromDate: (jalali) => controller.fromDateFilter.value = jalali, + toDate: controller.toDateFilter, + onChangedToDate: (jalali) => controller.toDateFilter.value = jalali, + onSubmit: () => controller.getAllSegmentation(), + ); + + Row itemListWidget(SegmentationModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 12), + Expanded( + flex: 3, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 4, + children: [ + Text( + item.toGuild != null ? 'قطعه‌بند' : 'مباشر', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + 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.toGuild != null + ? item.toGuild?.user?.fullname ?? 'N/A' + : item.buyer?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + + SizedBox(height: 2), + Text( + item.toGuild != null + ? item.toGuild?.guildsName ?? 'N/A' + : item.buyer?.shop ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + SizedBox(width: 4), + Expanded( + flex: 2, + child: Column( + spacing: 4, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + item.weight.separatedByCommaFa.addKg, + textAlign: TextAlign.center, + textDirection: TextDirection.ltr, + style: AppFonts.yekan14Bold.copyWith(color: AppColor.blueNormal), + ), + Text( + item.saleType == "governmental" ? 'دولتی' : 'آزاد', + textAlign: TextAlign.center, + textDirection: TextDirection.ltr, + style: AppFonts.yekan14Bold.copyWith( + color: item.saleType == "governmental" + ? AppColor.blueNormal + : AppColor.greenNormal, + ), + ), + ], + ), + ), + ], + ); + } + + Container 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.toGuild != null + ? item.toGuild?.user?.fullname ?? 'N/A' + : item.buyer?.fullname ?? 'N/A', + ), + buildRow( + title: 'تلفن خریدار', + value: item.toGuild != null + ? item.toGuild?.user?.mobile ?? 'N/A' + : item.buyer?.mobile ?? 'N/A', + ), + buildRow( + title: 'نام واحد', + value: item.toGuild != null + ? item.toGuild?.guildsName ?? 'N/A' + : item.buyer?.shop ?? 'N/A', + ), + buildRow(title: 'ماهیت', value: item.toGuild != null ? 'قطعه‌بند' : 'مباشر'), + buildRow(title: 'نوع فروش', value: item.saleType == "governmental" ? 'دولتی' : 'آزاد'), + buildRow(title: 'انبار فروش', value: item.quota == "governmental" ? 'دولتی' : 'آزاد'), + buildRow( + title: 'تاریخ تولید گوشت', + value: item.productionDate?.toJalali.formatCompactDate() ?? 'ندارد', + ), + + buildRow( + title: 'وزن قطعه‌بندی', + value: item.weight!.separatedByCommaFa, + valueLabel: 'کیلوگرم', + ), + + Row( + mainAxisAlignment: MainAxisAlignment.center, + spacing: 16.w, + children: [ + RElevated( + text: 'ویرایش', + width: 150.w, + height: 40.h, + onPressed: () { + controller.setEditData(item); + Get.bottomSheet( + addOrEditBottomSheet(controller, isOnEdit: true), + isScrollControlled: true, + ignoreSafeArea: false, + ).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.toggleExpansion(); + controller.deleteSegmentation(item.key!); + }, + onRefresh: () => controller.onRefresh(), + ); + }, + borderColor: AppColor.redNormal, + ), + ], + ), + ], + ), + ); + } +} diff --git a/packages/chicken/lib/features/steward/presentation/pages/segmentation/widgets/cu_bottom_sheet.dart b/packages/chicken/lib/features/steward/presentation/pages/segmentation/widgets/cu_bottom_sheet.dart new file mode 100644 index 0000000..3115f74 --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/pages/segmentation/widgets/cu_bottom_sheet.dart @@ -0,0 +1,401 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +<<<<<<<< HEAD:packages/chicken/lib/features/steward/segmentation/widgets/cu_bottom_sheet.dart +import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/segmentation/logic.dart'; +======== +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/segmentation/logic.dart'; +>>>>>>>> develop:packages/chicken/lib/features/steward/presentation/pages/segmentation/widgets/cu_bottom_sheet.dart +import 'package:rasadyar_core/core.dart'; + +Widget addOrEditBottomSheet(SegmentationLogic controller, {bool isOnEdit = false}) { + return BaseBottomSheet( + height: isOnEdit ? 350.h : 600.h, + child: SingleChildScrollView( + child: Form( + key: controller.formKey, + child: Column( + spacing: 16, + children: [ + Text( + isOnEdit ? 'ویرایش قطعه‌بندی' : 'افزودن قطعه‌بندی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + _productDropDown(controller), + Visibility( + visible: isOnEdit == false, + child: Container( + height: 50.h, + clipBehavior: Clip.none, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Stack( + fit: StackFit.expand, + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Positioned( + child: Container(color: Colors.white, child: Text("انبار")), + top: -10, + right: 8, + ), + Obx(() { + return RadioGroup( + groupValue: controller.quotaType.value, + onChanged: (value) { + controller.quotaType.value = value ?? 0; + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + controller.quotaType.value = 1; + }, + child: Row( + children: [ + Radio(value: 1), + Text('دولتی', style: AppFonts.yekan14), + ], + ), + ), + ), + + Expanded( + child: GestureDetector( + onTap: () { + controller.quotaType.value = 2; + }, + child: Row( + children: [ + Radio(value: 2), + Text('آزاد', style: AppFonts.yekan14), + ], + ), + ), + ), + ], + ), + ); + }), + ], + ), + ), + ), + + Obx(() { + return MonthlyDataCalendar( + label: 'تاریخ تولید گوشت', + selectedDate: controller.productionDate.value?.formatCompactDate(), + onDateSelect: (value) { + controller.productionDate.value = value.date; + controller.remainingStock.value = value.remainingStock; + }, + dayData: controller.quotaType.value == 1 + ? controller.governmentalProductionDateData + : controller.freeProductionDateData, + ); + }), + + RTextField( + controller: controller.weightController, + keyboardType: TextInputType.number, + autoValidateMode: AutovalidateMode.onUserInteraction, + borderColor: AppColor.darkGreyLight, + filledColor: AppColor.bgLight, + filled: true, + inputFormatters: [FilteringTextInputFormatter.digitsOnly, SeparatorInputFormatter()], + validator: (value) { + if ((int.tryParse(value?.clearComma ?? '0') ?? 0) > + (controller.remainingStock.value ?? 0)) { + return 'وزن تخصیصی بیشتر از موجودی انبار است'; + } + return null; + }, + onChanged: (p0) { + controller.weight.value = int.tryParse(p0.clearComma) ?? 0; + }, + label: 'وزن لاشه (کیلوگرم)', + ), + Visibility( + visible: isOnEdit == false, + child: Container( + height: 58.h, + clipBehavior: Clip.none, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + child: Stack( + fit: StackFit.expand, + alignment: Alignment.center, + clipBehavior: Clip.none, + children: [ + Positioned( + child: Container(color: Colors.white, child: Text("فروش")), + top: -10, + right: 8, + ), + Obx(() { + return RadioGroup( + groupValue: controller.priceType.value, + onChanged: (value) { + controller.priceType.value = value!; + }, + child: Row( + children: [ + Expanded( + child: GestureDetector( + onTap: (controller.broadcastPrice.value?.active ?? false) + ? () { + controller.priceType.value = 1; + } + : null, + child: Row( + children: [ + Radio( + value: 1, + enabled: controller.broadcastPrice.value?.active ?? false, + ), + Text( + 'قیمت مصوب', + style: AppFonts.yekan14.copyWith( + color: (controller.broadcastPrice.value?.active ?? false) + ? AppColor.textColor + : AppColor.labelTextColor, + ), + ), + ], + ), + ), + ), + + Expanded( + child: GestureDetector( + onTap: () { + controller.priceType.value = 2; + }, + child: Row( + children: [ + Radio(value: 2), + Text('قیمت آزاد', style: AppFonts.yekan14), + ], + ), + ), + ), + ], + ), + ); + }), + ], + ), + ), + ), + Visibility( + visible: isOnEdit == false, + child: Column( + spacing: 12, + children: [ + Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: AppColor.darkGreyLight, width: 1), + ), + + child: Column( + children: [ + const SizedBox(height: 8), + SizedBox( + height: 40, + child: ObxValue((data) { + return RadioGroup( + onChanged: (value) { + controller.segmentType.value = value!; + controller.selectedGuildModel.value = null; + controller.selectedGuildModel.refresh(); + }, + groupValue: controller.segmentType.value, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Radio(value: 1), + Text('قطعه‌بندی(کاربر)', style: AppFonts.yekan14), + SizedBox(width: 12), + Radio(value: 2), + Text('تخصیص به قطعه‌بند', style: AppFonts.yekan14), + ], + ), + ); + }, controller.priceType), + ), + const SizedBox(height: 12), + + ObxValue((data) { + return Visibility( + visible: data.value == 2, + child: guildsDropDown(controller), + ); + }, controller.segmentType), + ], + ), + ), + ], + ), + ), + + submitButtonWidget(controller, isOnEdit: isOnEdit), + + SizedBox(), + ], + ), + ), + ), + ); +} + +Widget submitButtonWidget(SegmentationLogic controller, {bool isOnEdit = false}) { + 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) { + Get.back(); + } + } + : null, + height: 40, + ); + }, controller.isSubmitButtonEnabled); +} + +Widget _productDropDown(SegmentationLogic controller) { + return Obx(() { + return OverlayDropdownWidget( + items: controller.rootLogic.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(), + ObxValue((data) { + return Visibility(visible: data.value != null, child: Text('موجودی: $data')); + }, controller.remainingStock), + ], + ), + ); + }); +} + +Widget guildsDropDown(SegmentationLogic controller) { + return Obx(() { + final item = controller.selectedGuildModel.value; + return OverlayDropdownWidget( + key: ValueKey(item?.user?.fullname ?? ''), + items: controller.guildsModel, + onChanged: (value) { + controller.selectedGuildModel.value = value; + }, + selectedItem: item, + + itemBuilder: (item) => Text( + item.user != null + ? '${item.steward == true ? 'مباشر' : 'صنف'} ${item.user!.fullname} (${item.user!.mobile})' + : 'بدون نام', + ), + labelBuilder: (item) => Text( + item?.user != null + ? '${item?.steward == true ? 'مباشر' : 'صنف'} ${item?.user!.fullname} (${item?.user!.mobile})' + : 'انتخاب مباشر/صنف', + ), + ); + }); +} + +Container modalDatePicker(SegmentationLogic controller, ValueChanged onDateSelected) { + Jalali currentDate = Jalali.now(); + 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: controller.saleDate.value, + mode: PersianCupertinoDatePickerMode.date, + maximumDate: currentDate.addDays(3), + minimumDate: currentDate.toDateTime().subtract(Duration(days: 1)).toString().toJalali, + maximumYear: currentDate.year, + minimumYear: currentDate.year, + onDateTimeChanged: (dateTime) { + tempPickedDate = dateTime; + }, + ), + ), + ), + ], + ), + ); +} diff --git a/packages/chicken/lib/features/steward/presentation/routes/pages.dart b/packages/chicken/lib/features/steward/presentation/routes/pages.dart new file mode 100644 index 0000000..b48481a --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/routes/pages.dart @@ -0,0 +1,135 @@ +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_all/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_in_province_waiting/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_out_of_province/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy_out_of_province/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_in_province/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_in_province/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_buyers/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_sales_list/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/segmentation/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class StewardPages { + StewardPages._(); + + static List get pages => [ + //region Steward Pages + GetPage( + name: StewardRoutes.initSteward, + page: () => StewardRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => StewardRootLogic()); + Get.lazyPut(() => HomeLogic()); + Get.lazyPut(() => BuyLogic()); + Get.lazyPut(() => SaleLogic()); + Get.lazyPut(() => SegmentationLogic()); + }), + ], + ), + + GetPage( + name: StewardRoutes.homeSteward, + page: () => HomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(HomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + + //sales + GetPage( + name: StewardRoutes.saleSteward, + page: () => SalePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => SaleLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + Get.lazyPut(() => SalesOutOfProvinceLogic()); + Get.lazyPut(() => SalesOutOfProvinceBuyersLogic()); + Get.lazyPut(() => StewardRootLogic()); + }), + ), + GetPage( + name: StewardRoutes.salesOutOfProvinceSteward, + page: () => SalesOutOfProvincePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => SalesOutOfProvinceLogic()); + Get.lazyPut(() => SalesOutOfProvinceBuyersLogic()); + Get.lazyPut(() => SalesOutOfProvinceSalesListLogic()); + }), + ), + GetPage( + name: StewardRoutes.salesOutOfProvinceBuyerSteward, + page: () => SalesOutOfProvinceBuyersPage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => SalesOutOfProvinceLogic()); + Get.lazyPut(() => SalesOutOfProvinceBuyersLogic()); + Get.lazyPut(() => SalesOutOfProvinceSalesListLogic()); + }), + ), + GetPage( + name: StewardRoutes.salesInProvinceSteward, + page: () => SalesInProvincePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic()); + Get.lazyPut(() => SalesInProvinceLogic()); + }), + ), + + //buy + GetPage( + name: StewardRoutes.buySteward, + page: () => BuyPage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic()); + Get.lazyPut(() => BuyLogic()); + }), + ), + GetPage( + name: StewardRoutes.buysOutOfProvinceSteward, + page: () => BuyOutOfProvincePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic()); + Get.lazyPut(() => BuyOutOfProvinceLogic()); + }), + ), + GetPage( + name: StewardRoutes.buysInProvinceSteward, + page: () => BuyInProvincePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic()); + Get.lazyPut(() => BuyInProvinceLogic()); + Get.lazyPut(() => BuyInProvinceWaitingLogic()); + Get.lazyPut(() => BuyInProvinceAllLogic()); + }), + ), + //endregion + ]; +} diff --git a/packages/chicken/lib/features/steward/presentation/routes/routes.dart b/packages/chicken/lib/features/steward/presentation/routes/routes.dart new file mode 100644 index 0000000..c1b7c5b --- /dev/null +++ b/packages/chicken/lib/features/steward/presentation/routes/routes.dart @@ -0,0 +1,20 @@ +sealed class StewardRoutes { + StewardRoutes._(); + + static const _base = '/chicken/steward'; + static const initSteward = '$_base/'; + static const homeSteward = '$_base/home'; + static const buySteward = '$_base/buy'; + static const saleSteward = '$_base/sale'; + static const segmentationSteward = '$_base/segmentation'; + + //buys + static const buysOutOfProvinceSteward = '$buySteward/buyOutOfProvince'; + static const buysInProvinceSteward = '$buySteward/buyInProvince'; + + //sales + static const salesInProvinceSteward = '$saleSteward/SalesInProvince'; + static const salesOutOfProvinceSteward = '$saleSteward/saleOutOfProvince'; + static const salesOutOfProvinceBuyerSteward = + '$saleSteward/saleOutOfProvinceBuyer '; +} diff --git a/packages/chicken/lib/features/steward/root/logic.dart b/packages/chicken/lib/features/steward/root/logic.dart index bfd6b5a..a2ddbb5 100644 --- a/packages/chicken/lib/features/steward/root/logic.dart +++ b/packages/chicken/lib/features/steward/root/logic.dart @@ -2,21 +2,25 @@ import 'dart:async'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; -import 'package:rasadyar_chicken/data/data_source/local/chicken_local.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/local/chicken_local.dart'; import 'package:rasadyar_chicken/data/di/chicken_di.dart'; -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.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_remain_weight/steward_remain_weight.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; -import 'package:rasadyar_chicken/data/models/response/waiting_arrival/waiting_arrival.dart' += +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/inventory/inventory_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_sales_info_dashboard/steward_sales_info_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/waiting_arrival/waiting_arrival.dart' hide ProductModel; -import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart'; -import 'package:rasadyar_chicken/features/common/profile/view.dart'; -import 'package:rasadyar_chicken/features/steward/buy/view.dart'; -import 'package:rasadyar_chicken/features/steward/home/view.dart'; -import 'package:rasadyar_chicken/features/steward/sale/view.dart'; -import 'package:rasadyar_chicken/features/steward/segmentation/view.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/common/common_repository.dart'; +import 'package:rasadyar_chicken/features/steward/data/repositories/steward_repository.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/buy/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/segmentation/view.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; @@ -36,8 +40,9 @@ class StewardRootLogic extends GetxController { ]; final defaultRoutes = { - 0: ChickenRoutes.buySteward, - 1: ChickenRoutes.saleSteward, += + 0: StewardRoutes.buySteward, + 1: StewardRoutes.saleSteward, }; RxList rolesProductsModel = RxList(); Rxn widelyUsedList = Rxn(); @@ -47,7 +52,8 @@ class StewardRootLogic extends GetxController { late DioRemote dioRemote; var tokenService = Get.find(); - late ChickenRepository chickenRepository; + late CommonRepository commonRepository; + late StewardRepository stewardRepository; late ChickenLocalDataSource localDatasource; RxList errorLocationType = RxList(); @@ -63,7 +69,8 @@ class StewardRootLogic extends GetxController { void onInit() { super.onInit(); localDatasource = diChicken.get(); - chickenRepository = diChicken.get(); + commonRepository = diChicken.get(); + stewardRepository = diChicken.get(); } @override @@ -122,8 +129,9 @@ class StewardRootLogic extends GetxController { _inventoryCancelToken?.cancel(); _inventoryCancelToken = CancelToken(); - await safeCall?>( - call: () async => await chickenRepository.getRolesProducts( += + await safeCall?>( + call: () async => await commonRepository.getInventory( token: tokenService.accessToken.value!, cancelToken: _inventoryCancelToken, queryParameters: buildRawQueryParams(role: 'Steward'), @@ -158,7 +166,8 @@ class StewardRootLogic extends GetxController { _provincesCancelToken = CancelToken(); try { - final res = await chickenRepository.getProvince( += + final res = await commonRepository.getProvince( cancelToken: _provincesCancelToken, ); if (res != null) { @@ -176,9 +185,9 @@ class StewardRootLogic extends GetxController { Future getRolesProducts() async { safeCall( - call: () async => await chickenRepository.getRolesProducts( += + call: () async => await commonRepository.getRolesProducts( token: tokenService.accessToken.value!, - queryParameters: buildQueryParams(role: 'Steward'), ), onSuccess: (result) { if (result != null) { @@ -191,7 +200,7 @@ class StewardRootLogic extends GetxController { Future getStewardSaleDashboard() async { safeCall( - call: () async => await chickenRepository.getStewardSalesInfoDashboard( + call: () async => await stewardRepository.getStewardSalesInfoDashboard( token: tokenService.accessToken.value!, queryParameters: buildRawQueryParams(role: 'Steward'), ), @@ -206,7 +215,8 @@ class StewardRootLogic extends GetxController { Future getStewardRemainWeightData() async { safeCall( - call: () async => await chickenRepository.getStewardRemainWeight( += + call: () async => await stewardRepository.getStewardRemainWeight( token: tokenService.accessToken.value!, ), onSuccess: (result) { diff --git a/packages/chicken/lib/features/steward/root/view.dart b/packages/chicken/lib/features/steward/root/view.dart index 668c910..46ec6a3 100644 --- a/packages/chicken/lib/features/steward/root/view.dart +++ b/packages/chicken/lib/features/steward/root/view.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:rasadyar_chicken/chicken.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; += +import 'package:rasadyar_chicken/features/common/data/model/response/kill_house_distribution_info/kill_house_distribution_info.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_core/core.dart'; @@ -26,7 +28,7 @@ class StewardRootPage extends GetView { final page = ChickenPages.pages.firstWhere( (e) => e.name == settings.name, orElse: () => ChickenPages.pages.firstWhere( - (e) => e.name == ChickenRoutes.buySteward, + (e) => e.name == StewardRoutes.buySteward, ), ); @@ -39,7 +41,7 @@ class StewardRootPage extends GetView { final page = ChickenPages.pages.firstWhere( (e) => e.name == settings.name, orElse: () => ChickenPages.pages.firstWhere( - (e) => e.name == ChickenRoutes.saleSteward, + (e) => e.name == StewardRoutes.saleSteward, ), ); diff --git a/packages/chicken/lib/features/steward/sale/logic.dart b/packages/chicken/lib/features/steward/sale/logic.dart index 2111b44..7dac288 100644 --- a/packages/chicken/lib/features/steward/sale/logic.dart +++ b/packages/chicken/lib/features/steward/sale/logic.dart @@ -1,19 +1,21 @@ - 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/roles_products/roles_products.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/request/conform_allocation/conform_allocation.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; class SaleLogic extends GetxController { - Rxn?> allocatedMadeModel = Rxn?>(); + Rxn?> allocatedMadeModel = + Rxn?>(); RxList guildsModel = [].obs; - Rxn stewardFreeDashboard = Rxn(); + Rxn stewardFreeDashboard = + Rxn(); StewardRootLogic rootLogic = Get.find(); @@ -24,14 +26,18 @@ class SaleLogic extends GetxController { void onReady() { super.onReady(); getStewardDashBord(); - } Future getAllocatedMade() async { safeCall( - call: () async => await rootLogic.chickenRepository.getAllocatedMade( + call: () async => await rootLogic.stewardRepository.getAllocatedMade( token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams(page: 1, pageSize: 20, search: 'filter', role: 'Steward'), + queryParameters: buildQueryParams( + page: 1, + pageSize: 20, + search: 'filter', + role: 'Steward', + ), ), onSuccess: (result) { if (result != null) { @@ -46,7 +52,7 @@ class SaleLogic extends GetxController { void confirmAllocation(ConformAllocation allocation) { safeCall( - call: () async => await rootLogic.chickenRepository.confirmAllocation( + call: () async => await rootLogic.stewardRepository.confirmAllocation( token: rootLogic.tokenService.accessToken.value!, allocation: allocation.toJson(), ), @@ -59,7 +65,7 @@ class SaleLogic extends GetxController { void denyAllocation(String token) { safeCall( - call: () async => await rootLogic.chickenRepository.denyAllocation( + call: () async => await rootLogic.stewardRepository.denyAllocation( token: rootLogic.tokenService.accessToken.value!, allocationToken: token, ), @@ -72,9 +78,10 @@ class SaleLogic extends GetxController { Future confirmAllAllocations() async { safeCall( - call: () async => await rootLogic.chickenRepository.confirmAllAllocation( + call: () async => await rootLogic.stewardRepository.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(); @@ -83,7 +90,6 @@ class SaleLogic extends GetxController { ); } - Future getGuilds() async {} Future addSale() async {} @@ -94,7 +100,7 @@ class SaleLogic extends GetxController { Future getStewardDashBord() async { safeCall( - call: () async => await rootLogic.chickenRepository.getStewardDashboard( + call: () async => await rootLogic.stewardRepository.getStewardDashboard( token: rootLogic.tokenService.accessToken.value!, stratDate: DateTime.now().formattedDashedGregorian, endDate: DateTime.now().formattedDashedGregorian, @@ -116,22 +122,20 @@ class SaleLogic extends GetxController { super.dispose(); } - void onPopScopTaped() async { - - final now = DateTime.now(); - if (_lastBackPressed == null || now.difference(_lastBackPressed!) > Duration(seconds: 2)) { - _lastBackPressed = now; - Get.snackbar( - 'خروج از برنامه', - 'برای خروج دوباره بازگشت را بزنید', - snackPosition: SnackPosition.TOP, - duration: Duration(seconds: 2), - backgroundColor: AppColor.warning, - ); - } else { - await SystemNavigator.pop(); - } - + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } } } diff --git a/packages/chicken/lib/features/steward/sale/view.dart b/packages/chicken/lib/features/steward/sale/view.dart index 055b800..b0ccdbe 100644 --- a/packages/chicken/lib/features/steward/sale/view.dart +++ b/packages/chicken/lib/features/steward/sale/view.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/chicken.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_core/core.dart'; @@ -25,14 +25,20 @@ class SalePage extends GetView { title: 'فروش داخل استان', vecIcon: Assets.vec.map2Svg.path, onTap: () { - Get.toNamed(ChickenRoutes.salesInProvinceSteward, id: stewardSecondKey); + Get.toNamed( + StewardRoutes.salesInProvinceSteward, + id: stewardSecondKey, + ); }, ), GlassMorphismCardIcon( title: 'فروش خارج استان', vecIcon: Assets.vec.saleOutProvinceSvg.path, onTap: () { - Get.toNamed(ChickenRoutes.salesOutOfProvinceSteward, id: stewardSecondKey); + Get.toNamed( + StewardRoutes.salesOutOfProvinceSteward, + id: stewardSecondKey, + ); }, ), ], @@ -89,14 +95,20 @@ class SalePage extends GetView { child: SvgGenImage.vec(iconPath).svg( width: 45, height: 45, - colorFilter: ColorFilter.mode(foregroundColor, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + foregroundColor, + BlendMode.srcIn, + ), ), ), Assets.vec.shoppingBasketSvg.svg( width: 55, height: 60, - colorFilter: ColorFilter.mode(foregroundColor, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + foregroundColor, + BlendMode.srcIn, + ), fit: BoxFit.cover, ), ], @@ -123,7 +135,9 @@ class SalePage extends GetView { children: [ Text( 'خلاصه اطلاعات', - style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + style: AppFonts.yekan16Bold.copyWith( + color: AppColor.blueNormal, + ), ), ], ), @@ -144,9 +158,15 @@ class SalePage extends GetView { spacing: 10, children: [ const SizedBox(height: 12), - buildRow('تعداد کل بارها', model.totalQuantity?.toString() ?? '0'), + buildRow( + 'تعداد کل بارها', + model.totalQuantity?.toString() ?? '0', + ), buildRow('تعداد کل', model.totalBars?.toString() ?? '0'), - buildRow('وزن کل (کیلوگرم)', model.totalWeight?.toString() ?? '0'), + buildRow( + 'وزن کل (کیلوگرم)', + model.totalWeight?.toString() ?? '0', + ), ], ), ), @@ -165,7 +185,9 @@ class SalePage extends GetView { child: Text( title, textAlign: TextAlign.right, - style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDarkHover, + ), ), ), Flexible( @@ -173,7 +195,9 @@ class SalePage extends GetView { child: Text( value, textAlign: TextAlign.left, - style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover), + style: AppFonts.yekan14.copyWith( + color: AppColor.darkGreyDarkHover, + ), ), ), ], diff --git a/packages/chicken/lib/features/steward/sales_in_province/view.dart b/packages/chicken/lib/features/steward/sales_in_province/view.dart index 03ba693..7afc896 100644 --- a/packages/chicken/lib/features/steward/sales_in_province/view.dart +++ b/packages/chicken/lib/features/steward/sales_in_province/view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; -import 'package:rasadyar_chicken/features/steward/sales_in_province/widgets/cu_sale_in_provience.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/response/allocated_made/allocated_made.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_in_province/widgets/cu_sale_in_provience.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/utils/string_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; diff --git a/packages/chicken/lib/features/steward/sales_in_province/widgets/cu_sale_in_provience.dart b/packages/chicken/lib/features/steward/sales_in_province/widgets/cu_sale_in_provience.dart index 5d5c11b..b5a608c 100644 --- a/packages/chicken/lib/features/steward/sales_in_province/widgets/cu_sale_in_provience.dart +++ b/packages/chicken/lib/features/steward/sales_in_province/widgets/cu_sale_in_provience.dart @@ -1,7 +1,8 @@ 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/features/steward/sales_in_province/logic.dart'; += +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_in_province/logic.dart'; import 'package:rasadyar_core/core.dart'; Widget addOrEditBottomSheet(SalesInProvinceLogic controller, {bool isEditMode = false}) { diff --git a/packages/chicken/lib/features/steward/sales_out_of_province/logic.dart b/packages/chicken/lib/features/steward/sales_out_of_province/logic.dart index 6db729a..2469f95 100644 --- a/packages/chicken/lib/features/steward/sales_out_of_province/logic.dart +++ b/packages/chicken/lib/features/steward/sales_out_of_province/logic.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.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/broadcast_price/broadcast_price.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/data/models/response/steward_remain_weight/steward_remain_weight.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sales_out_of_province_buyers/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sales_out_of_province_sales_list/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/broadcast_price/broadcast_price.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_remain_weight/steward_remain_weight.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_sales_list/logic.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -18,9 +19,11 @@ class SalesOutOfProvinceLogic extends GetxController { SaleLogic saleLogic = Get.find(); - SalesOutOfProvinceSalesListLogic saleListLogic = Get.find(); + SalesOutOfProvinceSalesListLogic saleListLogic = + Get.find(); - SalesOutOfProvinceBuyersLogic buyerLogic = Get.find(); + SalesOutOfProvinceBuyersLogic buyerLogic = + Get.find(); RxBool isExpanded = false.obs; RxInt currentPage = 1.obs; @@ -99,7 +102,8 @@ class SalesOutOfProvinceLogic extends GetxController { } void _updateGovernmentalProductionDateData() { - List dates = rootLogic.stewardRemainWeight.value?.governmental ?? []; + List dates = + rootLogic.stewardRemainWeight.value?.governmental ?? []; governmentalProductionDateData = { for (var element in dates) element.day.toString().toJalali.formatCompactDate(): DayData( @@ -135,7 +139,7 @@ class SalesOutOfProvinceLogic extends GetxController { salesList.value = Resource>.loading(); } await safeCall( - call: () => rootLogic.chickenRepository.getStewardFreeSaleBar( + call: () => rootLogic.stewardRepository.getStewardFreeSaleBar( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( pageSize: 20, @@ -150,16 +154,21 @@ class SalesOutOfProvinceLogic extends GetxController { ), onSuccess: (res) { if ((res?.count ?? 0) == 0) { - salesList.value = Resource>.empty(); + salesList.value = + Resource>.empty(); } else { - salesList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(salesList.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + salesList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(salesList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); isLoadingMoreAllocationsMade.value = false; } @@ -173,7 +182,8 @@ class SalesOutOfProvinceLogic extends GetxController { saleWeightController.addListener(() { checkSalesFormValid(); weight.value = int.parse(saleWeightController.text.clearComma); - var res = (weight / selectedProduct.value!.weightAverage!.toInt()).round(); + var res = (weight / selectedProduct.value!.weightAverage!.toInt()) + .round(); saleCountController.text = res.separatedByComma; }); ever(selectedBuyer, (_) => checkSalesFormValid); @@ -192,7 +202,8 @@ class SalesOutOfProvinceLogic extends GetxController { void setEditDataSales(StewardFreeSaleBar item) { quarantineCodeController.text = item.clearanceCode ?? ''; - saleWeightController.text = item.weightOfCarcasses?.toInt().toString() ?? ''; + saleWeightController.text = + item.weightOfCarcasses?.toInt().toString() ?? ''; saleDate.value = Jalali.fromDateTime(DateTime.parse(item.date!)); selectedCity.value = IranProvinceCityModel(name: item.city); selectedBuyer.value = buyerLogic.buyerList.value.data?.results?.firstWhere( @@ -204,13 +215,15 @@ class SalesOutOfProvinceLogic extends GetxController { quotaType.value = item.quota == 'governmental' ? 1 : 2; isSaleSubmitButtonEnabled.value = true; productionDate.value = item.productionDate.toJalali; - pricePerKiloController.text = pricePerKilo.value.toString().separatedByComma; + pricePerKiloController.text = pricePerKilo.value + .toString() + .separatedByComma; totalCostController.text = totalCost.value.toString().separatedByComma; } Future deleteStewardPurchaseOutOfProvince(String key) async { await safeCall( - call: () => rootLogic.chickenRepository.deleteOutProvinceStewardFreeBar( + call: () => rootLogic.stewardRepository.deleteOutProvinceStewardFreeBar( token: rootLogic.tokenService.accessToken.value!, key: key, ), @@ -228,12 +241,14 @@ class SalesOutOfProvinceLogic extends GetxController { productKey: selectedProduct.value?.key, saleType: saleType.value == 2 ? 'free' : 'exclusive', quota: quotaType.value == 1 ? 'governmental' : 'free', - productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, - distributionType: 'App', - ); += + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, + ); await safeCall( showError: true, - call: () => rootLogic.chickenRepository.createOutProvinceStewardFreeBar( + call: () => rootLogic.stewardRepository.createOutProvinceStewardFreeBar( token: rootLogic.tokenService.accessToken.value!, body: requestBody, ), @@ -273,7 +288,7 @@ class SalesOutOfProvinceLogic extends GetxController { key: key, ); await safeCall( - call: () => rootLogic.chickenRepository.updateOutProvinceStewardFreeBar( + call: () => rootLogic.stewardRepository.updateOutProvinceStewardFreeBar( token: rootLogic.tokenService.accessToken.value!, body: requestBody, ), @@ -309,7 +324,7 @@ class SalesOutOfProvinceLogic extends GetxController { ); await safeCall( showError: true, - call: () => rootLogic.chickenRepository.updateOutProvinceStewardFreeBar( + call: () => rootLogic.stewardRepository.updateOutProvinceStewardFreeBar( token: rootLogic.tokenService.accessToken.value!, body: requestBody, ), @@ -349,7 +364,7 @@ class SalesOutOfProvinceLogic extends GetxController { Future getBroadcastPrice() async { safeCall( - call: () async => await rootLogic.chickenRepository.getBroadcastPrice( + call: () async => await rootLogic.commonRepository.getBroadcastPrice( token: rootLogic.tokenService.accessToken.value!, ), onSuccess: (result) { @@ -376,7 +391,9 @@ class SalesOutOfProvinceLogic extends GetxController { saleDate.value = Jalali.now(); Future.delayed( Duration(milliseconds: 300), - () => defaultShowErrorMessage("تاریخ تولید نمی تواند قبل از تاریخ فروش باشد"), + () => defaultShowErrorMessage( + "تاریخ تولید نمی تواند قبل از تاریخ فروش باشد", + ), ); } } diff --git a/packages/chicken/lib/features/steward/sales_out_of_province_buyers/logic.dart b/packages/chicken/lib/features/steward/sales_out_of_province_buyers/logic.dart index 3efea0a..97af3e4 100644 --- a/packages/chicken/lib/features/steward/sales_out_of_province_buyers/logic.dart +++ b/packages/chicken/lib/features/steward/sales_out_of_province_buyers/logic.dart @@ -1,19 +1,21 @@ 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/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sales_out_of_province/logic.dart'; += +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province/logic.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; class SalesOutOfProvinceBuyersLogic extends GetxController { - StewardRootLogic rootLogic = Get.find(); + StewardRootLogic rootLogic = Get.find(); SaleLogic get saleLogic => Get.find(); - SalesOutOfProvinceLogic get saleOutOfProvince => Get.find(); + SalesOutOfProvinceLogic get saleOutOfProvince => + Get.find(); RxInt currentPage = 1.obs; RxInt expandedListIndex = (-1).obs; @@ -74,11 +76,14 @@ class SalesOutOfProvinceBuyersLogic extends GetxController { super.onClose(); } - Future getOutProvinceCarcassesBuyer([bool isLoadingMore = false]) async { + Future getOutProvinceCarcassesBuyer([ + bool isLoadingMore = false, + ]) async { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { - buyerList.value = Resource>.loading(); + buyerList.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -88,7 +93,7 @@ class SalesOutOfProvinceBuyersLogic extends GetxController { } await safeCall( - call: () => rootLogic.chickenRepository.getOutProvinceCarcassesBuyer( + call: () => rootLogic.stewardRepository.getOutProvinceCarcassesBuyer( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( pageSize: 20, @@ -99,19 +104,25 @@ class SalesOutOfProvinceBuyersLogic extends GetxController { value: searchedValue.value ?? '', ), ), - onError: (error, stackTrace) => isLoadingMoreAllocationsMade.value = false, + onError: (error, stackTrace) => + isLoadingMoreAllocationsMade.value = false, onSuccess: (res) { if ((res?.count ?? 0) == 0) { - buyerList.value = Resource>.empty(); + buyerList.value = + Resource>.empty(); } else { - buyerList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(buyerList.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + buyerList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(buyerList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); isLoadingMoreAllocationsMade.value = false; } @@ -130,8 +141,9 @@ class SalesOutOfProvinceBuyersLogic extends GetxController { Future getCites() async { await safeCall( - call: () => - rootLogic.chickenRepository.getCity(provinceName: selectedProvince.value?.name ?? ''), + call: () => rootLogic.commonRepository.getCity( + provinceName: selectedProvince.value?.name ?? '', + ), onSuccess: (result) { if (result != null && result.isNotEmpty) { cites.value = result; @@ -175,7 +187,7 @@ class SalesOutOfProvinceBuyersLogic extends GetxController { mobile: buyerPhoneController.text, role: 'Steward', ); - await rootLogic.chickenRepository.createOutProvinceCarcassesBuyer( + await rootLogic.stewardRepository.createOutProvinceCarcassesBuyer( token: rootLogic.tokenService.accessToken.value!, body: buyer, ); @@ -209,12 +221,12 @@ class SalesOutOfProvinceBuyersLogic extends GetxController { getOutProvinceCarcassesBuyer(); } - Future onRefresh() async { currentPage.value = 1; await rootLogic.onRefresh(); await getOutProvinceCarcassesBuyer(); } + void toggleExpansion({int? index}) { if (expandedListIndex.value == index || index == null) { expandedListIndex.value = -1; diff --git a/packages/chicken/lib/features/steward/sales_out_of_province_buyers/view.dart b/packages/chicken/lib/features/steward/sales_out_of_province_buyers/view.dart index 6bd61f9..bbd8051 100644 --- a/packages/chicken/lib/features/steward/sales_out_of_province_buyers/view.dart +++ b/packages/chicken/lib/features/steward/sales_out_of_province_buyers/view.dart @@ -1,6 +1,6 @@ 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/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; diff --git a/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/logic.dart b/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/logic.dart index 9c504f9..87edc6a 100644 --- a/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/logic.dart +++ b/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/logic.dart @@ -1,12 +1,13 @@ import 'package:flutter/material.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/features/steward/root/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sale/logic.dart'; -import 'package:rasadyar_chicken/features/steward/sales_out_of_province_buyers/logic.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/request/steward_free_sale_bar/steward_free_sale_bar_request.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/iran_province_city/iran_province_city_model.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sale/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/sales_out_of_province_buyers/logic.dart'; import 'package:rasadyar_chicken/presentation/utils/utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -15,7 +16,8 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { SaleLogic saleLogic = Get.find(); - SalesOutOfProvinceBuyersLogic buyerLogic = Get.find(); + SalesOutOfProvinceBuyersLogic buyerLogic = + Get.find(); RxInt selectedSegmentIndex = 0.obs; RxBool isExpanded = false.obs; @@ -32,12 +34,9 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { //TODO add this to Di ImagePicker imagePicker = ImagePicker(); - - RxInt saleType = 1.obs; RxInt quotaType = 1.obs; - GlobalKey formKey = GlobalKey(); TextEditingController quarantineCodeController = TextEditingController(); TextEditingController saleWeightController = TextEditingController(); @@ -82,7 +81,7 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { salesList.value = Resource>.loading(); } await safeCall( - call: () => rootLogic.chickenRepository.getStewardFreeSaleBar( + call: () => rootLogic.stewardRepository.getStewardFreeSaleBar( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( pageSize: 20, @@ -97,16 +96,21 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { ), onSuccess: (res) { if ((res?.count ?? 0) == 0) { - salesList.value = Resource>.empty(); + salesList.value = + Resource>.empty(); } else { - salesList.value = Resource>.success( - PaginationModel( - count: res?.count ?? 0, - next: res?.next, - previous: res?.previous, - results: [...(salesList.value.data?.results ?? []), ...(res?.results ?? [])], - ), - ); + salesList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(salesList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); isLoadingMoreAllocationsMade.value = false; } @@ -115,7 +119,6 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { } void setupListeners() { - quarantineCodeController.addListener(checkSalesFormValid); ever(selectedBuyer, (_) => checkSalesFormValid); ever(selectedProduct, (_) => checkSalesFormValid); @@ -133,7 +136,8 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { void setEditDataSales(StewardFreeSaleBar item) { quarantineCodeController.text = item.clearanceCode ?? ''; - saleWeightController.text = item.weightOfCarcasses?.toInt().toString() ?? ''; + saleWeightController.text = + item.weightOfCarcasses?.toInt().toString() ?? ''; saleDate.value = Jalali.fromDateTime(DateTime.parse(item.date!)); selectedCity.value = IranProvinceCityModel(name: item.city); selectedBuyer.value = buyerLogic.buyerList.value.data?.results?.firstWhere( @@ -147,7 +151,7 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { Future deleteStewardPurchaseOutOfProvince(String key) async { //todo /* await safeCall( - call: () => rootLogic.chickenRepository + call: () => rootLogic.commonRepository .editStewardPurchasesOutSideOfTheProvince( token: rootLogic.tokenService.accessToken.value!, stewardFreeBarKey: key, @@ -169,7 +173,7 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { productKey: selectedProduct.value?.key, ); await safeCall( - call: () => rootLogic.chickenRepository.createOutProvinceStewardFreeBar( + call: () => rootLogic.stewardRepository.createOutProvinceStewardFreeBar( token: rootLogic.tokenService.accessToken.value!, body: requestBody, ), @@ -198,7 +202,7 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { key: key, ); await safeCall( - call: () => rootLogic.chickenRepository.updateOutProvinceStewardFreeBar( + call: () => rootLogic.stewardRepository.updateOutProvinceStewardFreeBar( token: rootLogic.tokenService.accessToken.value!, body: requestBody, ), @@ -214,6 +218,7 @@ class SalesOutOfProvinceSalesListLogic extends GetxController { selectedProduct.value = null; key = null; } + void toggleExpansion({int? index}) { if (expandedListIndex.value == index || index == null) { expandedListIndex.value = -1; diff --git a/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/view.dart b/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/view.dart index 9286789..7f37994 100644 --- a/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/view.dart +++ b/packages/chicken/lib/features/steward/sales_out_of_province_sales_list/view.dart @@ -1,15 +1,16 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.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/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/out_province_carcasses_buyer/out_province_carcasses_buyer.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/data/model/response/steward_free_sale_bar/steward_free_sale_bar.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_core/core.dart'; import 'logic.dart'; -class SalesOutOfProvinceSalesListPage extends GetView { +class SalesOutOfProvinceSalesListPage + extends GetView { const SalesOutOfProvinceSalesListPage({super.key}); @override @@ -57,10 +58,14 @@ class SalesOutOfProvinceSalesListPage extends GetView controller.saleDate.value = jalali, + onChanged: (jalali) => + controller.saleDate.value = jalali, ), ), ], @@ -342,7 +363,9 @@ class SalesOutOfProvinceSalesListPage extends GetView selectedProduct.value = callback.first); + once( + rootLogic.rolesProductsModel, + (callback) => selectedProduct.value = callback.first, + ); getAllSegmentation(); getGuilds(); @@ -65,7 +69,8 @@ class SegmentationLogic extends GetxController { } void _updateGovernmentalProductionDateData() { - List dates = rootLogic.stewardRemainWeight.value?.governmental ?? []; + List dates = + rootLogic.stewardRemainWeight.value?.governmental ?? []; governmentalProductionDateData = { for (var element in dates) element.day.toString().toJalali.formatCompactDate(): DayData( @@ -90,7 +95,6 @@ class SegmentationLogic extends GetxController { setUpListener(); } - void setSearchValue(String? value) { searchedValue.value = value?.trim(); } @@ -134,14 +138,16 @@ class SegmentationLogic extends GetxController { hasWeight && productionDate.value != null && weight > 0 && - (segmentType.value == 1 || (segmentType.value == 2 && selectedGuildModel.value != null)); + (segmentType.value == 1 || + (segmentType.value == 2 && selectedGuildModel.value != null)); } Future getAllSegmentation([bool isLoadingMore = false]) async { if (isLoadingMore) { isLoadingMoreAllocationsMade.value = true; } else { - segmentationList.value = Resource>.loading(); + segmentationList.value = + Resource>.loading(); } if (searchedValue.value != null && @@ -152,7 +158,7 @@ class SegmentationLogic extends GetxController { await safeCall( showError: true, - call: () async => await rootLogic.chickenRepository.getSegmentation( + call: () async => await rootLogic.commonRepository.getSegmentation( token: rootLogic.tokenService.accessToken.value!, queryParameters: buildQueryParams( pageSize: 20, @@ -167,19 +173,21 @@ class SegmentationLogic extends GetxController { onSuccess: (result) { if ((result?.count ?? 0) == 0) { - segmentationList.value = Resource>.empty(); + 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 ?? []), - ], - ), - ); + 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; } @@ -191,7 +199,7 @@ class SegmentationLogic extends GetxController { await safeCall( showError: true, showSuccess: true, - call: () => rootLogic.chickenRepository.deleteSegmentation( + call: () => rootLogic.commonRepository.deleteSegmentation( token: rootLogic.tokenService.accessToken.value!, key: key, ), @@ -202,12 +210,14 @@ class SegmentationLogic extends GetxController { var res = true; safeCall( showError: true, - call: () async => await rootLogic.chickenRepository.editSegmentation( + call: () async => await rootLogic.commonRepository.editSegmentation( token: rootLogic.tokenService.accessToken.value!, model: SegmentationModel( key: selectedSegment.value?.key, weight: int.tryParse(weightController.text.clearComma) ?? 0, - productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, ), ), onSuccess: (result) { @@ -232,14 +242,18 @@ class SegmentationLogic extends GetxController { productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, ); if (segmentType.value == 2) { - segmentationModel = segmentationModel.copyWith(guildKey: selectedGuildModel.value?.key); + segmentationModel = segmentationModel.copyWith( + guildKey: selectedGuildModel.value?.key, + ); } segmentationModel = segmentationModel.copyWith( - productionDate: productionDate.value?.toDateTime().formattedDashedGregorian, + productionDate: productionDate.value + ?.toDateTime() + .formattedDashedGregorian, ); await safeCall( showError: true, - call: () async => await rootLogic.chickenRepository.createSegmentation( + call: () async => await rootLogic.commonRepository.createSegmentation( token: rootLogic.tokenService.accessToken.value!, model: segmentationModel, ), @@ -262,9 +276,12 @@ class SegmentationLogic extends GetxController { Future getGuilds() async { safeCall( - call: () async => await rootLogic.chickenRepository.getGuilds( + call: () async => await rootLogic.commonRepository.getGuilds( token: rootLogic.tokenService.accessToken.value!, - queryParameters: buildQueryParams(queryParams: {'all': true}, role: 'Steward'), + queryParameters: buildQueryParams( + queryParams: {'all': true}, + role: 'Steward', + ), ), onSuccess: (result) { if (result != null) { @@ -288,7 +305,7 @@ class SegmentationLogic extends GetxController { Future getBroadcastPrice() async { safeCall( - call: () async => await rootLogic.chickenRepository.getBroadcastPrice( + call: () async => await rootLogic.commonRepository.getBroadcastPrice( token: rootLogic.tokenService.accessToken.value!, ), onSuccess: (result) { diff --git a/packages/chicken/lib/features/steward/segmentation/view.dart b/packages/chicken/lib/features/steward/segmentation/view.dart index 46868f5..9ce3dcc 100644 --- a/packages/chicken/lib/features/steward/segmentation/view.dart +++ b/packages/chicken/lib/features/steward/segmentation/view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart'; -import 'package:rasadyar_chicken/features/steward/segmentation/widgets/cu_bottom_sheet.dart'; += +import 'package:rasadyar_chicken/features/steward/data/model/response/segmentation_model/segmentation_model.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/segmentation/widgets/cu_bottom_sheet.dart'; import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; import 'package:rasadyar_chicken/presentation/widget/filter_bottom_sheet.dart'; import 'package:rasadyar_core/core.dart'; diff --git a/packages/chicken/lib/features/steward/segmentation/widgets/cu_bottom_sheet.dart b/packages/chicken/lib/features/steward/segmentation/widgets/cu_bottom_sheet.dart index defd318..c3dc497 100644 --- a/packages/chicken/lib/features/steward/segmentation/widgets/cu_bottom_sheet.dart +++ b/packages/chicken/lib/features/steward/segmentation/widgets/cu_bottom_sheet.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:rasadyar_chicken/data/models/response/guild/guild_model.dart'; -import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; -import 'package:rasadyar_chicken/features/steward/segmentation/logic.dart'; += +import 'package:rasadyar_chicken/features/common/data/model/response/guild/guild_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/roles_products/roles_products.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/segmentation/logic.dart'; import 'package:rasadyar_core/core.dart'; Widget addOrEditBottomSheet(SegmentationLogic controller, {bool isOnEdit = false}) { diff --git a/packages/chicken/lib/features/steward/steward.dart b/packages/chicken/lib/features/steward/steward.dart index 2139d13..871d572 100644 --- a/packages/chicken/lib/features/steward/steward.dart +++ b/packages/chicken/lib/features/steward/steward.dart @@ -1,26 +1,3 @@ -export 'buy/logic.dart'; -export 'buy/view.dart'; -export 'buy_in_province/logic.dart'; -export 'buy_in_province/view.dart'; -export 'buy_in_province_all/logic.dart'; -export 'buy_in_province_all/view.dart'; -export 'buy_in_province_waiting/logic.dart'; -export 'buy_in_province_waiting/view.dart'; -export 'buy_out_of_province/logic.dart'; -export 'buy_out_of_province/view.dart'; -export 'home/logic.dart'; -export 'home/view.dart'; -export 'root/logic.dart'; -export 'root/view.dart'; -export 'sale/logic.dart'; -export 'sale/view.dart'; -export 'sales_in_province/logic.dart'; -export 'sales_in_province/view.dart'; -export 'sales_out_of_province/logic.dart'; -export 'sales_out_of_province/view.dart'; -export 'sales_out_of_province_buyers/logic.dart'; -export 'sales_out_of_province_buyers/view.dart'; -export 'sales_out_of_province_sales_list/logic.dart'; -export 'sales_out_of_province_sales_list/view.dart'; -export 'segmentation/logic.dart'; -export 'segmentation/view.dart'; \ No newline at end of file +export 'data/di/steward_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/super_admin/data/datasources/remote/super_admin_remote_data_source.dart b/packages/chicken/lib/features/super_admin/data/datasources/remote/super_admin_remote_data_source.dart new file mode 100644 index 0000000..d4fcff1 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/data/datasources/remote/super_admin_remote_data_source.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class SuperAdminRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/super_admin/data/datasources/remote/super_admin_remote_data_source_impl.dart b/packages/chicken/lib/features/super_admin/data/datasources/remote/super_admin_remote_data_source_impl.dart new file mode 100644 index 0000000..633157a --- /dev/null +++ b/packages/chicken/lib/features/super_admin/data/datasources/remote/super_admin_remote_data_source_impl.dart @@ -0,0 +1,39 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/datasources/remote/super_admin_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class SuperAdminRemoteDataSourceImpl implements SuperAdminRemoteDataSource { + final DioRemote _httpClient; + + SuperAdminRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} diff --git a/packages/chicken/lib/features/super_admin/data/di/super_admin_di.dart b/packages/chicken/lib/features/super_admin/data/di/super_admin_di.dart new file mode 100644 index 0000000..0dda3e1 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/data/di/super_admin_di.dart @@ -0,0 +1,36 @@ +import 'package:rasadyar_chicken/features/super_admin/data/datasources/remote/super_admin_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/datasources/remote/super_admin_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/repositories/super_admin_repository.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/repositories/super_admin_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for super_admin feature +Future setupSuperAdminDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => SuperAdminRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => SuperAdminRepositoryImpl(di.get()), + ); +} + +/// Re-register super_admin dependencies (used when base URL changes) +Future reRegisterSuperAdminDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => SuperAdminRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => SuperAdminRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/super_admin/data/repositories/super_admin_repository.dart b/packages/chicken/lib/features/super_admin/data/repositories/super_admin_repository.dart new file mode 100644 index 0000000..997416a --- /dev/null +++ b/packages/chicken/lib/features/super_admin/data/repositories/super_admin_repository.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class SuperAdminRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/super_admin/data/repositories/super_admin_repository_impl.dart b/packages/chicken/lib/features/super_admin/data/repositories/super_admin_repository_impl.dart new file mode 100644 index 0000000..9b844bf --- /dev/null +++ b/packages/chicken/lib/features/super_admin/data/repositories/super_admin_repository_impl.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/datasources/remote/super_admin_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/repositories/super_admin_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class SuperAdminRepositoryImpl implements SuperAdminRepository { + final SuperAdminRemoteDataSource _remote; + + SuperAdminRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..9fbe9b6 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,95 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + SuperAdminRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'SuperAdmin', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..c663465 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/active_hatching/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: superAdminActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart b/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart new file mode 100644 index 0000000..7a720d3 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/home/logic.dart @@ -0,0 +1,26 @@ +import 'package:rasadyar_chicken/features/super_admin/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class SuperAdminHomeItem { + final String title; + final String route; + final String icon; + + SuperAdminHomeItem({required this.title, required this.route, required this.icon}); +} + +class SuperAdminHomeLogic extends GetxController { + RxList items = [ + SuperAdminHomeItem( + title: "جوجه ریزی فعال", + route: SuperAdminRoutes.activeHatchingSuperAdmin, + icon: Assets.vec.activeFramSvg.path, + ), + SuperAdminHomeItem( + title: "بازرسی مزارع طیور", + route: SuperAdminRoutes.newInspectionSuperAdmin, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/home/view.dart b/packages/chicken/lib/features/super_admin/presentation/pages/home/view.dart new file mode 100644 index 0000000..9d957ff --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/home/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class SuperAdminHomePage extends GetView { + SuperAdminHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: superAdminActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/super_admin/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..d7386fc --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + SuperAdminRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.superAdminRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'SuperAdmin', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/super_admin/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..39478b4 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: superAdminActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/root/logic.dart b/packages/chicken/lib/features/super_admin/presentation/pages/root/logic.dart new file mode 100644 index 0000000..cec976c --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/root/logic.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/super_admin/data/repositories/super_admin_repository.dart'; + +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class SuperAdminRootLogic extends GetxController { + var tokenService = Get.find(); + + late SuperAdminRepository superAdminRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(superAdminActionKey), + onGenerateRoute: (settings) { + final page = SuperAdminPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => SuperAdminPages.pages.firstWhere( + (e) => e.name == SuperAdminRoutes.homeSuperAdmin, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + superAdminRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/pages/root/view.dart b/packages/chicken/lib/features/super_admin/presentation/pages/root/view.dart new file mode 100644 index 0000000..a86b0f1 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/pages/root/view.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class SuperAdminRootPage extends GetView { + const SuperAdminRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + superAdminActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + superAdminActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/super_admin/presentation/routes/pages.dart b/packages/chicken/lib/features/super_admin/presentation/routes/pages.dart new file mode 100644 index 0000000..9b7c76b --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/routes/pages.dart @@ -0,0 +1,76 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/super_admin/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class SuperAdminPages { + SuperAdminPages._(); + + static List get pages => [ + GetPage( + name: SuperAdminRoutes.initSuperAdmin, + page: () => SuperAdminRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => SuperAdminRootLogic()); + Get.lazyPut(() => SuperAdminHomeLogic()); + }), + ], + ), + GetPage( + name: SuperAdminRoutes.homeSuperAdmin, + page: () => SuperAdminHomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(SuperAdminHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + GetPage( + name: SuperAdminRoutes.actionSuperAdmin, + page: () => SuperAdminHomePage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => SuperAdminHomeLogic()); + }), + ], + ), + GetPage( + name: SuperAdminRoutes.activeHatchingSuperAdmin, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: SuperAdminRoutes.newInspectionSuperAdmin, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/super_admin/presentation/routes/routes.dart b/packages/chicken/lib/features/super_admin/presentation/routes/routes.dart new file mode 100644 index 0000000..cb2e030 --- /dev/null +++ b/packages/chicken/lib/features/super_admin/presentation/routes/routes.dart @@ -0,0 +1,10 @@ +sealed class SuperAdminRoutes { + SuperAdminRoutes._(); + + static const _base = '/chicken/superAdmin'; + static const initSuperAdmin = '$_base/'; + static const homeSuperAdmin = '$_base/home'; + static const actionSuperAdmin = '$_base/action'; + static const activeHatchingSuperAdmin = '$_base/activeHatching'; + static const newInspectionSuperAdmin = '$_base/newInspection'; +} diff --git a/packages/chicken/lib/features/super_admin/super_admin.dart b/packages/chicken/lib/features/super_admin/super_admin.dart new file mode 100644 index 0000000..2c0cf7f --- /dev/null +++ b/packages/chicken/lib/features/super_admin/super_admin.dart @@ -0,0 +1,3 @@ +export 'data/di/super_admin_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source.dart b/packages/chicken/lib/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source.dart new file mode 100644 index 0000000..19da44e --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class VetFarmRemoteDataSource { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source_impl.dart b/packages/chicken/lib/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source_impl.dart new file mode 100644 index 0000000..038718d --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source_impl.dart @@ -0,0 +1,39 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source.dart'; +import 'package:rasadyar_core/core.dart'; + +class VetFarmRemoteDataSourceImpl implements VetFarmRemoteDataSource { + final DioRemote _httpClient; + + VetFarmRemoteDataSourceImpl(this._httpClient); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + var res = await _httpClient.get( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + queryParameters: queryParameters, + fromJson: (json) => PaginationModel.fromJson( + json, + (json) => PoultryScienceReport.fromJson(json as Map), + ), + ); + return res.data; + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + await _httpClient.post( + '/poultry_science_report/', + headers: {'Authorization': 'Bearer $token'}, + data: request.toJson(), + ); + } +} diff --git a/packages/chicken/lib/features/vet_farm/data/di/vet_farm_di.dart b/packages/chicken/lib/features/vet_farm/data/di/vet_farm_di.dart new file mode 100644 index 0000000..81c5239 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/data/di/vet_farm_di.dart @@ -0,0 +1,36 @@ +import 'package:rasadyar_chicken/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source_impl.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/repositories/vet_farm_repository.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/repositories/vet_farm_repository_impl.dart'; +import 'package:rasadyar_core/core.dart'; + +/// Setup dependency injection for vet_farm feature +Future setupVetFarmDI(GetIt di, DioRemote dioRemote) async { + di.registerLazySingleton( + () => VetFarmRemoteDataSourceImpl(dioRemote), + ); + + di.registerLazySingleton( + () => VetFarmRepositoryImpl(di.get()), + ); +} + +/// Re-register vet_farm dependencies (used when base URL changes) +Future reRegisterVetFarmDI(GetIt di, DioRemote dioRemote) async { + await reRegister(di, () => VetFarmRemoteDataSourceImpl(dioRemote)); + await reRegister( + di, + () => VetFarmRepositoryImpl(di.get()), + ); +} + +/// Helper function to re-register a dependency +Future reRegister( + GetIt di, + T Function() factory, +) async { + if (di.isRegistered()) { + await di.unregister(); + } + di.registerLazySingleton(factory); +} diff --git a/packages/chicken/lib/features/vet_farm/data/repositories/vet_farm_repository.dart b/packages/chicken/lib/features/vet_farm/data/repositories/vet_farm_repository.dart new file mode 100644 index 0000000..5d55bb7 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/data/repositories/vet_farm_repository.dart @@ -0,0 +1,15 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_core/core.dart'; + +abstract class VetFarmRepository { + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }); + + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }); +} diff --git a/packages/chicken/lib/features/vet_farm/data/repositories/vet_farm_repository_impl.dart b/packages/chicken/lib/features/vet_farm/data/repositories/vet_farm_repository_impl.dart new file mode 100644 index 0000000..cfed199 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/data/repositories/vet_farm_repository_impl.dart @@ -0,0 +1,30 @@ +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/request/submit_inspection/submit_inspection_response.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/datasources/remote/vet_farm_remote_data_source.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/repositories/vet_farm_repository.dart'; +import 'package:rasadyar_core/core.dart'; + +class VetFarmRepositoryImpl implements VetFarmRepository { + final VetFarmRemoteDataSource _remote; + + VetFarmRepositoryImpl(this._remote); + + @override + Future?> getSubmitInspectionList({ + required String token, + Map? queryParameters, + }) async { + return await _remote.getSubmitInspectionList( + token: token, + queryParameters: queryParameters, + ); + } + + @override + Future submitInspection({ + required String token, + required SubmitInspectionResponse request, + }) async { + return await _remote.submitInspection(token: token, request: request); + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/logic.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/logic.dart new file mode 100644 index 0000000..e81ebab --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/logic.dart @@ -0,0 +1,95 @@ +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/repositories/poultry_science_repository.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingLogic extends GetxController { + VetFarmRootLogic rootLogic = Get.find(); + BaseLogic baseLogic = Get.find(); + late PoultryScienceRepository poultryScienceRepository; + Rx>> activeHatchingList = + Resource>.loading().obs; + + final RxBool isLoadingMoreList = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + List routesName = ['اقدام', 'جوجه ریزی فعال']; + + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + RxnString searchedValue = RxnString(); + + @override + void onInit() { + super.onInit(); + poultryScienceRepository = diChicken.get(); + } + + @override + void onReady() { + super.onReady(); + getHatchingList(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getHatchingList([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreList.value = true; + } else { + activeHatchingList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => await poultryScienceRepository.getHatchingPoultry( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + queryParams: {'type': 'hatching'}, + role: 'VetFarm', + pageSize: 50, + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + activeHatchingList.value = + Resource>.empty(); + } else { + activeHatchingList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(activeHatchingList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + Future onRefresh() async { + currentPage.value = 1; + await getHatchingList(); + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart new file mode 100644 index 0000000..3d0f986 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/active_hatching/view.dart @@ -0,0 +1,239 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/hatching/hatching_models.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet.dart'; +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +class ActiveHatchingPage extends GetView { + const ActiveHatchingPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasSearch: true, + hasFilter: false, + backId: vetFarmActionKey, + routes: controller.routesName, + onSearchChanged: (data) { + controller.searchedValue.value = data; + controller.getHatchingList(); + }, + child: hatchingWidget(), + /*widgets: [ + hatchingWidget() + ],*/ + ); + } + + Widget hatchingWidget() { + return ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidget(item), + secondChild: itemListExpandedWidget(item), + labelColor: AppColor.blueLight, + labelIcon: Assets.vec.activeFramSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getHatchingList(true), + ); + }, controller.activeHatchingList); + } + + Container itemListExpandedWidget(HatchingModel item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan16.copyWith(color: AppColor.greenDark), + ), + Spacer(), + + Visibility( + child: Text( + item.violation == true ? 'پیگیری' : 'عادی', + textAlign: TextAlign.center, + style: AppFonts.yekan10.copyWith(color: AppColor.redDark), + ), + ), + ], + ), + 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: [ + Text( + 'نژاد:${item.breed?.first.breed ?? 'N/A'}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + Text( + ' سن${item.age} (روز)', + + style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal), + ), + Text( + ' دوره جوجه ریزی:${item.period}', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ], + ), + ), + + buildRow( + title: 'شماره مجوز جوجه ریزی', + value: item.licenceNumber ?? 'N/A', + ), + buildUnitRow( + title: 'حجم جوجه ریزی', + value: item.quantity.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'مانده در سالن', + value: item.leftOver.separatedByCommaFa, + unit: '(قطعه)', + ), + buildUnitRow( + title: 'تلفات', + value: item.losses.separatedByCommaFa, + unit: '(قطعه)', + ), + buildRow( + title: 'دامپزشک فارم', + value: + '${item.vetFarm?.vetFarmFullName}(${item.vetFarm?.vetFarmMobile})', + ), + buildRow( + title: 'شرح بازرسی', + value: item.reportInfo?.image == false + ? 'ارسال تصویر جوجه ریزی فارم ' + : 'تکمیل شده', + titleStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + valueStyle: AppFonts.yekan14.copyWith( + color: (item.reportInfo?.image ?? false) + ? AppColor.greenNormal + : AppColor.redDark, + ), + ), + + RElevated( + height: 40.h, + isFullWidth: true, + onPressed: () { + Get.find().setHatchingModel( + item, + ); + Get.bottomSheet( + CreateInspectionBottomSheet(), + isScrollControlled: true, + ignoreSafeArea: false, + ).then((value) { + if (Get.isRegistered()) { + Get.find().clearForm(); + } + }); + }, + child: Text('ثبت بازرسی'), + ), + ], + ), + ); + } + + Widget itemListWidget(HatchingModel item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 3, + children: [ + Text( + item.poultry?.user?.fullname ?? 'N/A', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + Text( + item.poultry?.user?.mobile ?? 'N/A', + textAlign: TextAlign.center, + style: AppFonts.yekan14.copyWith(color: AppColor.bgDark), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 3, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + item.poultry?.unitName ?? 'N/Aaq', + textAlign: TextAlign.start, + style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), + ), + Text( + item.poultry?.licenceNumber ?? 'N/A', + textAlign: TextAlign.left, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + ], + ), + ), + Expanded( + flex: 1, + child: Assets.vec.scanSvg.svg( + width: 32.w, + height: 32.h, + colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn), + ), + ), + ], + ); + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart new file mode 100644 index 0000000..25da47a --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/home/logic.dart @@ -0,0 +1,25 @@ +import 'package:rasadyar_chicken/features/vet_farm/presentation/routes/routes.dart'; +import 'package:rasadyar_core/core.dart'; + +class VetFarmHomeItem { + final String title; + final String route; + final String icon; + + VetFarmHomeItem({required this.title, required this.route, required this.icon}); +} + +class VetFarmHomeLogic extends GetxController { + RxList items = [ + VetFarmHomeItem( + title: "جوجه ریزی فعال", + route: VetFarmRoutes.activeHatchingVetFarm, + icon: Assets.vec.activeFramSvg.path, + ), + VetFarmHomeItem( + title: "بازرسی مزارع طیور", + route: VetFarmRoutes.newInspectionVetFarm, + icon: Assets.vec.activeFramSvg.path, + ), + ].obs; +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/home/view.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/home/view.dart new file mode 100644 index 0000000..c88b6d8 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/home/view.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class HomePage extends GetView { + HomePage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isBase: true, + hasNews: true, + hasNotification: true, + child: gridWidget(), + ); + } + + Widget gridWidget() { + return ObxValue((data) { + return GridView.builder( + physics: BouncingScrollPhysics(), + padding: EdgeInsets.symmetric(vertical: 18.h, horizontal: 32.w), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + mainAxisSpacing: 24.h, + crossAxisSpacing: 24.w, + ), + itemCount: data.length, + hitTestBehavior: HitTestBehavior.opaque, + itemBuilder: (BuildContext context, int index) { + var item = data[index]; + return GlassMorphismCardIcon( + title: item.title, + vecIcon: item.icon, + onTap: () async { + Get.toNamed(item.route, id: vetFarmActionKey); + }, + ); + }, + ); + }, controller.items); + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/new_inspection/logic.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/new_inspection/logic.dart new file mode 100644 index 0000000..931d649 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/new_inspection/logic.dart @@ -0,0 +1,159 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/root/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class NewInspectionLogic extends GetxController { + BaseLogic baseLogic = Get.find(); + + Rx>> submitInspectionList = + Resource>.loading().obs; + + VetFarmRootLogic rootLogic = Get.find(); + + final RxBool isLoadingMoreAllocationsMade = false.obs; + RxInt currentPage = 1.obs; + RxInt expandedIndex = RxInt(-1); + RxList pickedImages = [].obs; + final List _multiPartPickedImages = []; + + RxBool isOnUpload = false.obs; + + RxDouble presentUpload = 0.0.obs; + RxList routesName = RxList(); + RxInt selectedSegmentIndex = 0.obs; + + RxnString searchedValue = RxnString(); + Rx fromDateFilter = Jalali.now().obs; + Rx toDateFilter = Jalali.now().obs; + + @override + void onInit() { + super.onInit(); + + routesName.value = ['اقدام'].toList(); + + ever(selectedSegmentIndex, (callback) { + routesName.removeLast(); + routesName.add(callback == 0 ? 'بازرسی' : 'بایگانی'); + }); + } + + @override + void onReady() { + super.onReady(); + + getReport(); + } + + @override + void onClose() { + super.onClose(); + baseLogic.clearSearch(); + } + + Future getReport([bool isLoadingMore = false]) async { + if (isLoadingMore) { + isLoadingMoreAllocationsMade.value = true; + } else { + submitInspectionList.value = + Resource>.loading(); + } + + if (searchedValue.value != null && + searchedValue.value!.trim().isNotEmpty && + currentPage.value > 1) { + currentPage.value = 1; + } + + safeCall( + call: () async => + await rootLogic.vetFarmRepository.getSubmitInspectionList( + token: rootLogic.tokenService.accessToken.value!, + queryParameters: buildQueryParams( + role: 'VetFarm', + pageSize: 50, + search: 'filter', + + page: currentPage.value, + ), + ), + onSuccess: (res) { + if ((res?.count ?? 0) == 0) { + submitInspectionList.value = + Resource>.empty(); + } else { + submitInspectionList.value = + Resource>.success( + PaginationModel( + count: res?.count ?? 0, + next: res?.next, + previous: res?.previous, + results: [ + ...(submitInspectionList.value.data?.results ?? []), + ...(res?.results ?? []), + ], + ), + ); + } + }, + ); + } + + Future pickImages() async { + determineCurrentPosition(); + var tmp = await pickCameraImage(); + if (tmp?.path != null && pickedImages.length < 7) { + pickedImages.add(tmp!); + } + } + + void removeImage(int index) { + pickedImages.removeAt(index); + } + + void closeBottomSheet() { + Get.back(); + } + + double calculateUploadProgress({required int sent, required int total}) { + if (total != 0) { + double progress = (sent * 100 / total) / 100; + return progress; + } else { + return 0.0; + } + } + + void toggleExpanded(int index) { + expandedIndex.value = expandedIndex.value == index ? -1 : index; + } + + void setSearchValue(String? data) { + dLog('Search Value: $data'); + searchedValue.value = data?.trim(); + getReport(); + } + + Future onRefresh() async { + currentPage.value = 1; + await getReport(); + } + + String getStatus(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return 'در حال بررسی'; + } + return status; + } + + Color getStatusColor(PoultryScienceReport item) { + final status = item.reportInformation?.inspectionStatus ?? item.state; + if (status == null || status.isEmpty) { + return AppColor.yellowNormal; + } + // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید + return AppColor.greenNormal; + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/new_inspection/view.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/new_inspection/view.dart new file mode 100644 index 0000000..e9daf41 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/new_inspection/view.dart @@ -0,0 +1,1134 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/poultry_science/data/model/response/poultry_science_report/poultry_science_report.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class NewInspectionPage extends GetView { + const NewInspectionPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + hasBack: true, + hasFilter: true, + hasSearch: true, + onFilterTap: () { + Get.bottomSheet(filterBottomSheet()); + }, + onRefresh: controller.onRefresh, + onSearchChanged: (data) => controller.setSearchValue(data), + backId: vetFarmActionKey, + routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), + child: Column(children: [reportWidget()]), + ); + } + + Widget reportWidget() { + return Expanded( + child: ObxValue((data) { + return RPaginatedListView( + listType: ListType.separated, + resource: data.value, + hasMore: data.value.data?.next != null, + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + itemBuilder: (context, index) { + var item = data.value.data!.results![index]; + return ObxValue((val) { + return ExpandableListItem2( + selected: val.value.isEqual(index), + onTap: () => controller.toggleExpanded(index), + index: index, + child: itemListWidgetReport(item), + secondChild: itemListExpandedWidgetReport(item), + labelColor: AppColor.greenLight, + labelIcon: Assets.vec.cubeSearchSvg.path, + ); + }, controller.expandedIndex); + }, + itemCount: data.value.data?.results?.length ?? 0, + separatorBuilder: (context, index) => SizedBox(height: 8.h), + onLoadMore: () async => controller.getReport(true), + ); + }, controller.submitInspectionList), + ); + } + + Widget itemListExpandedWidgetReport(PoultryScienceReport item) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + spacing: 8, + children: [ + buildRow( + title: 'وضعیت بازرسی', + value: controller.getStatus(item), + titleStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + valueStyle: AppFonts.yekan14.copyWith( + color: controller.getStatusColor(item), + ), + ), + if (item.hatching?.poultry?.unitName != null) + buildRow( + title: 'مرغداری', + value: item.hatching?.poultry?.unitName ?? '-', + ), + if (item.hatching?.id != null) + buildRow( + title: 'شناسه جوجه‌ریزی', + value: item.hatching!.id.toString(), + ), + + if (item + .reportInformation + ?.technicalOfficer + ?.technicalHealthOfficer != + null) + buildRow( + title: 'کارشناس بهداشت', + value: + item + .reportInformation! + .technicalOfficer! + .technicalHealthOfficer ?? + '-', + ), + if (item + .reportInformation + ?.technicalOfficer + ?.technicalEngineeringOfficer != + null) + buildRow( + title: 'کارشناس فنی', + value: + item + .reportInformation! + .technicalOfficer! + .technicalEngineeringOfficer ?? + '-', + ), + if (item.reportInformation?.casualties?.normalLosses != null || + item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات عادی', + value: (item.reportInformation?.casualties?.normalLosses ?? 0) + .toString(), + unit: '(قطعه)', + ), + if (item.reportInformation?.casualties?.abnormalLosses != null) + buildUnitRow( + title: 'تلفات غیرعادی', + value: item.reportInformation!.casualties!.abnormalLosses + .toString(), + unit: '(قطعه)', + ), + + if (item.reportInformation?.inspectionNotes != null && + item.reportInformation!.inspectionNotes!.isNotEmpty) + buildRow( + title: 'یادداشت بازرسی', + value: item.reportInformation!.inspectionNotes ?? '-', + ), + + RElevated( + text: 'جزییات', + isFullWidth: true, + width: 150.w, + height: 40.h, + onPressed: () { + showDetailsBottomSheet(item); + }, + textStyle: AppFonts.yekan16.copyWith(color: Colors.white), + backgroundColor: AppColor.greenNormal, + ), + ], + ), + ); + } + + Row itemListWidgetReport(PoultryScienceReport item) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + SizedBox(width: 20), + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + spacing: 5, + children: [ + Text( + 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + + Text( + item.createDate?.toJalali.formatCompactDate() ?? '-', + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + Expanded( + flex: 3, + child: Column( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), + ), + if (item.reportInformation?.inspectionStatus != null) + Text( + 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}', + textAlign: TextAlign.center, + style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon), + ), + ], + ), + ), + ], + ); + } + + void showDetailsBottomSheet(PoultryScienceReport item) { + Get.bottomSheet( + isScrollControlled: true, + BaseBottomSheet( + height: Get.height * 0.8, + rootChild: DetailsBottomSheetWidget(item: item), + ), + ); + } + + Widget filterBottomSheet() { + return BaseBottomSheet( + height: 200, + child: Column( + spacing: 16, + children: [ + Text( + 'فیلترها', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), + ), + Row( + spacing: 8, + children: [ + Expanded( + child: dateFilterWidget( + date: controller.fromDateFilter, + onChanged: (jalali) => + controller.fromDateFilter.value = jalali, + ), + ), + Expanded( + child: dateFilterWidget( + isFrom: false, + date: controller.toDateFilter, + onChanged: (jalali) => controller.toDateFilter.value = jalali, + ), + ), + ], + ), + RElevated( + text: 'اعمال فیلتر', + isFullWidth: true, + backgroundColor: AppColor.greenNormal, + onPressed: () { + controller.getReport(); + Get.back(); + }, + height: 40, + ), + ], + ), + ); + } +} + +class DetailsBottomSheetWidget extends StatefulWidget { + final PoultryScienceReport item; + + const DetailsBottomSheetWidget({super.key, required this.item}); + + @override + State createState() => + _DetailsBottomSheetWidgetState(); +} + +class _DetailsBottomSheetWidgetState extends State { + int selectedTabIndex = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.max, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 4, + vertical: 10, + ), + child: Text( + 'جزییات', + style: AppFonts.yekan18Bold.copyWith( + color: AppColor.iconColor, + ), + ), + ), + ], + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + tabBarWidget( + [ + 'اطلاعات کلی', + 'شرایط سالن', + 'تلفات', + 'کارشناس', + 'نهاده', + 'زیرساخت', + 'نیروی انسانی', + 'تسهیلات', + ], + selectedTabIndex, + (index) => setState(() => selectedTabIndex = index), + ), + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _buildTableContent(), + ), + ), + ), + ], + ); + } + + Widget _buildTableContent() { + switch (selectedTabIndex) { + case 0: + return generalInfoTable(); + case 1: + return generalConditionHallTable(); + case 2: + return casualtiesTable(); + case 3: + return technicalOfficerTable(); + case 4: + return inputStatusTable(); + case 5: + return infrastructureEnergyTable(); + case 6: + return hrTable(); + case 7: + return facilitiesTable(); + default: + return generalInfoTable(); + } + } + + Widget technicalOfficerTable() { + final officer = widget.item.reportInformation?.technicalOfficer; + if (officer == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'کارشناس فنی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'کارشناس بهداشت', + value: officer.technicalHealthOfficer ?? '-', + ), + rTableRow( + title: 'کارشناس فنی', + value: officer.technicalEngineeringOfficer ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget generalInfoTable() { + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'اطلاعات کلی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت بازرسی', + value: + widget.item.reportInformation?.inspectionStatus ?? + widget.item.state ?? + '-', + ), + rTableRow( + title: 'یادداشت بازرسی', + value: widget.item.reportInformation?.inspectionNotes ?? '-', + ), + rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'), + if (widget.item.lat != null && widget.item.log != null) + rTableRow( + title: 'موقعیت', + value: '${widget.item.lat}, ${widget.item.log}', + ), + if (widget.item.hatching?.id != null) + rTableRow( + title: 'شناسه جوجه ریزی', + value: widget.item.hatching!.id.toString(), + ), + ], + ), + ), + ], + ); + } + + Widget generalConditionHallTable() { + final hall = widget.item.reportInformation?.generalConditionHall; + if (hall == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'شرایط عمومی سالن', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow(title: 'وضعیت سلامت', value: hall.healthStatus ?? '-'), + rTableRow( + title: 'وضعیت تهویه', + value: hall.ventilationStatus ?? '-', + ), + rTableRow(title: 'وضعیت بستر', value: hall.bedCondition ?? '-'), + rTableRow(title: 'دما', value: hall.temperature ?? '-'), + rTableRow( + title: 'منبع آب آشامیدنی', + value: hall.drinkingWaterSource ?? '-', + ), + rTableRow( + title: 'کیفیت آب آشامیدنی', + value: hall.drinkingWaterQuality ?? '-', + ), + ], + ), + ), + if (hall.images != null && hall.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: hall.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(hall.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(hall.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget casualtiesTable() { + final casualties = widget.item.reportInformation?.casualties; + if (casualties == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تلفات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (casualties.normalLosses != null) + rTableRow( + title: 'تلفات عادی', + value: casualties.normalLosses.toString(), + ), + if (casualties.abnormalLosses != null) + rTableRow( + title: 'تلفات غیرعادی', + value: casualties.abnormalLosses.toString(), + ), + rTableRow( + title: 'منبع جوجه ریزی', + value: casualties.sourceOfHatching ?? '-', + ), + rTableRow( + title: 'علت تلفات غیرعادی', + value: casualties.causeAbnormalLosses ?? '-', + ), + rTableRow( + title: 'نوع بیماری', + value: casualties.typeDisease ?? '-', + ), + rTableRow( + title: 'نمونه‌برداری انجام شده', + value: casualties.samplingDone == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع نمونه‌برداری', + value: casualties.typeSampling ?? '-', + ), + ], + ), + ), + if (casualties.images != null && casualties.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: casualties.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(casualties.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(casualties.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget inputStatusTable() { + final inputStatus = widget.item.reportInformation?.inputStatus; + if (inputStatus == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'وضعیت نهاده', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'وضعیت نهاده', + value: inputStatus.inputStatus ?? '-', + ), + rTableRow( + title: 'نام شرکت', + value: inputStatus.companyName ?? '-', + ), + rTableRow( + title: 'کد پیگیری', + value: inputStatus.trackingCode ?? '-', + ), + rTableRow( + title: 'نوع دانه', + value: inputStatus.typeOfGrain ?? '-', + ), + rTableRow( + title: 'موجودی در انبار', + value: inputStatus.inventoryInWarehouse ?? '-', + ), + rTableRow( + title: 'موجودی تا بازدید', + value: inputStatus.inventoryUntilVisit ?? '-', + ), + rTableRow( + title: 'درجه دانه', + value: inputStatus.gradeGrain ?? '-', + ), + ], + ), + ), + if (inputStatus.images != null && inputStatus.images!.isNotEmpty) ...[ + SizedBox(height: 16), + Text( + 'تصاویر', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + SizedBox(height: 10), + SizedBox( + height: 100.h, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: inputStatus.images!.length, + separatorBuilder: (context, index) => SizedBox(width: 10), + itemBuilder: (context, index) => GestureDetector( + onTap: () => showImageDialog(inputStatus.images!, index), + child: Container( + width: 80.w, + height: 80.h, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(inputStatus.images![index]), + ), + ), + ), + ), + ), + ), + ], + ], + ); + } + + Widget infrastructureEnergyTable() { + final infra = widget.item.reportInformation?.infrastructureEnergy; + if (infra == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'زیرساخت و انرژی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'نوع ژنراتور', + value: infra.generatorType ?? '-', + ), + rTableRow( + title: 'مدل ژنراتور', + value: infra.generatorModel ?? '-', + ), + rTableRow( + title: 'تعداد ژنراتور', + value: infra.generatorCount ?? '-', + ), + rTableRow( + title: 'ظرفیت ژنراتور', + value: infra.generatorCapacity ?? '-', + ), + rTableRow(title: 'نوع سوخت', value: infra.fuelType ?? '-'), + rTableRow( + title: 'عملکرد ژنراتور', + value: infra.generatorPerformance ?? '-', + ), + rTableRow( + title: 'موجودی سوخت اضطراری', + value: infra.emergencyFuelInventory ?? '-', + ), + rTableRow( + title: 'تاریخچه قطع برق', + value: infra.hasPowerCutHistory == true ? 'بله' : 'خیر', + ), + if (infra.hasPowerCutHistory == true) ...[ + rTableRow( + title: 'مدت قطع برق', + value: infra.powerCutDuration ?? '-', + ), + rTableRow( + title: 'ساعت قطع برق', + value: infra.powerCutHour ?? '-', + ), + ], + rTableRow( + title: 'یادداشت اضافی', + value: infra.additionalNotes ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget hrTable() { + final hr = widget.item.reportInformation?.hr; + if (hr == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'نیروی انسانی', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + if (hr.numberEmployed != null) + rTableRow( + title: 'تعداد شاغلین', + value: hr.numberEmployed.toString(), + ), + if (hr.numberIndigenous != null) + rTableRow( + title: 'تعداد بومی', + value: hr.numberIndigenous.toString(), + ), + if (hr.numberNonIndigenous != null) + rTableRow( + title: 'تعداد غیربومی', + value: hr.numberNonIndigenous.toString(), + ), + rTableRow( + title: 'وضعیت قرارداد', + value: hr.contractStatus ?? '-', + ), + rTableRow( + title: 'آموزش دیده', + value: hr.trained == true ? 'بله' : 'خیر', + ), + ], + ), + ), + ], + ); + } + + Widget facilitiesTable() { + final facilities = widget.item.reportInformation?.facilities; + if (facilities == null) { + return Center( + child: Padding( + padding: const EdgeInsets.all(20), + child: Text( + 'اطلاعاتی وجود ندارد', + style: AppFonts.yekan14.copyWith(color: AppColor.textColor), + ), + ), + ); + } + + return Column( + children: [ + SizedBox(height: 10), + Row( + children: [ + Text( + 'تسهیلات', + style: AppFonts.yekan16Bold.copyWith(color: AppColor.iconColor), + ), + ], + ), + SizedBox(height: 10), + Container( + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + children: [ + rTableRow( + title: 'دارای تسهیلات', + value: facilities.hasFacilities == true ? 'بله' : 'خیر', + ), + rTableRow( + title: 'نوع تسهیلات', + value: facilities.typeOfFacility ?? '-', + ), + if (facilities.amount != null) + rTableRow(title: 'مبلغ', value: facilities.amount.toString()), + rTableRow(title: 'تاریخ', value: facilities.date ?? '-'), + rTableRow( + title: 'وضعیت بازپرداخت', + value: facilities.repaymentStatus ?? '-', + ), + rTableRow( + title: 'درخواست تسهیلات', + value: facilities.requestFacilities ?? '-', + ), + ], + ), + ), + ], + ); + } + + Widget tabBarWidget( + List tabs, + int selectedIndex, + Function(int) onTabSelected, + ) { + return SizedBox( + height: 40.h, + width: Get.width, + child: Column( + children: [ + SingleChildScrollView( + scrollDirection: Axis.horizontal, + reverse: true, + child: Row( + children: [ + ...tabs.map( + (tab) => GestureDetector( + onTap: () => onTabSelected(tabs.indexOf(tab)), + behavior: HitTestBehavior.opaque, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 10, + vertical: 11, + ), + decoration: BoxDecoration( + border: tab == tabs[selectedIndex] + ? Border( + bottom: BorderSide( + color: AppColor.blueNormalOld, + width: 3, + ), + ) + : null, + ), + child: Text( + tab, + style: AppFonts.yekan12Bold.copyWith( + color: tab == tabs[selectedIndex] + ? AppColor.blueNormalOld + : AppColor.mediumGrey, + ), + ), + ), + ), + ), + ], + ), + ), + Divider(color: AppColor.blackLightHover, height: 1, thickness: 1), + ], + ), + ); + } + + Row rTableRow({String? title, String? value}) { + return Row( + children: [ + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + color: AppColor.bgLight2, + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + title ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.iconColor), + ), + ), + ), + Expanded( + flex: 1, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 9, vertical: 11), + alignment: Alignment.centerRight, + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: AppColor.blackLightHover, width: 1), + ), + ), + child: Text( + value ?? '', + style: AppFonts.yekan14Bold.copyWith(color: AppColor.textColor), + ), + ), + ), + ], + ); + } + + void showImageDialog(List images, int initialIndex) { + final pageController = PageController(initialPage: initialIndex); + final currentIndex = initialIndex.obs; + + Get.dialog( + Dialog( + backgroundColor: Colors.transparent, + insetPadding: EdgeInsets.zero, + child: Container( + width: Get.width, + height: Get.height, + color: Colors.black, + child: Stack( + children: [ + PageView.builder( + controller: pageController, + itemCount: images.length, + onPageChanged: (index) { + currentIndex.value = index; + }, + itemBuilder: (context, index) { + return InteractiveViewer( + minScale: 0.5, + maxScale: 4.0, + child: Center( + child: Image.network( + images[index], + fit: BoxFit.contain, + loadingBuilder: (context, child, loadingProgress) { + if (loadingProgress == null) return child; + return Center( + child: CircularProgressIndicator( + value: loadingProgress.expectedTotalBytes != null + ? loadingProgress.cumulativeBytesLoaded / + loadingProgress.expectedTotalBytes! + : null, + color: Colors.white, + ), + ); + }, + errorBuilder: (context, error, stackTrace) { + return Center( + child: Icon( + Icons.error, + color: Colors.white, + size: 50, + ), + ); + }, + ), + ), + ); + }, + ), + Positioned( + top: 40, + right: 16, + child: IconButton( + icon: Icon(Icons.close, color: Colors.white, size: 30), + onPressed: () => Get.back(), + ), + ), + if (images.length > 1) + Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Obx( + () => Container( + padding: EdgeInsets.symmetric( + horizontal: 12, + vertical: 6, + ), + decoration: BoxDecoration( + color: Colors.black54, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + '${currentIndex.value + 1} / ${images.length}', + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ], + ), + ), + ), + barrierDismissible: true, + ); + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/root/logic.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/root/logic.dart new file mode 100644 index 0000000..c77df23 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/root/logic.dart @@ -0,0 +1,84 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:rasadyar_chicken/data/di/chicken_di.dart'; +import 'package:rasadyar_chicken/features/vet_farm/data/repositories/vet_farm_repository.dart'; + +import 'package:rasadyar_chicken/features/common/presentation/page/profile/view.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/routes/pages.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/utils/utils.dart'; +import 'package:rasadyar_core/core.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } + +class VetFarmRootLogic extends GetxController { + var tokenService = Get.find(); + + late VetFarmRepository vetFarmRepository; + + RxList errorLocationType = RxList(); + RxMap homeExpandedList = RxMap(); + DateTime? _lastBackPressed; + + RxInt currentPage = 0.obs; + + final pages = [ + Navigator( + key: Get.nestedKey(vetFarmActionKey), + onGenerateRoute: (settings) { + final page = VetFarmPages.pages.firstWhere( + (e) => e.name == settings.name, + orElse: () => VetFarmPages.pages.firstWhere( + (e) => e.name == VetFarmRoutes.homeVetFarm, + ), + ); + + return buildRouteFromGetPage(page); + }, + ), + + ProfilePage(), + ]; + + @override + void onInit() { + super.onInit(); + vetFarmRepository = diChicken.get(); + } + + void toggleExpanded(int index) { + if (homeExpandedList.keys.contains(index)) { + homeExpandedList.remove(index); + } else { + homeExpandedList[index] = false; + } + } + + void rootErrorHandler(DioException error) { + handleGeneric(error, () { + tokenService.deleteModuleTokens(Module.chicken); + }); + } + + void changePage(int index) { + currentPage.value = index; + } + + void popBackTaped() async { + final now = DateTime.now(); + if (_lastBackPressed == null || + now.difference(_lastBackPressed!) > Duration(seconds: 2)) { + _lastBackPressed = now; + Get.snackbar( + 'خروج از برنامه', + 'برای خروج دوباره بازگشت را بزنید', + snackPosition: SnackPosition.TOP, + duration: Duration(seconds: 2), + backgroundColor: AppColor.warning, + ); + } else { + await SystemNavigator.pop(); + } + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/pages/root/view.dart b/packages/chicken/lib/features/vet_farm/presentation/pages/root/view.dart new file mode 100644 index 0000000..8e905d6 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/pages/root/view.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/view.dart'; +import 'package:rasadyar_core/core.dart'; + +import 'logic.dart'; + +class VetFarmRootPage extends GetView { + const VetFarmRootPage({super.key}); + + @override + Widget build(BuildContext context) { + return ChickenBasePage( + isFullScreen: true, + onPopScopTaped: controller.popBackTaped, + child: ObxValue((data) { + return Stack( + children: [ + IndexedStack(children: controller.pages, index: data.value), + Positioned( + right: 0, + left: 0, + bottom: 0, + child: RBottomNavigation( + mainAxisAlignment: MainAxisAlignment.spaceAround, + items: [ + + RBottomNavigationItem( + label: 'خانه', + icon: Assets.vec.homeSvg.path, + isSelected: controller.currentPage.value == 0, + onTap: () { + Get.nestedKey( + vetFarmActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(0); + }, + ), + RBottomNavigationItem( + label: 'پروفایل', + icon: Assets.vec.profileCircleSvg.path, + isSelected: controller.currentPage.value == 1, + onTap: () { + Get.nestedKey( + vetFarmActionKey, + )?.currentState?.popUntil((route) => route.isFirst); + controller.changePage(1); + }, + ), + ], + ), + ), + ], + ); + }, controller.currentPage), + ); + } +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/routes/pages.dart b/packages/chicken/lib/features/vet_farm/presentation/routes/pages.dart new file mode 100644 index 0000000..2e889a7 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/routes/pages.dart @@ -0,0 +1,76 @@ +import 'package:rasadyar_chicken/features/poultry_science/presentation/widgets/submit_inspection_bottom_sheet/create_inspection_bottom_sheet_logic.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/home/logic.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/home/view.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/root/logic.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/root/view.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/active_hatching/logic.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/active_hatching/view.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/new_inspection/logic.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/new_inspection/view.dart'; +import 'package:rasadyar_chicken/features/vet_farm/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/presentation/routes/global_binding.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; +import 'package:rasadyar_core/core.dart'; + +class VetFarmPages { + VetFarmPages._(); + + static List get pages => [ + GetPage( + name: VetFarmRoutes.initVetFarm, + page: () => VetFarmRootPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + Get.lazyPut(() => VetFarmRootLogic()); + Get.lazyPut(() => VetFarmHomeLogic()); + }), + ], + ), + GetPage( + name: VetFarmRoutes.homeVetFarm, + page: () => HomePage(), + middlewares: [AuthMiddleware()], + binding: BindingsBuilder(() { + Get.put(VetFarmHomeLogic()); + Get.lazyPut(() => ChickenBaseLogic()); + }), + ), + GetPage( + name: VetFarmRoutes.actionVetFarm, + page: () => HomePage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => VetFarmHomeLogic()); + }), + ], + ), + GetPage( + name: VetFarmRoutes.activeHatchingVetFarm, + page: () => ActiveHatchingPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => ActiveHatchingLogic()); + Get.lazyPut(() => CreateInspectionBottomSheetLogic()); + }), + ], + ), + GetPage( + name: VetFarmRoutes.newInspectionVetFarm, + page: () => NewInspectionPage(), + middlewares: [AuthMiddleware()], + bindings: [ + GlobalBinding(), + BindingsBuilder(() { + Get.lazyPut(() => NewInspectionLogic()); + }), + ], + ), + ]; +} diff --git a/packages/chicken/lib/features/vet_farm/presentation/routes/routes.dart b/packages/chicken/lib/features/vet_farm/presentation/routes/routes.dart new file mode 100644 index 0000000..8021045 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/presentation/routes/routes.dart @@ -0,0 +1,10 @@ +sealed class VetFarmRoutes { + VetFarmRoutes._(); + + static const _base = '/chicken/vetFarm'; + static const initVetFarm = '$_base/'; + static const homeVetFarm = '$_base/home'; + static const actionVetFarm = '$_base/action'; + static const activeHatchingVetFarm = '$_base/activeHatching'; + static const newInspectionVetFarm = '$_base/newInspection'; +} diff --git a/packages/chicken/lib/features/vet_farm/vet_farm.dart b/packages/chicken/lib/features/vet_farm/vet_farm.dart new file mode 100644 index 0000000..258e885 --- /dev/null +++ b/packages/chicken/lib/features/vet_farm/vet_farm.dart @@ -0,0 +1,3 @@ +export 'data/di/vet_farm_di.dart'; +export 'presentation/routes/routes.dart'; +export 'presentation/routes/pages.dart'; diff --git a/packages/chicken/lib/hive_registrar.g.dart b/packages/chicken/lib/hive_registrar.g.dart index 25d0c02..f96cbe0 100644 --- a/packages/chicken/lib/hive_registrar.g.dart +++ b/packages/chicken/lib/hive_registrar.g.dart @@ -3,7 +3,7 @@ // Check in to version control import 'package:hive_ce/hive.dart'; -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; extension HiveRegistrar on HiveInterface { void registerAdapters() { diff --git a/packages/chicken/lib/presentation/routes/global_binding.dart b/packages/chicken/lib/presentation/routes/global_binding.dart index 61e35f6..992603f 100644 --- a/packages/chicken/lib/presentation/routes/global_binding.dart +++ b/packages/chicken/lib/presentation/routes/global_binding.dart @@ -1,10 +1,15 @@ -import 'package:rasadyar_chicken/features/common/profile/logic.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/profile/logic.dart'; +import 'package:rasadyar_chicken/presentation/widget/base_page/logic.dart'; import 'package:rasadyar_core/core.dart'; class GlobalBinding extends Bindings { @override void dependencies() { - Get.lazyPut(() => BaseLogic(), fenix: true); + // Register ChickenBaseLogic and also as BasePageLogic/BaseLogic for compatibility + // Since ChickenBaseLogic extends BasePageLogic, we can use the same instance + Get.lazyPut(() => ChickenBaseLogic(), fenix: true); + // Register the same instance as BasePageLogic/BaseLogic + Get.lazyPut(() => Get.find(), fenix: true); Get.lazyPut(() => ProfileLogic(), fenix: true); //root logics diff --git a/packages/chicken/lib/presentation/routes/pages.dart b/packages/chicken/lib/presentation/routes/pages.dart index bce66a1..e08ddce 100644 --- a/packages/chicken/lib/presentation/routes/pages.dart +++ b/packages/chicken/lib/presentation/routes/pages.dart @@ -1,237 +1,69 @@ -import 'package:rasadyar_chicken/features/common/auth/logic.dart'; -import 'package:rasadyar_chicken/features/common/auth/view.dart'; -import 'package:rasadyar_chicken/features/common/role/logic.dart'; -import 'package:rasadyar_chicken/features/common/role/view.dart'; +import 'package:rasadyar_chicken/features/common/common.dart'; import 'package:rasadyar_chicken/features/kill_house/action/logic.dart'; import 'package:rasadyar_chicken/features/kill_house/action/view.dart'; import 'package:rasadyar_chicken/features/kill_house/root/logic.dart'; import 'package:rasadyar_chicken/features/kill_house/root/view.dart'; import 'package:rasadyar_chicken/features/kill_house/submit_request/logic.dart'; import 'package:rasadyar_chicken/features/kill_house/submit_request/view.dart'; -import 'package:rasadyar_chicken/features/kill_house/warehouse_and_distribution/buy_in_province_entered/logic.dart'; import 'package:rasadyar_chicken/features/poultry_farm_inspection/poultry_farm_inspection.dart'; -import 'package:rasadyar_chicken/features/poultry_science/active_hatching/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/active_hatching/view.dart'; -import 'package:rasadyar_chicken/features/poultry_science/farm/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/farm/view.dart'; -import 'package:rasadyar_chicken/features/poultry_science/genocide/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/genocide/view.dart'; -import 'package:rasadyar_chicken/features/poultry_science/home/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/inspection/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/inspection/view.dart'; -import 'package:rasadyar_chicken/features/poultry_science/killing_registration/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/killing_registration/view.dart'; -import 'package:rasadyar_chicken/features/poultry_science/poultry_action/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/poultry_action/view.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/logic.dart'; -import 'package:rasadyar_chicken/features/poultry_science/root/view.dart'; +import 'package:rasadyar_chicken/features/poultry_science/poultry_science.dart'; import 'package:rasadyar_chicken/features/steward/steward.dart'; -import 'package:rasadyar_chicken/features/kill_house/warehouse_and_distribution/warehouse_and_distribution.dart' - as warehouse; +import 'package:rasadyar_chicken/features/province_operator/province_operator.dart'; +import 'package:rasadyar_chicken/features/province_inspector/province_inspector.dart'; +import 'package:rasadyar_chicken/features/city_jahad/city_jahad.dart'; +import 'package:rasadyar_chicken/features/vet_farm/vet_farm.dart'; +import 'package:rasadyar_chicken/features/super_admin/super_admin.dart'; +import 'package:rasadyar_chicken/features/province_supervisor/province_supervisor.dart'; +import 'package:rasadyar_chicken/features/jahad/jahad.dart'; import 'package:rasadyar_chicken/presentation/routes/global_binding.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/captcha/logic.dart'; import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_chicken/features/kill_house/warehouse_and_distribution/warehouse_and_distribution.dart' + as warehouse; sealed class ChickenPages { ChickenPages._(); static final pages = [ - GetPage( - name: ChickenRoutes.auth, - page: () => AuthPage(), - binding: BindingsBuilder(() { - Get.lazyPut(() => AuthLogic()); - Get.lazyPut(() => CaptchaWidgetLogic()); - Get.lazyPut(() => ChickenBaseLogic(), fenix: true); - }), - ), - - GetPage( - name: ChickenRoutes.role, - page: () => RolePage(), - binding: BindingsBuilder(() { - Get.lazyPut(() => RoleLogic()); - Get.lazyPut(() => ChickenBaseLogic(), fenix: true); - }), - ), + //region Common Pages + ...CommonPages.pages, + //endregion //region Steward Pages - GetPage( - name: ChickenRoutes.initSteward, - page: () => StewardRootPage(), - middlewares: [AuthMiddleware()], - bindings: [ - GlobalBinding(), - BindingsBuilder(() { - Get.lazyPut(() => ChickenBaseLogic(), fenix: true); - Get.lazyPut(() => StewardRootLogic()); - Get.lazyPut(() => HomeLogic()); - Get.lazyPut(() => BuyLogic()); - Get.lazyPut(() => SaleLogic()); - Get.lazyPut(() => SegmentationLogic()); - }), - ], - ), - - GetPage( - name: ChickenRoutes.homeSteward, - page: () => HomePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.put(HomeLogic()); - Get.lazyPut(() => ChickenBaseLogic()); - }), - ), - - //sales - GetPage( - name: ChickenRoutes.saleSteward, - page: () => SalePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => SaleLogic()); - Get.lazyPut(() => ChickenBaseLogic()); - Get.lazyPut(() => SalesOutOfProvinceLogic()); - Get.lazyPut(() => SalesOutOfProvinceBuyersLogic()); - Get.lazyPut(() => StewardRootLogic()); - }), - ), - GetPage( - name: ChickenRoutes.salesOutOfProvinceSteward, - page: () => SalesOutOfProvincePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => SalesOutOfProvinceLogic()); - Get.lazyPut(() => SalesOutOfProvinceBuyersLogic()); - Get.lazyPut(() => SalesOutOfProvinceSalesListLogic()); - }), - ), - GetPage( - name: ChickenRoutes.salesOutOfProvinceBuyerSteward, - page: () => SalesOutOfProvinceBuyersPage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => SalesOutOfProvinceLogic()); - Get.lazyPut(() => SalesOutOfProvinceBuyersLogic()); - Get.lazyPut(() => SalesOutOfProvinceSalesListLogic()); - }), - ), - GetPage( - name: ChickenRoutes.salesInProvinceSteward, - page: () => SalesInProvincePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => ChickenBaseLogic()); - Get.lazyPut(() => SalesInProvinceLogic()); - }), - ), - - //buy - GetPage( - name: ChickenRoutes.buySteward, - page: () => BuyPage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => ChickenBaseLogic()); - Get.lazyPut(() => BuyLogic()); - }), - ), - GetPage( - name: ChickenRoutes.buysOutOfProvinceSteward, - page: () => BuyOutOfProvincePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => ChickenBaseLogic()); - Get.lazyPut(() => BuyOutOfProvinceLogic()); - }), - ), - GetPage( - name: ChickenRoutes.buysInProvinceSteward, - page: () => BuyInProvincePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => ChickenBaseLogic()); - Get.lazyPut(() => BuyInProvinceLogic()); - Get.lazyPut(() => BuyInProvinceWaitingLogic()); - Get.lazyPut(() => BuyInProvinceAllLogic()); - }), - ), - + ...StewardPages.pages, //endregion //region Poultry science Pages - GetPage( - name: ChickenRoutes.initPoultryScience, - page: () => PoultryScienceRootPage(), - middlewares: [AuthMiddleware()], - bindings: [ - GlobalBinding(), - BindingsBuilder(() { - Get.lazyPut(() => PoultryScienceRootLogic()); - Get.lazyPut(() => PoultryScienceHomeLogic()); - Get.lazyPut(() => PoultryActionLogic()); - }), - ], - ), + ...PoultrySciencePages.pages, + //endregion - GetPage( - name: ChickenRoutes.inspectionPoultryScience, - page: () => InspectionPoultrySciencePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => InspectionPoultryScienceLogic()); - }), - ), - GetPage( - name: ChickenRoutes.actionPoultryScience, - page: () => PoultryActionPage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => PoultryActionLogic()); - }), - ), + //region Province Operator Pages + ...ProvinceOperatorPages.pages, + //endregion - GetPage( - name: ChickenRoutes.farmPoultryScience, - page: () => FarmPage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => FarmLogic()); - Get.lazyPut(() => PoultryScienceHomeLogic()); - Get.lazyPut(() => PoultryScienceRootLogic()); - }), - ), - GetPage( - name: ChickenRoutes.activeHatchingPoultryScience, - page: () => ActiveHatchingPage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => ActiveHatchingLogic()); - Get.lazyPut(() => PoultryScienceRootLogic()); - }), - ), - GetPage( - name: ChickenRoutes.genocidePoultryScience, - page: () => GenocidePage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => GenocideLogic()); - Get.lazyPut(() => PoultryScienceRootLogic()); - Get.lazyPut(() => KillingRegistrationLogic(), fenix: true); - }), - ), - GetPage( - name: ChickenRoutes.killingRegistrationPoultryScience, - page: () => KillingRegistrationPage(), - middlewares: [AuthMiddleware()], - binding: BindingsBuilder(() { - Get.lazyPut(() => KillingRegistrationLogic()); - Get.lazyPut(() => GenocideLogic()); - Get.lazyPut(() => PoultryScienceRootLogic()); - }), - ), + //region Province Inspector Pages + ...ProvinceInspectorPages.pages, + //endregion + + //region City Jahad Pages + ...CityJahadPages.pages, + //endregion + + //region Vet Farm Pages + ...VetFarmPages.pages, + //endregion + + //region Super Admin Pages + ...SuperAdminPages.pages, + //endregion + + //region Province Supervisor Pages + ...ProvinceSupervisorPages.pages, + //endregion + + //region Jahad Pages + ...JahadPages.pages, //endregion //region Poultry Farm Inspection diff --git a/packages/chicken/lib/presentation/routes/routes.dart b/packages/chicken/lib/presentation/routes/routes.dart index 2bb29aa..e3f9e34 100644 --- a/packages/chicken/lib/presentation/routes/routes.dart +++ b/packages/chicken/lib/presentation/routes/routes.dart @@ -1,39 +1,14 @@ +import 'package:rasadyar_chicken/features/common/presentation/routes/routes.dart'; + sealed class ChickenRoutes { ChickenRoutes._(); - static const auth = '/AuthChicken'; static const _base = '/chicken'; - static const role = '$_base/role'; - static const String profile = '$_base/profile'; + static const auth = CommonRoutes.auth; - //region Steward Routes - static const _steward = '$_base/steward'; - static const initSteward = '$_steward/'; - static const homeSteward = '$_steward/home'; - static const buySteward = '$_steward/buy'; - static const saleSteward = '$_steward/sale'; - static const segmentationSteward = '$_steward/segmentation'; - //buys - static const buysOutOfProvinceSteward = '$buySteward/buyOutOfProvince'; - static const buysInProvinceSteward = '$buySteward/buyInProvince'; - //sales - static const salesInProvinceSteward = '$saleSteward/SalesInProvince'; - static const salesOutOfProvinceSteward = '$saleSteward/saleOutOfProvince'; - static const salesOutOfProvinceBuyerSteward = '$saleSteward/saleOutOfProvinceBuyer '; - //endregion - - //region Poultry Science Routes - static const _poultryScience = '$_base/poultryScience'; - static const initPoultryScience = '$_poultryScience/'; - static const actionPoultryScience = '$_poultryScience/action'; - static const inspectionPoultryScience = '$_poultryScience/inspection'; - static const farmPoultryScience = '$_poultryScience/farm'; - static const activeHatchingPoultryScience = '$_poultryScience/activeHatching'; - static const genocidePoultryScience = '$_poultryScience/genocidePoultryScience'; - static const killingRegistrationPoultryScience = '$genocidePoultryScience/KillingRegistration'; //endregion diff --git a/packages/chicken/lib/presentation/utils/nested_keys_utils.dart b/packages/chicken/lib/presentation/utils/nested_keys_utils.dart index 39b48f6..745df67 100644 --- a/packages/chicken/lib/presentation/utils/nested_keys_utils.dart +++ b/packages/chicken/lib/presentation/utils/nested_keys_utils.dart @@ -19,4 +19,44 @@ const int killHouseWarehouseAndDistributionSaleKey = 110; +//endregion + +//region poultry science Keys +const int poultryScienceActionKey = 109; + +//endregion + +//region province operator Keys +const int provinceOperatorActionKey = 110; + +//endregion + +//region province inspector Keys +const int provinceInspectorActionKey = 111; + +//endregion + +//region city jahad Keys +const int cityJahadActionKey = 112; + +//endregion + +//region vet farm Keys +const int vetFarmActionKey = 113; + +//endregion + +//region super admin Keys +const int superAdminActionKey = 114; + +//endregion + +//region province supervisor Keys +const int provinceSupervisorActionKey = 115; + +//endregion + +//region jahad Keys +const int jahadActionKey = 116; + //endregion diff --git a/packages/chicken/lib/presentation/utils/utils.dart b/packages/chicken/lib/presentation/utils/utils.dart index f6f89f3..f5d0771 100644 --- a/packages/chicken/lib/presentation/utils/utils.dart +++ b/packages/chicken/lib/presentation/utils/utils.dart @@ -1,19 +1,28 @@ import 'package:flutter/material.dart'; +import 'package:rasadyar_chicken/features/common/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; import 'package:rasadyar_core/core.dart'; const int timeDebounce = 1200; void handleGeneric(DioException error, [void Function()? onError]) { - Get.showSnackbar(_errorSnackBar('اعتبار توکن شما منقضی شده است لطفا دوباره وارد شوید')); + Get.showSnackbar( + _errorSnackBar('اعتبار توکن شما منقضی شده است لطفا دوباره وارد شوید'), + ); - Get.offAllNamed(ChickenRoutes.auth, arguments: Module.chicken); + Get.offAllNamed(CommonRoutes.auth, arguments: Module.chicken); } GetSnackBar _errorSnackBar(String message) { return GetSnackBar( - titleText: Text('خطا', style: AppFonts.yekan14.copyWith(color: Colors.white)), - messageText: Text(message, style: AppFonts.yekan12.copyWith(color: Colors.white)), + titleText: Text( + 'خطا', + style: AppFonts.yekan14.copyWith(color: Colors.white), + ), + messageText: Text( + message, + style: AppFonts.yekan12.copyWith(color: Colors.white), + ), backgroundColor: AppColor.error, margin: EdgeInsets.symmetric(horizontal: 12, vertical: 8), borderRadius: 12, diff --git a/packages/chicken/lib/presentation/widget/base_page/logic.dart b/packages/chicken/lib/presentation/widget/base_page/logic.dart index 1c63f60..4c5c387 100644 --- a/packages/chicken/lib/presentation/widget/base_page/logic.dart +++ b/packages/chicken/lib/presentation/widget/base_page/logic.dart @@ -1,14 +1,16 @@ import 'package:rasadyar_chicken/data/di/chicken_di.dart'; -import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/common/common_repository.dart'; import 'package:rasadyar_core/core.dart'; -import '../../../data/models/response/user_profile/user_profile.dart'; +import '../../../features/common/data/model/response/user_profile/user_profile.dart'; class ChickenBaseLogic extends BasePageLogic { var tokenService = Get.find(); - ChickenRepository chickenRepository = diChicken.get(); + CommonRepository commonRepository = diChicken.get(); - Rx> userProfile = Rx>(Resource.loading()); + Rx> userProfile = Rx>( + Resource.loading(), + ); @override void onInit() { @@ -19,8 +21,9 @@ class ChickenBaseLogic extends BasePageLogic { Future getUserProfile() async { userProfile.value = Resource.loading(); await safeCall( - call: () async => - await chickenRepository.getUserProfile(token: tokenService.accessToken.value!), + call: () async => await commonRepository.getUserProfile( + token: tokenService.accessToken.value!, + ), onSuccess: (result) { if (result != null) { userProfile.value = Resource.success(result); diff --git a/packages/chicken/lib/presentation/widget/captcha/view.dart b/packages/chicken/lib/presentation/widget/captcha/view.dart index 940adc7..10003cf 100644 --- a/packages/chicken/lib/presentation/widget/captcha/view.dart +++ b/packages/chicken/lib/presentation/widget/captcha/view.dart @@ -1,8 +1,6 @@ -import 'dart:math'; - import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/features/common/auth/logic.dart'; +import 'package:rasadyar_chicken/features/common/presentation/page/auth/logic.dart'; import 'package:rasadyar_core/core.dart'; import 'logic.dart'; @@ -12,98 +10,90 @@ class CaptchaWidget extends GetView { @override Widget build(BuildContext context) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureDetector( - onTap: controller.getCaptcha, - child: Container( - width: 135, - height: 50, - alignment: Alignment.center, - clipBehavior: Clip.antiAliasWithSaveLayer, - decoration: BoxDecoration( - color: AppColor.whiteNormalHover, - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(8), - ), - child: controller.obx( - (state) => Text( - state ?? '', - style: AppFonts.yekan20Bold.copyWith(color: Colors.black, letterSpacing: 2.5), - textAlign: TextAlign.center, - ), - onLoading: const Center( - child: CupertinoActivityIndicator(color: AppColor.blueNormal), - ), - onError: (error) { - return Center( - child: Text('خطا ', style: AppFonts.yekan13.copyWith(color: Colors.red)), - ); - }, - ), - ), - ), - - const SizedBox(width: 8), - Expanded( - child: Form( - key: controller.formKey, - autovalidateMode: AutovalidateMode.disabled, - child: RTextField( - label: 'کد امنیتی', - controller: controller.textController, - focusedBorder: OutlineInputBorder( + return SizedBox( + height: 50.h, + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + GestureDetector( + onTap: controller.getCaptcha, + child: Container( + width: 135.w, + height: 50.h, + alignment: Alignment.center, + decoration: BoxDecoration( + color: AppColor.whiteNormalHover, + border: Border.all(color: Colors.grey.shade300), borderRadius: BorderRadius.circular(8), - borderSide: BorderSide(color: AppColor.textColor, width: 1), ), - keyboardType: TextInputType.numberWithOptions(decimal: false, signed: false), - maxLines: 1, - maxLength: 6, - suffixIcon: (controller.textController.text.trim().isNotEmpty ?? false) - ? clearButton(() => controller.textController.clear()) - : null, - - validator: (value) { - if (value == null || value.isEmpty) { - return 'کد امنیتی را وارد کنید'; - } - return null; - }, - onChanged: (pass) { - if (pass.length == 6) { - if (controller.formKey.currentState?.validate() ?? false) { - Get.find().isDisabled.value = false; - } - } - }, - style: AppFonts.yekan13, + child: controller.obx( + (state) => Text( + state ?? '', + style: AppFonts.yekan20Bold.copyWith( + color: Colors.black, + letterSpacing: 2.5, + ), + textAlign: TextAlign.center, + ), + onLoading: const Center( + child: CupertinoActivityIndicator(color: AppColor.blueNormal), + ), + onError: (error) { + return Center( + child: Text( + 'خطا ', + style: AppFonts.yekan13.copyWith(color: Colors.red), + ), + ); + }, + ), ), ), - ), - ], + + const SizedBox(width: 8), + Expanded( + child: Form( + key: controller.formKey, + autovalidateMode: AutovalidateMode.disabled, + child: RTextField( + height: 50.h, + isFullHeight: true, + label: 'کد امنیتی', + controller: controller.textController, + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(8), + borderSide: BorderSide(color: AppColor.textColor, width: 1), + ), + keyboardType: TextInputType.numberWithOptions( + decimal: false, + signed: false, + ), + filled: false, + borderColor: Colors.grey.shade300, + maxLines: 1, + maxLength: 6, + suffixIcon: (controller.textController.text.trim().isNotEmpty) + ? clearButton(() => controller.textController.clear()) + : null, + validator: (value) { + if (value == null || value.isEmpty) { + return 'کد امنیتی را وارد کنید'; + } + return null; + }, + onChanged: (pass) { + if (pass.length == 6) { + if (controller.formKey.currentState?.validate() ?? false) { + Get.find().isDisabled.value = false; + } + } + }, + style: AppFonts.yekan13, + ), + ), + ), + ], + ), ); } } - -class _CaptchaLinePainter extends CustomPainter { - @override - void paint(Canvas canvas, Size size) { - final random = Random(); - final paint1 = Paint() - ..color = Colors.deepOrange - ..strokeWidth = 2; - final paint2 = Paint() - ..color = Colors.blue - ..strokeWidth = 2; - - // First line: top-left to bottom-right - canvas.drawLine(Offset(0, 0), Offset(size.width, size.height), paint1); - - // Second line: bottom-left to top-right - canvas.drawLine(Offset(0, size.height), Offset(size.width, 0), paint2); - } - - @override - bool shouldRepaint(covariant CustomPainter oldDelegate) => false; -} diff --git a/packages/chicken/lib/presentation/widget/steward/widely_used/logic.dart b/packages/chicken/lib/presentation/widget/steward/widely_used/logic.dart index dcaeb11..56a4a19 100644 --- a/packages/chicken/lib/presentation/widget/steward/widely_used/logic.dart +++ b/packages/chicken/lib/presentation/widget/steward/widely_used/logic.dart @@ -1,5 +1,4 @@ - -import 'package:rasadyar_chicken/features/steward/root/logic.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/pages/root/logic.dart'; import 'package:rasadyar_core/core.dart'; enum WidelyUsedType { edit, normal } @@ -8,8 +7,6 @@ class WidelyUsedLogic extends GetxController { Rx type = WidelyUsedType.normal.obs; StewardRootLogic rootLogic = Get.find(); - - @override void onClose() { // TODO: implement onClose diff --git a/packages/chicken/lib/presentation/widget/steward/widely_used/view.dart b/packages/chicken/lib/presentation/widget/steward/widely_used/view.dart index 6f623cb..ace6375 100644 --- a/packages/chicken/lib/presentation/widget/steward/widely_used/view.dart +++ b/packages/chicken/lib/presentation/widget/steward/widely_used/view.dart @@ -1,6 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:rasadyar_chicken/presentation/routes/routes.dart'; +import 'package:rasadyar_chicken/features/steward/presentation/routes/routes.dart'; import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.dart'; import 'package:rasadyar_core/core.dart'; @@ -39,7 +39,10 @@ class WidelyUsedWidget extends StatelessWidget { controller.rootLogic.currentPage.value = 0; controller.rootLogic.currentPage.refresh(); await Future.delayed(Duration(milliseconds: 100)); - Get.toNamed(ChickenRoutes.buysOutOfProvinceSteward, id: stewardFirstKey); + Get.toNamed( + StewardRoutes.buysOutOfProvinceSteward, + id: stewardFirstKey, + ); }, ), @@ -52,7 +55,10 @@ class WidelyUsedWidget extends StatelessWidget { controller.rootLogic.currentPage.value = 0; controller.rootLogic.currentPage.refresh(); await Future.delayed(Duration(milliseconds: 100)); - Get.toNamed(ChickenRoutes.buysInProvinceSteward, id: stewardFirstKey); + Get.toNamed( + StewardRoutes.buysInProvinceSteward, + id: stewardFirstKey, + ); }, isOnEdit: false, ), @@ -65,7 +71,10 @@ class WidelyUsedWidget extends StatelessWidget { controller.rootLogic.currentPage.value = 1; controller.rootLogic.currentPage.refresh(); await Future.delayed(Duration(milliseconds: 100)); - Get.toNamed(ChickenRoutes.salesOutOfProvinceSteward, id: stewardSecondKey); + Get.toNamed( + StewardRoutes.salesOutOfProvinceSteward, + id: stewardSecondKey, + ); }, ), @@ -77,7 +86,10 @@ class WidelyUsedWidget extends StatelessWidget { controller.rootLogic.currentPage.value = 1; controller.rootLogic.currentPage.refresh(); await Future.delayed(Duration(milliseconds: 100)); - Get.toNamed(ChickenRoutes.salesInProvinceSteward, id: stewardSecondKey); + Get.toNamed( + StewardRoutes.salesInProvinceSteward, + id: stewardSecondKey, + ); }, ), ], @@ -93,7 +105,11 @@ class WidelyUsedWidget extends StatelessWidget { borderRadius: BorderRadius.circular(8), border: Border.all(width: 0.50, color: const Color(0xFFA9A9A9)), ), - child: Text('پر کاربردها', textAlign: TextAlign.right, style: AppFonts.yekan16), + child: Text( + 'پر کاربردها', + textAlign: TextAlign.right, + style: AppFonts.yekan16, + ), ), ), ], @@ -126,20 +142,27 @@ class WidelyUsedWidget extends StatelessWidget { padding: EdgeInsets.all(4), decoration: ShapeDecoration( color: cardColor ?? Color(0xFFBECDFF), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), ), child: Container( width: 40.w, height: 40.h, decoration: ShapeDecoration( color: labelColor ?? AppColor.blueNormal, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), ), padding: EdgeInsets.all(4), child: SvgGenImage.vec(iconPath).svg( width: 24.w, height: 24.h, - colorFilter: ColorFilter.mode(Colors.white, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + Colors.white, + BlendMode.srcIn, + ), fit: BoxFit.cover, ), ), @@ -152,7 +175,9 @@ class WidelyUsedWidget extends StatelessWidget { padding: EdgeInsets.all(4), decoration: ShapeDecoration( color: Colors.white60, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), ), ), ), @@ -172,9 +197,16 @@ class WidelyUsedWidget extends StatelessWidget { child: Container( width: 16, height: 16, - decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.white), + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, + ), alignment: Alignment.center, - child: Icon(CupertinoIcons.minus, color: AppColor.error, size: 15), + child: Icon( + CupertinoIcons.minus, + color: AppColor.error, + size: 15, + ), ), ), ), @@ -183,7 +215,12 @@ class WidelyUsedWidget extends StatelessWidget { ), ], ), - Text(title, style: AppFonts.yekan10.copyWith(color: textColor ?? AppColor.textColor)), + Text( + title, + style: AppFonts.yekan10.copyWith( + color: textColor ?? AppColor.textColor, + ), + ), ], ), ); @@ -201,16 +238,24 @@ class WidelyUsedWidget extends StatelessWidget { padding: EdgeInsets.all(4), decoration: ShapeDecoration( color: const Color(0xFFD9F7F0), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), ), child: Assets.vec.messageAddSvg.svg( width: 40, height: 40, - colorFilter: ColorFilter.mode(AppColor.greenNormal, BlendMode.srcIn), + colorFilter: ColorFilter.mode( + AppColor.greenNormal, + BlendMode.srcIn, + ), fit: BoxFit.cover, ), ), - Text('افزودن', style: AppFonts.yekan10.copyWith(color: AppColor.greenDarkHover)), + Text( + 'افزودن', + style: AppFonts.yekan10.copyWith(color: AppColor.greenDarkHover), + ), ], ); } diff --git a/packages/chicken/pubspec.lock b/packages/chicken/pubspec.lock new file mode 100644 index 0000000..4744afb --- /dev/null +++ b/packages/chicken/pubspec.lock @@ -0,0 +1,1846 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d + url: "https://pub.dev" + source: hosted + version: "91.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: f51c8499b35f9b26820cfe914828a6a98a94efd5cc78b37bb7d03debae3a1d08 + url: "https://pub.dev" + source: hosted + version: "8.4.1" + android_intent_plus: + dependency: transitive + description: + name: android_intent_plus + sha256: "14a9f94c5825a528e8c38ee89a33dbeba947efbbf76f066c174f4f3ae4f48feb" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + animated_stack_widget: + dependency: transitive + description: + name: animated_stack_widget + sha256: ce4788dd158768c9d4388354b6fb72600b78e041a37afc4c279c63ecafcb9408 + url: "https://pub.dev" + source: hosted + version: "0.0.4" + archive: + dependency: transitive + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.dev" + source: hosted + version: "4.0.7" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + asn1lib: + dependency: transitive + description: + name: asn1lib + sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" + url: "https://pub.dev" + source: hosted + version: "1.6.5" + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: c1668065e9ba04752570ad7e038288559d1e2ca5c6d0131c0f5f55e39e777413 + url: "https://pub.dev" + source: hosted + version: "4.0.3" + build_config: + dependency: transitive + description: + name: build_config + sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: bf05f6e12cfea92d3c09308d7bcdab1906cd8a179b023269eed00c071004b957 + url: "https://pub.dev" + source: hosted + version: "4.1.1" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "110c56ef29b5eb367b4d17fc79375fa8c18a6cd7acd92c05bb3986c17a079057" + url: "https://pub.dev" + source: hosted + version: "2.10.4" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "426cf75afdb23aa74bd4e471704de3f9393f3c7b04c1e2d9c6f1073ae0b8b139" + url: "https://pub.dev" + source: hosted + version: "8.12.1" + cached_network_image: + dependency: transitive + description: + name: cached_network_image + sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + camera: + dependency: transitive + description: + name: camera + sha256: eefad89f262a873f38d21e5eec853461737ea074d7c9ede39f3ceb135d201cab + url: "https://pub.dev" + source: hosted + version: "0.11.3" + camera_android_camerax: + dependency: transitive + description: + name: camera_android_camerax + sha256: "474d8355961658d43f1c976e2fa1ca715505bea1adbd56df34c581aaa70ec41f" + url: "https://pub.dev" + source: hosted + version: "0.6.26+2" + camera_avfoundation: + dependency: transitive + description: + name: camera_avfoundation + sha256: "035b90c1e33c2efad7548f402572078f6e514d4f82be0a315cd6c6af7e855aa8" + url: "https://pub.dev" + source: hosted + version: "0.9.22+6" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" + url: "https://pub.dev" + source: hosted + version: "2.12.0" + camera_web: + dependency: transitive + description: + name: camera_web + sha256: "3bc7bb1657a0f29c34116453c5d5e528c23efcf5e75aac0a3387cf108040bf65" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "11654819532ba94c34de52ff5feb52bd81cba1de00ef2ed622fd50295f9d4243" + url: "https://pub.dev" + source: hosted + version: "4.11.0" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" + connectivity_plus: + dependency: transitive + description: + name: connectivity_plus + sha256: "33bae12a398f841c6cda09d1064212957265869104c478e5ad51e2fb26c3973c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" + url: "https://pub.dev" + source: hosted + version: "1.15.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608" + url: "https://pub.dev" + source: hosted + version: "0.3.5+1" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + cupertino_icons: + dependency: transitive + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + dart_earcut: + dependency: transitive + description: + name: dart_earcut + sha256: e485001bfc05dcbc437d7bfb666316182e3522d4c3f9668048e004d0eb2ce43b + url: "https://pub.dev" + source: hosted + version: "1.2.0" + dart_polylabel2: + dependency: transitive + description: + name: dart_polylabel2 + sha256: "7eeab15ce72894e4bdba6a8765712231fc81be0bd95247de4ad9966abc57adc6" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b + url: "https://pub.dev" + source: hosted + version: "3.1.3" + dartx: + dependency: transitive + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" + device_frame_plus: + dependency: transitive + description: + name: device_frame_plus + sha256: ccc94abccd4d9f0a9f19ef239001b3a59896e678ad42601371d7065889f2bf78 + url: "https://pub.dev" + source: hosted + version: "1.5.0" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c" + url: "https://pub.dev" + source: hosted + version: "12.3.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + url: "https://pub.dev" + source: hosted + version: "7.0.3" + device_preview_plus: + dependency: transitive + description: + name: device_preview_plus + sha256: eb3e67929c9f04759e0d3708ad91d1018235549bcf8699f8a94909684c6555ae + url: "https://pub.dev" + source: hosted + version: "2.5.5" + dio: + dependency: transitive + description: + name: dio + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 + url: "https://pub.dev" + source: hosted + version: "5.9.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + encrypt: + dependency: transitive + description: + name: encrypt + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" + url: "https://pub.dev" + source: hosted + version: "5.0.3" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" + url: "https://pub.dev" + source: hosted + version: "0.9.4" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" + url: "https://pub.dev" + source: hosted + version: "0.9.5" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85" + url: "https://pub.dev" + source: hosted + version: "2.7.0" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd" + url: "https://pub.dev" + source: hosted + version: "0.9.3+5" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flat_buffers: + dependency: transitive + description: + name: flat_buffers + sha256: "380bdcba5664a718bfd4ea20a45d39e13684f5318fcd8883066a55e21f37f4c3" + url: "https://pub.dev" + source: hosted + version: "23.5.26" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + flutter_gen_core: + dependency: transitive + description: + name: flutter_gen_core + sha256: b6bafbbd981da2f964eb45bcb8b8a7676a281084f8922c0c75de4cfbaa849311 + url: "https://pub.dev" + source: hosted + version: "5.12.0" + flutter_gen_runner: + dependency: transitive + description: + name: flutter_gen_runner + sha256: c99b10af9d404e3f46fd1927e7d90099779e935e86022674c4c2a9e6c2a93b29 + url: "https://pub.dev" + source: hosted + version: "5.12.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_map: + dependency: transitive + description: + name: flutter_map + sha256: "391e7dc95cc3f5190748210a69d4cfeb5d8f84dcdfa9c3235d0a9d7742ccb3f8" + url: "https://pub.dev" + source: hosted + version: "8.2.2" + flutter_map_animations: + dependency: transitive + description: + name: flutter_map_animations + sha256: bf583863561861aaaf4854ae7ed8940d79bea7d32918bf7a85d309b25235a09e + url: "https://pub.dev" + source: hosted + version: "0.9.0" + flutter_map_marker_cluster: + dependency: transitive + description: + name: flutter_map_marker_cluster + sha256: "04a20d9b1c3a18b67cc97c1240f75361ab98449b735ab06f2534ece0d0794733" + url: "https://pub.dev" + source: hosted + version: "8.2.2" + flutter_map_marker_popup: + dependency: transitive + description: + name: flutter_map_marker_popup + sha256: "982b38455e739fe04abf05066340e0ce5883c40fb08b121cc8c60f5ee2c664a3" + url: "https://pub.dev" + source: hosted + version: "8.1.0" + flutter_map_tile_caching: + dependency: transitive + description: + name: flutter_map_tile_caching + sha256: "90e097223d8ab74425cf15b449a03adfa4d4c28406dc757e1c396aff0f9beba7" + url: "https://pub.dev" + source: hosted + version: "10.1.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1 + url: "https://pub.dev" + source: hosted + version: "2.0.33" + flutter_rating_bar: + dependency: transitive + description: + name: flutter_rating_bar + sha256: d2af03469eac832c591a1eba47c91ecc871fe5708e69967073c043b2d775ed93 + url: "https://pub.dev" + source: hosted + version: "4.0.1" + flutter_screenutil: + dependency: transitive + description: + name: flutter_screenutil + sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de" + url: "https://pub.dev" + source: hosted + version: "5.9.3" + flutter_secure_storage: + dependency: transitive + description: + name: flutter_secure_storage + sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea" + url: "https://pub.dev" + source: hosted + version: "9.2.4" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + flutter_secure_storage_macos: + dependency: transitive + description: + name: flutter_secure_storage_macos + sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247" + url: "https://pub.dev" + source: hosted + version: "3.1.3" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + flutter_slidable: + dependency: transitive + description: + name: flutter_slidable + sha256: ea369262929d3cc6ebf9d8a00c196127966f117fe433a5e5cb47fb08008ca203 + url: "https://pub.dev" + source: hosted + version: "4.0.3" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95" + url: "https://pub.dev" + source: hosted + version: "2.2.3" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + freezed: + dependency: "direct dev" + description: + name: freezed + sha256: "13065f10e135263a4f5a4391b79a8efc5fb8106f8dd555a9e49b750b45393d77" + url: "https://pub.dev" + source: hosted + version: "3.2.3" + freezed_annotation: + dependency: "direct main" + description: + name: freezed_annotation + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + geolocator: + dependency: transitive + description: + name: geolocator + sha256: ee2212a3df8292ec4c90b91183b8001d3f5a800823c974b570c5f9344ca320dc + url: "https://pub.dev" + source: hosted + version: "14.0.1" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a" + url: "https://pub.dev" + source: hosted + version: "5.0.2" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 + url: "https://pub.dev" + source: hosted + version: "2.3.13" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" + url: "https://pub.dev" + source: hosted + version: "4.2.6" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 + url: "https://pub.dev" + source: hosted + version: "4.1.3" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" + url: "https://pub.dev" + source: hosted + version: "0.2.5" + get: + dependency: transitive + description: + name: get + sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" + url: "https://pub.dev" + source: hosted + version: "4.7.3" + get_it: + dependency: transitive + description: + name: get_it + sha256: ae78de7c3f2304b8d81f2bb6e320833e5e81de942188542328f074978cc0efa9 + url: "https://pub.dev" + source: hosted + version: "8.3.0" + get_test: + dependency: "direct dev" + description: + name: get_test + sha256: "558c39cb35fb37bd501f337dc143de60a4314d5ef3b75f4b0551d6741634995b" + url: "https://pub.dev" + source: hosted + version: "4.0.1" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + hashcodes: + dependency: transitive + description: + name: hashcodes + sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + hive_ce: + dependency: transitive + description: + name: hive_ce + sha256: "81d39a03c4c0ba5938260a8c3547d2e71af59defecea21793d57fc3551f0d230" + url: "https://pub.dev" + source: hosted + version: "2.15.1" + hive_ce_flutter: + dependency: transitive + description: + name: hive_ce_flutter + sha256: "26d656c9e8974f0732f1d09020e2d7b08ba841b8961a02dbfb6caf01474b0e9a" + url: "https://pub.dev" + source: hosted + version: "2.3.3" + hive_ce_generator: + dependency: "direct dev" + description: + name: hive_ce_generator + sha256: b19ac263cb37529513508ba47352c41e6de72ba879952898d9c18c9c8a955921 + url: "https://pub.dev" + source: hosted + version: "1.10.0" + http: + dependency: transitive + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "51555e36056541237b15b57afc31a0f53d4f9aefd9bd00873a6dc0090e54e332" + url: "https://pub.dev" + source: hosted + version: "4.6.0" + image_cropper: + dependency: transitive + description: + name: image_cropper + sha256: "46c8f9aae51c8350b2a2982462f85a129e77b04675d35b09db5499437d7a996b" + url: "https://pub.dev" + source: hosted + version: "11.0.0" + image_cropper_for_web: + dependency: transitive + description: + name: image_cropper_for_web + sha256: e09749714bc24c4e3b31fbafa2e5b7229b0ff23e8b14d4ba44bd723b77611a0f + url: "https://pub.dev" + source: hosted + version: "7.0.0" + image_cropper_platform_interface: + dependency: transitive + description: + name: image_cropper_platform_interface + sha256: "886a30ec199362cdcc2fbb053b8e53347fbfb9dbbdaa94f9ff85622609f5e7ff" + url: "https://pub.dev" + source: hosted + version: "8.0.0" + image_picker: + dependency: transitive + description: + name: image_picker + sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "5e9bf126c37c117cf8094215373c6d561117a3cfb50ebc5add1a61dc6e224677" + url: "https://pub.dev" + source: hosted + version: "0.8.13+10" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad" + url: "https://pub.dev" + source: hosted + version: "0.8.13+3" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91" + url: "https://pub.dev" + source: hosted + version: "0.2.2+1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c" + url: "https://pub.dev" + source: hosted + version: "2.11.1" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_size_getter: + dependency: transitive + description: + name: image_size_getter + sha256: "7c26937e0ae341ca558b7556591fd0cc456fcc454583b7cb665d2f03e93e590f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + intl: + dependency: transitive + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.dev" + source: hosted + version: "1.0.5" + isolate_channel: + dependency: transitive + description: + name: isolate_channel + sha256: f3d36f783b301e6b312c3450eeb2656b0e7d1db81331af2a151d9083a3f6b18d + url: "https://pub.dev" + source: hosted + version: "0.2.2+1" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3 + url: "https://pub.dev" + source: hosted + version: "6.11.2" + latlong2: + dependency: transitive + description: + name: latlong2 + sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe" + url: "https://pub.dev" + source: hosted + version: "0.9.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: "direct dev" + description: + name: lints + sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 + url: "https://pub.dev" + source: hosted + version: "6.0.0" + lists: + dependency: transitive + description: + name: lists + sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + logger: + dependency: transitive + description: + name: logger + sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3 + url: "https://pub.dev" + source: hosted + version: "2.6.2" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + lottie: + dependency: transitive + description: + name: lottie + sha256: "8ae0be46dbd9e19641791dc12ee480d34e1fd3f84c749adc05f3ad9342b71b95" + url: "https://pub.dev" + source: hosted + version: "3.3.2" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mgrs_dart: + dependency: transitive + description: + name: mgrs_dart + sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7 + url: "https://pub.dev" + source: hosted + version: "2.0.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + mockito: + dependency: transitive + description: + name: mockito + sha256: dac24d461418d363778d53198d9ac0510b9d073869f078450f195766ec48d05e + url: "https://pub.dev" + source: hosted + version: "5.6.1" + mocktail: + dependency: "direct dev" + description: + name: mocktail + sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + objectbox: + dependency: transitive + description: + name: objectbox + sha256: "3cc186749178a3556e1020c9082d0897d0f9ecbdefcc27320e65c5bc650f0e57" + url: "https://pub.dev" + source: hosted + version: "4.3.1" + objectbox_flutter_libs: + dependency: transitive + description: + name: objectbox_flutter_libs + sha256: cd754766e04229a4f51250f121813d9a3c1a74fc21cd68e48b3c6085cbcd6c85 + url: "https://pub.dev" + source: hosted + version: "4.3.1" + octo_image: + dependency: transitive + description: + name: octo_image + sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" + package_info_plus: + dependency: transitive + description: + name: package_info_plus + sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d + url: "https://pub.dev" + source: hosted + version: "9.0.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e + url: "https://pub.dev" + source: hosted + version: "2.2.22" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4" + url: "https://pub.dev" + source: hosted + version: "2.5.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + permission_handler: + dependency: transitive + description: + name: permission_handler + sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 + url: "https://pub.dev" + source: hosted + version: "12.0.1" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" + url: "https://pub.dev" + source: hosted + version: "13.0.1" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 + url: "https://pub.dev" + source: hosted + version: "9.4.7" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + url: "https://pub.dev" + source: hosted + version: "0.1.3+5" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 + url: "https://pub.dev" + source: hosted + version: "4.3.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + persian_datetime_picker: + dependency: transitive + description: + name: persian_datetime_picker + sha256: "6a5ae6b9f717a6619ae29e65e4c8074285865a88d339dd05c91b9a5b6f8f47d7" + url: "https://pub.dev" + source: hosted + version: "3.2.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1" + url: "https://pub.dev" + source: hosted + version: "7.0.1" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" + pool: + dependency: transitive + description: + name: pool + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + url: "https://pub.dev" + source: hosted + version: "1.5.2" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.dev" + source: hosted + version: "6.0.3" + pretty_dio_logger: + dependency: transitive + description: + name: pretty_dio_logger + sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407" + url: "https://pub.dev" + source: hosted + version: "1.4.0" + proj4dart: + dependency: transitive + description: + name: proj4dart + sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e + url: "https://pub.dev" + source: hosted + version: "2.1.0" + provider: + dependency: transitive + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + rasadyar_core: + dependency: "direct main" + description: + path: "../core" + relative: true + source: path + version: "1.3.0" + rive: + dependency: transitive + description: + name: rive + sha256: "2551a44fa766a7ed3f52aa2b94feda6d18d00edc25dee5f66e72e9b365bb6d6c" + url: "https://pub.dev" + source: hosted + version: "0.13.20" + rive_common: + dependency: transitive + description: + name: rive_common + sha256: "2ba42f80d37a4efd0696fb715787c4785f8a13361e8aea9227c50f1e78cf763a" + url: "https://pub.dev" + source: hosted + version: "0.4.15" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" + shamsi_date: + dependency: transitive + description: + name: shamsi_date + sha256: "0383fddc9bce91e9e08de0c909faf93c3ab3a0e532abd271fb0dcf5d0617487b" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" + url: "https://pub.dev" + source: hosted + version: "2.5.4" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "83af5c682796c0f7719c2bbf74792d113e40ae97981b8f266fa84574573556bc" + url: "https://pub.dev" + source: hosted + version: "2.4.18" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + shimmer: + dependency: transitive + description: + name: shimmer + sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + smooth_page_indicator: + dependency: transitive + description: + name: smooth_page_indicator + sha256: b21ebb8bc39cf72d11c7cfd809162a48c3800668ced1c9da3aade13a32cf6c1c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "07b277b67e0096c45196cbddddf2d8c6ffc49342e88bf31d460ce04605ddac75" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "6a3c6cc82073a8797f8c4dc4572146114a39652851c157db37e964d9c7038723" + url: "https://pub.dev" + source: hosted + version: "1.3.8" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.dev" + source: hosted + version: "0.10.13" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.dev" + source: hosted + version: "1.10.1" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_android: + dependency: transitive + description: + name: sqflite_android + sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88 + url: "https://pub.dev" + source: hosted + version: "2.4.2+2" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + sqflite_darwin: + dependency: transitive + description: + name: sqflite_darwin + sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_platform_interface: + dependency: transitive + description: + name: sqflite_platform_interface + sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + url: "https://pub.dev" + source: hosted + version: "3.4.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test: + dependency: "direct dev" + description: + name: test + sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" + url: "https://pub.dev" + source: hosted + version: "1.26.3" + test_api: + dependency: transitive + description: + name: test_api + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" + source: hosted + version: "0.7.7" + test_core: + dependency: transitive + description: + name: test_core + sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" + url: "https://pub.dev" + source: hosted + version: "0.6.12" + time: + dependency: transitive + description: + name: time + sha256: "46187cf30bffdab28c56be9a63861b36e4ab7347bf403297595d6a97e10c789f" + url: "https://pub.dev" + source: hosted + version: "2.1.6" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + unicode: + dependency: transitive + description: + name: unicode + sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + uuid: + dependency: transitive + description: + name: uuid + sha256: a11b666489b1954e01d992f3d601b1804a33937b5a8fe677bd26b8a9f96f96e8 + url: "https://pub.dev" + source: hosted + version: "4.5.2" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 + url: "https://pub.dev" + source: hosted + version: "1.1.19" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" + url: "https://pub.dev" + source: hosted + version: "1.1.13" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: d354a7ec6931e6047785f4db12a1f61ec3d43b207fc0790f863818543f8ff0dc + url: "https://pub.dev" + source: hosted + version: "1.1.19" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + url: "https://pub.dev" + source: hosted + version: "15.0.2" + watcher: + dependency: transitive + description: + name: watcher + sha256: f52385d4f73589977c80797e60fe51014f7f2b957b5e9a62c3f6ada439889249 + url: "https://pub.dev" + source: hosted + version: "1.2.0" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + win32: + dependency: transitive + description: + name: win32 + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e + url: "https://pub.dev" + source: hosted + version: "5.15.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + wkt_parser: + dependency: transitive + description: + name: wkt_parser + sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" + url: "https://pub.dev" + source: hosted + version: "6.6.1" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" + yaml_writer: + dependency: transitive + description: + name: yaml_writer + sha256: "69651cd7238411179ac32079937d4aa9a2970150d6b2ae2c6fe6de09402a5dc5" + url: "https://pub.dev" + source: hosted + version: "2.1.0" +sdks: + dart: ">=3.10.0 <4.0.0" + flutter: ">=3.35.7" diff --git a/packages/chicken/pubspec.yaml b/packages/chicken/pubspec.yaml index 4babdf4..ec0ab3d 100644 --- a/packages/chicken/pubspec.yaml +++ b/packages/chicken/pubspec.yaml @@ -1,6 +1,6 @@ name: rasadyar_chicken description: A starting point for Dart libraries or applications. -version: 1.3.20 +version: 1.8.0 environment: sdk: ^3.10.0 diff --git a/packages/chicken/test/data/common/fa_user_role_test.dart b/packages/chicken/test/data/common/fa_user_role_test.dart index e16bf4e..697e80b 100644 --- a/packages/chicken/test/data/common/fa_user_role_test.dart +++ b/packages/chicken/test/data/common/fa_user_role_test.dart @@ -1,4 +1,4 @@ -import 'package:flutter_test/flutter_test.dart'; +/* import 'package:flutter_test/flutter_test.dart'; import 'package:rasadyar_chicken/data/common/fa_user_role.dart'; import 'package:rasadyar_chicken/presentation/routes/routes.dart'; @@ -23,4 +23,4 @@ void main() { expect(getFaUserRoleWithOnTap(null), {'نامشخص': null}); }); }); -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/packages/chicken/test/data/data_source/local/chicken_local_imp_test.dart b/packages/chicken/test/data/data_source/local/chicken_local_imp_test.dart index 54fd1f2..dac5423 100644 --- a/packages/chicken/test/data/data_source/local/chicken_local_imp_test.dart +++ b/packages/chicken/test/data/data_source/local/chicken_local_imp_test.dart @@ -1,7 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:rasadyar_chicken/data/data_source/local/chicken_local_imp.dart'; -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/local/chicken_local_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/model/local/widely_used_local_model.dart'; import 'package:rasadyar_core/core.dart'; class MockHiveLocalStorage extends Mock implements HiveLocalStorage {} diff --git a/packages/chicken/test/data/data_source/remote/auth/auth_remote_imp_test.dart b/packages/chicken/test/data/data_source/remote/auth/auth_remote_imp_test.dart index 707a977..96271c8 100644 --- a/packages/chicken/test/data/data_source/remote/auth/auth_remote_imp_test.dart +++ b/packages/chicken/test/data/data_source/remote/auth/auth_remote_imp_test.dart @@ -1,8 +1,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote_imp.dart'; -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; import 'package:rasadyar_core/core.dart'; class MockDioRemote extends Mock implements DioRemote {} diff --git a/packages/chicken/test/data/models/response/user_profile_model/user_profile_model_test.dart b/packages/chicken/test/data/models/response/user_profile_model/user_profile_model_test.dart index c0334a0..91b9cef 100644 --- a/packages/chicken/test/data/models/response/user_profile_model/user_profile_model_test.dart +++ b/packages/chicken/test/data/models/response/user_profile_model/user_profile_model_test.dart @@ -1,5 +1,5 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; void main() { group('UserProfileModel', () { diff --git a/packages/chicken/test/data/repositories/auth/auth_repository_imp_test.dart b/packages/chicken/test/data/repositories/auth/auth_repository_imp_test.dart index 3dea869..dc2d6ae 100644 --- a/packages/chicken/test/data/repositories/auth/auth_repository_imp_test.dart +++ b/packages/chicken/test/data/repositories/auth/auth_repository_imp_test.dart @@ -1,9 +1,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart'; -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; -import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; +import 'package:rasadyar_chicken/features/common/data/repositories/auth/auth_repository_imp.dart'; class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {} diff --git a/packages/chicken/test/data/repositories/poultry_science/poultry_science_repository_test.dart b/packages/chicken/test/data/repositories/poultry_science/poultry_science_repository_test.dart deleted file mode 100644 index 02d66ae..0000000 --- a/packages/chicken/test/data/repositories/poultry_science/poultry_science_repository_test.dart +++ /dev/null @@ -1,145 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote.dart'; -import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; -import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository_imp.dart'; -import 'package:rasadyar_core/core.dart'; - -class _MockRemote extends Mock implements PoultryScienceRemoteDatasource {} - -void main() { - setUpAll(() { - registerFallbackValue(FormData()); - registerFallbackValue(const KillRegistrationRequest()); - registerFallbackValue({}); - }); - - group('PoultryScienceRepositoryImp', () { - late _MockRemote remote; - late PoultryScienceRepositoryImp repo; - - setUp(() { - remote = _MockRemote(); - repo = PoultryScienceRepositoryImp(remote); - }); - - test('getHomePoultry delegates', () async { - when(() => remote.getHomePoultryScience(token: any(named: 'token'), type: any(named: 'type'))) - .thenAnswer((_) async => null); - final res = await repo.getHomePoultry(token: 't', type: 'x'); - expect(res, null); - verify(() => remote.getHomePoultryScience(token: 't', type: 'x')).called(1); - }); - - test('getHatchingPoultry delegates', () async { - when(() => remote.getHatchingPoultry(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getHatchingPoultry(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getHatchingPoultry(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('submitPoultryScienceReport delegates', () async { - when(() => remote.submitPoultryScienceReport(token: any(named: 'token'), data: any(named: 'data'), onSendProgress: any(named: 'onSendProgress'))) - .thenAnswer((_) async {}); - await repo.submitPoultryScienceReport(token: 't', data: FormData()); - verify(() => remote.submitPoultryScienceReport(token: 't', data: any(named: 'data'), onSendProgress: any(named: 'onSendProgress'))).called(1); - }); - - test('getHatchingPoultryReport delegates', () async { - when(() => remote.getPoultryScienceReport(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getHatchingPoultryReport(token: 't', queryParameters: {'q': 1}); - expect(res, null); - verify(() => remote.getPoultryScienceReport(token: 't', queryParameters: {'q': 1})).called(1); - }); - - test('getPoultryScienceFarmList delegates', () async { - when(() => remote.getPoultryScienceFarmList(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getPoultryScienceFarmList(token: 't', queryParameters: {'p': 1}); - expect(res, null); - verify(() => remote.getPoultryScienceFarmList(token: 't', queryParameters: {'p': 1})).called(1); - }); - - test('getApprovedPrice delegates', () async { - when(() => remote.getApprovedPrice(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getApprovedPrice(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getApprovedPrice(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('getAllPoultry delegates', () async { - when(() => remote.getAllPoultry(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getAllPoultry(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getAllPoultry(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('getSellForFreezing delegates', () async { - when(() => remote.getSellForFreezing(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getSellForFreezing(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getSellForFreezing(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('getPoultryExport delegates', () async { - when(() => remote.getPoultryExport(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getPoultryExport(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getPoultryExport(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('getUserPoultry delegates', () async { - when(() => remote.getUserPoultry(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getUserPoultry(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getUserPoultry(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('getPoultryHatching delegates', () async { - when(() => remote.getPoultryHatching(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getPoultryHatching(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getPoultryHatching(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('getKillHouseList delegates', () async { - when(() => remote.getKillHouseList(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getKillHouseList(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getKillHouseList(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('submitKillRegistration delegates', () async { - when(() => remote.submitKillRegistration(token: any(named: 'token'), request: any(named: 'request'))) - .thenAnswer((_) async {}); - await repo.submitKillRegistration(token: 't', request: const KillRegistrationRequest()); - verify(() => remote.submitKillRegistration(token: 't', request: any(named: 'request'))).called(1); - }); - - test('getPoultryOderList delegates', () async { - when(() => remote.getPoultryOderList(token: any(named: 'token'), queryParameters: any(named: 'queryParameters'))) - .thenAnswer((_) async => null); - final res = await repo.getPoultryOderList(token: 't', queryParameters: {'a': 1}); - expect(res, null); - verify(() => remote.getPoultryOderList(token: 't', queryParameters: {'a': 1})).called(1); - }); - - test('deletePoultryOder delegates', () async { - when(() => remote.deletePoultryOder(token: any(named: 'token'), orderId: any(named: 'orderId'))) - .thenAnswer((_) async {}); - await repo.deletePoultryOder(token: 't', orderId: 'id'); - verify(() => remote.deletePoultryOder(token: 't', orderId: 'id')).called(1); - }); - }); -} - - diff --git a/packages/chicken/test/integration/auth_flow_integration_test.dart b/packages/chicken/test/integration/auth_flow_integration_test.dart index a693e9f..1b1bde0 100644 --- a/packages/chicken/test/integration/auth_flow_integration_test.dart +++ b/packages/chicken/test/integration/auth_flow_integration_test.dart @@ -1,9 +1,9 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/auth/auth_remote.dart'; -import 'package:rasadyar_chicken/data/models/response/user_info/user_info_model.dart'; -import 'package:rasadyar_chicken/data/models/response/user_profile_model/user_profile_model.dart'; -import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart'; +import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; +import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; + class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {} diff --git a/packages/chicken/test/integration/poultry_science_integration_test.dart b/packages/chicken/test/integration/poultry_science_integration_test.dart deleted file mode 100644 index 1a28677..0000000 --- a/packages/chicken/test/integration/poultry_science_integration_test.dart +++ /dev/null @@ -1,641 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/poultry_science/poultry_science_remote.dart'; -import 'package:rasadyar_chicken/data/models/poultry_export/poultry_export.dart'; -import 'package:rasadyar_chicken/data/models/request/kill_registration/kill_registration.dart'; -import 'package:rasadyar_chicken/data/models/response/all_poultry/all_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/approved_price/approved_price.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching/hatching_models.dart'; -import 'package:rasadyar_chicken/data/models/response/hatching_report/hatching_report.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_poultry/kill_house_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_request_poultry/kill_request_poultry.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_farm/poultry_farm.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_hatching/poultry_hatching.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_order/poultry_order.dart'; -import 'package:rasadyar_chicken/data/models/response/poultry_science/home_poultry_science/home_poultry_science_model.dart'; -import 'package:rasadyar_chicken/data/models/response/sell_for_freezing/sell_for_freezing.dart'; -import 'package:rasadyar_chicken/data/repositories/poultry_science/poultry_science_repository_imp.dart'; -import 'package:rasadyar_core/core.dart'; - -class MockPoultryScienceRemoteDataSource extends Mock - implements PoultryScienceRemoteDatasource {} - -void main() { - late PoultryScienceRepositoryImp poultryScienceRepository; - late MockPoultryScienceRemoteDataSource mockRemote; - - setUp(() { - mockRemote = MockPoultryScienceRemoteDataSource(); - poultryScienceRepository = PoultryScienceRepositoryImp(mockRemote); - }); - - group('Poultry Science Integration Tests', () { - const token = 'test-token'; - - group('Complete Poultry Science Home Flow', () { - test('should complete full poultry science home workflow', () async { - // Arrange - const type = 'hatching'; - - final expectedHomeModel = HomePoultryScienceModel( - farmCount: 5, - hatchingCount: 1000, - hatchingQuantity: 500, - hatchingLeftOver: 200, - hatchingLosses: 50, - hatchingKilledQuantity: 250, - hatchingMaxAge: 45, - hatchingMinAge: 30, - ); - - final expectedHatching = [ - HatchingModel( - id: 1, - key: 'hatching-1', - date: '2024-01-01', - quantity: 100, - state: 'active', - ), - ]; - final expectedHatchingPagination = PaginationModel( - results: expectedHatching, - count: 1, - next: null, - previous: null, - ); - - // Mock the flow - when( - () => mockRemote.getHomePoultryScience(token: token, type: type), - ).thenAnswer((_) async => expectedHomeModel); - - when( - () => mockRemote.getHatchingPoultry( - token: token, - queryParameters: any(named: 'queryParameters'), - ), - ).thenAnswer((_) async => expectedHatchingPagination); - - // Act - Step 1: Get home poultry science data - final homeModel = await poultryScienceRepository.getHomePoultry( - token: token, - type: type, - ); - - // Act - Step 2: Get hatching poultry data - final hatchingData = await poultryScienceRepository.getHatchingPoultry( - token: token, - queryParameters: {'page': '1', 'limit': '10'}, - ); - - // Assert - expect(homeModel, equals(expectedHomeModel)); - expect(hatchingData, equals(expectedHatchingPagination)); - - verify( - () => mockRemote.getHomePoultryScience(token: token, type: type), - ).called(1); - verify( - () => mockRemote.getHatchingPoultry( - token: token, - queryParameters: any(named: 'queryParameters'), - ), - ).called(1); - }); - }); - - group('Hatching Report Management Flow', () { - test('should complete hatching report management workflow', () async { - // Arrange - final queryParameters = {'page': '1', 'limit': '10'}; - - final expectedReports = [ - HatchingReport( - id: 1, - key: 'report-1', - date: DateTime.parse('2024-01-01'), - state: 'completed', - ), - ]; - final expectedPagination = PaginationModel( - results: expectedReports, - count: 1, - next: null, - previous: null, - ); - - final mockFormData = MockFormData(); - - // Mock the flow - when( - () => mockRemote.getPoultryScienceReport( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedPagination); - - when( - () => mockRemote.submitPoultryScienceReport( - token: token, - data: mockFormData, - onSendProgress: any(named: 'onSendProgress'), - ), - ).thenAnswer((_) async {}); - - // Act - Step 1: Get hatching reports - final reports = await poultryScienceRepository.getHatchingPoultryReport( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 2: Submit new report - await poultryScienceRepository.submitPoultryScienceReport( - token: token, - data: mockFormData, - ); - - // Assert - expect(reports, equals(expectedPagination)); - - verify( - () => mockRemote.getPoultryScienceReport( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.submitPoultryScienceReport( - token: token, - data: mockFormData, - onSendProgress: any(named: 'onSendProgress'), - ), - ).called(1); - }); - }); - - group('Poultry Farm Management Flow', () { - test('should complete poultry farm management workflow', () async { - // Arrange - final queryParameters = {'page': '1', 'limit': '10'}; - - final expectedFarms = [ - PoultryFarm( - id: 1, - key: 'farm-1', - unitName: 'Farm 1', - totalCapacity: 1000, - cityName: 'Tehran', - ), - ]; - final expectedPagination = PaginationModel( - results: expectedFarms, - count: 1, - next: null, - previous: null, - ); - - // Mock the flow - when( - () => mockRemote.getPoultryScienceFarmList( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedPagination); - - // Act - final farms = await poultryScienceRepository.getPoultryScienceFarmList( - token: token, - queryParameters: queryParameters, - ); - - // Assert - expect(farms, equals(expectedPagination)); - - verify( - () => mockRemote.getPoultryScienceFarmList( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - }); - }); - - group('Pricing and Market Data Flow', () { - test('should complete pricing and market data workflow', () async { - // Arrange - final queryParameters = {'date': '2024-01-01'}; - - final expectedApprovedPrice = ApprovedPrice( - approved: true, - lowestPrice: 45000.0, - highestPrice: 55000.0, - lowestWeight: 1.5, - highestWeight: 2.5, - ); - - final expectedSellForFreezing = SellForFreezing(permission: true); - - final expectedPoultryExport = PoultryExport( - key: 'export-key', - allow: true, - limitationStatus: false, - limitation: 100.0, - ); - - // Mock the flow - when( - () => mockRemote.getApprovedPrice( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedApprovedPrice); - - when( - () => mockRemote.getSellForFreezing( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedSellForFreezing); - - when( - () => mockRemote.getPoultryExport( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedPoultryExport); - - // Act - Step 1: Get approved price - final approvedPrice = await poultryScienceRepository.getApprovedPrice( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 2: Get sell for freezing data - final sellForFreezing = await poultryScienceRepository - .getSellForFreezing(token: token, queryParameters: queryParameters); - - // Act - Step 3: Get poultry export data - final poultryExport = await poultryScienceRepository.getPoultryExport( - token: token, - queryParameters: queryParameters, - ); - - // Assert - expect(approvedPrice, equals(expectedApprovedPrice)); - expect(sellForFreezing, equals(expectedSellForFreezing)); - expect(poultryExport, equals(expectedPoultryExport)); - - verify( - () => mockRemote.getApprovedPrice( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.getSellForFreezing( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.getPoultryExport( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - }); - }); - - group('Kill Registration Flow', () { - test('should complete kill registration workflow', () async { - // Arrange - final queryParameters = {'page': '1', 'limit': '10'}; - - final expectedKillRequests = [ - KillRequestPoultry( - key: 'kill-request-1', - unitName: 'Farm 1', - totalCapacity: 1000, - cityName: 'Tehran', - provinceName: 'Tehran', - ), - ]; - - final expectedKillHouses = [ - KillHousePoultry( - name: 'Kill House 1', - killer: true, - fullname: 'Kill House Manager', - quantitySum: 500, - firstQuantity: 100, - poultryQuantitySum: 400, - killReqKey: 'killhouse-1', - ), - ]; - - final expectedPoultryHatching = [ - PoultryHatching( - key: 'hatching-1', - quantity: 100, - losses: 5, - leftOver: 95, - killedQuantity: 50, - state: 'active', - date: '2024-01-01', - age: 30, - ), - ]; - - final killRegistrationRequest = KillRegistrationRequest( - killReqKey: 'registration-key', - operatorKey: 'operator-1', - poultryHatchingKey: 'hatching-1', - quantity: 100, - sendDate: '2024-01-01', - chickenBreed: 'Broiler', - indexWeight: 2.0, - losses: '5', - freezing: false, - export: false, - cash: true, - credit: false, - role: 'farmer', - poultryKey: 'poultry-1', - amount: 100000, - financialOperation: 'cash', - freeSaleInProvince: true, - confirmPoultryMobile: '09123456789', - ); - - // Mock the flow - when( - () => mockRemote.getUserPoultry( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer( - (_) async => expectedKillRequests.cast(), - ); - - when( - () => mockRemote.getKillHouseList( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedKillHouses.cast()); - - when( - () => mockRemote.getPoultryHatching( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer( - (_) async => expectedPoultryHatching.cast(), - ); - - when( - () => mockRemote.submitKillRegistration( - token: token, - request: killRegistrationRequest, - ), - ).thenAnswer((_) async {}); - - // Act - Step 1: Get user poultry - final killRequests = await poultryScienceRepository.getUserPoultry( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 2: Get kill house list - final killHouses = await poultryScienceRepository.getKillHouseList( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 3: Get poultry hatching - final poultryHatching = await poultryScienceRepository - .getPoultryHatching(token: token, queryParameters: queryParameters); - - // Act - Step 4: Submit kill registration - await poultryScienceRepository.submitKillRegistration( - token: token, - request: killRegistrationRequest, - ); - - // Assert - expect(killRequests, equals(expectedKillRequests)); - expect(killHouses, equals(expectedKillHouses)); - expect(poultryHatching, equals(expectedPoultryHatching)); - - verify( - () => mockRemote.getUserPoultry( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.getKillHouseList( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.getPoultryHatching( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.submitKillRegistration( - token: token, - request: killRegistrationRequest, - ), - ).called(1); - }); - }); - - group('Poultry Order Management Flow', () { - test('should complete poultry order management workflow', () async { - // Arrange - final queryParameters = {'page': '1', 'limit': '10'}; - const orderId = 'order-1'; - - final expectedOrders = [ - PoultryOrder( - key: 'order-1', - id: 1, - orderCode: 1001, - createDate: '2024-01-01', - sendDate: '2024-01-02', - quantity: 100, - firstQuantity: 100, - amount: 5000000.0, - finalState: 'pending', - provinceState: 'pending', - stateProcess: 'processing', - freeSaleInProvince: true, - freezing: false, - export: false, - market: true, - ), - ]; - final expectedPagination = PaginationModel( - count: 1, - next: null, - previous: null, - results: expectedOrders, - ); - - // Mock the flow - when( - () => mockRemote.getPoultryOderList( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedPagination); - - when( - () => mockRemote.deletePoultryOder(token: token, orderId: orderId), - ).thenAnswer((_) async {}); - - // Act - Step 1: Get poultry orders - final orders = await poultryScienceRepository.getPoultryOderList( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 2: Delete poultry order - await poultryScienceRepository.deletePoultryOder( - token: token, - orderId: orderId, - ); - - // Assert - expect(orders, equals(expectedPagination)); - - verify( - () => mockRemote.getPoultryOderList( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.deletePoultryOder(token: token, orderId: orderId), - ).called(1); - }); - }); - - group('All Poultry Data Flow', () { - test('should complete all poultry data retrieval workflow', () async { - // Arrange - final queryParameters = {'type': 'all'}; - - final expectedAllPoultry = [ - AllPoultry( - key: 'poultry-1', - unitName: 'Poultry Farm 1', - lastHatchingRemainQuantity: 100, - provinceAllowSellFree: true, - ), - ]; - - // Mock the flow - when( - () => mockRemote.getAllPoultry( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedAllPoultry.cast()); - - // Act - final allPoultry = await poultryScienceRepository.getAllPoultry( - token: token, - queryParameters: queryParameters, - ); - - // Assert - expect(allPoultry, equals(expectedAllPoultry)); - - verify( - () => mockRemote.getAllPoultry( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - }); - }); - - group('Error Handling in Poultry Science Workflow', () { - test('should handle home poultry data retrieval failure', () async { - // Arrange - const type = 'hatching'; - - when( - () => mockRemote.getHomePoultryScience(token: token, type: type), - ).thenAnswer((_) async => null); - - // Act - final homeModel = await poultryScienceRepository.getHomePoultry( - token: token, - type: type, - ); - - // Assert - expect(homeModel, isNull); - verify( - () => mockRemote.getHomePoultryScience(token: token, type: type), - ).called(1); - }); - - test('should handle kill registration submission failure', () async { - // Arrange - final killRegistrationRequest = KillRegistrationRequest( - killReqKey: 'registration-key', - operatorKey: 'operator-1', - poultryHatchingKey: 'hatching-1', - quantity: 100, - sendDate: '2024-01-01', - chickenBreed: 'Broiler', - indexWeight: 2.0, - losses: '5', - freezing: false, - export: false, - cash: true, - credit: false, - role: 'farmer', - poultryKey: 'poultry-1', - amount: 100000, - financialOperation: 'cash', - freeSaleInProvince: true, - confirmPoultryMobile: '09123456789', - ); - - when( - () => mockRemote.submitKillRegistration( - token: token, - request: killRegistrationRequest, - ), - ).thenThrow(Exception('Kill registration submission failed')); - - // Act & Assert - expect( - () => poultryScienceRepository.submitKillRegistration( - token: token, - request: killRegistrationRequest, - ), - throwsA(isA()), - ); - - verify( - () => mockRemote.submitKillRegistration( - token: token, - request: killRegistrationRequest, - ), - ).called(1); - }); - }); - }); -} - -// Mock FormData class -class MockFormData extends Mock implements FormData {} diff --git a/packages/chicken/test/integration/steward_workflow_integration_test.dart b/packages/chicken/test/integration/steward_workflow_integration_test.dart deleted file mode 100644 index ab200c1..0000000 --- a/packages/chicken/test/integration/steward_workflow_integration_test.dart +++ /dev/null @@ -1,466 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:mocktail/mocktail.dart'; -import 'package:rasadyar_chicken/data/data_source/local/chicken_local.dart'; -import 'package:rasadyar_chicken/data/data_source/remote/chicken/chicken_remote.dart'; -import 'package:rasadyar_chicken/data/models/local/widely_used_local_model.dart'; -import 'package:rasadyar_chicken/data/models/request/create_steward_free_bar/create_steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/allocated_made/allocated_made.dart'; -import 'package:rasadyar_chicken/data/models/response/broadcast_price/broadcast_price.dart'; -import 'package:rasadyar_chicken/data/models/response/guild_profile/guild_profile.dart'; -import 'package:rasadyar_chicken/data/models/response/roles_products/roles_products.dart'; -import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart'; -import 'package:rasadyar_chicken/data/models/response/segmentation_model/segmentation_model.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar/steward_free_bar.dart'; -import 'package:rasadyar_chicken/data/models/response/steward_free_bar_dashboard/steward_free_bar_dashboard.dart'; -import 'package:rasadyar_chicken/data/repositories/chicken/chicken_repository_imp.dart'; -import 'package:rasadyar_core/core.dart'; - -class MockChickenRemoteDatasource extends Mock - implements ChickenRemoteDatasource {} - -class MockChickenLocalDataSource extends Mock - implements ChickenLocalDataSource {} - -void main() { - late ChickenRepositoryImp chickenRepository; - late MockChickenRemoteDatasource mockRemote; - late MockChickenLocalDataSource mockLocal; - - setUp(() { - mockRemote = MockChickenRemoteDatasource(); - mockLocal = MockChickenLocalDataSource(); - chickenRepository = ChickenRepositoryImp( - remote: mockRemote, - local: mockLocal, - ); - }); - - group('Steward Workflow Integration Tests', () { - const token = 'test-token'; - - group('Complete Steward Dashboard Flow', () { - test('should complete full steward dashboard workflow', () async { - // Arrange - const startDate = '2024-01-01'; - const endDate = '2024-01-31'; - - final expectedDashboard = StewardFreeBarDashboard( - totalBars: 1000, - totalQuantity: 800, - totalWeight: 200, - ); - - final expectedBroadcastPrice = BroadcastPrice( - active: true, - killHousePrice: 45000, - stewardPrice: 50000, - guildPrice: 55000, - ); - - final expectedProfile = GuildProfile( - key: 'profile-key', - guilds_name: 'Test Guild', - type_activity: 'Test Guild Type', - area_activity: 'Test Guild Type Description', - ); - - // Mock the flow - when( - () => mockRemote.getStewardDashboard( - token: token, - stratDate: startDate, - endDate: endDate, - ), - ).thenAnswer((_) async => expectedDashboard); - - when( - () => mockRemote.getBroadcastPrice(token: token), - ).thenAnswer((_) async => expectedBroadcastPrice); - - when( - () => mockRemote.getProfile(token: token), - ).thenAnswer((_) async => expectedProfile); - - // Act - Step 1: Get steward dashboard - final dashboard = await chickenRepository.getStewardDashboard( - token: token, - stratDate: startDate, - endDate: endDate, - ); - - // Act - Step 2: Get broadcast price - final broadcastPrice = await chickenRepository.getBroadcastPrice( - token: token, - ); - - // Act - Step 3: Get profile - final profile = await chickenRepository.getProfile(token: token); - - // Assert - expect(dashboard, equals(expectedDashboard)); - expect(broadcastPrice, equals(expectedBroadcastPrice)); - expect(profile, equals(expectedProfile)); - - verify( - () => mockRemote.getStewardDashboard( - token: token, - stratDate: startDate, - endDate: endDate, - ), - ).called(1); - verify(() => mockRemote.getBroadcastPrice(token: token)).called(1); - verify(() => mockRemote.getProfile(token: token)).called(1); - }); - }); - - group('Inventory Management Flow', () { - test('should complete inventory management workflow', () async { - // Arrange - final expectedInventory = [ - ProductModel( - key: 'inventory-1', - name: 'Product 1', - totalCarcassesQuantity: 100, - ), - ProductModel( - key: 'inventory-2', - name: 'Product 2', - totalCarcassesQuantity: 200, - ), - ]; - - final expectedKillHouseInfo = KillHouseDistributionInfo( - stewardAllocationsWeight: 1000.0, - freeSalesWeight: 500.0, - ); - - // Mock the flow - when( - () => mockRemote.getRolesProduct( - token: token, - role: 'steward', - cancelToken: any(named: 'cancelToken'), - ), - ).thenAnswer((_) async => expectedInventory); - - when( - () => mockRemote.getKillHouseDistributionInfo(token: token), - ).thenAnswer((_) async => expectedKillHouseInfo); - - // Act - Step 1: Get inventory - final inventory = await chickenRepository.getRolesProduct( - token: token, - role: 'steward', - ); - - // Act - Step 2: Get kill house distribution info - final killHouseInfo = await chickenRepository - .getKillHouseDistributionInfo(token: token); - - // Assert - expect(inventory, equals(expectedInventory)); - expect(killHouseInfo, equals(expectedKillHouseInfo)); - - verify( - () => mockRemote.getRolesProduct( - token: token, - role: 'steward', - cancelToken: any(named: 'cancelToken'), - ), - ).called(1); - verify( - () => mockRemote.getKillHouseDistributionInfo(token: token), - ).called(1); - }); - }); - - group('Allocation Management Flow', () { - test('should complete allocation management workflow', () async { - // Arrange - final queryParameters = {'page': '1', 'limit': '10'}; - - final expectedAllocations = [ - AllocatedMadeModel( - key: 'allocation-1', - productName: 'Product 1', - numberOfCarcasses: 100, - ), - ]; - final expectedPagination = PaginationModel( - results: expectedAllocations, - count: 1, - ); - - final allocationRequest = { - 'allocationId': 'allocation-1', - 'confirmed': true, - }; - - // Mock the flow - when( - () => mockRemote.getAllocatedMade( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedPagination); - - when( - () => mockRemote.confirmAllocation( - token: token, - allocation: allocationRequest, - ), - ).thenAnswer((_) async {}); - - // Act - Step 1: Get allocated made - final allocations = await chickenRepository.getAllocatedMade( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 2: Confirm allocation - await chickenRepository.confirmAllocation( - token: token, - allocation: allocationRequest, - ); - - // Assert - expect(allocations, equals(expectedPagination)); - - verify( - () => mockRemote.getAllocatedMade( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.confirmAllocation( - token: token, - allocation: allocationRequest, - ), - ).called(1); - }); - }); - - group('Steward Free Bar Management Flow', () { - test('should complete steward free bar management workflow', () async { - // Arrange - final queryParameters = {'page': '1', 'limit': '10'}; - - final expectedFreeBars = [ - StewardFreeBar( - key: 'freebar-1', - killHouseName: 'Bar 1', - weightOfCarcasses: 500.0, - ), - ]; - final expectedPagination = PaginationModel( - results: expectedFreeBars, - count: 1, - ); - - final createRequest = CreateStewardFreeBar( - key: 'new-freebar', - killHouseName: 'New Bar', - weightOfCarcasses: 300, - ); - - // Mock the flow - when( - () => mockRemote.getStewardPurchasesOutSideOfTheProvince( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedPagination); - - when( - () => mockRemote.createStewardPurchasesOutSideOfTheProvince( - token: token, - body: createRequest, - ), - ).thenAnswer((_) async {}); - - // Act - Step 1: Get steward purchases outside province - final freeBars = await chickenRepository - .getStewardPurchasesOutSideOfTheProvince( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 2: Create new steward purchase - await chickenRepository.createStewardPurchasesOutSideOfTheProvince( - token: token, - body: createRequest, - ); - - // Assert - expect(freeBars, equals(expectedPagination)); - - verify( - () => mockRemote.getStewardPurchasesOutSideOfTheProvince( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.createStewardPurchasesOutSideOfTheProvince( - token: token, - body: createRequest, - ), - ).called(1); - }); - }); - - group('Segmentation Management Flow', () { - test('should complete segmentation management workflow', () async { - // Arrange - final queryParameters = {'page': '1', 'limit': '10'}; - - final expectedSegments = [ - SegmentationModel( - key: 'segment-1', - result: 'Segment 1', - quota: 'Description 1', - ), - ]; - final expectedPagination = PaginationModel( - results: expectedSegments, - count: 1, - ); - - final newSegment = SegmentationModel( - key: 'new-segment', - result: 'New Segment', - quota: 'New Description', - ); - - // Mock the flow - when( - () => mockRemote.getSegmentation( - token: token, - queryParameters: queryParameters, - ), - ).thenAnswer((_) async => expectedPagination); - - when( - () => mockRemote.createSegmentation(token: token, model: newSegment), - ).thenAnswer((_) async {}); - - // Act - Step 1: Get segmentation - final segments = await chickenRepository.getSegmentation( - token: token, - queryParameters: queryParameters, - ); - - // Act - Step 2: Create new segmentation - await chickenRepository.createSegmentation( - token: token, - model: newSegment, - ); - - // Assert - expect(segments, equals(expectedPagination)); - - verify( - () => mockRemote.getSegmentation( - token: token, - queryParameters: queryParameters, - ), - ).called(1); - verify( - () => mockRemote.createSegmentation(token: token, model: newSegment), - ).called(1); - }); - }); - - group('Local Data Integration', () { - test('should integrate local data with remote operations', () async { - // Arrange - final expectedWidelyUsed = WidelyUsedLocalModel( - hasInit: true, - items: [], - ); - - // Mock local data - when(() => mockLocal.getAllWidely()).thenReturn(expectedWidelyUsed); - - // Act - final widelyUsed = chickenRepository.getAllWidely(); - - // Assert - expect(widelyUsed, equals(expectedWidelyUsed)); - verify(() => mockLocal.getAllWidely()).called(1); - }); - - test('should initialize widely used data', () async { - // Arrange - when(() => mockLocal.initWidleyUsed()).thenAnswer((_) async {}); - - // Act - await chickenRepository.initWidleyUsed(); - - // Assert - verify(() => mockLocal.initWidleyUsed()).called(1); - }); - }); - - group('Error Handling in Steward Workflow', () { - test('should handle inventory retrieval failure', () async { - // Arrange - when( - () => mockRemote.getRolesProduct( - token: token, - role: 'steward', - cancelToken: any(named: 'cancelToken'), - ), - ).thenAnswer((_) async => null); - - // Act - final inventory = await chickenRepository.getRolesProduct( - token: token, - role: 'steward', - ); - - // Assert - expect(inventory, isNull); - verify( - () => mockRemote.getRolesProduct( - token: token, - role: 'steward', - cancelToken: any(named: 'cancelToken'), - ), - ).called(1); - }); - - test('should handle allocation confirmation failure', () async { - // Arrange - final allocationRequest = { - 'allocationId': 'allocation-1', - 'confirmed': true, - }; - - when( - () => mockRemote.confirmAllocation( - token: token, - allocation: allocationRequest, - ), - ).thenThrow(Exception('Allocation confirmation failed')); - - // Act & Assert - expect( - () => chickenRepository.confirmAllocation( - token: token, - allocation: allocationRequest, - ), - throwsA(isA()), - ); - - verify( - () => mockRemote.confirmAllocation( - token: token, - allocation: allocationRequest, - ), - ).called(1); - }); - }); - }); -} diff --git a/packages/core/devtools_options.yaml b/packages/core/devtools_options.yaml index ff5a421..a39b6d9 100644 --- a/packages/core/devtools_options.yaml +++ b/packages/core/devtools_options.yaml @@ -1,4 +1,6 @@ description: This file stores settings for Dart & Flutter DevTools. documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states extensions: - - hive_ce: true \ No newline at end of file + - hive_ce: true + - provider: true + - shared_preferences: true \ No newline at end of file diff --git a/packages/core/lib/data/model/local/app_model/app_model.dart b/packages/core/lib/data/model/local/app_model/app_model.dart index ff90e83..5cb7998 100644 --- a/packages/core/lib/data/model/local/app_model/app_model.dart +++ b/packages/core/lib/data/model/local/app_model/app_model.dart @@ -2,6 +2,7 @@ import 'package:rasadyar_core/core.dart'; part 'app_model.g.dart'; + @HiveType(typeId: appModelTypeId) class AppModel extends HiveObject { @HiveField(0, defaultValue: true) @@ -16,7 +17,12 @@ class AppModel extends HiveObject { @HiveField(3) List? targetPages; - AppModel({this.isFirstRun, this.isDarkMode, this.selectedModule, this.targetPages}); + AppModel({ + this.isFirstRun, + this.isDarkMode, + this.selectedModule, + this.targetPages, + }); @override String toString() { diff --git a/packages/core/lib/data/model/local/app_model/app_model.g.yaml b/packages/core/lib/data/model/local/app_model/app_model.g.yaml new file mode 100644 index 0000000..4b0101f --- /dev/null +++ b/packages/core/lib/data/model/local/app_model/app_model.g.yaml @@ -0,0 +1,39 @@ +# Generated by Hive CE +# Manual modifications may be necessary for certain migrations +# Check in to version control +nextTypeId: 3 +types: + AppModel: + typeId: 0 + nextIndex: 4 + fields: + isFirstRun: + index: 0 + isDarkMode: + index: 1 + selectedModule: + index: 2 + targetPages: + index: 3 + TargetPage: + typeId: 1 + nextIndex: 4 + fields: + route: + index: 0 + functions: + index: 1 + module: + index: 2 + selectedRole: + index: 3 + Module: + typeId: 2 + nextIndex: 3 + fields: + liveStocks: + index: 0 + inspection: + index: 1 + chicken: + index: 2 diff --git a/packages/core/lib/data/model/local/hive_adapters.dart b/packages/core/lib/data/model/local/hive_adapters.dart new file mode 100644 index 0000000..917d383 --- /dev/null +++ b/packages/core/lib/data/model/local/hive_adapters.dart @@ -0,0 +1,15 @@ +import 'package:hive_ce_flutter/hive_flutter.dart'; +import 'package:rasadyar_core/data/model/local/app_model/app_model.dart'; +import 'package:rasadyar_core/data/model/local/user_local/user_local_model.dart'; + + +@GenerateAdapters([ + AdapterSpec(), + AdapterSpec(), + AdapterSpec(), + AdapterSpec(), +]) +part 'hive_adapters.g.dart'; + + + diff --git a/packages/core/lib/data/model/local/hive_adapters.g.dart b/packages/core/lib/data/model/local/hive_adapters.g.dart new file mode 100644 index 0000000..e65e428 --- /dev/null +++ b/packages/core/lib/data/model/local/hive_adapters.g.dart @@ -0,0 +1,185 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'hive_adapters.dart'; + +// ************************************************************************** +// AdaptersGenerator +// ************************************************************************** + +class AppModelAdapter extends TypeAdapter { + @override + final typeId = 0; + + @override + AppModel read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return AppModel( + isFirstRun: fields[0] == null ? true : fields[0] as bool?, + isDarkMode: fields[1] as bool?, + selectedModule: fields[2] as Module?, + targetPages: (fields[3] as List?)?.cast(), + ); + } + + @override + void write(BinaryWriter writer, AppModel obj) { + writer + ..writeByte(4) + ..writeByte(0) + ..write(obj.isFirstRun) + ..writeByte(1) + ..write(obj.isDarkMode) + ..writeByte(2) + ..write(obj.selectedModule) + ..writeByte(3) + ..write(obj.targetPages); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is AppModelAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class TargetPageAdapter extends TypeAdapter { + @override + final typeId = 1; + + @override + TargetPage read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return TargetPage( + route: fields[0] as String?, + functions: (fields[1] as List?)?.cast(), + module: fields[2] as Module?, + )..selectedRole = fields[3] as String?; + } + + @override + void write(BinaryWriter writer, TargetPage obj) { + writer + ..writeByte(4) + ..writeByte(0) + ..write(obj.route) + ..writeByte(1) + ..write(obj.functions) + ..writeByte(2) + ..write(obj.module) + ..writeByte(3) + ..write(obj.selectedRole); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is TargetPageAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class UserLocalModelAdapter extends TypeAdapter { + @override + final typeId = 2; + + @override + UserLocalModel read(BinaryReader reader) { + final numOfFields = reader.readByte(); + final fields = { + for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(), + }; + return UserLocalModel( + username: fields[0] as String?, + password: fields[1] as String?, + token: fields[2] as String?, + refreshToken: fields[3] as String?, + module: fields[4] as Module?, + backend: fields[5] as String?, + roles: (fields[6] as List?)?.cast(), + ); + } + + @override + void write(BinaryWriter writer, UserLocalModel obj) { + writer + ..writeByte(7) + ..writeByte(0) + ..write(obj.username) + ..writeByte(1) + ..write(obj.password) + ..writeByte(2) + ..write(obj.token) + ..writeByte(3) + ..write(obj.refreshToken) + ..writeByte(4) + ..write(obj.module) + ..writeByte(5) + ..write(obj.backend) + ..writeByte(6) + ..write(obj.roles); + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is UserLocalModelAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} + +class ModuleAdapter extends TypeAdapter { + @override + final typeId = 3; + + @override + Module read(BinaryReader reader) { + switch (reader.readByte()) { + case 0: + return Module.liveStocks; + case 1: + return Module.inspection; + case 2: + return Module.chicken; + default: + return Module.liveStocks; + } + } + + @override + void write(BinaryWriter writer, Module obj) { + switch (obj) { + case Module.liveStocks: + writer.writeByte(0); + case Module.inspection: + writer.writeByte(1); + case Module.chicken: + writer.writeByte(2); + } + } + + @override + int get hashCode => typeId.hashCode; + + @override + bool operator ==(Object other) => + identical(this, other) || + other is ModuleAdapter && + runtimeType == other.runtimeType && + typeId == other.typeId; +} diff --git a/packages/core/lib/data/model/local/hive_adapters.g.yaml b/packages/core/lib/data/model/local/hive_adapters.g.yaml new file mode 100644 index 0000000..70c0bf5 --- /dev/null +++ b/packages/core/lib/data/model/local/hive_adapters.g.yaml @@ -0,0 +1,57 @@ +# Generated by Hive CE +# Manual modifications may be necessary for certain migrations +# Check in to version control +nextTypeId: 4 +types: + AppModel: + typeId: 0 + nextIndex: 4 + fields: + isFirstRun: + index: 0 + isDarkMode: + index: 1 + selectedModule: + index: 2 + targetPages: + index: 3 + TargetPage: + typeId: 1 + nextIndex: 4 + fields: + route: + index: 0 + functions: + index: 1 + module: + index: 2 + selectedRole: + index: 3 + UserLocalModel: + typeId: 2 + nextIndex: 7 + fields: + username: + index: 0 + password: + index: 1 + token: + index: 2 + refreshToken: + index: 3 + module: + index: 4 + backend: + index: 5 + roles: + index: 6 + Module: + typeId: 3 + nextIndex: 3 + fields: + liveStocks: + index: 0 + inspection: + index: 1 + chicken: + index: 2 diff --git a/packages/core/lib/hive_registrar.g.dart b/packages/core/lib/data/model/local/hive_registrar.g.dart similarity index 81% rename from packages/core/lib/hive_registrar.g.dart rename to packages/core/lib/data/model/local/hive_registrar.g.dart index d576099..72d82b0 100644 --- a/packages/core/lib/hive_registrar.g.dart +++ b/packages/core/lib/data/model/local/hive_registrar.g.dart @@ -9,8 +9,11 @@ import 'package:rasadyar_core/data/model/local/user_local/user_local_model.dart' extension HiveRegistrar on HiveInterface { void registerAdapters() { registerAdapter(AppModelAdapter()); + registerAdapter(ModuleAdapter()); + registerAdapter(TargetPageAdapter()); + registerAdapter(UserLocalModelAdapter()); } } @@ -18,8 +21,12 @@ extension HiveRegistrar on HiveInterface { extension IsolatedHiveRegistrar on IsolatedHiveInterface { void registerAdapters() { registerAdapter(AppModelAdapter()); + registerAdapter(AppModelAdapter()); + registerAdapter(ModuleAdapter()); registerAdapter(ModuleAdapter()); registerAdapter(TargetPageAdapter()); + registerAdapter(TargetPageAdapter()); + registerAdapter(UserLocalModelAdapter()); registerAdapter(UserLocalModelAdapter()); } } diff --git a/packages/core/lib/data/model/local/user_local/user_local_model.dart b/packages/core/lib/data/model/local/user_local/user_local_model.dart index 5adc717..0c700f6 100644 --- a/packages/core/lib/data/model/local/user_local/user_local_model.dart +++ b/packages/core/lib/data/model/local/user_local/user_local_model.dart @@ -2,6 +2,8 @@ import 'package:rasadyar_core/core.dart'; part 'user_local_model.g.dart'; + + @HiveType(typeId: authUserLocalModelTypeId) class UserLocalModel extends HiveObject { @HiveField(0) diff --git a/packages/core/lib/data/model/local/user_local/user_local_model.g.yaml b/packages/core/lib/data/model/local/user_local/user_local_model.g.yaml new file mode 100644 index 0000000..91a0bff --- /dev/null +++ b/packages/core/lib/data/model/local/user_local/user_local_model.g.yaml @@ -0,0 +1,23 @@ +# Generated by Hive CE +# Manual modifications may be necessary for certain migrations +# Check in to version control +nextTypeId: 1 +types: + UserLocalModel: + typeId: 0 + nextIndex: 7 + fields: + username: + index: 0 + password: + index: 1 + token: + index: 2 + refreshToken: + index: 3 + module: + index: 4 + backend: + index: 5 + roles: + index: 6 diff --git a/packages/core/lib/data/services/g_service.dart b/packages/core/lib/data/services/g_service.dart index 0506cfc..b674b3c 100644 --- a/packages/core/lib/data/services/g_service.dart +++ b/packages/core/lib/data/services/g_service.dart @@ -1,5 +1,6 @@ import 'package:rasadyar_core/core.dart'; -import 'package:rasadyar_core/hive_registrar.g.dart'; +import 'package:rasadyar_core/data/model/local/hive_registrar.g.dart'; + class GService extends GetxService { final String _boxName = "appBox"; @@ -42,14 +43,18 @@ class GService extends GetxService { if (isFirstTime()) { return null; } - var res = box.values.first.targetPages?.firstWhereOrNull((element) => element.module == module); + var res = box.values.first.targetPages?.firstWhereOrNull( + (element) => element.module == module, + ); return res; } Future saveRoute(Module module, String route) async { AppModel model = box.values.first; - TargetPage? targetPage = model.targetPages?.firstWhere((element) => element.module == module); + TargetPage? targetPage = model.targetPages?.firstWhere( + (element) => element.module == module, + ); if (targetPage != null) { targetPage.route = route; model.save(); @@ -62,7 +67,9 @@ class GService extends GetxService { Future saveRole(Module module, String role) async { AppModel model = box.values.first; - TargetPage? targetPage = model.targetPages?.firstWhere((element) => element.module == module); + TargetPage? targetPage = model.targetPages?.firstWhere( + (element) => element.module == module, + ); if (targetPage != null) { targetPage.selectedRole = role; model.save(); diff --git a/packages/core/lib/infrastructure/remote/dio_remote.dart b/packages/core/lib/infrastructure/remote/dio_remote.dart index 2e15d60..2ca74ef 100644 --- a/packages/core/lib/infrastructure/remote/dio_remote.dart +++ b/packages/core/lib/infrastructure/remote/dio_remote.dart @@ -37,6 +37,7 @@ class DioRemote implements IHttpClient { PrettyDioLogger( request: true, enabled: true, + requestHeader: true, responseHeader: true, requestBody: true, diff --git a/packages/core/lib/injection/di.dart b/packages/core/lib/injection/di.dart index 65308b8..43f8723 100644 --- a/packages/core/lib/injection/di.dart +++ b/packages/core/lib/injection/di.dart @@ -14,6 +14,8 @@ Future setupAllCoreProvider() async { // await FMTCObjectBoxBackend().initialise(); await diCore.allReady(); + + } Future _setupLocalStorage() async { diff --git a/packages/core/lib/presentation/widget/image_picker/image_picker_controller.dart b/packages/core/lib/presentation/widget/image_picker/image_picker_controller.dart new file mode 100644 index 0000000..09ee4e7 --- /dev/null +++ b/packages/core/lib/presentation/widget/image_picker/image_picker_controller.dart @@ -0,0 +1,102 @@ +import 'package:camera/camera.dart'; +import 'package:flutter/foundation.dart'; +import 'package:rasadyar_core/utils/logger_utils.dart'; + +class RImagePickerController extends ChangeNotifier { + List _cameras = []; + + CameraController? cameraController; + + bool isLoading = false; + + bool isCameraReady = false; + bool frontCamera = true; + bool isCameraLoading = false; + bool hasTwoCameras = false; + + List capturedImages = []; + + Future getAvailableCameras() async { + _cameras = await availableCameras(); + if (_cameras.length > 1) { + hasTwoCameras = true; + } + } + + Future openCamera() async { + try { + isCameraLoading = true; + await disposeCameraController(); + + await getAvailableCameras(); + + if (_cameras.isNotEmpty) { + if (hasTwoCameras && frontCamera) { + cameraController = CameraController( + _cameras[0], + ResolutionPreset.high, + enableAudio: false, + ); + } + if (hasTwoCameras && !frontCamera) { + cameraController = CameraController( + _cameras[1], + ResolutionPreset.high, + enableAudio: false, + ); + } + + await cameraController?.initialize(); + + isCameraReady = true; + isCameraLoading = false; + notifyListeners(); + } else { + isCameraReady = false; + isCameraLoading = false; + notifyListeners(); + } + } catch (e) { + isCameraReady = false; + isCameraLoading = false; + notifyListeners(); + eLog(e); + } + } + + Future takePicture() async { + if (cameraController == null || !cameraController!.value.isInitialized) { + return; + } + if (isLoading) return; + + try { + isLoading = true; + notifyListeners(); + final image = await cameraController!.takePicture(); + + capturedImages.insert(0, image); + + isLoading = false; + } catch (e) { + eLog(e); + } finally { + isLoading = false; + notifyListeners(); + } + } + + void removeImage(int index) { + if (index < capturedImages.length) { + capturedImages.removeAt(index); + notifyListeners(); + } + } + + Future disposeCameraController() async { + isCameraReady = false; + notifyListeners(); + await cameraController?.dispose(); + cameraController = null; + } +} diff --git a/packages/core/lib/presentation/widget/image_picker/image_picker_widget.dart b/packages/core/lib/presentation/widget/image_picker/image_picker_widget.dart new file mode 100644 index 0000000..557bbd0 --- /dev/null +++ b/packages/core/lib/presentation/widget/image_picker/image_picker_widget.dart @@ -0,0 +1,211 @@ +import 'dart:io'; + +import 'package:camera/camera.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:rasadyar_core/core.dart'; + +class RImagePicker extends StatefulWidget { + const RImagePicker({super.key, this.maxImages, required this.controller}); + final int? maxImages; + final RImagePickerController controller; + + @override + State createState() => _RImagePickerState(); +} + +class _RImagePickerState extends State { + @override + void initState() { + super.initState(); + widget.controller.openCamera(); + } + + @override + void dispose() { + widget.controller.disposeCameraController(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + body: AnimatedBuilder( + animation: widget.controller, + builder: (context, child) { + if (!widget.controller.isCameraReady) { + return const Center( + child: CoreLoadingIndicator( + color: Colors.white, + variant: CoreLoadingVariant.cupertino, + size: CoreLoadingSize.medium, + ), + ); + } + + return Stack( + alignment: Alignment.center, + fit: StackFit.expand, + children: [ + CameraPreview(widget.controller.cameraController!), + + Positioned( + top: 50, + right: 10, + child: GestureDetector( + onTap: () => Get.back(), + child: Container( + width: 40.w, + height: 40.h, + decoration: BoxDecoration( + color: Colors.white.withAlpha(50), + borderRadius: BorderRadius.circular(10.r), + ), + child: Icon( + CupertinoIcons.clear, + color: Colors.white, + size: 20, + ), + ), + ), + ), + + Positioned( + bottom: 40, + right: 10, + + child: RFab( + onPressed: () => Get.back(), + icon: Assets.vec.checkSvg.svg(), + backgroundColor: AppColor.greenNormal, + ), + ), + + if (widget.maxImages == null || + widget.controller.capturedImages.length < + (widget.maxImages ?? 1000)) ...[ + Positioned( + bottom: 40, + left: 0, + right: 0, + child: Center( + child: FloatingActionButton( + onPressed: widget.controller.isLoading + ? null + : () async { + await widget.controller.takePicture(); + }, + backgroundColor: Colors.white, + child: widget.controller.isLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.black, + ), + ), + ) + : const Icon(Icons.camera_alt, color: Colors.black), + ), + ), + ), + ], + + Positioned( + bottom: 40, + left: 10, + + child: Center( + child: FloatingActionButton( + onPressed: widget.controller.isCameraLoading + ? null + : () async { + widget.controller.frontCamera = + !widget.controller.frontCamera; + + await widget.controller.openCamera(); + }, + backgroundColor: Colors.white, + child: widget.controller.isCameraLoading + ? const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.black, + ), + ), + ) + : const Icon(Icons.cameraswitch, color: Colors.black), + ), + ), + ), + + if (widget.controller.capturedImages.isNotEmpty) ...[ + Positioned( + bottom: 120, + left: 0, + right: 0, + height: 100.h, + child: ListView.separated( + itemCount: widget.controller.capturedImages.length, + padding: EdgeInsets.symmetric( + horizontal: 20.w, + vertical: 10.h, + ), + scrollDirection: Axis.horizontal, + separatorBuilder: (context, index) => SizedBox(width: 10.w), + itemBuilder: (context, index) { + final image = widget.controller.capturedImages[index]; + return Container( + width: 100.w, + height: 100.h, + decoration: BoxDecoration( + border: Border.all(color: Colors.white, width: 2), + borderRadius: BorderRadius.circular(8.r), + image: DecorationImage( + image: FileImage(File(image.path)), + fit: BoxFit.cover, + ), + ), + child: Stack( + fit: StackFit.expand, + children: [ + Positioned( + top: 2, + right: 2, + child: GestureDetector( + onTap: () => + widget.controller.removeImage(index), + child: Container( + padding: const EdgeInsets.all(4), + decoration: const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + child: const Icon( + Icons.close, + size: 16, + color: Colors.white, + ), + ), + ), + ), + ], + ), + ); + }, + ), + ), + ], + ], + ); + }, + ), + ); + } +} diff --git a/packages/core/lib/presentation/widget/inputs/r_input.dart b/packages/core/lib/presentation/widget/inputs/r_input.dart index f46631e..af0d2f1 100644 --- a/packages/core/lib/presentation/widget/inputs/r_input.dart +++ b/packages/core/lib/presentation/widget/inputs/r_input.dart @@ -23,6 +23,7 @@ class RTextField extends StatefulWidget { final BoxConstraints? boxConstraints; final RTextFieldVariant variant; final bool filled; + final bool isFullHeight; final Color? filledColor; final Color? borderColor; final bool showCounter; @@ -92,6 +93,7 @@ class RTextField extends StatefulWidget { this.prefixIcon, this.suffix, this.boxConstraints, + this.isFullHeight = false, // 📐 Layout & appearance this.borderColor, @@ -201,8 +203,8 @@ class _RTextFieldState extends State { child: Padding( padding: widget.padding ?? EdgeInsets.zero, child: TextFormField( + textAlignVertical: TextAlignVertical.center, controller: widget.controller, - focusNode: widget.focusNode, textAlign: widget.textAlign ?? TextAlign.start, readOnly: widget.readonly, @@ -229,7 +231,11 @@ class _RTextFieldState extends State { textInputAction: widget.textInputAction, autofillHints: widget.autofillHints, decoration: InputDecoration( - contentPadding: const EdgeInsets.symmetric(horizontal: 16), + contentPadding: EdgeInsets.symmetric( + horizontal: 16, + vertical: widget.isFullHeight ? widget.height / 3 : 0, + ), + errorStyle: widget.errorStyle, errorMaxLines: 1, isDense: widget.isDense, diff --git a/packages/core/lib/presentation/widget/widget.dart b/packages/core/lib/presentation/widget/widget.dart index e2d6bc3..9399923 100644 --- a/packages/core/lib/presentation/widget/widget.dart +++ b/packages/core/lib/presentation/widget/widget.dart @@ -50,3 +50,7 @@ export 'tabs/new_tab.dart'; export 'tabs/r_segment.dart'; export 'tabs/tab.dart'; export 'vec_widget.dart'; + +//image picker +export 'image_picker/image_picker_controller.dart'; +export 'image_picker/image_picker_widget.dart'; diff --git a/packages/core/lib/utils/logger_utils.dart b/packages/core/lib/utils/logger_utils.dart index 8d83ded..151e960 100644 --- a/packages/core/lib/utils/logger_utils.dart +++ b/packages/core/lib/utils/logger_utils.dart @@ -3,41 +3,37 @@ import 'package:logger/logger.dart'; import 'package:rasadyar_core/injection/di.dart'; void iLog(dynamic message) { - if(kDebugMode){ + if (kDebugMode) { diCore.get().i(message.toString()); } } -void wLog(dynamic message){ - if(kDebugMode){ +void wLog(dynamic message) { + if (kDebugMode) { diCore.get().w(message.toString()); } } void eLog(dynamic message) { - if(kDebugMode){ - diCore.get().e(message.toString()); + if (kDebugMode) { + diCore.get().e(message.toString()); } } - void dLog(dynamic message) { - if(kDebugMode){ - diCore.get().d(message.toString()); + if (kDebugMode) { + diCore.get().d(message.toString()); } } - -void fLog(dynamic message){ - if(kDebugMode){ - diCore.get().f(message.toString()); +void fLog(dynamic message) { + if (kDebugMode) { + diCore.get().f(message.toString()); } } - void tLog(dynamic message) { - if(kDebugMode){ - diCore.get().t(message.toString()); + if (kDebugMode) { + diCore.get().t(message.toString()); } } - diff --git a/packages/core/pubspec.lock b/packages/core/pubspec.lock index a15e57e..2b06e71 100644 --- a/packages/core/pubspec.lock +++ b/packages/core/pubspec.lock @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: build - sha256: dfb67ccc9a78c642193e0c2d94cb9e48c2c818b3178a86097d644acdcde6a8d9 + sha256: c1668065e9ba04752570ad7e038288559d1e2ca5c6d0131c0f5f55e39e777413 url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.3" build_config: dependency: transitive description: @@ -101,10 +101,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "7b5b569f3df370590a85029148d6fc66c7d0201fc6f1847c07dd85d365ae9fcd" + sha256: "110c56ef29b5eb367b4d17fc79375fa8c18a6cd7acd92c05bb3986c17a079057" url: "https://pub.dev" source: hosted - version: "2.10.3" + version: "2.10.4" built_collection: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: built_value - sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d + sha256: "426cf75afdb23aa74bd4e471704de3f9393f3c7b04c1e2d9c6f1073ae0b8b139" url: "https://pub.dev" source: hosted - version: "8.12.0" + version: "8.12.1" cached_network_image: dependency: "direct main" description: @@ -145,6 +145,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + camera: + dependency: "direct main" + description: + name: camera + sha256: eefad89f262a873f38d21e5eec853461737ea074d7c9ede39f3ceb135d201cab + url: "https://pub.dev" + source: hosted + version: "0.11.3" + camera_android_camerax: + dependency: transitive + description: + name: camera_android_camerax + sha256: "474d8355961658d43f1c976e2fa1ca715505bea1adbd56df34c581aaa70ec41f" + url: "https://pub.dev" + source: hosted + version: "0.6.26+2" + camera_avfoundation: + dependency: transitive + description: + name: camera_avfoundation + sha256: "035b90c1e33c2efad7548f402572078f6e514d4f82be0a315cd6c6af7e855aa8" + url: "https://pub.dev" + source: hosted + version: "0.9.22+6" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" + url: "https://pub.dev" + source: hosted + version: "2.12.0" + camera_web: + dependency: transitive + description: + name: camera_web + sha256: "3bc7bb1657a0f29c34116453c5d5e528c23efcf5e75aac0a3387cf108040bf65" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" characters: dependency: transitive description: @@ -237,10 +277,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239" + sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608" url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "0.3.5+1" crypto: dependency: transitive description: @@ -309,10 +349,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: dd0e8e02186b2196c7848c9d394a5fd6e5b57a43a546082c5820b1ec72317e33 + sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c" url: "https://pub.dev" source: hosted - version: "12.2.0" + version: "12.3.0" device_info_plus_platform_interface: dependency: transitive description: @@ -381,18 +421,18 @@ packages: dependency: transitive description: name: file_selector_linux - sha256: "80a877f5ec570c4fb3b40720a70b6f31e8bb1315a464b4d3e92fe82754d4b21a" + sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" url: "https://pub.dev" source: hosted - version: "0.9.3+3" + version: "0.9.4" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "44f24d102e368370951b98ffe86c7325b38349e634578312976607d28cc6d747" + sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" url: "https://pub.dev" source: hosted - version: "0.9.4+6" + version: "0.9.5" file_selector_platform_interface: dependency: transitive description: @@ -511,10 +551,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "306f0596590e077338312f38837f595c04f28d6cdeeac392d3d74df2f0003687" + sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1 url: "https://pub.dev" source: hosted - version: "2.0.32" + version: "2.0.33" flutter_rating_bar: dependency: "direct main" description: @@ -591,10 +631,10 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: "055de8921be7b8e8b98a233c7a5ef84b3a6fcc32f46f1ebf5b9bb3576d108355" + sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.3" flutter_test: dependency: "direct dev" description: flutter @@ -681,10 +721,10 @@ packages: dependency: "direct main" description: name: get - sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 + sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" url: "https://pub.dev" source: hosted - version: "4.7.2" + version: "4.7.3" get_it: dependency: "direct main" description: @@ -745,10 +785,10 @@ packages: dependency: "direct dev" description: name: hive_ce_generator - sha256: b19ac263cb37529513508ba47352c41e6de72ba879952898d9c18c9c8a955921 + sha256: c3d04f17b39cac9439e1c7d098d0b3fd93a488d167af2bd52746dbb5fc109411 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" http: dependency: transitive description: @@ -777,10 +817,10 @@ packages: dependency: transitive description: name: image - sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + sha256: "51555e36056541237b15b57afc31a0f53d4f9aefd9bd00873a6dc0090e54e332" url: "https://pub.dev" source: hosted - version: "4.5.4" + version: "4.6.0" image_cropper: dependency: "direct main" description: @@ -817,26 +857,26 @@ packages: dependency: transitive description: name: image_picker_android - sha256: a1cd1584fae64f6ecca63113fd5450e3483c097cc05e43a2f073330f62adcabe + sha256: "5e9bf126c37c117cf8094215373c6d561117a3cfb50ebc5add1a61dc6e224677" url: "https://pub.dev" source: hosted - version: "0.8.13+8" + version: "0.8.13+10" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" + sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: "997d100ce1dda5b1ba4085194c5e36c9f8a1fb7987f6a36ab677a344cd2dc986" + sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad" url: "https://pub.dev" source: hosted - version: "0.8.13+2" + version: "0.8.13+3" image_picker_linux: dependency: transitive description: @@ -921,10 +961,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: "33a040668b31b320aafa4822b7b1e177e163fc3c1e835c6750319d4ab23aa6fe" + sha256: "6b253f7851cf1626a05c8b49c792e04a14897349798c03798137f2b5f7e0b5b1" url: "https://pub.dev" source: hosted - version: "6.11.1" + version: "6.11.3" latlong2: dependency: "direct main" description: @@ -1041,10 +1081,10 @@ packages: dependency: transitive description: name: mockito - sha256: "4feb43bc4eb6c03e832f5fcd637d1abb44b98f9cfa245c58e27382f58859f8f6" + sha256: dac24d461418d363778d53198d9ac0510b9d073869f078450f195766ec48d05e url: "https://pub.dev" source: hosted - version: "5.5.1" + version: "5.6.1" mocktail: dependency: "direct dev" description: @@ -1153,18 +1193,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "95c68a74d3cab950fd0ed8073d9fab15c1c06eb1f3eec68676e87aabc9ecee5a" + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e url: "https://pub.dev" source: hosted - version: "2.2.21" + version: "2.2.22" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "97390a0719146c7c3e71b6866c34f1cde92685933165c1c671984390d2aca776" + sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4" url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "2.5.1" path_provider_linux: dependency: transitive description: @@ -1369,18 +1409,18 @@ packages: dependency: transitive description: name: shared_preferences - sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "2.5.4" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "07d552dbe8e71ed720e5205e760438ff4ecfb76ec3b32ea664350e2ca4b0c43b" + sha256: "83af5c682796c0f7719c2bbf74792d113e40ae97981b8f266fa84574573556bc" url: "https://pub.dev" source: hosted - version: "2.4.16" + version: "2.4.18" shared_preferences_foundation: dependency: transitive description: @@ -1478,18 +1518,18 @@ packages: dependency: transitive description: name: source_gen - sha256: "9098ab86015c4f1d8af6486b547b11100e73b193e1899015033cb3e14ad20243" + sha256: "07b277b67e0096c45196cbddddf2d8c6ffc49342e88bf31d460ce04605ddac75" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.1" source_helper: dependency: transitive description: name: source_helper - sha256: "6a3c6cc82073a8797f8c4dc4572146114a39652851c157db37e964d9c7038723" + sha256: e82b1996c63da42aa3e6a34cc1ec17427728a1baf72ed017717a5669a7123f0d url: "https://pub.dev" source: hosted - version: "1.3.8" + version: "1.3.9" source_map_stack_trace: dependency: transitive description: @@ -1630,10 +1670,10 @@ packages: dependency: transitive description: name: time - sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" + sha256: "46187cf30bffdab28c56be9a63861b36e4ab7347bf403297595d6a97e10c789f" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.6" typed_data: dependency: transitive description: @@ -1702,10 +1742,10 @@ packages: dependency: transitive description: name: watcher - sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" + sha256: f52385d4f73589977c80797e60fe51014f7f2b957b5e9a62c3f6ada439889249 url: "https://pub.dev" source: hosted - version: "1.1.4" + version: "1.2.0" web: dependency: transitive description: diff --git a/packages/core/pubspec.yaml b/packages/core/pubspec.yaml index a1fce85..40a9c26 100644 --- a/packages/core/pubspec.yaml +++ b/packages/core/pubspec.yaml @@ -91,9 +91,10 @@ dependencies: ##code generation freezed_annotation: ^3.1.0 json_annotation: ^4.9.0 + camera: ^0.11.3 dependency_overrides: - analyzer: ^8.0.0 # Ensures analyzer ^8.0.0 is used despite other conflicts + analyzer: ^8.0.0 dev_dependencies: diff --git a/packages/inspection/devtools_options.yaml b/packages/inspection/devtools_options.yaml index ff5a421..a39b6d9 100644 --- a/packages/inspection/devtools_options.yaml +++ b/packages/inspection/devtools_options.yaml @@ -1,4 +1,6 @@ description: This file stores settings for Dart & Flutter DevTools. documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states extensions: - - hive_ce: true \ No newline at end of file + - hive_ce: true + - provider: true + - shared_preferences: true \ No newline at end of file diff --git a/packages/inspection/lib/presentation/pages/inspection_map/logic.dart b/packages/inspection/lib/presentation/pages/inspection_map/logic.dart index 7875532..f5bbcc6 100644 --- a/packages/inspection/lib/presentation/pages/inspection_map/logic.dart +++ b/packages/inspection/lib/presentation/pages/inspection_map/logic.dart @@ -4,7 +4,6 @@ import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_inspection/data/model/response/poultry_location/poultry_location_model.dart'; import 'package:rasadyar_inspection/data/repositories/inspection/inspection_repository_imp.dart'; import 'package:rasadyar_inspection/injection/inspection_di.dart'; -import 'package:rasadyar_inspection/presentation/widget/base_page/logic.dart' hide BaseLogic; import 'widget/map/logic.dart'; diff --git a/packages/livestock/devtools_options.yaml b/packages/livestock/devtools_options.yaml index ff5a421..a39b6d9 100644 --- a/packages/livestock/devtools_options.yaml +++ b/packages/livestock/devtools_options.yaml @@ -1,4 +1,6 @@ description: This file stores settings for Dart & Flutter DevTools. documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states extensions: - - hive_ce: true \ No newline at end of file + - hive_ce: true + - provider: true + - shared_preferences: true \ No newline at end of file diff --git a/packages/livestock/lib/data/common/checkk_di_middleware.dart b/packages/livestock/lib/data/common/checkk_di_middleware.dart index 7ca3e64..2ced215 100644 --- a/packages/livestock/lib/data/common/checkk_di_middleware.dart +++ b/packages/livestock/lib/data/common/checkk_di_middleware.dart @@ -1,6 +1,4 @@ -import 'package:flutter/material.dart'; import 'package:rasadyar_core/core.dart'; -import 'package:rasadyar_livestock/injection/live_stock_di.dart'; class CheckDiMiddleWare extends GetMiddleware { diff --git a/packages/livestock/lib/presentation/page/root/logic.dart b/packages/livestock/lib/presentation/page/root/logic.dart index 3b3a76f..2e265ec 100644 --- a/packages/livestock/lib/presentation/page/root/logic.dart +++ b/packages/livestock/lib/presentation/page/root/logic.dart @@ -1,4 +1,3 @@ -import 'dart:math'; import 'package:flutter/material.dart'; import 'package:rasadyar_core/core.dart'; diff --git a/packages/livestock/pubspec.lock b/packages/livestock/pubspec.lock new file mode 100644 index 0000000..d17cafe --- /dev/null +++ b/packages/livestock/pubspec.lock @@ -0,0 +1,1878 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f + url: "https://pub.dev" + source: hosted + version: "85.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: "974859dc0ff5f37bc4313244b3218c791810d03ab3470a579580279ba971a48d" + url: "https://pub.dev" + source: hosted + version: "7.7.1" + android_intent_plus: + dependency: transitive + description: + name: android_intent_plus + sha256: "14a9f94c5825a528e8c38ee89a33dbeba947efbbf76f066c174f4f3ae4f48feb" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + animated_stack_widget: + dependency: transitive + description: + name: animated_stack_widget + sha256: ce4788dd158768c9d4388354b6fb72600b78e041a37afc4c279c63ecafcb9408 + url: "https://pub.dev" + source: hosted + version: "0.0.4" + archive: + dependency: transitive + description: + name: archive + sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + url: "https://pub.dev" + source: hosted + version: "4.0.7" + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + asn1lib: + dependency: transitive + description: + name: asn1lib + sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" + url: "https://pub.dev" + source: hosted + version: "1.6.5" + async: + dependency: transitive + description: + name: async + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.dev" + source: hosted + version: "2.13.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + build: + dependency: transitive + description: + name: build + sha256: ce76b1d48875e3233fde17717c23d1f60a91cc631597e49a400c89b475395b1d + url: "https://pub.dev" + source: hosted + version: "3.1.0" + build_config: + dependency: transitive + description: + name: build_config + sha256: "4f64382b97504dc2fcdf487d5aae33418e08b4703fc21249e4db6d804a4d0187" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "8e928697a82be082206edb0b9c99c5a4ad6bc31c9e9b8b2f291ae65cd4a25daa" + url: "https://pub.dev" + source: hosted + version: "4.0.4" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: d1d57f7807debd7349b4726a19fd32ec8bc177c71ad0febf91a20f84cd2d4b46 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: b24597fceb695969d47025c958f3837f9f0122e237c6a22cb082a5ac66c3ca30 + url: "https://pub.dev" + source: hosted + version: "2.7.1" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "066dda7f73d8eb48ba630a55acb50c4a84a2e6b453b1cb4567f581729e794f7b" + url: "https://pub.dev" + source: hosted + version: "9.3.1" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "0b1b12a0a549605e5f04476031cd0bc91ead1d7c8e830773a18ee54179b3cb62" + url: "https://pub.dev" + source: hosted + version: "8.11.0" + cached_network_image: + dependency: transitive + description: + name: cached_network_image + sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + cached_network_image_platform_interface: + dependency: transitive + description: + name: cached_network_image_platform_interface + sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + cached_network_image_web: + dependency: transitive + description: + name: cached_network_image_web + sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + camera: + dependency: transitive + description: + name: camera + sha256: eefad89f262a873f38d21e5eec853461737ea074d7c9ede39f3ceb135d201cab + url: "https://pub.dev" + source: hosted + version: "0.11.3" + camera_android_camerax: + dependency: transitive + description: + name: camera_android_camerax + sha256: "474d8355961658d43f1c976e2fa1ca715505bea1adbd56df34c581aaa70ec41f" + url: "https://pub.dev" + source: hosted + version: "0.6.26+2" + camera_avfoundation: + dependency: transitive + description: + name: camera_avfoundation + sha256: "035b90c1e33c2efad7548f402572078f6e514d4f82be0a315cd6c6af7e855aa8" + url: "https://pub.dev" + source: hosted + version: "0.9.22+6" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" + url: "https://pub.dev" + source: hosted + version: "2.12.0" + camera_web: + dependency: transitive + description: + name: camera_web + sha256: "3bc7bb1657a0f29c34116453c5d5e528c23efcf5e75aac0a3387cf108040bf65" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" + characters: + dependency: transitive + description: + name: characters + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" + url: "https://pub.dev" + source: hosted + version: "2.0.4" + cli_config: + dependency: transitive + description: + name: cli_config + sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec + url: "https://pub.dev" + source: hosted + version: "0.2.0" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e" + url: "https://pub.dev" + source: hosted + version: "4.10.1" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" + connectivity_plus: + dependency: transitive + description: + name: connectivity_plus + sha256: "33bae12a398f841c6cda09d1064212957265869104c478e5ad51e2fb26c3973c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + convert: + dependency: transitive + description: + name: convert + sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + coverage: + dependency: transitive + description: + name: coverage + sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" + url: "https://pub.dev" + source: hosted + version: "1.15.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" + cupertino_icons: + dependency: transitive + description: + name: cupertino_icons + sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 + url: "https://pub.dev" + source: hosted + version: "1.0.8" + dart_earcut: + dependency: transitive + description: + name: dart_earcut + sha256: e485001bfc05dcbc437d7bfb666316182e3522d4c3f9668048e004d0eb2ce43b + url: "https://pub.dev" + source: hosted + version: "1.2.0" + dart_polylabel2: + dependency: transitive + description: + name: dart_polylabel2 + sha256: "7eeab15ce72894e4bdba6a8765712231fc81be0bd95247de4ad9966abc57adc6" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + dartx: + dependency: transitive + description: + name: dartx + sha256: "8b25435617027257d43e6508b5fe061012880ddfdaa75a71d607c3de2a13d244" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + dbus: + dependency: transitive + description: + name: dbus + sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" + url: "https://pub.dev" + source: hosted + version: "0.7.11" + device_frame_plus: + dependency: transitive + description: + name: device_frame_plus + sha256: ccc94abccd4d9f0a9f19ef239001b3a59896e678ad42601371d7065889f2bf78 + url: "https://pub.dev" + source: hosted + version: "1.5.0" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c" + url: "https://pub.dev" + source: hosted + version: "12.3.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f + url: "https://pub.dev" + source: hosted + version: "7.0.3" + device_preview_plus: + dependency: transitive + description: + name: device_preview_plus + sha256: eb3e67929c9f04759e0d3708ad91d1018235549bcf8699f8a94909684c6555ae + url: "https://pub.dev" + source: hosted + version: "2.5.5" + dio: + dependency: transitive + description: + name: dio + sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 + url: "https://pub.dev" + source: hosted + version: "5.9.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + encrypt: + dependency: transitive + description: + name: encrypt + sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" + url: "https://pub.dev" + source: hosted + version: "5.0.3" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" + url: "https://pub.dev" + source: hosted + version: "0.9.3+2" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: "8c9250b2bd2d8d4268e39c82543bacbaca0fda7d29e0728c3c4bbb7c820fd711" + url: "https://pub.dev" + source: hosted + version: "0.9.4+3" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + url: "https://pub.dev" + source: hosted + version: "2.6.2" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" + url: "https://pub.dev" + source: hosted + version: "0.9.3+4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flat_buffers: + dependency: transitive + description: + name: flat_buffers + sha256: "380bdcba5664a718bfd4ea20a45d39e13684f5318fcd8883066a55e21f37f4c3" + url: "https://pub.dev" + source: hosted + version: "23.5.26" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_cache_manager: + dependency: transitive + description: + name: flutter_cache_manager + sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" + url: "https://pub.dev" + source: hosted + version: "3.4.1" + flutter_gen_core: + dependency: transitive + description: + name: flutter_gen_core + sha256: b6bafbbd981da2f964eb45bcb8b8a7676a281084f8922c0c75de4cfbaa849311 + url: "https://pub.dev" + source: hosted + version: "5.12.0" + flutter_gen_runner: + dependency: transitive + description: + name: flutter_gen_runner + sha256: c99b10af9d404e3f46fd1927e7d90099779e935e86022674c4c2a9e6c2a93b29 + url: "https://pub.dev" + source: hosted + version: "5.12.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + flutter_map: + dependency: transitive + description: + name: flutter_map + sha256: "391e7dc95cc3f5190748210a69d4cfeb5d8f84dcdfa9c3235d0a9d7742ccb3f8" + url: "https://pub.dev" + source: hosted + version: "8.2.2" + flutter_map_animations: + dependency: transitive + description: + name: flutter_map_animations + sha256: bf583863561861aaaf4854ae7ed8940d79bea7d32918bf7a85d309b25235a09e + url: "https://pub.dev" + source: hosted + version: "0.9.0" + flutter_map_marker_cluster: + dependency: transitive + description: + name: flutter_map_marker_cluster + sha256: "04a20d9b1c3a18b67cc97c1240f75361ab98449b735ab06f2534ece0d0794733" + url: "https://pub.dev" + source: hosted + version: "8.2.2" + flutter_map_marker_popup: + dependency: transitive + description: + name: flutter_map_marker_popup + sha256: "982b38455e739fe04abf05066340e0ce5883c40fb08b121cc8c60f5ee2c664a3" + url: "https://pub.dev" + source: hosted + version: "8.1.0" + flutter_map_tile_caching: + dependency: transitive + description: + name: flutter_map_tile_caching + sha256: "90e097223d8ab74425cf15b449a03adfa4d4c28406dc757e1c396aff0f9beba7" + url: "https://pub.dev" + source: hosted + version: "10.1.1" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e + url: "https://pub.dev" + source: hosted + version: "2.0.28" + flutter_rating_bar: + dependency: transitive + description: + name: flutter_rating_bar + sha256: d2af03469eac832c591a1eba47c91ecc871fe5708e69967073c043b2d775ed93 + url: "https://pub.dev" + source: hosted + version: "4.0.1" + flutter_screenutil: + dependency: transitive + description: + name: flutter_screenutil + sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de" + url: "https://pub.dev" + source: hosted + version: "5.9.3" + flutter_secure_storage: + dependency: transitive + description: + name: flutter_secure_storage + sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea" + url: "https://pub.dev" + source: hosted + version: "9.2.4" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + flutter_secure_storage_macos: + dependency: transitive + description: + name: flutter_secure_storage_macos + sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247" + url: "https://pub.dev" + source: hosted + version: "3.1.3" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8 + url: "https://pub.dev" + source: hosted + version: "1.1.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709 + url: "https://pub.dev" + source: hosted + version: "3.1.2" + flutter_slidable: + dependency: transitive + description: + name: flutter_slidable + sha256: ea369262929d3cc6ebf9d8a00c196127966f117fe433a5e5cb47fb08008ca203 + url: "https://pub.dev" + source: hosted + version: "4.0.3" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95" + url: "https://pub.dev" + source: hosted + version: "2.2.3" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + freezed: + dependency: "direct dev" + description: + name: freezed + sha256: "13065f10e135263a4f5a4391b79a8efc5fb8106f8dd555a9e49b750b45393d77" + url: "https://pub.dev" + source: hosted + version: "3.2.3" + freezed_annotation: + dependency: "direct main" + description: + name: freezed_annotation + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 + url: "https://pub.dev" + source: hosted + version: "4.0.0" + geolocator: + dependency: transitive + description: + name: geolocator + sha256: ee2212a3df8292ec4c90b91183b8001d3f5a800823c974b570c5f9344ca320dc + url: "https://pub.dev" + source: hosted + version: "14.0.1" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a" + url: "https://pub.dev" + source: hosted + version: "5.0.2" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 + url: "https://pub.dev" + source: hosted + version: "2.3.13" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" + url: "https://pub.dev" + source: hosted + version: "4.2.6" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172 + url: "https://pub.dev" + source: hosted + version: "4.1.3" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" + url: "https://pub.dev" + source: hosted + version: "0.2.5" + get: + dependency: transitive + description: + name: get + sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 + url: "https://pub.dev" + source: hosted + version: "4.7.2" + get_it: + dependency: transitive + description: + name: get_it + sha256: ae78de7c3f2304b8d81f2bb6e320833e5e81de942188542328f074978cc0efa9 + url: "https://pub.dev" + source: hosted + version: "8.3.0" + get_test: + dependency: "direct dev" + description: + name: get_test + sha256: "558c39cb35fb37bd501f337dc143de60a4314d5ef3b75f4b0551d6741634995b" + url: "https://pub.dev" + source: hosted + version: "4.0.1" + glob: + dependency: transitive + description: + name: glob + sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + url: "https://pub.dev" + source: hosted + version: "2.1.3" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + hashcodes: + dependency: transitive + description: + name: hashcodes + sha256: "80f9410a5b3c8e110c4b7604546034749259f5d6dcca63e0d3c17c9258f1a651" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + hive_ce: + dependency: transitive + description: + name: hive_ce + sha256: "81d39a03c4c0ba5938260a8c3547d2e71af59defecea21793d57fc3551f0d230" + url: "https://pub.dev" + source: hosted + version: "2.15.1" + hive_ce_flutter: + dependency: transitive + description: + name: hive_ce_flutter + sha256: "26d656c9e8974f0732f1d09020e2d7b08ba841b8961a02dbfb6caf01474b0e9a" + url: "https://pub.dev" + source: hosted + version: "2.3.3" + hive_ce_generator: + dependency: "direct dev" + description: + name: hive_ce_generator + sha256: a169feeff2da9cc2c417ce5ae9bcebf7c8a95d7a700492b276909016ad70a786 + url: "https://pub.dev" + source: hosted + version: "1.9.3" + http: + dependency: transitive + description: + name: http + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" + url: "https://pub.dev" + source: hosted + version: "1.6.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8 + url: "https://pub.dev" + source: hosted + version: "3.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + image: + dependency: transitive + description: + name: image + sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + url: "https://pub.dev" + source: hosted + version: "4.5.4" + image_cropper: + dependency: transitive + description: + name: image_cropper + sha256: "46c8f9aae51c8350b2a2982462f85a129e77b04675d35b09db5499437d7a996b" + url: "https://pub.dev" + source: hosted + version: "11.0.0" + image_cropper_for_web: + dependency: transitive + description: + name: image_cropper_for_web + sha256: e09749714bc24c4e3b31fbafa2e5b7229b0ff23e8b14d4ba44bd723b77611a0f + url: "https://pub.dev" + source: hosted + version: "7.0.0" + image_cropper_platform_interface: + dependency: transitive + description: + name: image_cropper_platform_interface + sha256: "886a30ec199362cdcc2fbb053b8e53347fbfb9dbbdaa94f9ff85622609f5e7ff" + url: "https://pub.dev" + source: hosted + version: "8.0.0" + image_picker: + dependency: transitive + description: + name: image_picker + sha256: "784210112be18ea55f69d7076e2c656a4e24949fa9e76429fe53af0c0f4fa320" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: "5e9bf126c37c117cf8094215373c6d561117a3cfb50ebc5add1a61dc6e224677" + url: "https://pub.dev" + source: hosted + version: "0.8.13+10" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "997d100ce1dda5b1ba4085194c5e36c9f8a1fb7987f6a36ab677a344cd2dc986" + url: "https://pub.dev" + source: hosted + version: "0.8.13+2" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91" + url: "https://pub.dev" + source: hosted + version: "0.2.2+1" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c" + url: "https://pub.dev" + source: hosted + version: "2.11.1" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae + url: "https://pub.dev" + source: hosted + version: "0.2.2" + image_size_getter: + dependency: transitive + description: + name: image_size_getter + sha256: "9a299e3af2ebbcfd1baf21456c3c884037ff524316c97d8e56035ea8fdf35653" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + intl: + dependency: transitive + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + io: + dependency: transitive + description: + name: io + sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + url: "https://pub.dev" + source: hosted + version: "1.0.5" + isolate_channel: + dependency: transitive + description: + name: isolate_channel + sha256: f3d36f783b301e6b312c3450eeb2656b0e7d1db81331af2a151d9083a3f6b18d + url: "https://pub.dev" + source: hosted + version: "0.2.2+1" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + url: "https://pub.dev" + source: hosted + version: "4.9.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3 + url: "https://pub.dev" + source: hosted + version: "6.11.2" + latlong2: + dependency: transitive + description: + name: latlong2 + sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe" + url: "https://pub.dev" + source: hosted + version: "0.9.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: "direct dev" + description: + name: lints + sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 + url: "https://pub.dev" + source: hosted + version: "6.0.0" + lists: + dependency: transitive + description: + name: lists + sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + logger: + dependency: transitive + description: + name: logger + sha256: a7967e31b703831a893bbc3c3dd11db08126fe5f369b5c648a36f821979f5be3 + url: "https://pub.dev" + source: hosted + version: "2.6.2" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + lottie: + dependency: transitive + description: + name: lottie + sha256: c5fa04a80a620066c15cf19cc44773e19e9b38e989ff23ea32e5903ef1015950 + url: "https://pub.dev" + source: hosted + version: "3.3.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + url: "https://pub.dev" + source: hosted + version: "0.12.17" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + url: "https://pub.dev" + source: hosted + version: "0.11.1" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mgrs_dart: + dependency: transitive + description: + name: mgrs_dart + sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7 + url: "https://pub.dev" + source: hosted + version: "2.0.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + mockito: + dependency: transitive + description: + name: mockito + sha256: "2314cbe9165bcd16106513df9cf3c3224713087f09723b128928dc11a4379f99" + url: "https://pub.dev" + source: hosted + version: "5.5.0" + mocktail: + dependency: "direct dev" + description: + name: mocktail + sha256: "890df3f9688106f25755f26b1c60589a92b3ab91a22b8b224947ad041bf172d8" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + objectbox: + dependency: transitive + description: + name: objectbox + sha256: "3cc186749178a3556e1020c9082d0897d0f9ecbdefcc27320e65c5bc650f0e57" + url: "https://pub.dev" + source: hosted + version: "4.3.1" + objectbox_flutter_libs: + dependency: transitive + description: + name: objectbox_flutter_libs + sha256: cd754766e04229a4f51250f121813d9a3c1a74fc21cd68e48b3c6085cbcd6c85 + url: "https://pub.dev" + source: hosted + version: "4.3.1" + octo_image: + dependency: transitive + description: + name: octo_image + sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc + url: "https://pub.dev" + source: hosted + version: "2.2.0" + package_info_plus: + dependency: transitive + description: + name: package_info_plus + sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d + url: "https://pub.dev" + source: hosted + version: "9.0.0" + package_info_plus_platform_interface: + dependency: transitive + description: + name: package_info_plus_platform_interface + sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 + url: "https://pub.dev" + source: hosted + version: "2.2.17" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + permission_handler: + dependency: transitive + description: + name: permission_handler + sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 + url: "https://pub.dev" + source: hosted + version: "12.0.1" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" + url: "https://pub.dev" + source: hosted + version: "13.0.1" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 + url: "https://pub.dev" + source: hosted + version: "9.4.7" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + url: "https://pub.dev" + source: hosted + version: "0.1.3+5" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 + url: "https://pub.dev" + source: hosted + version: "4.3.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" + persian_datetime_picker: + dependency: transitive + description: + name: persian_datetime_picker + sha256: "6a5ae6b9f717a6619ae29e65e4c8074285865a88d339dd05c91b9a5b6f8f47d7" + url: "https://pub.dev" + source: hosted + version: "3.2.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" + url: "https://pub.dev" + source: hosted + version: "6.1.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + url: "https://pub.dev" + source: hosted + version: "3.9.1" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + posix: + dependency: transitive + description: + name: posix + sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" + url: "https://pub.dev" + source: hosted + version: "6.0.3" + pretty_dio_logger: + dependency: transitive + description: + name: pretty_dio_logger + sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407" + url: "https://pub.dev" + source: hosted + version: "1.4.0" + proj4dart: + dependency: transitive + description: + name: proj4dart + sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e + url: "https://pub.dev" + source: hosted + version: "2.1.0" + provider: + dependency: transitive + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + url: "https://pub.dev" + source: hosted + version: "1.5.0" + rasadyar_core: + dependency: "direct main" + description: + path: "../core" + relative: true + source: path + version: "1.3.0" + rive: + dependency: transitive + description: + name: rive + sha256: "2551a44fa766a7ed3f52aa2b94feda6d18d00edc25dee5f66e72e9b365bb6d6c" + url: "https://pub.dev" + source: hosted + version: "0.13.20" + rive_common: + dependency: transitive + description: + name: rive_common + sha256: "2ba42f80d37a4efd0696fb715787c4785f8a13361e8aea9227c50f1e78cf763a" + url: "https://pub.dev" + source: hosted + version: "0.4.15" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" + url: "https://pub.dev" + source: hosted + version: "0.28.0" + shamsi_date: + dependency: transitive + description: + name: shamsi_date + sha256: "0383fddc9bce91e9e08de0c909faf93c3ab3a0e532abd271fb0dcf5d0617487b" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + shared_preferences: + dependency: transitive + description: + name: shared_preferences + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + url: "https://pub.dev" + source: hosted + version: "2.5.3" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "83af5c682796c0f7719c2bbf74792d113e40ae97981b8f266fa84574573556bc" + url: "https://pub.dev" + source: hosted + version: "2.4.18" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shelf: + dependency: transitive + description: + name: shelf + sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 + url: "https://pub.dev" + source: hosted + version: "1.4.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + shelf_static: + dependency: transitive + description: + name: shelf_static + sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3 + url: "https://pub.dev" + source: hosted + version: "1.1.3" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + shimmer: + dependency: transitive + description: + name: shimmer + sha256: "5f88c883a22e9f9f299e5ba0e4f7e6054857224976a5d9f839d4ebdc94a14ac9" + url: "https://pub.dev" + source: hosted + version: "3.0.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + smooth_page_indicator: + dependency: transitive + description: + name: smooth_page_indicator + sha256: b21ebb8bc39cf72d11c7cfd809162a48c3800668ced1c9da3aade13a32cf6c1c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "7b19d6ba131c6eb98bfcbf8d56c1a7002eba438af2e7ae6f8398b2b0f4f381e3" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "4f81479fe5194a622cdd1713fe1ecb683a6e6c85cd8cec8e2e35ee5ab3fdf2a1" + url: "https://pub.dev" + source: hosted + version: "1.3.6" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b + url: "https://pub.dev" + source: hosted + version: "2.1.2" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + url: "https://pub.dev" + source: hosted + version: "0.10.13" + source_span: + dependency: transitive + description: + name: source_span + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" + url: "https://pub.dev" + source: hosted + version: "1.10.1" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + sqflite: + dependency: transitive + description: + name: sqflite + sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03 + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_android: + dependency: transitive + description: + name: sqflite_android + sha256: ecd684501ebc2ae9a83536e8b15731642b9570dc8623e0073d227d0ee2bfea88 + url: "https://pub.dev" + source: hosted + version: "2.4.2+2" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + sqflite_darwin: + dependency: transitive + description: + name: sqflite_darwin + sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + sqflite_platform_interface: + dependency: transitive + description: + name: sqflite_platform_interface + sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + synchronized: + dependency: transitive + description: + name: synchronized + sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + url: "https://pub.dev" + source: hosted + version: "3.4.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test: + dependency: "direct dev" + description: + name: test + sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7" + url: "https://pub.dev" + source: hosted + version: "1.26.3" + test_api: + dependency: transitive + description: + name: test_api + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 + url: "https://pub.dev" + source: hosted + version: "0.7.7" + test_core: + dependency: transitive + description: + name: test_core + sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0" + url: "https://pub.dev" + source: hosted + version: "0.6.12" + time: + dependency: transitive + description: + name: time + sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" + url: "https://pub.dev" + source: hosted + version: "2.1.5" + timing: + dependency: transitive + description: + name: timing + sha256: "62ee18aca144e4a9f29d212f5a4c6a053be252b895ab14b5821996cff4ed90fe" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + unicode: + dependency: transitive + description: + name: unicode + sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1" + url: "https://pub.dev" + source: hosted + version: "0.3.1" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: a4f059dc26fc8295b5921376600a194c4ec7d55e72f2fe4c7d2831e103d461e6 + url: "https://pub.dev" + source: hosted + version: "1.1.19" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" + url: "https://pub.dev" + source: hosted + version: "1.1.13" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "557a315b7d2a6dbb0aaaff84d857967ce6bdc96a63dc6ee2a57ce5a6ee5d3331" + url: "https://pub.dev" + source: hosted + version: "1.1.17" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + url: "https://pub.dev" + source: hosted + version: "15.0.0" + watcher: + dependency: transitive + description: + name: watcher + sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a" + url: "https://pub.dev" + source: hosted + version: "1.1.2" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + web_socket: + dependency: transitive + description: + name: web_socket + sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8 + url: "https://pub.dev" + source: hosted + version: "3.0.3" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + win32: + dependency: transitive + description: + name: win32 + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + url: "https://pub.dev" + source: hosted + version: "5.14.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + wkt_parser: + dependency: transitive + description: + name: wkt_parser + sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" + yaml_writer: + dependency: transitive + description: + name: yaml_writer + sha256: "69651cd7238411179ac32079937d4aa9a2970150d6b2ae2c6fe6de09402a5dc5" + url: "https://pub.dev" + source: hosted + version: "2.1.0" +sdks: + dart: ">=3.10.0 <4.0.0" + flutter: ">=3.35.7" diff --git a/pubspec.lock b/pubspec.lock index 1038136..ee97555 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -77,10 +77,10 @@ packages: dependency: transitive description: name: build - sha256: dfb67ccc9a78c642193e0c2d94cb9e48c2c818b3178a86097d644acdcde6a8d9 + sha256: c1668065e9ba04752570ad7e038288559d1e2ca5c6d0131c0f5f55e39e777413 url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.0.3" build_config: dependency: transitive description: @@ -101,10 +101,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "7b5b569f3df370590a85029148d6fc66c7d0201fc6f1847c07dd85d365ae9fcd" + sha256: "110c56ef29b5eb367b4d17fc79375fa8c18a6cd7acd92c05bb3986c17a079057" url: "https://pub.dev" source: hosted - version: "2.10.3" + version: "2.10.4" built_collection: dependency: transitive description: @@ -117,10 +117,10 @@ packages: dependency: transitive description: name: built_value - sha256: a30f0a0e38671e89a492c44d005b5545b830a961575bbd8336d42869ff71066d + sha256: "426cf75afdb23aa74bd4e471704de3f9393f3c7b04c1e2d9c6f1073ae0b8b139" url: "https://pub.dev" source: hosted - version: "8.12.0" + version: "8.12.1" cached_network_image: dependency: transitive description: @@ -145,6 +145,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + camera: + dependency: transitive + description: + name: camera + sha256: eefad89f262a873f38d21e5eec853461737ea074d7c9ede39f3ceb135d201cab + url: "https://pub.dev" + source: hosted + version: "0.11.3" + camera_android_camerax: + dependency: transitive + description: + name: camera_android_camerax + sha256: "474d8355961658d43f1c976e2fa1ca715505bea1adbd56df34c581aaa70ec41f" + url: "https://pub.dev" + source: hosted + version: "0.6.26+2" + camera_avfoundation: + dependency: transitive + description: + name: camera_avfoundation + sha256: "035b90c1e33c2efad7548f402572078f6e514d4f82be0a315cd6c6af7e855aa8" + url: "https://pub.dev" + source: hosted + version: "0.9.22+6" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + sha256: "98cfc9357e04bad617671b4c1f78a597f25f08003089dd94050709ae54effc63" + url: "https://pub.dev" + source: hosted + version: "2.12.0" + camera_web: + dependency: transitive + description: + name: camera_web + sha256: "3bc7bb1657a0f29c34116453c5d5e528c23efcf5e75aac0a3387cf108040bf65" + url: "https://pub.dev" + source: hosted + version: "0.3.5+2" change_app_package_name: dependency: "direct dev" description: @@ -237,10 +277,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "942a4791cd385a68ccb3b32c71c427aba508a1bb949b86dff2adbe4049f16239" + sha256: "701dcfc06da0882883a2657c445103380e53e647060ad8d9dfb710c100996608" url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "0.3.5+1" crypto: dependency: transitive description: @@ -309,10 +349,10 @@ packages: dependency: transitive description: name: device_info_plus - sha256: dd0e8e02186b2196c7848c9d394a5fd6e5b57a43a546082c5820b1ec72317e33 + sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c" url: "https://pub.dev" source: hosted - version: "12.2.0" + version: "12.3.0" device_info_plus_platform_interface: dependency: transitive description: @@ -381,18 +421,18 @@ packages: dependency: transitive description: name: file_selector_linux - sha256: "80a877f5ec570c4fb3b40720a70b6f31e8bb1315a464b4d3e92fe82754d4b21a" + sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" url: "https://pub.dev" source: hosted - version: "0.9.3+3" + version: "0.9.4" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "44f24d102e368370951b98ffe86c7325b38349e634578312976607d28cc6d747" + sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" url: "https://pub.dev" source: hosted - version: "0.9.4+6" + version: "0.9.5" file_selector_platform_interface: dependency: transitive description: @@ -524,10 +564,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "306f0596590e077338312f38837f595c04f28d6cdeeac392d3d74df2f0003687" + sha256: ee8068e0e1cd16c4a82714119918efdeed33b3ba7772c54b5d094ab53f9b7fd1 url: "https://pub.dev" source: hosted - version: "2.0.32" + version: "2.0.33" flutter_rating_bar: dependency: transitive description: @@ -604,10 +644,10 @@ packages: dependency: transitive description: name: flutter_svg - sha256: "055de8921be7b8e8b98a233c7a5ef84b3a6fcc32f46f1ebf5b9bb3576d108355" + sha256: "87fbd7c534435b6c5d9d98b01e1fd527812b82e68ddd8bd35fc45ed0fa8f0a95" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.3" flutter_test: dependency: "direct dev" description: flutter @@ -691,10 +731,10 @@ packages: dependency: transitive description: name: get - sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 + sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a" url: "https://pub.dev" source: hosted - version: "4.7.2" + version: "4.7.3" get_it: dependency: transitive description: @@ -787,10 +827,10 @@ packages: dependency: transitive description: name: image - sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" + sha256: "51555e36056541237b15b57afc31a0f53d4f9aefd9bd00873a6dc0090e54e332" url: "https://pub.dev" source: hosted - version: "4.5.4" + version: "4.6.0" image_cropper: dependency: transitive description: @@ -827,26 +867,26 @@ packages: dependency: transitive description: name: image_picker_android - sha256: a1cd1584fae64f6ecca63113fd5450e3483c097cc05e43a2f073330f62adcabe + sha256: "5e9bf126c37c117cf8094215373c6d561117a3cfb50ebc5add1a61dc6e224677" url: "https://pub.dev" source: hosted - version: "0.8.13+8" + version: "0.8.13+10" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6" + sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: "997d100ce1dda5b1ba4085194c5e36c9f8a1fb7987f6a36ab677a344cd2dc986" + sha256: "956c16a42c0c708f914021666ffcd8265dde36e673c9fa68c81f7d085d9774ad" url: "https://pub.dev" source: hosted - version: "0.8.13+2" + version: "0.8.13+3" image_picker_linux: dependency: transitive description: @@ -936,10 +976,10 @@ packages: dependency: "direct dev" description: name: json_serializable - sha256: "33a040668b31b320aafa4822b7b1e177e163fc3c1e835c6750319d4ab23aa6fe" + sha256: c5b2ee75210a0f263c6c7b9eeea80553dbae96ea1bf57f02484e806a3ffdffa3 url: "https://pub.dev" source: hosted - version: "6.11.1" + version: "6.11.2" latlong2: dependency: transitive description: @@ -1056,10 +1096,10 @@ packages: dependency: transitive description: name: mockito - sha256: "4feb43bc4eb6c03e832f5fcd637d1abb44b98f9cfa245c58e27382f58859f8f6" + sha256: dac24d461418d363778d53198d9ac0510b9d073869f078450f195766ec48d05e url: "https://pub.dev" source: hosted - version: "5.5.1" + version: "5.6.1" mocktail: dependency: "direct dev" description: @@ -1160,18 +1200,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "95c68a74d3cab950fd0ed8073d9fab15c1c06eb1f3eec68676e87aabc9ecee5a" + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e url: "https://pub.dev" source: hosted - version: "2.2.21" + version: "2.2.22" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "97390a0719146c7c3e71b6866c34f1cde92685933165c1c671984390d2aca776" + sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4" url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "2.5.1" path_provider_linux: dependency: transitive description: @@ -1354,7 +1394,7 @@ packages: path: "packages/chicken" relative: true source: path - version: "1.3.20" + version: "1.8.0" rasadyar_core: dependency: "direct main" description: @@ -1412,18 +1452,18 @@ packages: dependency: transitive description: name: shared_preferences - sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "2.5.4" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "07d552dbe8e71ed720e5205e760438ff4ecfb76ec3b32ea664350e2ca4b0c43b" + sha256: "83af5c682796c0f7719c2bbf74792d113e40ae97981b8f266fa84574573556bc" url: "https://pub.dev" source: hosted - version: "2.4.16" + version: "2.4.18" shared_preferences_foundation: dependency: transitive description: @@ -1505,10 +1545,10 @@ packages: dependency: transitive description: name: source_gen - sha256: "9098ab86015c4f1d8af6486b547b11100e73b193e1899015033cb3e14ad20243" + sha256: "07b277b67e0096c45196cbddddf2d8c6ffc49342e88bf31d460ce04605ddac75" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.1" source_helper: dependency: transitive description: @@ -1633,10 +1673,10 @@ packages: dependency: transitive description: name: time - sha256: "370572cf5d1e58adcb3e354c47515da3f7469dac3a95b447117e728e7be6f461" + sha256: "46187cf30bffdab28c56be9a63861b36e4ab7347bf403297595d6a97e10c789f" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.6" typed_data: dependency: transitive description: @@ -1705,10 +1745,10 @@ packages: dependency: transitive description: name: watcher - sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a" + sha256: f52385d4f73589977c80797e60fe51014f7f2b957b5e9a62c3f6ada439889249 url: "https://pub.dev" source: hosted - version: "1.1.4" + version: "1.2.0" web: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f2adbe2..a0bc17e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,10 +1,10 @@ name: rasadyar_app description: "A new Flutter project." -publish_to: 'none' -version: 1.3.33+30 +publish_to: "none" +version: 1.3.41+37 environment: - sdk: ^3.9.2 + sdk: ^3.10.0 dependencies: flutter: @@ -26,7 +26,6 @@ dependencies: rasadyar_chicken: path: ./packages/chicken - ##code generation freezed_annotation: ^3.1.0 json_annotation: ^4.9.0 @@ -48,13 +47,9 @@ dev_dependencies: mocktail: ^1.0.4 get_test: ^4.0.1 - - - flutter: uses-material-design: true - assets: - assets/icons/ - assets/images/ @@ -62,13 +57,11 @@ flutter: - assets/vec/ - assets/anim/ - fonts: - family: yekan fonts: - asset: fonts/iranyekanregularfanum.ttf - flutter_gen: output: packages/core/lib/presentation/common line_length: 120 @@ -77,4 +70,3 @@ flutter_gen: image: true flutter_svg: true lottie: true -