From fde2208c854f5e8bc9e97929229489ffd4c734bd Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Thu, 18 Jun 2026 12:15:18 +0530 Subject: [PATCH] Added panel box validation resource pages --- .../Resources/PanelBoxValidationResource.php | 1221 +++++++++++++++++ .../Pages/CreatePanelBoxValidation.php | 269 ++++ .../Pages/EditPanelBoxValidation.php | 22 + .../Pages/ListPanelBoxValidations.php | 19 + .../Pages/ViewPanelBoxValidation.php | 19 + 5 files changed, 1550 insertions(+) create mode 100644 app/Filament/Resources/PanelBoxValidationResource.php create mode 100644 app/Filament/Resources/PanelBoxValidationResource/Pages/CreatePanelBoxValidation.php create mode 100644 app/Filament/Resources/PanelBoxValidationResource/Pages/EditPanelBoxValidation.php create mode 100644 app/Filament/Resources/PanelBoxValidationResource/Pages/ListPanelBoxValidations.php create mode 100644 app/Filament/Resources/PanelBoxValidationResource/Pages/ViewPanelBoxValidation.php diff --git a/app/Filament/Resources/PanelBoxValidationResource.php b/app/Filament/Resources/PanelBoxValidationResource.php new file mode 100644 index 0000000..d625d91 --- /dev/null +++ b/app/Filament/Resources/PanelBoxValidationResource.php @@ -0,0 +1,1221 @@ +statePath('data') + ->schema([ + Forms\Components\Select::make('plant_id') + ->label('Plant Name') + ->relationship('plant', 'name') + ->reactive() + ->options(function (callable $get) { + $userHas = Filament::auth()->user()->plant_id; + + return ($userHas && strlen($userHas) > 0) ? Plant::where('id', $userHas)->pluck('name', 'id')->toArray() : Plant::orderBy('code')->pluck('name', 'id')->toArray(); + }) + ->afterStateUpdated(function (callable $set, callable $get, $state) { + $set('item_id', null); + $set('line_id', null); + $set('production_order', null); + + $set('part_validation_type_options', []); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('validation1_image_url', null); + + $set('plant', $state); + + $pId = $get('plant_id'); + if (! $pId) { + $set('pqPlantError', 'Please select a plant first.'); + } else { + $set('pqPlantError', null); + } + + $pId = $get('line_id'); + if (! $pId) { + $set('pqLineError', null); + } + }) + ->required() + // ->default(fn () => request()->query('plant_id')) + ->default(fn ($get) => $get('plant') ?? session('last_selected_plant_id')) + ->extraAttributes(fn ($get) => [ + 'class' => $get('pqPlantError') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null) + ->hintColor('danger'), + Forms\Components\Hidden::make('plant') + ->default(fn () => session('last_selected_plant_id')) + ->afterStateHydrated(function ($state, $set) { + if (! $state && request()->has('plant_id')) { + $set('plant_id', request()->get('plant_id')); + } + }), + Forms\Components\Select::make('line_id') + ->label('Line Name') + ->relationship('line', titleAttribute: 'name') + ->reactive() + ->required() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + if (! $plantId) { + return []; + } + + return Line::where('plant_id', $plantId) + ->pluck('name', 'id') + ->toArray(); + }) + ->afterStateUpdated(function (callable $set, callable $get, $state) { + $set('item_id', null); + $set('production_order', null); + + $set('line', $state); + + $pId = $get('line_id'); + if (! $pId) { + $set('pqLineError', 'Please select a line.'); + } else { + $set('pqLineError', null); + } + }) + ->default(fn ($get) => $get('line') ?? session('last_selected_line')) + ->extraAttributes(fn ($get) => [ + 'class' => $get('pqLineError') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('pqLineError') ? $get('pqLineError') : null) + ->hintColor('danger'), + Forms\Components\Hidden::make('line') + ->default(fn () => session('last_selected_line')) + ->afterStateHydrated(function ($state, $set) { + if (! $state && request()->has('line_id')) { + $set('line_id', request()->get('line_id')); + } + }), + Forms\Components\Hidden::make('serialPanelConfirmed') + ->reactive() + ->default(false), + Forms\Components\Hidden::make('sticker_master_id') + // ->relationship('stickerMaster', 'id') + ->required(), + Forms\Components\TextInput::make('production_order') + ->placeholder('Scan the valid Production Order') + ->minLength(7) + ->maxLength(14) + ->reactive() + ->readOnly(fn (callable $get) => $get('item_id')) + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + if (! is_numeric($get('production_order')) || ! preg_match('/^[1-9][0-9]{6,13}$/', $get('production_order'))) { + $set('prodOrdError', 'Must be a numeric value with 7 to 14 digits.'); + $set('production_order', null); + $set('item_id', null); + $set('sticker_master_id', null); + $set('uom', null); + $set('serial_number', null); + } else { + $set('prodOrdError', null); + $set('production_order', $state); + $set('production', $state); + } + }) + ->default(fn ($get) => $get('production') ?? session('last_selected_production')) + ->extraAttributes(fn ($get) => [ + 'class' => $get('prodOrdError') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('prodOrdError') ? $get('prodOrdError') : null) + ->hintColor('danger') + ->required(), + Forms\Components\Hidden::make('production') + ->default(fn () => session('last_selected_production')) + ->afterStateHydrated(function ($state, $set) { + if (! $state && request()->has('production_order')) { + $set('production_order', request()->get('production_order')); + } + }), + Forms\Components\TextInput::make('item_id') + ->label('Item Code') + // ->id('item_id') + ->placeholder('Scan the valid QR code') + ->reactive() + ->required() + ->autofocus() + ->live() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + + $pId = $get('line_id'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('validation1_image_url', null); + $set('serialPanelConfirmed', false); + + if (! $pId) { + $set('pqLineError', 'Please select a line.'); + } else { + $set('pqLineError', null); + } + + $pOrder = $get('production_order'); + if (! $pOrder) { + $set('prodOrdError', "Production Order can't be empty."); + $set('production_order', null); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('validation1_image_url', null); + } else { + $set('prodOrdError', null); + } + + $serialFields = [ + 'serial_number_motor_qr', 'serial_number_pump_qr', 'pack_slip_motor_qr', 'name_plate_motor_qr', 'tube_sticker_motor_qr', 'warranty_card_qr', + ]; + + $set('serial_number', null); + + $serialnumber = ['serial_number_motor_qr']; + + $partValidationColumns = [ + 'part_validation1', 'part_validation2', 'part_validation3', 'part_validation4', 'part_validation5', + ]; + + foreach ($serialFields as $field) { + $set($field.'_visible', false); + $set($field, null); + } + + foreach ($partValidationColumns as $column) { + $set($column.'_visible', false); + $set($column, null); + } + + // Proceed with validation logic for new scanned QR code + if (! $state || trim($state) == '') { + $set('validationError', null); + + return; + } + + // // Check if QR format contains '|' + if (strpos($state, '|') == false) { + $set('validationError', 'Scan valid QR code. (Ex: Item_Code|Serial_Number)'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } + + if (! preg_match('/^[a-zA-Z0-9]{6,}+\|[1-9][a-zA-Z0-9]{8,}+(\|)?$/', $state)) { + $splits = explode('|', $state); + $iCode = trim($splits[0]); + $sNumber = isset($splits[1]) ? trim($splits[1]) : null; + + if (! ctype_alnum($iCode)) { + $set('validationError', 'Item code must contain alpha-numeric values.'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } elseif (strlen($iCode) < 6) { + $set('validationError', 'Item code must be at least 6 digits.'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } elseif (! ctype_alnum($sNumber)) { + $set('validationError', 'Serial Number must contain alpha-numeric values.'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } elseif (strlen($sNumber) < 9) { + $set('validationError', 'Serial Number must be at least 9 digits.'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } + // } + + } else { + $set('validationError', null); + } + + $parts = explode('|', $state); + + $itemCode = trim($parts[0]); // Extract item code // 123456|123456789 + + $serialNumber = trim($parts[1]); + + // Store serial number before resetting fields + $previousSerialNumber = $serialNumber; + + $previousItemCode = $itemCode; + + if (strlen($itemCode) < 6) { + $set('validationError', 'Item code must be at least 6 digits.'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } elseif (! ctype_alnum($itemCode)) { + $set('validationError', 'Item Code should contain alpha-numeric values.'); + $set('item_id', null); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } elseif ($serialNumber == '') { + $set('validationError', 'Waiting for full QR scan...'); + + return; + } elseif (strlen($serialNumber) < 9) { + $set('validationError', 'Serial Number must be at least 9 digits.'); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } elseif (! ctype_alnum($serialNumber)) { + $set('validationError', 'Serial Number should contain alpha-numeric values.'); + $set('item_id', null); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } else { + $set('validationError', null); + } + + $plantId = $get('plant_id'); // Get selected plant + + if (! $plantId) { + $set('validationError', 'Please select a plant first.'); + $set('item_id', null); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } + // Check if the item exists for the selected plant + $stickerMaster = StickerMaster::where('plant_id', $plantId)->whereHas('item', function ($query) use ($itemCode) { + $query->where('code', $itemCode); + })->first(); + + if (! $stickerMaster) { + $set('validationError', 'Item code does not exist in master data.'); + $set('sticker_master_id', null); + $set('uom', null); + $set('serial_number', null); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } else { + if (! $stickerMaster->item->uom) { + $set('validationError', "Item code does not have 'UOM' in master data."); + $set('sticker_master_id', null); + $set('uom', null); + $set('serial_number', null); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('validation1_image_url', null); + + return; + } elseif (! is_numeric($get('production_order')) || ! preg_match('/^[1-9][0-9]{6,13}$/', $get('production_order'))) { + $set('prodOrdError', 'Must be a numeric value.'); + $set('item_id', null); + $set('sticker_master_id', null); + $set('uom', null); + $set('serial_number', null); + $set('part_validation_type', null); + $set('show_validation_image', false); + $set('part_validation_type_options', []); + $set('validation1_image_url', null); + + return; + } + + $set('sticker_master_id', $stickerMaster->id); + $set('uom', $stickerMaster->item->uom); + $set('item_id', $itemCode); + // $set('serial_number', null); + // $set('serial_number', $serialNumber); + } + // Check if user input matches the database values + foreach ($partValidationColumns as $field) { + if ($get("{$field}_visible")) { + $userInput = $get($field); + $expectedValue = $stickerMaster->$field; + + if ($userInput != null && $userInput != $expectedValue) { + $set('validationError', "Invalid input for $field. Expected: $expectedValue"); + + return; // Stop execution if any validation fails + } + } + } + + $serialExists = PanelBoxValidation::where('serial_number', $serialNumber)->where('plant_id', $plantId)->exists(); + + if ($serialExists && ! $get('id')) { + $set('validationError', 'Serial number already exists in quality validation.'); + $set('sticker_master_id', null); + $set('uom', null); + $set('serial_number', null); + + return; + } + + $set('validationError', null); + + foreach ($serialFields as $column) { + + $colFld = $column; + if (str_ends_with($colFld, '_qr')) { + $colFld = substr($colFld, 0, -3); + } + + if ($stickerMaster->$colFld != null) { + $set($column.'_visible', true); + } else { + $set($column.'_visible', false); + } + } + + foreach ($partValidationColumns as $column) { + if ($stickerMaster->$column != null) { + $set($column.'_visible', true); + } else { + $set($column.'_visible', false); + } + } + + foreach ($serialnumber as $field) { + if ($get("{$field}_visible")) { + $set($field, $serialNumber); + $colFld = $field; + if (str_ends_with($colFld, '_qr')) { + $colFld = substr($colFld, 0, -3); + } + $set($colFld, '1'); + break; + } + } + // $serialAssigned = false; + + // foreach ($serialFields as $column) { + + // $colFld = $column; + + // if (str_ends_with($colFld, '_qr')) { + // $colFld = substr($colFld, 0, -3); + // } + + // $count = (int) ($stickerMaster->$colFld ?? 0); + + // // visibility always + // $set($column . '_count', $count); + + // $set($column . '_visible', $count > 0); + + // // assign serial only once + // if (!$serialAssigned && $count > 0) { + + // // single textbox + // if ($count == 1) { + // $set($column . '_1', $serialNumber); + // } + + // // multiple textbox + // if ($count > 1) { + + // for ($i = 1; $i <= $count; $i++) { + + // $set($column . '_' . $i, $serialNumber); + // } + // } + + // $set($colFld, '1'); + + // $serialAssigned = true; + // } + // } + + $set('serial_number', $serialNumber); + // Find item based on scanned code + $item = Item::where('code', $itemCode) + ->where('plant_id', $plantId)->first(); + + if (! $item) { + $set('part_validation_type_options', []); + return; + } + + // Find sticker master + $sticker = StickerMaster::where('plant_id', $plantId)->where('item_id', $item->id)->first(); + + if (! $sticker) { + $set('part_validation_type_options', []); + return; + } + + // Build dynamic options + $options = []; + + if (! empty($sticker->part_validation1)) { + $options['part_validation1'] = 'Part Validation 1'; + } + if (! empty($sticker->part_validation2)) { + $options['part_validation2'] = 'Part Validation 2'; + } + if (! empty($sticker->part_validation3)) { + $options['part_validation3'] = 'Part Validation 3'; + } + if (! empty($sticker->part_validation4)) { + $options['part_validation4'] = 'Part Validation 4'; + } + + // Save options in hidden field + $set('part_validation_type_options', $options); + + }) + ->extraAttributes(fn ($get) => [ + 'class' => $get('validationError') ? 'border-red-500' : '', + 'id' => 'item_id', + 'onkeydown' => "if (event.key === 'Enter') { event.preventDefault(); event.stopPropagation(); return false; }", + ]) + ->hint(fn ($get) => $get('validationError') ? $get('validationError') : null) + ->hintColor('danger'), + Forms\Components\Hidden::make('part_validation_type_options') + ->default([]) + ->reactive() + ->dehydrated(false), + Forms\Components\Hidden::make('show_validation_image') + ->reactive() + ->default(false), + Forms\Components\Hidden::make('validation1_image_url') + ->reactive(), + Forms\Components\Hidden::make('serial_number') + ->reactive(), + Forms\Components\TextInput::make('serial_number_motor_qr') + ->label('Serial Number') + ->reactive() + ->readOnly(fn (callable $get) => !$get('id')) + ->hidden(fn (callable $get) => !$get('serial_number_motor_qr_visible')) // Controls visibility + ->default(''), + Forms\Components\Hidden::make('serial_number_panel') + ->reactive(), + Forms\Components\TextInput::make('serial_number_panel_qr') + ->label('Serial Number Panel') + ->hidden(fn (callable $get) => !$get('serial_number_pump_qr_visible')) + ->default('') + ->reactive() + ->required() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + if (!$state || trim($state) == '') { + $set('serialPanelError', null); + return; + } + + $parts = explode('/', $state); + $extracted = trim(end($parts)); + + if (count($parts) < 3 || $extracted == '') { + $set('serialPanelError', 'Format must be: SupplierCode/ItemCode/SerialNumber'); + $set('serial_number_panel', null); + return; + } + + $expected = $get('serial_number'); + + if ($extracted != $expected) { + $set('serialPanelError', 'Serial number panel does not match.'); + $set('serial_number_panel_qr', null); + return; + } + else{ + + $set('serialPanelError', null); + $set('serial_number_panel_qr', $extracted); + $set('serial_number_panel', '1'); + return; + } + }) + ->hint(fn ($get) => $get('serialPanelError') ?? null) + ->hintColor('danger') + ->extraAttributes(fn ($get) => [ + 'class' => $get('serialPanelError') ? 'border-red-500' : '', + ]), + Forms\Components\Hidden::make('pack_slip_panel') + ->reactive(), + Forms\Components\TextInput::make('pack_slip_panel_qr') + ->label('Pack Slip Panel') + ->hidden(fn (callable $get) => !$get('pack_slip_motor_qr_visible')) + ->default('') + ->reactive() + ->required() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + if (!$state || trim($state) == '') { + $set('packSlipPanelError', null); + return; + } + + $parts = explode('/', $state); + $extracted = trim(end($parts)); + + if (count($parts) < 3 || $extracted == '') { + $set('packSlipPanelError', 'Format must be: SupplierCode/ItemCode/SerialNumber'); + $set('pack_slip_panel_qr', null); + return; + } + + $expected = $get('serial_number'); + + if ($extracted != $expected) { + $set('packSlipPanelError', 'Pack Slip Panel serial does not match.'); + $set('pack_slip_panel', null); + return; + } + else{ + $set('packSlipPanelError', null); + $set('pack_slip_panel_qr', $extracted); + $set('pack_slip_panel', '1'); + return; + } + }) + ->hint(fn ($get) => $get('packSlipPanelError') ?? null) + ->hintColor('danger') + ->extraAttributes(fn ($get) => [ + 'class' => $get('packSlipPanelError') ? 'border-red-500' : '', + ]), + Forms\Components\Hidden::make('name_plate_panel') + ->label('Name Plate Panel') + ->reactive(), + Forms\Components\TextInput::make('name_plate_panel_qr') + ->label('Name Plate Panel') + ->hidden(fn (callable $get) => !$get('name_plate_motor_qr_visible')) + ->default('') + ->reactive() + ->required() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + if (!$state || trim($state) == '') { + $set('namePlatePanelError', null); + return; + } + + $parts = explode('/', $state); + $extracted = trim(end($parts)); + + if (count($parts) < 3 || $extracted == '') { + $set('namePlatePanelError', 'Format must be: SupplierCode/ItemCode/SerialNumber'); + $set('name_plate_panel_qr', null); + return; + } + + $expected = $get('serial_number'); + + if ($extracted != $expected) { + $set('namePlatePanelError', 'Name Plate Panel serial does not match.'); + $set('name_plate_panel', null); + return; + } + else{ + $set('namePlatePanelError', null); + $set('name_plate_panel_qr', $extracted); + $set('name_plate_panel', '1'); + return; + } + }) + ->hint(fn ($get) => $get('namePlatePanelError') ?? null) + ->hintColor('danger') + ->extraAttributes(fn ($get) => [ + 'class' => $get('namePlatePanelError') ? 'border-red-500' : '', + ]), + Forms\Components\Hidden::make('tube_sticker_panel') + ->label('Tube Sticker Panel') + ->reactive(), + Forms\Components\TextInput::make('tube_sticker_panel_qr') + ->label('Tube Sticker Panel') + ->hidden(fn (callable $get) => !$get('tube_sticker_motor_qr_visible')) + ->default('') + ->reactive() + ->required() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + if (!$state || trim($state) == '') { + $set('tubeStickerPanelError', null); + return; + } + + $parts = explode('/', $state); + $extracted = trim(end($parts)); + + if (count($parts) < 3 || $extracted == '') { + $set('tubeStickerPanelError', 'Format must be: SupplierCode/ItemCode/SerialNumber'); + $set('tube_sticker_panel_qr', null); + return; + } + + $expected = $get('serial_number'); + + if ($extracted != $expected) { + $set('tubeStickerPanelError', 'Tube Sticker Panel serial does not match.'); + $set('tube_sticker_panel_qr', null); + return; + } + else{ + $set('tubeStickerPanelError', null); + $set('tube_sticker_panel_qr', $extracted); + $set('tube_sticker_panel', '1'); + return; + } + }) + ->hint(fn ($get) => $get('tubeStickerPanelError') ?? null) + ->hintColor('danger') + ->extraAttributes(fn ($get) => [ + 'class' => $get('tubeStickerPanelError') ? 'border-red-500' : '', + ]), + + Forms\Components\Hidden::make('warranty_card_panel') + ->label('Warranty Card') + ->reactive(), + Forms\Components\TextInput::make('warranty_card_qr') + ->label('Warranty Card Panel') + ->hidden(fn (callable $get) => !$get('warranty_card_qr_visible')) + ->default('') + ->reactive() + ->required() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + if (!$state || trim($state) == '') { + $set('warrantyCardPanelError', null); + return; + } + + $parts = explode('/', $state); + $extracted = trim(end($parts)); + + if (count($parts) < 3 || $extracted == '') { + $set('warrantyCardPanelError', 'Format must be: SupplierCode/ItemCode/SerialNumber'); + $set('warranty_card_qr', null); + return; + } + + $expected = $get('serial_number'); + + if ($extracted != $expected) { + $set('warrantyCardPanelError', 'Tube Sticker Panel serial does not match.'); + $set('warranty_card_qr', null); + return; + } + else{ + $set('warrantyCardPanelError', null); + $set('warranty_card_qr', $extracted); + $set('warranty_card_panel', '1'); + return; + } + }) + ->hint(fn ($get) => $get('warrantyCardPanelError') ?? null) + ->hintColor('danger') + ->extraAttributes(fn ($get) => [ + 'class' => $get('warrantyCardPanelError') ? 'border-red-500' : '', + ]), + + Forms\Components\TextInput::make('part_validation1') + ->label('Part Validation 1') + ->hidden(fn (callable $get) => ! $get('part_validation1_visible')) + ->default('') + ->reactive() + ->required() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + + $mPorder = $get('production_order'); + + $mPlantId = $get('plant_id'); + + $mlineId = $get('line_id'); + + $plant = Plant::find($mPlantId); + $plantCodePart1 = $plant?->code; + + $mLine = Line::find($mlineId); + $mLinePart = $mLine?->name; + + $stickerMasterId = $get('sticker_master_id'); + if (! $stickerMasterId) { + return; + } + + $stickerMaster = StickerMaster::find($stickerMasterId); + if (! $stickerMaster) { + return; + } + + $expectedValue = $stickerMaster->part_validation1; + $mExpectedValue = $expectedValue ?? null; + + if ($state == null || trim($state) == '') { + $set('part_validation1_error', null); + + return; + } + + + if (strpos($state, '|') !== false) { + $state = explode('|', $state)[0]; + if ($state != $expectedValue){ + $set('part_validation1_error', 'Invalid input for part validation 1.'); + } + else{ + $set('part_validation1', $state); + $set('part_validation1_error', null); + } + } + if ($state == $expectedValue) { + $set('part_validation1_error', null); + } else { + $set('part_validation1_error', 'Invalid input for part validation 1.'); + + return; + } + }) + ->extraAttributes(fn ($get) => [ + 'class' => $get('part_validation1_error') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('part_validation1_error')) + ->hintColor('danger'), + + Forms\Components\TextInput::make('part_validation2') + ->label('Part Validation 2') + ->hidden(fn (callable $get) => ! $get('part_validation2_visible')) + ->default('') + ->required() + ->reactive() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + + $mPorder = $get('production_order'); + + $mPlantId = $get('plant_id'); + $plant = Plant::find($mPlantId); + $plantCodePart2 = $plant?->code; + + $mlineId = $get('line_id'); + + $mLine = Line::find($mlineId); + $mLinePart = $mLine?->name; + + $stickerMasterId = $get('sticker_master_id'); + if (! $stickerMasterId) { + return; + } + + $stickerMaster = StickerMaster::find($stickerMasterId); + if (! $stickerMaster) { + return; + } + + $expectedValue = $stickerMaster->part_validation2; + $mExpectedValue = $expectedValue ?? null; + + if ($state == null || trim($state) == '') { + $set('part_validation2_error', null); + + return; + } + + if ($state == $expectedValue) { + $set('part_validation2_error', null); + } else { + $set('part_validation2_error', 'Invalid input for part validation 2.'); + + return; + } + }) + ->extraAttributes(fn ($get) => [ + 'class' => $get('part_validation2_error') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('part_validation2_error')) + ->hintColor('danger'), + + Forms\Components\TextInput::make('part_validation3') + ->label('Part Validation 3') + ->hidden(fn (callable $get) => ! $get('part_validation3_visible')) + ->default('') + ->required() + ->reactive() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + $stickerMasterId = $get('sticker_master_id'); + + $mPorder = $get('production_order'); + + $mPlantId = $get('plant_id'); + $plant = Plant::find($mPlantId); + $plantCodePart3 = $plant?->code; + + $mlineId = $get('line_id'); + + $mLine = Line::find($mlineId); + $mLinePart = $mLine?->name; + + if (! $stickerMasterId) { + return; + } + + $stickerMaster = StickerMaster::find($stickerMasterId); + if (! $stickerMaster) { + return; + } + + if ($state == null || trim($state) == '') { + $set('part_validation3_error', null); + + return; + } + + $expectedValue = $stickerMaster->part_validation3; + $mExpectedValue = $expectedValue ?? null; + + if ($state == $expectedValue) { + $set('part_validation3_error', null); + } else { + $set('part_validation3_error', 'Invalid input for part validation 3.'); + + return; + } + }) + ->extraAttributes(fn ($get) => [ + 'class' => $get('part_validation3_error') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('part_validation3_error')) + ->hintColor('danger'), + + Forms\Components\TextInput::make('part_validation4') + ->label('Part Validation 4') + ->hidden(fn (callable $get) => ! $get('part_validation4_visible')) + ->default('') + ->required() + ->reactive() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + $stickerMasterId = $get('sticker_master_id'); + $mPorder = $get('production_order'); + + $mPlantId = $get('plant_id'); + $plant = Plant::find($mPlantId); + $plantCodePart4 = $plant?->code; + + $mlineId = $get('line_id'); + + $mLine = Line::find($mlineId); + $mLinePart = $mLine?->name; + + if (! $stickerMasterId) { + return; + } + + $stickerMaster = StickerMaster::find($stickerMasterId); + if (! $stickerMaster) { + return; + } + + $expectedValue = $stickerMaster->part_validation4; + + if ($state == null || trim($state) == '') { + $set('part_validation4_error', null); + + return; + } + + if ($state == $expectedValue) { + $set('part_validation4_error', null); + } else { + $set('part_validation4_error', 'Invalid input for part validation 4.'); + return; + } + }) + ->extraAttributes(fn ($get) => [ + 'class' => $get('part_validation4_error') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('part_validation4_error')) + ->hintColor('danger'), + + Forms\Components\TextInput::make('part_validation5') + ->label('Part Validation 5') + ->hidden(fn (callable $get) => ! $get('part_validation5_visible')) + ->default('') + ->required() + ->reactive() + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + $stickerMasterId = $get('sticker_master_id'); + + if (! $stickerMasterId) { + return; + } + + $stickerMaster = StickerMaster::find($stickerMasterId); + if (! $stickerMaster) { + return; + } + + $expectedValue = $stickerMaster->part_validation5; + + // If input is empty, reset the error + if ($state == null || trim($state) == '') { + $set('part_validation5_error', null); + + return; + } + + if ($state == $expectedValue) { + $set('part_validation5_error', null); + } elseif (strpos($state, '/') != false) { + $parts = explode('/', $state); + if (count($parts) >= 2) { + $segmentToValidate = $parts[1]; + if ($segmentToValidate == $expectedValue) { + $set('part_validation5_error', null); + $set('part_validation5', $segmentToValidate); + } else { + $set('part_validation5_error', 'Invalid input for part validation 5.'); + $set('part_validation5', null); + + return; + } + } else { + $set('part_validation5_error', 'Invalid input format for part validation 5.'); + $set('part_validation5', null); + + return; + } + } else { + $set('part_validation5_error', 'Invalid input for part validation 5.'); + $set('part_validation5', null); + + return; + } + + }) + ->extraAttributes(fn ($get) => [ + 'class' => $get('part_validation5_error') ? 'border-red-500' : '', + ]) + ->hint(fn ($get) => $get('part_validation5_error')) + ->hintColor('danger'), + // Forms\Components\TextInput::make('id') + // ->hidden() + // ->readOnly(), + 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\View::make('components.panel-checklist-wrapper') + ->visible(fn ($livewire) => $livewire->showChecklist) + ->statePath('checklist') + ->viewData(fn ($livewire) => [ + 'existingRecords' => $livewire->existingRecords->toArray(), + 'data' => $livewire->data, + 'showChecklist' => $livewire->showChecklist, + ]), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('No.') + ->label('No.') + ->alignCenter() + ->getStateUsing(function ($record, $livewire, $column, $rowLoop) { + $paginator = $livewire->getTableRecords(); + $perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10; + $currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1; + return ($currentPage - 1) * $perPage + $rowLoop->iteration; + }), + Tables\Columns\TextColumn::make('plant.name') + ->label('Plant') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('line.name') + ->label('Line') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('stickerMaster.item.code') + ->label('Item Code') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('serial_number') + ->label('Serial Number') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('serial_number_panel') + ->label('Serial Number Panel') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('pack_slip_panel') + ->label('Pack Slip Panel') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('name_plate_panel') + ->label('Name Plate Panel') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('tube_sticker_panel') + ->label('Tube Sticker Panel') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('warranty_card_panel') + ->label('Warranty Card Panel') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('part_validation1') + ->label('Part Validation 1') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('part_validation2') + ->label('Part Validation 2') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('part_validation3') + ->label('Part Validation 3') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('part_validation4') + ->label('Part Validation 4') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('part_validation5') + ->label('Part Validation 5') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('created_at') + ->label('Created At') + ->alignCenter() + ->dateTime() + ->sortable(), + Tables\Columns\TextColumn::make('created_by') + ->label('Created By') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('updated_at') + ->label('Updated At') + ->alignCenter() + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_by') + ->label('Updated By') + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('deleted_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + ->filters([ + Tables\Filters\TrashedFilter::make(), + ]) + ->actions([ + Tables\Actions\ViewAction::make(), + Tables\Actions\EditAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + Tables\Actions\ForceDeleteBulkAction::make(), + Tables\Actions\RestoreBulkAction::make(), + ]), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListPanelBoxValidations::route('/'), + 'create' => Pages\CreatePanelBoxValidation::route('/create'), + 'view' => Pages\ViewPanelBoxValidation::route('/{record}'), + 'edit' => Pages\EditPanelBoxValidation::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/PanelBoxValidationResource/Pages/CreatePanelBoxValidation.php b/app/Filament/Resources/PanelBoxValidationResource/Pages/CreatePanelBoxValidation.php new file mode 100644 index 0000000..d27bf9c --- /dev/null +++ b/app/Filament/Resources/PanelBoxValidationResource/Pages/CreatePanelBoxValidation.php @@ -0,0 +1,269 @@ + 'setChecklist', + 'checklist-cancelled' => 'handleChecklistCancel', + 'checklist-saved' => 'checkListSaved', + ]; + + public function setChecklist($checklist) + { + $this->data['checklist'] = $checklist; + } + + public function doCreate() + { + $this->create(); + } + + public function mount(): void + { + parent::mount(); + + session()->forget([ + 'last_selected_plant_id', + 'last_selected_line', + 'last_selected_production', + ]); + } + + public function handleChecklistCancel() + { + $this->skipChecklistValidation = true; + $this->showChecklist = false; + } + + protected function mutateFormDataBeforeCreate(array $data): array + { + // if ($this->shouldSkipChecklist) { + // return $data; + // } + + if ($this->checkIfHasCharacteristics($data)) { + $this->showChecklist = true; + $this->halt(); + } + + return $data; + } + + protected function checkIfHasCharacteristics(array $data) + { + $plantId = $data['plant_id'] ?? null; + $itemCode = $data['item_id'] ?? null; + $lineId = $data['line_id'] ?? null; + + if (!$plantId || !$itemCode || !$lineId) { + return false; + } + + $item = \App\Models\Item::where('code', $itemCode) + ->where('plant_id', $plantId) + ->first(); + + $categoryName = trim($item->category) ?? null; + + if (!$item) { + $this->existingRecords = collect(); + return false; + } + + $this->existingRecords = ProductCharacteristicsMaster::where('plant_id', $plantId) + ->where('category', $categoryName) + ->where('line_id', $lineId) + ->get(); + + return $this->existingRecords->isNotEmpty(); + } + + public function checkListSaved() + { + $this->showChecklist = false; + + $plantId = $this->data['plant_id'] ?? null; + $lineId = $this->data['line_id'] ?? null; + $productionOrder = $this->data['production_order'] ?? null; + + return redirect()->to( + static::getResource()::getUrl('create', [ + 'plant_id' => $this->data['plant_id'] ?? null, + 'line_id' => $this->data['line_id'] ?? null, + 'production_order' => $this->data['production_order'] ?? null, + ]) + ); + } + + protected function beforeCreate(): void + { + $errors = []; + + if (!empty($this->data['validationError'])) { + $errors['validationError'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['serialPanelError'])) { + $errors['serialPanelError'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['packSlipPanelError'])) { + $errors['packSlipPanelError'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['namePlatePanelError'])) { + $errors['namePlatePanelError'] = ['Fix the errors before submitting.']; + } + + //..name plate + + if (!empty($this->data['tubeStickerPanelError'])) { + $errors['tubeStickerPanelError'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['warrantyCardPanelError'])) { + $errors['warrantyCardPanelError'] = ['Fix the errors before submitting.']; + } + + //..part validations + + if (!empty($this->data['part_validation1_error'])) { + $errors['part_validation1_error'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['part_validation2_error'])) { + $errors['part_validation2_error'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['part_validation3_error'])) { + $errors['part_validation3_error'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['part_validation4_error'])) { + $errors['part_validation4_error'] = ['Fix the errors before submitting.']; + } + + if (!empty($this->data['part_validation5_error'])) { + $errors['part_validation5_error'] = ['Fix the errors before submitting.']; + } + + if (!empty($errors)) { + throw ValidationException::withMessages($errors); + } + + $this->checkExisting(); + + $checklist = $this->data['data']['checklist'] ?? []; + + if (count($this->existingRecords) > 0){ + + $this->showChecklist = true; + $this->halt(); + } + else{ + $this->showChecklist = false; + } + } + + public function checkExisting() + { + $plant_id = $this->data['plant_id'] ?? null; + $item_code = $this->data['item_id'] ?? null; + $line_id = $this->data['line_id'] ?? null; + + + $item = \App\Models\Item::where('code', $item_code)->where('plant_id', $plant_id)->first(); + + if (!$item) { + $this->existingRecords = collect(); + return; + } + + // $item_id = $item->id; + $categoryName = trim($item->category) ?? null; + + $this->existingRecords = ProductCharacteristicsMaster::where('plant_id', $plant_id) + ->where('category', $categoryName) + ->where('line_id', $line_id) + ->get(); + } + + protected function afterCreate(): void + { + // Get the value from the hidden field 'plant' + $plant = $this->form->getState()['plant'] ?? null; + $line = $this->form->getState()['line'] ?? null; + $production = $this->form->getState()['production'] ?? null; + + // $this->skipChecklistValidation = false; + // $this->showChecklist = false; + // $this->checklist = []; + + // $this->form->fill(); + + // reset checklist + $this->checklist = []; + + $this->skipChecklistValidation = false; + $this->showChecklist = false; + + $this->form->fill([]); + + $this->data = []; + + $this->resetValidation(); + $this->resetErrorBag(); + + $this->form->fill([ + 'plant_id' => null, + 'line_id' => null, + 'production_order' => null, + ]); + + + // $this->dispatch('focus-item-id'); + session()->flash('focus_item_id_after_redirect', true); + logger('Focus flag set in session'); + + if ($plant) { + session(['last_selected_plant_id' => $plant]); + } + if ($line) { + session(['last_selected_line' => $line]); + } + if ($production) { + session(['last_selected_production' => $production]); + } + } + + protected function getRedirectUrl(): string + { + //return $this->getResource()::getUrl('create'); // Stay on Create Page after savin + + return $this->getResource()::getUrl('create', [ + 'plant_id' => $this->data['plant_id'] ?? null, + 'line_id' => $this->data['line_id'] ?? null, + 'production_order' => $this->data['production_order'] ?? null, + ]); + } +} diff --git a/app/Filament/Resources/PanelBoxValidationResource/Pages/EditPanelBoxValidation.php b/app/Filament/Resources/PanelBoxValidationResource/Pages/EditPanelBoxValidation.php new file mode 100644 index 0000000..09e0774 --- /dev/null +++ b/app/Filament/Resources/PanelBoxValidationResource/Pages/EditPanelBoxValidation.php @@ -0,0 +1,22 @@ +