diff --git a/app/Filament/Resources/GuardPatrolEntryResource.php b/app/Filament/Resources/GuardPatrolEntryResource.php
new file mode 100644
index 0000000..60540a5
--- /dev/null
+++ b/app/Filament/Resources/GuardPatrolEntryResource.php
@@ -0,0 +1,696 @@
+schema([
+ Forms\Components\Select::make('plant_id')
+ ->label('Plant')
+ ->relationship('plant', 'name')
+ ->required()
+ ->reactive()
+ ->default(function () {
+ return optional(GuardPatrolEntry::where('created_by', Filament::auth()->user()?->name)->latest()->first())->plant_id;
+ })
+ ->disabled(fn (Get $get) => !empty($get('id')))
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ $plantId = $get('plant_id');
+ if (!$plantId) {
+ $set('gPePlantError', 'Please select a plant first.');
+ return;
+ }
+ else
+ {
+ $set('patrol_time', now()->format('Y-m-d H:i:s'));
+ $set('updated_by', Filament::auth()->user()?->name);
+ $set('gPePlantError', null);
+ }
+ })
+ ->extraAttributes(fn ($get) => [
+ 'class' => $get('gPePlantError') ? 'border-red-500' : '',
+ ])
+ ->hint(fn ($get) => $get('gPePlantError') ? $get('gPePlantError') : null)
+ ->hintColor('danger'),
+ Forms\Components\Select::make('guard_name_id')
+ ->label('Guard Name')
+ // ->relationship('guardNames', 'name')
+ ->options(function (callable $get) {
+ $plantId = $get('plant_id');
+ if (!$plantId) {
+ return [];
+ }
+
+ return GuardName::where('plant_id', $plantId)
+ ->pluck('name', 'id')
+ ->toArray();
+ })
+ ->required()
+ ->reactive()
+ ->default(function () {
+ return optional(GuardPatrolEntry::where('created_by', Filament::auth()->user()?->name)->latest()->first())->guard_name_id;
+ })
+ ->disabled(fn (Get $get) => !empty($get('id')))
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ $guardName = $get('guard_name_id');
+ if (!$guardName) {
+ $set('gPeGuardNameError', 'Please select a guard name first.');
+ return;
+ }
+ else
+ {
+ $set('patrol_time', now()->format('Y-m-d H:i:s'));
+ $set('updated_by', Filament::auth()->user()?->name);
+ $set('gPeGuardNameError', null);
+ }
+ })
+ ->extraAttributes(fn ($get) => [
+ 'class' => $get('gPeGuardNameError') ? 'border-red-500' : '',
+ ])
+ ->hint(fn ($get) => $get('gPeGuardNameError') ? $get('gPeGuardNameError') : null)
+ ->hintColor('danger'),
+ Forms\Components\Hidden::make('check_point_name')//TextInput
+ ->label('Check Point Name')
+ ->reactive()
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ $set('patrol_time', now()->format('Y-m-d H:i:s'));
+ $set('updated_by', Filament::auth()->user()?->name);
+ })
+ ->extraAttributes([
+ 'x-on:keydown.enter.prevent' => '$wire.processCheckPointName()',
+ ]),
+ Forms\Components\Select::make('check_point_name_id')
+ ->label('Check Point Name')
+ // ->relationship('checkPointNames', 'name')
+ ->options(function (callable $get) {
+ $plantId = $get('plant_id');
+ if (!$plantId) {
+ return [];
+ }
+
+ return CheckPointName::where('plant_id', $plantId)
+ ->pluck('name', 'id')
+ ->toArray();
+ })
+ ->required()
+ // ->searchable()
+ ->reactive()
+ // ->default(function () {
+ // return optional(GuardPatrolEntry::where('created_by', Filament::auth()->user()?->name)->latest()->first())->check_point_name_id;
+ // })
+ ->disabled(fn (Get $get) => !empty($get('id')))
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ $checkPointName = $get('check_point_name_id');
+ if (!$checkPointName) {
+ $set('check_point_name_id', null);
+ $set('gPeCheckPointNameError', 'Please select a check point name first.');
+ return;
+ }
+ else
+ {
+ $set('patrol_time', now()->format('Y-m-d H:i:s'));
+ $set('updated_by', Filament::auth()->user()?->name);
+ $set('gPeCheckPointNameError', null);
+ }
+ })
+ ->extraAttributes(fn ($get) => [
+ 'class' => $get('gPeCheckPointNameError') ? 'border-red-500' : '',
+ ])
+ ->hint(fn ($get) => $get('gPeCheckPointNameError') ? $get('gPeCheckPointNameError') : null)
+ ->hintColor('danger')
+ ->rule(function (callable $get) {
+ return Rule::unique('guard_patrol_entries', 'check_point_name_id')
+ ->where('guard_name_id', $get('guard_name_id'))
+ ->where('patrol_time', now())
+ ->where('plant_id', $get('plant_id'))
+ ->ignore($get('id'));
+ }),
+ Forms\Components\TextInput::make('reader_code')
+ ->label('Reader Code')
+ ->hidden(fn (Get $get) => !$get('id'))
+ ->reactive()
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ if(!$get('id'))
+ {
+ $set('patrol_time', now()->format('Y-m-d H:i:s'));
+ }
+ $set('updated_by', Filament::auth()->user()?->name);
+ }),
+ Forms\Components\DateTimePicker::make('patrol_time')
+ ->label('Patrol Time')
+ ->reactive()
+ ->default(fn () => now())
+ ->readOnly(fn (Get $get) => !$get('id'))
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ $set('updated_by', Filament::auth()->user()?->name);
+ })
+ ->required()
+ ->rule(function (callable $get) {
+ return Rule::unique('guard_patrol_entries', 'patrol_time')
+ ->where('guard_name_id', $get('guard_name_id'))
+ ->where('check_point_name_id', $get('check_point_name_id'))
+ ->where('plant_id', $get('plant_id'))
+ ->ignore($get('id'));
+ }),
+ Forms\Components\Hidden::make('created_by')
+ ->default(fn () => Filament::auth()->user()?->name)
+ ->required(),
+ Forms\Components\Hidden::make('updated_by')
+ ->reactive()
+ ->default(fn () => Filament::auth()->user()?->name)
+ ->required(),
+ Forms\Components\TextInput::make('id')
+ ->hidden()
+ ->reactive()
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ $set('updated_by', Filament::auth()->user()?->name);
+ })
+ ->readOnly(),
+ ]);
+ }
+
+ 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('id')
+ // ->label('ID')
+ // ->numeric()
+ // ->sortable(),
+ Tables\Columns\TextColumn::make('plant.name')
+ ->label('Plant')
+ ->alignCenter()
+ ->searchable()
+ ->sortable(),
+ Tables\Columns\TextColumn::make('guardNames.name') //guard_name_id
+ ->label('Guard Name')
+ ->alignCenter()
+ ->searchable()
+ ->sortable(),
+ Tables\Columns\TextColumn::make('checkPointNames.name') //check_point_name_id
+ ->label('Check Point Name')
+ ->alignCenter()
+ ->searchable()
+ ->sortable(),
+ Tables\Columns\TextColumn::make('reader_code')
+ ->label('Reader Code')
+ ->alignCenter()
+ ->searchable()
+ ->sortable(),
+ Tables\Columns\TextColumn::make('patrol_time')
+ ->label('Patrol Time')
+ ->dateTime()
+ ->searchable()
+ ->alignCenter()
+ ->sortable(),
+ Tables\Columns\TextColumn::make('created_at')
+ ->label('Created At')
+ ->dateTime()
+ ->alignCenter()
+ ->sortable(),
+ Tables\Columns\TextColumn::make('created_by')
+ ->label('Created By')
+ ->searchable()
+ ->alignCenter(),
+ Tables\Columns\TextColumn::make('updated_at')
+ ->label('Updated At')
+ ->dateTime()
+ ->alignCenter()
+ ->sortable(),
+ Tables\Columns\TextColumn::make('updated_by')
+ ->label('Updated By')
+ ->searchable()
+ ->alignCenter(),
+ Tables\Columns\TextColumn::make('deleted_at')
+ ->label('Deleted 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([
+ Tables\Actions\Action::make('guard_patrol_entries')
+ ->label('Import Guard Patrol Entries')
+ ->form([
+ Select::make('plant_id')
+ ->options(Plant::pluck('name', 'id')->toArray())
+ ->label('Select Plant')
+ ->reactive()
+ ->required()
+ ->default(function () {
+ return optional(GuardPatrolEntry::where('created_by', Filament::auth()->user()?->name)->latest()->first())->plant_id;
+ })
+ ->afterStateUpdated(function ($state, callable $set, callable $get) {
+ $plantId = $get('plant_id');
+ $set('guard_patrol_entry', null);
+ if (!$plantId) {
+ $set('gPeSelectPlantError', 'Please select a plant first.');
+ return;
+ }
+ else
+ {
+ $set('gPeSelectPlantError', null);
+ }
+ })
+ ->extraAttributes(fn ($get) => [
+ 'class' => $get('gPeSelectPlantError') ? 'border-red-500' : '',
+ ])
+ ->hint(fn ($get) => $get('gPeSelectPlantError') ? $get('gPeSelectPlantError') : null)
+ ->hintColor('danger'),
+ FileUpload::make('guard_patrol_entry')
+ ->label('Import Guard Patrol Entries')
+ // ->required()
+ ->preserveFilenames() // <- this keeps the original filename
+ ->storeFiles(false)
+ ->reactive()
+ ->required()
+ ->disk('local')
+ ->visible(fn (Get $get) => !empty($get('plant_id')))
+ ->directory('uploads/temp')
+ // Allow only .xlsx and .xls
+ ->acceptedFileTypes(['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel'])
+ // Optional: Custom error message if needed
+ ->validationMessages([
+ 'mimes' => 'Only .xlsx and .xls files are allowed.',
+ ])
+ // Server-side validation for extra safety
+ ->rules(['mimes:xlsx,xls']),
+ ])
+ ->action(function (array $data) {
+ $uploadedFile = $data['guard_patrol_entry'];
+
+ $plantId = $data['plant_id'];
+
+ $user = Filament::auth()->user()->name;
+
+ $disk = Storage::disk('local');
+
+ $originalName = $uploadedFile->getClientOriginalName(); // e.g. 3RA0018732.xlsx
+
+ $uploadedFileName = pathinfo($originalName, PATHINFO_FILENAME);
+ // $uploadedFileName = trim(str_replace('.xlsx', '', $originalName));
+
+ $folderPath = Configuration::where('c_name', 'GUARD_PATROL_ENTRY_FOLDER_PATH')->where('plant_id', $plantId)->value('c_value');
+
+ if(!$folderPath)
+ {
+ Notification::make()
+ ->title('Upload Folder Path Not Found!')
+ ->body('Please set the folder path in configuration for Guard Patrol Entry.')
+ ->danger()
+ ->send();
+ return;
+ }
+
+ $fullFolderPath = "uploads/$folderPath";
+
+ // Check if the folder exists, if not, create it
+ if (!Storage::disk('local')->exists($fullFolderPath))
+ {
+ Storage::disk('local')->makeDirectory($fullFolderPath);
+ }
+
+ $path = $uploadedFile->storeAs($fullFolderPath, $originalName, 'local');
+
+ $fullPath = Storage::disk('local')->path($path);
+
+ if ($fullPath && file_exists($fullPath))
+ {
+ $rows = Excel::toArray(null, $fullPath)[0];
+
+ if((count($rows) - 1) <= 0)
+ {
+ Notification::make()
+ ->title('Invalid Guard Patrol Entry Found')
+ ->body('Uploaded excel sheet is empty or
contains no valid data.')
+ ->danger()
+ ->send();
+
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ return;
+ }
+
+ $invalidRows=[];
+ $invalidGuardCheckPoints=[];
+ $unknownGuards=[];
+ $unknownCheckPoints=[];
+ $invalidPatrolTimes=[];
+ $validRowsFound = false;
+
+ foreach ($rows as $index => $row)
+ {
+ if ($index === 0) continue; // Skip header
+
+ $rowNumber = trim($row[0]);
+ $guardName = trim($row[1]);
+ $checkPointName = trim($row[2]);
+ $readerCode = trim($row[3]);
+ $patrolTime = trim($row[4]);
+
+ if (empty($rowNumber)) { continue; }
+
+ if (empty($guardName) || empty($checkPointName) || empty($readerCode) || empty($patrolTime)) {
+ $invalidRows[] = $rowNumber;
+ continue;
+ }
+ else
+ {
+ if(Str::length($guardName) < 3 || Str::length($checkPointName) < 3 || Str::length($readerCode) < 3 || Str::length($patrolTime) < 3)
+ {
+ $invalidGuardCheckPoints[] = $rowNumber;
+ continue;
+ }
+ else
+ {
+ $isValidRow = true;
+ $guardNames = GuardName::where('plant_id', $plantId)->where('name', $guardName)->first();
+ if (!$guardNames) {
+ $unknownGuards[] = $guardName;
+ $isValidRow = false;
+ }
+
+ $checkPointNames = CheckPointName::where('plant_id', $plantId)->where('name', $checkPointName)->first();
+ if (!$checkPointNames) {
+ $unknownCheckPoints[] = $checkPointName;
+ $isValidRow = false;
+ }
+
+ $formats = ['d-m-Y H:i:s', 'd-m-Y H:i']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'
+ $patrolDateTime = null;
+ foreach ($formats as $format) {
+ try {
+ $patrolDateTime = Carbon::createFromFormat($format, $patrolTime);
+ break;
+ } catch (\Exception $e) {
+ $invalidPatrolTimes[] = $rowNumber;
+ $isValidRow = false;
+ }
+ }
+
+ if (!isset($patrolDateTime)) {
+ $invalidPatrolTimes[] = $rowNumber;
+ $isValidRow = false;
+ //$warnMsg[] = "Invalid 'Patrol DateTime' format. Expected DD-MM-YYYY HH:MM:SS";
+ }
+
+ if ($isValidRow && !$validRowsFound) {
+ $validRowsFound = true;
+ }
+ }
+ }
+ }
+
+ $uniqueInvalidRows = array_unique($invalidRows);
+ if (!empty($uniqueInvalidRows)) {
+ Notification::make()
+ ->title('Invalid Guard Patrol Entry Found')
+ ->body('The following rows contain empty values (Guard name or Check point name or Reader code or Patrol time):
' . implode(', ', $uniqueInvalidRows))
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ return;
+ }
+
+ //should contain minimum 13 digit alpha numeric values
+ $uniqueInvalidGuardCheckPoints = array_unique($invalidGuardCheckPoints);
+ if (!empty($uniqueInvalidGuardCheckPoints)) {
+ Notification::make()
+ ->title('Invalid Guard Patrol Entry Found')
+ ->body('The following rows contain invalid values (Guard name or Check point name or Reader code or Patrol time):
' . implode(', ', $uniqueInvalidGuardCheckPoints))
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ return;
+ }
+
+ $invalidDataFound = false;
+ $uniqueUnknownGuards = array_unique($unknownGuards);
+ if (!empty($uniqueUnknownGuards)) {
+ Notification::make()
+ ->title('Unknown Guard Names Found')
+ ->body("The following guard names aren't exist in master data:
" . implode(', ', $uniqueUnknownGuards))
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ $invalidDataFound = true;
+ }
+
+ $uniqueUnknownCheckPoints = array_unique($unknownCheckPoints);
+ if (!empty($uniqueUnknownCheckPoints)) {
+ Notification::make()
+ ->title('Unknown Check Point Names Found')
+ ->body("The following check point names aren't exist in master data:
" . implode(', ', $uniqueUnknownCheckPoints))
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ $invalidDataFound = true;
+ }
+
+ $uniqueInvalidPatrolTimes = array_unique($invalidPatrolTimes);
+ if (!empty($uniqueInvalidPatrolTimes)) {
+ Notification::make()
+ ->title('Invalid Patrol Time Format Found')
+ ->body("The following rows contains invalid patrol time format (Expected 'DD-MM-YYYY HH:MM:SS'):
" . implode(', ', $uniqueInvalidPatrolTimes))
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ $invalidDataFound = true;
+ }
+
+ if ($invalidDataFound) {
+ return;
+ }
+
+ if (!$validRowsFound) {
+ Notification::make()
+ ->title('Invalid Guard Patrol Entry Found')
+ ->body('Uploaded excel sheet is empty or
contains no valid data.')
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ return;
+ }
+
+ $validCnt = 0;
+ $dupCnt = 0;
+ $validRowsFound = false;
+ foreach ($rows as $index => $row)
+ {
+ if ($index === 0) continue; // Skip header
+
+ $rowNumber = trim($row[0]);
+ $guardName = trim($row[1]);
+ $checkPointName = trim($row[2]);
+ $readerCode = trim($row[3]);
+ $patrolTime = trim($row[4]);
+
+ if (empty($rowNumber)) { continue; }
+
+ if (empty($guardName) || empty($checkPointName) || empty($readerCode) || empty($patrolTime)) {
+ continue;
+ }
+
+ $isValidRow = true;
+
+ $formats = ['d-m-Y H:i:s', 'd-m-Y H:i']; //'07-05-2025 08:00' or '07-05-2025 08:00:00'
+ $patrolDateTime = null;
+ foreach ($formats as $format) {
+ try {
+ $patrolDateTime = Carbon::createFromFormat($format, $patrolTime);
+ break;
+ } catch (\Exception $e) {
+ $isValidRow = false;
+ }
+ }
+
+ if (!isset($patrolDateTime)) {
+ $isValidRow = false;
+ }
+
+ if ($isValidRow) {
+ $guardNames = GuardName::where('plant_id', $plantId)->where('name', $guardName)->first();
+ $checkPointNames = CheckPointName::where('plant_id', $plantId)->where('name', $checkPointName)->first();
+
+ $guardEntryFound = GuardPatrolEntry::where('plant_id', $plantId)->where('guard_name_id', $guardNames->id)->where('check_point_name_id', $checkPointNames->id)->where('patrol_time', $patrolDateTime->format('Y-m-d H:i:s'))->first();
+
+ if ($guardEntryFound) {
+ //$warnMsg[] = "Duplicate guard patrol entry found";
+ $dupCnt++;
+ continue;
+ }
+ else
+ {
+ $validCnt++;
+ GuardPatrolEntry::updateOrCreate([
+ 'plant_id' => $plantId,
+ 'guard_name_id' => $guardNames->id,
+ 'check_point_name_id' => $checkPointNames->id,
+ 'patrol_time' => $patrolDateTime->format('Y-m-d H:i:s')
+ ],
+ [
+ 'reader_code' => $readerCode,
+ 'created_by' => $user,
+ 'updated_by' => $user
+ ]
+ );
+ $validRowsFound = true;
+ }
+ }
+ }
+
+ if (!$validRowsFound && $dupCnt > 0) {
+ Notification::make()
+ ->title('Duplicate Guard Patrol Entry Found')
+ ->body("Uploaded excel sheet contains '{$dupCnt}' duplicate entries!
Please check the uploaded file and try again.")
+ ->danger()
+ ->send();
+ if ($disk->exists($path))
+ {
+ $disk->delete($path);
+ }
+ }
+ else if ($validRowsFound && $validCnt > 0)
+ {
+ //session(['guard_patrol_entry_path' => $fullPath]);
+ Notification::make()
+ ->title("Success: '{$validCnt}' guard patrol entries imported successfully.")
+ ->success()
+ ->send();
+ if ($disk->exists($path))
+ {
+ $disk->delete($path);
+ }
+ }
+ else
+ {
+ Notification::make()
+ ->title('Failed: Something went wrong while uploading guard patrol entries!')
+ ->danger()
+ ->send();
+ if ($disk->exists($path)) {
+ $disk->delete($path);
+ }
+ }
+ }
+ })
+ ->visible(function() {
+ return Filament::auth()->user()->can('view import guard patrol entries');
+ }),
+ ImportAction::make()
+ ->label('Import Guard Patrol Entry')
+ // ->hidden()
+ ->color('warning')
+ ->importer(GuardPatrolEntryImporter::class)
+ ->visible(function() {
+ return Filament::auth()->user()->can('view import guard patrol entry');
+ }),
+ ExportAction::make()
+ ->label('Export Guard Patrol Entry')
+ ->color('warning')
+ ->exporter(GuardPatrolEntryExporter::class)
+ ->visible(function() {
+ return Filament::auth()->user()->can('view export guard patrol entry');
+ }),
+ ]);
+ }
+
+ public static function getRelations(): array
+ {
+ return [
+ //
+ ];
+ }
+
+ public static function getPages(): array
+ {
+ return [
+ 'index' => Pages\ListGuardPatrolEntries::route('/'),
+ 'create' => Pages\CreateGuardPatrolEntry::route('/create'),
+ 'view' => Pages\ViewGuardPatrolEntry::route('/{record}'),
+ 'edit' => Pages\EditGuardPatrolEntry::route('/{record}/edit'),
+ ];
+ }
+
+ public static function getEloquentQuery(): Builder
+ {
+ return parent::getEloquentQuery()
+ ->withoutGlobalScopes([
+ SoftDeletingScope::class,
+ ]);
+ }
+}
diff --git a/app/Filament/Resources/GuardPatrolEntryResource/Pages/CreateGuardPatrolEntry.php b/app/Filament/Resources/GuardPatrolEntryResource/Pages/CreateGuardPatrolEntry.php
new file mode 100644
index 0000000..08ee645
--- /dev/null
+++ b/app/Filament/Resources/GuardPatrolEntryResource/Pages/CreateGuardPatrolEntry.php
@@ -0,0 +1,293 @@
+ 'handleUpdateSnoQuantity',
+ // ];
+
+ // public ?array $data = null;
+
+
+ public function processCheckPointName()
+ {
+ // $plantId = $this->form->getState()['plant_id'];
+
+ // $plantId = trim($plantId) ?? null;
+
+ // $pendingPallet = $this->form->getState()['pending_pallet_list'];
+
+ // $palletNumber = trim($this->form->getState()['pallet_number'])?? null;
+
+ // $palletNumber = trim($palletNumber) ?? null;
+
+ // $serialNumber = trim($this->form->getState()['serial_number'])?? null;
+
+ // $serialNumber = trim($serialNumber) ?? null;
+
+ // $operatorName = Filament::auth()->user()?->name;
+
+ // $clickedAt = session('pallet_clicked_time');
+
+ // $clickedBy = session('pallet_created_by');
+
+
+ // if(!$palletNumber)
+ // {
+ // Notification::make()
+ // ->title('Pallet number cannot be empty')
+ // ->danger()
+ // ->send();
+ // $this->form->fill([
+ // 'serial_number' => null,
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => 0,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+
+
+ // $count = PalletValidation::where('plant_id', $plantId)
+ // ->where('pallet_number', $palletNumber)
+ // ->count('pallet_number');
+
+
+ // if(!$serialNumber)
+ // {
+ // Notification::make()
+ // ->title('Serial number cannot be empty')
+ // ->danger()
+ // ->send();
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // $this->form->fill([
+ // 'serial_number' => null,
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+ // if(strlen($serialNumber) < 13)
+ // {
+ // Notification::make()
+ // ->title('Serial number should contain minimum 13 digits.')
+ // ->danger()
+ // ->send();
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // $this->form->fill([
+ // 'serial_number' => null,
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+ // if (!ctype_alnum($serialNumber))
+ // {
+ // Notification::make()
+ // ->title('Serial number must contain alpha-numeric values only.')
+ // ->danger()
+ // ->send();
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // $this->form->fill([
+ // 'serial_number' => null,
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+
+ // $existInvoiceSno = LocatorInvoiceValidation::where('serial_number', $serialNumber)
+ // ->where('plant_id', $plantId)
+ // ->where('scanned_status', '=', 'Scanned')
+ // ->first();
+
+ // $invoiceNumber = $existInvoiceSno?->invoice_number;
+ // if($existInvoiceSno)
+ // {
+ // Notification::make()
+ // ->title("Scanned serial number '{$serialNumber}' already completed the scanning process and exist in invoice number : {$invoiceNumber}.
Scan the new serial number to add!")
+ // ->danger()
+ // ->send();
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // $this->form->fill([
+ // 'serial_number' => null,
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+
+ // $existingRecord = PalletValidation::where('serial_number', $serialNumber)
+ // ->where('plant_id', $plantId)
+ // ->first();
+
+ // if ($existingRecord)
+ // {
+
+ // if ($existingRecord && $existingRecord->pallet_number == $palletNumber)
+ // {
+ // Notification::make()
+ // ->title("Scanned serial number '{$serialNumber}' is already exists in pallet number '{$palletNumber}'.
Scan the new serial number to proceed.")
+ // ->danger()
+ // ->send();
+ // }
+ // else if ($existingRecord && $existingRecord->pallet_number && $existingRecord->pallet_number != $palletNumber)
+ // {
+ // Notification::make()
+ // ->title("Scanned serial number '{$serialNumber}' already exists in pallet number '{$existingRecord->pallet_number}'.
Scan the new serial number to proceed.")
+ // ->danger()
+ // ->send();
+ // }
+ // else if ($existingRecord && $existingRecord->locator_number)
+ // {
+ // Notification::make()
+ // ->title("Scanned serial number '{$serialNumber}' is already exists in locator number '{$existingRecord->locator_number}'.
Scan the new serial number to proceed.")
+ // ->danger()
+ // ->send();
+ // }
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // $this->form->fill([
+ // 'serial_number' => null,
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+
+ // try
+ // {
+
+ // $existingPallet = PalletValidation::where('plant_id', $plantId)
+ // ->where('pallet_number', $palletNumber)
+ // ->first();
+
+ // $createdAt = $existingPallet ? $existingPallet->created_at : $clickedAt ?? now();
+
+ // $createdBy = $existingPallet ? $existingPallet->created_by : $clickedBy ?? $operatorName;
+
+ // $record = PalletValidation::create([
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'serial_number' => $serialNumber,
+ // 'created_by' => $createdBy,
+ // 'scanned_by' => $operatorName,
+ // 'created_at' => $createdAt,
+ // 'scanned_at' => now(),
+ // 'updated_by' => $operatorName,
+ // ]);
+
+ // $count = PalletValidation::where('plant_id', $plantId)
+ // ->where('pallet_number', $palletNumber)
+ // ->count('pallet_number');
+
+ // if ($record)
+ // {
+ // Notification::make()
+ // ->title("Scanned serial number : '{$serialNumber}' successfully inserted into pallet table!
Scan the next new serial number to proceed...")
+ // ->success()
+ // ->send();
+
+ // $this->snoCount = PalletValidation::where('plant_id', $plantId)
+ // ->where('pallet_number', $palletNumber)
+ // ->count();
+
+ // $this->form->fill([
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'serial_number' => null,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // }
+ // else
+ // {
+ // Notification::make()
+ // ->title('Pallet validation not inserted.')
+ // ->danger()
+ // ->send();
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // $this->form->fill([
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'serial_number' => null,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+ // }
+ // catch (\Exception $e)
+ // {
+ // Notification::make()
+ // ->title('Error: Pallet validation not inserted.')
+ // ->body("Something went wrong while inserting serial number : '{$serialNumber}' into pallet table!\nScan the new serial number to proceed...")
+ // ->danger()
+ // ->send();
+ // $this->dispatch('loadData', $palletNumber, $plantId);
+ // $this->form->fill([
+ // 'plant_id' => $plantId,
+ // 'pallet_number' => $palletNumber,
+ // 'serial_number' => null,
+ // 'pending_pallet_list' => $pendingPallet,
+ // 'Sno_quantity' => $count,
+ // 'created_by' => $operatorName,
+ // 'scanned_by' => $operatorName,
+ // ]);
+ // return;
+ // }
+ }
+
+ protected function getRedirectUrl(): string
+ {
+ return $this->getResource()::getUrl('create'); // Stay on Create Page after saving
+ }
+}
diff --git a/app/Filament/Resources/GuardPatrolEntryResource/Pages/EditGuardPatrolEntry.php b/app/Filament/Resources/GuardPatrolEntryResource/Pages/EditGuardPatrolEntry.php
new file mode 100644
index 0000000..35c1317
--- /dev/null
+++ b/app/Filament/Resources/GuardPatrolEntryResource/Pages/EditGuardPatrolEntry.php
@@ -0,0 +1,22 @@
+