diff --git a/app/Filament/Exports/ProductCharacteristicsMasterExporter.php b/app/Filament/Exports/ProductCharacteristicsMasterExporter.php index 14ac682..e78a63d 100644 --- a/app/Filament/Exports/ProductCharacteristicsMasterExporter.php +++ b/app/Filament/Exports/ProductCharacteristicsMasterExporter.php @@ -26,6 +26,8 @@ class ProductCharacteristicsMasterExporter extends Exporter ->label('PLANT CODE'), ExportColumn::make('item.code') ->label('ITEM CODE'), + ExportColumn::make('item.description') + ->label('ITEM DESCRIPTION'), ExportColumn::make('line.name') ->label('LINE NAME'), // machine.workGroupMaster.name ExportColumn::make('machine.workGroupMaster.name') diff --git a/app/Filament/Imports/ProductCharacteristicsMasterImporter.php b/app/Filament/Imports/ProductCharacteristicsMasterImporter.php index 03b52d3..e343f43 100644 --- a/app/Filament/Imports/ProductCharacteristicsMasterImporter.php +++ b/app/Filament/Imports/ProductCharacteristicsMasterImporter.php @@ -24,75 +24,77 @@ class ProductCharacteristicsMasterImporter extends Importer { return [ ImportColumn::make('plant') + ->label('PLANT CODE') ->requiredMapping() - ->exampleHeader('Plant Code') - ->example('1000') - ->label('Plant Code') + ->exampleHeader('PLANT CODE') + ->example(['1000', '1000']) ->relationship(resolveUsing: 'code') ->rules(['required']), ImportColumn::make('item') + ->label('ITEM CODE') ->requiredMapping() - ->exampleHeader('Item Code') - ->example('630214') - ->label('Item Code') + ->exampleHeader('ITEM CODE') + ->example(['123456', '123456']) ->relationship(resolveUsing: 'code') ->rules(['required']), ImportColumn::make('line') + ->label('LINE NAME') ->requiredMapping() - ->exampleHeader('Line Name') - ->example('4 inch pump line') - ->label('Line Name') + ->exampleHeader('LINE NAME') + ->example(['4 inch pump line', '4 inch pump line']) ->relationship(resolveUsing: 'name') ->rules(['required']), ImportColumn::make('work_group_master_id') - ->label('Group Work Center') + ->label('GROUP WORK CENTER') ->requiredMapping() - ->exampleHeader('Group Work Center') - ->example('RMGCGABC') + ->exampleHeader('GROUP WORK CENTER') + ->example(['RMGSTR01', 'RMGSTR01']) ->relationship(resolveUsing: 'name') ->rules(['required']), ImportColumn::make('machine') + ->label('WORK CENTER') ->requiredMapping() - ->exampleHeader('Work Center') - ->example('RMGCE001') - ->label('Work Center') + ->exampleHeader('WORK CENTER') + ->example(['RMISTR01', 'RMISTR02']) ->relationship(resolveUsing: 'work_center') ->rules(['required']), ImportColumn::make('characteristics_type') - ->exampleHeader('Characteristics Type') - ->example('Process or Product') - ->label('Characteristics Type') + ->label('CHARACTERISTICS TYPE') + ->requiredMapping() + ->exampleHeader('CHARACTERISTICS TYPE') + ->example(['Product', 'Process']) ->rules(['required']), ImportColumn::make('name') - ->exampleHeader('Characteristics Name') - ->example('Body') - ->label('Characteristics Name') + ->label('CHARACTERISTICS NAME') + ->requiredMapping() + ->exampleHeader('CHARACTERISTICS NAME') + ->example(['TEST01', 'TEST02']) ->rules(['required']), ImportColumn::make('inspection_type') - ->exampleHeader('Inspection Type') - ->example('Visual or Value') - ->label('Inspection Type') + ->label('INSPECTION TYPE') + ->requiredMapping() + ->exampleHeader('INSPECTION TYPE') + ->example(['Value', 'Visual']) ->rules(['required']), ImportColumn::make('lower') - ->exampleHeader('Lower') - ->example('0') - ->label('Lower') - ->rules(['numeric']), + ->label('LOWER') + ->requiredMapping() + ->exampleHeader('LOWER') + ->example(['5', '0']) + ->rules(['required']), ImportColumn::make('middle') - ->exampleHeader('Middle') - ->example('1') - ->label('Middle') - ->numeric() - ->rules(['numeric']), + ->label('MIDDLE') + ->requiredMapping() + ->exampleHeader('MIDDLE') + ->example(['10', '0']) + ->rules(['required']), ImportColumn::make('upper') - ->exampleHeader('Upper') - ->example('2') - ->label('Upper') - ->rules(['numeric']), - ImportColumn::make('created_by') - ->exampleHeader('Created By') - ->example('Admin') - ->label('Created By'), + ->label('UPPER') + ->requiredMapping() + ->exampleHeader('UPPER') + ->example(['15', '0']) + ->rules(['required']), + // ImportColumn::make('created_by'), // ImportColumn::make('updated_by'), ]; @@ -102,117 +104,172 @@ class ProductCharacteristicsMasterImporter extends Importer { $warnMsg = []; - $plantCod = $this->data['plant']; - $updatedBy = Filament::auth()->user()->name; // ?? 'Admin' - $lower = null; - $middle = null; - $upper = null; - $plantId = null; - $name = trim($this->data['name']); - if (Str::length($plantCod) < 4 || ! is_numeric($plantCod) || ! preg_match('/^[1-9]\d{3,}$/', $plantCod)) { - $warnMsg[] = 'Invalid plant code found'; - } else { - $plant = Plant::where('code', $plantCod)->first(); - if (! $plant) { - $warnMsg[] = 'Plant not found'; - } else { - $plantId = $plant->id; - $itemExists = Item::where('code', $this->data['item'])->first(); - if (! $itemExists) { - $warnMsg[] = 'Item not found'; - } + $plantCod = trim($this->data['plant']) ?? null; + $itemCod = trim($this->data['item']) ?? null; + $lineNam = trim($this->data['line']) ?? null; + $groupWorkCenter = trim($this->data['work_group_master_id']) ?? null; + $workCenter = trim($this->data['machine']) ?? null; + $charTyp = trim($this->data['characteristics_type']) ?? null; + $charName = trim($this->data['name']) ?? null; + $inspectTyp = trim($this->data['inspection_type']) ?? null; + $lower = trim($this->data['lower']) ?? null; + $middle = trim($this->data['middle']) ?? null; + $upper = trim($this->data['upper']) ?? null; + $createdBy = Filament::auth()->user()->name; + $updatedBy = null; - $itemAgainstPlant = Item::where('code', $this->data['item']) - ->where('plant_id', $plantId) - ->first(); + $plantId = null; + $itemId = null; + $lineId = null; + $workGroupMasterId = 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 ($itemCod == null || $itemCod == '') { + $warnMsg[] = "Item code can't be empty!"; + } elseif (Str::length($itemCod) < 6 || ! ctype_alnum($itemCod)) { + $warnMsg[] = 'Invalid item code found!'; + } + if ($lineNam == null || $lineNam == '') { + $warnMsg[] = "Line name can't be empty!"; + } + if ($groupWorkCenter == null || $groupWorkCenter == '') { + $warnMsg[] = "Group work center can't be empty!"; + } + if ($workCenter == null || $workCenter == '') { + $warnMsg[] = "Work center can't be empty!"; + } + if ($charTyp == null || $charTyp == '') { + $warnMsg[] = "Characteristics type can't be empty!"; + } + if ($charName == null || $charName == '') { + $warnMsg[] = "Characteristics name can't be empty!"; + } + if ($inspectTyp == null || $inspectTyp == '') { + $warnMsg[] = "Inspection type can't be empty!"; + } + if ($lower == null || $lower == '') { + $warnMsg[] = "Lower value can't be empty!"; + } + if ($middle == null || $middle == '') { + $warnMsg[] = "Middle value can't be empty!"; + } + if ($upper == null || $upper == '') { + $warnMsg[] = "Upper value can't be empty!"; + } + + 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; + $itemExists = Item::where('code', $itemCod)->first(); + if (! $itemExists) { + $warnMsg[] = 'Item code not found!'; + } else { + $itemAgainstPlant = Item::where('code', $itemCod)->where('plant_id', $plantId)->first(); if (! $itemAgainstPlant) { - $warnMsg[] = 'Item code not found for the given plant'; + $warnMsg[] = 'Item code not found for the given plant!'; } else { $itemId = $itemAgainstPlant->id; } + } - $lineExists = Line::where('name', $this->data['line'])->first(); - if (! $lineExists) { - $warnMsg[] = 'Line not found'; - } - - $lineAgainstPlant = Line::where('name', $this->data['line']) - ->where('plant_id', $plantId) - ->first(); - + $lineExists = Line::where('name', $lineNam)->first(); + if (! $lineExists) { + $warnMsg[] = 'Line name not found!'; + } else { + $lineAgainstPlant = Line::where('name', $lineNam)->where('plant_id', $plantId)->first(); if (! $lineAgainstPlant) { - $warnMsg[] = 'Line not found for the given plant'; + $warnMsg[] = 'Line name not found for the given plant!'; } else { - $LineId = $lineAgainstPlant->id; - } + $lineId = $lineAgainstPlant->id; - $WorkgroupMaster = WorkGroupMaster::where('name', $this->data['work_group_master_id'])->where('plant_id', $plantId)->first(); - if (! $WorkgroupMaster) { - $warnMsg[] = 'Work Group Master value not found'; - } else { - - $workGroupMasterId = $WorkgroupMaster->id; - - // 2. Now check if this WorkGroupMaster id exists in ANY of the 10 columns - $existsInLine = Line::where('plant_id', $plantId) - ->where(function ($q) use ($workGroupMasterId) { - for ($i = 1; $i <= 10; $i++) { - $q->orWhere("work_group{$i}_id", $workGroupMasterId); - } - }) - ->exists(); - - if (! $existsInLine) { - $warnMsg[] = "Work Group Master '{$WorkgroupMaster->name}' is not mapped to any line in this plant"; + $WorkgroupMaster = WorkGroupMaster::where('name', $groupWorkCenter)->first(); + if (! $WorkgroupMaster) { + $warnMsg[] = 'Group work center not found!'; } else { - $workGroupMasterId = $WorkgroupMaster->id; + $WorkgroupMaster = WorkGroupMaster::where('name', $groupWorkCenter)->where('plant_id', $plantId)->first(); + if (! $WorkgroupMaster) { + $warnMsg[] = 'Group work center not found for the given plant!'; + } else { + $workGroupMasterId = $WorkgroupMaster->id; + + // 2. Now check if this WorkGroupMaster id exists in ANY of the 10 columns + $existsInLine = Line::where('plant_id', $plantId)->where('id', $lineId) + ->where(function ($q) use ($workGroupMasterId) { + for ($i = 1; $i <= 10; $i++) { + $q->orWhere("work_group{$i}_id", $workGroupMasterId); + } + }) + ->exists(); + + if (! $existsInLine) { + $workGroupMasterId = null; + $warnMsg[] = "Group work center '{$WorkgroupMaster->name}' is not mapped for the given line!"; + } else { + $workGroupMasterId = $WorkgroupMaster->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 { + $machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->where('line_id', $lineId)->first(); + + if (! $machine) { + $warnMsg[] = 'Work center not found for the given line!'; + } else { + $machine = Machine::where('work_center', $workCenter)->where('plant_id', $plantId)->where('line_id', $lineId)->where('work_group_master_id', $workGroupMasterId)->first(); + + if (! $machine) { + $warnMsg[] = 'Work center not found for the given group work center!'; + } else { + $machineId = $machine->id; + } + } + } + } + } + } } } + } - $machine = Machine::where('work_center', $this->data['machine'])->first(); - if (! $machine) { - $warnMsg[] = 'Work Center not found'; - } else { - $machineId = $machine->id; - } + $user = User::where('name', $createdBy)->first(); + if (! $user) { + $warnMsg[] = 'Created by user not found!'; + } else { + $updatedBy = $createdBy; + } - $machineAgainstPlant = Machine::where('work_center', $this->data['machine']) - ->where('plant_id', $plantId) - ->first(); - - if (! $machineAgainstPlant) { - $warnMsg[] = 'Work Center not found for the given plant'; - } else { - $machineId = $machineAgainstPlant->id; - } - - if ($name == null || $name == '') { - $warnMsg[] = "Name can't be empty"; - } - - $user = User::where('name', $this->data['created_by'])->first(); - if (! $user) { - $warnMsg[] = 'Operator ID not found'; - } - - $updatedBy = Filament::auth()->user()->name; // ?? 'Admin' - if (! $updatedBy) { - $warnMsg[] = 'Invalid updated by user name found'; - } - - if (($this->data['inspection_type'] ?? null) == 'Value') { - $lower = $this->data['lower'] ?? null; - $middle = $this->data['middle'] ?? null; - $upper = $this->data['upper'] ?? null; - - if (is_null($upper) || is_null($lower) || is_null($middle)) { - $warnMsg[] = "For 'Value' inspection type, Upper, Lower, and Middle values are required."; - } elseif (! is_numeric($upper) || ! is_numeric($lower) || ! is_numeric($middle)) { - $warnMsg[] = 'Upper, Lower, and Middle values must be numeric.'; - } elseif (! ($lower <= $middle && $middle <= $upper)) { - $warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower ≤ Middle ≤ Upper."; + if ($inspectTyp == 'Value') { + if (is_null($upper) || is_null($lower) || is_null($middle)) { + $warnMsg[] = 'Upper, Lower, and Middle values are required.'; + } elseif (! is_numeric($upper) || ! is_numeric($lower) || ! is_numeric($middle)) { + $warnMsg[] = 'Upper, Lower, and Middle values must be numeric.'; + } elseif ($lower == $upper) { + if ($lower != $middle) { + $warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower = Middle = Upper."; } + } elseif (! ($lower < $middle && $middle < $upper)) { + $warnMsg[] = "For 'Value' inspection type, values must satisfy: Lower < Middle < Upper."; } + } else { + $lower = null; + $middle = null; + $upper = null; } } @@ -220,49 +277,33 @@ class ProductCharacteristicsMasterImporter extends Importer throw new RowImportFailedException(implode(', ', $warnMsg)); } - // $record = ProductCharacteristicsMaster::firstOrNew([ - // 'plant_id' => $plantId, - // 'item_id' => $itemId, - // 'line_id' => $LineId, - // 'work_group_master_id' => $workGroupMasterId, - // 'machine_id' => $machineId, - // ]); - // // If record is new, fill all fields - // if (! $record->exists) { - // $record->name = $name; - // $record->characteristics_type = $this->data['characteristics_type']; - // $record->inspection_type = $this->data['inspection_type']; - // $record->lower = $this->data['lower'] ?? null; - // $record->upper = $this->data['upper'] ?? null; - // $record->middle = $this->data['middle'] ?? null; - // $record->created_by = $this->data['created_by'] ?? null; - // $record->updated_by = $updatedBy ?? null; - // } else { - // // Record exists → update only updated_by and updated_at - // $record->updated_by = $updatedBy ?? null; - // $record->touch(); - // } - // $record->save(); + if ($machineId) { + $record = ProductCharacteristicsMaster::where('plant_id', $plantId)->where('line_id', $lineId)->where('work_group_master_id', $workGroupMasterId)->where('machine_id', $machineId)->where('item_id', $itemId)->first(); + // ->where('characteristics_type', $get('characteristics_type')) + if ($record) { + $createdBy = $record->created_by; + } - ProductCharacteristicsMaster::updateOrCreate( - [ - 'plant_id' => $plantId, - 'item_id' => $itemId, - 'line_id' => $LineId, - 'work_group_master_id' => $workGroupMasterId, - 'machine_id' => $machineId, - ], - [ - 'name' => $name, - 'characteristics_type' => $this->data['characteristics_type'], - 'inspection_type' => $this->data['inspection_type'], - 'lower' => $lower, - 'middle' => $middle, - 'upper' => $upper, - // 'created_by' => user ?? $this->data['created_by'], - 'created_by' => $this->data['created_by'] ?? null, - 'updated_by' => $updatedBy ?? null, - ]); + ProductCharacteristicsMaster::updateOrCreate( + [ + 'plant_id' => $plantId, + 'item_id' => $itemId, + 'line_id' => $lineId, + 'work_group_master_id' => $workGroupMasterId, + 'machine_id' => $machineId, + // 'characteristics_type' => $charTyp, + ], + [ + 'name' => $charName, + 'characteristics_type' => $charTyp, + 'inspection_type' => $inspectTyp, + 'lower' => $lower, + 'middle' => $middle, + 'upper' => $upper, + 'created_by' => $createdBy, + 'updated_by' => $updatedBy, + ]); + } return null; diff --git a/app/Filament/Resources/ProductCharacteristicsMasterResource.php b/app/Filament/Resources/ProductCharacteristicsMasterResource.php index da9a4f5..c4831e9 100644 --- a/app/Filament/Resources/ProductCharacteristicsMasterResource.php +++ b/app/Filament/Resources/ProductCharacteristicsMasterResource.php @@ -27,6 +27,8 @@ use Filament\Tables\Filters\Filter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; +use Illuminate\Validation\Rule; +use Str; class ProductCharacteristicsMasterResource extends Resource { @@ -71,12 +73,31 @@ class ProductCharacteristicsMasterResource extends Resource return []; } - return \App\Models\Item::where('plant_id', $plantId)->pluck('code', 'id'); + return Item::where('plant_id', $plantId)->pluck('code', 'id'); }) ->disabled(fn (Get $get) => ! empty($get('id'))) ->afterStateUpdated(function ($state, callable $set) { $set('updated_by', Filament::auth()->user()?->name); }) + ->rules([ + function (callable $get) { + return Rule::unique('product_characteristics_masters', 'item_id') + ->where('plant_id', $get('plant_id')) + ->where('line_id', $get('line_id')) + ->where('work_group_master_id', $get('work_group_master_id')) + ->where('machine_id', $get('machine_id')) + // ->where('characteristics_type', $get('characteristics_type')) + ->ignore($get('id')); + }, + // function (callable $get): Closure { + // return function (string $attribute, $value, Closure $fail) use ($get) { + // $rework = $get('rework_status'); + // if ($value && Str::contains($value, '.') && $rework == 0) { + // $fail("Rework status should be 'Yes' for rework coil number '{$value}'!"); + // } + // }; + // }, + ]) ->required(), Forms\Components\Select::make('line_id') ->label('Line') @@ -190,7 +211,7 @@ class ProductCharacteristicsMasterResource extends Resource }) ->required(), Forms\Components\TextInput::make('name') - ->label('Name') + ->label('Characteristics Name') ->reactive() ->afterStateUpdated(function ($state, callable $set) { $set('updated_by', Filament::auth()->user()?->name); @@ -311,13 +332,13 @@ class ProductCharacteristicsMasterResource extends Resource ->alignCenter() ->searchable() ->sortable(), - Tables\Columns\TextColumn::make('line.name') - ->label('Line') + Tables\Columns\TextColumn::make('item.description') + ->label('Item Description') ->alignCenter() ->searchable() ->sortable(), - Tables\Columns\TextColumn::make('characteristics_type') - ->label('Characteristics Type') + Tables\Columns\TextColumn::make('line.name') + ->label('Line') ->alignCenter() ->searchable() ->sortable(), @@ -331,10 +352,16 @@ class ProductCharacteristicsMasterResource extends Resource ->alignCenter() ->searchable() ->sortable(), - // Tables\Columns\TextColumn::make('machine.work_center') - // ->label('Work Center') - // ->alignCenter() - // ->sortable(), + Tables\Columns\TextColumn::make('characteristics_type') + ->label('Characteristics Type') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('name') + ->label('Characteristics Name') + ->alignCenter() + ->searchable() + ->sortable(), Tables\Columns\TextColumn::make('inspection_type') ->label('Inspection Type') ->alignCenter() diff --git a/app/Http/Controllers/CharacteristicsController.php b/app/Http/Controllers/CharacteristicsController.php index 5cd841e..570511f 100644 --- a/app/Http/Controllers/CharacteristicsController.php +++ b/app/Http/Controllers/CharacteristicsController.php @@ -109,8 +109,8 @@ class CharacteristicsController extends Controller ->get([ 'line_id', 'machine_id', - 'characteristics_type', 'name', + 'characteristics_type', 'inspection_type', 'lower', 'middle', @@ -2142,7 +2142,6 @@ class CharacteristicsController extends Controller public function getCharMaster(Request $request) { - $expectedUser = env('API_AUTH_USER'); $expectedPw = env('API_AUTH_PW'); $header_auth = $request->header('Authorization'); @@ -2282,8 +2281,8 @@ class CharacteristicsController extends Controller $output = [ 'work_group_master' => $workGroupName ?? '', 'name' => $charMaster?->name ?? '', - 'inspection_type' => $charMaster?->inspection_type ?? '', 'characteristics_type' => $charMaster?->characteristics_type ?? '', + 'inspection_type' => $charMaster?->inspection_type ?? '', 'lower' => (string) $charMaster?->lower ?? '', 'middle' => (string) $charMaster?->middle ?? '', 'upper' => (string) $charMaster?->upper ?? '',