d2d.emegrendeles.hu/app/Filament/Pages/SupplierCustomerCodes.php

173 lines
5.9 KiB
PHP

<?php
namespace App\Filament\Pages;
use App\Models\ProfitCenter;
use App\Models\ProfitCenterSupplierCode;
use App\Models\Supplier;
use Filament\Actions\Action;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Utilities\Get;
use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema;
use Laravel\Pennant\Feature;
class SupplierCustomerCodes extends Page implements HasForms
{
use InteractsWithForms;
protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-identification';
protected string $view = 'filament.pages.supplier-customer-codes';
protected static ?string $title = 'Beszállítói vevőkódok';
protected static ?string $navigationLabel = 'Beszállítói vevőkódok';
protected static bool $shouldRegisterNavigation = false;
public ?array $data = [];
/**
* Rollout-védelem: a SupplierCustomerCode Pennant flag alapján dől el, ki éri el ezt
* az oldalt - a topbar menüpont is ezt hívja (ld. speed-button-nav-bar.blade.php).
*/
public static function canAccess(): bool
{
if (! $user = auth()->user()) {
return false;
}
return Feature::for($user)->active('SupplierCustomerCode');
}
public function mount(): void
{
abort_unless(static::canAccess(), 403);
$this->form->fill();
}
public function form(Schema $form): Schema
{
return $form
->schema([
Grid::make(2)
->schema([
Select::make('supplier_id')
->label('Beszállító')
->options(Supplier::query()->orderBy('name')->pluck('name', 'id'))
->required()
->searchable()
->live()
->afterStateUpdated(fn (?string $state, Set $set) => $this->loadSupplierData($state, $set)),
TextInput::make('search')
->label('Profitcenter keresése')
->placeholder('Kezdjen el gépelni a szűküléshez...')
->live(debounce: 300)
->visible(fn (Get $get) => filled($get('supplier_id'))),
]),
Toggle::make('hasCustomerCode')
->label('Vevőkód funkció aktív ennél a beszállítónál')
->visible(fn (Get $get) => filled($get('supplier_id'))),
Section::make('Profitcenterenkénti vevőkód')
->visible(fn (Get $get) => filled($get('supplier_id')))
->columns(3)
->schema(fn (Get $get) => $this->profitCenterCodeFields($get('search'))),
])
->statePath('data');
}
/**
* @return array<int, TextInput>
*/
private function profitCenterCodeFields(?string $search = null): array
{
return ProfitCenter::query()
->when(filled($search), fn ($query) => $query->where('name', 'like', '%'.$search.'%'))
->orderBy('name')
->get()
->map(fn (ProfitCenter $profitCenter) => TextInput::make("codes.{$profitCenter->id}")
->label($profitCenter->name)
->inlineLabel()
->maxLength(255))
->all();
}
private function loadSupplierData(?string $supplierId, Set $set): void
{
$codes = [];
if ($supplierId) {
$supplier = Supplier::find($supplierId);
$set('hasCustomerCode', (bool) $supplier?->hasCustomerCode);
$codes = ProfitCenterSupplierCode::query()
->where('supplier_id', $supplierId)
->pluck('customerCode', 'profit_center_id')
->all();
} else {
$set('hasCustomerCode', false);
}
foreach (ProfitCenter::query()->pluck('id') as $profitCenterId) {
$set("codes.{$profitCenterId}", $codes[$profitCenterId] ?? null);
}
}
protected function getFormActions(): array
{
return [
Action::make('save')
->label('Mentés')
->submit('save')
->color('primary'),
];
}
public function save(): void
{
$state = $this->form->getState();
$supplierId = $state['supplier_id'];
Supplier::whereKey($supplierId)->update([
'hasCustomerCode' => (bool) ($state['hasCustomerCode'] ?? false),
]);
// A form aktuális szűrés (keresés) miatt csak a látható mezőket adná vissza a getState() -
// a $this->data-ban viszont minden profitcenter kódja benne marad, mert a loadSupplierData()
// mindegyiket explicit beállítja, függetlenül attól, hogy éppen renderelve van-e.
foreach ($this->data['codes'] ?? [] as $profitCenterId => $customerCode) {
$customerCode = is_string($customerCode) ? trim($customerCode) : $customerCode;
if (blank($customerCode)) {
ProfitCenterSupplierCode::query()
->where('supplier_id', $supplierId)
->where('profit_center_id', $profitCenterId)
->delete();
continue;
}
ProfitCenterSupplierCode::updateOrCreate(
['supplier_id' => $supplierId, 'profit_center_id' => $profitCenterId],
['customerCode' => $customerCode],
);
}
Notification::make()
->title('Mentve')
->body('A beszállító vevőkód adatai elmentve.')
->success()
->send();
}
}