diff --git a/app/Enums/Level.php b/app/Enums/Level.php new file mode 100644 index 00000000..83627f1d --- /dev/null +++ b/app/Enums/Level.php @@ -0,0 +1,25 @@ + self::getViolenceHeading($record)) ->schema(self::getViolenceHistoryInfolistSchema()), - InfolistSection::make(__('beneficiary.section.initial_evaluation.heading.violences_types')) + InfolistSection::make(fn (Beneficiary $record) => self::getViolencesTypesHeading($record)) ->schema(self::getViolencesTypesInfolistSchema()), - InfolistSection::make(__('beneficiary.section.initial_evaluation.heading.risk_factors')) + InfolistSection::make(fn (Beneficiary $record) => self::getRiskFactorsHeading($record)) ->schema(self::getRiskFactorsInfolistSchema()), - InfolistSection::make(__('beneficiary.section.initial_evaluation.heading.victim_perception_of_the_risk')) + InfolistSection::make(fn (Beneficiary $record) => self::getVictimPerceptionOfTherRiskHeading($record)) ->schema(self::getVictimPerceptionOfTheRiskInfolistSchema()), - InfolistSection::make(__('beneficiary.section.initial_evaluation.heading.aggravating_factors')) + InfolistSection::make(fn (Beneficiary $record) => self::getAggravatingFactorsHeading($record)) ->schema(self::getAggravatingFactorsInfolistSchema()), InfolistSection::make(__('beneficiary.section.initial_evaluation.heading.social_support')) ->columns() @@ -497,9 +499,75 @@ public static function getSocialSupportInfolistSchema(): array { return [ TextEntry::make('FR_S6Q1') - ->label(__('beneficiary.section.initial_evaluation.labels.FR_S6Q1')), + ->label(__('beneficiary.section.initial_evaluation.labels.FR_S6Q1')) + ->badge(), EnumEntry::make('FR_S6Q2') - ->label(__('beneficiary.section.initial_evaluation.labels.FR_S6Q2')), + ->label(__('beneficiary.section.initial_evaluation.labels.FR_S6Q2')) + ->badge(), ]; } + + private static function getViolenceHeading(Beneficiary $record): string + { + $totalAnswers = 5; + $fields = ['previous_acts_of_violence', 'violence_against_children_or_family_members', + 'abuser_exhibited_generalized_violent', 'protection_order_in_past', 'abuser_violated_protection_order']; + $trueAnswers = self::getTrueAnswers($record->riskFactors, $fields); + + return __('beneficiary.section.initial_evaluation.heading.violence_history') . ' ' . + __('general.true_answers', ['total_answers' => $totalAnswers, 'true_answers' => $trueAnswers]); + } + + private static function getViolencesTypesHeading(Beneficiary $record): string + { + $totalAnswers = 7; + $fields = ['frequency_of_violence_acts', 'use_weapons_in_act_of_violence', 'controlling_and_isolating', + 'stalked_or_harassed', 'sexual_violence', 'death_threats', 'strangulation_attempt']; + $trueAnswers = self::getTrueAnswers($record->riskFactors, $fields); + + return __('beneficiary.section.initial_evaluation.heading.violences_types') . ' ' . + __('general.true_answers', ['total_answers' => $totalAnswers, 'true_answers' => $trueAnswers]); + } + + private static function getRiskFactorsHeading(Beneficiary $record): string + { + $totalAnswers = 4; + $fields = ['FR_S3Q1', 'FR_S3Q2', 'FR_S3Q3', 'FR_S3Q4']; + $trueAnswers = self::getTrueAnswers($record->riskFactors, $fields); + + return __('beneficiary.section.initial_evaluation.heading.risk_factors') . ' ' . + __('general.true_answers', ['total_answers' => $totalAnswers, 'true_answers' => $trueAnswers]); + } + + private static function getVictimPerceptionOfTherRiskHeading(Beneficiary $record): string + { + $totalAnswers = 2; + $fields = ['FR_S4Q1', 'FR_S4Q2']; + $trueAnswers = self::getTrueAnswers($record->riskFactors, $fields); + + return __('beneficiary.section.initial_evaluation.heading.victim_perception_of_the_risk') . ' ' . + __('general.true_answers', ['total_answers' => $totalAnswers, 'true_answers' => $trueAnswers]); + } + + private static function getAggravatingFactorsHeading(Beneficiary $record): string + { + $totalAnswers = 5; + $fields = ['FR_S5Q1', 'FR_S5Q2', 'FR_S5Q3', 'FR_S5Q4', 'FR_S5Q5']; + $trueAnswers = self::getTrueAnswers($record->riskFactors, $fields); + + return __('beneficiary.section.initial_evaluation.heading.aggravating_factors') . ' ' . + __('general.true_answers', ['total_answers' => $totalAnswers, 'true_answers' => $trueAnswers]); + } + + private static function getTrueAnswers(RiskFactors $riskFactors, array $fields): int + { + $count = 0; + foreach ($fields as $field) { + if (Ternary::isYes($riskFactors->$field)) { + $count++; + } + } + + return $count; + } } diff --git a/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewBeneficiary.php b/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewBeneficiary.php index 076e83fd..e96b4836 100644 --- a/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewBeneficiary.php +++ b/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewBeneficiary.php @@ -4,6 +4,7 @@ namespace App\Filament\Organizations\Resources\BeneficiaryResource\Pages; +use App\Enums\Level; use App\Enums\Ternary; use App\Filament\Organizations\Resources\BeneficiaryResource; use App\Infolists\Components\EnumEntry; @@ -190,6 +191,16 @@ private function evaluations(): Group ->hidden(fn ($state) => $state == '-') ->badge() ->formatStateUsing(fn ($state) => $state != '-' ? $state->label() : ''), + TextEntry::make('riskFactors.risk_level') + ->label('') + ->formatStateUsing(fn ($state) => $state != '-' ? $state->label() : '') + ->hidden(fn ($state) => $state == '-') + ->badge() + ->colors([ + 'success' => Level::LOW, + 'warning' => Level::MEDIUM, + 'danger' => Level::HIGH, + ]), // TODO add risk grade ]) ->columns(), diff --git a/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewInitialEvaluation.php b/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewInitialEvaluation.php index 77ebea9b..419efeef 100644 --- a/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewInitialEvaluation.php +++ b/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/ViewInitialEvaluation.php @@ -48,17 +48,21 @@ public function infolist(Infolist $infolist): Infolist ->schema(EditViolence::getInfoListSchema())]), Tabs\Tab::make(__('beneficiary.wizard.risk_factors.label')) ->schema([ - Section::make(__('beneficiary.wizard.risk_factors.label')) - ->headerActions([ - Action::make('edit') - ->label(__('general.action.edit')) - ->url(fn ($record) => BeneficiaryResource::getUrl( - 'edit_initial_evaluation_risk_factors', - ['record' => $record] - )) - ->link(), - ]) - ->schema(EditRiskFactors::getInfoListSchema())]), + Section::make(fn ($record) => $record->riskFactors->risk_level->label() ?? + __('beneficiary.wizard.risk_factors.label')) + ->schema([ + Section::make(__('beneficiary.wizard.risk_factors.label')) + ->headerActions([ + Action::make('edit') + ->label(__('general.action.edit')) + ->url(fn ($record) => BeneficiaryResource::getUrl( + 'edit_initial_evaluation_risk_factors', + ['record' => $record] + )) + ->link(), + ]) + ->schema(EditRiskFactors::getInfoListSchema())]), + ]), Tabs\Tab::make(__('beneficiary.wizard.requested_services.label')) ->schema([ Section::make(__('beneficiary.wizard.requested_services.label')) diff --git a/app/Models/RiskFactors.php b/app/Models/RiskFactors.php index 5df85323..b3104247 100644 --- a/app/Models/RiskFactors.php +++ b/app/Models/RiskFactors.php @@ -5,7 +5,10 @@ namespace App\Models; use App\Concerns\BelongsToBeneficiary; +use App\Enums\Helps; +use App\Enums\Level; use App\Enums\Ternary; +use Illuminate\Database\Eloquent\Casts\AsEnumCollection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -65,6 +68,7 @@ class RiskFactors extends Model 'FR_S6Q1_description', 'FR_S6Q2', 'FR_S6Q2_description', + 'risk_level', ]; protected $casts = [ @@ -91,7 +95,86 @@ class RiskFactors extends Model 'FR_S5Q3' => Ternary::class, 'FR_S5Q4' => Ternary::class, 'FR_S5Q5' => Ternary::class, - 'FR_S6Q1' => Ternary::class, - 'FR_S6Q2' => Ternary::class, + 'FR_S6Q1' => AsEnumCollection::class . ':' . Helps::class, + 'FR_S6Q2' => AsEnumCollection::class . ':' . Helps::class, + 'risk_level' => Level::class, ]; + + protected static function boot() + { + parent::boot(); + self::creating(fn (RiskFactors $model) => self::calculateRiskLevel($model)); + + self::updating(fn (RiskFactors $model) => self::calculateRiskLevel($model)); + } + + public static function calculateRiskLevel(self $model): void + { + if (self::hasHighRiskLevel($model)) { + $model->risk_level = Level::HIGH; + + return; + } + + if (self::hasMediumRiskLevel($model)) { + $model->risk_level = Level::MEDIUM; + + return; + } + + if (self::hasLowRiskLevel($model)) { + $model->risk_level = Level::LOW; + } + } + + private static function hasHighRiskLevel(self $model): bool + { + if (Ternary::isYes($model->use_weapons_in_act_of_violence)) { + return true; + } + + if (Ternary::isYes($model->death_threats)) { + return true; + } + + if (Ternary::isYes($model->FR_S4Q1)) { + return true; + } + + if (self::getTrueAnswersCount($model) >= 5) { + return true; + } + + return false; + } + + private static function getTrueAnswersCount(self $model): int + { + $count = 0; + foreach ($model->getAttributes() as $value) { + if (Ternary::isYes($value)) { + $count++; + } + } + + return $count; + } + + private static function hasMediumRiskLevel(self $model): bool + { + if (self::getTrueAnswersCount($model) == 4) { + return true; + } + + return false; + } + + private static function hasLowRiskLevel(self $model): bool + { + if (self::getTrueAnswersCount($model) >= 1) { + return true; + } + + return false; + } } diff --git a/database/migrations/2024_04_29_084929_create_risk_factors_table.php b/database/migrations/2024_04_29_084929_create_risk_factors_table.php index 66cb4103..3382ce6a 100644 --- a/database/migrations/2024_04_29_084929_create_risk_factors_table.php +++ b/database/migrations/2024_04_29_084929_create_risk_factors_table.php @@ -67,6 +67,7 @@ public function up(): void $table->string('FR_S6Q1_description')->nullable(); $table->string('FR_S6Q2'); $table->string('FR_S6Q2_description')->nullable(); + $table->string('risk_level')->nullable(); $table->timestamps(); }); } diff --git a/lang/ro/enum.php b/lang/ro/enum.php index 55b0957d..f0aceeaa 100644 --- a/lang/ro/enum.php +++ b/lang/ro/enum.php @@ -180,4 +180,10 @@ 'beneficiary' => 'Solicitare din partea beneficiarului', 'other' => 'Semnalare caz de către altcineva', ], + + 'level' => [ + 'high' => 'Grad de risc crescut', + 'medium' => 'Grad de risc mediu', + 'low' => 'Grad de risc scăzut', + ], ]; diff --git a/lang/ro/general.php b/lang/ro/general.php index cc1ad401..a594a428 100644 --- a/lang/ro/general.php +++ b/lang/ro/general.php @@ -11,4 +11,5 @@ 'edit' => 'Editeaza', ], + 'true_answers' => '(:true_answers/:total_answers răspunsuri afirmative)', ];