After Production Quantity and Overall Validation

This commit is contained in:
dhanabalan
2025-03-30 23:04:29 +05:30
parent e46f290fd1
commit 6e44b690f1
16 changed files with 1726 additions and 407 deletions

View File

@@ -34,7 +34,7 @@ class ItemImporter extends Importer
->requiredMapping() ->requiredMapping()
->exampleHeader('Plant Name') ->exampleHeader('Plant Name')
->label('Plant Name') ->label('Plant Name')
->relationship(resolveUsing:'name') ->relationship(resolveUsing: 'name')
->rules(['required']), ->rules(['required']),
]; ];
} }

View File

@@ -13,6 +13,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
class BlockResource extends Resource class BlockResource extends Resource
{ {
@@ -22,18 +23,60 @@ class BlockResource extends Resource
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 3;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->required(), ->required()
// ->unique(ignoreRecord: true), ->unique(ignoreRecord: true)
// ->columnSpanFull(), ->placeholder('Scan the valid name')
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('name');
// Ensure `linestop_id` is not cleared
if (!$nameId) {
$set('bNameError', 'Scan the valid name.');
return;
}
else
{
$set('bNameError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('bNameError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('bNameError') ? $get('bNameError') : null)
->hintColor('danger'),
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
// ->unique(ignoreRecord: true) // ->unique(ignoreRecord: true)
->required(), ->required()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('plant_id');
// Ensure `linestop_id` is not cleared
if (!$nameId) {
$set('bPlantError', 'Please select a plant first.');
return;
}
else
{
$set('bPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('bPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('bPlantError') ? $get('bPlantError') : null)
->hintColor('danger'),
])
->columns(2),
]); ]);
} }

View File

@@ -15,6 +15,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
class CompanyResource extends Resource class CompanyResource extends Resource
{ {
@@ -24,15 +25,40 @@ class CompanyResource extends Resource
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 1;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->required() ->required()
//->citext('name') //->citext('name')
->placeholder('Scan the valid name')
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->columnSpanFull(), ->columnSpanFull()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$companyId = $get('name');
// Ensure `linestop_id` is not cleared
if (!$companyId) {
$set('cNameError', 'Scan the valid name first.');
return;
}
else
{
$set('cNameError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('cNameError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('cNameError') ? $get('cNameError') : null)
->hintColor('danger'),
])
->columns(2),
]); ]);
} }

View File

@@ -15,6 +15,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
class ItemResource extends Resource class ItemResource extends Resource
{ {
@@ -24,26 +25,106 @@ class ItemResource extends Resource
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 5;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->required(), ->required()
// ->nullable(), // ->nullable(),
->reactive()
// ->afterStateUpdated(fn ($set) => $set('block_id', null) & $set('name', null) & $set('start_time', null) & $set('duration', null) & $set('end_time', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
// Ensure `linestop_id` is not cleared
if (!$plantId) {
$set('iPlantError', 'Please select a plant first.');
return;
}
else
{
$set('iPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iPlantError') ? $get('iPlantError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('code') Forms\Components\TextInput::make('code')
->required() ->required()
->placeholder('Scan the valid code')
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->alphaNum()
->minLength(6) ->minLength(6)
->autocapitalize('code'), // ->autocapitalize('characters')
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$code = $get('code');
// Ensure `linestop_id` is not cleared
if (!$code) {
$set('iCodeError', 'Scan the valid code.');
return;
}
else
{
if (strlen($code) < 6) {
$set('iCodeError', 'Item code must be at least 6 digits.');
return;
}
else if (!preg_match('/^[a-zA-Z0-9]{6,}$/', $code)) {
$set('code',null);
$set('iCodeError', 'Item code must contain only alpha-numeric characters.');
return;
}
$set('iCodeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iCodeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iCodeError') ? $get('iCodeError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('hourly_quantity') Forms\Components\TextInput::make('hourly_quantity')
->required() ->required()
->numeric() ->label('Hourly Quantity')
->minValue(1), ->placeholder('Scan the valid quantity')
->integer()
->minValue(1)
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$hourQuan = $get('hourly_quantity');
// Ensure `linestop_id` is not cleared
if (!$hourQuan) {
$set('iHourQuanError', 'Scan the valid hourly quantity.');
return;
}
else
{
if (!preg_match('/^[0-9]{1,}$/', $hourQuan)) {
$set('hourly_quantity',null);
$set('iHourQuanError', 'Quantity must be integer value.');
return;
}
$set('iHourQuanError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('iHourQuanError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('iHourQuanError') ? $get('iHourQuanError') : null)
->hintColor('danger'),
Forms\Components\Textarea::make('description') Forms\Components\Textarea::make('description')
->required(), ->required()
->placeholder('Scan the valid description'),
// ->columnSpanFull(), // ->columnSpanFull(),
])
->columns(2),
]); ]);
} }

View File

@@ -14,6 +14,8 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
use Illuminate\Validation\Rules\Unique;
class LineResource extends Resource class LineResource extends Resource
{ {
@@ -22,21 +24,108 @@ class LineResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 6;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->required(), ->required()
// ->nullable(), // ->nullable(),
Forms\Components\Textarea::make('name') ->reactive()
->required(), // ->afterStateUpdated(fn ($set) => $set('block_id', null) & $set('name', null) & $set('start_time', null) & $set('duration', null) & $set('end_time', null))
// ->columnSpanFull(), ->afterStateUpdated(function ($state, callable $set, callable $get) {
Forms\Components\Textarea::make('type') $plantId = $get('plant_id');
->required(), // Ensure `linestop_id` is not cleared
//->columnSpanFull(), if (!$plantId) {
$set('lPlantError', 'Please select a plant first.');
return;
}
else
{
$set('lPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('lPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('lPlantError') ? $get('lPlantError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('name')
->required()
->placeholder('Scan the valid name')
// ->unique(
// ignoreRecord: true,
// modifyRuleUsing: function (Unique $rule) {
// return $rule->where('plant_id', $this->data['plant_id']);
// }
// )
// ->rule(function () {
// return function ($attribute, $value, $fail) {
// $exists = Line::where('name', $value)
// ->where('plant_id', request()->input('plant_id'))
// ->exists();
// if ($exists) {
// $fail('The combination of name and plant ID must be unique.');
// }
// };
// })
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineNam = $get('name');
// Ensure `linestop_id` is not cleared
if (!$lineNam) {
$set('lNameError', 'Scan the valid name.');
return;
}
else
{
$exists = Line::where('name', $lineNam)
->where('plant_id', $get('plant_id'))
->exists();
if ($exists) {
$set('name', null);
$set('lNameError', 'The name has already been taken.');
// $set('lNameError', 'The combination of name and plant ID must be unique.');
return;
}
$set('lNameError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('lNameError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('lNameError') ? $get('lNameError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('type')
->required()
->placeholder('Scan the valid type')
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineTyp = $get('type');
// Ensure `linestop_id` is not cleared
if (!$lineTyp) {
$set('lTypeError', 'Scan the valid type.');
return;
}
else
{
$set('lTypeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('lTypeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('lTypeError') ? $get('lTypeError') : null)
->hintColor('danger'),
])
->columns(2),
]); ]);
} }

View File

@@ -6,6 +6,7 @@ use App\Filament\Imports\LineStopImporter;
use App\Filament\Resources\LineStopResource\Pages; use App\Filament\Resources\LineStopResource\Pages;
use App\Filament\Resources\LineStopResource\RelationManagers; use App\Filament\Resources\LineStopResource\RelationManagers;
use App\Models\LineStop; use App\Models\LineStop;
use Doctrine\DBAL\Exception\InvalidColumnType\ColumnPrecisionRequired;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Resources\Resource; use Filament\Resources\Resource;
@@ -14,6 +15,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
class LineStopResource extends Resource class LineStopResource extends Resource
{ {
@@ -23,16 +25,71 @@ class LineStopResource extends Resource
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 7;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\TextInput::make('code') Forms\Components\TextInput::make('code')
->required() ->required()
->autocapitalize(autocapitalize: 'code'), ->alphaNum()
Forms\Components\Textarea::make('reason') ->unique(ignoreRecord: true)
->required(), ->minLength(3)
//->columnSpanFull(), ->placeholder('Scan the valid code')
->autocapitalize(autocapitalize: 'characters')
->columnSpan(1)
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$code = $get('code');
if (!$code) {
$set('lsCodeError', 'Scan the valid code.');
return;
}
else
{
if (strlen($code) < 3) {
$set('lsCodeError', 'Code must be at least 3 digits.');
return;
}
else if (!preg_match('/^[a-zA-Z0-9]{3,}$/', $code)) {
$set('code',null);
$set('lsCodeError', 'Alpha-numeric only allowed.');
return;
}
$set('lsCodeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('lsCodeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('lsCodeError') ? $get('lsCodeError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('reason')
->required()
->placeholder('Scan the valid reason')
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$reason = $get('reason');
if (!$reason) {
$set('lsReasonError', 'Scan the valid reason.');
return;
}
else
{
$set('lsReasonError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('lsReasonError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('lsReasonError') ? $get('lsReasonError') : null)
->hintColor('danger')
->columnSpan(['default' => 1, 'sm' => 2]),
])
->columns(['default' => 1, 'sm' => 3]),
]); ]);
} }

View File

@@ -23,6 +23,8 @@ class PlantResource extends Resource
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 2;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
@@ -32,19 +34,104 @@ class PlantResource extends Resource
Forms\Components\TextInput::make('code') Forms\Components\TextInput::make('code')
->required() ->required()
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->numeric() ->integer()
->minValue(1000), ->reactive()
->placeholder('Scan the valid code')
->minValue(1000)
->afterStateUpdated(function ($state, callable $set, callable $get) {
$codeId = $get('code');
// Ensure `linestop_id` is not cleared
if (!$codeId) {
$set('pCodeError', 'Scan the valid code.');
return;
}
else
{
if (strlen($codeId) < 4) {
$set('pCodeError', 'Code must be at least 4 digits.');
return;
}
// if (!preg_match('/^[1-9][0-9]{3,}$/', $codeId)) {
// $set('code',null);
// $set('pCodeError', 'Code should not begin with zero and must contain 4 digit number.');
// return;
// }
$set('pCodeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pCodeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pCodeError') ? $get('pCodeError') : null)
->hintColor('danger'),
Forms\Components\Select::make('company_id') Forms\Components\Select::make('company_id')
// ->placeholder('Choose the valid company name')
->relationship('company', 'name') ->relationship('company', 'name')
->required(), ->required()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$companyId = $get('company_id');
// Ensure `linestop_id` is not cleared
if (!$companyId) {
$set('pCompanyError', 'Please select a company first.');
return;
}
else
{
$set('pCompanyError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pCompanyError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pCompanyError') ? $get('pCompanyError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->required() ->required()
->placeholder('Scan the valid name')
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->columnSpanFull(), ->columnSpanFull()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('name');
// Ensure `linestop_id` is not cleared
if (!$nameId) {
$set('pNameError', 'Scan the valid name.');
return;
}
else
{
$set('pNameError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pNameError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pNameError') ? $get('pNameError') : null)
->hintColor('danger'),
Forms\Components\Textarea::make('address') Forms\Components\Textarea::make('address')
->required() ->required()
->placeholder('Scan the valid address')
->unique(ignoreRecord: true) ->unique(ignoreRecord: true)
->columnSpanFull(), ->columnSpanFull()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('address');
// Ensure `linestop_id` is not cleared
if (!$nameId) {
$set('pAddressError', 'Scan the valid address.');
return;
}
else
{
$set('pAddressError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pAddressError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pAddressError') ? $get('pAddressError') : null)
->hintColor('danger'),
]) ])
->columns(2), ->columns(2),
]); ]);

View File

@@ -15,7 +15,7 @@ use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Carbon\Carbon; use Carbon\Carbon;
use Filament\Forms\Components\Section;
class ProductionLineStopResource extends Resource class ProductionLineStopResource extends Resource
{ {
@@ -31,48 +31,125 @@ class ProductionLineStopResource extends Resource
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->required() ->required()
->nullable() // ->nullable()
->reactive(), ->reactive()
// ->afterStateUpdated(fn ($set) => $set('block_name', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
$set('block_name', null);
if (!$plantId) {
$set('plsPlantError', 'Please select a plant first.');
return;
}
else
{
$set('plsPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('plsPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('plsPlantError') ? $get('plsPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('block_name') Forms\Components\Select::make('block_name')
->required() ->required()
->nullable() // ->nullable()
->label('Block')
->options(function (callable $get) {
if (!$get('plant_id')) {
return [];
}
return \App\Models\Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id')
->toArray();
})
->reactive() ->reactive()
->afterStateUpdated(fn ($set) => $set('shift_id', null)), // ->afterStateUpdated(fn ($set) => $set('shift_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$blockId = $get('block_name');
$set('shift_id', null);
if (!$blockId) {
$set('plsBlockError', 'Please select a block first.');
return;
}
else
{
$set('plsBlockError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('plsBlockError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('plsBlockError') ? $get('plsBlockError') : null)
->hintColor('danger'),
Forms\Components\Select::make('shift_id') Forms\Components\Select::make('shift_id')
->relationship('shift', 'name') ->relationship('shift', 'name')
->required() ->required()
->nullable() // ->nullable()
// ->options(fn (callable $get) => // ->options(fn (callable $get) =>
// \App\Models\Shift::where('plant_id', $get('plant_id')) // \App\Models\Shift::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id') // ->pluck('name', 'id')
// ->toArray() // Convert collection to array // ->toArray() // Convert collection to array
// ) // )
->options(function (callable $get) { ->options(function (callable $get) {
if (!$get('plant_id')) { if (!$get('plant_id') || !$get('block_name')) {
return []; return [];
} }
// // Get the block ID based on plant_id and block_name
// $block = \App\Models\Block::where('plant_id', $get('plant_id'))
// ->where('name', $get('block_name'))
// ->first();
// if (!$block) {
// return [];
// }
// return \App\Models\Shift::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id')
// ->toArray();
return \App\Models\Shift::where('plant_id', $get('plant_id')) return \App\Models\Shift::where('plant_id', $get('plant_id'))
->where('block_id', $get('block_name'))
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
->reactive() ->reactive()
->afterStateUpdated(fn ($set) => $set('line_id', null)), // ->afterStateUpdated(fn ($set) => $set('line_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$shiftId = $get('shift_id');
$set('line_id', null);
if (!$shiftId) {
$set('plsShiftError', 'Please select a shift first.');
return;
}
else
{
$set('plsShiftError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('plsShiftError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('plsShiftError') ? $get('plsShiftError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id') Forms\Components\Select::make('line_id')
->relationship('line', 'name') ->relationship('line', 'name')
->required() ->required()
->nullable() // ->nullable()
// ->options(fn (callable $get) => // ->options(fn (callable $get) =>
// \App\Models\Line::where('plant_id', $get('plant_id')) // \App\Models\Line::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id') // ->pluck('name', 'id')
// ->toArray() // Convert collection to array // ->toArray() // Convert collection to array
// ) // )
->options(function (callable $get) { ->options(function (callable $get) {
if (!$get('plant_id')) { if (!$get('plant_id') || !$get('block_name') || !$get('shift_id')) {
return []; return [];
} }
@@ -80,7 +157,23 @@ class ProductionLineStopResource extends Resource
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
->reactive(), ->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (!$lineId) {
$set('plsLineError', 'Please select a line first.');
return;
}
else
{
$set('plsLineError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('plsLineError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('plsLineError') ? $get('plsLineError') : null)
->hintColor('danger'),
// Forms\Components\Select::make('linestop_id') // Forms\Components\Select::make('linestop_id')
// ->label('Line Stop Code') // ->label('Line Stop Code')
// ->relationship('linestop', 'code') // ->relationship('linestop', 'code')
@@ -94,9 +187,10 @@ class ProductionLineStopResource extends Resource
// \App\Models\LineStop::where('id', $get('linestop_id')) // \App\Models\LineStop::where('id', $get('linestop_id'))
// ->pluck('code', 'id') // ->pluck('code', 'id')
// ) // )
->placeholder('Scan the valid code')
->options(fn () => \App\Models\LineStop::pluck('code', 'id')) ->options(fn () => \App\Models\LineStop::pluck('code', 'id'))
->required() ->required()
->nullable() // ->nullable()
// ->reactive() // ->reactive()
->searchable() ->searchable()
->live(debounce: 500) // Enable live updates ->live(debounce: 500) // Enable live updates
@@ -138,14 +232,18 @@ class ProductionLineStopResource extends Resource
), ),
Forms\Components\TextInput::make('stop_hour') Forms\Components\TextInput::make('stop_hour')
->required() ->required()
->label( 'Stop Hour')
// ->dehydrated(false) // Don't send to backend // ->dehydrated(false) // Don't send to backend
->readOnly(true) ->readOnly(true)
->numeric(), ->numeric(),
Forms\Components\TextInput::make('stop_min') Forms\Components\TextInput::make('stop_min')
->required() ->required()
->label('Stop Minute')
// ->dehydrated(false) // ->dehydrated(false)
->readOnly(true) ->readOnly(true)
->numeric(), ->numeric(),
])
->columns(2),
]); ]);
} }

View File

@@ -14,6 +14,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
class ProductionPlanResource extends Resource class ProductionPlanResource extends Resource
{ {
@@ -28,48 +29,108 @@ class ProductionPlanResource extends Resource
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->required() ->required()
->nullable() // ->nullable()
->reactive(), ->reactive()
// ->afterStateUpdated(fn ($set) => $set('block_name', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
$set('block_name', null);
if (!$plantId) {
$set('ppPlantError', 'Please select a plant first.');
return;
}
else
{
$set('ppPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppPlantError') ? $get('ppPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('block_name') Forms\Components\Select::make('block_name')
->required() ->required()
->nullable() // ->nullable()
->reactive() ->label('Block')
->afterStateUpdated(fn ($set) => $set('shift_id', null)),
Forms\Components\Select::make('shift_id')
->relationship('shift', 'name')
->required()
->nullable()
// ->options(fn (callable $get) =>
// \App\Models\Shift::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id')
// ->toArray() // Convert collection to array
// )
->options(function (callable $get) { ->options(function (callable $get) {
if (!$get('plant_id')) { if (!$get('plant_id')) {
return []; return [];
} }
return \App\Models\Shift::where('plant_id', $get('plant_id')) return \App\Models\Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
->reactive() ->reactive()
->afterStateUpdated(fn ($set) => $set('line_id', null)), //->afterStateUpdated(fn ($set) => $set('shift_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$blockId = $get('block_name');
$set('shift_id', null);
if (!$blockId) {
$set('ppBlockError', 'Please select a block first.');
return;
}
else
{
$set('ppBlockError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppBlockError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppBlockError') ? $get('ppBlockError') : null)
->hintColor('danger'),
Forms\Components\Select::make('shift_id')
->relationship('shift', 'name')
->required()
// ->nullable()
->options(function (callable $get) {
if (!$get('plant_id') || !$get('block_name')) {
return [];
}
return \App\Models\Shift::where('plant_id', $get('plant_id'))
->where('block_id', $get('block_name'))
->pluck('name', 'id')
->toArray();
})
->reactive()
// ->afterStateUpdated(fn ($set) => $set('line_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$shiftId = $get('shift_id');
$set('line_id', null);
if (!$shiftId) {
$set('ppShiftError', 'Please select a shift first.');
return;
}
else
{
$set('ppShiftError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppShiftError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppShiftError') ? $get('ppShiftError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id') Forms\Components\Select::make('line_id')
->relationship('line', 'name') ->relationship('line', 'name')
->required() ->required()
->nullable() // ->nullable()
// ->options(fn (callable $get) => // ->options(fn (callable $get) =>
// \App\Models\Line::where('plant_id', $get('plant_id')) // \App\Models\Line::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id') // ->pluck('name', 'id')
// ->toArray() // Convert collection to array // ->toArray() // Convert collection to array
// ) // )
->options(function (callable $get) { ->options(function (callable $get) {
if (!$get('plant_id')) { if (!$get('plant_id') || !$get('block_name') || !$get('shift_id')) {
return []; return [];
} }
@@ -77,17 +138,54 @@ class ProductionPlanResource extends Resource
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
->reactive(), ->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (!$lineId) {
$set('ppLineError', 'Please select a line first.');
return;
}
else
{
$set('ppLineError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppLineError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppLineError') ? $get('ppLineError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('plan_quantity') Forms\Components\TextInput::make('plan_quantity')
->required() ->required()
->numeric() ->integer()
->minValue(1), ->label('Plan Quantity')
->placeholder('Scan the valid quantity')
->minValue(1)
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$planQuan = $get('plan_quantity');
if (!$planQuan) {
$set('ppPlanQuanError', 'Scan the valid plan quantity.');
return;
}
else
{
$set('ppPlanQuanError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppPlanQuanError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppPlanQuanError') ? $get('ppPlanQuanError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('production_quantity') Forms\Components\TextInput::make('production_quantity')
->required() ->required()
->numeric() ->integer()
->label('Production Quantity')
->readOnly() ->readOnly()
->default(0), ->default(0),
])
->columns(2),
]); ]);
} }

View File

@@ -14,6 +14,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
class ProductionQuantityResource extends Resource class ProductionQuantityResource extends Resource
{ {
@@ -28,48 +29,110 @@ class ProductionQuantityResource extends Resource
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->required() ->required()
->nullable() // ->nullable()
->reactive(), ->reactive()
// ->afterStateUpdated(fn ($set) => $set('block_name', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
$set('block_name', null);
if (!$plantId) {
$set('pqPlantError', 'Please select a plant first.');
return;
}
else
{
$set('validationError', null);
$set('pqPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pqPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pqPlantError') ? $get('pqPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('block_name') Forms\Components\Select::make('block_name')
->required() ->required()
->nullable() // ->nullable()
->reactive()
->afterStateUpdated(fn ($set) => $set('shift_id', null)),
Forms\Components\Select::make('shift_id')
->relationship('shift', 'name')
->required()
->nullable()
// ->options(fn (callable $get) =>
// \App\Models\Shift::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id')
// ->toArray() // Convert collection to array
// )
->options(function (callable $get) { ->options(function (callable $get) {
if (!$get('plant_id')) { if (!$get('plant_id')) {
return []; return [];
} }
return \App\Models\Shift::where('plant_id', $get('plant_id')) return \App\Models\Block::where('plant_id', $get('plant_id'))
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
->reactive() ->reactive()
->afterStateUpdated(fn ($set) => $set('line_id', null)), // ->afterStateUpdated(fn ($set) => $set('shift_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$blockId = $get('block_name');
$set('shift_id', null);
if (!$blockId) {
$set('pqBlockError', 'Please select a block first.');
return;
}
else
{
$set('validationError', null);
$set('pqBlockError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pqBlockError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pqBlockError') ? $get('pqBlockError') : null)
->hintColor('danger'),
Forms\Components\Select::make('shift_id')
->relationship('shift', 'name')
->required()
// ->nullable()
->options(function (callable $get) {
if (!$get('plant_id') || !$get('block_name')) {
return [];
}
return \App\Models\Shift::where('plant_id', $get('plant_id'))
->where('block_id', $get('block_name'))
->pluck('name', 'id')
->toArray();
})
->reactive()
->afterStateUpdated(fn ($set) => $set('line_id', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$shiftId = $get('shift_id');
$set('line_id', null);
if (!$shiftId) {
$set('pqShiftError', 'Please select a shift first.');
return;
}
else
{
$set('validationError', null);
$set('pqShiftError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('pqShiftError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('pqShiftError') ? $get('pqShiftError') : null)
->hintColor('danger'),
Forms\Components\Select::make('line_id') Forms\Components\Select::make('line_id')
->relationship('line', 'name') ->relationship('line', 'name')
->required() ->required()
->nullable() // ->nullable()
// ->options(fn (callable $get) => // ->options(fn (callable $get) =>
// \App\Models\Line::where('plant_id', $get('plant_id')) // \App\Models\Line::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id') // ->pluck('name', 'id')
// ->toArray() // Convert collection to array // ->toArray() // Convert collection to array
// ) // )
->options(function (callable $get) { ->options(function (callable $get) {
if (!$get('plant_id')) { if (!$get('plant_id') || !$get('block_name') || !$get('shift_id')) {
return []; return [];
} }
@@ -77,7 +140,24 @@ class ProductionQuantityResource extends Resource
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
->reactive(), ->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$lineId = $get('line_id');
if (!$lineId) {
$set('ppLineError', 'Please select a line first.');
return;
}
else
{
$set('validationError', null);
$set('ppLineError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('ppLineError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('ppLineError') ? $get('ppLineError') : null)
->hintColor('danger'),
// Forms\Components\Select::make('item_id') // Forms\Components\Select::make('item_id')
// ->label('Item Code') // ->label('Item Code')
// ->relationship('item', 'code') // ->relationship('item', 'code')
@@ -89,44 +169,153 @@ class ProductionQuantityResource extends Resource
// Virtual field for code input (not stored in DB) // Virtual field for code input (not stored in DB)
Forms\Components\TextInput::make('item_code') Forms\Components\TextInput::make('item_code')
->label('Item Code') ->label('Item Code')
->required() // ->required()
->reactive() ->reactive()
->afterStateUpdated(function ($state, callable $get, callable $set) { ->afterStateUpdated(function ($state, callable $get, callable $set) {
// **Check if input is empty before processing**
if (empty($state)) {
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
$set('validationError', null);
return;
}
else
{
if (!$get('plant_id')) {
$set('item_code', null);
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
$set('validationError', 'Please select a plant first.');
return;
}
else if (!$get('block_name')) {
$set('item_code', null);
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
$set('validationError', 'Please select a block first.');
return;
}
else if (!$get('shift_id')) {
$set('item_code', null);
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
$set('validationError', 'Please select a shift first.');
return;
}
else if (!$get('line_id')) {
$set('item_code', null);
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
$set('validationError', 'Please select a line first.');
return;
}
$set('validationError', null);
}
if (!preg_match('/^[a-zA-Z0-9]+\|[a-zA-Z0-9]+(\|)?$/', $state)) {
$set('validationError', 'Scan valid QR code. (Ex: Item_Code|Serial_Number )');
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
return;
}
// Only search when all parent IDs are selected // Only search when all parent IDs are selected
if ($get('plant_id') && $get('line_id')) { $parts = explode('|', $state);
$item = \App\Models\Item::where('code', $state)
$itemCode = trim($parts[0]); // Extract item code // 123456|123456789
$serialNumber = isset($parts[1]) ? trim($parts[1]) : null;
if (strlen($itemCode) < 6) {
$set('validationError', 'Item code must be at least 6 digits.');
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
return;
}
else if (!ctype_alnum($itemCode)) {
$set('validationError', 'Item code should contain alpha-numeric values.');
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
return;
}
else if ($serialNumber === '') {
$set('validationError', 'Waiting for full QR scan...');
$set('item_description', null);
$set('serial_number', null);
return; // Do not clear item_id, just wait for full input
}
else if (strlen($serialNumber) < 9) {
$set('validationError', 'Serial Number must be at least 9 digits.');
$set('item_description', null);
$set('serial_number', null);
return;
}
else if (!ctype_alnum($serialNumber)) {
$set('validationError', 'Serial Number should contain alpha-numeric values.');
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
return;
}
else
{
$set('validationError', null);
}
// Fetch item using item code and plant_id
$item = \App\Models\Item::where('code', $itemCode)
->where('plant_id', $get('plant_id')) ->where('plant_id', $get('plant_id'))
->where('line_id', $get('line_id'))
->first(); ->first();
if ($item) { if ($item)
$set('item_id', $item->id); // Set actual foreign key {
} else { $sNo = ProductionQuantity::where('serial_number', $serialNumber)
$set('item_id', null); // Clear item_id if not found // ->where('plant_id', $get('plant_id'))
->exists();
if (!$sNo)
{
$set('serial_number', $serialNumber);
$set('item_id', $item->id);
$set('item_code', $itemCode); //$itemCode
$set('item_description', $item->description);
} }
else
{
$set('validationError', 'Serial number already exist in database.');
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
return;
}
}
else
{
$set('validationError', 'Item code does not exist in master data.');
$set('item_id', null);
$set('item_description', null);
$set('serial_number', null);
return;
} }
}) })
->rules([ ->extraAttributes(fn ($get) => [
function ($get) { 'class' => $get('validationError') ? 'border-red-500' : '',
return function ($attribute, $value, $fail) use ($get) { ])
// Check if item exists with the given code and foreign keys ->hint(fn ($get) => $get('validationError') ? $get('validationError') : null)
$exists = \App\Models\Item::where('code', $value) ->hintColor('danger'),
->where('plant_id', $get('plant_id'))
->where('line_id', $get('line_id'))
->exists();
if (!$exists) {
// Custom error message
$fail("The item code '{$value}' does not exist for the selected Plant/Block/Line.");
}
};
},
]),
Forms\Components\Hidden::make('item_id') Forms\Components\Hidden::make('item_id')
->required(), ->required(),
Forms\Components\TextInput::make('item_description') Forms\Components\TextInput::make('item_description')
->label('Description') ->label('Description')
->reactive()
->readOnly(true)
->required(), ->required(),
// Forms\Components\Select::make('item_id') // Forms\Components\Select::make('item_id')
// ->label('Description') // ->label('Description')
@@ -134,8 +323,12 @@ class ProductionQuantityResource extends Resource
// ->required(), // ->required(),
Forms\Components\TextInput::make('serial_number') Forms\Components\TextInput::make('serial_number')
->required() ->required()
->unique(ignoreRecord: true)
->readOnly(true)
->autocapitalize('serial_number'), ->autocapitalize('serial_number'),
//->columnSpanFull(), //->columnSpanFull(),
])
->columns(2),
]); ]);
} }

View File

@@ -5,6 +5,7 @@ namespace App\Filament\Resources;
use App\Filament\Resources\QualityValidationResource\Pages; use App\Filament\Resources\QualityValidationResource\Pages;
use App\Filament\Resources\QualityValidationResource\RelationManagers; use App\Filament\Resources\QualityValidationResource\RelationManagers;
use App\Models\QualityValidation; use App\Models\QualityValidation;
use Closure;
use Filament\Forms; use Filament\Forms;
use Filament\Forms\Form; use Filament\Forms\Form;
use Filament\Resources\Resource; use Filament\Resources\Resource;
@@ -20,6 +21,7 @@ class QualityValidationResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack'; protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationGroup = 'Display'; protected static ?string $navigationGroup = 'Display';
public $isSubmitted = false;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
@@ -27,29 +29,445 @@ class QualityValidationResource extends Resource
->schema([ ->schema([
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->reactive()
->afterStateUpdated(fn (callable $set) => [
$set('item_id', null),
$set('validationError', null),
])
->required(), ->required(),
Forms\Components\Select::make('item_id') Forms\Components\Hidden::make('sticker_master_id')
->relationship('item', 'code') // ->relationship('stickerMaster', 'id')
->searchable()
->required(),
Forms\Components\Select::make('stickermaster_id')
->relationship('stickermaster', 'id')
->required(),
Forms\Components\TextInput::make('scan_qr')
->label('Scan QR Code')
->required(), ->required(),
Forms\Components\TextInput::make('production_order') Forms\Components\TextInput::make('production_order')
->required(), ->required(),
Forms\Components\TextInput::make('part_validation1'), Forms\Components\TextInput::make('item_id')
->label('Item Code')
->placeholder('Scan the valid QR code')
->reactive()
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
Forms\Components\TextInput::make('part_validation2'), // Reset visibility of all serial and part validation fields
$serialFields = [
'serial_number_motor', 'serial_number_pump', 'serial_number_pumpset',
'pack_slip_motor', 'pack_slip_pump', 'pack_slip_pumpset',
'name_plate_motor', 'name_plate_pump', 'name_plate_pumpset',
'tube_sticker_motor', 'tube_sticker_pump', 'tube_sticker_pumpset',
'warranty_card'
];
Forms\Components\TextInput::make('part_validation3'), $partValidationColumns = [
'part_validation1', 'part_validation2', 'part_validation3',
'part_validation4', 'part_validation5'
];
Forms\Components\TextInput::make('part_validation4'), foreach ($serialFields as $field) {
$set($field . '_visible', false);
$set($field, null);
}
Forms\Components\TextInput::make('part_validation5'), foreach ($partValidationColumns as $column) {
$set($column . '_visible', false);
$set($column, null);
}
// Proceed with validation logic for new scanned QR code
if (!$state) {
return;
}
if (strpos($state, '|') === false)
{
return;
}
$parts = explode('|', $state);
$itemCode = trim($parts[0]); // Extract item code // 123456|123456789
$serialNumber = trim($parts[1]);
if (strlen($itemCode) < 6) {
$set('validationError', 'Item code must be at least 6 digits.');
$set('item_id', null);
return;
}
else if (!ctype_alnum($itemCode)) {
$set('validationError', 'Item Code should contain alpha-numeric values.');
$set('item_id', null);
return;
}
else if ($serialNumber === '') {
$set('validationError', 'Waiting for full QR scan...');
return; // Do not clear item_id, just wait for full input
}
else if (strlen($serialNumber) < 9) {
$set('validationError', 'Serial Number must be at least 9 digits.');
return;
}
else if (!ctype_alnum($serialNumber)) {
$set('validationError', 'Serial Number should contain alpha-numeric values.');
$set('item_id', null);
return;
}
else
{
$set('validationError', null);
}
if (!preg_match('/^[a-zA-Z0-9]+\|[a-zA-Z0-9]+(\|)?$/', $state)) {
$set('validationError', 'Invalid QR code format. Expected: Item_Code|Serial_Number.');
return;
}
//$set('validationError', null);
$plantId = $get('plant_id'); // Get selected plant
if (!$plantId) {
$set('validationError', 'Please select a plant first.');
$set('item_id', null);
$set('sticker_master_id', null);
return;
}
// Check if the item exists for the selected plant
$stickerMaster = \App\Models\StickerMaster::where('plant_id', $plantId)
->whereHas('item', function ($query) use ($itemCode) {
$query->where('code', $itemCode);
})->first();
if (!$stickerMaster) {
$set('validationError', 'Scanned item code does not exist for the selected plant.');
$set('sticker_master_id', null);
return;
}
else
{
$set('sticker_master_id', $stickerMaster->id);
$set('item_id', $itemCode);
}
// Check if user input matches the database values
foreach ($partValidationColumns as $field) {
if ($get("{$field}_visible")) { // Only validate visible fields
$userInput = $get($field); // Get user input
$expectedValue = $stickerMaster->$field; // Get expected value from DB
if ($userInput !== null && $userInput !== $expectedValue) {
$set('validationError', "Invalid input for $field. Expected: $expectedValue");
return; // Stop execution if any validation fails
}
}
}
// Clear validation error if all inputs match
$set('validationError', null);
// Filter columns with value `1`
$visibleColumns = [];
foreach ($serialFields as $column) {
if ($stickerMaster->$column === 1) {
$visibleColumns[] = $column;
}
}
// Filter part validation columns that are not `null`
$visiblePartValidations = [];
foreach ($partValidationColumns as $column) {
if ($stickerMaster->$column !== null) {
$visiblePartValidations[] = $column;
}
}
foreach ($serialFields as $column) {
if ($stickerMaster->$column == 1) {
$set($column . '_visible', true);
} else {
$set($column . '_visible', false);
}
}
foreach ($partValidationColumns as $column) {
if ($stickerMaster->$column !== null) {
$set($column . '_visible', true); // Separate key for visibility
} else {
$set($column . '_visible', false);
}
}
// Assign serial number to only visible text inputs
foreach ($serialFields as $field) {
if ($get("{$field}_visible")) {
$set($field, $serialNumber);
}
}
})
->extraAttributes(fn ($get) => [
'class' => $get('validationError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('validationError') ? $get('validationError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('serial_number_motor')
->hidden(fn (callable $get) => !$get('serial_number_motor_visible')) // Controls visibility
->default(''), // Keeps input empty
Forms\Components\TextInput::make('serial_number_pump')
->hidden(fn (callable $get) => !$get('serial_number_pump_visible'))
->default(''),
Forms\Components\TextInput::make('serial_number_pumpset')
->hidden(fn (callable $get) => !$get('serial_number_pumpset_visible'))
->default(''),
Forms\Components\TextInput::make('pack_slip_motor')
->hidden(fn (callable $get) => !$get('pack_slip_motor_visible'))
->default(''),
Forms\Components\TextInput::make('pack_slip_pump')
->hidden(fn (callable $get) => !$get('pack_slip_pump_visible'))
->default(''),
Forms\Components\TextInput::make('pack_slip_pumpset')
->hidden(fn (callable $get) => !$get('pack_slip_pumpset_visible'))
->default(''),
Forms\Components\TextInput::make('name_plate_motor')
->hidden(fn (callable $get) => !$get('name_plate_motor_visible'))
->default(''),
Forms\Components\TextInput::make('name_plate_pump')
->hidden(fn (callable $get) => !$get('name_plate_pump_visible'))
->default(''),
Forms\Components\TextInput::make('name_plate_pumpset')
->hidden(fn (callable $get) => !$get('name_plate_pumpset_visible'))
->default(''),
Forms\Components\TextInput::make('tube_sticker_motor')
->hidden(fn (callable $get) => !$get('tube_sticker_motor_visible'))
->default(''),
Forms\Components\TextInput::make('tube_sticker_pump')
->hidden(fn (callable $get) => !$get('tube_sticker_pump_visible'))
->default(''),
Forms\Components\TextInput::make('tube_sticker_pumpset')
->hidden(fn (callable $get) => !$get('tube_sticker_pumpset_visible'))
->default(''),
Forms\Components\TextInput::make('warranty_card')
->hidden(fn (callable $get) => !$get('warranty_card_visible'))
->default(''),
Forms\Components\TextInput::make('part_validation1')
->hidden(fn (callable $get) => !$get('part_validation1_visible'))
->default('')
->reactive()
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$stickerMasterId = $get('sticker_master_id');
if (!$stickerMasterId) {
return;
}
$stickerMaster = \App\Models\StickerMaster::find($stickerMasterId);
if (!$stickerMaster) {
return;
}
$expectedValue = $stickerMaster->part_validation1;
// If input is empty, reset the error
if ($state === null || trim($state) === '') {
$set('part_validation1_error', null);
return;
}
if ($state === $expectedValue)
{
$set('part_validation1_error', null);
}
else
{
$set('part_validation1_error', "Invalid input for part validation 1."); // Expected: $expectedValue
}
})
->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')
->hidden(fn (callable $get) => !$get('part_validation2_visible'))
->default('')
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$stickerMasterId = $get('sticker_master_id');
if (!$stickerMasterId) {
return;
}
$stickerMaster = \App\Models\StickerMaster::find($stickerMasterId);
if (!$stickerMaster) {
return;
}
$expectedValue = $stickerMaster->part_validation2;
// If input is empty, reset the error
if ($state === null || trim($state) === '') {
$set('part_validation2_error', null);
return;
}
// If input is empty, do not show an error
if ($state === $expectedValue)
{
$set('part_validation2_error', null);
}
else
{
$set('part_validation2_error', "Invalid input for part validation 2."); // Expected: $expectedValue
}
})
->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')
->hidden(fn (callable $get) => !$get('part_validation3_visible'))
->default('')
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$stickerMasterId = $get('sticker_master_id');
if (!$stickerMasterId) {
return;
}
$stickerMaster = \App\Models\StickerMaster::find($stickerMasterId);
if (!$stickerMaster) {
return;
}
$expectedValue = $stickerMaster->part_validation3;
// If input is empty, reset the error
if ($state === null || trim($state) === '') {
$set('part_validation3_error', null);
return;
}
// If input is empty, do not show an error
if ($state === $expectedValue)
{
$set('part_validation3_error', null);
}
else
{
$set('part_validation3_error', "Invalid input for part validation 3."); // Expected: $expectedValue
}
})
->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')
->hidden(fn (callable $get) => !$get('part_validation4_visible'))
->default('')
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$stickerMasterId = $get('sticker_master_id');
if (!$stickerMasterId) {
return;
}
$stickerMaster = \App\Models\StickerMaster::find($stickerMasterId);
if (!$stickerMaster) {
return;
}
$expectedValue = $stickerMaster->part_validation4;
// If input is empty, reset the error
if ($state === null || trim($state) === '') {
$set('part_validation4_error', null);
return;
}
// If input is empty, do not show an error
if ($state === $expectedValue)
{
$set('part_validation4_error', null);
}
else
{
$set('part_validation4_error', "Invalid input for part validation 4."); // Expected: $expectedValue
}
})
->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')
->hidden(fn (callable $get) => !$get('part_validation5_visible'))
->default('')
->required()
->afterStateUpdated(function (callable $set, callable $get, ?string $state) {
$stickerMasterId = $get('sticker_master_id');
if (!$stickerMasterId) {
return;
}
$stickerMaster = \App\Models\StickerMaster::find($stickerMasterId);
if (!$stickerMaster) {
return;
}
$expectedValue = $stickerMaster->part_validation4;
// If input is empty, reset the error
if ($state === null || trim($state) === '') {
$set('part_validation5_error', null);
return;
}
// If input is empty, do not show an error
if ($state === $expectedValue)
{
$set('part_validation5_error', null);
}
else
{
$set('part_validation5_error', "Invalid input for part validation 5."); // Expected: $expectedValue
}
})
->extraAttributes(fn ($get) => [
'class' => $get('part_validation5_error') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('part_validation5_error'))
->hintColor('danger'),
]); ]);
} }
@@ -61,13 +479,10 @@ class QualityValidationResource extends Resource
->label('ID') ->label('ID')
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('item.id')
->numeric()
->sortable(),
Tables\Columns\TextColumn::make('plant.name') Tables\Columns\TextColumn::make('plant.name')
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('stickermaster.id') Tables\Columns\TextColumn::make('stickerMaster.id')
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('created_at') Tables\Columns\TextColumn::make('created_at')

View File

@@ -14,6 +14,7 @@ use Filament\Tables\Actions\ImportAction;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope; use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Forms\Components\Section;
class ShiftResource extends Resource class ShiftResource extends Resource
{ {
@@ -23,20 +24,43 @@ class ShiftResource extends Resource
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 4;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
->schema([
Section::make('')
->schema([ ->schema([
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->required() ->required()
->nullable() // ->nullable()
->reactive() ->reactive()
->afterStateUpdated(fn ($set) => $set('block_id', null)), // Reset block_id when plant changes // ->afterStateUpdated(fn ($set) => $set('block_id', null) & $set('name', null) & $set('start_time', null) & $set('duration', null) & $set('end_time', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id');
$set('block_id', null);
// Ensure `linestop_id` is not cleared
if (!$plantId) {
$set('sPlantError', 'Please select a plant first.');
return;
}
else
{
$set('sPlantError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('sPlantError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('sPlantError') ? $get('sPlantError') : null)
->hintColor('danger'),
Forms\Components\Select::make('block_id') Forms\Components\Select::make('block_id')
->relationship('block', 'name') ->relationship('block', 'name')
->required() ->required()
->nullable() // ->nullable()
->reactive()
// ->options(fn (callable $get) => // ->options(fn (callable $get) =>
// \App\Models\Block::where('plant_id', $get('plant_id')) // \App\Models\Block::where('plant_id', $get('plant_id'))
// ->pluck('name', 'id') // ->pluck('name', 'id')
@@ -51,28 +75,130 @@ class ShiftResource extends Resource
->pluck('name', 'id') ->pluck('name', 'id')
->toArray(); ->toArray();
}) })
->reactive(), // ->afterStateUpdated(fn ($set) => $set('name', null))
->afterStateUpdated(function ($state, callable $set, callable $get) {
$blockId = $get('block_id');
$set('name', null);
// Ensure `linestop_id` is not cleared
if (!$blockId) {
$set('sBlockError', 'Please select a block first.');
return;
}
else
{
$set('sBlockError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('sBlockError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('sBlockError') ? $get('sBlockError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('name') Forms\Components\TextInput::make('name')
->required(), ->placeholder('Scan the valid name')
->required()
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('name');
$set('start_time', null);
// Ensure `linestop_id` is not cleared
if (!$nameId) {
$set('sNameError', 'Scan the valid name.');
return;
}
else
{
$set('sNameError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('sNameError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('sNameError') ? $get('sNameError') : null)
->hintColor('danger'),
Forms\Components\TimePicker::make('start_time') Forms\Components\TimePicker::make('start_time')
->required() ->required()
->label('Start Time')
->live() ->live()
->afterStateUpdated(fn (callable $set, callable $get, $state) => // ->afterStateUpdated(fn (callable $set, callable $get, $state) =>
$set('end_time', self::calculateEndTime($state, $get('duration'))) // $set('end_time', self::calculateEndTime($state, $get('duration')))
), // )
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$nameId = $get('start_time');
// $set('duration', null);
$set('end_time', self::calculateEndTime($state, $get('duration')));
// Ensure `linestop_id` is not cleared
if (!$nameId) {
$set('sStartTimeError', 'Choose the valid start time.');
return;
}
else
{
$set('sStartTimeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('sStartTimeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('sStartTimeError') ? $get('sStartTimeError') : null)
->hintColor('danger'),
Forms\Components\TextInput::make('duration') Forms\Components\TextInput::make('duration')
->required() ->required()
->placeholder('Scan the valid duration')
->numeric()
->inputMode('decimal') ->inputMode('decimal')
->minValue(0.01) // Minimum valid duration ->minValue(0.01) // Minimum valid duration
->lazy() ->lazy()
->afterStateUpdated(fn (callable $set, callable $get, $state) => // ->afterStateUpdated(fn (callable $set, callable $get, $state) =>
$set('end_time', self::calculateEndTime($get('start_time'), $state)) // $set('end_time', self::calculateEndTime($get('start_time'), $state))
), // )
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$duration = $get('duration');
// $set('end_time', null);
$set('end_time', self::calculateEndTime($get('start_time'), $state));
// Ensure `linestop_id` is not cleared
if (!$duration) {
$set('sDurationError', 'Scan the valid duration.');
return;
}
else
{
$set('sDurationError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('sDurationError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('sDurationError') ? $get('sDurationError') : null)
->hintColor('danger'),
Forms\Components\TimePicker::make('end_time') Forms\Components\TimePicker::make('end_time')
->required(), ->required()
->label('End Time')
->readOnly()
// ->native(false), // ->native(false),
->reactive()
->afterStateUpdated(function ($state, callable $set, callable $get) {
$endTime = $get('end_time');
$set('end_time', self::calculateEndTime($get('start_time'), $state));
// Ensure `linestop_id` is not cleared
if (!$endTime) {
$set('sEndTimeError', 'Choose the valid start time & duration.');
return;
}
else
{
$set('sEndTimeError', null);
}
})
->extraAttributes(fn ($get) => [
'class' => $get('sEndTimeError') ? 'border-red-500' : '',
])
->hint(fn ($get) => $get('sEndTimeError') ? $get('sEndTimeError') : null)
->hintColor('danger'),
])
->columns(2),
]); ]);

View File

@@ -21,6 +21,8 @@ class StickerMasterResource extends Resource
protected static ?string $navigationGroup = 'Master Entries'; protected static ?string $navigationGroup = 'Master Entries';
protected static ?int $navigationSort = 8;
public static function form(Form $form): Form public static function form(Form $form): Form
{ {
return $form return $form
@@ -28,17 +30,27 @@ class StickerMasterResource extends Resource
Forms\Components\Select::make('plant_id') Forms\Components\Select::make('plant_id')
->relationship('plant', 'name') ->relationship('plant', 'name')
->reactive() ->reactive()
->afterStateUpdated(fn (callable $set) => $set('item_id', null)) ->nullable()
->afterStateUpdated(fn (callable $set) =>
$set('item_id', null) & $set('item_description', null)
)
->required(), ->required(),
Forms\Components\Select::make('item_id') Forms\Components\Select::make('item_id')
->label('Item Code') ->label('Item Code')
->options(fn (callable $get) => ->options(function (callable $get) {
\App\Models\Item::where('plant_id', $get('plant_id')) if (!$get('plant_id')) {
return [];
}
return \App\Models\Item::where('plant_id', $get('plant_id'))
->pluck('code', 'id') ->pluck('code', 'id')
) ->toArray();
})
->required() ->required()
->nullable()
->searchable() ->searchable()
->reactive()
->live(debounce: 500) // Enable live updates ->live(debounce: 500) // Enable live updates
->afterStateUpdated(function ($state, callable $set, callable $get) { ->afterStateUpdated(function ($state, callable $set, callable $get) {
$plantId = $get('plant_id'); // Get selected plant_id $plantId = $get('plant_id'); // Get selected plant_id
@@ -180,11 +192,9 @@ class StickerMasterResource extends Resource
->label('ID') ->label('ID')
->numeric() ->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('item.id') Tables\Columns\TextColumn::make('item.code')
->numeric()
->sortable(), ->sortable(),
Tables\Columns\TextColumn::make('plant.name') Tables\Columns\TextColumn::make('plant.name')
->numeric()
->sortable(), ->sortable(),
Tables\Columns\CheckboxColumn::make('serial_number_motor') Tables\Columns\CheckboxColumn::make('serial_number_motor')
->disabled(true) ->disabled(true)

View File

@@ -11,9 +11,9 @@ class QualityValidation extends Model
use SoftDeletes; use SoftDeletes;
protected $fillable = [ protected $fillable = [
'item_id', 'sticker_master_id',
'plant_id', 'plant_id',
'stickermaster_id ', 'production_order',
'serial_number_motor', 'serial_number_motor',
'serial_number_pump', 'serial_number_pump',
'serial_number_pumpset', 'serial_number_pumpset',
@@ -34,18 +34,13 @@ class QualityValidation extends Model
'part_validation5', 'part_validation5',
]; ];
public function item(): BelongsTo public function stickerMaster(): BelongsTo
{ {
return $this->belongsTo(Item::class); return $this->belongsTo(StickerMaster::class);
} }
public function plant(): BelongsTo public function plant(): BelongsTo
{ {
return $this->belongsTo(Plant::class); return $this->belongsTo(Plant::class);
} }
public function stickermaster(): BelongsTo
{
return $this->belongsTo(StickerMaster::class);
}
} }

View File

@@ -7,6 +7,7 @@ use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\AuthenticateSession; use Filament\Http\Middleware\AuthenticateSession;
use Filament\Http\Middleware\DisableBladeIconComponents; use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent; use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Navigation\MenuItem;
use Filament\Navigation\NavigationGroup; use Filament\Navigation\NavigationGroup;
use Filament\Pages; use Filament\Pages;
use Filament\Panel; use Filament\Panel;
@@ -39,6 +40,7 @@ class AdminPanelProvider extends PanelProvider
->pages([ ->pages([
]) ])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets') ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
// ->widgets([ // ->widgets([
// Widgets\AccountWidget::class, // Widgets\AccountWidget::class,

View File

@@ -15,9 +15,8 @@ return new class extends Migration
CREATE TABLE quality_validations ( CREATE TABLE quality_validations (
id BIGINT GENERATED always AS IDENTITY PRIMARY KEY, id BIGINT GENERATED always AS IDENTITY PRIMARY KEY,
item_id BIGINT NOT NULL,
plant_id BIGINT NOT NULL, plant_id BIGINT NOT NULL,
stickermaster_id BIGINT NOT NULL, sticker_master_id BIGINT NOT NULL,
production_order TEXT NOT NULL, production_order TEXT NOT NULL,
@@ -48,13 +47,13 @@ return new class extends Migration
updated_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMP, deleted_at TIMESTAMP,
FOREIGN KEY (item_id) REFERENCES items (id),
FOREIGN KEY (plant_id) REFERENCES plants (id), FOREIGN KEY (plant_id) REFERENCES plants (id),
FOREIGN KEY (stickerMaster_id) REFERENCES sticker_masters (id) FOREIGN KEY (sticker_master_id) REFERENCES sticker_masters (id)
); );
SQL; SQL;
DB::statement($sql); DB::statement($sql);
} }
/** /**