From 3fbb2be2541166e67f58ab19dcf8633a473cf99f Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Thu, 9 Apr 2026 12:56:44 +0530 Subject: [PATCH] Refactored alignments and updated validation logic on resource / importer / exporter pages --- .../CharacteristicApproverMasterExporter.php | 10 +- .../CharacteristicApproverMasterImporter.php | 210 ++++++++++++++---- .../CharacteristicApproverMasterResource.php | 27 ++- 3 files changed, 189 insertions(+), 58 deletions(-) diff --git a/app/Filament/Exports/CharacteristicApproverMasterExporter.php b/app/Filament/Exports/CharacteristicApproverMasterExporter.php index 1b7b387..32f09c4 100644 --- a/app/Filament/Exports/CharacteristicApproverMasterExporter.php +++ b/app/Filament/Exports/CharacteristicApproverMasterExporter.php @@ -28,28 +28,28 @@ class CharacteristicApproverMasterExporter extends Exporter ->label('PLANT CODE'), ExportColumn::make('machine.work_center') ->label('WORK CENTER'), - ExportColumn::make('machine_name') - ->label('MACHINE NAME'), ExportColumn::make('approver_type') ->label('APPROVER TYPE'), + ExportColumn::make('machine_name') + ->label('MACHINE NAME'), ExportColumn::make('characteristic_field') ->label('MASTER CHARACTERISTIC FIELD'), ExportColumn::make('name1') ->label('APPROVER NAME 1'), ExportColumn::make('mail1') - ->label('APPROVER MAIL 1'), + ->label('MAIL 1'), ExportColumn::make('duration1') ->label('DURATION 1'), ExportColumn::make('name2') ->label('APPROVER NAME 2'), ExportColumn::make('mail2') - ->label('APPROVER MAIL 2'), + ->label('MAIL 2'), ExportColumn::make('duration2') ->label('DURATION 2'), ExportColumn::make('name3') ->label('APPROVER NAME 3'), ExportColumn::make('mail3') - ->label('APPROVER MAIL 3'), + ->label('MAIL 3'), ExportColumn::make('duration3') ->label('DURATION 3'), ExportColumn::make('created_at') diff --git a/app/Filament/Imports/CharacteristicApproverMasterImporter.php b/app/Filament/Imports/CharacteristicApproverMasterImporter.php index 7fff36e..20e16f1 100644 --- a/app/Filament/Imports/CharacteristicApproverMasterImporter.php +++ b/app/Filament/Imports/CharacteristicApproverMasterImporter.php @@ -3,9 +3,14 @@ namespace App\Filament\Imports; use App\Models\CharacteristicApproverMaster; +use App\Models\Machine; +use App\Models\Plant; +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 Str; class CharacteristicApproverMasterImporter extends Importer { @@ -17,80 +22,80 @@ class CharacteristicApproverMasterImporter extends Importer ImportColumn::make('plant') ->requiredMapping() ->exampleHeader('Plant Code') - ->examples(['1000','1000']) + ->examples(['1000', '1000']) ->label('Plant Code') ->relationship(resolveUsing: 'code') ->rules(['required']), ImportColumn::make('machine') ->requiredMapping() ->exampleHeader('Work Center') - ->examples(['RMGLAS02','RMGLAS02']) + ->examples(['RMGLAS02', 'RMGLAS02']) ->label('Work Center') - ->relationship() + ->relationship(resolveUsing: 'work_center') ->rules(['required']), + ImportColumn::make('approver_type') + ->requiredMapping() + ->exampleHeader('Approver Type') + ->examples(['Characteristic', 'Quality']) + ->label('Approver Type'), ImportColumn::make('machine_name') ->requiredMapping() ->exampleHeader('Machine Name') - ->examples(['15002635','17002635']) + ->examples(['15002635', '17002635']) ->label('Machine Name'), + ImportColumn::make('characteristic_field') + ->requiredMapping() + ->exampleHeader('Master Characteristic Field') + ->examples(['NIL', 'MV SERIES']) + ->label('Master Characteristic Field'), ImportColumn::make('name1') ->requiredMapping() ->exampleHeader('Approver Name 1') - ->examples(['Suresh.D','Suresh.D']) + ->examples(['Test 1', 'Test 4']) ->label('Approver Name 1'), ImportColumn::make('mail1') ->requiredMapping() - ->exampleHeader('Approver Mail 1') - ->examples(['suresh@cripumps.com','suresh@cripumps.com']) - ->label('Approver Mail 1'), - ImportColumn::make('name2') - ->requiredMapping() - ->exampleHeader('Approver Name 2') - ->examples(['Ramesh.G','Ramesh.G']) - ->label('Approver Name 2'), - ImportColumn::make('mail2') - ->requiredMapping() - ->exampleHeader('Approver Mail 2') - ->examples(['ramesh@cripumps.com','ramesh@cripumps.com']) - ->label('Approver Mail 2'), - ImportColumn::make('name3') - ->requiredMapping() - ->exampleHeader('Approver Name 3') - ->examples(['Ganesh.K','Ganesh.K']) - ->label('Approver Name 3'), - ImportColumn::make('mail3') - ->requiredMapping() - ->exampleHeader('Approver Mail 3') - ->examples(['ganesh@cripumps.com','ganesh@cripumps.com']) - ->label('Approver Mail 3'), + ->exampleHeader('Mail 1') + ->examples(['test1@cripumps.com', 'test4@cripumps.com']) + ->label('Mail 1'), ImportColumn::make('duration1') ->numeric() ->requiredMapping() ->exampleHeader('Duration 1') - ->examples(['0.05','0.30']) + ->examples(['0.05', '0.30']) ->label('Duration 1'), + ImportColumn::make('name2') + ->requiredMapping() + ->exampleHeader('Approver Name 2') + ->examples(['Test 2', 'Test 5']) + ->label('Approver Name 2'), + ImportColumn::make('mail2') + ->requiredMapping() + ->exampleHeader('Mail 2') + ->examples(['test2@cripumps.com', 'test5@cripumps.com']) + ->label('Mail 2'), ImportColumn::make('duration2') ->numeric() ->requiredMapping() ->exampleHeader('Duration 2') - ->examples(['0.05','0.30']) + ->examples(['0.05', '0.30']) ->label('Duration 2'), + ImportColumn::make('name3') + ->requiredMapping() + ->exampleHeader('Approver Name 3') + ->examples(['Test 3', 'Test 6']) + ->label('Approver Name 3'), + ImportColumn::make('mail3') + ->requiredMapping() + ->exampleHeader('Mail 3') + ->examples(['test3@cripumps.com', 'test6@cripumps.com']) + ->label('Mail 3'), ImportColumn::make('duration3') ->numeric() ->requiredMapping() ->exampleHeader('Duration 3') - ->examples(['0.05','0.30']) + ->examples(['0.05', '0.30']) ->label('Duration 3'), - ImportColumn::make('characteristic_field') - ->requiredMapping() - ->exampleHeader('Characteristic Field') - ->examples(['MV SERIES','PV SERIES']) - ->label('Characteristic Field'), - ImportColumn::make('approver_type') - ->requiredMapping() - ->exampleHeader('Approver Type') - ->examples(['Characteristic','Quality']) - ->label('Approver Type'), ]; } @@ -101,15 +106,132 @@ class CharacteristicApproverMasterImporter extends Importer // 'email' => $this->data['email'], // ]); - return new CharacteristicApproverMaster(); + $warnMsg = []; + $plantCod = trim($this->data['plant']) ?? null; + $workCenter = trim($this->data['machine']) ?? null; + $apprTyp = trim($this->data['approver_type']) ?? null; + $machineNam = trim($this->data['machine_name']) ?? null; + $mastCharFld = trim($this->data['characteristic_field']) ?? null; // zmm_pumpseries + $apprNam1 = trim($this->data['name1']) ?? null; + $apprMail1 = trim($this->data['mail1']) ?? null; + $apprDur1 = trim($this->data['duration1']) ?? 0.01; + $apprNam2 = trim($this->data['name2']) ?? null; + $apprMail2 = trim($this->data['mail2']) ?? null; + $apprDur2 = trim($this->data['duration2']) ?? 0.01; + $apprNam3 = trim($this->data['name3']) ?? null; + $apprMail3 = trim($this->data['mail3']) ?? null; + $apprDur3 = trim($this->data['duration3']) ?? 0.01; + $createdBy = Filament::auth()->user()->name; + $updatedBy = $createdBy; + + $plantId = null; + $machineId = null; + + if ($plantCod == null || $plantCod == '') { + $warnMsg[] = "Plant code can't be empty!"; + } elseif (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) { + $warnMsg[] = 'Invalid plant code found!'; + } + if ($workCenter == null || $workCenter == '') { + $warnMsg[] = "Work center can't be empty!"; + } + if ($apprTyp == '' || $apprTyp == null || ($apprTyp != 'Characteristic' && $apprTyp != 'Quality')) { + $warnMsg[] = "Approver type must be either 'Characteristic' or 'Quality'!"; + } + if ($machineNam == null || $machineNam == '') { + $warnMsg[] = "Machine name can't be empty!"; + } + if ($mastCharFld == null || $mastCharFld == '') { + $mastCharFld = 'NIL'; + } + if ($apprNam1 == null || $apprNam1 == '') { + $warnMsg[] = "Approver name 1 can't be empty!"; + } + if ($apprMail1 == null || $apprMail1 == '') { + $warnMsg[] = "Approver email 1 can't be empty!"; + } + if (! is_numeric($apprDur1)) { + $warnMsg[] = 'Duration 1 must be a numeric value (HH.MM)!'; + } + if ($apprDur2 != null && $apprDur2 != '' && ! is_numeric($apprDur2)) { + $warnMsg[] = 'Duration 2 must be a numeric value (HH.MM)!'; + } + if ($apprDur3 != null && $apprDur3 != '' && ! is_numeric($apprDur3)) { + $warnMsg[] = 'Duration 3 must be a numeric value (HH.MM)!'; + } + + if (! empty($warnMsg)) { + throw new RowImportFailedException(implode(', ', $warnMsg)); + } + + $plant = Plant::where('code', $plantCod)->first(); + if (! $plant) { + $warnMsg[] = 'Plant code not found!'; + } else { + $plantId = $plant->id; + + $machine = Machine::where('work_center', $workCenter)->first(); + if (! $machine) { + $warnMsg[] = 'Work center not found!'; + } else { + $machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->first(); + + if (! $machine) { + $warnMsg[] = 'Work center not found for the given plant!'; + } else { + $machineId = $machine->id; + } + } + + $getCreatedBy = CharacteristicApproverMaster::where('plant_id', $plantId) + ->where('machine_id', $machineId) + ->where('approver_type', $apprTyp) + ->where('machine_name', $machineNam) + ->where('characteristic_field', $mastCharFld) + ->first()?->created_by; + + if ($getCreatedBy) { + $createdBy = $getCreatedBy; + } + } + + if (! empty($warnMsg)) { + throw new RowImportFailedException(implode(', ', $warnMsg)); + } + + CharacteristicApproverMaster::updateOrCreate( + [ + 'plant_id' => $plantId, + 'machine_id' => $machineId, + 'approver_type' => $apprTyp, + 'machine_name' => $machineNam, + 'characteristic_field' => $mastCharFld, + ], + [ + 'name1' => $apprNam1, + 'mail1' => $apprMail1, + 'duration1' => $apprDur1, + 'name2' => $apprNam2, + 'mail2' => $apprMail2, + 'duration2' => $apprDur2, + 'name3' => $apprNam3, + 'mail3' => $apprMail3, + 'duration3' => $apprDur3, + 'created_by' => $createdBy, + 'updated_by' => $updatedBy, + ]); + + return null; + + // return new CharacteristicApproverMaster; } public static function getCompletedNotificationBody(Import $import): string { - $body = 'Your characteristic approver master import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.'; + $body = 'Your characteristic approver master import has completed and '.number_format($import->successful_rows).' '.str('row')->plural($import->successful_rows).' imported.'; if ($failedRowsCount = $import->getFailedRowsCount()) { - $body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.'; + $body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to import.'; } return $body; diff --git a/app/Filament/Resources/CharacteristicApproverMasterResource.php b/app/Filament/Resources/CharacteristicApproverMasterResource.php index 0537de4..bebe0cf 100644 --- a/app/Filament/Resources/CharacteristicApproverMasterResource.php +++ b/app/Filament/Resources/CharacteristicApproverMasterResource.php @@ -19,6 +19,7 @@ use Filament\Tables\Actions\ImportAction; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Validation\Rule; class CharacteristicApproverMasterResource extends Resource { @@ -83,7 +84,7 @@ class CharacteristicApproverMasterResource extends Resource $set('updated_by', Filament::auth()->user()?->name); }), Forms\Components\TextInput::make('machine_name') - ->label('Machine') + ->label('Machine Name') ->columnSpan(1) ->reactive() ->required() @@ -101,7 +102,7 @@ class CharacteristicApproverMasterResource extends Resource $set('updated_by', Filament::auth()->user()?->name); }), Forms\Components\Select::make('approver_type') - ->label('Request Type') + ->label('Approver Type') ->columnSpan(1) ->reactive() ->nullable() @@ -130,7 +131,7 @@ class CharacteristicApproverMasterResource extends Resource // return optional(CharacteristicApproverMaster::latest()->first())->approver_type ?? null; }) ->afterStateUpdated(function ($state, callable $set) { - $set('characteristic_field', null); + $set('characteristic_field', 'NIL'); $set('updated_by', Filament::auth()->user()?->name); }), Forms\Components\TextInput::make('characteristic_field') @@ -149,6 +150,14 @@ class CharacteristicApproverMasterResource extends Resource $set('characteristic_field', 'NIL'); } $set('updated_by', Filament::auth()->user()?->name); + }) + ->rule(function (callable $get) { + return Rule::unique('characteristic_approver_masters', 'characteristic_field') + ->where('plant_id', $get('plant_id')) + ->where('machine_id', $get('machine_id')) + ->where('approver_type', trim($get('approver_type'))) + ->where('machine_name', trim($get('machine_name'))) + ->ignore($get('id')); }), Section::make('Approver - 1') // ->description('Prevent abuse by limiting the number of requests per period') @@ -281,7 +290,7 @@ class CharacteristicApproverMasterResource extends Resource return ($currentPage - 1) * $perPage + $rowLoop->iteration; }), Tables\Columns\TextColumn::make('plant.name') - ->label('Plant') + ->label('Plant Name') ->alignCenter() ->searchable() ->sortable(), @@ -295,6 +304,11 @@ class CharacteristicApproverMasterResource extends Resource ->alignCenter() ->searchable() ->sortable(), + Tables\Columns\TextColumn::make('machine_name') + ->label('Machine Name') + ->alignCenter() + ->searchable() + ->sortable(), Tables\Columns\TextColumn::make('characteristic_field') ->label('Master Characteristic Field') ->alignCenter() @@ -302,11 +316,6 @@ class CharacteristicApproverMasterResource extends Resource ->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()