From 028d985e9f76c3583d3963f0e14386ef5d4a7441 Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Sat, 30 May 2026 11:56:57 +0530 Subject: [PATCH 1/3] Added crud admin rights to particular users and edit email permission to particular user --- app/Filament/Imports/UserImporter.php | 25 ++++++++++++++++++------- app/Filament/Resources/UserResource.php | 13 +++++++++---- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/app/Filament/Imports/UserImporter.php b/app/Filament/Imports/UserImporter.php index da3758d..abb1b56 100644 --- a/app/Filament/Imports/UserImporter.php +++ b/app/Filament/Imports/UserImporter.php @@ -8,6 +8,7 @@ use Filament\Actions\Imports\Exceptions\RowImportFailedException; use Filament\Actions\Imports\ImportColumn; use Filament\Actions\Imports\Importer; use Filament\Actions\Imports\Models\Import; +use Filament\Facades\Filament; use Spatie\Permission\Models\Role; use Str; @@ -56,6 +57,12 @@ class UserImporter extends Importer $warnMsg = []; $plantCod = $this->data['plant_id']; $plant = null; + $user = $this->data['name']; + $mail = $this->data['email']; + $pass = $this->data['password']; + $restrictedUsers = ['Admin', 'Dhanabalan S', 'Ranjith B']; + $adminUser = Filament::auth()->user()?->name; + if (Str::length($plantCod) > 0 && (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod))) { $warnMsg[] = 'Invalid plant code found!'; } elseif (Str::length($plantCod) <= 0) { @@ -70,14 +77,14 @@ class UserImporter extends Importer } } - if (Str::length($this->data['name']) < 3) { + if (Str::length($user) < 3) { $warnMsg[] = 'Invalid user name found!'; } // || !is_numeric($this->data['code']) || !preg_match('/^[1-9]\d{3,}$/', $this->data['code']) - if (Str::length($this->data['email']) < 5) { + if (Str::length($mail) < 5) { $warnMsg[] = 'Invalid email found!'; } - if (Str::length($this->data['password']) < 3) { + if (Str::length($pass) < 3) { $warnMsg[] = 'Invalid password found!'; } // Validate roles if provided @@ -97,16 +104,20 @@ class UserImporter extends Importer $warnMsg[] = 'User roles not found!'; } + if (! in_array($adminUser, $restrictedUsers, true) && in_array($user, $restrictedUsers, true)) { + throw new RowImportFailedException("You don't have permission to import user with name '{$user}'!"); + } + if (! empty($warnMsg)) { throw new RowImportFailedException(implode(', ', $warnMsg)); } $user = User::updateOrCreate([ - 'email' => $this->data['email'], + 'email' => $mail, ], [ - 'name' => $this->data['name'], - 'password' => $this->data['password'], + 'name' => $user, + 'password' => $pass, 'plant_id' => $plant, ]); @@ -118,7 +129,7 @@ class UserImporter extends Importer return null; // return User::firstOrNew([ // // Update existing records, matching them by `$this->data['column_name']` - // 'email' => $this->data['email'], + // 'email' => $mail, // ]); // return new User(); diff --git a/app/Filament/Resources/UserResource.php b/app/Filament/Resources/UserResource.php index 308a290..dc7aabf 100644 --- a/app/Filament/Resources/UserResource.php +++ b/app/Filament/Resources/UserResource.php @@ -10,6 +10,7 @@ use App\Models\User; use Filament\Facades\Filament; use Filament\Forms; use Filament\Forms\Form; +use Filament\Forms\Get; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Actions\ExportAction; @@ -53,16 +54,19 @@ class UserResource extends Resource ->minLength(3) // ->reactive() ->live(debounce: 600) + ->disabled(fn (Get $get) => ! empty($get('id')) && Filament::auth()->user()?->name != 'Admin' && Filament::auth()->user()?->name != 'Dhanabalan S' && Filament::auth()->user()?->name != 'Ranjith B' && ($get('name') == 'Admin' || $get('name') == 'Dhanabalan S' || $get('name') == 'Ranjith B')) ->afterStateUpdated(function ($state, callable $set, callable $get) { - $set('email', $state.'@cripumps.com'); + if (Filament::auth()->user()?->name != 'Dhanabalan S') { + $set('email', $state.'@cripumps.com'); + } }) ->maxLength(255), Forms\Components\TextInput::make('email') ->label('Email') + ->required() // ->email() ->unique(ignoreRecord: true) - ->required() - ->readOnly() + ->readOnly(fn () => Filament::auth()->user()?->name != 'Dhanabalan S') // ->rule(function (callable $get) { // return Rule::unique('users', 'email') // ->ignore($get('id')); // Ignore current record during updates @@ -75,10 +79,11 @@ class UserResource extends Resource ->label('Email Verified At'), Forms\Components\TextInput::make('password') ->label('Password') + ->required() ->password() ->minLength(3) ->revealable() - ->required() + ->disabled(fn (Get $get) => ! empty($get('id')) && Filament::auth()->user()?->name != 'Admin' && Filament::auth()->user()?->name != 'Dhanabalan S' && Filament::auth()->user()?->name != 'Ranjith B' && ($get('name') == 'Admin' || $get('name') == 'Dhanabalan S' || $get('name') == 'Ranjith B')) // ->dehydrateStateUsing(fn (string $state): string => Hash::make($state)) ->maxLength(255), // Forms\Components\Select::make('roles') From 968a564109fdf89c7f79adbe477090d6d58e78b5 Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Sat, 30 May 2026 13:44:43 +0530 Subject: [PATCH 2/3] Updated validation logic on edit --- .../Resources/LeakTestReadingResource.php | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/Filament/Resources/LeakTestReadingResource.php b/app/Filament/Resources/LeakTestReadingResource.php index eeb1be6..d3e747d 100644 --- a/app/Filament/Resources/LeakTestReadingResource.php +++ b/app/Filament/Resources/LeakTestReadingResource.php @@ -58,6 +58,8 @@ class LeakTestReadingResource extends Resource $plantId = $get('plant_id'); $set('lsrPlantError', null); + $set('lsrCodeError', null); + $set('lsrSerialError', null); $set('item_code', null); $set('serial_number', null); $set('test_status', null); @@ -80,10 +82,10 @@ class LeakTestReadingResource extends Resource ->alphaNum() ->minLength(6) ->reactive() - ->disabled(fn (Get $get) => ! empty($get('id'))) + ->disabled(fn (Get $get) => ! empty($get('id')) && ! Filament::auth()->user()->hasRole('Super Admin')) ->afterStateUpdated(function ($state, callable $set, callable $get) { $code = $get('item_code'); - // Ensure `linestop_id` is not cleared + $set('lsrCodeError', null); if (! $code) { $set('lsrCodeError', 'Scan the valid item code.'); @@ -95,7 +97,9 @@ class LeakTestReadingResource extends Resource return; } elseif (! ctype_alnum($code)) { $set('item_code', null); - $set('lsrSerialError', 'Item code must contain only alpha-numeric characters!'); + $set('lsrCodeError', 'Item code must contain only alpha-numeric characters!'); + + return; } elseif (! preg_match('/^[a-zA-Z1-9][a-zA-Z0-9]{5,}$/', $code)) { $set('item_code', null); $set('lsrCodeError', "Item code should not begin with '0' or letter!"); @@ -117,10 +121,10 @@ class LeakTestReadingResource extends Resource ->alphaNum() ->minLength(9) ->reactive() - ->disabled(fn (Get $get) => ! empty($get('id'))) + ->disabled(fn (Get $get) => ! empty($get('id')) && ! Filament::auth()->user()->hasRole('Super Admin')) ->afterStateUpdated(function ($state, callable $set, callable $get) { $serial = $get('serial_number'); - // Ensure `linestop_id` is not cleared + $set('lsrSerialError', null); if (! $serial) { $set('lsrSerialError', 'Scan the valid serial number!'); @@ -133,6 +137,8 @@ class LeakTestReadingResource extends Resource } elseif (! ctype_alnum($serial)) { $set('serial_number', null); $set('lsrSerialError', 'Serial number must contain only alpha-numeric characters!'); + + return; } elseif (! preg_match('/^[1-9][a-zA-Z0-9]{8,}$/', $serial)) { $set('serial_number', null); $set('lsrSerialError', "Serial number should not begin with '0' or letter!"); @@ -152,6 +158,7 @@ class LeakTestReadingResource extends Resource ->label('Test Status') ->searchable() ->reactive() + // ->disabled(fn (Get $get) => ! empty($get('id'))) ->options(function (callable $set, callable $get) { $plantId = $get('plant_id'); $itemCode = $get('item_code'); From 693c20300134cfe1285d97e7eb2e090e8861bba2 Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Sat, 30 May 2026 16:43:18 +0530 Subject: [PATCH 3/3] Added logic for item code filteration in table section --- .../Resources/AsrsItemValidationResource.php | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/app/Filament/Resources/AsrsItemValidationResource.php b/app/Filament/Resources/AsrsItemValidationResource.php index 094e7a4..7cf5938 100644 --- a/app/Filament/Resources/AsrsItemValidationResource.php +++ b/app/Filament/Resources/AsrsItemValidationResource.php @@ -24,6 +24,7 @@ use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\DateTimePicker; use App\Models\Plant; +use Illuminate\Support\Facades\Auth; class AsrsItemValidationResource extends Resource { @@ -148,7 +149,11 @@ class AsrsItemValidationResource extends Resource Tables\Columns\TextColumn::make('item_code') ->label('Item Code') ->alignCenter() - ->searchable() + ->searchable(query: function ($query, string $search) { + $itemCode = explode('|', trim($search))[0]; + $query->where('item_code', $itemCode); + }) + // ->searchable() ->sortable(), Tables\Columns\TextColumn::make('item_description') ->label('Item Description') @@ -238,12 +243,17 @@ class AsrsItemValidationResource extends Resource } return AsrsItemValidation::where('plant_id', $plantId) + ->distinct() ->pluck('item_code', 'item_code') ->toArray(); }) ->afterStateUpdated(function ($state, callable $set, callable $get) { $set('Rework', null); }), + TextInput::make('uom') + ->label('UOM') + ->reactive() + ->placeholder('Enter UOM'), Select::make('status') ->label('Status') ->reactive() @@ -286,6 +296,7 @@ class AsrsItemValidationResource extends Resource if ( empty($data['Plant']) && empty($data['item_code']) && + empty($data['uom']) && empty($data['status']) && empty($data['created_from']) && empty($data['created_to']) @@ -311,7 +322,9 @@ class AsrsItemValidationResource extends Resource if (! empty($data['item_code'])) { $query->where('item_code', 'like', '%'.$data['item_code'].'%'); } - + if (! empty($data['uom'])) { + $query->where('uom', 'like', '%'.$data['uom'].'%'); + } if (!empty($data['status'])) { if ($data['status'] == 'NotUpdated') { @@ -351,6 +364,10 @@ class AsrsItemValidationResource extends Resource $indicators[] = 'Item Code: '.$data['item_code']; } + if (! empty($data['uom'])) { + $indicators[] = 'UOM: '.$data['uom']; + } + if (! empty($data['status'])) { $indicators[] = 'Status: '.$data['status']; } @@ -369,7 +386,15 @@ class AsrsItemValidationResource extends Resource ->filtersFormMaxHeight('280px') ->actions([ Tables\Actions\ViewAction::make(), - Tables\Actions\EditAction::make(), + Tables\Actions\EditAction::make() + ->hidden(function ($record): bool { + if (auth()->user()?->hasRole('SuperAdmin')) { + return false; + } + + return empty($record->status) + || trim(strtolower($record->status)) == 'updated'; + }), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([