From 66e09c116db6354a0c5d7756ba9f6a3674327a09 Mon Sep 17 00:00:00 2001 From: Alex Popa Date: Tue, 17 Dec 2024 02:36:08 +0200 Subject: [PATCH 1/5] Monthly plan --- .../Resources/InterventionPlanResource.php | 3 + .../Widgets/Interventions.php | 1 + .../Widgets/MonthlyPlanWidget.php | 40 ++++++ .../Resources/MonthlyPlanResource.php | 64 +++++++++ .../Pages/CreateMonthlyPlan.php | 122 ++++++++++++++++++ .../Pages/EditMonthlyPlan.php | 21 +++ .../Pages/ListMonthlyPlans.php | 21 +++ app/Models/InterventionPlan.php | 5 + app/Models/MonthlyPlan.php | 45 +++++++ app/Models/MonthlyPlanInterventions.php | 13 ++ app/Models/MonthlyPlanService.php | 25 ++++ ...2_16_204001_create_monthly_plans_table.php | 36 ++++++ ...909_create_monthly_plan_services_table.php | 39 ++++++ ...reate_monthly_plan_interventions_table.php | 37 ++++++ lang/ro/intervention_plan.php | 9 ++ 15 files changed, 481 insertions(+) create mode 100644 app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php create mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource.php create mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php create mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php create mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ListMonthlyPlans.php create mode 100644 app/Models/MonthlyPlan.php create mode 100644 app/Models/MonthlyPlanInterventions.php create mode 100644 app/Models/MonthlyPlanService.php create mode 100644 database/migrations/2024_12_16_204001_create_monthly_plans_table.php create mode 100644 database/migrations/2024_12_16_210909_create_monthly_plan_services_table.php create mode 100644 database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource.php b/app/Filament/Organizations/Resources/InterventionPlanResource.php index e9e5ddbf..3bc78bae 100644 --- a/app/Filament/Organizations/Resources/InterventionPlanResource.php +++ b/app/Filament/Organizations/Resources/InterventionPlanResource.php @@ -7,6 +7,7 @@ use App\Filament\Organizations\Resources\InterventionServiceResource\Pages\EditCounselingSheet; use App\Filament\Organizations\Resources\InterventionServiceResource\Pages\EditInterventionService; use App\Filament\Organizations\Resources\InterventionServiceResource\Pages\ViewInterventionService; +use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\CreateMonthlyPlan; use App\Models\InterventionPlan; use Filament\Resources\Resource; @@ -24,6 +25,8 @@ public static function getPages(): array 'view_intervention_service' => ViewInterventionService::route('{parent}/service/{record}'), 'edit_intervention_service' => EditInterventionService::route('{parent}/service/{record}/edit'), 'edit_counseling_sheet' => EditCounselingSheet::route('{parent}/service/{record}/editCounselingSheet'), + + 'create_monthly_plan' => CreateMonthlyPlan::route('{parent}/createMonthlyPlan'), ]; } } diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/Interventions.php b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/Interventions.php index 058de199..b719baa8 100644 --- a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/Interventions.php +++ b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/Interventions.php @@ -12,6 +12,7 @@ class Interventions extends MultiWidget ServicesWidget::class, BenefitsWidget::class, ResultsWidget::class, + MonthlyPlanWidget::class, ]; public function shouldPersistMultiWidgetTabsInSession(): bool diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php new file mode 100644 index 00000000..6e778cb7 --- /dev/null +++ b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php @@ -0,0 +1,40 @@ +query(fn () => $this->record->monthlyPlans()) + ->heading(__('intervention_plan.headings.monthly_plans')) + ->headerActions([ + CreateAction::make() + ->label(__('intervention_plan.actions.create_monthly_plan')) + ->url(fn () => InterventionPlanResource::getUrl('create_monthly_plan', ['parent' => $this->record])), + ]) + ->columns([ + TextColumn::make('interval'), + TextColumn::make('caseManager.full_name'), + TextColumn::make('service_count'), + TextColumn::make('intervention_count'), + ]); + } + + public function getDisplayName(): string + { + return __('intervention_plan.headings.monthly_plans'); + } +} diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource.php b/app/Filament/Organizations/Resources/MonthlyPlanResource.php new file mode 100644 index 00000000..4e7aa842 --- /dev/null +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource.php @@ -0,0 +1,64 @@ +schema([ + // + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + // + ]) + ->filters([ + // + ]) + ->actions([ + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListMonthlyPlans::route('/'), + 'create' => Pages\CreateMonthlyPlan::route('/create'), + 'edit' => Pages\EditMonthlyPlan::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php new file mode 100644 index 00000000..0bbe0bfd --- /dev/null +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php @@ -0,0 +1,122 @@ +label(__('intervention_plan.headings.monthly_plan_details')) + ->hidden() + ->schema([ + Section::make() + ->maxWidth('3xl') + ->columns() + ->schema([ + DatePicker::make('start_date') + ->label(__('intervention_plan.labels.monthly_plan_start_date')) + ->required(), + + DatePicker::make('end_date') + ->label(__('intervention_plan.labels.monthly_plan_end_date')) + ->required(), + + Select::make('case_manager_user_id') + ->label(__('intervention_plan.labels.case_manager')) + ->placeholder(__('intervention_plan.placeholders.specialist')) + ->options( + fn () => $this->parent + ->beneficiary + ->specialistsMembers + ->pluck('full_name', 'id') + ) + ->required(), + + Select::make('specialists') + ->label(__('intervention_plan.labels.specialists')) + ->placeholder(__('intervention_plan.placeholders.specialists')) + ->multiple() + ->options( + fn () => $this->parent + ->beneficiary + ->specialistsTeam + ->pluck('name_role', 'id') + ) + ->required(), + ]), + + ]), + + Step::make('services_and_interventions') + ->label(__('intervention_plan.headings.services_and_interventions')) + ->schema([ + Repeater::make('monthlyPlanServices') + ->relationship('monthlyPlanServices') + ->schema([ + Grid::make() + ->maxWidth('3xl') + ->schema([ + Select::make('service_id') + ->relationship('service', 'name'), + + TextInput::make('institution') + ->default(Filament::getTenant()->name), + + TextInput::make('responsible_person') + ->columnSpanFull(), + + Textarea::make('objections') + ->columnSpanFull(), + ]), + + TableRepeater::make('monthlyPlanInterventions') + ->relationship('monthlyPlanInterventions') + ->schema([ + Select::make('intervention_id'), + TextInput::make('objections'), + TextInput::make('observations'), + ]), + ]), + ]), + ]; + } +} diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php new file mode 100644 index 00000000..80c1a724 --- /dev/null +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php @@ -0,0 +1,21 @@ +hasManyThrough(BeneficiaryIntervention::class, InterventionService::class); } + + public function monthlyPlans(): HasMany + { + return $this->hasMany(MonthlyPlan::class); + } } diff --git a/app/Models/MonthlyPlan.php b/app/Models/MonthlyPlan.php new file mode 100644 index 00000000..c98e1561 --- /dev/null +++ b/app/Models/MonthlyPlan.php @@ -0,0 +1,45 @@ + 'date', + 'end_date' => 'date', + 'specialists' => Collection::class, + ]; + + public function interventionPlan(): BelongsTo + { + return $this->belongsTo(InterventionPlan::class); + } + + public function monthlyPlanServices(): HasMany + { + return $this->hasMany(MonthlyPlanService::class); + } + + public function monthlyPlanInterventions(): HasMany + { + return $this->hasMany(MonthlyPlanInterventions::class); + } +} diff --git a/app/Models/MonthlyPlanInterventions.php b/app/Models/MonthlyPlanInterventions.php new file mode 100644 index 00000000..d877eacc --- /dev/null +++ b/app/Models/MonthlyPlanInterventions.php @@ -0,0 +1,13 @@ +belongsTo(Service::class); + } + + public function monthlyPlanInterventions(): HasMany + { + return $this->hasMany(MonthlyPlanInterventions::class); + } +} diff --git a/database/migrations/2024_12_16_204001_create_monthly_plans_table.php b/database/migrations/2024_12_16_204001_create_monthly_plans_table.php new file mode 100644 index 00000000..71c3dadd --- /dev/null +++ b/database/migrations/2024_12_16_204001_create_monthly_plans_table.php @@ -0,0 +1,36 @@ +id(); + $table->foreignIdFor(InterventionPlan::class); + $table->date('start_date'); + $table->date('end_date'); + $table->foreignIdFor(User::class, 'case_manager_user_id'); + $table->json('specialists'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('monthly_plans'); + } +}; diff --git a/database/migrations/2024_12_16_210909_create_monthly_plan_services_table.php b/database/migrations/2024_12_16_210909_create_monthly_plan_services_table.php new file mode 100644 index 00000000..f0b697df --- /dev/null +++ b/database/migrations/2024_12_16_210909_create_monthly_plan_services_table.php @@ -0,0 +1,39 @@ +id(); + $table->foreignIdFor(MonthlyPlan::class); + $table->foreignIdFor(Service::class)->nullable()->constrained()->cascadeOnDelete(); + $table->string('institution')->nullable(); + $table->string('responsible_person')->nullable(); + $table->date('start_date')->nullable(); + $table->date('end_date')->nullable(); + $table->text('objective')->nullable(); + $table->text('service_details')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('monthly_plan_services'); + } +}; diff --git a/database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php b/database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php new file mode 100644 index 00000000..7f524ea4 --- /dev/null +++ b/database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php @@ -0,0 +1,37 @@ +id(); + $table->foreignIdFor(MonthlyPlan::class)->constrained()->cascadeOnDelete(); + $table->foreignIdFor(MonthlyPlanService::class)->constrained()->cascadeOnDelete(); + $table->foreignIdFor(ServiceIntervention::class)->nullable()->constrained()->cascadeOnDelete(); + $table->string('objections')->nullable(); + $table->string('observations')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('monthly_plan_interventions'); + } +}; diff --git a/lang/ro/intervention_plan.php b/lang/ro/intervention_plan.php index 2c58edd7..2495b5a8 100644 --- a/lang/ro/intervention_plan.php +++ b/lang/ro/intervention_plan.php @@ -158,6 +158,10 @@ 'integration_and_participation_in_social_service_observations' => 'Alte observații legate de integrare și participare în serviciul social', 'count' => 'Nr', 'social_relationship' => 'Relația socială #:number', + 'monthly_plan_start_date' => 'Început perioadă de referință', + 'monthly_plan_end_date' => 'Final perioadă de referință', + 'case_manager' => 'Manager caz', + 'specialists' => 'Echipă caz', ], 'headings' => [ @@ -217,6 +221,10 @@ 'professional_experience' => 'Experiența profesională', 'children_details' => 'Date adiționale despre copii', 'integration_and_participation_in_social_service' => 'Integrare și participare în serviciul social', + 'monthly_plans' => 'Planuri lunare', + 'monthly_plan_details' => 'Detalii plan', + 'services_and_interventions' => 'Servicii și intervenții', + 'create_monthly_plan' => 'Creează plan lunar', ], 'actions' => [ @@ -246,6 +254,7 @@ 'organization_service' => 'Alege un serviciu', 'institution' => 'Introdu numele organizației', 'specialist' => 'Alege un specialist', + 'specialists' => 'Alege specialiști', 'objections' => 'Descrieți pe scurt obiectivele acordării serviciului', 'benefit_category' => 'Alege o categorie', 'result_observations' => 'Notați pe scurt orice observații sau notiție relevante pentru activitate', From 2bdd2f176021c048c55512122a20ae1fd7afca82 Mon Sep 17 00:00:00 2001 From: Alex Popa Date: Thu, 19 Dec 2024 02:57:05 +0200 Subject: [PATCH 2/5] Monthly plan --- .../Resources/InterventionPlanResource.php | 6 +- .../Widgets/MonthlyPlanWidget.php | 66 ++++++- .../Pages/CreateMonthlyPlan.php | 166 +++++++++++++++- .../Pages/EditMonthlyPlan.php | 183 ++++++++++++++++++ .../Pages/ViewMonthlyPlan.php | 141 ++++++++++++++ app/Infolists/Components/TableEntry.php | 123 ++++++++++++ app/Models/MonthlyPlan.php | 31 ++- app/Models/MonthlyPlanInterventions.php | 23 +++ app/Models/MonthlyPlanService.php | 16 ++ app/Models/Organization.php | 8 +- .../Breadcrumb/InterventionPlanBreadcrumb.php | 22 +++ ...reate_monthly_plan_interventions_table.php | 2 - lang/ro/intervention_plan.php | 27 +++ .../components/table-entry.blade.php | 118 +++++++++++ 14 files changed, 907 insertions(+), 25 deletions(-) create mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php create mode 100644 app/Infolists/Components/TableEntry.php create mode 100644 resources/views/infolists/components/table-entry.blade.php diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource.php b/app/Filament/Organizations/Resources/InterventionPlanResource.php index 3bc78bae..560a466b 100644 --- a/app/Filament/Organizations/Resources/InterventionPlanResource.php +++ b/app/Filament/Organizations/Resources/InterventionPlanResource.php @@ -8,6 +8,8 @@ use App\Filament\Organizations\Resources\InterventionServiceResource\Pages\EditInterventionService; use App\Filament\Organizations\Resources\InterventionServiceResource\Pages\ViewInterventionService; use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\CreateMonthlyPlan; +use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\EditMonthlyPlan; +use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\ViewMonthlyPlan; use App\Models\InterventionPlan; use Filament\Resources\Resource; @@ -26,7 +28,9 @@ public static function getPages(): array 'edit_intervention_service' => EditInterventionService::route('{parent}/service/{record}/edit'), 'edit_counseling_sheet' => EditCounselingSheet::route('{parent}/service/{record}/editCounselingSheet'), - 'create_monthly_plan' => CreateMonthlyPlan::route('{parent}/createMonthlyPlan'), + 'create_monthly_plan' => CreateMonthlyPlan::route('{parent}/createMonthlyPlan/{copyLastPlan?}'), + 'view_monthly_plan' => ViewMonthlyPlan::route('{parent}/monthlyPlan{record}'), + 'edit_monthly_plan' => EditMonthlyPlan::route('{parent}/monthlyPlan{record}/edit'), ]; } } diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php index 6e778cb7..ac18a776 100644 --- a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php +++ b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php @@ -6,7 +6,10 @@ use App\Filament\Organizations\Resources\InterventionPlanResource; use App\Models\InterventionPlan; +use App\Models\MonthlyPlan; +use Filament\Tables\Actions\Action; use Filament\Tables\Actions\CreateAction; +use Filament\Tables\Actions\ViewAction; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; use Filament\Widgets\TableWidget as BaseWidget; @@ -18,19 +21,68 @@ class MonthlyPlanWidget extends BaseWidget public function table(Table $table): Table { return $table - ->query(fn () => $this->record->monthlyPlans()) + ->query( + fn () => $this->record->monthlyPlans() + ->with('caseManager.user') + ->withCount(['monthlyPlanServices', 'monthlyPlanInterventions']) + ) ->heading(__('intervention_plan.headings.monthly_plans')) ->headerActions([ + Action::make('create_modal') + ->label(__('intervention_plan.actions.create_monthly_plan')) + ->modalHeading(__('intervention_plan.headings.create_monthly_plan_modal')) + ->modalDescription(__('intervention_plan.labels.create_monthly_plan_modal')) + ->modalSubmitAction( + Action::make('crete_from_last') + ->label(__('intervention_plan.actions.create_monthly_plan_from_last')) + ->url(InterventionPlanResource::getUrl('create_monthly_plan', [ + 'parent' => $this->record, + 'copyLastPlan' => 'copyLastPlan', + ])) + ) + ->modalCancelAction( + Action::make('create_simple') + ->label(__('intervention_plan.actions.create_monthly_plan_simple')) + ->outlined() + ->url(InterventionPlanResource::getUrl('create_monthly_plan', ['parent' => $this->record])) + ) + ->visible(fn () => $this->record->monthlyPlans->count()), + CreateAction::make() ->label(__('intervention_plan.actions.create_monthly_plan')) - ->url(fn () => InterventionPlanResource::getUrl('create_monthly_plan', ['parent' => $this->record])), + ->url(InterventionPlanResource::getUrl('create_monthly_plan', ['parent' => $this->record])) + ->visible(fn () => ! $this->record->monthlyPlans->count()), ]) ->columns([ - TextColumn::make('interval'), - TextColumn::make('caseManager.full_name'), - TextColumn::make('service_count'), - TextColumn::make('intervention_count'), - ]); + TextColumn::make('interval') + ->label(__('intervention_plan.headings.interval')), + + TextColumn::make('caseManager.user.full_name') + ->label(__('intervention_plan.headings.case_manager')), + + TextColumn::make('monthly_plan_services_count') + ->label(__('intervention_plan.headings.services_count')), + + TextColumn::make('monthly_plan_interventions_count') + ->label(__('intervention_plan.headings.interventions_count')), + ]) + ->actions([ + ViewAction::make() + ->label(__('general.action.view_details')) + ->url(fn (MonthlyPlan $record) => InterventionPlanResource::getUrl('view_monthly_plan', [ + 'parent' => $this->record, + 'record' => $record, + ])), + ]) + ->recordUrl( + fn (MonthlyPlan $record) => InterventionPlanResource::getUrl('view_monthly_plan', [ + 'parent' => $this->record, + 'record' => $record, + ]) + ) + ->emptyStateHeading(__('intervention_plan.headings.empty_state_monthly_plan_table')) + ->emptyStateDescription(__('intervention_plan.labels.empty_state_monthly_plan_table')) + ->emptyStateIcon('heroicon-o-document'); } public function getDisplayName(): string diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php index 0bbe0bfd..8f9c5e02 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php @@ -7,19 +7,28 @@ use App\Concerns\HasParentResource; use App\Concerns\PreventMultipleSubmit; //use App\Concerns\PreventSubmitFormOnEnter; +use App\Filament\Organizations\Resources\InterventionPlanResource; use App\Filament\Organizations\Resources\MonthlyPlanResource; use App\Forms\Components\DatePicker; use App\Forms\Components\Repeater; use App\Forms\Components\Select; use App\Forms\Components\TableRepeater; +use App\Models\Service; +use App\Services\Breadcrumb\InterventionPlanBreadcrumb; use Filament\Facades\Filament; +use Filament\Forms\Components\Actions\Action; use Filament\Forms\Components\Grid; +use Filament\Forms\Components\Hidden; +use Filament\Forms\Components\Placeholder; use Filament\Forms\Components\Section; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Wizard\Step; +use Filament\Forms\Get; +use Filament\Forms\Set; use Filament\Resources\Pages\CreateRecord; use Filament\Resources\Pages\CreateRecord\Concerns\HasWizard; +use Filament\Support\Enums\Alignment; use Illuminate\Contracts\Support\Htmlable; class CreateMonthlyPlan extends CreateRecord @@ -31,9 +40,12 @@ class CreateMonthlyPlan extends CreateRecord protected static string $resource = MonthlyPlanResource::class; + protected array | null $services = null; + public function getBreadcrumbs(): array { - return []; + return InterventionPlanBreadcrumb::make($this->parent) + ->getCreateMonthlyPlan($this->getRecord()); } public function getTitle(): string|Htmlable @@ -41,12 +53,52 @@ public function getTitle(): string|Htmlable return __('intervention_plan.headings.create_monthly_plan'); } + protected function getRedirectUrl(): string + { + return InterventionPlanResource::getUrl('view_monthly_plan', [ + 'parent' => $this->parent, + 'record' => $this->getRecord(), + ]); + } + + protected function afterFill(): void + { + $copyLastPlan = (bool) request('copyLastPlan'); + + if (! $copyLastPlan) { + $this->form->fill([ + 'start_date' => now(), + 'case_manager_user_id' => $this->parent + ->beneficiary + ->managerTeam + ->first() + ?->user_id, + 'specialists' => $this->parent + ->beneficiary + ->specialistsTeam + ->pluck('id'), + ]); + + return; + } + + $lastPlan = $this->parent + ->monthlyPlans() + ->with(['monthlyPlanServices.monthlyPlanInterventions']) + ->orderByDesc('id') + ->first(); + $this->services = $lastPlan?->monthlyPlanServices + ->toArray(); + + $this->form->fill($lastPlan + ?->toArray()); + } + public function getSteps(): array { return [ Step::make('details') ->label(__('intervention_plan.headings.monthly_plan_details')) - ->hidden() ->schema([ Section::make() ->maxWidth('3xl') @@ -54,10 +106,12 @@ public function getSteps(): array ->schema([ DatePicker::make('start_date') ->label(__('intervention_plan.labels.monthly_plan_start_date')) + ->displayFormat('d-m-Y') ->required(), DatePicker::make('end_date') ->label(__('intervention_plan.labels.monthly_plan_end_date')) + ->displayFormat('d-m-Y') ->required(), Select::make('case_manager_user_id') @@ -84,38 +138,130 @@ public function getSteps(): array ->required(), ]), + Hidden::make('intervention_plan_id') + ->default($this->parent->id), ]), Step::make('services_and_interventions') ->label(__('intervention_plan.headings.services_and_interventions')) + ->afterStateHydrated(function (Set $set, Get $get) { + if (! $this->services) { + return; + } + + $set('monthlyPlanServices', $this->services); + foreach ($get('monthlyPlanServices') as $key => $service) { + $interventionPath = \sprintf('monthlyPlanServices.%s.monthlyPlanInterventions', $key); + $set($interventionPath, $this->services[$key]['monthly_plan_interventions']); + } + }) ->schema([ Repeater::make('monthlyPlanServices') ->relationship('monthlyPlanServices') + ->hiddenLabel() + ->itemLabel(function () { + static $index = 0; + + return __('intervention_plan.headings.service_count', [ + 'number' => ++$index, + ]); + }) + ->addAction( + fn (Action $action) => $action + ->link() + ->label(__('intervention_plan.actions.add_service_repeater')) + ->color('primary') + ) + ->addActionAlignment(Alignment::Left) ->schema([ Grid::make() ->maxWidth('3xl') + ->afterStateHydrated(function (Set $set, Get $get, $state) { + if (! $this->services) { + return; + } + static $index = 0; + debug('fill_interventions'); + $set('monthlyPlanInterventions', $this->services[$index]['monthly_plan_interventions']); + $index++; + }) ->schema([ Select::make('service_id') - ->relationship('service', 'name'), + ->label(__('intervention_plan.labels.service_type')) + ->placeholder(__('intervention_plan.placeholders.select_service')) + ->relationship('service', 'name') + ->required() + ->live(), TextInput::make('institution') - ->default(Filament::getTenant()->name), + ->label(__('intervention_plan.labels.responsible_institution')) + ->placeholder(__('intervention_plan.placeholders.responsible_institution')) + ->default(Filament::getTenant()->name) + ->maxLength(200), TextInput::make('responsible_person') - ->columnSpanFull(), + ->label(__('intervention_plan.labels.responsible_person')) + ->placeholder(__('intervention_plan.placeholders.responsible_person')) + ->columnSpanFull() + ->maxLength(200), + + DatePicker::make('start_date') + ->displayFormat('d-m-Y') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')), + + DatePicker::make('end_date') + ->displayFormat('d-m-Y') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')), - Textarea::make('objections') - ->columnSpanFull(), + Textarea::make('objective') + ->label(__('intervention_plan.labels.service_objective')) + ->placeholder(__('intervention_plan.placeholders.service_objective')) + ->columnSpanFull() + ->maxLength(2000), ]), TableRepeater::make('monthlyPlanInterventions') ->relationship('monthlyPlanInterventions') + ->hiddenLabel() + ->hideLabels() + ->addActionLabel(__('intervention_plan.actions.add_intervention_repeater')) ->schema([ - Select::make('intervention_id'), - TextInput::make('objections'), - TextInput::make('observations'), + Placeholder::make('number') + ->label(__('intervention_plan.labels.count')) + ->hiddenLabel() + ->content(function () { + static $index = 0; + + return ++$index; + }), + + Select::make('service_intervention_id') + ->label(__('intervention_plan.headings.interventions')) + ->placeholder(__('intervention_plan.placeholders.select_intervention')) + ->options( + fn (Get $get) => $get('../../service_id') ? + Service::find((int) $get('../../service_id')) + ->load('serviceInterventions') + ->serviceInterventions + ->pluck('name', 'id') : + [] + ), + + TextInput::make('objections') + ->label(__('intervention_plan.labels.objections')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_objective')) + ->maxLength(200), + + TextInput::make('observations') + ->label(__('intervention_plan.labels.observations')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')) + ->maxLength(200), ]), ]), + + Textarea::make('observations') + ->label(__('intervention_plan.labels.observations')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')), ]), ]; } diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php index 80c1a724..977dfd9c 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php @@ -4,14 +4,197 @@ namespace App\Filament\Organizations\Resources\MonthlyPlanResource\Pages; +use App\Concerns\HasParentResource; +use App\Filament\Organizations\Resources\InterventionPlanResource; use App\Filament\Organizations\Resources\MonthlyPlanResource; +use App\Forms\Components\DatePicker; +use App\Forms\Components\Repeater; +use App\Forms\Components\Select; +use App\Forms\Components\TableRepeater; +use App\Models\Service; use Filament\Actions; +use Filament\Facades\Filament; +use Filament\Forms\Components\Actions\Action; +use Filament\Forms\Components\Grid; +use Filament\Forms\Components\Hidden; +use Filament\Forms\Components\Placeholder; +use Filament\Forms\Components\Section; +use Filament\Forms\Components\Textarea; +use Filament\Forms\Components\TextInput; +use Filament\Forms\Form; +use Filament\Forms\Get; use Filament\Resources\Pages\EditRecord; +use Filament\Support\Enums\Alignment; class EditMonthlyPlan extends EditRecord { + use HasParentResource; + protected static string $resource = MonthlyPlanResource::class; + public function getBreadcrumbs(): array + { + return []; + } + + protected function getRedirectUrl(): ?string + { + return InterventionPlanResource::getUrl('view_monthly_plan', [ + 'parent' => $this->parent, + 'record' => $this->getRecord(), + ]); + } + + public function form(Form $form): Form + { + return $form->schema([ + Section::make('details') + ->label(__('intervention_plan.headings.monthly_plan_details')) + ->schema([ + Section::make() + ->maxWidth('3xl') + ->columns() + ->schema([ + DatePicker::make('start_date') + ->label(__('intervention_plan.labels.monthly_plan_start_date')) + ->required(), + + DatePicker::make('end_date') + ->label(__('intervention_plan.labels.monthly_plan_end_date')) + ->required(), + + Select::make('case_manager_user_id') + ->label(__('intervention_plan.labels.case_manager')) + ->placeholder(__('intervention_plan.placeholders.specialist')) + ->options( + fn () => $this->parent + ->beneficiary + ->specialistsMembers + ->pluck('full_name', 'id') + ) + ->required(), + + Select::make('specialists') + ->label(__('intervention_plan.labels.specialists')) + ->placeholder(__('intervention_plan.placeholders.specialists')) + ->multiple() + ->options( + fn () => $this->parent + ->beneficiary + ->specialistsTeam + ->pluck('name_role', 'id') + ) + ->required(), + ]), + + Hidden::make('intervention_plan_id') + ->default($this->parent->id), + ]), + + Section::make('services_and_interventions') + ->label(__('intervention_plan.headings.services_and_interventions')) + ->schema([ + Repeater::make('monthlyPlanServices') + ->relationship('monthlyPlanServices') + ->hiddenLabel() + ->itemLabel(function () { + static $index = 0; + + return __('intervention_plan.headings.service_count', [ + 'number' => ++$index, + ]); + }) + ->addAction( + fn (Action $action) => $action + ->link() + ->label(__('intervention_plan.actions.add_service_repeater')) + ->color('primary') + ) + ->addActionAlignment(Alignment::Left) + ->schema([ + Grid::make() + ->maxWidth('3xl') + ->schema([ + Select::make('service_id') + ->label(__('intervention_plan.labels.service_type')) + ->placeholder(__('intervention_plan.placeholders.select_service')) + ->relationship('service', 'name') + ->required() + ->live(), + + TextInput::make('institution') + ->label(__('intervention_plan.labels.responsible_institution')) + ->placeholder(__('intervention_plan.placeholders.responsible_institution')) + ->default(Filament::getTenant()->name) + ->maxLength(200), + + TextInput::make('responsible_person') + ->label(__('intervention_plan.labels.responsible_person')) + ->placeholder(__('intervention_plan.placeholders.responsible_person')) + ->columnSpanFull() + ->maxLength(200), + + DatePicker::make('start_date') + ->displayFormat('d-m-Y') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')), + + DatePicker::make('end_date') + ->displayFormat('d-m-Y') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')), + + Textarea::make('objective') + ->label(__('intervention_plan.labels.service_objective')) + ->placeholder(__('intervention_plan.placeholders.service_objective')) + ->columnSpanFull() + ->maxLength(2000), + ]), + + TableRepeater::make('monthlyPlanInterventions') + ->relationship('monthlyPlanInterventions') + ->hiddenLabel() + ->hideLabels() + ->addActionLabel(__('intervention_plan.actions.add_intervention_repeater')) + ->schema([ + Placeholder::make('number') + ->label(__('intervention_plan.labels.count')) + ->hiddenLabel() + ->content(function () { + static $index = 0; + + return ++$index; + }), + + Select::make('service_intervention_id') + ->label(__('intervention_plan.headings.interventions')) + ->placeholder(__('intervention_plan.placeholders.select_intervention')) + ->options( + fn (Get $get) => $get('../../service_id') ? + Service::find((int) $get('../../service_id')) + ->load('serviceInterventions') + ->serviceInterventions + ->pluck('name', 'id') : + [] + ), + + TextInput::make('objections') + ->label(__('intervention_plan.labels.objections')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_objections')) + ->maxLength(200), + + TextInput::make('observations') + ->label(__('intervention_plan.labels.observations')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')) + ->maxLength(200), + ]), + ]), + + Textarea::make('observations') + ->label(__('intervention_plan.labels.observations')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')), + ]), + ]); + } + protected function getHeaderActions(): array { return [ diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php new file mode 100644 index 00000000..c7b827aa --- /dev/null +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php @@ -0,0 +1,141 @@ +parent)->getViewMonthlyPlan($this->getRecord()); + } + + public function getTitle(): string|Htmlable + { + return __('intervention_plan.headings.monthly_plan'); + } + + protected function getHeaderActions(): array + { + return [ + // TODO add download action + // EditAction::make() + // ->url(InterventionPlanResource::getUrl('edit_monthly_plan', [ + // 'parent' => $this->getRecord()->interventionPlan, + // 'record' => $this->getRecord(), + // ])), + ]; + } + + public function infolist(Infolist $infolist): Infolist + { + $this->getRecord() + ->load([ + 'monthlyPlanServices.service', + 'monthlyPlanServices.monthlyPlanInterventions.serviceIntervention', + ]); + + return $infolist->schema([ + Section::make() + ->maxWidth('3xl') + ->columns() + ->schema([ + + TextEntry::make('beneficiary.full_name') + ->label(__('intervention_plan.labels.full_name')), + + TextEntry::make('beneficiary.organization_beneficiary_id') + ->label(__('intervention_plan.labels.organization_beneficiary_id')), + + TextEntry::make('start_date') + ->label(__('intervention_plan.labels.plan_date')) + ->date('d.m.Y'), + + TextEntry::make('interval') + ->label(__('intervention_plan.labels.interval')), + + TextEntry::make('caseManager.user.full_name'), + + TextEntry::make('specialists') + ->formatStateUsing( + fn (string $state) => collect(explode(',', $state)) + ->map( + fn (string $specialistID) => Specialist::find((int) (trim($specialistID))) + ->name_role + ) + ->implode(', ') + ) + ->listWithLineBreaks(), + + RepeatableEntry::make('monthlyPlanServices') + ->hiddenLabel() + ->columns() + ->columnSpanFull() + ->schema([ + SectionHeader::make('service.name'), + + TextEntry::make('institution') + ->label(__('intervention_plan.labels.responsible_institution')), + + TextEntry::make('responsible_person') + ->label(__('intervention_plan.labels.responsible_person')), + + TextEntry::make('start_date') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')) + ->formatStateUsing( + fn ($state) => $state === '-' ? $state : Carbon::parse($state)->format('d.m.Y') + ), + + TextEntry::make('end_date') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')) + ->formatStateUsing( + fn ($state) => $state === '-' ? $state : Carbon::parse($state)->format('d.m.Y') + ), + + TextEntry::make('objective') + ->label(__('intervention_plan.labels.service_objective')), + + TableEntry::make('monthlyPlanInterventions') + ->columnSpanFull() + ->hiddenLabel() + ->schema([ + TextEntry::make('serviceIntervention.name') + ->label(__('intervention_plan.headings.interventions')) + ->hiddenLabel(), + + TextEntry::make('objections') + ->label(__('intervention_plan.labels.objections')) + ->hiddenLabel(), + + TextEntry::make('observations') + ->label(__('intervention_plan.labels.observations')) + ->hiddenLabel(), + ]), + ]), + + ]), + + ]); + } +} diff --git a/app/Infolists/Components/TableEntry.php b/app/Infolists/Components/TableEntry.php new file mode 100644 index 00000000..c69e8486 --- /dev/null +++ b/app/Infolists/Components/TableEntry.php @@ -0,0 +1,123 @@ +breakPoint = $breakPoint; + + return $this; + } + + public function columnWidths(array | Closure $widths = []): static + { + $this->columnWidths = $widths; + + return $this; + } + + public function withoutHeader(bool|Closure $condition = true): static + { + $this->withoutHeader = $condition; + + return $this; + } + + public function emptyLabel(bool|string|Closure|null $label = null): static + { + $this->emptyLabel = $label; + + return $this; + } + + public function alignHeaders(string|Closure $alignment = 'left'): static + { + $this->headersAlignment = $alignment; + + return $this; + } + + public function shouldHideHeader(): bool + { + return $this->evaluate($this->withoutHeader); + } + + public function getBreakPoint(): string + { + return $this->breakPoint; + } + + public function getColumnWidths(): array + { + return $this->evaluate($this->columnWidths); + } + + public function getEmptyLabel(): bool|string|null + { + return $this->evaluate($this->emptyLabel); + } + + public function getHeadersAlignment(): string + { + return $this->evaluate($this->headersAlignment) ?? 'left'; + } + + public function getHeaders(): array + { + $mergedHeaders = []; + + $customHeaders = $this->evaluate($this->headers); + + foreach ($this->getChildComponents() as $field) { + if ($field instanceof Hidden || $field->isHidden()) { + continue; + } + + $key = method_exists($field, 'getName') ? $field->getName() : $field->getId(); + + $isRequired = false; + + if (property_exists($field, 'isRequired') && \is_bool($field->isRequired())) { + $isRequired = $field->isRequired(); + + if (property_exists($field, 'isMarkedAsRequired') && \is_bool($field->isMarkedAsRequired)) { + $isRequired = $field->isRequired() && $field->isMarkedAsRequired; + } + } + + $item = [ + 'label' => $customHeaders[$key] ?? $field->getLabel(), + 'width' => $this->getColumnWidths()[$key] ?? null, + 'required' => $isRequired, + ]; + + $mergedHeaders[method_exists($field, 'getName') ? $field->getName() : $field->getId()] = $item; + } + + $this->headers = $mergedHeaders; + + return $this->evaluate($this->headers); + } +} diff --git a/app/Models/MonthlyPlan.php b/app/Models/MonthlyPlan.php index c98e1561..4effdd4c 100644 --- a/app/Models/MonthlyPlan.php +++ b/app/Models/MonthlyPlan.php @@ -8,11 +8,14 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; -use Illuminate\Support\Collection; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; +use Znck\Eloquent\Relations\BelongsToThrough; +use Znck\Eloquent\Traits\BelongsToThrough as BelongsToThroughTrait; class MonthlyPlan extends Model { use HasFactory; + use BelongsToThroughTrait; protected $fillable = [ 'intervention_plan_id', @@ -25,21 +28,41 @@ class MonthlyPlan extends Model protected $casts = [ 'start_date' => 'date', 'end_date' => 'date', - 'specialists' => Collection::class, + 'specialists' => 'collection', ]; + public function organization(): BelongsToThrough + { + return $this->belongsToThrough(Organization::class, InterventionPlan::class); + } + public function interventionPlan(): BelongsTo { return $this->belongsTo(InterventionPlan::class); } + public function beneficiary(): BelongsToThrough + { + return $this->belongsToThrough(Beneficiary::class, InterventionPlan::class); + } + public function monthlyPlanServices(): HasMany { return $this->hasMany(MonthlyPlanService::class); } - public function monthlyPlanInterventions(): HasMany + public function monthlyPlanInterventions(): HasManyThrough + { + return $this->hasManyThrough(MonthlyPlanInterventions::class, MonthlyPlanService::class); + } + + public function caseManager(): BelongsTo + { + return $this->belongsTo(Specialist::class, 'case_manager_user_id'); + } + + public function getIntervalAttribute(): string { - return $this->hasMany(MonthlyPlanInterventions::class); + return \sprintf('%s - %s', $this->start_date->format('d.m.Y'), $this->end_date->format('d.m.Y')); } } diff --git a/app/Models/MonthlyPlanInterventions.php b/app/Models/MonthlyPlanInterventions.php index d877eacc..1c94bd69 100644 --- a/app/Models/MonthlyPlanInterventions.php +++ b/app/Models/MonthlyPlanInterventions.php @@ -6,8 +6,31 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; class MonthlyPlanInterventions extends Model { use HasFactory; + + protected $fillable = [ + 'monthly_plan_service_id', + 'service_intervention_id', + 'objections', + 'observations', + ]; + + public function monthlyPlan(): BelongsTo + { + return $this->belongsTo(MonthlyPlan::class); + } + + public function monthlyPlanService(): BelongsTo + { + return $this->belongsTo(MonthlyPlanService::class); + } + + public function serviceIntervention(): BelongsTo + { + return $this->belongsTo(ServiceIntervention::class); + } } diff --git a/app/Models/MonthlyPlanService.php b/app/Models/MonthlyPlanService.php index 2d9aa94f..a602cdaa 100644 --- a/app/Models/MonthlyPlanService.php +++ b/app/Models/MonthlyPlanService.php @@ -13,6 +13,22 @@ class MonthlyPlanService extends Model { use HasFactory; + protected $fillable = [ + 'monthly_plan_id', + 'service_id', + 'institution', + 'responsible_person', + 'start_date', + 'end_date', + 'objective', + 'service_details', + ]; + + public function monthlyPlan(): BelongsTo + { + return $this->belongsTo(MonthlyPlan::class); + } + public function service(): BelongsTo { return $this->belongsTo(Service::class); diff --git a/app/Models/Organization.php b/app/Models/Organization.php index de9d8307..5aa3003d 100644 --- a/app/Models/Organization.php +++ b/app/Models/Organization.php @@ -16,6 +16,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\MorphToMany; use Spatie\Image\Enums\Fit; @@ -81,11 +82,16 @@ public function communityProfile(): HasOne }); } - public function monitorings() + public function monitorings(): HasManyThrough { return $this->hasManyThrough(Monitoring::class, Beneficiary::class); } + public function monthlyPlans(): HasManyThrough + { + return $this->hasManyThrough(MonthlyPlan::class, InterventionPlan::class); + } + public function registerMediaCollections(): void { $this->addMediaCollection('logo') diff --git a/app/Services/Breadcrumb/InterventionPlanBreadcrumb.php b/app/Services/Breadcrumb/InterventionPlanBreadcrumb.php index a67241e0..f1c128ce 100644 --- a/app/Services/Breadcrumb/InterventionPlanBreadcrumb.php +++ b/app/Services/Breadcrumb/InterventionPlanBreadcrumb.php @@ -10,6 +10,7 @@ use App\Models\BeneficiaryIntervention; use App\Models\InterventionPlan; use App\Models\InterventionService; +use App\Models\MonthlyPlan; class InterventionPlanBreadcrumb { @@ -62,4 +63,25 @@ public function getInterventionBreadcrumb(BeneficiaryIntervention $record): arra ]) => $record->organizationServiceIntervention->serviceInterventionWithoutStatusCondition->name] ); } + + public function getViewMonthlyPlan(MonthlyPlan $record): array + { + return array_merge( + $this->getInterventionPlanBreadcrumb(), + [self::$resourcePath::getUrl('view_monthly_plan', [ + 'parent' => $this->record, + 'record' => $record, + ]) => __('intervention_plan.headings.monthly_plan')] + ); + } + + public function getCreateMonthlyPlan(): array + { + return array_merge( + $this->getInterventionPlanBreadcrumb(), + [self::$resourcePath::getUrl('create_monthly_plan', [ + 'parent' => $this->record, + ]) => __('intervention_plan.headings.create_monthly_plan')] + ); + } } diff --git a/database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php b/database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php index 7f524ea4..d7e3391d 100644 --- a/database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php +++ b/database/migrations/2024_12_16_213316_create_monthly_plan_interventions_table.php @@ -2,7 +2,6 @@ declare(strict_types=1); -use App\Models\MonthlyPlan; use App\Models\MonthlyPlanService; use App\Models\ServiceIntervention; use Illuminate\Database\Migrations\Migration; @@ -18,7 +17,6 @@ public function up(): void { Schema::create('monthly_plan_interventions', function (Blueprint $table) { $table->id(); - $table->foreignIdFor(MonthlyPlan::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(MonthlyPlanService::class)->constrained()->cascadeOnDelete(); $table->foreignIdFor(ServiceIntervention::class)->nullable()->constrained()->cascadeOnDelete(); $table->string('objections')->nullable(); diff --git a/lang/ro/intervention_plan.php b/lang/ro/intervention_plan.php index 2495b5a8..b6ab942c 100644 --- a/lang/ro/intervention_plan.php +++ b/lang/ro/intervention_plan.php @@ -98,6 +98,7 @@ 'next_meeting' => 'Următoarea', 'empty_state_table_without_intervetntions' => 'Adaugă intervenții în planul beneficiarului, pentru a putea documenta activitățile și ședințele realizate în cadrul serviciilor', 'empty_state_result_table' => 'Poți adăuga rezultate acum sau oricând după crearea planului', + 'empty_state_monthly_plan_table' => 'Poți adăuga planuri lunare acum sau oricând după crearea planului', 'result' => 'Rezultat observat', 'started_at' => 'Demers inițiat la', 'ended_at' => 'Realizat/ soluționat la', @@ -162,6 +163,12 @@ 'monthly_plan_end_date' => 'Final perioadă de referință', 'case_manager' => 'Manager caz', 'specialists' => 'Echipă caz', + 'responsible_person' => 'Persoane responsabile', + 'service_objective' => 'Obiective specifice serviciu', + 'monthly_plan_service_interval_start' => 'Început perioadă de acordare', + 'monthly_plan_service_interval_end' => 'Final perioadă de acordare', + 'organization_beneficiary_id' => 'Nr Caz', + 'create_monthly_plan_modal' => 'Poți alege să începi cu plan lunar necompletată sau cu un duplicat al ultimului plan lunar realizat pe acest caz. Dacă vei porni de la un duplicat, va trebui să modifici informațiile care s-au schimbat de la o lună la alta.', ], 'headings' => [ @@ -209,6 +216,7 @@ 'edit_counseling_sheet' => 'Editează fișă consiliere', 'results_table' => 'Rezultate realizate', 'empty_state_result_table' => 'Nici un rezultat adăugat', + 'empty_state_monthly_plan_table' => 'Nici un plan lunar adăugat', 'result' => 'Rezultat', 'specialist' => 'Specialist', 'started_at' => 'Inițiat la', @@ -225,6 +233,13 @@ 'monthly_plan_details' => 'Detalii plan', 'services_and_interventions' => 'Servicii și intervenții', 'create_monthly_plan' => 'Creează plan lunar', + 'service_count' => 'Serviciul :number', + 'interval' => 'Perioada de referință', + 'case_manager' => 'Manager caz', + 'services_count' => 'Nr servicii', + 'interventions_count' => 'Nr intervenții', + 'monthly_plan' => 'Plan de intervenție lunar', + 'create_monthly_plan_modal' => 'Crează un plan lunar de intervenție nou', ], 'actions' => [ @@ -232,7 +247,9 @@ 'edit' => 'Editează', 'edit_intervention_plan' => 'Actualizează detalii', 'add_service' => 'Adaugă serviciu', + 'add_service_repeater' => 'Adaugă încă un serviciu', 'add_intervention' => 'Adaugă intervenție', + 'add_intervention_repeater' => 'Adaugă intervenție', 'delete_service' => 'Șterge serviciu', 'add_meeting' => 'Adaugă o ședință sau o activitate', 'delete_meeting' => 'Șterge ședința', @@ -247,6 +264,9 @@ 'delete_result' => 'Șterge rezultat', 'add_social_relationship' => 'Adaugă încă o relație socială', 'view_children_identity' => 'Vezi detalii identitate copii', + 'create_monthly_plan' => 'Crează un plan', + 'create_monthly_plan_from_last' => 'Pornește de la un duplicat', + 'create_monthly_plan_simple' => 'Începe cu un plan necompletată', ], 'placeholders' => [ @@ -271,5 +291,12 @@ 'peoples' => 'Introdu un număr', 'add_details' => 'Adaugă detalii', 'select_age' => 'Alege un an', + 'select_service' => 'Alege un serviciu', + 'responsible_institution' => 'Introdu o instituție', + 'responsible_person' => 'Introdu un responsabil', + 'service_objective' => 'Descrie obiectivele specifice ale acordării serviciului în perioada de acordare', + 'select_intervention' => 'Alege o intervenție', + 'monthly_plan_objective' => 'Specifică obiective', + 'monthly_plan_observations' => 'Specifică observații', ], ]; diff --git a/resources/views/infolists/components/table-entry.blade.php b/resources/views/infolists/components/table-entry.blade.php new file mode 100644 index 00000000..20e921e5 --- /dev/null +++ b/resources/views/infolists/components/table-entry.blade.php @@ -0,0 +1,118 @@ +@php + use Filament\Forms\Components\Actions\Action; + + $containers = $getChildComponentContainers(); + + $headers = $getHeaders(); + $columnWidths = $getColumnWidths(); + $breakPoint = $getBreakPoint(); + $hasContainers = count($containers) > 0; + $hasHiddenHeader = $shouldHideHeader(); + $statePath = $getStatePath(); + + $emptyLabel = $getEmptyLabel(); + +@endphp + + +
merge($getExtraAttributes())->class([ + 'filament-table-repeater-component space-y-6 relative', + match ($breakPoint) { + 'sm' => 'break-point-sm', + 'lg' => 'break-point-lg', + 'xl' => 'break-point-xl', + '2xl' => 'break-point-2xl', + default => 'break-point-md', + } + ]) }} + > + @if (count($containers) || $emptyLabel !== false) +
! $hasContainers && $breakPoint === 'sm', + 'md:ring-gray-950/5 dark:md:ring-white/20' => ! $hasContainers && $breakPoint === 'md', + 'lg:ring-gray-950/5 dark:lg:ring-white/20' => ! $hasContainers && $breakPoint === 'lg', + 'xl:ring-gray-950/5 dark:xl:ring-white/20' => ! $hasContainers && $breakPoint === 'xl', + '2xl:ring-gray-950/5 dark:2xl:ring-white/20' => ! $hasContainers && $breakPoint === '2xl', + ])> + + $hasHiddenHeader, + 'filament-table-repeater-header rounded-t-xl overflow-hidden border-b border-gray-950/5 dark:border-white/20' => ! $hasHiddenHeader, + ])> + + @foreach ($headers as $key => $header) + + @endforeach + + + + @if (count($containers)) + @foreach ($containers as $uuid => $row) + + @foreach($row->getComponents() as $cell) + @if(! $cell instanceof \Filament\Forms\Components\Hidden && ! $cell->isHidden()) + + @else + {{ $cell }} + @endif + @endforeach + + + @endforeach + @else + + + + @endif + +
$loop->first, + 'ltr:rounded-tr-xl rtl:rounded-tl-xl' => $loop->last, + match($getHeadersAlignment()) { + 'center' => 'text-center', + 'right' => 'text-right rtl:text-left', + default => 'text-left rtl:text-right' + } + ]) + @if ($header['width']) + style="width: {{ $header['width'] }}" + @endif + > + {{ $header['label'] }} + @if ($header['required']) + + * + + @endif +
$cell->isLabelHidden(), + ]) + @php + $cellKey = method_exists($cell, 'getName') ? $cell->getName() : $cell->getId(); + @endphp + @if ( + $columnWidths && + isset($columnWidths[$cellKey]) + ) + style="width: {{ $columnWidths[$cellKey] }}" + @endif + > + {{ $cell }} +
+ {{ $emptyLabel ?: __('filament-table-repeater::components.repeater.empty.label') }} +
+
+ @endif +
+
From 02751815cbf1759cf5cd417d5b3c74675a6a8989 Mon Sep 17 00:00:00 2001 From: Alex Popa Date: Thu, 19 Dec 2024 19:54:23 +0200 Subject: [PATCH 3/5] Monthly plan --- .../Resources/InterventionPlanResource.php | 6 +- .../Widgets/MonthlyPlanWidget.php | 4 +- .../Resources/MonthlyPlanResource.php | 2 +- .../Pages/CreateMonthlyPlan.php | 183 ++-------------- .../Pages/EditMonthlyPlan.php | 204 ----------------- .../Pages/EditMonthlyPlanDetails.php | 98 +++++++++ ...ditMonthlyPlanServicesAndInterventions.php | 170 ++++++++++++++ .../Pages/ViewMonthlyPlan.php | 207 +++++++++++------- app/Models/MonthlyPlan.php | 2 +- lang/ro/intervention_plan.php | 4 + 10 files changed, 420 insertions(+), 460 deletions(-) delete mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php create mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanDetails.php create mode 100644 app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource.php b/app/Filament/Organizations/Resources/InterventionPlanResource.php index 560a466b..bf31b75a 100644 --- a/app/Filament/Organizations/Resources/InterventionPlanResource.php +++ b/app/Filament/Organizations/Resources/InterventionPlanResource.php @@ -8,7 +8,8 @@ use App\Filament\Organizations\Resources\InterventionServiceResource\Pages\EditInterventionService; use App\Filament\Organizations\Resources\InterventionServiceResource\Pages\ViewInterventionService; use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\CreateMonthlyPlan; -use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\EditMonthlyPlan; +use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\EditMonthlyPlanDetails; +use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\EditMonthlyPlanServicesAndInterventions; use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages\ViewMonthlyPlan; use App\Models\InterventionPlan; use Filament\Resources\Resource; @@ -30,7 +31,8 @@ public static function getPages(): array 'create_monthly_plan' => CreateMonthlyPlan::route('{parent}/createMonthlyPlan/{copyLastPlan?}'), 'view_monthly_plan' => ViewMonthlyPlan::route('{parent}/monthlyPlan{record}'), - 'edit_monthly_plan' => EditMonthlyPlan::route('{parent}/monthlyPlan{record}/edit'), + 'edit_monthly_plan_details' => EditMonthlyPlanDetails::route('{parent}/monthlyPlan{record}/editDetails'), + 'edit_monthly_plan_services_and_interventions' => EditMonthlyPlanServicesAndInterventions::route('{parent}/monthlyPlan{record}/editServicesAndInterventions'), ]; } } diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php index ac18a776..0482c372 100644 --- a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php +++ b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php @@ -23,7 +23,7 @@ public function table(Table $table): Table return $table ->query( fn () => $this->record->monthlyPlans() - ->with('caseManager.user') + ->with('caseManager') ->withCount(['monthlyPlanServices', 'monthlyPlanInterventions']) ) ->heading(__('intervention_plan.headings.monthly_plans')) @@ -57,7 +57,7 @@ public function table(Table $table): Table TextColumn::make('interval') ->label(__('intervention_plan.headings.interval')), - TextColumn::make('caseManager.user.full_name') + TextColumn::make('caseManager.full_name') ->label(__('intervention_plan.headings.case_manager')), TextColumn::make('monthly_plan_services_count') diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource.php b/app/Filament/Organizations/Resources/MonthlyPlanResource.php index 4e7aa842..4c7d7402 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource.php @@ -58,7 +58,7 @@ public static function getPages(): array return [ 'index' => Pages\ListMonthlyPlans::route('/'), 'create' => Pages\CreateMonthlyPlan::route('/create'), - 'edit' => Pages\EditMonthlyPlan::route('/{record}/edit'), + 'edit' => Pages\EditMonthlyPlanDetails::route('/{record}/edit'), ]; } } diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php index 8f9c5e02..a751d5c2 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/CreateMonthlyPlan.php @@ -6,29 +6,16 @@ use App\Concerns\HasParentResource; use App\Concerns\PreventMultipleSubmit; -//use App\Concerns\PreventSubmitFormOnEnter; +use App\Concerns\PreventSubmitFormOnEnter; use App\Filament\Organizations\Resources\InterventionPlanResource; use App\Filament\Organizations\Resources\MonthlyPlanResource; -use App\Forms\Components\DatePicker; -use App\Forms\Components\Repeater; -use App\Forms\Components\Select; -use App\Forms\Components\TableRepeater; -use App\Models\Service; use App\Services\Breadcrumb\InterventionPlanBreadcrumb; use Filament\Facades\Filament; -use Filament\Forms\Components\Actions\Action; -use Filament\Forms\Components\Grid; -use Filament\Forms\Components\Hidden; -use Filament\Forms\Components\Placeholder; -use Filament\Forms\Components\Section; -use Filament\Forms\Components\Textarea; -use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Wizard\Step; use Filament\Forms\Get; use Filament\Forms\Set; use Filament\Resources\Pages\CreateRecord; use Filament\Resources\Pages\CreateRecord\Concerns\HasWizard; -use Filament\Support\Enums\Alignment; use Illuminate\Contracts\Support\Htmlable; class CreateMonthlyPlan extends CreateRecord @@ -36,7 +23,7 @@ class CreateMonthlyPlan extends CreateRecord use HasWizard; use HasParentResource; use PreventMultipleSubmit; -// use PreventSubmitFormOnEnter; + use PreventSubmitFormOnEnter; protected static string $resource = MonthlyPlanResource::class; @@ -66,8 +53,17 @@ protected function afterFill(): void $copyLastPlan = (bool) request('copyLastPlan'); if (! $copyLastPlan) { + $this->services = [ + [ + 'start_date' => now(), + 'end_date' => now()->addMonth(), + 'institution' => Filament::getTenant()->name, + ], + ]; + $this->form->fill([ 'start_date' => now(), + 'end_date' => now()->addMonth(), 'case_manager_user_id' => $this->parent ->beneficiary ->managerTeam @@ -77,6 +73,7 @@ protected function afterFill(): void ->beneficiary ->specialistsTeam ->pluck('id'), + 'intervention_plan_id' => $this->parent->id, ]); return; @@ -99,48 +96,7 @@ public function getSteps(): array return [ Step::make('details') ->label(__('intervention_plan.headings.monthly_plan_details')) - ->schema([ - Section::make() - ->maxWidth('3xl') - ->columns() - ->schema([ - DatePicker::make('start_date') - ->label(__('intervention_plan.labels.monthly_plan_start_date')) - ->displayFormat('d-m-Y') - ->required(), - - DatePicker::make('end_date') - ->label(__('intervention_plan.labels.monthly_plan_end_date')) - ->displayFormat('d-m-Y') - ->required(), - - Select::make('case_manager_user_id') - ->label(__('intervention_plan.labels.case_manager')) - ->placeholder(__('intervention_plan.placeholders.specialist')) - ->options( - fn () => $this->parent - ->beneficiary - ->specialistsMembers - ->pluck('full_name', 'id') - ) - ->required(), - - Select::make('specialists') - ->label(__('intervention_plan.labels.specialists')) - ->placeholder(__('intervention_plan.placeholders.specialists')) - ->multiple() - ->options( - fn () => $this->parent - ->beneficiary - ->specialistsTeam - ->pluck('name_role', 'id') - ) - ->required(), - ]), - - Hidden::make('intervention_plan_id') - ->default($this->parent->id), - ]), + ->schema(EditMonthlyPlanDetails::getSchema($this->parent->beneficiary)), Step::make('services_and_interventions') ->label(__('intervention_plan.headings.services_and_interventions')) @@ -152,117 +108,12 @@ public function getSteps(): array $set('monthlyPlanServices', $this->services); foreach ($get('monthlyPlanServices') as $key => $service) { $interventionPath = \sprintf('monthlyPlanServices.%s.monthlyPlanInterventions', $key); - $set($interventionPath, $this->services[$key]['monthly_plan_interventions']); + $interventions = $this->services[$key]['monthly_plan_interventions'] ?? [[]]; + + $set($interventionPath, $interventions); } }) - ->schema([ - Repeater::make('monthlyPlanServices') - ->relationship('monthlyPlanServices') - ->hiddenLabel() - ->itemLabel(function () { - static $index = 0; - - return __('intervention_plan.headings.service_count', [ - 'number' => ++$index, - ]); - }) - ->addAction( - fn (Action $action) => $action - ->link() - ->label(__('intervention_plan.actions.add_service_repeater')) - ->color('primary') - ) - ->addActionAlignment(Alignment::Left) - ->schema([ - Grid::make() - ->maxWidth('3xl') - ->afterStateHydrated(function (Set $set, Get $get, $state) { - if (! $this->services) { - return; - } - static $index = 0; - debug('fill_interventions'); - $set('monthlyPlanInterventions', $this->services[$index]['monthly_plan_interventions']); - $index++; - }) - ->schema([ - Select::make('service_id') - ->label(__('intervention_plan.labels.service_type')) - ->placeholder(__('intervention_plan.placeholders.select_service')) - ->relationship('service', 'name') - ->required() - ->live(), - - TextInput::make('institution') - ->label(__('intervention_plan.labels.responsible_institution')) - ->placeholder(__('intervention_plan.placeholders.responsible_institution')) - ->default(Filament::getTenant()->name) - ->maxLength(200), - - TextInput::make('responsible_person') - ->label(__('intervention_plan.labels.responsible_person')) - ->placeholder(__('intervention_plan.placeholders.responsible_person')) - ->columnSpanFull() - ->maxLength(200), - - DatePicker::make('start_date') - ->displayFormat('d-m-Y') - ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')), - - DatePicker::make('end_date') - ->displayFormat('d-m-Y') - ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')), - - Textarea::make('objective') - ->label(__('intervention_plan.labels.service_objective')) - ->placeholder(__('intervention_plan.placeholders.service_objective')) - ->columnSpanFull() - ->maxLength(2000), - ]), - - TableRepeater::make('monthlyPlanInterventions') - ->relationship('monthlyPlanInterventions') - ->hiddenLabel() - ->hideLabels() - ->addActionLabel(__('intervention_plan.actions.add_intervention_repeater')) - ->schema([ - Placeholder::make('number') - ->label(__('intervention_plan.labels.count')) - ->hiddenLabel() - ->content(function () { - static $index = 0; - - return ++$index; - }), - - Select::make('service_intervention_id') - ->label(__('intervention_plan.headings.interventions')) - ->placeholder(__('intervention_plan.placeholders.select_intervention')) - ->options( - fn (Get $get) => $get('../../service_id') ? - Service::find((int) $get('../../service_id')) - ->load('serviceInterventions') - ->serviceInterventions - ->pluck('name', 'id') : - [] - ), - - TextInput::make('objections') - ->label(__('intervention_plan.labels.objections')) - ->placeholder(__('intervention_plan.placeholders.monthly_plan_objective')) - ->maxLength(200), - - TextInput::make('observations') - ->label(__('intervention_plan.labels.observations')) - ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')) - ->maxLength(200), - ]), - ]), - - Textarea::make('observations') - ->label(__('intervention_plan.labels.observations')) - ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')), - ]), + ->schema(EditMonthlyPlanServicesAndInterventions::getSchema()), ]; } } diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php deleted file mode 100644 index 977dfd9c..00000000 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlan.php +++ /dev/null @@ -1,204 +0,0 @@ - $this->parent, - 'record' => $this->getRecord(), - ]); - } - - public function form(Form $form): Form - { - return $form->schema([ - Section::make('details') - ->label(__('intervention_plan.headings.monthly_plan_details')) - ->schema([ - Section::make() - ->maxWidth('3xl') - ->columns() - ->schema([ - DatePicker::make('start_date') - ->label(__('intervention_plan.labels.monthly_plan_start_date')) - ->required(), - - DatePicker::make('end_date') - ->label(__('intervention_plan.labels.monthly_plan_end_date')) - ->required(), - - Select::make('case_manager_user_id') - ->label(__('intervention_plan.labels.case_manager')) - ->placeholder(__('intervention_plan.placeholders.specialist')) - ->options( - fn () => $this->parent - ->beneficiary - ->specialistsMembers - ->pluck('full_name', 'id') - ) - ->required(), - - Select::make('specialists') - ->label(__('intervention_plan.labels.specialists')) - ->placeholder(__('intervention_plan.placeholders.specialists')) - ->multiple() - ->options( - fn () => $this->parent - ->beneficiary - ->specialistsTeam - ->pluck('name_role', 'id') - ) - ->required(), - ]), - - Hidden::make('intervention_plan_id') - ->default($this->parent->id), - ]), - - Section::make('services_and_interventions') - ->label(__('intervention_plan.headings.services_and_interventions')) - ->schema([ - Repeater::make('monthlyPlanServices') - ->relationship('monthlyPlanServices') - ->hiddenLabel() - ->itemLabel(function () { - static $index = 0; - - return __('intervention_plan.headings.service_count', [ - 'number' => ++$index, - ]); - }) - ->addAction( - fn (Action $action) => $action - ->link() - ->label(__('intervention_plan.actions.add_service_repeater')) - ->color('primary') - ) - ->addActionAlignment(Alignment::Left) - ->schema([ - Grid::make() - ->maxWidth('3xl') - ->schema([ - Select::make('service_id') - ->label(__('intervention_plan.labels.service_type')) - ->placeholder(__('intervention_plan.placeholders.select_service')) - ->relationship('service', 'name') - ->required() - ->live(), - - TextInput::make('institution') - ->label(__('intervention_plan.labels.responsible_institution')) - ->placeholder(__('intervention_plan.placeholders.responsible_institution')) - ->default(Filament::getTenant()->name) - ->maxLength(200), - - TextInput::make('responsible_person') - ->label(__('intervention_plan.labels.responsible_person')) - ->placeholder(__('intervention_plan.placeholders.responsible_person')) - ->columnSpanFull() - ->maxLength(200), - - DatePicker::make('start_date') - ->displayFormat('d-m-Y') - ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')), - - DatePicker::make('end_date') - ->displayFormat('d-m-Y') - ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')), - - Textarea::make('objective') - ->label(__('intervention_plan.labels.service_objective')) - ->placeholder(__('intervention_plan.placeholders.service_objective')) - ->columnSpanFull() - ->maxLength(2000), - ]), - - TableRepeater::make('monthlyPlanInterventions') - ->relationship('monthlyPlanInterventions') - ->hiddenLabel() - ->hideLabels() - ->addActionLabel(__('intervention_plan.actions.add_intervention_repeater')) - ->schema([ - Placeholder::make('number') - ->label(__('intervention_plan.labels.count')) - ->hiddenLabel() - ->content(function () { - static $index = 0; - - return ++$index; - }), - - Select::make('service_intervention_id') - ->label(__('intervention_plan.headings.interventions')) - ->placeholder(__('intervention_plan.placeholders.select_intervention')) - ->options( - fn (Get $get) => $get('../../service_id') ? - Service::find((int) $get('../../service_id')) - ->load('serviceInterventions') - ->serviceInterventions - ->pluck('name', 'id') : - [] - ), - - TextInput::make('objections') - ->label(__('intervention_plan.labels.objections')) - ->placeholder(__('intervention_plan.placeholders.monthly_plan_objections')) - ->maxLength(200), - - TextInput::make('observations') - ->label(__('intervention_plan.labels.observations')) - ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')) - ->maxLength(200), - ]), - ]), - - Textarea::make('observations') - ->label(__('intervention_plan.labels.observations')) - ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')), - ]), - ]); - } - - protected function getHeaderActions(): array - { - return [ - Actions\DeleteAction::make(), - ]; - } -} diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanDetails.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanDetails.php new file mode 100644 index 00000000..8e2196d5 --- /dev/null +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanDetails.php @@ -0,0 +1,98 @@ +parent) + ->getViewMonthlyPlan($this->getRecord()); + } + + public function getTitle(): string + { + return __('intervention_plan.headings.edit_monthly_plan_title'); + } + + protected function getRedirectUrl(): ?string + { + return InterventionPlanResource::getUrl('view_monthly_plan', [ + 'parent' => $this->parent, + 'record' => $this->getRecord(), + 'tab' => \sprintf('-%s-tab', $this->getTabSlug()), + ]); + } + + protected function getTabSlug(): string + { + return Str::slug(__('intervention_plan.headings.monthly_plan_details')); + } + + public function form(Form $form): Form + { + return $form->schema(self::getSchema($this->parent->beneficiary)); + } + + public static function getSchema(?Beneficiary $beneficiary = null): array + { + return [ + Section::make() + ->maxWidth('3xl') + ->columns() + ->schema([ + DatePicker::make('start_date') + ->label(__('intervention_plan.labels.monthly_plan_start_date')) + ->displayFormat('d-m-Y') + ->required(), + + DatePicker::make('end_date') + ->label(__('intervention_plan.labels.monthly_plan_end_date')) + ->displayFormat('d-m-Y') + ->required(), + + Select::make('case_manager_user_id') + ->label(__('intervention_plan.labels.case_manager')) + ->placeholder(__('intervention_plan.placeholders.specialist')) + ->options( + fn () => $beneficiary + ->specialistsMembers + ->pluck('full_name', 'id') + ) + ->required(), + + Select::make('specialists') + ->label(__('intervention_plan.labels.specialists')) + ->placeholder(__('intervention_plan.placeholders.specialists')) + ->multiple() + ->options( + fn () => $beneficiary + ->specialistsTeam + ->pluck('name_role', 'id') + ) + ->required(), + ]), + + Hidden::make('intervention_plan_id'), + ]; + } +} diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php new file mode 100644 index 00000000..1c7b4f51 --- /dev/null +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php @@ -0,0 +1,170 @@ +parent) + ->getViewMonthlyPlan($this->getRecord()); + } + + public function getTitle(): string + { + return __('intervention_plan.headings.edit_monthly_plan_services_and_interventions_title'); + } + + protected function getRedirectUrl(): ?string + { + return InterventionPlanResource::getUrl('view_monthly_plan', [ + 'parent' => $this->parent, + 'record' => $this->getRecord(), + 'tab' => \sprintf('-%s-tab', $this->getTabSlug()), + ]); + } + + protected function getTabSlug(): string + { + return Str::slug(__('intervention_plan.headings.services_and_interventions')); + } + + public function form(Form $form): Form + { + return $form->schema([ + Section::make(__('intervention_plan.headings.services_and_interventions')) + ->schema($this->getSchema()), + ]); + } + + public static function getSchema(): array + { + return [ + Repeater::make('monthlyPlanServices') + ->relationship('monthlyPlanServices') + ->hiddenLabel() + ->itemLabel(function () { + static $index = 0; + + return __('intervention_plan.headings.service_count', [ + 'number' => ++$index, + ]); + }) + ->addAction( + fn (Action $action) => $action + ->link() + ->label(__('intervention_plan.actions.add_service_repeater')) + ->color('primary') + ) + ->addActionAlignment(Alignment::Left) + ->schema([ + Grid::make() + ->maxWidth('3xl') + ->schema([ + Select::make('service_id') + ->label(__('intervention_plan.labels.service_type')) + ->placeholder(__('intervention_plan.placeholders.select_service')) + ->relationship('service', 'name') + ->required() + ->live(), + + TextInput::make('institution') + ->label(__('intervention_plan.labels.responsible_institution')) + ->placeholder(__('intervention_plan.placeholders.responsible_institution')) + ->default(Filament::getTenant()->name) + ->maxLength(200), + + TextInput::make('responsible_person') + ->label(__('intervention_plan.labels.responsible_person')) + ->placeholder(__('intervention_plan.placeholders.responsible_person')) + ->columnSpanFull() + ->maxLength(200), + + DatePicker::make('start_date') + ->displayFormat('d-m-Y') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')), + + DatePicker::make('end_date') + ->displayFormat('d-m-Y') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')), + + Textarea::make('objective') + ->label(__('intervention_plan.labels.service_objective')) + ->placeholder(__('intervention_plan.placeholders.service_objective')) + ->columnSpanFull() + ->maxLength(2000), + ]), + + TableRepeater::make('monthlyPlanInterventions') + ->relationship('monthlyPlanInterventions') + ->hiddenLabel() + ->hideLabels() + ->addActionLabel(__('intervention_plan.actions.add_intervention_repeater')) + ->schema([ + Placeholder::make('number') + ->label(__('intervention_plan.labels.count')) + ->hiddenLabel() + ->content(function () { + static $index = 0; + + return ++$index; + }), + + Select::make('service_intervention_id') + ->label(__('intervention_plan.headings.interventions')) + ->placeholder(__('intervention_plan.placeholders.select_intervention')) + ->options( + fn (Get $get) => $get('../../service_id') ? + Service::find((int) $get('../../service_id')) + ->load('serviceInterventions') + ->serviceInterventions + ->pluck('name', 'id') : + [] + ), + + TextInput::make('objections') + ->label(__('intervention_plan.labels.objections')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_objective')) + ->maxLength(200), + + TextInput::make('observations') + ->label(__('intervention_plan.labels.observations')) + ->placeholder(__('intervention_plan.placeholders.monthly_plan_observations')) + ->maxLength(200), + ]), + + Textarea::make('service_details') + ->label(__('intervention_plan.labels.service_details')) + ->placeholder(__('intervention_plan.placeholders.service_details')), + ]), + ]; + } +} diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php index c7b827aa..f30b1dec 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php @@ -12,9 +12,11 @@ use App\Models\Specialist; use App\Services\Breadcrumb\InterventionPlanBreadcrumb; use Carbon\Carbon; -use Filament\Actions\EditAction; +use Filament\Infolists\Components\Actions\Action; use Filament\Infolists\Components\RepeatableEntry; use Filament\Infolists\Components\Section; +use Filament\Infolists\Components\Tabs; +use Filament\Infolists\Components\Tabs\Tab; use Filament\Infolists\Components\TextEntry; use Filament\Infolists\Infolist; use Filament\Resources\Pages\ViewRecord; @@ -28,7 +30,8 @@ class ViewMonthlyPlan extends ViewRecord public function getBreadcrumbs(): array { - return InterventionPlanBreadcrumb::make($this->parent)->getViewMonthlyPlan($this->getRecord()); + return InterventionPlanBreadcrumb::make($this->parent) + ->getViewMonthlyPlan($this->getRecord()); } public function getTitle(): string|Htmlable @@ -36,18 +39,6 @@ public function getTitle(): string|Htmlable return __('intervention_plan.headings.monthly_plan'); } - protected function getHeaderActions(): array - { - return [ - // TODO add download action - // EditAction::make() - // ->url(InterventionPlanResource::getUrl('edit_monthly_plan', [ - // 'parent' => $this->getRecord()->interventionPlan, - // 'record' => $this->getRecord(), - // ])), - ]; - } - public function infolist(Infolist $infolist): Infolist { $this->getRecord() @@ -57,83 +48,131 @@ public function infolist(Infolist $infolist): Infolist ]); return $infolist->schema([ - Section::make() - ->maxWidth('3xl') - ->columns() + Tabs::make() + ->persistTabInQueryString() ->schema([ - - TextEntry::make('beneficiary.full_name') - ->label(__('intervention_plan.labels.full_name')), - - TextEntry::make('beneficiary.organization_beneficiary_id') - ->label(__('intervention_plan.labels.organization_beneficiary_id')), - - TextEntry::make('start_date') - ->label(__('intervention_plan.labels.plan_date')) - ->date('d.m.Y'), - - TextEntry::make('interval') - ->label(__('intervention_plan.labels.interval')), - - TextEntry::make('caseManager.user.full_name'), - - TextEntry::make('specialists') - ->formatStateUsing( - fn (string $state) => collect(explode(',', $state)) - ->map( - fn (string $specialistID) => Specialist::find((int) (trim($specialistID))) - ->name_role - ) - ->implode(', ') - ) - ->listWithLineBreaks(), - - RepeatableEntry::make('monthlyPlanServices') - ->hiddenLabel() - ->columns() - ->columnSpanFull() + Tab::make(__('intervention_plan.headings.monthly_plan_details')) ->schema([ - SectionHeader::make('service.name'), - - TextEntry::make('institution') - ->label(__('intervention_plan.labels.responsible_institution')), - - TextEntry::make('responsible_person') - ->label(__('intervention_plan.labels.responsible_person')), - - TextEntry::make('start_date') - ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')) - ->formatStateUsing( - fn ($state) => $state === '-' ? $state : Carbon::parse($state)->format('d.m.Y') - ), - - TextEntry::make('end_date') - ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')) - ->formatStateUsing( - fn ($state) => $state === '-' ? $state : Carbon::parse($state)->format('d.m.Y') - ), - - TextEntry::make('objective') - ->label(__('intervention_plan.labels.service_objective')), - - TableEntry::make('monthlyPlanInterventions') - ->columnSpanFull() - ->hiddenLabel() + Section::make() + ->maxWidth('3xl') + ->columns() ->schema([ - TextEntry::make('serviceIntervention.name') - ->label(__('intervention_plan.headings.interventions')) - ->hiddenLabel(), + SectionHeader::make('monthly_plan_details') + ->state(__('intervention_plan.headings.monthly_plan_details')) + ->action( + Action::make('edit_details') + ->label(__('general.action.edit')) + ->link() + ->url( + InterventionPlanResource::getUrl('edit_monthly_plan_details', [ + 'parent' => $this->parent, + 'record' => $this->getRecord(), + ]) + ) + ), + + TextEntry::make('beneficiary.full_name') + ->label(__('intervention_plan.labels.full_name')), + + TextEntry::make('beneficiary.organization_beneficiary_id') + ->label(__('intervention_plan.labels.organization_beneficiary_id')), + + TextEntry::make('start_date') + ->label(__('intervention_plan.labels.plan_date')) + ->date('d.m.Y'), + + TextEntry::make('interval') + ->label(__('intervention_plan.labels.interval')), + + TextEntry::make('caseManager.full_name') + ->label(__('intervention_plan.labels.case_manager')), + + TextEntry::make('specialists') + ->label(__('intervention_plan.labels.specialists')) + ->formatStateUsing( + fn (string $state) => collect(explode(',', $state)) + ->map( + fn (string $specialistID) => Specialist::find((int) (trim($specialistID))) + ->name_role + ) + ->implode(', ') + ) + ->listWithLineBreaks(), + ]), - TextEntry::make('objections') - ->label(__('intervention_plan.labels.objections')) - ->hiddenLabel(), + ]), - TextEntry::make('observations') - ->label(__('intervention_plan.labels.observations')) - ->hiddenLabel(), + Tab::make(__('intervention_plan.headings.services_and_interventions')) + ->schema([ + Section::make() + ->maxWidth('3xl') + ->schema([ + SectionHeader::make('monthly_plan_details') + ->state(__('intervention_plan.headings.services_and_interventions')) + ->action( + Action::make('edit_details') + ->label(__('general.action.edit')) + ->link() + ->url( + InterventionPlanResource::getUrl('edit_monthly_plan_services_and_interventions', [ + 'parent' => $this->parent, + 'record' => $this->getRecord(), + ]) + ) + ), + + RepeatableEntry::make('monthlyPlanServices') + ->hiddenLabel() + ->columns() + ->columnSpanFull() + ->schema([ + SectionHeader::make('service.name'), + + TextEntry::make('institution') + ->label(__('intervention_plan.labels.responsible_institution')), + + TextEntry::make('responsible_person') + ->label(__('intervention_plan.labels.responsible_person')), + + TextEntry::make('start_date') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_start')) + ->formatStateUsing( + fn ($state) => $state === '-' ? $state : Carbon::parse($state)->format('d.m.Y') + ), + + TextEntry::make('end_date') + ->label(__('intervention_plan.labels.monthly_plan_service_interval_end')) + ->formatStateUsing( + fn ($state) => $state === '-' ? $state : Carbon::parse($state)->format('d.m.Y') + ), + + TextEntry::make('objective') + ->label(__('intervention_plan.labels.service_objective')), + + TableEntry::make('monthlyPlanInterventions') + ->columnSpanFull() + ->hiddenLabel() + ->schema([ + TextEntry::make('serviceIntervention.name') + ->label(__('intervention_plan.headings.interventions')) + ->hiddenLabel(), + + TextEntry::make('objections') + ->label(__('intervention_plan.labels.objections')) + ->hiddenLabel(), + + TextEntry::make('observations') + ->label(__('intervention_plan.labels.observations')) + ->hiddenLabel(), + ]), + + TextEntry::make('service_details') + ->label(__('intervention_plan.labels.service_details')) + ->columnSpanFull(), + ]), ]), - ]), + ]), ]), ]); diff --git a/app/Models/MonthlyPlan.php b/app/Models/MonthlyPlan.php index 4effdd4c..70892b98 100644 --- a/app/Models/MonthlyPlan.php +++ b/app/Models/MonthlyPlan.php @@ -58,7 +58,7 @@ public function monthlyPlanInterventions(): HasManyThrough public function caseManager(): BelongsTo { - return $this->belongsTo(Specialist::class, 'case_manager_user_id'); + return $this->belongsTo(User::class, 'case_manager_user_id'); } public function getIntervalAttribute(): string diff --git a/lang/ro/intervention_plan.php b/lang/ro/intervention_plan.php index 758ac384..7b0ba074 100644 --- a/lang/ro/intervention_plan.php +++ b/lang/ro/intervention_plan.php @@ -172,6 +172,7 @@ 'beneficiary' => 'Beneficiar', 'actions' => 'Acțiuni', 'selected_interval' => 'Interval selectat', + 'service_details' => 'Detalii acordare serviciu', ], 'headings' => [ @@ -245,6 +246,8 @@ 'create_monthly_plan_modal' => 'Crează un plan lunar de intervenție nou', 'dashboard_intervention_table' => 'Sumar intervenții', 'dashboard_intervention_table_empty_state' => 'Odată deschis primul caz și creat primul plan de intervenție pentru acesta, o listă a intervențiilor va fi afișată în acest tabel.', + 'edit_monthly_plan_title' => 'Editează plan lunar', + 'edit_monthly_plan_services_and_interventions_title' => 'Editează servicii si intervenții', ], 'actions' => [ @@ -304,5 +307,6 @@ 'monthly_plan_objective' => 'Specifică obiective', 'monthly_plan_observations' => 'Specifică observații', 'search_by_beneficiary_or_specialist' => 'Caută caz sau specialist', + 'service_details' => 'Adaugă orice detalii relevante acordării intervenției sau intervențiilor', ], ]; From 5d86d10d25c79e3b5e09be75b170b1736e57d9ba Mon Sep 17 00:00:00 2001 From: Alex Popa Date: Fri, 20 Dec 2024 00:55:42 +0200 Subject: [PATCH 4/5] Policy and delete action --- .../Widgets/MonthlyPlanWidget.php | 2 +- .../Pages/ViewMonthlyPlan.php | 20 ++++++ app/Policies/MonthlyPlanPolicy.php | 67 +++++++++++++++++++ lang/ro/intervention_plan.php | 2 + 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 app/Policies/MonthlyPlanPolicy.php diff --git a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php index 0482c372..64d13b8a 100644 --- a/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php +++ b/app/Filament/Organizations/Resources/InterventionPlanResource/Widgets/MonthlyPlanWidget.php @@ -23,7 +23,7 @@ public function table(Table $table): Table return $table ->query( fn () => $this->record->monthlyPlans() - ->with('caseManager') + ->with(['caseManager', 'beneficiary']) ->withCount(['monthlyPlanServices', 'monthlyPlanInterventions']) ) ->heading(__('intervention_plan.headings.monthly_plans')) diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php index f30b1dec..7f0759e0 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/ViewMonthlyPlan.php @@ -5,6 +5,7 @@ namespace App\Filament\Organizations\Resources\MonthlyPlanResource\Pages; use App\Concerns\HasParentResource; +use App\Filament\Organizations\Resources\BeneficiaryResource; use App\Filament\Organizations\Resources\InterventionPlanResource; use App\Filament\Organizations\Resources\MonthlyPlanResource; use App\Infolists\Components\SectionHeader; @@ -12,6 +13,7 @@ use App\Models\Specialist; use App\Services\Breadcrumb\InterventionPlanBreadcrumb; use Carbon\Carbon; +use Filament\Actions\DeleteAction; use Filament\Infolists\Components\Actions\Action; use Filament\Infolists\Components\RepeatableEntry; use Filament\Infolists\Components\Section; @@ -39,6 +41,24 @@ public function getTitle(): string|Htmlable return __('intervention_plan.headings.monthly_plan'); } + public function getHeaderActions(): array + { + return [ + DeleteAction::make() + ->label(__('intervention_plan.actions.delete_monthly_plan')) + ->icon('heroicon-o-trash') + ->modalHeading(__('intervention_plan.headings.delete_monthly_plan_modal')) + ->modalSubmitActionLabel(__('intervention_plan.actions.delete_monthly_plan')) + ->successRedirectUrl( + BeneficiaryResource::getUrl('view_intervention_plan', [ + 'parent' => $this->parent->beneficiary, + 'record' => $this->parent, + ]) + ) + ->outlined(), + ]; + } + public function infolist(Infolist $infolist): Infolist { $this->getRecord() diff --git a/app/Policies/MonthlyPlanPolicy.php b/app/Policies/MonthlyPlanPolicy.php new file mode 100644 index 00000000..b5b27490 --- /dev/null +++ b/app/Policies/MonthlyPlanPolicy.php @@ -0,0 +1,67 @@ +hasAccessToBeneficiary($monthlyPlan->beneficiary); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, MonthlyPlan $monthlyPlan): bool + { + return $user->hasAccessToBeneficiary($monthlyPlan->beneficiary); + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, MonthlyPlan $monthlyPlan): bool + { + return $user->hasAccessToBeneficiary($monthlyPlan->beneficiary); + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, MonthlyPlan $monthlyPlan): bool + { + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, MonthlyPlan $monthlyPlan): bool + { + return true; + } +} diff --git a/lang/ro/intervention_plan.php b/lang/ro/intervention_plan.php index 7b0ba074..434a8f88 100644 --- a/lang/ro/intervention_plan.php +++ b/lang/ro/intervention_plan.php @@ -248,6 +248,7 @@ 'dashboard_intervention_table_empty_state' => 'Odată deschis primul caz și creat primul plan de intervenție pentru acesta, o listă a intervențiilor va fi afișată în acest tabel.', 'edit_monthly_plan_title' => 'Editează plan lunar', 'edit_monthly_plan_services_and_interventions_title' => 'Editează servicii si intervenții', + 'delete_monthly_plan_modal' => 'Șterge plan lunar', ], 'actions' => [ @@ -275,6 +276,7 @@ 'create_monthly_plan' => 'Crează un plan', 'create_monthly_plan_from_last' => 'Pornește de la un duplicat', 'create_monthly_plan_simple' => 'Începe cu un plan necompletată', + 'delete_monthly_plan' => 'Șterge planul lunar', ], 'placeholders' => [ From dda014ffdb6a2c61c73168a1f1639ac497778af7 Mon Sep 17 00:00:00 2001 From: Alex Popa Date: Fri, 20 Dec 2024 11:46:27 +0200 Subject: [PATCH 5/5] Service status and cleanup --- .../Resources/MonthlyPlanResource.php | 37 ------------------- ...ditMonthlyPlanServicesAndInterventions.php | 36 ++++++++++++++---- app/Models/Service.php | 12 +++--- 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource.php b/app/Filament/Organizations/Resources/MonthlyPlanResource.php index 4c7d7402..211cfde7 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource.php @@ -6,10 +6,7 @@ use App\Filament\Organizations\Resources\MonthlyPlanResource\Pages; use App\Models\MonthlyPlan; -use Filament\Forms\Form; use Filament\Resources\Resource; -use Filament\Tables; -use Filament\Tables\Table; class MonthlyPlanResource extends Resource { @@ -19,40 +16,6 @@ class MonthlyPlanResource extends Resource public static string $parentResource = InterventionPlanResource::class; - public static function form(Form $form): Form - { - return $form - ->schema([ - // - ]); - } - - public static function table(Table $table): Table - { - return $table - ->columns([ - // - ]) - ->filters([ - // - ]) - ->actions([ - Tables\Actions\EditAction::make(), - ]) - ->bulkActions([ - Tables\Actions\BulkActionGroup::make([ - Tables\Actions\DeleteBulkAction::make(), - ]), - ]); - } - - public static function getRelations(): array - { - return [ - // - ]; - } - public static function getPages(): array { return [ diff --git a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php index 1c7b4f51..86008bbd 100644 --- a/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php +++ b/app/Filament/Organizations/Resources/MonthlyPlanResource/Pages/EditMonthlyPlanServicesAndInterventions.php @@ -12,6 +12,7 @@ use App\Forms\Components\Select; use App\Forms\Components\TableRepeater; use App\Models\Service; +use App\Models\ServiceIntervention; use App\Services\Breadcrumb\InterventionPlanBreadcrumb; use Filament\Facades\Filament; use Filament\Forms\Components\Actions\Action; @@ -92,7 +93,18 @@ public static function getSchema(): array Select::make('service_id') ->label(__('intervention_plan.labels.service_type')) ->placeholder(__('intervention_plan.placeholders.select_service')) - ->relationship('service', 'name') + ->options(function (?int $state) { + $services = Service::query() + ->active() + ->get() + ->pluck('name', 'id'); + + if ($state && ! isset($services[$state])) { + $services[$state] = Service::find($state)->name; + } + + return $services; + }) ->required() ->live(), @@ -142,12 +154,22 @@ public static function getSchema(): array ->label(__('intervention_plan.headings.interventions')) ->placeholder(__('intervention_plan.placeholders.select_intervention')) ->options( - fn (Get $get) => $get('../../service_id') ? - Service::find((int) $get('../../service_id')) - ->load('serviceInterventions') - ->serviceInterventions - ->pluck('name', 'id') : - [] + function (Get $get, ?int $state) { + if (! $get('../../service_id')) { + return []; + } + + $interventions = Service::find((int) $get('../../service_id')) + ->load('activeServiceInterventions') + ->activeServiceInterventions + ->pluck('name', 'id'); + + if ($state && ! isset($interventions[$state])) { + $interventions[$state] = ServiceIntervention::find($state)->name; + } + + return $interventions; + } ), TextInput::make('objections') diff --git a/app/Models/Service.php b/app/Models/Service.php index 312f7f2b..f7763688 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -10,8 +10,6 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; -use Illuminate\Database\Eloquent\Relations\HasManyThrough; -use Illuminate\Database\Eloquent\Relations\HasOne; class Service extends Model { @@ -27,16 +25,16 @@ class Service extends Model 'counseling_sheet' => CounselingSheet::class, ]; -// public function counselingSheet(): HasOne -// { -// -// } - public function serviceInterventions(): HasMany { return $this->hasMany(ServiceIntervention::class); } + public function activeServiceInterventions(): HasMany + { + return $this->serviceInterventions()->active(); + } + public function interventions(): HasMany { return $this->hasMany(Intervention::class);