From d4192d300275a110c0e24710701c64fefce9b400 Mon Sep 17 00:00:00 2001 From: dhanabalan Date: Sun, 21 Sep 2025 15:21:37 +0530 Subject: [PATCH] Add resource file for Equipment Masters --- .../Resources/EquipmentMasterResource.php | 505 ++++++++++++++++++ .../Pages/CreateEquipmentMaster.php | 17 + .../Pages/EditEquipmentMaster.php | 22 + .../Pages/ListEquipmentMasters.php | 19 + .../Pages/ViewEquipmentMaster.php | 19 + 5 files changed, 582 insertions(+) create mode 100644 app/Filament/Resources/EquipmentMasterResource.php create mode 100644 app/Filament/Resources/EquipmentMasterResource/Pages/CreateEquipmentMaster.php create mode 100644 app/Filament/Resources/EquipmentMasterResource/Pages/EditEquipmentMaster.php create mode 100644 app/Filament/Resources/EquipmentMasterResource/Pages/ListEquipmentMasters.php create mode 100644 app/Filament/Resources/EquipmentMasterResource/Pages/ViewEquipmentMaster.php diff --git a/app/Filament/Resources/EquipmentMasterResource.php b/app/Filament/Resources/EquipmentMasterResource.php new file mode 100644 index 0000000..d73c284 --- /dev/null +++ b/app/Filament/Resources/EquipmentMasterResource.php @@ -0,0 +1,505 @@ +schema([ + Forms\Components\Select::make('plant_id') + ->label('Plant') + ->reactive() + ->relationship('plant', 'name') + ->required(), + Forms\Components\Select::make('machine_id') + //->relationship('machine', 'name') + ->label('Work Center') + ->reactive() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + if (empty($plantId)) { + return []; + } + return \App\Models\Machine::where('plant_id', $plantId)->pluck('work_center', 'id'); + }) + ->required(), + Forms\Components\TextInput::make('name') + ->label('Name'), + Forms\Components\TextInput::make('description') + ->label('Description'), + Forms\Components\TextInput::make('make') + ->label('Make'), + Forms\Components\TextInput::make('model') + ->label('Model'), + Forms\Components\TextInput::make('equipment_number') + ->label('Equipment Number') + ->reactive() + ->rules(function (callable $get) { + return [ + Rule::unique('equipment_masters', 'equipment_number') + ->where(function ($query) use ($get) { + return $query->where('plant_id', $get('plant_id')); + }) + ->ignore($get('id')), + ]; + }) + ->afterStateUpdated(function ($state, callable $set) { + if (! $state) { + return; + } + + $model = EquipmentMaster::where('equipment_number', $state)->first(); + + if ($model?->attachment) { + $set('attachment', $model->attachment); + } else { + $set('attachment', null); + } + }), + //->afterStateUpdated(function ($state, callable $set) { + // if (! $state) { + // return; + // } + + // $model = EquipmentMaster::where('equipment_number', $state)->first(); + + // if ($model?->attachment) { + // $set('attachment', $model->attachment); + // } else { + // $set('attachment', null); + // } + // }), + Forms\Components\TextInput::make('instrument_serial_number') + ->label('Instrument Serial Number'), + // Forms\Components\DateTimePicker::make('calibrated_on') + // ->label('Calibrated On') + // ->required(), + // Forms\Components\TextInput::make('frequency') + // ->label('Frequency') + // ->required() + // ->numeric() + // ->default(1), + // Forms\Components\DateTimePicker::make('next_calibration_date') + // ->label('Next Calibration Date') + // ->required(), + Forms\Components\DateTimePicker::make('calibrated_on') + ->label('Calibrated On') + ->required() + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $frequency = $get('frequency') ?? '1'; + $nextDate = self::calculateNextCalibrationDate($state, $frequency); + $set('next_calibration_date', $nextDate); + }), + // ->afterStateUpdated(function ($state, callable $get, callable $set) { + // $frequency = (int) $get('frequency'); + + // if ($state && $frequency != 0) { + // $calibratedOn = $state instanceof Carbon ? $state : Carbon::parse($state); + // $nextDate = $calibratedOn->copy()->addDays($frequency); + // $set('next_calibration_date', $nextDate); + // } else { + // $set('next_calibration_date', null); + // } + // }), + + Forms\Components\TextInput::make('frequency') + ->label('Frequency (days)') + ->required() + ->numeric() + ->minValue(1) + ->default(1) + ->reactive() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $calibratedOn = $get('calibrated_on'); + $nextDate = self::calculateNextCalibrationDate($calibratedOn, $state); + $set('next_calibration_date', $nextDate); + }), + // ->afterStateUpdated(function ($state, callable $get, callable $set) { + // $calibratedOn = $get('calibrated_on'); + // $frequency = (int) $state; + + // if ($calibratedOn && $frequency !== 0) { + // $calibratedOn = $calibratedOn instanceof Carbon ? $calibratedOn : Carbon::parse($calibratedOn); + // $nextDate = $calibratedOn->copy()->addDays($frequency); + // $set('next_calibration_date', $nextDate); + // } + // else + // { + // $set('next_calibration_date', null); + // } + // }), + + Forms\Components\DateTimePicker::make('next_calibration_date') + ->label('Next Calibration Date') + ->readOnly() + ->required(), + + Forms\Components\TextInput::make('calibrated_by') + ->label('Calibrated By'), + Forms\Components\Textarea::make('calibration_certificate') + ->label('Calibration Certificate'), + + Forms\Components\FileUpload::make('attachment') + ->label('PDF Upload') + ->acceptedFileTypes(['application/pdf']) + ->storeFiles(false) + ->disk('local') + ->directory('uploads/temp') + ->preserveFilenames() + ->reactive(), + + // Forms\Components\Actions::make([ + // Action::make('uploadNow') + // ->label('Upload PDF Now') + // ->action(function ($get, callable $set) { + + // $uploadedFiles = $get('attachment'); + + // if (is_array($uploadedFiles) && count($uploadedFiles) > 0) { + // $uploaded = reset($uploadedFiles); + + // if ($uploaded instanceof TemporaryUploadedFile) { + // $originalName = $uploaded->getClientOriginalName(); + // $storedPath = $uploaded->storeAs( + // 'uploads/temp', + // $originalName, + // 'local' + // ); + + // } + // } + + // }), + // ]), + // Forms\Components\Actions::make([ + // Action::make('downloadAttachment') + // ->label('Download PDF') + // ->action(function ($get) { + // $uploadedFiles = $get('attachment'); + + // $equipmentNumber = $get('equipment_number'); + + // if (!$equipmentNumber) { + // Notification::make() + // ->title('No equipment number entered') + // ->danger() + // ->send(); + // return; + // } + + // $files = Storage::disk('local')->files('uploads/temp'); + + // $fileToDownload = null; + + // foreach ($files as $file) { + // if (str_contains($file, $equipmentNumber)) { + // $fileToDownload = $file; + // break; + // } + // } + + // if (!$fileToDownload) { + // Notification::make() + // ->title('PDF not found for this equipment') + // ->danger() + // ->send(); + // return; + // } + + // return response()->download(Storage::disk('local')->path($fileToDownload)); + // }), + // ]), + Forms\Components\Actions::make([ + Action::make('uploadNow') + ->label('Upload PDF Now') + // ->action(function ($get, callable $set) { + // $uploadedFiles = $get('attachment'); + + // if (is_array($uploadedFiles) && count($uploadedFiles) > 0) { + // $uploaded = reset($uploadedFiles); + + // if ($uploaded instanceof TemporaryUploadedFile) { + // $originalName = $uploaded->getClientOriginalName(); + // $storedPath = $uploaded->storeAs( + // 'uploads/temp', + // $originalName, + // 'local' + // ); + // } + // } + // }), + ->action(function ($get, callable $set) { + $uploadedFiles = $get('attachment'); + + if (is_array($uploadedFiles) && count($uploadedFiles) > 0) { + $uploaded = reset($uploadedFiles); + + if ($uploaded instanceof TemporaryUploadedFile) { + $originalName = $uploaded->getClientOriginalName(); + + $storedPath = $uploaded->storeAs( + 'uploads/temp', + $originalName, + 'local' + ); + + Notification::make() + ->title('PDF uploaded successfully') + ->success() + ->send(); + return; + } + } + else + { + Notification::make() + ->title('No file selected to upload') + ->warning() + ->send(); + return; + } + }), + + Action::make('downloadAttachment') + ->label('Download PDF') + ->action(function ($get) { + $equipmentNumber = $get('equipment_number'); + + if (!$equipmentNumber) { + Notification::make() + ->title('No equipment number entered') + ->danger() + ->send(); + return; + } + + $files = Storage::disk('local')->files('uploads/temp'); + + $fileToDownload = null; + foreach ($files as $file) { + if (str_contains($file, $equipmentNumber)) { + $fileToDownload = $file; + break; + } + } + + if (!$fileToDownload) { + Notification::make() + ->title('PDF not found for this equipment') + ->danger() + ->send(); + return; + } + + return response()->download(Storage::disk('local')->path($fileToDownload)); + }), + ]) + ->columns(2), + + Forms\Components\Hidden::make('created_by') + ->label('Created By') + ->default(Filament::auth()->user()?->name), + Forms\Components\Hidden::make('updated_by') + ->label('Updated By'), + ]); + } + + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('No.') + ->label('No.') + ->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() + ->sortable(), + Tables\Columns\TextColumn::make('machine.work_center') + ->label('Work Center') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('name') + ->label('Name') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('description') + ->label('Description') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('make') + ->label('Make') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('model') + ->label('Model') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('equipment_number') + ->label('Equipment Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('instrument_serial_number') + ->label('Instrument Serial Number') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('calibrated_on') + ->label('Calibrated On') + ->alignCenter() + ->dateTime() + ->sortable(), + Tables\Columns\TextColumn::make('frequency') + ->label('Frequency') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('next_calibration_date') + ->label('Next Calibration Date') + ->alignCenter() + ->dateTime() + ->sortable(), + Tables\Columns\TextColumn::make('calibrated_by') + ->label('Calibrated By') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('calibration_certificate') + ->label('Calibration Certificate') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('created_by') + ->label('Created Bys') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('updated_by') + ->label('Updated By') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('created_at') + ->label('Created At') + ->dateTime() + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_at') + ->label('Updated At') + ->dateTime() + ->alignCenter() + ->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(), + ]), + ]) + ->headerActions([ + ImportAction::make() + ->importer(EquipmentMasterImporter::class) + ->visible(function() { + return Filament::auth()->user()->can('view import equipment master'); + }), + ExportAction::make() + ->exporter(EquipmentMasterExporter::class) + ->visible(function() { + return Filament::auth()->user()->can('view export equipment master'); + }), + ]); + } + + public static function getRelations(): array + { + return [ + // + ]; + } + + public static function getPages(): array + { + return [ + 'index' => Pages\ListEquipmentMasters::route('/'), + 'create' => Pages\CreateEquipmentMaster::route('/create'), + 'view' => Pages\ViewEquipmentMaster::route('/{record}'), + 'edit' => Pages\EditEquipmentMaster::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } + + protected static function calculateNextCalibrationDate(?string $startDateTime, ?string $durationDays): ?string + { + if (!$startDateTime || !$durationDays) { + return null; + } + + try + { + $startDateTimeCarbon = Carbon::parse($startDateTime); + $durationDays = str_replace(',', '.', $durationDays); + + if(!is_numeric($durationDays)) + { + return null; + } + + $nextCalibrationDate = $startDateTimeCarbon->addDays(floatval($durationDays)); + return $nextCalibrationDate->format('Y-m-d H:i:s'); + } + catch (\Exception $e) + { + return null; + } + } +} diff --git a/app/Filament/Resources/EquipmentMasterResource/Pages/CreateEquipmentMaster.php b/app/Filament/Resources/EquipmentMasterResource/Pages/CreateEquipmentMaster.php new file mode 100644 index 0000000..964877b --- /dev/null +++ b/app/Filament/Resources/EquipmentMasterResource/Pages/CreateEquipmentMaster.php @@ -0,0 +1,17 @@ +getResource()::getUrl('create'); + } +} diff --git a/app/Filament/Resources/EquipmentMasterResource/Pages/EditEquipmentMaster.php b/app/Filament/Resources/EquipmentMasterResource/Pages/EditEquipmentMaster.php new file mode 100644 index 0000000..5a5d943 --- /dev/null +++ b/app/Filament/Resources/EquipmentMasterResource/Pages/EditEquipmentMaster.php @@ -0,0 +1,22 @@ +