diff --git a/app/Filament/Resources/ProcessOrderResource.php b/app/Filament/Resources/ProcessOrderResource.php new file mode 100644 index 0000000..3052c87 --- /dev/null +++ b/app/Filament/Resources/ProcessOrderResource.php @@ -0,0 +1,360 @@ +schema([ + Forms\Components\Select::make('plant_id') + ->label('Plant') + ->reactive() + ->relationship('plant', 'name') + ->required(), + Forms\Components\Select::make('item_id') + ->label('Item Code') + // ->relationship('item', 'id') + // ->required(), + ->reactive() + ->searchable() + ->options(function (callable $get) { + $plantId = $get('plant_id'); + if (empty($plantId)) { + return []; + } + return \App\Models\Item::where('plant_id', $plantId)->pluck('code', 'id'); + }) + ->afterStateUpdated(function (callable $set, callable $get, ?string $state) { + $plantId = $get('plant_id'); + $itemId = $get('item_id'); + // dd($plantId); + + if ($plantId && $itemId) { + // Get the item code using item_id + $itemCode = \App\Models\Item::where('id', $itemId)->value('code'); + + if ($itemCode) { + // Now get the item description using plant_id + code + $item = \App\Models\Item::where('plant_id', $plantId) + ->where('code', $itemCode) + ->first(); + + $set('item_description', $item?->description); + } else { + $set('item_description', null); + } + } else { + $set('item_description', null); + } + }) + ->required(), + Forms\Components\TextInput::make('item_description') + ->label('Description') + ->required() + ->reactive() + ->readOnly(true), + Forms\Components\TextInput::make('process_order') + ->label('Process Order') + ->required(), + 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(); + $path = 'uploads/ProcessOrder/' . $originalName; + + // Check if file already exists + if (Storage::disk('local')->exists($path)) { + Notification::make() + ->title('Duplicate File') + ->body("The file '{$originalName}' already exists in uploads/temp.") + ->warning() + ->send(); + return; // Stop here + } + + $storedPath = $uploaded->storeAs( + 'uploads/ProcessOrder', + $originalName, + 'local' + ); + + // $fullPath = storage_path('app/' . $storedPath); + $fullPath = storage_path('app/' . $storedPath); + + // Parse PDF using smalot/pdfparser + $parser = new Parser(); + $pdf = $parser->parseContent(file_get_contents($uploaded->getRealPath())); + $text = $pdf->getText(); + + + // if (preg_match('/Batch ID:\s*(\d+)\s*--/i', $text, $matches)) + // { + // $batchId = $matches[1]; + // } + if (preg_match('/Batch ID:\s*(\d+)(?:\s*--)?/i', $text, $matches)) { + $batchId = $matches[1]; + } + else + { + $batchId = null; + } + + // Get the value of process_order field + $processOrder = $get('process_order'); + + if ($batchId != $processOrder) { + Notification::make() + ->title('Mismatch') + ->body("Batch ID ($batchId) does not match Process Order ($processOrder)") + ->danger() + ->send(); + return; + } + + if ($batchId == $processOrder) + { + // If batch matches, store the PDF permanently + $storedPath = $uploaded->storeAs( + 'uploads/ProcessOrder', + $originalName, + 'local' + ); + + Notification::make() + ->title('Success') + ->body("Batch ID matches Process Order: $batchId. 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('process_order'); + + if (!$equipmentNumber) { + Notification::make() + ->title('No process order entered') + ->danger() + ->send(); + return; + } + + $files = Storage::disk('local')->files('uploads/ProcessOrder'); + + $fileToDownload = null; + foreach ($files as $file) { + if (str_contains($file, $equipmentNumber)) { + $fileToDownload = $file; + break; + } + } + + if (!$fileToDownload) { + Notification::make() + ->title('PDF not found for this process order') + ->danger() + ->send(); + return; + } + + return response()->download(Storage::disk('local')->path($fileToDownload)); + }), + + // Action::make('removeAttachment') + // ->label('Remove PDF') + // ->action(function ($get) { + // $equipmentNumber = $get('process_order'); + + // if (!$equipmentNumber) { + // Notification::make() + // ->title('No process order entered') + // ->danger() + // ->send(); + // return; + // } + + // // Get all files from uploads/temp + // $files = Storage::disk('local')->files('uploads/ProcessOrder'); + + // $fileToDelete = null; + // foreach ($files as $file) { + // if (str_contains($file, $equipmentNumber)) { + // $fileToDelete = $file; + // break; + // } + // } + + // if (!$fileToDelete) { + // Notification::make() + // ->title('PDF not found for this process order') + // ->danger() + // ->send(); + // return; + // } + + // // Delete the matched file + // Storage::disk('local')->delete($fileToDelete); + + // Notification::make() + // ->title('PDF removed successfully') + // ->body("File for process order {$equipmentNumber} has been deleted.") + // ->success() + // ->send(); + // }), + ]), + + Forms\Components\Hidden::make('created_by') + ->label('Created By') + ->default(Filament::auth()->user()?->name), + Forms\Components\Hidden::make('updated_by') + ->default(Filament::auth()->user()?->name), + ]); + } + + 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('item.code') + ->label('Item') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('item.description') + ->label('Description') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('created_at') + ->label('Created At') + ->alignCenter() + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + 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') + ->label('Deleted At') + ->alignCenter() + ->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\ListProcessOrders::route('/'), + 'create' => Pages\CreateProcessOrder::route('/create'), + 'view' => Pages\ViewProcessOrder::route('/{record}'), + 'edit' => Pages\EditProcessOrder::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/ProcessOrderResource/Pages/CreateProcessOrder.php b/app/Filament/Resources/ProcessOrderResource/Pages/CreateProcessOrder.php new file mode 100644 index 0000000..1c87a8a --- /dev/null +++ b/app/Filament/Resources/ProcessOrderResource/Pages/CreateProcessOrder.php @@ -0,0 +1,12 @@ +