Skip to content

Commit 8074422

Browse files
wip
1 parent 9cbd6fe commit 8074422

File tree

5 files changed

+394
-25
lines changed

5 files changed

+394
-25
lines changed

app/Filament/Organizations/Resources/Cases/Pages/DetailedEvaluation/CreateCaseDetailedEvaluation.php

Lines changed: 255 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,29 @@
77
use App\Actions\BackAction;
88
use App\Concerns\PreventMultipleSubmit;
99
use App\Concerns\PreventSubmitFormOnEnter;
10+
use App\Enums\AddressType;
1011
use App\Enums\Applicant;
12+
use App\Enums\Occupation;
1113
use App\Enums\RecommendationService;
1214
use App\Filament\Organizations\Resources\Cases\CaseResource;
15+
use App\Forms\Components\CountyCitySelect;
1316
use App\Forms\Components\DatePicker;
1417
use App\Forms\Components\Select;
1518
use App\Models\Beneficiary;
1619
use App\Models\BeneficiaryPartner;
1720
use Filament\Facades\Filament;
21+
use Filament\Forms\Components\Checkbox;
1822
use Filament\Forms\Components\CheckboxList;
1923
use Filament\Forms\Components\Repeater;
2024
use Filament\Forms\Components\RichEditor;
2125
use Filament\Forms\Components\Textarea;
2226
use Filament\Forms\Components\TextInput;
2327
use Filament\Resources\Pages\CreateRecord\Concerns\HasWizard;
2428
use Filament\Resources\Pages\EditRecord;
29+
use Filament\Schemas\Components\Grid;
2530
use Filament\Schemas\Components\Section;
2631
use Filament\Schemas\Components\Utilities\Get;
32+
use Filament\Schemas\Components\Utilities\Set;
2733
use Filament\Schemas\Components\Wizard\Step;
2834
use Illuminate\Contracts\Support\Htmlable;
2935

@@ -35,6 +41,13 @@ class CreateCaseDetailedEvaluation extends EditRecord
3541

3642
protected static string $resource = CaseResource::class;
3743

44+
/**
45+
* Partner address data captured before save (form state is cleared of these after save).
46+
*
47+
* @var array{legal_residence?: array, effective_residence?: array, same_as_legal_residence?: bool}|null
48+
*/
49+
protected ?array $pendingPartnerAddressData = null;
50+
3851
public function getTitle(): string|Htmlable
3952
{
4053
return __('beneficiary.page.create_detailed_evaluation.title');
@@ -85,13 +98,166 @@ public function getSteps(): array
8598
];
8699
}
87100

101+
/**
102+
* @param array<string, mixed> $data
103+
* @return array<string, mixed>
104+
*/
105+
protected function mutateFormDataBeforeFill(array $data): array
106+
{
107+
$record = $this->getRecord();
108+
if (! $record instanceof Beneficiary) {
109+
return $data;
110+
}
111+
112+
$partner = $record->partner;
113+
if (! $partner) {
114+
return $data;
115+
}
116+
117+
$partner->loadMissing(['legal_residence', 'effective_residence']);
118+
$partnerData = $data['partner'] ?? [];
119+
120+
if ($partner->legal_residence) {
121+
$partnerData['legal_residence'] = array_merge(
122+
$partnerData['legal_residence'] ?? [],
123+
$partner->legal_residence->only(['county_id', 'city_id', 'address'])
124+
);
125+
}
126+
if ($partner->effective_residence) {
127+
$partnerData['effective_residence'] = array_merge(
128+
$partnerData['effective_residence'] ?? [],
129+
$partner->effective_residence->only(['county_id', 'city_id', 'address'])
130+
);
131+
}
132+
133+
$data['partner'] = $partnerData;
134+
135+
return $data;
136+
}
137+
138+
/**
139+
* @param array<string, mixed> $data
140+
* @return array<string, mixed>
141+
*/
142+
protected function mutateFormDataBeforeSave(array $data): array
143+
{
144+
$partnerData = $data['partner'] ?? [];
145+
146+
$rawState = method_exists($this->form, 'getRawState') ? $this->form->getRawState() : (array) $this->data;
147+
$partnerFromState = $data['partner'] ?? $rawState['partner'] ?? [];
148+
$partnerFromLivewire = $rawState['partner'] ?? $this->data['partner'] ?? [];
149+
$legal = $partnerFromState['legal_residence'] ?? $partnerFromLivewire['legal_residence'] ?? [];
150+
$effective = $partnerFromState['effective_residence'] ?? $partnerFromLivewire['effective_residence'] ?? [];
151+
$this->pendingPartnerAddressData = [
152+
'legal_residence' => is_array($legal) ? $legal : [],
153+
'effective_residence' => is_array($effective) ? $effective : [],
154+
'same_as_legal_residence' => (bool) ($partnerFromState['same_as_legal_residence'] ?? $partnerFromLivewire['same_as_legal_residence'] ?? false),
155+
];
156+
157+
unset($partnerData['legal_residence'], $partnerData['effective_residence']);
158+
$data['partner'] = $partnerData;
159+
160+
return $data;
161+
}
162+
88163
public function afterSave(): void
89164
{
90-
$partnerRecord = $this->getRecord()->partner;
165+
$record = $this->getRecord();
166+
if (! $record instanceof Beneficiary) {
167+
return;
168+
}
169+
170+
$partnerRecord = $record->partner;
91171
if ($partnerRecord && $partnerRecord->same_as_legal_residence) {
92172
$partnerRecord->loadMissing(['legal_residence', 'effective_residence']);
93173
BeneficiaryPartner::copyLegalResidenceToEffectiveResidence($partnerRecord);
94174
}
175+
176+
$this->savePartnerAddressesFromFormState();
177+
}
178+
179+
private function savePartnerAddressesFromFormState(): void
180+
{
181+
$record = $this->getRecord();
182+
if (! $record instanceof Beneficiary) {
183+
return;
184+
}
185+
186+
$partner = $record->partner;
187+
if (! $partner) {
188+
return;
189+
}
190+
191+
$partnerState = $this->pendingPartnerAddressData ?? [];
192+
$this->pendingPartnerAddressData = null;
193+
194+
$legalData = $partnerState['legal_residence'] ?? [];
195+
$effectiveData = $partnerState['effective_residence'] ?? [];
196+
$sameAsLegal = (bool) ($partnerState['same_as_legal_residence'] ?? false);
197+
198+
if ($this->hasPartnerAddressData($legalData)) {
199+
$attrs = array_merge(
200+
$this->buildPartnerAddressAttributes($legalData, AddressType::LEGAL_RESIDENCE),
201+
[
202+
'address_type' => AddressType::LEGAL_RESIDENCE,
203+
'addressable_id' => $partner->getKey(),
204+
'addressable_type' => $partner->getMorphClass(),
205+
]
206+
);
207+
$partner->legal_residence()->updateOrCreate(
208+
['addressable_id' => $partner->getKey(), 'addressable_type' => $partner->getMorphClass()],
209+
$attrs
210+
);
211+
} else {
212+
$partner->legal_residence?->delete();
213+
}
214+
215+
$effectivePayload = $sameAsLegal ? $legalData : $effectiveData;
216+
if ($this->hasPartnerAddressData($effectivePayload)) {
217+
$attrs = array_merge(
218+
$this->buildPartnerAddressAttributes($effectivePayload, AddressType::EFFECTIVE_RESIDENCE),
219+
[
220+
'address_type' => AddressType::EFFECTIVE_RESIDENCE,
221+
'addressable_id' => $partner->getKey(),
222+
'addressable_type' => $partner->getMorphClass(),
223+
]
224+
);
225+
$partner->effective_residence()->updateOrCreate(
226+
['addressable_id' => $partner->getKey(), 'addressable_type' => $partner->getMorphClass()],
227+
$attrs
228+
);
229+
} else {
230+
$partner->effective_residence?->delete();
231+
}
232+
}
233+
234+
/**
235+
* @param array<string, mixed> $data
236+
*/
237+
private function hasPartnerAddressData(array $data): bool
238+
{
239+
$countyId = $data['county_id'] ?? null;
240+
$cityId = $data['city_id'] ?? null;
241+
$address = $data['address'] ?? null;
242+
243+
return $countyId !== null || $cityId !== null || filled($address);
244+
}
245+
246+
/**
247+
* @param array<string, mixed> $data
248+
* @return array<string, mixed>
249+
*/
250+
private function buildPartnerAddressAttributes(array $data, AddressType $type): array
251+
{
252+
$attrs = [
253+
'country_id' => $data['country_id'] ?? null,
254+
'county_id' => $data['county_id'] ?? null,
255+
'city_id' => $data['city_id'] ?? null,
256+
'address' => $data['address'] ?? null,
257+
'environment' => $data['environment'] ?? null,
258+
];
259+
260+
return array_filter($attrs, fn ($v) => $v !== null && $v !== '');
95261
}
96262

97263
/**
@@ -106,7 +272,6 @@ protected function getDetailedEvaluationStepSchema(): array
106272
Repeater::make('detailedEvaluationSpecialists')
107273
->relationship('detailedEvaluationSpecialists')
108274
->label(__('beneficiary.section.detailed_evaluation.labels.specialists'))
109-
->minItems(3)
110275
->addActionLabel(__('beneficiary.action.add_row'))
111276
->deletable()
112277
->columns(4)
@@ -163,10 +328,96 @@ protected function getPartnerStepSchema(): array
163328
->relationship('partner')
164329
->maxWidth('3xl')
165330
->schema([
166-
\Filament\Forms\Components\Textarea::make('observations')
331+
Grid::make(2)
332+
->schema([
333+
TextInput::make('last_name')
334+
->label(__('field.last_name'))
335+
->placeholder(__('beneficiary.placeholder.partner_last_name'))
336+
->maxLength(50),
337+
TextInput::make('first_name')
338+
->label(__('field.first_name'))
339+
->placeholder(__('beneficiary.placeholder.partner_first_name'))
340+
->maxLength(50),
341+
TextInput::make('age')
342+
->label(__('field.age'))
343+
->placeholder(__('beneficiary.placeholder.partner_age'))
344+
->numeric()
345+
->minValue(0)
346+
->maxValue(99)
347+
->validationAttribute(__('field.age')),
348+
Select::make('occupation')
349+
->label(__('field.occupation'))
350+
->placeholder(__('beneficiary.placeholder.occupation'))
351+
->options(Occupation::options())
352+
->enum(Occupation::class),
353+
]),
354+
Grid::make()
355+
->schema([
356+
...CountyCitySelect::make()
357+
->countyField('legal_residence.county_id')
358+
->cityField('legal_residence.city_id')
359+
->countyLabel(__('field.legal_residence_county'))
360+
->cityLabel(__('field.legal_residence_city'))
361+
->countyPlaceholder(__('placeholder.county'))
362+
->cityPlaceholder(__('placeholder.city'))
363+
->required(false)
364+
->countyAfterStateUpdated(function (Set $set, Get $get): void {
365+
if ($get('same_as_legal_residence')) {
366+
$set('effective_residence.county_id', $get('legal_residence.county_id'));
367+
$set('effective_residence.city_id', null);
368+
}
369+
})
370+
->cityAfterStateUpdated(function (Set $set, Get $get, $state): void {
371+
if ($get('same_as_legal_residence')) {
372+
$set('effective_residence.city_id', $state);
373+
}
374+
})
375+
->schema(),
376+
TextInput::make('legal_residence.address')
377+
->label(__('field.legal_residence_address'))
378+
->placeholder(__('placeholder.address'))
379+
->maxLength(50),
380+
]),
381+
Checkbox::make('same_as_legal_residence')
382+
->label(__('field.same_as_legal_residence'))
383+
->live()
384+
->afterStateUpdated(function (bool $state, Set $set, Get $get): void {
385+
if (! $state) {
386+
$set('effective_residence.county_id', null);
387+
$set('effective_residence.city_id', null);
388+
$set('effective_residence.address', null);
389+
}
390+
if ($state) {
391+
$set('effective_residence.county_id', $get('legal_residence.county_id'));
392+
$set('effective_residence.city_id', $get('legal_residence.city_id'));
393+
$set('effective_residence.address', $get('legal_residence.address'));
394+
}
395+
})
396+
->columnSpanFull(),
397+
Grid::make()
398+
->schema([
399+
...CountyCitySelect::make()
400+
->countyField('effective_residence.county_id')
401+
->cityField('effective_residence.city_id')
402+
->countyLabel(__('field.effective_residence_county'))
403+
->cityLabel(__('field.effective_residence_city'))
404+
->countyPlaceholder(__('placeholder.county'))
405+
->cityPlaceholder(__('placeholder.city'))
406+
->required(false)
407+
->countyDisabled(fn (Get $get): bool => (bool) $get('same_as_legal_residence'))
408+
->cityDisabled(fn (Get $get): bool => $get('same_as_legal_residence') || ! $get('effective_residence.county_id'))
409+
->schema(),
410+
TextInput::make('effective_residence.address')
411+
->label(__('field.effective_residence_address'))
412+
->placeholder(__('placeholder.address'))
413+
->maxLength(50)
414+
->disabled(fn (Get $get): bool => (bool) $get('same_as_legal_residence')),
415+
]),
416+
Textarea::make('observations')
167417
->label(__('beneficiary.section.detailed_evaluation.labels.observations'))
168418
->placeholder(__('beneficiary.placeholder.partner_relevant_observations'))
169-
->maxLength(500),
419+
->maxLength(500)
420+
->columnSpanFull(),
170421
]),
171422
];
172423
}

0 commit comments

Comments
 (0)