feat: update poultry science feature with new data models and repository methods, enhance inspection submission process, and improve UI for better user experience

This commit is contained in:
2025-12-13 12:22:13 +03:30
parent b8a914ec0e
commit 0d47710e81
27 changed files with 4856 additions and 376 deletions

View File

@@ -1,5 +1,5 @@
sdk.dir=/Users/mojtaba/Library/Android/sdk sdk.dir=C:\\Users\\Housh11\\AppData\\Local\\Android\\sdk
flutter.sdk=/Users/mojtaba/develop/flutter flutter.sdk=C:\\src\\flutter
flutter.buildMode=debug flutter.buildMode=debug
flutter.versionName=1.3.35 flutter.versionName=1.3.35
flutter.versionCode=32 flutter.versionCode=32

View File

@@ -4,6 +4,7 @@ import 'package:rasadyar_chicken/features/poultry_science/data/model/response/ho
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/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/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/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/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/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/kill_request_poultry/kill_request_poultry.dart';
@@ -96,7 +97,7 @@ abstract class PoultryScienceRemoteDataSource {
required List<XFile> images, required List<XFile> images,
}); });
Future<PaginationModel<SubmitInspectionResponse>?> getSubmitInspectionList({ Future<PaginationModel<PoultryScienceReport>?> getSubmitInspectionList({
required String token, required String token,
Map<String, dynamic>? queryParameters, Map<String, dynamic>? queryParameters,
}); });

View File

@@ -4,6 +4,7 @@ import 'package:rasadyar_chicken/features/poultry_science/data/model/response/ho
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/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/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/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/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/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/kill_request_poultry/kill_request_poultry.dart';
@@ -263,7 +264,7 @@ class PoultryScienceRemoteDataSourceImpl
} }
@override @override
Future<PaginationModel<SubmitInspectionResponse>?> getSubmitInspectionList({ Future<PaginationModel<PoultryScienceReport>?> getSubmitInspectionList({
required String token, required String token,
Map<String, dynamic>? queryParameters, Map<String, dynamic>? queryParameters,
}) async { }) async {
@@ -271,10 +272,9 @@ class PoultryScienceRemoteDataSourceImpl
'/poultry_science_report/', '/poultry_science_report/',
headers: {'Authorization': 'Bearer $token'}, headers: {'Authorization': 'Bearer $token'},
queryParameters: queryParameters, queryParameters: queryParameters,
fromJson: (json) => PaginationModel<SubmitInspectionResponse>.fromJson( fromJson: (json) => PaginationModel<PoultryScienceReport>.fromJson(
json, json,
(json) => (json) => PoultryScienceReport.fromJson(json as Map<String, dynamic>),
SubmitInspectionResponse.fromJson(json as Map<String, dynamic>),
), ),
); );
return res.data; return res.data;

View File

@@ -4,7 +4,7 @@ part 'hatching_models.freezed.dart';
part 'hatching_models.g.dart'; part 'hatching_models.g.dart';
@freezed @freezed
abstract class HatchingModel with _$HatchingModel{ abstract class HatchingModel with _$HatchingModel {
const factory HatchingModel({ const factory HatchingModel({
int? id, int? id,
Poultry? poultry, Poultry? poultry,
@@ -94,6 +94,11 @@ abstract class HatchingModel with _$HatchingModel{
String? outputArchiver, String? outputArchiver,
num? barDifferenceRequestWeight, num? barDifferenceRequestWeight,
num? barDifferenceRequestQuantity, num? barDifferenceRequestQuantity,
num? totalDiseaseLosses,
num? totalFlockDestruction,
num? totalNormalFlockLosses,
num? totalForceMajeureLosses,
num? totalFireLosses,
String? healthCertificate, String? healthCertificate,
num? samasatDischargePercentage, num? samasatDischargePercentage,
String? personTypeName, String? personTypeName,
@@ -107,11 +112,13 @@ abstract class HatchingModel with _$HatchingModel{
String? tenantCity, String? tenantCity,
bool? hasTenant, bool? hasTenant,
String? archiveDate, String? archiveDate,
bool? unknown,
String? createdBy, String? createdBy,
String? modifiedBy, String? modifiedBy,
}) = _HatchingModel; }) = _HatchingModel;
factory HatchingModel.fromJson(Map<String, dynamic> json) => _$HatchingModelFromJson(json); factory HatchingModel.fromJson(Map<String, dynamic> json) =>
_$HatchingModelFromJson(json);
} }
@freezed @freezed
@@ -187,17 +194,16 @@ abstract class Poultry with _$Poultry {
int? wallet, int? wallet,
}) = _Poultry; }) = _Poultry;
factory Poultry.fromJson(Map<String, dynamic> json) => _$PoultryFromJson(json); factory Poultry.fromJson(Map<String, dynamic> json) =>
_$PoultryFromJson(json);
} }
@freezed @freezed
abstract class PoultryUser with _$PoultryUser { abstract class PoultryUser with _$PoultryUser {
const factory PoultryUser({ const factory PoultryUser({String? fullname, String? mobile}) = _PoultryUser;
String? fullname,
String? mobile,
}) = _PoultryUser;
factory PoultryUser.fromJson(Map<String, dynamic> json) => _$PoultryUserFromJson(json); factory PoultryUser.fromJson(Map<String, dynamic> json) =>
_$PoultryUserFromJson(json);
} }
@freezed @freezed
@@ -209,27 +215,24 @@ abstract class PoultryAddress with _$PoultryAddress {
String? postalCode, String? postalCode,
}) = _PoultryAddress; }) = _PoultryAddress;
factory PoultryAddress.fromJson(Map<String, dynamic> json) => _$PoultryAddressFromJson(json); factory PoultryAddress.fromJson(Map<String, dynamic> json) =>
_$PoultryAddressFromJson(json);
} }
@freezed @freezed
abstract class ProvinceRef with _$ProvinceRef { abstract class ProvinceRef with _$ProvinceRef {
const factory ProvinceRef({ const factory ProvinceRef({String? key, String? name}) = _ProvinceRef;
String? key,
String? name,
}) = _ProvinceRef;
factory ProvinceRef.fromJson(Map<String, dynamic> json) => _$ProvinceRefFromJson(json); factory ProvinceRef.fromJson(Map<String, dynamic> json) =>
_$ProvinceRefFromJson(json);
} }
@freezed @freezed
abstract class CityRef with _$CityRef { abstract class CityRef with _$CityRef {
const factory CityRef({ const factory CityRef({String? key, String? name}) = _CityRef;
String? key,
String? name,
}) = _CityRef;
factory CityRef.fromJson(Map<String, dynamic> json) => _$CityRefFromJson(json); factory CityRef.fromJson(Map<String, dynamic> json) =>
_$CityRefFromJson(json);
} }
@freezed @freezed
@@ -247,7 +250,8 @@ abstract class ChainCompany with _$ChainCompany {
num? wallet, num? wallet,
}) = _ChainCompany; }) = _ChainCompany;
factory ChainCompany.fromJson(Map<String, dynamic> json) => _$ChainCompanyFromJson(json); factory ChainCompany.fromJson(Map<String, dynamic> json) =>
_$ChainCompanyFromJson(json);
} }
@freezed @freezed
@@ -289,7 +293,8 @@ abstract class ChainUser with _$ChainUser {
String? unitAddress, String? unitAddress,
}) = _ChainUser; }) = _ChainUser;
factory ChainUser.fromJson(Map<String, dynamic> json) => _$ChainUserFromJson(json); factory ChainUser.fromJson(Map<String, dynamic> json) =>
_$ChainUserFromJson(json);
} }
@freezed @freezed
@@ -306,27 +311,26 @@ abstract class ChainUserState with _$ChainUserState {
String? nationalCode, String? nationalCode,
}) = _ChainUserState; }) = _ChainUserState;
factory ChainUserState.fromJson(Map<String, dynamic> json) => _$ChainUserStateFromJson(json); factory ChainUserState.fromJson(Map<String, dynamic> json) =>
_$ChainUserStateFromJson(json);
} }
@freezed @freezed
abstract class VetFarm with _$VetFarm { abstract class VetFarm with _$VetFarm {
const factory VetFarm({ const factory VetFarm({String? vetFarmFullName, String? vetFarmMobile}) =
String? vetFarmFullName, _VetFarm;
String? vetFarmMobile,
}) = _VetFarm;
factory VetFarm.fromJson(Map<String, dynamic> json) => _$VetFarmFromJson(json); factory VetFarm.fromJson(Map<String, dynamic> json) =>
_$VetFarmFromJson(json);
} }
@freezed @freezed
abstract class ActiveKill with _$ActiveKill { abstract class ActiveKill with _$ActiveKill {
const factory ActiveKill({ const factory ActiveKill({bool? activeKill, num? countOfRequest}) =
bool? activeKill, _ActiveKill;
num? countOfRequest,
}) = _ActiveKill;
factory ActiveKill.fromJson(Map<String, dynamic> json) => _$ActiveKillFromJson(json); factory ActiveKill.fromJson(Map<String, dynamic> json) =>
_$ActiveKillFromJson(json);
} }
@freezed @freezed
@@ -348,7 +352,8 @@ abstract class KillingInfo with _$KillingInfo {
num? wareHouseBarsWeightLose, num? wareHouseBarsWeightLose,
}) = _KillingInfo; }) = _KillingInfo;
factory KillingInfo.fromJson(Map<String, dynamic> json) => _$KillingInfoFromJson(json); factory KillingInfo.fromJson(Map<String, dynamic> json) =>
_$KillingInfoFromJson(json);
} }
@freezed @freezed
@@ -361,17 +366,16 @@ abstract class FreeGovernmentalInfo with _$FreeGovernmentalInfo {
num? leftTotalFreeCommitmentQuantity, num? leftTotalFreeCommitmentQuantity,
}) = _FreeGovernmentalInfo; }) = _FreeGovernmentalInfo;
factory FreeGovernmentalInfo.fromJson(Map<String, dynamic> json) => _$FreeGovernmentalInfoFromJson(json); factory FreeGovernmentalInfo.fromJson(Map<String, dynamic> json) =>
_$FreeGovernmentalInfoFromJson(json);
} }
@freezed @freezed
abstract class ReportInfo with _$ReportInfo { abstract class ReportInfo with _$ReportInfo {
const factory ReportInfo({ const factory ReportInfo({bool? poultryScience, bool? image}) = _ReportInfo;
bool? poultryScience,
bool? image,
}) = _ReportInfo;
factory ReportInfo.fromJson(Map<String, dynamic> json) => _$ReportInfoFromJson(json); factory ReportInfo.fromJson(Map<String, dynamic> json) =>
_$ReportInfoFromJson(json);
} }
@freezed @freezed
@@ -382,18 +386,17 @@ abstract class LatestHatchingChange with _$LatestHatchingChange {
String? fullName, String? fullName,
}) = _LatestHatchingChange; }) = _LatestHatchingChange;
factory LatestHatchingChange.fromJson(Map<String, dynamic> json) => _$LatestHatchingChangeFromJson(json); factory LatestHatchingChange.fromJson(Map<String, dynamic> json) =>
_$LatestHatchingChangeFromJson(json);
} }
@freezed @freezed
abstract class Registrar with _$Registrar { abstract class Registrar with _$Registrar {
const factory Registrar({ const factory Registrar({String? date, String? role, String? fullname}) =
String? date, _Registrar;
String? role,
String? fullname,
}) = _Registrar;
factory Registrar.fromJson(Map<String, dynamic> json) => _$RegistrarFromJson(json); factory Registrar.fromJson(Map<String, dynamic> json) =>
_$RegistrarFromJson(json);
} }
@freezed @freezed
@@ -405,7 +408,8 @@ abstract class LastChange with _$LastChange {
String? fullName, String? fullName,
}) = _LastChange; }) = _LastChange;
factory LastChange.fromJson(Map<String, dynamic> json) => _$LastChangeFromJson(json); factory LastChange.fromJson(Map<String, dynamic> json) =>
_$LastChangeFromJson(json);
} }
@freezed @freezed
@@ -416,6 +420,6 @@ abstract class BreedItem with _$BreedItem {
num? remainQuantity, num? remainQuantity,
}) = _BreedItem; }) = _BreedItem;
factory BreedItem.fromJson(Map<String, dynamic> json) => _$BreedItemFromJson(json); factory BreedItem.fromJson(Map<String, dynamic> json) =>
_$BreedItemFromJson(json);
} }

View File

@@ -126,6 +126,11 @@ _HatchingModel _$HatchingModelFromJson(
outputArchiver: json['output_archiver'] as String?, outputArchiver: json['output_archiver'] as String?,
barDifferenceRequestWeight: json['bar_difference_request_weight'] as num?, barDifferenceRequestWeight: json['bar_difference_request_weight'] as num?,
barDifferenceRequestQuantity: json['bar_difference_request_quantity'] 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?, healthCertificate: json['health_certificate'] as String?,
samasatDischargePercentage: json['samasat_discharge_percentage'] as num?, samasatDischargePercentage: json['samasat_discharge_percentage'] as num?,
personTypeName: json['person_type_name'] as String?, personTypeName: json['person_type_name'] as String?,
@@ -139,6 +144,7 @@ _HatchingModel _$HatchingModelFromJson(
tenantCity: json['tenant_city'] as String?, tenantCity: json['tenant_city'] as String?,
hasTenant: json['has_tenant'] as bool?, hasTenant: json['has_tenant'] as bool?,
archiveDate: json['archive_date'] as String?, archiveDate: json['archive_date'] as String?,
unknown: json['unknown'] as bool?,
createdBy: json['created_by'] as String?, createdBy: json['created_by'] as String?,
modifiedBy: json['modified_by'] as String?, modifiedBy: json['modified_by'] as String?,
); );
@@ -233,6 +239,11 @@ Map<String, dynamic> _$HatchingModelToJson(_HatchingModel instance) =>
'output_archiver': instance.outputArchiver, 'output_archiver': instance.outputArchiver,
'bar_difference_request_weight': instance.barDifferenceRequestWeight, 'bar_difference_request_weight': instance.barDifferenceRequestWeight,
'bar_difference_request_quantity': instance.barDifferenceRequestQuantity, '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, 'health_certificate': instance.healthCertificate,
'samasat_discharge_percentage': instance.samasatDischargePercentage, 'samasat_discharge_percentage': instance.samasatDischargePercentage,
'person_type_name': instance.personTypeName, 'person_type_name': instance.personTypeName,
@@ -246,6 +257,7 @@ Map<String, dynamic> _$HatchingModelToJson(_HatchingModel instance) =>
'tenant_city': instance.tenantCity, 'tenant_city': instance.tenantCity,
'has_tenant': instance.hasTenant, 'has_tenant': instance.hasTenant,
'archive_date': instance.archiveDate, 'archive_date': instance.archiveDate,
'unknown': instance.unknown,
'created_by': instance.createdBy, 'created_by': instance.createdBy,
'modified_by': instance.modifiedBy, 'modified_by': instance.modifiedBy,
}; };

View File

@@ -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<String, dynamic> 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<int>? poultry,
}) = _PoultryScienceRef;
factory PoultryScienceRef.fromJson(Map<String, dynamic> json) =>
_$PoultryScienceRefFromJson(json);
}
@freezed
abstract class UserRef with _$UserRef {
const factory UserRef({String? fullname, String? mobile, CityRef? city}) =
_UserRef;
factory UserRef.fromJson(Map<String, dynamic> json) =>
_$UserRefFromJson(json);
}
@freezed
abstract class UserWithCity with _$UserWithCity {
const factory UserWithCity({
String? fullname,
String? mobile,
CityRef? city,
}) = _UserWithCity;
factory UserWithCity.fromJson(Map<String, dynamic> 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<String, dynamic> 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<String, dynamic> json) => _$HrInfoFromJson(json);
}
@freezed
abstract class Casualties with _$Casualties {
const factory Casualties({
List<String>? images,
String? typeDisease,
num? normalLosses,
bool? samplingDone,
String? typeSampling,
num? abnormalLosses,
String? sourceOfHatching,
String? causeAbnormalLosses,
}) = _Casualties;
factory Casualties.fromJson(Map<String, dynamic> 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<String, dynamic> json) =>
_$FacilitiesFromJson(json);
}
@freezed
abstract class InputStatus with _$InputStatus {
const factory InputStatus({
List<String>? images,
String? gradeGrain,
String? companyName,
String? inputStatus,
String? trackingCode,
String? typeOfGrain,
String? inventoryUntilVisit,
String? inventoryInWarehouse,
}) = _InputStatus;
factory InputStatus.fromJson(Map<String, dynamic> json) =>
_$InputStatusFromJson(json);
}
@freezed
abstract class TechnicalOfficer with _$TechnicalOfficer {
const factory TechnicalOfficer({
String? technicalHealthOfficer,
String? technicalEngineeringOfficer,
}) = _TechnicalOfficer;
factory TechnicalOfficer.fromJson(Map<String, dynamic> 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<String, dynamic> json) =>
_$InfrastructureEnergyFromJson(json);
}
@freezed
abstract class GeneralConditionHall with _$GeneralConditionHall {
const factory GeneralConditionHall({
List<String>? images,
String? temperature,
String? bedCondition,
String? healthStatus,
String? ventilationStatus,
String? drinkingWaterSource,
String? drinkingWaterQuality,
}) = _GeneralConditionHall;
factory GeneralConditionHall.fromJson(Map<String, dynamic> json) =>
_$GeneralConditionHallFromJson(json);
}

View File

@@ -0,0 +1,339 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'poultry_science_report.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_PoultryScienceReport _$PoultryScienceReportFromJson(
Map<String, dynamic> json,
) => _PoultryScienceReport(
id: (json['id'] as num?)?.toInt(),
poultryScience: json['poultry_science'] == null
? null
: PoultryScienceRef.fromJson(
json['poultry_science'] as Map<String, dynamic>,
),
hatching: json['hatching'] == null
? null
: HatchingModel.fromJson(json['hatching'] as Map<String, dynamic>),
user: json['user'] == null
? null
: UserRef.fromJson(json['user'] as Map<String, dynamic>),
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<String, dynamic>,
),
createdBy: json['created_by'] as String?,
modifiedBy: json['modified_by'] as String?,
);
Map<String, dynamic> _$PoultryScienceReportToJson(
_PoultryScienceReport instance,
) => <String, dynamic>{
'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<String, dynamic> json) =>
_PoultryScienceRef(
id: (json['id'] as num?)?.toInt(),
user: json['user'] == null
? null
: UserWithCity.fromJson(json['user'] as Map<String, dynamic>),
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<dynamic>?)
?.map((e) => (e as num).toInt())
.toList(),
);
Map<String, dynamic> _$PoultryScienceRefToJson(_PoultryScienceRef instance) =>
<String, dynamic>{
'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<String, dynamic> json) => _UserRef(
fullname: json['fullname'] as String?,
mobile: json['mobile'] as String?,
city: json['city'] == null
? null
: CityRef.fromJson(json['city'] as Map<String, dynamic>),
);
Map<String, dynamic> _$UserRefToJson(_UserRef instance) => <String, dynamic>{
'fullname': instance.fullname,
'mobile': instance.mobile,
'city': instance.city,
};
_UserWithCity _$UserWithCityFromJson(Map<String, dynamic> json) =>
_UserWithCity(
fullname: json['fullname'] as String?,
mobile: json['mobile'] as String?,
city: json['city'] == null
? null
: CityRef.fromJson(json['city'] as Map<String, dynamic>),
);
Map<String, dynamic> _$UserWithCityToJson(_UserWithCity instance) =>
<String, dynamic>{
'fullname': instance.fullname,
'mobile': instance.mobile,
'city': instance.city,
};
_ReportInformation _$ReportInformationFromJson(Map<String, dynamic> json) =>
_ReportInformation(
hr: json['hr'] == null
? null
: HrInfo.fromJson(json['hr'] as Map<String, dynamic>),
casualties: json['casualties'] == null
? null
: Casualties.fromJson(json['casualties'] as Map<String, dynamic>),
facilities: json['facilities'] == null
? null
: Facilities.fromJson(json['facilities'] as Map<String, dynamic>),
inputStatus: json['input_status'] == null
? null
: InputStatus.fromJson(json['input_status'] as Map<String, dynamic>),
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<String, dynamic>,
),
infrastructureEnergy: json['infrastructure_energy'] == null
? null
: InfrastructureEnergy.fromJson(
json['infrastructure_energy'] as Map<String, dynamic>,
),
generalConditionHall: json['general_condition_hall'] == null
? null
: GeneralConditionHall.fromJson(
json['general_condition_hall'] as Map<String, dynamic>,
),
);
Map<String, dynamic> _$ReportInformationToJson(_ReportInformation instance) =>
<String, dynamic>{
'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<String, dynamic> 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<String, dynamic> _$HrInfoToJson(_HrInfo instance) => <String, dynamic>{
'trained': instance.trained,
'contract_status': instance.contractStatus,
'number_employed': instance.numberEmployed,
'number_indigenous': instance.numberIndigenous,
'number_non_indigenous': instance.numberNonIndigenous,
};
_Casualties _$CasualtiesFromJson(Map<String, dynamic> json) => _Casualties(
images: (json['images'] as List<dynamic>?)?.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<String, dynamic> _$CasualtiesToJson(_Casualties instance) =>
<String, dynamic>{
'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<String, dynamic> 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<String, dynamic> _$FacilitiesToJson(_Facilities instance) =>
<String, dynamic>{
'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<String, dynamic> json) => _InputStatus(
images: (json['images'] as List<dynamic>?)?.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<String, dynamic> _$InputStatusToJson(_InputStatus instance) =>
<String, dynamic>{
'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<String, dynamic> json) =>
_TechnicalOfficer(
technicalHealthOfficer: json['technical_health_officer'] as String?,
technicalEngineeringOfficer:
json['technical_engineering_officer'] as String?,
);
Map<String, dynamic> _$TechnicalOfficerToJson(_TechnicalOfficer instance) =>
<String, dynamic>{
'technical_health_officer': instance.technicalHealthOfficer,
'technical_engineering_officer': instance.technicalEngineeringOfficer,
};
_InfrastructureEnergy _$InfrastructureEnergyFromJson(
Map<String, dynamic> 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<String, dynamic> _$InfrastructureEnergyToJson(
_InfrastructureEnergy instance,
) => <String, dynamic>{
'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<String, dynamic> json,
) => _GeneralConditionHall(
images: (json['images'] as List<dynamic>?)?.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<String, dynamic> _$GeneralConditionHallToJson(
_GeneralConditionHall instance,
) => <String, dynamic>{
'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,
};

View File

@@ -4,6 +4,7 @@ import 'package:rasadyar_chicken/features/poultry_science/data/model/response/ho
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/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/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/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/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/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/kill_request_poultry/kill_request_poultry.dart';
@@ -96,7 +97,7 @@ abstract class PoultryScienceRepository {
required List<XFile> images, required List<XFile> images,
}); });
Future<PaginationModel<SubmitInspectionResponse>?> getSubmitInspectionList({ Future<PaginationModel<PoultryScienceReport>?> getSubmitInspectionList({
required String token, required String token,
Map<String, dynamic>? queryParameters, Map<String, dynamic>? queryParameters,
}); });

View File

@@ -4,6 +4,7 @@ import 'package:rasadyar_chicken/features/poultry_science/data/model/response/ho
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/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/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/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/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/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/kill_request_poultry/kill_request_poultry.dart';
@@ -191,7 +192,7 @@ class PoultryScienceRepositoryImpl implements PoultryScienceRepository {
} }
@override @override
Future<PaginationModel<SubmitInspectionResponse>?> getSubmitInspectionList({ Future<PaginationModel<PoultryScienceReport>?> getSubmitInspectionList({
required String token, required String token,
Map<String, dynamic>? queryParameters, Map<String, dynamic>? queryParameters,
}) async { }) async {

View File

@@ -15,7 +15,7 @@ class ActiveHatchingPage extends GetView<ActiveHatchingLogic> {
return ChickenBasePage( return ChickenBasePage(
hasSearch: true, hasSearch: true,
hasFilter: false, hasFilter: false,
backId: poultryFirstKey, backId: poultryScienceActionKey,
routes: controller.routesName, routes: controller.routesName,
onSearchChanged: (data) { onSearchChanged: (data) {
controller.searchedValue.value = data; controller.searchedValue.value = data;

View File

@@ -28,7 +28,7 @@ class FarmPage extends GetView<FarmLogic> {
controller.getFarmList(); controller.getFarmList();
}, },
routes: controller.routes, routes: controller.routes,
backId: poultryFirstKey, backId: poultryScienceActionKey,
child: Column(children: [firstTagInformation(), farmListWidget()]), child: Column(children: [firstTagInformation(), farmListWidget()]),
); );
} }
@@ -76,7 +76,6 @@ class FarmPage extends GetView<FarmLogic> {
itemCount: data.value.data?.results?.length ?? 0, itemCount: data.value.data?.results?.length ?? 0,
separatorBuilder: (context, index) => SizedBox(height: 8.h), separatorBuilder: (context, index) => SizedBox(height: 8.h),
onLoadMore: () async => controller.getFarmList(true), onLoadMore: () async => controller.getFarmList(true),
); );
}, controller.farmList), }, controller.farmList),
); );
@@ -85,7 +84,10 @@ class FarmPage extends GetView<FarmLogic> {
Container itemListExpandedWidget(PoultryFarm item) { Container itemListExpandedWidget(PoultryFarm item) {
return Container( return Container(
padding: EdgeInsets.symmetric(horizontal: 8), 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( child: Column(
spacing: 8, spacing: 8,
children: [ children: [
@@ -134,10 +136,19 @@ class FarmPage extends GetView<FarmLogic> {
), ),
), ),
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.breedingUniqueId ?? 'N/A'),
buildRow(title: 'کد اپیدمیولوژیک', value: item.epidemiologicalCode ?? 'N/A'), buildRow(
buildRow(title: 'کد بهداشتی', value: item.healthCertificateNumber ?? 'N/A'), title: 'کد اپیدمیولوژیک',
value: item.epidemiologicalCode ?? 'N/A',
),
buildRow(
title: 'کد بهداشتی',
value: item.healthCertificateNumber ?? 'N/A',
),
buildRow( buildRow(
title: 'دامپزشک فارم', title: 'دامپزشک فارم',
value: '${item.vetFarm?.fullName} (${item.vetFarm?.mobile ?? '-'})', value: '${item.vetFarm?.fullName} (${item.vetFarm?.mobile ?? '-'})',

View File

@@ -23,7 +23,7 @@ class GenocidePage extends GetView<GenocideLogic> {
controller.searchedValue.value = data; controller.searchedValue.value = data;
controller.getPoultryOrderList(); controller.getPoultryOrderList();
}, },
backId: poultryFirstKey, backId: poultryScienceActionKey,
onFilterTap: () { onFilterTap: () {
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true, isScrollControlled: true,

View File

@@ -23,7 +23,7 @@ class InspectionPoultrySciencePage extends GetView<InspectionPoultryScienceLogic
}, },
onRefresh: controller.onRefresh, onRefresh: controller.onRefresh,
onSearchChanged: (data) => controller.setSearchValue(data), onSearchChanged: (data) => controller.setSearchValue(data),
backId: poultryFirstKey, backId: poultryScienceActionKey,
routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName),
child: Column( child: Column(
children: [ children: [

View File

@@ -1,13 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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/poultry_science_report/poultry_science_report.dart';
import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart'; import 'package:rasadyar_chicken/features/poultry_science/presentation/pages/root/logic.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
class NewInspectionPoultryScienceLogic extends GetxController { class NewInspectionPoultryScienceLogic extends GetxController {
BaseLogic baseLogic = Get.find<BaseLogic>(); BaseLogic baseLogic = Get.find<BaseLogic>();
Rx<Resource<PaginationModel<SubmitInspectionResponse>>> submitInspectionList = Rx<Resource<PaginationModel<PoultryScienceReport>>> submitInspectionList =
Resource<PaginationModel<SubmitInspectionResponse>>.loading().obs; Resource<PaginationModel<PoultryScienceReport>>.loading().obs;
PoultryScienceRootLogic rootLogic = Get.find<PoultryScienceRootLogic>(); PoultryScienceRootLogic rootLogic = Get.find<PoultryScienceRootLogic>();
@@ -57,7 +57,7 @@ class NewInspectionPoultryScienceLogic extends GetxController {
isLoadingMoreAllocationsMade.value = true; isLoadingMoreAllocationsMade.value = true;
} else { } else {
submitInspectionList.value = submitInspectionList.value =
Resource<PaginationModel<SubmitInspectionResponse>>.loading(); Resource<PaginationModel<PoultryScienceReport>>.loading();
} }
if (searchedValue.value != null && if (searchedValue.value != null &&
@@ -74,18 +74,18 @@ class NewInspectionPoultryScienceLogic extends GetxController {
role: 'PoultryScience', role: 'PoultryScience',
pageSize: 50, pageSize: 50,
search: 'filter', search: 'filter',
page: currentPage.value, page: currentPage.value,
), ),
), ),
onSuccess: (res) { onSuccess: (res) {
if ((res?.count ?? 0) == 0) { if ((res?.count ?? 0) == 0) {
submitInspectionList.value = submitInspectionList.value =
Resource<PaginationModel<SubmitInspectionResponse>>.empty(); Resource<PaginationModel<PoultryScienceReport>>.empty();
} else { } else {
submitInspectionList.value = submitInspectionList.value =
Resource<PaginationModel<SubmitInspectionResponse>>.success( Resource<PaginationModel<PoultryScienceReport>>.success(
PaginationModel<SubmitInspectionResponse>( PaginationModel<PoultryScienceReport>(
count: res?.count ?? 0, count: res?.count ?? 0,
next: res?.next, next: res?.next,
previous: res?.previous, previous: res?.previous,
@@ -140,15 +140,17 @@ class NewInspectionPoultryScienceLogic extends GetxController {
await getReport(); await getReport();
} }
String getStatus(SubmitInspectionResponse item) { String getStatus(PoultryScienceReport item) {
if (item.inspectionStatus == null || item.inspectionStatus!.isEmpty) { final status = item.reportInformation?.inspectionStatus ?? item.state;
if (status == null || status.isEmpty) {
return 'در حال بررسی'; return 'در حال بررسی';
} }
return item.inspectionStatus!; return status;
} }
Color getStatusColor(SubmitInspectionResponse item) { Color getStatusColor(PoultryScienceReport item) {
if (item.inspectionStatus == null || item.inspectionStatus!.isEmpty) { final status = item.reportInformation?.inspectionStatus ?? item.state;
if (status == null || status.isEmpty) {
return AppColor.yellowNormal; return AppColor.yellowNormal;
} }
// می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید // می‌توانید منطق رنگ را بر اساس inspectionStatus تنظیم کنید

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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/poultry_science_report/poultry_science_report.dart';
import 'package:rasadyar_chicken/presentation/utils/nested_keys_utils.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/base_page/view.dart';
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
@@ -21,7 +21,7 @@ class NewInspectionPoultrySciencePage
}, },
onRefresh: controller.onRefresh, onRefresh: controller.onRefresh,
onSearchChanged: (data) => controller.setSearchValue(data), onSearchChanged: (data) => controller.setSearchValue(data),
backId: poultryFirstKey, backId: poultryScienceActionKey,
routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName), routesWidget: ContainerBreadcrumb(rxRoutes: controller.routesName),
child: Column(children: [reportWidget()]), child: Column(children: [reportWidget()]),
); );
@@ -57,7 +57,7 @@ class NewInspectionPoultrySciencePage
); );
} }
Widget itemListExpandedWidgetReport(SubmitInspectionResponse item) { Widget itemListExpandedWidgetReport(PoultryScienceReport item) {
return Container( return Container(
padding: EdgeInsets.symmetric(horizontal: 8), padding: EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -77,42 +77,66 @@ class NewInspectionPoultrySciencePage
color: controller.getStatusColor(item), color: controller.getStatusColor(item),
), ),
), ),
if (item.poultryHatchingId != null) if (item.hatching?.poultry?.unitName != null)
buildRow(
title: 'مرغداری',
value: item.hatching?.poultry?.unitName ?? '-',
),
if (item.hatching?.id != null)
buildRow( buildRow(
title: 'شناسه جوجه‌ریزی', title: 'شناسه جوجه‌ریزی',
value: item.poultryHatchingId.toString(), value: item.hatching!.id.toString(),
), ),
if (item.role != null)
buildRow(title: 'نقش', value: item.role ?? '-'), if (item
if (item.technicalOfficer?.technicalHealthOfficer != null) .reportInformation
?.technicalOfficer
?.technicalHealthOfficer !=
null)
buildRow( buildRow(
title: 'کارشناس بهداشت', title: 'کارشناس بهداشت',
value: item.technicalOfficer!.technicalHealthOfficer ?? '-', value:
item
.reportInformation!
.technicalOfficer!
.technicalHealthOfficer ??
'-',
), ),
if (item.technicalOfficer?.technicalEngineeringOfficer != null) if (item
.reportInformation
?.technicalOfficer
?.technicalEngineeringOfficer !=
null)
buildRow( buildRow(
title: 'کارشناس فنی', title: 'کارشناس فنی',
value: item.technicalOfficer!.technicalEngineeringOfficer ?? '-', value:
item
.reportInformation!
.technicalOfficer!
.technicalEngineeringOfficer ??
'-',
), ),
if (item.casualties?.normalLosses != null || if (item.reportInformation?.casualties?.normalLosses != null ||
item.casualties?.abnormalLosses != null) item.reportInformation?.casualties?.abnormalLosses != null)
buildUnitRow( buildUnitRow(
title: 'تلفات عادی', title: 'تلفات عادی',
value: (item.casualties?.normalLosses ?? 0).toString(), value: (item.reportInformation?.casualties?.normalLosses ?? 0)
.toString(),
unit: '(قطعه)', unit: '(قطعه)',
), ),
if (item.casualties?.abnormalLosses != null) if (item.reportInformation?.casualties?.abnormalLosses != null)
buildUnitRow( buildUnitRow(
title: 'تلفات غیرعادی', title: 'تلفات غیرعادی',
value: item.casualties!.abnormalLosses.toString(), value: item.reportInformation!.casualties!.abnormalLosses
.toString(),
unit: '(قطعه)', unit: '(قطعه)',
), ),
if (item.lat != null && item.log != null)
buildRow(title: 'موقعیت', value: '${item.lat}, ${item.log}'), if (item.reportInformation?.inspectionNotes != null &&
if (item.inspectionNotes != null && item.inspectionNotes!.isNotEmpty) item.reportInformation!.inspectionNotes!.isNotEmpty)
buildRow( buildRow(
title: 'یادداشت بازرسی', title: 'یادداشت بازرسی',
value: item.inspectionNotes ?? '-', value: item.reportInformation!.inspectionNotes ?? '-',
), ),
RElevated( RElevated(
@@ -124,14 +148,14 @@ class NewInspectionPoultrySciencePage
showDetailsBottomSheet(item); showDetailsBottomSheet(item);
}, },
textStyle: AppFonts.yekan16.copyWith(color: Colors.white), textStyle: AppFonts.yekan16.copyWith(color: Colors.white),
backgroundColor: AppColor.blueNormal, backgroundColor: AppColor.greenNormal,
), ),
], ],
), ),
); );
} }
Row itemListWidgetReport(SubmitInspectionResponse item) { Row itemListWidgetReport(PoultryScienceReport item) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
@@ -144,16 +168,14 @@ class NewInspectionPoultrySciencePage
spacing: 5, spacing: 5,
children: [ children: [
Text( Text(
item.role ?? 'نقش نامشخص', 'شناسه جوجه‌ریزی: ${item.hatching?.id ?? '-'}',
textAlign: TextAlign.start, textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
), ),
Text( Text(
controller.getStatus(item), item.createDate?.toJalali.formatCompactDate() ?? '-',
textAlign: TextAlign.start, style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon),
style: AppFonts.yekan14.copyWith(
color: controller.getStatusColor(item),
),
), ),
], ],
), ),
@@ -166,39 +188,26 @@ class NewInspectionPoultrySciencePage
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text( Text(
'شناسه جوجه‌ریزی: ${item.poultryHatchingId ?? 'N/A'}', 'مرغداری: ${item.hatching?.poultry?.unitName ?? '-'}',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal), style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
), ),
if (item.technicalOfficer?.technicalHealthOfficer != null) if (item.reportInformation?.inspectionStatus != null)
Text( Text(
'کارشناس: ${item.technicalOfficer!.technicalHealthOfficer}', 'وضعیت بازرسی: ${item.reportInformation?.inspectionStatus ?? '-'}',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.bgDark), style: AppFonts.yekan12.copyWith(color: AppColor.bgIcon),
)
else
Text(
item.inspectionStatus ?? 'وضعیت نامشخص',
textAlign: TextAlign.center,
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),
),
),
], ],
); );
} }
void showDetailsBottomSheet(SubmitInspectionResponse item) { void showDetailsBottomSheet(PoultryScienceReport item) {
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true,
BaseBottomSheet( BaseBottomSheet(
height: Get.height * 0.8, height: Get.height * 0.8,
rootChild: DetailsBottomSheetWidget(item: item), rootChild: DetailsBottomSheetWidget(item: item),
@@ -252,7 +261,7 @@ class NewInspectionPoultrySciencePage
} }
class DetailsBottomSheetWidget extends StatefulWidget { class DetailsBottomSheetWidget extends StatefulWidget {
final SubmitInspectionResponse item; final PoultryScienceReport item;
const DetailsBottomSheetWidget({super.key, required this.item}); const DetailsBottomSheetWidget({super.key, required this.item});
@@ -344,7 +353,7 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
} }
Widget technicalOfficerTable() { Widget technicalOfficerTable() {
final officer = widget.item.technicalOfficer; final officer = widget.item.reportInformation?.technicalOfficer;
if (officer == null) { if (officer == null) {
return Center( return Center(
child: Padding( child: Padding(
@@ -415,22 +424,25 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
children: [ children: [
rTableRow( rTableRow(
title: 'وضعیت بازرسی', title: 'وضعیت بازرسی',
value: widget.item.inspectionStatus ?? '-', value:
widget.item.reportInformation?.inspectionStatus ??
widget.item.state ??
'-',
), ),
rTableRow( rTableRow(
title: 'یادداشت بازرسی', title: 'یادداشت بازرسی',
value: widget.item.inspectionNotes ?? '-', value: widget.item.reportInformation?.inspectionNotes ?? '-',
), ),
rTableRow(title: 'نقش', value: widget.item.role ?? '-'), rTableRow(title: 'نقش', value: widget.item.reporterRole ?? '-'),
if (widget.item.lat != null && widget.item.log != null) if (widget.item.lat != null && widget.item.log != null)
rTableRow( rTableRow(
title: 'موقعیت', title: 'موقعیت',
value: '${widget.item.lat}, ${widget.item.log}', value: '${widget.item.lat}, ${widget.item.log}',
), ),
if (widget.item.poultryHatchingId != null) if (widget.item.hatching?.id != null)
rTableRow( rTableRow(
title: 'شناسه جوجه ریزی', title: 'شناسه جوجه ریزی',
value: widget.item.poultryHatchingId.toString(), value: widget.item.hatching!.id.toString(),
), ),
], ],
), ),
@@ -440,7 +452,7 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
} }
Widget generalConditionHallTable() { Widget generalConditionHallTable() {
final hall = widget.item.generalConditionHall; final hall = widget.item.reportInformation?.generalConditionHall;
if (hall == null) { if (hall == null) {
return Center( return Center(
child: Padding( child: Padding(
@@ -504,14 +516,17 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: hall.images!.length, itemCount: hall.images!.length,
separatorBuilder: (context, index) => SizedBox(width: 10), separatorBuilder: (context, index) => SizedBox(width: 10),
itemBuilder: (context, index) => Container( itemBuilder: (context, index) => GestureDetector(
width: 80.w, onTap: () => showImageDialog(hall.images!, index),
height: 80.h, child: Container(
decoration: BoxDecoration( width: 80.w,
borderRadius: BorderRadius.circular(8), height: 80.h,
image: DecorationImage( decoration: BoxDecoration(
fit: BoxFit.cover, borderRadius: BorderRadius.circular(8),
image: NetworkImage(hall.images![index]), image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(hall.images![index]),
),
), ),
), ),
), ),
@@ -523,7 +538,7 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
} }
Widget casualtiesTable() { Widget casualtiesTable() {
final casualties = widget.item.casualties; final casualties = widget.item.reportInformation?.casualties;
if (casualties == null) { if (casualties == null) {
return Center( return Center(
child: Padding( child: Padding(
@@ -602,14 +617,17 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: casualties.images!.length, itemCount: casualties.images!.length,
separatorBuilder: (context, index) => SizedBox(width: 10), separatorBuilder: (context, index) => SizedBox(width: 10),
itemBuilder: (context, index) => Container( itemBuilder: (context, index) => GestureDetector(
width: 80.w, onTap: () => showImageDialog(casualties.images!, index),
height: 80.h, child: Container(
decoration: BoxDecoration( width: 80.w,
borderRadius: BorderRadius.circular(8), height: 80.h,
image: DecorationImage( decoration: BoxDecoration(
fit: BoxFit.cover, borderRadius: BorderRadius.circular(8),
image: NetworkImage(casualties.images![index]), image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(casualties.images![index]),
),
), ),
), ),
), ),
@@ -621,7 +639,7 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
} }
Widget inputStatusTable() { Widget inputStatusTable() {
final inputStatus = widget.item.inputStatus; final inputStatus = widget.item.reportInformation?.inputStatus;
if (inputStatus == null) { if (inputStatus == null) {
return Center( return Center(
child: Padding( child: Padding(
@@ -698,14 +716,17 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: inputStatus.images!.length, itemCount: inputStatus.images!.length,
separatorBuilder: (context, index) => SizedBox(width: 10), separatorBuilder: (context, index) => SizedBox(width: 10),
itemBuilder: (context, index) => Container( itemBuilder: (context, index) => GestureDetector(
width: 80.w, onTap: () => showImageDialog(inputStatus.images!, index),
height: 80.h, child: Container(
decoration: BoxDecoration( width: 80.w,
borderRadius: BorderRadius.circular(8), height: 80.h,
image: DecorationImage( decoration: BoxDecoration(
fit: BoxFit.cover, borderRadius: BorderRadius.circular(8),
image: NetworkImage(inputStatus.images![index]), image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(inputStatus.images![index]),
),
), ),
), ),
), ),
@@ -717,7 +738,7 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
} }
Widget infrastructureEnergyTable() { Widget infrastructureEnergyTable() {
final infra = widget.item.infrastructureEnergy; final infra = widget.item.reportInformation?.infrastructureEnergy;
if (infra == null) { if (infra == null) {
return Center( return Center(
child: Padding( child: Padding(
@@ -801,7 +822,7 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
} }
Widget hrTable() { Widget hrTable() {
final hr = widget.item.hr; final hr = widget.item.reportInformation?.hr;
if (hr == null) { if (hr == null) {
return Center( return Center(
child: Padding( child: Padding(
@@ -865,7 +886,7 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
} }
Widget facilitiesTable() { Widget facilitiesTable() {
final facilities = widget.item.facilities; final facilities = widget.item.reportInformation?.facilities;
if (facilities == null) { if (facilities == null) {
return Center( return Center(
child: Padding( child: Padding(
@@ -930,64 +951,49 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
Function(int) onTabSelected, Function(int) onTabSelected,
) { ) {
return SizedBox( return SizedBox(
height: 38.h, height: 40.h,
width: Get.width, width: Get.width,
child: Stack( child: Column(
fit: StackFit.expand,
children: [ children: [
Positioned( SingleChildScrollView(
right: 0, scrollDirection: Axis.horizontal,
top: 0, reverse: true,
bottom: 0, child: Row(
child: SingleChildScrollView( children: [
scrollDirection: Axis.horizontal, ...tabs.map(
reverse: true, (tab) => GestureDetector(
child: Row( onTap: () => onTabSelected(tabs.indexOf(tab)),
children: [ behavior: HitTestBehavior.opaque,
...tabs.map( child: Container(
(tab) => GestureDetector( padding: EdgeInsets.symmetric(
onTap: () => onTabSelected(tabs.indexOf(tab)), horizontal: 10,
behavior: HitTestBehavior.opaque, vertical: 11,
child: Container( ),
padding: EdgeInsets.symmetric( decoration: BoxDecoration(
horizontal: 10, border: tab == tabs[selectedIndex]
vertical: 11, ? Border(
), bottom: BorderSide(
decoration: BoxDecoration( color: AppColor.blueNormalOld,
border: tab == tabs[selectedIndex] width: 3,
? Border( ),
bottom: BorderSide( )
color: AppColor.blueNormalOld, : null,
width: 3, ),
), child: Text(
) tab,
: null, style: AppFonts.yekan12Bold.copyWith(
), color: tab == tabs[selectedIndex]
child: Text( ? AppColor.blueNormalOld
tab, : AppColor.mediumGrey,
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,
), ),
), ),
Divider(color: AppColor.blackLightHover, height: 1, thickness: 1),
], ],
), ),
); );
@@ -1032,4 +1038,98 @@ class _DetailsBottomSheetWidgetState extends State<DetailsBottomSheetWidget> {
], ],
); );
} }
void showImageDialog(List<String> 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,
);
}
} }

View File

@@ -10,7 +10,12 @@ class PoultryActionPage extends GetView<PoultryActionLogic> {
@override @override
Widget build(BuildContext context) { 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() { Widget gridWidget() {
@@ -31,7 +36,7 @@ class PoultryActionPage extends GetView<PoultryActionLogic> {
title: item.title, title: item.title,
vecIcon: item.icon, vecIcon: item.icon,
onTap: () async { onTap: () async {
Get.toNamed(item.route, id: poultryFirstKey); Get.toNamed(item.route, id: poultryScienceActionKey);
}, },
); );
}, },

View File

@@ -25,7 +25,7 @@ class PoultryScienceRootLogic extends GetxController {
final pages = [ final pages = [
Navigator( Navigator(
key: Get.nestedKey(poultryFirstKey), key: Get.nestedKey(poultryScienceActionKey),
onGenerateRoute: (settings) { onGenerateRoute: (settings) {
final page = ChickenPages.pages.firstWhere( final page = ChickenPages.pages.firstWhere(
(e) => e.name == settings.name, (e) => e.name == settings.name,

View File

@@ -30,11 +30,9 @@ class PoultryScienceRootPage extends GetView<PoultryScienceRootLogic> {
isSelected: controller.currentPage.value == 0, isSelected: controller.currentPage.value == 0,
onTap: () { onTap: () {
Get.nestedKey( Get.nestedKey(
poultrySecondKey, poultryScienceActionKey,
)?.currentState?.popUntil((route) => route.isFirst);
Get.nestedKey(
poultryFirstKey,
)?.currentState?.popUntil((route) => route.isFirst); )?.currentState?.popUntil((route) => route.isFirst);
controller.changePage(0); controller.changePage(0);
}, },
), ),
@@ -44,11 +42,9 @@ class PoultryScienceRootPage extends GetView<PoultryScienceRootLogic> {
isSelected: controller.currentPage.value == 1, isSelected: controller.currentPage.value == 1,
onTap: () { onTap: () {
Get.nestedKey( Get.nestedKey(
poultryFirstKey, poultryScienceActionKey,
)?.currentState?.popUntil((route) => route.isFirst);
Get.nestedKey(
poultryThirdKey,
)?.currentState?.popUntil((route) => route.isFirst); )?.currentState?.popUntil((route) => route.isFirst);
controller.changePage(1); controller.changePage(1);
}, },
), ),
@@ -58,11 +54,9 @@ class PoultryScienceRootPage extends GetView<PoultryScienceRootLogic> {
isSelected: controller.currentPage.value == 2, isSelected: controller.currentPage.value == 2,
onTap: () { onTap: () {
Get.nestedKey( Get.nestedKey(
poultryFirstKey, poultryScienceActionKey,
)?.currentState?.popUntil((route) => route.isFirst);
Get.nestedKey(
poultrySecondKey,
)?.currentState?.popUntil((route) => route.isFirst); )?.currentState?.popUntil((route) => route.isFirst);
controller.changePage(2); controller.changePage(2);
}, },
), ),

View File

@@ -28,7 +28,7 @@ class CreateInspectionBottomSheetLogic extends GetxController
RxBool nextStepButtonEnabled = false.obs; RxBool nextStepButtonEnabled = false.obs;
RxInt casualtiesInformationHeight = 310.obs; RxInt casualtiesInformationHeight = 315.obs;
SubmitInspectionResponse? submitInspectionResponse; SubmitInspectionResponse? submitInspectionResponse;
@@ -87,7 +87,7 @@ class CreateInspectionBottomSheetLogic extends GetxController
TextEditingController otherTypeOfDiseaseController = TextEditingController(); TextEditingController otherTypeOfDiseaseController = TextEditingController();
RxList<String> pultryImagesUrls = RxList<String>(); RxList<String> pultryImagesUrls = RxList<String>();
RxMap<XFile, bool> pultryImages = RxMap<XFile, bool>(); RxList<XFile> pultryImages = RxList<XFile>();
TextEditingController hatchingTemperatureController = TextEditingController(); TextEditingController hatchingTemperatureController = TextEditingController();
TextEditingController waterHardnessController = TextEditingController(); TextEditingController waterHardnessController = TextEditingController();
@@ -189,13 +189,13 @@ class CreateInspectionBottomSheetLogic extends GetxController
TextEditingController(); TextEditingController();
RxList<String> hallImagesUrls = RxList<String>(); RxList<String> hallImagesUrls = RxList<String>();
RxMap<XFile, bool> hallImages = RxMap<XFile, bool>(); RxList<XFile> hallImages = RxList<XFile>();
RxList<String> inputWarehouseImagesUrls = RxList<String>(); RxList<String> inputWarehouseImagesUrls = RxList<String>();
RxMap<XFile, bool> inputWarehouseImages = RxMap<XFile, bool>(); RxList<XFile> inputWarehouseImages = RxList<XFile>();
RxList<String> lossesImagesUrls = RxList<String>(); RxList<String> lossesImagesUrls = RxList<String>();
RxMap<XFile, bool> lossesImages = RxMap<XFile, bool>(); RxList<XFile> lossesImages = RxList<XFile>();
//location //location
Rxn<LatLng> currentLocation = Rxn<LatLng>(); Rxn<LatLng> currentLocation = Rxn<LatLng>();
@@ -525,6 +525,7 @@ class CreateInspectionBottomSheetLogic extends GetxController
void setInspectorConclusionIndex(int index, String item) { void setInspectorConclusionIndex(int index, String item) {
inspectorConclusion.value = item; inspectorConclusion.value = item;
submitInspectionResponse?.inspectionStatus = item;
inspectorConclusionIndex.value = index == inspectorConclusionIndex.value inspectorConclusionIndex.value = index == inspectorConclusionIndex.value
? -1 ? -1
: index; : index;
@@ -563,17 +564,18 @@ class CreateInspectionBottomSheetLogic extends GetxController
} }
} }
Future<void> pickImageFromCamera(RxMap<XFile, bool> images) async { Future<void> pickImageFromCamera(RxList<XFile> images) async {
try { try {
final XFile? image = await imagePicker.pickImage( final XFile? image = await imagePicker.pickImage(
source: ImageSource.camera, source: ImageSource.camera,
preferredCameraDevice: CameraDevice.rear,
imageQuality: 50, imageQuality: 50,
maxWidth: 1080, maxWidth: 1080,
maxHeight: 720, maxHeight: 720,
); );
if (image != null) { if (image != null) {
images[image] = false; images.add(image);
//await uploadImage(image); //await uploadImage(image);
} }
@@ -601,10 +603,10 @@ class CreateInspectionBottomSheetLogic extends GetxController
if (urls != null) { if (urls != null) {
pultryImagesUrls.addAll(urls); pultryImagesUrls.addAll(urls);
} }
pultryImages[imageFile] = true; pultryImages.add(imageFile);
}, },
onError: (error, e) { onError: (error, e) {
pultryImages[imageFile] = false; pultryImages.remove(imageFile);
}, },
); );
} }
@@ -657,7 +659,7 @@ class CreateInspectionBottomSheetLogic extends GetxController
// آپلود عکس‌های سالن // آپلود عکس‌های سالن
if (hallImages.isNotEmpty) { if (hallImages.isNotEmpty) {
uploadStatusMessage.value = 'در حال آپلود عکس‌های سالن...'; uploadStatusMessage.value = 'در حال آپلود عکس‌های سالن...';
final hallImageFiles = hallImages.keys.toList(); final hallImageFiles = hallImages.toList();
final hallUrls = await uploadImageBatch(hallImageFiles); final hallUrls = await uploadImageBatch(hallImageFiles);
if (hallUrls != null && hallUrls.isNotEmpty) { if (hallUrls != null && hallUrls.isNotEmpty) {
@@ -672,7 +674,7 @@ class CreateInspectionBottomSheetLogic extends GetxController
// آپلود عکس‌های انبار دان // آپلود عکس‌های انبار دان
if (inputWarehouseImages.isNotEmpty) { if (inputWarehouseImages.isNotEmpty) {
uploadStatusMessage.value = 'در حال آپلود عکس‌های انبار دان...'; uploadStatusMessage.value = 'در حال آپلود عکس‌های انبار دان...';
final inputImageFiles = inputWarehouseImages.keys.toList(); final inputImageFiles = inputWarehouseImages.toList();
final inputUrls = await uploadImageBatch(inputImageFiles); final inputUrls = await uploadImageBatch(inputImageFiles);
if (inputUrls != null && inputUrls.isNotEmpty) { if (inputUrls != null && inputUrls.isNotEmpty) {
@@ -687,7 +689,7 @@ class CreateInspectionBottomSheetLogic extends GetxController
// آپلود عکس‌های تلفات // آپلود عکس‌های تلفات
if (lossesImages.isNotEmpty) { if (lossesImages.isNotEmpty) {
uploadStatusMessage.value = 'در حال آپلود عکس‌های تلفات...'; uploadStatusMessage.value = 'در حال آپلود عکس‌های تلفات...';
final lossesImageFiles = lossesImages.keys.toList(); final lossesImageFiles = lossesImages.toList();
final lossesUrls = await uploadImageBatch(lossesImageFiles); final lossesUrls = await uploadImageBatch(lossesImageFiles);
if (lossesUrls != null && lossesUrls.isNotEmpty) { if (lossesUrls != null && lossesUrls.isNotEmpty) {
@@ -702,14 +704,12 @@ class CreateInspectionBottomSheetLogic extends GetxController
// آپلود عکس‌های مرغداری // آپلود عکس‌های مرغداری
if (pultryImages.isNotEmpty) { if (pultryImages.isNotEmpty) {
uploadStatusMessage.value = 'در حال آپلود عکس‌های مرغداری...'; uploadStatusMessage.value = 'در حال آپلود عکس‌های مرغداری...';
final poultryImageFiles = pultryImages.keys.toList(); final poultryImageFiles = pultryImages.toList();
final poultryUrls = await uploadImageBatch(poultryImageFiles); final poultryUrls = await uploadImageBatch(poultryImageFiles);
if (poultryUrls != null && poultryUrls.isNotEmpty) { if (poultryUrls != null && poultryUrls.isNotEmpty) {
// اگر فیلد جداگانه‌ای برای عکس‌های مرغداری نداریم، به generalConditionHall اضافه می‌کنیم // اگر فیلد جداگانه‌ای برای عکس‌های مرغداری نداریم، به generalConditionHall اضافه می‌کنیم
if (submitInspectionResponse?.generalConditionHall?.images == null) { submitInspectionResponse?.generalConditionHall?.images ??= [];
submitInspectionResponse?.generalConditionHall?.images = [];
}
submitInspectionResponse?.generalConditionHall?.images?.addAll( submitInspectionResponse?.generalConditionHall?.images?.addAll(
poultryUrls, poultryUrls,
); );
@@ -738,8 +738,8 @@ class CreateInspectionBottomSheetLogic extends GetxController
} }
} }
void removeImage(RxMap<XFile, bool> images, XFile image) { void removeImage(RxList<XFile> images, String imagePath) {
images.remove(image); images.removeWhere((element) => element.path == imagePath);
} }
void setTypeOfDiseaseIndex(String item) { void setTypeOfDiseaseIndex(String item) {
@@ -853,10 +853,6 @@ class CreateInspectionBottomSheetLogic extends GetxController
hallImages.remove(key); hallImages.remove(key);
} }
void removeInputWarehouseImage(XFile key) {
inputWarehouseImages.remove(key);
}
void removeLossesImage(XFile key) { void removeLossesImage(XFile key) {
lossesImages.remove(key); lossesImages.remove(key);
} }
@@ -939,9 +935,10 @@ class CreateInspectionBottomSheetLogic extends GetxController
submitInspectionResponse?.hr?.numberNonIndigenous = int.parse( submitInspectionResponse?.hr?.numberNonIndigenous = int.parse(
nonNativeWorkersCountController.text.clearComma, nonNativeWorkersCountController.text.clearComma,
); );
iLog(submitInspectionResponse?.toJson());
submitInspectionResponse?.inspectionNotes =
inspectorConclusionDescriptionController.text;
await safeCall( await safeCall(
call: () async { call: () async {
await repository.submitInspection( await repository.submitInspection(
@@ -950,16 +947,17 @@ class CreateInspectionBottomSheetLogic extends GetxController
); );
}, },
onSuccess: (result) { onSuccess: (result) {
Get.back(); Get.back();
Future.delayed(Duration(seconds: 2), () { Get.snackbar( Future.delayed(Duration(seconds: 2), () {
'موفق', Get.snackbar(
'بازرسی با موفقیت ثبت شد', 'موفق',
snackPosition: SnackPosition.TOP, 'بازرسی با موفقیت ثبت شد',
backgroundColor: Colors.green, snackPosition: SnackPosition.TOP,
colorText: Colors.white, backgroundColor: Colors.green,
);}); colorText: Colors.white,
);
});
}, },
onError: (error, stackTrace) { onError: (error, stackTrace) {
Get.snackbar( Get.snackbar(

View File

@@ -13,8 +13,8 @@ Widget step1Page(CreateInspectionBottomSheetLogic controller) {
Container( Container(
height: controller.tenantStatusController.text == 'دارد' height: controller.tenantStatusController.text == 'دارد'
? 588.h ? 600.h
: 445.h, : 460.h,
clipBehavior: Clip.none, clipBehavior: Clip.none,
width: Get.width, width: Get.width,
child: farmInfoWidget( child: farmInfoWidget(

View File

@@ -14,7 +14,7 @@ Widget step2Page(CreateInspectionBottomSheetLogic controller) {
SizedBox(height: 35.h), SizedBox(height: 35.h),
Container( Container(
height: 600.h, height: 630.h,
clipBehavior: Clip.none, clipBehavior: Clip.none,
width: Get.width, width: Get.width,
child: farmInfoWidget( child: farmInfoWidget(
@@ -71,83 +71,63 @@ Column generalConditionOfTheHall(CreateInspectionBottomSheetLogic controller) {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
// Fix: Use spread .entries.map for map iteration, and correct image argument
spacing: 8, spacing: 8,
children: [ children: [
...controller.pultryImages.entries ...controller.pultryImages.map(
.map( (entry) => Stack(
(entry) => Stack( children: [
children: [ Container(
Container( height: 80.h,
height: 80.h, width: 80.w,
width: 80.w, decoration: BoxDecoration(
decoration: BoxDecoration( borderRadius: BorderRadius.circular(8),
borderRadius: BorderRadius.circular(8), border: Border.all(
border: Border.all( width: 1,
width: 1, color: AppColor.blackLightHover,
color: AppColor.blackLightHover,
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.file(
File(entry.key.path),
fit: BoxFit.cover,
),
),
), ),
// Delete button ),
Positioned( child: ClipRRect(
top: -4, borderRadius: BorderRadius.circular(8),
right: -4, child: Image.file(
child: GestureDetector( File(entry.path),
onTap: () => fit: BoxFit.cover,
controller.removeImage(controller.pultryImages, entry.key),
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 ),
if (entry.value == false)
Positioned.fill(
child: Container(
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<Color>(
Colors.white,
),
),
),
),
),
),
],
), ),
) // 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 // Add image button
GestureDetector( GestureDetector(
onTap: () => controller.pickImageFromCamera(controller.pultryImages), onTap: () => controller.pickImageFromCamera(
controller.pultryImages,
),
child: Container( child: Container(
height: 80.h, height: 80.h,
width: 80.w, width: 80.w,

View File

@@ -14,7 +14,7 @@ Widget step3Page(CreateInspectionBottomSheetLogic controller) {
SizedBox(height: 35.h), SizedBox(height: 35.h),
Container( Container(
height: 360.h, height: 370.h,
clipBehavior: Clip.none, clipBehavior: Clip.none,
width: Get.width, width: Get.width,
child: farmInfoWidget( child: farmInfoWidget(
@@ -27,7 +27,7 @@ Widget step3Page(CreateInspectionBottomSheetLogic controller) {
SizedBox(height: 30.h), SizedBox(height: 30.h),
Container( Container(
height: 610.h, height: 625.h,
clipBehavior: Clip.none, clipBehavior: Clip.none,
width: Get.width, width: Get.width,
child: farmInfoWidget( child: farmInfoWidget(
@@ -39,7 +39,7 @@ Widget step3Page(CreateInspectionBottomSheetLogic controller) {
SizedBox(height: 24.h), SizedBox(height: 24.h),
Container( Container(
height: 310.h, height: 320.h,
clipBehavior: Clip.none, clipBehavior: Clip.none,
width: Get.width, width: Get.width,
child: farmInfoWidget( child: farmInfoWidget(
@@ -51,7 +51,7 @@ Widget step3Page(CreateInspectionBottomSheetLogic controller) {
SizedBox(height: 24.h), SizedBox(height: 24.h),
Container( Container(
height: 325.h, height: 335.h,
clipBehavior: Clip.none, clipBehavior: Clip.none,
width: Get.width, width: Get.width,
child: farmInfoWidget( child: farmInfoWidget(
@@ -461,8 +461,8 @@ Column facilitiesAndSupport(CreateInspectionBottomSheetLogic controller) {
children: [ children: [
SizedBox(height: 1.h), SizedBox(height: 1.h),
ResourceOverlayDropdown( ResourceOverlayDropdown(
items: Resource.success([ 'دارد', 'ندارد']), items: Resource.success(['دارد', 'ندارد']),
onChanged: (item) => controller.setHasFacilities(item), onChanged: (item) => controller.setHasFacilities(item),
itemBuilder: (item) => Text(item), itemBuilder: (item) => Text(item),
labelBuilder: (selected) => Text(selected ?? ' تسهیلات دریافتی فعال'), labelBuilder: (selected) => Text(selected ?? ' تسهیلات دریافتی فعال'),

View File

@@ -16,7 +16,7 @@ Widget step4Page(CreateInspectionBottomSheetLogic controller) {
SizedBox(height: 35.h), SizedBox(height: 35.h),
Container( Container(
height: 440.h, height: 455.h,
clipBehavior: Clip.none, clipBehavior: Clip.none,
width: Get.width, width: Get.width,
child: farmInfoWidget( child: farmInfoWidget(
@@ -62,7 +62,7 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
spacing: 8, spacing: 8,
children: [ children: [
...controller.hallImages.entries.map( ...controller.hallImages.map(
(entry) => Stack( (entry) => Stack(
children: [ children: [
Container( Container(
@@ -78,7 +78,7 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: Image.file( child: Image.file(
File(entry.key.path), File(entry.path),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@@ -90,7 +90,7 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
child: GestureDetector( child: GestureDetector(
onTap: () => controller.removeImage( onTap: () => controller.removeImage(
controller.hallImages, controller.hallImages,
entry.key, entry.path,
), ),
child: Container( child: Container(
width: 24, width: 24,
@@ -172,7 +172,7 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
spacing: 8, spacing: 8,
children: [ children: [
...controller.inputWarehouseImages.entries.map( ...controller.inputWarehouseImages.map(
(entry) => Stack( (entry) => Stack(
children: [ children: [
Container( Container(
@@ -188,18 +188,19 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: Image.file( child: Image.file(
File(entry.key.path), File(entry.path),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
), ),
// Delete button // Delete button
Positioned( Positioned(
top: 4, top: 4,
left: 4, left: 4,
child: GestureDetector( child: GestureDetector(
onTap: () => controller.removeInputWarehouseImage( onTap: () => controller.removeImage(
entry.key, controller.inputWarehouseImages,
entry.path,
), ),
child: Container( child: Container(
width: 24, width: 24,
@@ -268,7 +269,7 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
spacing: 8, spacing: 8,
children: [ children: [
...controller.lossesImages.entries.map( ...controller.lossesImages.map(
(entry) => Stack( (entry) => Stack(
children: [ children: [
Container( Container(
@@ -284,7 +285,7 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: Image.file( child: Image.file(
File(entry.key.path), File(entry.path),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@@ -294,8 +295,9 @@ Column documents(CreateInspectionBottomSheetLogic controller) {
top: 4, top: 4,
left: 4, left: 4,
child: GestureDetector( child: GestureDetector(
onTap: () => controller.removeInputWarehouseImage( onTap: () => controller.removeImage(
entry.key, controller.lossesImages,
entry.path,
), ),
child: Container( child: Container(
width: 24, width: 24,

View File

@@ -12,7 +12,16 @@ const int poultrySecondKey = 106;
const int poultryThirdKey = 107; const int poultryThirdKey = 107;
//endregion //endregion
//region kill house Keys //region kill house Keys
const int killHouseActionKey = 108; const int killHouseActionKey = 108;
//endregion //endregion
//region poultry science Keys
const int poultryScienceActionKey = 109;
//endregion

View File

@@ -37,11 +37,11 @@ class DioRemote implements IHttpClient {
PrettyDioLogger( PrettyDioLogger(
request: true, request: true,
enabled: true, enabled: true,
error: false,
requestHeader: true, requestHeader: true,
responseHeader: true, responseHeader: true,
requestBody: true, requestBody: true,
responseBody: false, responseBody: true,
), ),
); );
} }