From 75fd3d98413a0739f68e03427c642d249427c85d Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Tue, 27 Jan 2026 15:52:05 +0530 Subject: [PATCH 1/3] Enhanced validation and error handling in storeLaserRequestChar method --- .../Controllers/CharacteristicsController.php | 129 +++++++++++++----- 1 file changed, 98 insertions(+), 31 deletions(-) diff --git a/app/Http/Controllers/CharacteristicsController.php b/app/Http/Controllers/CharacteristicsController.php index 81fadc3..0e69378 100644 --- a/app/Http/Controllers/CharacteristicsController.php +++ b/app/Http/Controllers/CharacteristicsController.php @@ -3011,6 +3011,8 @@ class CharacteristicsController extends Controller $userName = 'Admin'; } + $charField = $request->header('characteristic-field'); + $json = $request->input('data'); $data = json_decode($json, true); @@ -3034,6 +3036,10 @@ class CharacteristicsController extends Controller ], 404); } + if ($charField == null || $charField == '') { + $charField = 'nil'; + } + $plant = Plant::where('code', $plantCode)->first(); if (! $plant) { return response()->json([ @@ -3072,24 +3078,6 @@ class CharacteristicsController extends Controller ], 404); } - $machine = Machine::where('work_center', $workCenter)->first(); - if (! $machine) { - return response()->json([ - 'status_code' => 'ERROR', - 'status_description' => "Work center '{$workCenter}' not found!", - ], 404); - } - - $machineAgaPlant = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first(); - if (! $machineAgaPlant) { - return response()->json([ - 'status_code' => 'ERROR', - 'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}'!", - ], 404); - } - - $MachineId = $machineAgaPlant->id; - if ($machineName == null || $machineName == '' || ! $machineName) { return response()->json([ 'status_code' => 'ERROR', @@ -3097,11 +3085,82 @@ class CharacteristicsController extends Controller ], 404); } + if ($itemCode == null || $itemCode == '') { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Item Code can't be empty!", + ], 400); + } elseif (Str::length($itemCode) < 6 || ! ctype_alnum($itemCode)) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => 'Invalid item code found!', + ], 404); + } + + if (! $jobNo) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Job number can't be empty", + ], 404); + } elseif (Str::length($jobNo) < 7) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Job number '{$jobNo}' should contain minimum 7 digits!", + ], 404); + } elseif (! is_numeric($jobNo)) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Job number '{$jobNo}' should contain only numeric values!", + ], 404); + } + + $machine = Machine::where('work_center', $workCenter)->first(); + if (! $machine) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Work center '{$workCenter}' not found in master!", + ], 404); + } + + $machineAgaPlant = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first(); + if (! $machineAgaPlant) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}' in master!", + ], 404); + } + + $MachineId = $machineAgaPlant->id; + + $pCode = CharacteristicApproverMaster::where('plant_id', $plantId)->first(); + if (! $pCode) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Plant code '{$plantCode}' not found in characteristic approver master!", + ], 404); + } + + $wCenter = CharacteristicApproverMaster::where('machine_id', $MachineId)->first(); + if (! $wCenter) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Work center '{$workCenter}' not found in characteristic approver master!", + ], 404); + } + + $wCenterAgaPlant = CharacteristicApproverMaster::where('machine_id', $MachineId)->where('plant_id', $plantId)->first(); + if (! $wCenterAgaPlant) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Work center '{$workCenter}' not found for the plant code '{$plantCode}' in characteristic approver master!", + ], 404); + } + $mName = CharacteristicApproverMaster::where('machine_name', $machineName)->first(); if (! $mName) { return response()->json([ 'status_code' => 'ERROR', - 'status_description' => "Machine name '{$machineName}' not found in master!", + 'status_description' => "Machine name '{$machineName}' not found in characteristic approver master!", ], 404); } @@ -3109,19 +3168,28 @@ class CharacteristicsController extends Controller if (! $mNameAgaPlant) { return response()->json([ 'status_code' => 'ERROR', - 'status_description' => "Machine name '{$machineName}' not found in master against plant code '{$plantCode}'!", + 'status_description' => "Machine name '{$machineName}' not found for the plant code '{$plantCode}' in characteristic approver master!", ], 404); } - $charId = $mNameAgaPlant->id; - - if ($itemCode == null || $itemCode == '' || ! $itemCode) { + $mNameAgaWorkCenter = CharacteristicApproverMaster::where('machine_name', $machineName)->where('machine_id', $MachineId)->first(); + if (! $mNameAgaWorkCenter) { return response()->json([ 'status_code' => 'ERROR', - 'status_description' => "Item code can't be empty!", + 'status_description' => "Machine name '{$machineName}' not found for the work center '{$workCenter}' in characteristic approver master!", ], 404); } + $mNameAgaWorkCenterForPlant = CharacteristicApproverMaster::where('machine_name', $machineName)->where('machine_id', $MachineId)->where('plant_id', $plantId)->first(); + if (! $mNameAgaWorkCenterForPlant) { + return response()->json([ + 'status_code' => 'ERROR', + 'status_description' => "Machine name '{$machineName}' and work center '{$workCenter}' not found for the plant code '{$plantCode}' in characteristic approver master!", + ], 404); + } + + $charId = $mNameAgaWorkCenterForPlant->id; + $iCode = Item::where('code', $itemCode)->first(); if (! $iCode) { return response()->json([ @@ -3144,10 +3212,7 @@ class CharacteristicsController extends Controller foreach ($characteristics as $char) { $charName = strtolower($char['characteristic_name']) ?? null; - $pendingExists = RequestCharacteristic::where('aufnr', $jobNo) - ->where('characteristic_name', $charName) - ->latest() - ->first(); + $pendingExists = RequestCharacteristic::where('plant_id', $plantId)->where('aufnr', $jobNo)->where('characteristic_name', $charName)->latest()->first(); if ($pendingExists) { @@ -3176,7 +3241,8 @@ class CharacteristicsController extends Controller $year = now()->format('y'); $month = now()->format('m'); - $prefix = "WF-{$year}{$month}-"; + $date = now()->format('d'); + $prefix = "WF-{$year}{$month}{$date}-"; // $existingWorkflowId = RequestCharacteristic::where('plant_id', $plantId) // ->where('machine_id', $MachineId) @@ -3188,8 +3254,9 @@ class CharacteristicsController extends Controller // } - $lastWorkflow = RequestCharacteristic::where('plant_id', $plantId) - ->where('machine_id', $MachineId) + $lastWorkflow = RequestCharacteristic::where('work_flow_id', 'like', "{$prefix}%") + // ->where('plant_id', $plantId) + // ->where('machine_id', $MachineId) ->where('work_flow_id', 'like', "{$prefix}%") ->orderByDesc('work_flow_id') ->first(); -- 2.49.1 From 11d48a7a915a1d4eeb733526e87e8f8bae947b7a Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Tue, 27 Jan 2026 15:54:09 +0530 Subject: [PATCH 2/3] Refactor RequestCharacteristicResource form and table structure for improved organization and functionality --- .../RequestCharacteristicResource.php | 867 ++++++++++++------ 1 file changed, 569 insertions(+), 298 deletions(-) diff --git a/app/Filament/Resources/RequestCharacteristicResource.php b/app/Filament/Resources/RequestCharacteristicResource.php index c20f0b0..631e03e 100644 --- a/app/Filament/Resources/RequestCharacteristicResource.php +++ b/app/Filament/Resources/RequestCharacteristicResource.php @@ -9,7 +9,10 @@ use App\Models\Machine; use App\Models\RequestCharacteristic; use Filament\Facades\Filament; use Filament\Forms; +use Filament\Forms\Components\Section; use Filament\Forms\Form; +use Filament\Forms\Get; +use Filament\Forms\Set; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Table; @@ -54,317 +57,503 @@ class RequestCharacteristicResource extends Resource return $form ->schema([ - Forms\Components\Select::make('plant_id') - ->label('Plant') - ->relationship('plant', 'name') - ->required() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\Select::make('machine_id') - ->label('Work Center') - // ->relationship('machine', 'name') - ->reactive() - ->searchable() - ->options(function (callable $get) { - $plantId = $get('plant_id'); - if (empty($plantId)) { - return []; - } + Section::make('') + ->schema([ + Forms\Components\Select::make('plant_id') + ->label('Plant') + ->reactive() + ->relationship('plant', 'name') + ->required() + ->default(function () { + return optional(RequestCharacteristic::latest()->first())->plant_id; + }) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $plantId = $get('plant_id'); + $updRec = $get('id'); + $set('machine_id', null); + $set('item_id', null); + $set('aufnr', null); + $set('machine_name', null); + $set('characteristic_approver_master_id', null); + if (! $updRec && $plantId) { + $set('work_flow_id', self::isNewWorkFlow($get)); + } + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(fn ($get) => self::isFieldDisabled($get)), + Forms\Components\Select::make('machine_id') + ->label('Work Center') + // ->relationship('machine', 'name') + ->reactive() + ->searchable() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + if (! $plantId) { + return []; + } - return Machine::where('plant_id', $plantId)->pluck('work_center', 'id'); - }) - ->required() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\TextInput::make('work_flow_id') - ->label('Work Flow ID') - ->readOnly() - ->reactive(), - // ->rule(function (callable $get) { - // return Rule::unique('request_characteristics', 'work_flow_id') - // ->where('plant_id', $get('plant_id')) - // ->ignore($get('id')); - // }), - Forms\Components\Select::make('item_id') - ->label('Item') - // ->relationship('item', 'id') - ->reactive() - ->searchable() - ->options(function (callable $get) { - $plantId = $get('plant_id'); - if (empty($plantId)) { - return []; - } + return Machine::where('plant_id', $plantId)->pluck('work_center', 'id'); + }) + ->required() + ->default(function () { + return optional(RequestCharacteristic::latest()->first())->machine_id ?? []; + }) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('item_id', null); + $set('aufnr', null); + $set('machine_name', null); + $set('characteristic_approver_master_id', null); + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(fn ($get) => self::isFieldDisabled($get)), + Forms\Components\TextInput::make('work_flow_id') + ->label('Work Flow ID') + ->readOnly() + ->reactive() + ->default(function ($state, callable $set, callable $get) { + $updRec = $get('id'); + if (! $updRec) { + return self::isNewWorkFlow($get); + } + $set('updated_by', Filament::auth()->user()?->name); + }), + // ->rule(function (callable $get) { + // return Rule::unique('request_characteristics', 'work_flow_id') + // ->where('plant_id', $get('plant_id')) + // ->ignore($get('id')); + // }), + Forms\Components\Select::make('item_id') + ->label('Item') + // ->relationship('item', 'id') + ->reactive() + ->searchable() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + if (! $plantId) { + return []; + } - return Item::where('plant_id', $plantId)->pluck('code', 'id'); - }) - ->required() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\Select::make('characteristic_approver_master_id') - ->label('Characteristic Approver') - // ->relationship('characteristicApproverMaster', 'id') - ->reactive() - ->searchable() - ->options(function (callable $get) { - $plantId = $get('plant_id'); + return Item::where('plant_id', $plantId)->pluck('code', 'id'); + }) + ->required() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('aufnr', null); + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(fn ($get) => self::isFieldDisabled($get)), + Forms\Components\TextInput::make('aufnr') + ->label('Aufnr') + ->reactive() + ->required() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(fn ($get) => self::isFieldDisabled($get)), + Forms\Components\Select::make('machine_name') + ->label('Machines') + ->reactive() + ->nullable() + ->searchable() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + $machineId = $get('machine_id'); - $machineId = $get('machine_id'); + if (! $plantId || ! $machineId) { + return []; + } - if (! $plantId) { - return []; - } + return CharacteristicApproverMaster::where('plant_id', $plantId)->where('machine_id', $machineId)->pluck('machine_name', 'id')->unique(); + }) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('characteristic_approver_master_id', null); + $set('updated_by', Filament::auth()->user()?->name); + }) + ->default(function () { + return optional(RequestCharacteristic::latest()->first())->characteristic_approver_master_id ?? []; + }) + ->afterStateHydrated(function ($component, $state, Get $get, Set $set) { + if ($get('id')) { + $reqId = RequestCharacteristic::where('id', $get('id'))->first()?->characteristic_approver_master_id; + if ($reqId) { + $reqMac = CharacteristicApproverMaster::where('id', $reqId)->first()?->machine_name; + if ($reqMac) { + $set('machine_name', $reqMac); + } else { + $set('machine_name', null); + } + } else { + $set('machine_name', null); + } + } + }) + ->required(), + Forms\Components\Select::make('characteristic_approver_master_id') + ->label('Master Characteristic') + ->relationship('characteristicApproverMaster', 'characteristic_field') + ->reactive() + ->nullable() + ->searchable() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + $machineId = $get('machine_id'); + $machineName = $get('machine_name'); - $approvers = CharacteristicApproverMaster::where('plant_id', $plantId) - ->where('machine_id', $machineId) - ->get(); + if (! $plantId || ! $machineId || ! $machineName) { + return []; + } - $options = []; + return CharacteristicApproverMaster::where('plant_id', $plantId)->where('machine_id', $machineId)->where('machine_name', $machineName)->pluck('characteristic_field', 'id'); + }) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->required(), + // ->disabled(fn ($get) => self::isFieldDisabled($get)) + Section::make('Request Characteristic') + // ->columnSpan(['default' => 2, 'sm' => 4]) + ->reactive() + ->schema([ + Forms\Components\TextInput::make('characteristic_name') + ->label('Characteristic Name') + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(fn ($get) => self::isFieldDisabled($get)), + Forms\Components\TextInput::make('current_value') + ->label('Current Value') + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(fn ($get) => self::isFieldDisabled(get: $get)), + Forms\Components\TextInput::make('update_value') + ->label('Update Value') + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(fn ($get) => self::isFieldDisabled($get)), + ]) + ->collapsible() + ->columns(['default' => 1, 'sm' => 3]), + Section::make(function ($get): string { + $approverId = $get('characteristic_approver_master_id'); + $approverName = $approverId ? CharacteristicApproverMaster::find($approverId)?->name1 : null; - foreach ($approvers as $approver) { - if ($approver->name1) { - $options[$approver->id.'_name1'] = $approver->name1; - } - if ($approver->name2) { - $options[$approver->id.'_name2'] = $approver->name2; - } - if ($approver->name3) { - $options[$approver->id.'_name3'] = $approver->name3; - } - } + return 'Approver - 1'.($approverName ? " ( {$approverName} )" : ''); + }) + ->reactive() + // ->description(fn (Get $get) => CharacteristicApproverMaster::find($get('characteristic_approver_master_id'))?->name1 ?? 'Select approver above' + // ) + ->schema([ + Forms\Components\Select::make('approver_status1') + ->label('Approver Status') + ->reactive() + ->options([ + 'Approved' => 'Approved', + 'Hold' => 'Hold', + 'Rejected' => 'Rejected', + ]) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + if ($state && empty($get('approved1_at'))) { + $set('approved1_at', now()); + } + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); + $approverId = $get('characteristic_approver_master_id'); - return $options; - }) - ->dehydrateStateUsing(function ($state, callable $set) { + if (! $approverId) { + return true; + } - if (empty($state) || ! str_contains($state, '_')) { - return $state; - } + if (str_contains($approverId, '_')) { + [$approverId, $level] = explode('_', $approverId); + } - $parts = explode('_', $state); + $approver = CharacteristicApproverMaster::find($approverId); + if (! $approver) { + return true; + } - if (count($parts) != 2) { - return null; - } + // Super Admin can edit any + if ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; // field enabled + } - [$id, $level] = $parts; + // Otherwise, enable only if the user's name matches + return $approver->name1 != $currentUser?->name; + }), + Forms\Components\TextInput::make('approver_remark1') + ->label('Approver Remark') + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); + $updId = $get('id'); - $set('approver_level', $level); + if (! $updId) { + return true; + } elseif ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; + } else { + return true; + } + }), + Forms\Components\DateTimePicker::make('approved1_at') + // ->label('Approved At') + ->label(fn (callable $get): string => match ($get('approver_status1')) { + 'Approved' => 'Approved At', + 'Hold' => 'Hold At', + 'Rejected' => 'Rejected At', + default => 'Updated At', + }) + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); // logged-in user + $approverId = $get('characteristic_approver_master_id'); - return (int) $id; - }) - ->required() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\TextInput::make('aufnr') - ->label('Aufnr') - ->reactive() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\TextInput::make('characteristic_name') - ->label('Characteristic Name') - ->reactive() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\TextInput::make('current_value') - ->label('Current Value') - ->reactive() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\TextInput::make('update_value') - ->label('Update Value') - ->reactive() - ->disabled(fn ($get) => self::isFieldDisabled($get)), - Forms\Components\Select::make('approver_status1') - ->label('Approver Status 1') - ->reactive() - ->options([ - 'Approved' => 'Approved', - 'Hold' => 'Hold', - 'Rejected' => 'Rejected', + if (! $approverId) { + return true; + } + + if (str_contains($approverId, '_')) { + [$approverId, $level] = explode('_', $approverId); + } + + $approver = CharacteristicApproverMaster::find($approverId); + if (! $approver) { + return true; + } + if ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; + } + + return $approver->name1 != $currentUser?->name; + }), + ]) + ->collapsed()// collapsible() + ->columns(['default' => 1, 'sm' => 3]), + Section::make(function ($get): string { + $approverId = $get('characteristic_approver_master_id'); + $approverName = $approverId ? CharacteristicApproverMaster::find($approverId)?->name2 : null; + + return 'Approver - 2'.($approverName ? " ( {$approverName} )" : ''); + }) + ->reactive() + ->schema([ + Forms\Components\Select::make('approver_status2') + ->label('Approver Status') + ->reactive() + ->options([ + 'Approved' => 'Approved', + 'Hold' => 'Hold', + 'Rejected' => 'Rejected', + ]) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + if ($state && empty($get('approved2_at'))) { + $set('approved2_at', now()); + } + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); // get the User object + $approverId = $get('characteristic_approver_master_id'); + + if (! $approverId) { + return true; + } + + if (str_contains($approverId, '_')) { + [$approverId, $level] = explode('_', $approverId); + } + + $approver = CharacteristicApproverMaster::find($approverId); + if (! $approver) { + return true; + } + + // Super Admin can always edit + if ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; // ENABLE field + } + + // Otherwise, enable only if the user's name matches + return $approver->name2 != $currentUser?->name; + }), + Forms\Components\TextInput::make('approver_remark2') + ->label('Approver Remark') + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); + $updId = $get('id'); + + if (! $updId) { + return true; + } elseif ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; + } else { + return true; + } + }), + Forms\Components\DateTimePicker::make('approved2_at') + ->label(fn (callable $get): string => match ($get('approver_status2')) { + 'Approved' => 'Approved At', + 'Hold' => 'Hold At', + 'Rejected' => 'Rejected At', + default => 'Updated At', + }) + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); // logged-in user + $approverId = $get('characteristic_approver_master_id'); + + if (! $approverId) { + return true; + } + + if (str_contains($approverId, '_')) { + [$approverId, $level] = explode('_', $approverId); + } + + $approver = CharacteristicApproverMaster::find($approverId); + if (! $approver) { + return true; + } + if ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; + } + + return $approver->name2 != $currentUser?->name; + }), + // ->dehydrated(true), + ]) + ->collapsed()// collapsible() + ->columns(['default' => 1, 'sm' => 3]), + Section::make(function ($get): string { + $approverId = $get('characteristic_approver_master_id'); + $approverName = $approverId ? CharacteristicApproverMaster::find($approverId)?->name3 : null; + + return 'Approver - 3'.($approverName ? " ( {$approverName} )" : ''); + }) + ->reactive() + ->schema([ + Forms\Components\Select::make('approver_status3') + ->label('Approver Status') + ->reactive() + ->options([ + 'Approved' => 'Approved', + 'Hold' => 'Hold', + 'Rejected' => 'Rejected', + ]) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + if ($state && empty($get('approved3_at'))) { + $set('approved3_at', now()); + } + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); + $approverId = $get('characteristic_approver_master_id'); + + if (! $approverId) { + return true; + } + + if (str_contains($approverId, '_')) { + [$approverId, $level] = explode('_', $approverId); + } + + $approver = CharacteristicApproverMaster::find($approverId); + if (! $approver) { + return true; + } + + if ($currentUser->hasRole('Super Admin')) { + return false; + } else { + return $approver->name3 != $currentUser?->name; + } + + }), + Forms\Components\TextInput::make('approver_remark3') + ->label('Approver Remark') + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); + $updId = $get('id'); + + if (! $updId) { + return true; + } elseif ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; + } else { + return true; + } + }), + Forms\Components\DateTimePicker::make('approved3_at') + ->label(fn (callable $get): string => match ($get('approver_status3')) { + 'Approved' => 'Approved At', + 'Hold' => 'Hold At', + 'Rejected' => 'Rejected At', + default => 'Updated At', + }) + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->disabled(function ($get) { + $currentUser = Filament::auth()->user(); // logged-in user + $approverId = $get('characteristic_approver_master_id'); + + if (! $approverId) { + return true; + } + + if (str_contains($approverId, '_')) { + [$approverId, $level] = explode('_', $approverId); + } + + $approver = CharacteristicApproverMaster::find($approverId); + if (! $approver) { + return true; + } + if ($currentUser && $currentUser->hasRole('Super Admin')) { + return false; + } + + return $approver->name3 != $currentUser?->name; + }), + ]) + ->collapsed()// collapsible() + ->columns(['default' => 1, 'sm' => 3]), + Forms\Components\Hidden::make('created_by') + ->label('Created By') + ->default(Filament::auth()->user()?->name), + Forms\Components\Hidden::make('updated_by') + ->label('Updated By') + ->default(Filament::auth()->user()?->name), + Forms\Components\TextInput::make('id') + ->hidden() + ->readOnly(), ]) - ->disabled(function ($get) { - $currentUser = Filament::auth()->user(); - $approverId = $get('characteristic_approver_master_id'); - - if (! $approverId) { - return true; - } - - if (str_contains($approverId, '_')) { - [$approverId, $level] = explode('_', $approverId); - } - - $approver = CharacteristicApproverMaster::find($approverId); - if (! $approver) { - return true; - } - - // Super Admin can edit any - if ($currentUser && $currentUser->hasRole('Super Admin')) { - return false; // field enabled - } - - // Otherwise, enable only if the user's name matches - return $approver->name1 != $currentUser?->name; - }), - Forms\Components\TextInput::make('approver_remark1') - ->label('Approver Remark 1') - ->reactive(), - Forms\Components\DateTimePicker::make('approved1_at') - ->label('Approved At 1') - ->reactive() - ->disabled(function ($get) { - $currentUser = Filament::auth()->user(); // logged-in user - $approverId = $get('characteristic_approver_master_id'); - - if (! $approverId) { - return true; - } - - if (str_contains($approverId, '_')) { - [$approverId, $level] = explode('_', $approverId); - } - - $approver = CharacteristicApproverMaster::find($approverId); - if (! $approver) { - return true; - } - if ($currentUser && $currentUser->hasRole('Super Admin')) { - return false; - } - - return $approver->name1 != $currentUser?->name; - }), - Forms\Components\Select::make('approver_status2') - ->label('Approver Status 2') - ->reactive() - ->afterStateUpdated(function ($state, callable $set, callable $get) { - if ($state && empty($get('approved2_at'))) { - $set('approved2_at', now()); - } - }) - ->options([ - 'Approved' => 'Approved', - 'Hold' => 'Hold', - 'Rejected' => 'Rejected', - ]) - ->disabled(function ($get) { - $currentUser = Filament::auth()->user(); // get the User object - $approverId = $get('characteristic_approver_master_id'); - - if (! $approverId) { - return true; - } - - if (str_contains($approverId, '_')) { - [$approverId, $level] = explode('_', $approverId); - } - - $approver = CharacteristicApproverMaster::find($approverId); - if (! $approver) { - return true; - } - - // Super Admin can always edit - if ($currentUser && $currentUser->hasRole('Super Admin')) { - return false; // ENABLE field - } - - // Otherwise, enable only if the user's name matches - return $approver->name2 != $currentUser?->name; - }), - Forms\Components\TextInput::make('approver_remark2') - ->label('Approver Remark 2') - ->reactive(), - Forms\Components\DateTimePicker::make('approved2_at') - ->label('Approverd At 2') - ->reactive() - ->disabled(function ($get) { - $currentUser = Filament::auth()->user(); // logged-in user - $approverId = $get('characteristic_approver_master_id'); - - if (! $approverId) { - return true; - } - - if (str_contains($approverId, '_')) { - [$approverId, $level] = explode('_', $approverId); - } - - $approver = CharacteristicApproverMaster::find($approverId); - if (! $approver) { - return true; - } - if ($currentUser && $currentUser->hasRole('Super Admin')) { - return false; - } - - return $approver->name2 != $currentUser?->name; - }) - ->dehydrated(true), - Forms\Components\Select::make('approver_status3') - ->label('Approver Status 3') - ->reactive() - ->options([ - 'Approved' => 'Approved', - 'Hold' => 'Hold', - 'Rejected' => 'Rejected', - ]) - ->disabled(function ($get) { - $currentUser = Filament::auth()->user(); - $approverId = $get('characteristic_approver_master_id'); - - if (! $approverId) { - return true; - } - - if (str_contains($approverId, '_')) { - [$approverId, $level] = explode('_', $approverId); - } - - $approver = CharacteristicApproverMaster::find($approverId); - if (! $approver) { - return true; - } - - if ($currentUser->hasRole('Super Admin')) { - return false; - } else { - return $approver->name3 != $currentUser?->name; - } - - }), - Forms\Components\TextInput::make('approver_remark3') - ->label('Approver Remark 3') - ->reactive(), - Forms\Components\DateTimePicker::make('approved3_at') - ->label('Approverd At 3') - ->reactive() - ->disabled(function ($get) { - $currentUser = Filament::auth()->user(); // logged-in user - $approverId = $get('characteristic_approver_master_id'); - - if (! $approverId) { - return true; - } - - if (str_contains($approverId, '_')) { - [$approverId, $level] = explode('_', $approverId); - } - - $approver = CharacteristicApproverMaster::find($approverId); - if (! $approver) { - return true; - } - if ($currentUser && $currentUser->hasRole('Super Admin')) { - return false; - } - - return $approver->name3 != $currentUser?->name; - }), - Forms\Components\Hidden::make('created_by') - ->label('Created By') - ->default(Filament::auth()->user()?->name), - Forms\Components\Hidden::make('updated_by') - ->label('Updated By') - ->default(Filament::auth()->user()?->name), - Forms\Components\TextInput::make('id') - ->hidden() - ->readOnly(), + ->columns(['default' => 1, 'sm' => 3]), ]); } @@ -399,6 +588,36 @@ class RequestCharacteristicResource extends Resource ]); } + protected static function isNewWorkFlow($get): string + { + $year = now()->format('y'); + $month = now()->format('m'); + $date = now()->format('d'); + $prefix = "WF-{$year}{$month}{$date}-"; + + $lastWorkflow = RequestCharacteristic::where('work_flow_id', 'like', "{$prefix}%") + // ->where('machine_id', $MachineId) + ->where('work_flow_id', 'like', "{$prefix}%") + ->orderByDesc('work_flow_id') + ->first(); + + if ($lastWorkflow) { + $lastSerial = substr($lastWorkflow->work_flow_id, strlen($prefix)); + $nextSerial = str_pad( + intval($lastSerial) + 1, + 3, + '0', + STR_PAD_LEFT + ); + } else { + $nextSerial = '001'; + } + + $workFlowId = "{$prefix}{$nextSerial}"; + + return $workFlowId; + } + public static function table(Table $table): Table { return $table @@ -436,10 +655,24 @@ class RequestCharacteristicResource extends Resource ->alignCenter() ->searchable() ->sortable(), + Tables\Columns\TextColumn::make('characteristicApproverMaster.machine_name') + ->label('Machine') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('characteristicApproverMaster.characteristic_field') + ->label('Master Characteristic') + ->alignCenter() + ->searchable() + ->formatStateUsing(fn (string $state): string => strtoupper(__($state))) + ->extraAttributes(['class' => 'uppercase']) + ->sortable(), Tables\Columns\TextColumn::make('characteristic_name') ->label('Characteristic Name') ->alignCenter() ->searchable() + ->formatStateUsing(fn (string $state): string => strtoupper(__($state))) + ->extraAttributes(['class' => 'uppercase']) ->sortable(), Tables\Columns\TextColumn::make('current_value') ->label('Current Value') @@ -458,6 +691,17 @@ class RequestCharacteristicResource extends Resource ->sortable(), Tables\Columns\TextColumn::make('approver_status1') ->label('Approver Status 1') + ->color(fn (string $state): string => match ($state) { + 'Approved' => 'success', + 'Hold' => 'warning', + 'Rejected' => 'danger', + default => 'gray', + }) + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('approver_remark1') + ->label('Approver Remark 1') // ->color('success') ->alignCenter() ->searchable() @@ -475,7 +719,18 @@ class RequestCharacteristicResource extends Resource ->sortable(), Tables\Columns\TextColumn::make('approver_status2') ->label('Approver Status 2') - // ->color('danger') + ->color(fn (string $state): string => match ($state) { + 'Approved' => 'success', + 'Hold' => 'warning', + 'Rejected' => 'danger', + default => 'gray', + }) + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('approver_remark2') + ->label('Approver Remark 2') + // ->color('success') ->alignCenter() ->searchable() ->sortable(), @@ -492,7 +747,18 @@ class RequestCharacteristicResource extends Resource ->sortable(), Tables\Columns\TextColumn::make('approver_status3') ->label('Approver Status 3') - // ->color('primary') + ->color(fn (string $state): string => match ($state) { + 'Approved' => 'success', + 'Hold' => 'warning', + 'Rejected' => 'danger', + default => 'gray', + }) + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('approver_remark3') + ->label('Approver Remark 3') + // ->color('success') ->alignCenter() ->searchable() ->sortable(), @@ -503,26 +769,31 @@ class RequestCharacteristicResource extends Resource ->searchable() ->sortable(), Tables\Columns\TextColumn::make('created_at') + ->label('Created At') ->dateTime() ->alignCenter() ->searchable() ->sortable(), Tables\Columns\TextColumn::make('created_by') + ->label('Created By') ->alignCenter() ->searchable() ->sortable(), Tables\Columns\TextColumn::make('updated_at') + ->label('Updated At') ->dateTime() ->alignCenter() ->searchable() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('updated_by') + ->label('Updated By') ->alignCenter() ->searchable() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('deleted_at') + ->label('Deleted At') ->dateTime() ->alignCenter() ->searchable() -- 2.49.1 From c8bfbb122bccdacda09e1e95caa091afdba7b08f Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Tue, 27 Jan 2026 15:54:37 +0530 Subject: [PATCH 3/3] Refactor CharacteristicApproverMasterResource form structure and enhance table columns for improved usability and search functionality --- .../CharacteristicApproverMasterResource.php | 196 +++++++++++++----- 1 file changed, 148 insertions(+), 48 deletions(-) diff --git a/app/Filament/Resources/CharacteristicApproverMasterResource.php b/app/Filament/Resources/CharacteristicApproverMasterResource.php index 9a2533a..bfb36c2 100644 --- a/app/Filament/Resources/CharacteristicApproverMasterResource.php +++ b/app/Filament/Resources/CharacteristicApproverMasterResource.php @@ -7,6 +7,7 @@ use App\Models\CharacteristicApproverMaster; use App\Models\Machine; use Filament\Facades\Filament; use Filament\Forms; +use Filament\Forms\Components\Section; use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Tables; @@ -26,53 +27,125 @@ class CharacteristicApproverMasterResource extends Resource { return $form ->schema([ - Forms\Components\Select::make('plant_id') - ->label('Plant') - ->reactive() - ->relationship('plant', 'name') - ->required(), - Forms\Components\Select::make('machine_id') - ->label('Work Center') - // ->relationship('machine', 'name') - ->reactive() - ->searchable() - ->options(function (callable $get) { - $plantId = $get('plant_id'); - if (empty($plantId)) { - return []; - } + Section::make('') + ->schema([ + Forms\Components\Select::make('plant_id') + ->label('Plant') + ->columnSpan(2) + ->reactive() + ->relationship('plant', 'name') + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->required(), + Forms\Components\Select::make('machine_id') + ->label('Work Center') + ->columnSpan(2) + // ->relationship('machine', 'name') + ->reactive() + ->searchable() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + if (empty($plantId)) { + return []; + } - return Machine::where('plant_id', $plantId)->pluck('work_center', 'id'); - }) - ->required(), - Forms\Components\TextInput::make('characteristic_field') - ->label('Characteristic Field'), - Forms\Components\TextInput::make('machine_name') - ->label('Machine Name'), - Forms\Components\TextInput::make('name1') - ->label('Name-1'), - Forms\Components\TextInput::make('mail1') - ->label('Mail-1'), - Forms\Components\TextInput::make('duration1') - ->label('Duration-1 (Hour.Minute)'), - Forms\Components\TextInput::make('name2') - ->label('Name-2'), - Forms\Components\TextInput::make('mail2') - ->label('Mail-2'), - Forms\Components\TextInput::make('duration2') - ->label('Duration-2 (Hour.Minute)'), - Forms\Components\TextInput::make('name3') - ->label('Name-3'), - Forms\Components\TextInput::make('mail3') - ->label('Mail-3'), - Forms\Components\TextInput::make('duration3') - ->label('Duration-3 (Hour.Minute)'), - Forms\Components\Hidden::make('created_by') - ->label('Created By') - ->default(Filament::auth()->user()?->name), - Forms\Components\Hidden::make('updated_by') - ->label('Updated By') - ->default(Filament::auth()->user()?->name), + return Machine::where('plant_id', $plantId)->pluck('work_center', 'id'); + }) + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }) + ->required(), + Forms\Components\TextInput::make('characteristic_field') + ->label('Characteristic Field') + ->columnSpan(2) + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('machine_name') + ->label('Machine') + ->columnSpan(2) + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Section::make('Approver - 1') + // ->description('Prevent abuse by limiting the number of requests per period') + ->columnSpan(['default' => 2, 'sm' => 4]) + ->schema([ + Forms\Components\TextInput::make('name1') + ->label('Name') + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('mail1') + ->label('Mail') + ->columnSpan(['default' => 1, 'sm' => 2]) + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('duration1') + ->label('Duration (HH.MM)') + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + ]) + ->collapsed()// collapsible() + ->columns(['default' => 1, 'sm' => 4]), + Section::make('Approver - 2') + ->columnSpan(['default' => 2, 'sm' => 4]) + ->schema([ + Forms\Components\TextInput::make('name2') + ->label('Name') + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('mail2') + ->label('Mail') + ->columnSpan(['default' => 1, 'sm' => 2]) + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('duration2') + ->label('Duration (HH.MM)') + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + ]) + ->collapsed()// collapsible() + ->columns(['default' => 1, 'sm' => 4]), + Section::make('Approver - 3') + ->columnSpan(['default' => 2, 'sm' => 4]) + ->schema([ + Forms\Components\TextInput::make('name3') + ->label('Name') + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('mail3') + ->label('Mail') + ->columnSpan(['default' => 1, 'sm' => 2]) + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + Forms\Components\TextInput::make('duration3') + ->label('Duration (HH.MM)') + ->afterStateUpdated(function ($state, callable $set) { + $set('updated_by', Filament::auth()->user()?->name); + }), + ]) + ->collapsed()// collapsible() + ->columns(['default' => 1, 'sm' => 4]), + Forms\Components\Hidden::make('created_by') + ->label('Created By') + ->default(Filament::auth()->user()?->name), + Forms\Components\Hidden::make('updated_by') + ->label('Updated By') + ->default(Filament::auth()->user()?->name), + Forms\Components\TextInput::make('id') + ->hidden() + ->readOnly(), + ]) + ->columns(['default' => 1, 'sm' => 4]), ]); } @@ -92,26 +165,34 @@ class CharacteristicApproverMasterResource extends Resource Tables\Columns\TextColumn::make('plant.name') ->label('Plant') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('machine.work_center') ->label('Work Center') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('characteristic_field') ->label('Characteristic Field') ->alignCenter() + ->searchable() + ->formatStateUsing(fn (string $state): string => strtoupper(__($state))) + ->extraAttributes(['class' => 'uppercase']) ->sortable(), Tables\Columns\TextColumn::make('machine_name') ->label('Machine Name') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('name1') ->label('Approver Name 1') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('mail1') ->label('Mail 1') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('duration1') ->label('Duration 1 (Hour.Minute)') @@ -120,10 +201,12 @@ class CharacteristicApproverMasterResource extends Resource Tables\Columns\TextColumn::make('name2') ->label('Approver Name 2') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('mail2') ->label('Mail 2') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('duration2') ->label('Duration 2 (Hour.Minute)') @@ -132,10 +215,12 @@ class CharacteristicApproverMasterResource extends Resource Tables\Columns\TextColumn::make('name3') ->label('Approver Name 3') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('mail3') ->label('Mail 3') ->alignCenter() + ->searchable() ->sortable(), Tables\Columns\TextColumn::make('duration3') ->label('Duration 3 (Hour.Minute)') @@ -145,16 +230,31 @@ class CharacteristicApproverMasterResource extends Resource ->label('Created At') ->alignCenter() ->dateTime() - ->sortable() - ->toggleable(isToggledHiddenByDefault: true), + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('created_by') + ->label('Created By') + ->alignCenter() + ->searchable() + ->sortable(), Tables\Columns\TextColumn::make('updated_at') ->label('Updated At') ->alignCenter() ->dateTime() + ->searchable() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_by') + ->label('Updated By') + ->alignCenter() + ->searchable() ->sortable() ->toggleable(isToggledHiddenByDefault: true), Tables\Columns\TextColumn::make('deleted_at') + ->label('Deleted At') ->dateTime() + ->alignCenter() + ->searchable() ->sortable() ->toggleable(isToggledHiddenByDefault: true), ]) -- 2.49.1