From 86c995d5dff86398dded4621a8fbebe90969e522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrei=20Ioni=C8=9B=C4=83?= Date: Fri, 15 Dec 2023 14:24:10 +0000 Subject: [PATCH] wip --- app/Enums/AggressorLegalHistory.php | 23 +++ app/Enums/AggressorRelationship.php | 27 ++++ app/Enums/Drug.php | 26 ++++ app/Enums/Violence.php | 29 ++++ app/Filament/Admin/Pages/Dashboard.php | 18 +++ .../EditBeneficiaryPersonalInformation.php | 142 +++++++++++++++++- app/Models/Aggressor.php | 64 ++++++++ app/Models/Beneficiary.php | 7 + app/Models/Organization.php | 2 + app/Models/User.php | 27 +++- app/Providers/Filament/AdminPanelProvider.php | 2 +- database/factories/AggressorFactory.php | 69 +++++++++ database/factories/BeneficiaryFactory.php | 11 ++ database/factories/UserFactory.php | 10 ++ .../2014_10_12_000000_create_users_table.php | 1 + ...1_20_130401_create_beneficiaries_table.php | 3 +- ...3_12_14_201551_create_aggressors_table.php | 53 +++++++ database/seeders/DatabaseSeeder.php | 5 + lang/ro/enum.php | 37 +++++ lang/ro/field.php | 22 ++- lang/ro/placeholder.php | 2 +- 21 files changed, 563 insertions(+), 17 deletions(-) create mode 100644 app/Enums/AggressorLegalHistory.php create mode 100644 app/Enums/AggressorRelationship.php create mode 100644 app/Enums/Drug.php create mode 100644 app/Enums/Violence.php create mode 100644 app/Filament/Admin/Pages/Dashboard.php create mode 100644 app/Models/Aggressor.php create mode 100644 database/factories/AggressorFactory.php create mode 100644 database/migrations/2023_12_14_201551_create_aggressors_table.php diff --git a/app/Enums/AggressorLegalHistory.php b/app/Enums/AggressorLegalHistory.php new file mode 100644 index 00000000..864c7fc8 --- /dev/null +++ b/app/Enums/AggressorLegalHistory.php @@ -0,0 +1,23 @@ + auth()->user()->first_name, + ]); + } +} diff --git a/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/EditBeneficiaryPersonalInformation.php b/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/EditBeneficiaryPersonalInformation.php index 952f4eff..5a633ed9 100644 --- a/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/EditBeneficiaryPersonalInformation.php +++ b/app/Filament/Organizations/Resources/BeneficiaryResource/Pages/EditBeneficiaryPersonalInformation.php @@ -4,11 +4,17 @@ namespace App\Filament\Organizations\Resources\BeneficiaryResource\Pages; +use App\Enums\AggressorLegalHistory; +use App\Enums\AggressorRelationship; +use App\Enums\CivilStatus; +use App\Enums\Drug; +use App\Enums\Gender; use App\Enums\HomeOwnership; use App\Enums\Income; use App\Enums\Occupation; use App\Enums\Studies; use App\Enums\Ternary; +use App\Enums\Violence; use App\Filament\Organizations\Resources\BeneficiaryResource; use Filament\Forms\Components\Grid; use Filament\Forms\Components\Section; @@ -77,8 +83,8 @@ protected static function beneficiarySection(): Section ->enum(Ternary::class) ->live(), - TextInput::make('psychiatric_history_notes') - ->label(__('field.psychiatric_history_notes')) + TextInput::make('psychiatric_notes') + ->label(__('field.psychiatric_notes')) ->visible(fn (Get $get) => Ternary::isYes($get('psychiatric_history'))), ]), @@ -91,8 +97,8 @@ protected static function beneficiarySection(): Section ->enum(Ternary::class) ->live(), - TextInput::make('criminal_history_notes') - ->label(__('field.criminal_history_notes')) + TextInput::make('criminal_notes') + ->label(__('field.criminal_notes')) ->visible(fn (Get $get) => Ternary::isYes($get('criminal_history'))), ]), @@ -133,4 +139,132 @@ protected static function beneficiarySection(): Section ->enum(HomeOwnership::class), ]); } + + protected static function aggressorSection(): Section + { + return Section::make(__('beneficiary.section.personal_information.section.aggressor')) + ->relationship('aggressor') + ->columns() + ->schema([ + Select::make('relationship') + ->label(__('field.aggressor_relationship')) + ->placeholder(__('placeholder.select_one')) + ->options(AggressorRelationship::options()) + ->enum(AggressorRelationship::class) + ->live(), + + TextInput::make('age') + ->label(__('field.aggressor_age')) + ->placeholder(__('placeholder.number')) + ->numeric() + ->minValue(0) + ->maxValue(200), + + Select::make('gender') + ->label(__('field.aggressor_gender')) + ->placeholder(__('placeholder.select_one')) + ->options(Gender::options()) + ->enum(Gender::class), + + Select::make('citizenship_id') + ->label(__('field.aggressor_citizenship')) + ->placeholder(__('placeholder.citizenship')) + ->relationship('citizenship', 'name') + ->nullable(), + + Select::make('civil_status') + ->label(__('field.aggressor_civil_status')) + ->placeholder(__('placeholder.civil_status')) + ->options(CivilStatus::options()) + ->enum(CivilStatus::class), + + Select::make('studies') + ->label(__('field.aggressor_studies')) + ->placeholder(__('placeholder.studies')) + ->options(Studies::options()) + ->enum(Studies::class), + + Select::make('occupation') + ->label(__('field.aggressor_occupation')) + ->placeholder(__('placeholder.select_one')) + ->options(Occupation::options()) + ->enum(Occupation::class), + + Grid::make() + ->schema([ + Select::make('has_violence_history') + ->label(__('field.aggressor_has_violence_history')) + ->placeholder(__('placeholder.select_one')) + ->options(Ternary::options()) + ->enum(Ternary::class) + ->live(), + + Select::make('violence_types') + ->label(__('field.aggressor_violence_types')) + ->placeholder(__('placeholder.select_many')) + ->visible(fn (Get $get) => Ternary::isYes($get('violence_history'))) + ->options(Violence::options()) + ->enum(Violence::class) + ->multiple(), + + ]), + + Grid::make() + ->schema([ + Select::make('has_psychiatric_history') + ->label(__('field.aggressor_has_psychiatric_history')) + ->placeholder(__('placeholder.select_one')) + ->options(Ternary::options()) + ->enum(Ternary::class) + ->live(), + + TextInput::make('psychiatric_history_notes') + ->label(__('field.aggressor_psychiatric_history_notes')) + ->visible(fn (Get $get) => Ternary::isYes($get('psychiatric_history'))), + ]), + + Grid::make() + ->schema([ + Select::make('has_drug_history') + ->label(__('field.aggressor_has_drug_history')) + ->placeholder(__('placeholder.select_one')) + ->options(Ternary::options()) + ->enum(Ternary::class) + ->live(), + + Select::make('drugs') + ->label(__('field.aggressor_drugs')) + ->placeholder(__('placeholder.select_many')) + ->visible(fn (Get $get) => Ternary::isYes($get('has_drug_history'))) + ->options(Drug::options()) + ->enum(Drug::class) + ->multiple(), + ]), + + Grid::make() + ->schema([ + Select::make('legal_history') + ->label(__('field.aggressor_legal_history')) + ->placeholder(__('placeholder.select_many')) + ->visible(fn (Get $get) => Ternary::isYes($get('violence_history'))) + ->options(AggressorLegalHistory::options()) + ->enum(AggressorLegalHistory::class) + ->multiple() + ->live(), + ]), + + Grid::make() + ->schema([ + Select::make('has_protection_order') + ->label(__('field.has_protection_order')) + ->placeholder(__('placeholder.select_one')) + ->options(Ternary::options()) + ->enum(Ternary::class) + ->live(), + + TextInput::make('protection_order_notes') + ->label(__('field.protection_order_notes')), + ]), + ]); + } } diff --git a/app/Models/Aggressor.php b/app/Models/Aggressor.php new file mode 100644 index 00000000..fbecbe91 --- /dev/null +++ b/app/Models/Aggressor.php @@ -0,0 +1,64 @@ + 'integer', + 'civil_status' => CivilStatus::class, + 'drugs' => AsEnumCollection::class . ':' . Drug::class, + 'gender' => Gender::class, + 'has_drug_history' => Ternary::class, + 'has_protection_order' => Ternary::class, + 'has_psychiatric_history' => Ternary::class, + 'has_violence_history' => Ternary::class, + 'legal_history' => AsEnumCollection::class . ':' . AggressorLegalHistory::class, + 'occupation' => Occupation::class, + 'relationship' => AggressorRelationship::class, + 'studies' => Studies::class, + 'violence_types' => AsEnumCollection::class . ':' . Violence::class, + ]; + + public function beneficiary(): BelongsTo + { + return $this->belongsTo(Beneficiary::class); + } +} diff --git a/app/Models/Beneficiary.php b/app/Models/Beneficiary.php index 36ea1d4a..6d10f344 100644 --- a/app/Models/Beneficiary.php +++ b/app/Models/Beneficiary.php @@ -22,6 +22,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasOne; class Beneficiary extends Model { @@ -127,6 +128,12 @@ public function legalResidenceCity(): BelongsTo return $this->belongsTo(City::class, 'legal_residence_city_id'); } + public function aggressor(): HasOne + { + return $this->hasOne(Aggressor::class) + ->withDefault(); + } + public function age(): Attribute { return Attribute::make( diff --git a/app/Models/Organization.php b/app/Models/Organization.php index f5dfd1b8..697ec334 100644 --- a/app/Models/Organization.php +++ b/app/Models/Organization.php @@ -65,10 +65,12 @@ public function registerMediaCollections(): void ->registerMediaConversions(function () { $this->addMediaConversion('thumb') ->fit(Manipulations::FIT_CONTAIN, 64, 64) + ->keepOriginalImageFormat() ->optimize(); $this->addMediaConversion('large') ->fit(Manipulations::FIT_CONTAIN, 256, 256) + ->keepOriginalImageFormat() ->optimize(); }); } diff --git a/app/Models/User.php b/app/Models/User.php index 5774eb11..13f93dcb 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -63,6 +63,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar, HasName, protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', + 'is_admin' => 'boolean', ]; public function organizations(): MorphToMany @@ -77,19 +78,16 @@ public function registerMediaCollections(): void ->registerMediaConversions(function () { $this->addMediaConversion('thumb') ->fit(Manipulations::FIT_CONTAIN, 64, 64) + ->keepOriginalImageFormat() ->optimize(); $this->addMediaConversion('large') ->fit(Manipulations::FIT_CONTAIN, 256, 256) + ->keepOriginalImageFormat() ->optimize(); }); } - public function canAccessPanel(Panel $panel): bool - { - return $this->hasVerifiedEmail(); - } - public function getFilamentAvatarUrl(): ?string { return $this->getFirstMediaUrl('avatar', 'thumb'); @@ -100,9 +98,26 @@ public function getFilamentName(): string return "{$this->first_name} {$this->last_name}"; } + public function canAccessPanel(Panel $panel): bool + { + if (app()->isLocal()) { + return true; + } + + if ($panel->getId() === 'admin') { + return $this->is_admin; + } + + return $this->getTenants($panel)->isNotEmpty(); + } + public function getTenants(Panel $panel): Collection { - return $this->organizations; + if ($panel->getId() === 'organization') { + return $this->organizations; + } + + return collect(); } public function canAccessTenant(Model $tenant): bool diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index e006638c..6f4e5049 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -4,12 +4,12 @@ namespace App\Providers\Filament; +use App\Filament\Admin\Pages; use Filament\Forms\Components\DateTimePicker; use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\DisableBladeIconComponents; use Filament\Http\Middleware\DispatchServingFilamentEvent; use Filament\Infolists\Infolist; -use Filament\Pages; use Filament\Pages\Page; use Filament\Panel; use Filament\PanelProvider; diff --git a/database/factories/AggressorFactory.php b/database/factories/AggressorFactory.php new file mode 100644 index 00000000..646b570f --- /dev/null +++ b/database/factories/AggressorFactory.php @@ -0,0 +1,69 @@ + + */ +class AggressorFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'beneficiary_id' => Beneficiary::factory(), + + 'relationship' => fake()->randomElement(AggressorRelationship::values()), + 'age' => fake()->randomNumber(2), + 'gender' => fake()->randomElement(Gender::values()), + 'civil_status' => fake()->randomElement(CivilStatus::values()), + 'studies' => fake()->randomElement(Studies::values()), + 'occupation' => fake()->randomElement(Occupation::values()), + 'has_violence_history' => fake()->randomElement(Ternary::values()), + 'has_psychiatric_history' => fake()->randomElement(Ternary::values()), + 'has_drug_history' => fake()->randomElement(Ternary::values()), + 'legal_history' => fake()->randomElements(AggressorLegalHistory::values()), + 'has_protection_order' => fake()->randomElement(Ternary::values()), + ]; + } + + public function configure(): static + { + return $this->afterMaking(function (Aggressor $aggressor) { + if (Ternary::isYes($aggressor->has_violence_history)) { + $aggressor->violence_types = fake()->randomElements(Violence::values()); + } + + if (Ternary::isYes($aggressor->has_psychiatric_history)) { + $aggressor->psychiatric_history_notes = fake()->sentence(); + } + + if (Ternary::isYes($aggressor->has_drug_history)) { + $aggressor->drugs = fake()->randomElements(Drug::values()); + } + + if (Ternary::isYes($aggressor->has_protection_order)) { + $aggressor->protection_order_notes = fake()->sentence(); + } + }); + } +} diff --git a/database/factories/BeneficiaryFactory.php b/database/factories/BeneficiaryFactory.php index f4fd172f..a29af642 100644 --- a/database/factories/BeneficiaryFactory.php +++ b/database/factories/BeneficiaryFactory.php @@ -9,6 +9,8 @@ use App\Enums\Gender; use App\Enums\IDType; use App\Enums\ResidenceEnvironment; +use App\Models\Aggressor; +use App\Models\Beneficiary; use App\Models\City; use Illuminate\Database\Eloquent\Factories\Factory; @@ -128,4 +130,13 @@ public function withChildren(): static ]); } + + public function configure(): static + { + return $this->afterCreating(function (Beneficiary $beneficiary) { + Aggressor::factory() + ->for($beneficiary) + ->create(); + }); + } } diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index d6790bf9..5e222f19 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -41,4 +41,14 @@ public function unverified(): static 'email_verified_at' => null, ]); } + + /** + * Indicate that the user is an administrator. + */ + public function admin(): static + { + return $this->state(fn (array $attributes) => [ + 'is_admin' => true, + ]); + } } diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 95c6bcfb..28b68e3f 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -17,6 +17,7 @@ public function up(): void $table->string('last_name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); + $table->boolean('is_admin')->default(false); $table->string('password'); $table->rememberToken(); $table->timestamps(); diff --git a/database/migrations/2023_11_20_130401_create_beneficiaries_table.php b/database/migrations/2023_11_20_130401_create_beneficiaries_table.php index 77d2e482..d0af695e 100644 --- a/database/migrations/2023_11_20_130401_create_beneficiaries_table.php +++ b/database/migrations/2023_11_20_130401_create_beneficiaries_table.php @@ -3,7 +3,6 @@ declare(strict_types=1); use App\Enums\CaseStatus; -use App\Enums\Ternary; use App\Models\Beneficiary; use App\Models\Country; use App\Models\Ethnicity; @@ -85,7 +84,7 @@ public function up(): void $table->text('children_notes')->nullable(); - $table->enum('has_family_doctor', Ternary::values())->nullable(); + $table->string('has_family_doctor')->nullable(); $table->string('family_doctor_name')->nullable(); $table->string('family_doctor_contact')->nullable(); diff --git a/database/migrations/2023_12_14_201551_create_aggressors_table.php b/database/migrations/2023_12_14_201551_create_aggressors_table.php new file mode 100644 index 00000000..74808ae9 --- /dev/null +++ b/database/migrations/2023_12_14_201551_create_aggressors_table.php @@ -0,0 +1,53 @@ +id(); + $table->timestamps(); + + $table->foreignIdFor(Beneficiary::class) + ->constrained() + ->cascadeOnDelete(); + + $table->foreignIdFor(Country::class, 'citizenship_id') + ->nullable() + ->constrained('countries') + ->cascadeOnDelete(); + + $table->string('relationship')->nullable(); + $table->tinyInteger('age')->unsigned()->nullable(); + $table->string('gender')->nullable(); + $table->string('civil_status')->nullable(); + + $table->string('studies')->nullable(); + $table->string('occupation')->nullable(); + + $table->string('has_violence_history')->nullable(); + $table->json('violence_types')->nullable(); + + $table->string('has_psychiatric_history')->nullable(); + $table->string('psychiatric_history_notes')->nullable(); + + $table->string('has_drug_history')->nullable(); + $table->json('drugs')->nullable(); + + $table->json('legal_history')->nullable(); + $table->string('has_protection_order')->nullable(); + $table->string('protection_order_notes')->nullable(); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index f93624a2..7cc72cdc 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -8,6 +8,7 @@ use App\Models\Ethnicity; use App\Models\Organization; use App\Models\Service; +use App\Models\User; use Illuminate\Database\Seeder; use Illuminate\Support\Facades\Mail; @@ -24,6 +25,10 @@ public function run(): void Mail::fake(); + User::factory(['email' => 'admin@example.com']) + ->admin() + ->create(); + Country::factory() ->count(195) ->create(); diff --git a/lang/ro/enum.php b/lang/ro/enum.php index 36576bf0..8bca53c8 100644 --- a/lang/ro/enum.php +++ b/lang/ro/enum.php @@ -82,4 +82,41 @@ -1 => 'Nu știe/ Nu răspunde', ], + 'aggressor_relationship' => [ + 'marital' => 'Maritală', + 'consensual' => 'Relație consensuală (Concubin)', + 'former_partner' => 'Fost partener', + 'parental' => 'Parentală sau asimilată (Agresorul e părinte)', + 'filial' => 'Filiație (Agresorul e Fiul/Fiica)', + 'other_related' => 'Altă relație de rudenie', + 'other' => 'Altă situație', + ], + + 'violence' => [ + 'verbal' => 'Verbală', + 'psychological' => 'Psihologică', + 'physical' => 'Fizică', + 'sexual' => 'Sexuală', + 'economic' => 'Economică', + 'social' => 'Socială', + 'spiritual' => 'Spirituală', + 'cyber' => 'Cibernetică', + 'deprivation' => 'Prin deprivare/ neglijare', + ], + + 'drug' => [ + 'alcohol_occasional' => 'Alcool ocazional', + 'alcohol_frequent' => 'Alcool frecvent', + 'tobacco' => 'Tutun', + 'tranquilizers' => 'Tranchilizante', + 'drugs' => 'Droguri', + 'other' => 'Altele', + ], + + 'aggressor_legal_history' => [ + 'crimes' => 'Infracțiuni', + 'contraventions' => 'Contravenții', + 'protection_order' => 'Ordin de protecție', + ], + ]; diff --git a/lang/ro/field.php b/lang/ro/field.php index 8b0caad7..9ca0abe6 100644 --- a/lang/ro/field.php +++ b/lang/ro/field.php @@ -75,7 +75,7 @@ 'children_18_care_count' => 'Număr copii în întreținere cu vârsta 18 ani+', 'children_accompanying_count' => 'Număr care însoțesc beneficiara', 'doesnt_have_children' => 'Persoana nu are copii', - 'child_name' => 'Nume și preunme copil', + 'child_name' => 'Nume și prenume copil', 'current_address' => 'Domiciliul actual', 'child_status' => 'Statut/ ocupație', 'children_notes' => 'Observații despre copii', @@ -83,9 +83,9 @@ 'family_doctor_name' => 'Nume medic de familie', 'family_doctor_contact' => 'Contact medic de familie', 'psychiatric_history' => 'Antecedente psihiatrice', - 'psychiatric_history_notes' => 'Observații antecedente psihiatrice', + 'psychiatric_notes' => 'Observații antecedente psihiatrice', 'criminal_history' => 'Antecedente penale', - 'criminal_history_notes' => 'Observații antecedente penale', + 'criminal_notes' => 'Observații antecedente penale', 'studies' => 'Studii absolvite', 'occupation' => 'Ocupație', 'workplace' => 'Locul de muncă', @@ -93,4 +93,20 @@ 'elder_care_count' => 'Vârstnici în întreținere (65+)', 'homeownership' => 'Dreptul de proprietate asupra locuinței primare', + 'aggressor_relationship' => 'Relația victimei cu agresorul', + 'aggressor_age' => 'Vârsta agresorului (ani)', + 'aggressor_gender' => 'Genul agresorului', + 'aggressor_citizenship' => 'Cetățenia agresorului', + 'aggressor_civil_status' => 'Stare civilă agresor', + 'aggressor_studies' => 'Studii absolvite agresor', + 'aggressor_occupation' => 'Ocupație agresor', + 'aggressor_has_violence_history' => 'Acte anterioare de VD', + 'aggressor_violence_types' => 'Tipul de VD anterior', + 'aggressor_has_psychiatric_history' => 'Antecedente psihiatrice agresor', + 'aggressor_psychiatric_history_notes' => 'Observații antecendente psihiatrice agresor', + 'aggressor_has_drug_history' => 'Consum de substanțe agresor', + 'aggressor_drugs' => 'Tip de substanțe consumate', + 'aggressor_legal_history' => 'Aspecte legale agresor', + 'has_protection_order' => 'Ordin de protecție', + 'protection_order_notes' => 'Observații ordin de protecție', ]; diff --git a/lang/ro/placeholder.php b/lang/ro/placeholder.php index 2d9a6d95..62dc6c00 100644 --- a/lang/ro/placeholder.php +++ b/lang/ro/placeholder.php @@ -10,7 +10,7 @@ 'prior_name' => 'Alte nume deținute în trecut', 'civil_status' => 'Alege starea civilă', 'cnp' => 'Cod Numeric Personal', - 'select_many' => 'alege răspunsurile care se aplică', + 'select_many' => 'Alege răspunsurile care se aplică', 'select_one' => 'Alege un răspuns', 'id_number' => 'Introdu număr act', 'id_serial' => 'Introdu serie act',