diff --git a/app/Filament/Resources/LocatorInvoiceValidationResource.php b/app/Filament/Resources/LocatorInvoiceValidationResource.php new file mode 100644 index 0000000..daba71c --- /dev/null +++ b/app/Filament/Resources/LocatorInvoiceValidationResource.php @@ -0,0 +1,697 @@ +schema([ + Section::make('') + ->schema([ + Forms\Components\Select::make('plant_id') + ->label('Plant') + ->reactive() + ->relationship('plant', 'name') + ->disabled(fn (Get $get) => $get('invoice_number')) + ->required() + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $plantId = $get('plant_id'); + if ($plantId) + { + $set('plant', $plantId); + $set('invoice_number', null); + $set('pallet_number', null); + $set('serial_number', null); + $set('sno_quantity', null); + } + else + { + $set('plant', null); + $set('invoice_number', null); + $set('pallet_number', null); + $set('serial_number', null); + $set('sno_quantity', null); + } + }), + + Forms\Components\Hidden::make('plant') + ->reactive(), + + Forms\Components\TextInput::make('invoice_number') + ->label('Scan Invoice No') + ->required() + ->reactive() + ->extraAttributes([ + 'x-data' => '{ value: "" }', + 'x-model' => 'value', + 'x-on:keydown.enter.prevent' => '$wire.processinvoiceSNo()', + ]) + ->readOnly(fn (callable $get) => !$get('plant') || $get('pallet_number') || $get('serial_number')) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $plantId = $get('plant'); + if (!$plantId) { + $set('invoice_number', null); + $set('pallet_number', null); + + } + $set('update_invoice', null); + $set('pallet_number', null); + $set('serial_number', null); + }), + Forms\Components\TextInput::make('pallet_number') + ->label('Scan Pallet No') + ->reactive() + // ->readOnly(fn (callable $get) => !$get('plant') || !$get('invoice_number') || $get('serial_number')) + ->readOnly(function (callable $get) { + $invoiceNumber = $get('invoice_number'); + $plantId = $get('plant'); + $invoiceExist = false; + + if (!empty($invoiceNumber) && !empty($plantId)) { + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && !$allScanned) { + $invoiceExist = true; + } + } + + return $invoiceExist == false || !$get('plant') || !$get('invoice_number') || $get('serial_number'); + }) + ->extraAttributes([ + 'wire:keydown.enter.prevent' => 'processPalletNo()', + ]) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $plantId = $get('plant'); + if (!$plantId) { + $set('invoice_number', null); + $set('pallet_number', null); + } + $set('update_locator_invoice', null); + }), + Forms\Components\TextInput::make('serial_number') + ->label('Scan Serial No') + ->reactive() + // ->readOnly(fn (callable $get) => !$get('plant') || !$get('invoice_number') || $get('pallet_number')) + ->readOnly(function (callable $get) { + $invoiceNumber = $get('invoice_number'); + $plantId = $get('plant'); + $invoiceExist = false; + + if (!empty($invoiceNumber) && !empty($plantId)) { + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && !$allScanned) { + $invoiceExist = true; + } + } + + return $invoiceExist == false || !$get('plant') || !$get('invoice_number') || $get('pallet_number'); + }) + ->extraAttributes([ + 'x-data' => '{ value: "" }', + 'x-model' => 'value', + 'x-on:keydown.enter.prevent' => '$wire.processSerialNo()', + ]), + Forms\Components\TextInput::make('sno_quantity') + ->label('SNo. Quantity') + ->readOnly(), + + //Forms\Components\View::make('forms.components.update-invoice-button'), + + ToggleButtons::make('update_invoice') + ->label('Update Invoice?') + ->boolean() + ->grouped() + ->reactive() + ->hidden(function (callable $get) { + $invoiceNumber = $get('invoice_number'); + $plantId = $get('plant'); + $invoiceExist = false; + + if (!empty($invoiceNumber) && !empty($plantId)) { + + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && !$allScanned) { + $invoiceExist = true; + } + } + + return $get('update_invoice') == '0' || $invoiceExist == false || !empty($get('pallet_number')) || !empty($get('serial_number')); //$get('invoice_number') == null + }), + + Forms\Components\TextInput::make('id') + ->hidden() + ->readOnly(), + + ToggleButtons::make('update_locator_invoice') + ->label('Update Partial Pallet?') + ->boolean() + ->grouped() + ->reactive() + ->hidden(function (callable $get) { + $palletNumber = $get('pallet_number'); + $plantId = $get('plant'); + $isPalletValid = false; + + if (!empty($palletNumber) && !empty($plantId)) { + $pallet = PalletValidation::where('plant_id', $plantId) + ->where('pallet_number', $palletNumber) + ->first(); + $isPalletValid = $pallet !== null; + } + + return !$isPalletValid || $get('update_locator_invoice') == '0' || !empty($get('serial_number')); + }) + ->afterStateUpdated(function ($state, callable $set, callable $get, $livewire) { + $plantId = $get('plant'); + + $palletNumber = $get('pallet_number'); + + $serialNumber = $get('serial_number'); + + $invoiceNumber = $get('invoice_number'); + + $operatorName = Filament::auth()->user()->name; + + if ($state !== '1') { + $set('update_locator_invoice', '0'); + $set('pallet_number', null); + return; + } + + $palletRecord = PalletValidation::where('plant_id', $plantId) + ->where('pallet_number', $palletNumber) + ->first(); + + if (!$palletRecord) + { + Notification::make() + ->title("Pallet number '{$palletNumber}' does not exist.") + ->danger() + ->send(); + return; + } + + $palletRecords = PalletValidation::where('plant_id', $plantId) + ->where('pallet_number', $palletNumber) + ->get(); + + $allCompleted = true; + foreach ($palletRecords as $record) { + if ($record->pallet_status != 'Completed') { + $allCompleted = false; + break; + } + } + + if (!$allCompleted) + { + Notification::make() + ->title("Pallet number '{$palletNumber}' is not completed in masters") + ->danger() + ->send(); + return; + } + + // if ($allCompleted) + // { + // $serialNumbers = $palletRecords->pluck('serial_number') + // ->map(function ($serial) { + // return trim($serial); + // }) + // ->all(); + + // $InvoiceSerialNumbers = LocatorInvoiceValidation::where('plant_id', $plantId) + // ->where('invoice_number', $invoiceNumber) + // ->pluck('serial_number') + // ->all(); + + // $missingSerialNumbers = array_diff($InvoiceSerialNumbers, $serialNumbers); + + // $allmatchedSerialNumbers = array_unique(array_merge($InvoiceSerialNumbers, $serialNumbers)); + + // if (!empty($missingSerialNumbers)) + // { + + // $matchedSerialNumbers = array_diff($serialNumbers, $missingSerialNumbers); + + // foreach ($matchedSerialNumbers as $serial) + // { + // $invoiceRecord = LocatorInvoiceValidation::where('plant_id', $plantId) + // ->where('invoice_number', $invoiceNumber) + // ->where('serial_number', $serial) + // ->first(); + + // if ($invoiceRecord) + // { + // $invoiceRecord->scanned_status = 'Scanned'; + // $invoiceRecord->pallet_number = $palletNumber; + // $invoiceRecord->scanned_at = now(); + // $invoiceRecord->scanned_by = $operatorName; + // $invoiceRecord->save(); + + // Notification::make() + // ->title("Pallet number '{$palletNumber}' scanned successfully") + // ->success() + // ->send(); + // } + + // PalletValidation::where('plant_id', $plantId) + // ->where('pallet_number', $palletNumber) + // ->where('serial_number', $serial) + // ->forceDelete(); + + // $livewire('loadData', $invoiceNumber, $plantId); + // } + // } + // else + // { + // foreach ($allmatchedSerialNumbers as $serial) + // { + // $invoiceRecord = LocatorInvoiceValidation::where('plant_id', $plantId) + // ->where('invoice_number', $invoiceNumber) + // ->where('serial_number', $serial) + // ->first(); + + // if ($invoiceRecord) + // { + // $invoiceRecord->scanned_status = 'Scanned'; + // $invoiceRecord->pallet_number = $palletNumber; + // $invoiceRecord->scanned_at = now(); + // $invoiceRecord->scanned_by = $operatorName; + // $invoiceRecord->save(); + + // Notification::make() + // ->title("Pallet number '{$palletNumber}' scanned successfully") + // ->success() + // ->send(); + // } + + // PalletValidation::where('plant_id', $plantId) + // ->where('pallet_number', $palletNumber) + // ->where('serial_number', $serial) + // ->forceDelete(); + + // $this->dispatch('loadData', $invoiceNumber, $plantId); + // } + // } + // } + }) + ]) + ->columns(5), + + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\TextColumn::make('No.') + ->label('No.') + ->alignCenter() + ->getStateUsing(function ($record, $livewire, $column, $rowLoop) { + $paginator = $livewire->getTableRecords(); + $perPage = method_exists($paginator, 'perPage') ? $paginator->perPage() : 10; + $currentPage = method_exists($paginator, 'currentPage') ? $paginator->currentPage() : 1; + return ($currentPage - 1) * $perPage + $rowLoop->iteration; + }), + Tables\Columns\TextColumn::make('plant.name') + ->label('Plant') + ->alignCenter() + ->searchable() + ->sortable(), + Tables\Columns\TextColumn::make('invoice_number') + ->label('Invoice Number') + ->searchable() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('serial_number') + ->label('Serial Number') + ->searchable() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('pallet_number') + ->label('Pallet Number') + ->searchable() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('locator_number') + ->label('Locator Number') + ->searchable() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('scanned_status') + ->label('Scanned Status') + ->searchable() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('upload_status') + ->label('Upload Status') + ->searchable() + ->alignCenter(), + Tables\Columns\TextColumn::make('created_by') + ->label('Created By') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('created_at') + ->label('Created At') + ->dateTime() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('updated_by') + ->label('Updated By') + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('updated_at') + ->label('Updated At') + ->dateTime() + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + Tables\Columns\TextColumn::make('scanned_by') + ->label('Scanned By') + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('scanned_at') + ->label('Scanned At') + ->dateTime() + ->alignCenter() + ->sortable(), + Tables\Columns\TextColumn::make('deleted_at') + ->dateTime() + ->alignCenter() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + ]) + + ->headerActions([ + Tables\Actions\Action::make('import_invoice') + ->label('Import Invoice') + ->form([ + Select::make('plant_id') + ->options(Plant::pluck('name', 'id')->toArray()) + ->label('Select Plant') + ->required() + ->default(function () { + return optional(InvoiceValidation::latest()->first())->plant_id; + }) + ->afterStateUpdated(function ($state, callable $set, callable $get) { + $set('invoice_serial_number', null); + }) + ->reactive(), + + FileUpload::make('invoice_serial_number') + ->label('Invoice Serial Number') + // ->required() + ->preserveFilenames() // <- this keeps the original filename + ->storeFiles(false) + ->reactive() + ->required() + ->disk('local') + ->visible(fn (Get $get) => !empty($get('plant_id'))) + ->directory('uploads/temp'), + ]) + ->action(function (array $data) { + $uploadedFile = $data['invoice_serial_number']; + + $disk = Storage::disk('local'); + + $plantId = $data['plant_id']; + + $originalName = $uploadedFile->getClientOriginalName(); // e.g. 3RA0018732.xlsx + + $invoiceNumber = pathinfo($originalName, PATHINFO_FILENAME); + // $invoiceNumber = trim(str_replace('.xlsx', '', $originalName)); + // $originalNameOnly = pathinfo($originalName, PATHINFO_FILENAME); + + $folderPath = Configuration::where('c_name', 'INVOICE_FOLDER_PATH') + ->value('c_value'); + + $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 Locator Invoice Found') + ->body('Uploaded excel sheet is empty or
contains no valid data.') + ->danger() + ->send(); + + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + + $invalidSerialCodes=[]; + $duplicateSerials = []; + $seenSerialNumbers = []; + $validRowsFound = false; + + foreach ($rows as $index => $row) + { + if ($index === 0) continue; // Skip header + + $serialNumber = trim($row[0]); + + if (empty($serialNumber)) + { + continue; + } + else + { + if(Str::length($serialNumber) < 13 || !ctype_alnum($serialNumber)) + { + $invalidSerialCodes[] = $serialNumber; + } + else + { + if (in_array($serialNumber, $seenSerialNumbers)) { + $duplicateSerials[] = $serialNumber; + } + else + { + $seenSerialNumbers[] = $serialNumber; + $validRowsFound = true; + } + } + } + } + + $uniqueSerialCodes = array_unique($invalidSerialCodes); + + if (!empty($uniqueSerialCodes)) { + Notification::make() + ->title('Invalid Serial Numbers Found') + ->body('The following serial numbers should contain minimum 13 digit alpha numeric values:
' . implode(', ', $uniqueSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + + $duplicateSerialCodes = array_unique($duplicateSerials); + + if (!empty($duplicateSerialCodes)) { + Notification::make() + ->title('Duplicate Serial Numbers Found') + ->body('The following serial numbers are already exist in imported excel:
' . implode(', ', $duplicateSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + + if (!$validRowsFound) { + Notification::make() + ->title('Invalid Locator Invoice Found') + ->body('Uploaded excel sheet is empty or
contains no valid data.') + ->danger() + ->send(); + if ($disk->exists($path)) { + $disk->delete($path); + } + return; + } + + $serialsToCheck = $seenSerialNumbers; + + $existingSerials = LocatorInvoiceValidation::whereIn('serial_number', $serialsToCheck) + ->where('invoice_number', '!=', $invoiceNumber) + ->where('plant_id', $plantId) + ->pluck('serial_number') + ->toArray(); + + if (!empty($existingSerials)) { + Notification::make() + ->title('Duplicate Serial Numbers Found') + ->body('The following serial numbers already exist with a different invoice number:
' . implode(', ', $existingSerials)) + ->danger() + ->send(); + if ($disk->exists($path)) + { + $disk->delete($path); + } + return; + } + else + { + // Save full file path to session + session(['uploaded_invoice_path' => $fullPath]); + Notification::make() + ->title('Success: Invoice imported successfully.') + ->success() + ->send(); + } + } + }) + ->visible(function() { + return Filament::auth()->user()->can('view import dispatch serial invoice validation'); + }), + + ImportAction::make() + ->importer(LocatorInvoiceValidationImporter::class) + ->visible(function() { + return Filament::auth()->user()->can('view import locator invoice validation'); + }), + ExportAction::make() + ->exporter(LocatorInvoiceValidationExporter::class) + ->visible(function() { + return Filament::auth()->user()->can('view export locator invoice validation'); + }), + ]) + + ->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\ListLocatorInvoiceValidations::route('/'), + 'create' => Pages\CreateLocatorInvoiceValidation::route('/create'), + 'view' => Pages\ViewLocatorInvoiceValidation::route('/{record}'), + 'edit' => Pages\EditLocatorInvoiceValidation::route('/{record}/edit'), + ]; + } + + public static function getEloquentQuery(): Builder + { + return parent::getEloquentQuery() + ->withoutGlobalScopes([ + SoftDeletingScope::class, + ]); + } +} diff --git a/app/Filament/Resources/LocatorInvoiceValidationResource/Pages/CreateLocatorInvoiceValidation.php b/app/Filament/Resources/LocatorInvoiceValidationResource/Pages/CreateLocatorInvoiceValidation.php new file mode 100644 index 0000000..a4e11ba --- /dev/null +++ b/app/Filament/Resources/LocatorInvoiceValidationResource/Pages/CreateLocatorInvoiceValidation.php @@ -0,0 +1,1580 @@ +form->getState()['plant']; + + $plantId = trim($plantId) ?? null; + + $palletNumber = $this->form->getState()['pallet_number']; + + $palletNumber = trim($palletNumber) ?? null; + + $serialNumber = $this->form->getState()['serial_number']; + + $serialNumber = trim($serialNumber) ?? null; + + $invoiceNumber = $this->form->getState()['invoice_number']; + + $invoiceNumber = trim($invoiceNumber) ?? null; + + $updateStatus = $this->form->getState()['update_invoice'] ?? null; + + $user = Filament::auth()->user(); + + $operatorName = $user->name; + + if(!$plantId) + { + Notification::make() + ->title('Plant Not Found') + ->body("Plant can't be empty!") + ->danger() + ->send(); + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + try + { + // $record1 = LocatorInvoiceValidation::query() + // ->where('plant_id', $plantId) + // ->where('invoice_number', $invoiceNumber) + // ->first(); + + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && $allScanned) { + Notification::make() + ->title('Completed: Locator Invoice') + ->body("Locator invoice '$invoiceNumber' completed the scanning process.
Scan the next 'Locator Invoice' to proceed..!") + ->info() + ->send(); + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $invoiceExist = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->count('invoice_number'); + + if($invoiceExist <= 0) + { + $filename = $invoiceNumber . '.xlsx'; + + $folderPath = Configuration::where('c_name', 'INVOICE_FOLDER_PATH') + ->where('plant_id', $plantId) + ->value('c_value'); + + $fullFolderPath = "uploads/$folderPath"; + + $directory = $fullFolderPath; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + $fullPath = $disk->path($filePath); + + if ($disk->exists($filePath)) + { + $fullPath = $disk->path($filePath); + } + else + { + Notification::make() + ->title('Invoice File Not Found') + ->body("Import the scanned 'Invoice' file to proceed..!") + ->danger() + ->seconds(2) + ->send(); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => 0, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + $this->dispatch('loadData', '', $plantId); + return; + } + + if ($fullPath && file_exists($fullPath)) + { + $rows = Excel::toArray(null, $fullPath)[0]; + + if((count($rows) - 1) <= 0) + { + Notification::make() + // ->title('Records Not Found') + // ->body("Import the valid 'Serial Invoice' file to proceed..!") + ->title('Invalid Locator Invoice Found') + ->body('Uploaded excel sheet is empty or
contains no valid data.') + ->danger() + ->send(); + + if ($disk->exists($filePath)) + { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $invalidSerialCodes=[]; + $duplicateSerials = []; + $seenSerialNumbers = []; + $validRowsFound = false; + + foreach ($rows as $index => $row) + { + if ($index === 0) continue; // Skip header + + $serialNumber = trim((string)($row[0] ?? '')); + + if (empty($serialNumber)) + { + continue; + } + else + { + if(Str::length($serialNumber) < 13 || !ctype_alnum($serialNumber)) + { + $invalidSerialCodes[] = $serialNumber; + } + else + { + if (in_array($serialNumber, $seenSerialNumbers)) { + $duplicateSerials[] = $serialNumber; + } + else + { + $seenSerialNumbers[] = $serialNumber; + $validRowsFound = true; + } + } + } + } + + $uniqueSerialCodes = array_unique($invalidSerialCodes); + + if (!empty($uniqueSerialCodes)) { + Notification::make() + ->title('Invalid Serial Numbers Found') + ->body('The following serial numbers should contain minimum 13 digit alpha numeric values:
' . implode(', ', $uniqueSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $duplicateSerialCodes = array_unique($duplicateSerials); + + if (!empty($duplicateSerialCodes)) { + Notification::make() + ->title('Duplicate Serial Numbers Found') + ->body('The following serial numbers are already exist in imported excel:
' . implode(', ', $duplicateSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + if (!$validRowsFound) { + Notification::make() + ->title('Invalid Locator Invoice Found') + ->body('Uploaded excel sheet is empty or
contains no valid data.') + ->danger() + ->send(); + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => 0, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $serialsToCheck = $seenSerialNumbers; + + $existingSerials = LocatorInvoiceValidation::whereIn('serial_number', $serialsToCheck) + ->where('invoice_number', '!=', $invoiceNumber) + ->where('plant_id', $plantId) + ->pluck('serial_number') + ->toArray(); + + if (!empty($existingSerials)) { + Notification::make() + ->title('Duplicate Serial Numbers Found') + ->body('The following serial numbers already exist with a different invoice number:
' . implode(', ', $existingSerials)) + ->danger() + ->send(); + if ($disk->exists($filePath)) + { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => 0, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + $createdAny = false; + foreach ($seenSerialNumbers as $serialNumber) + { + // $deleted = LocatorInvoiceValidation::where('invoice_number', $invoiceNumber) + // ->where('serial_number', $serialNumber) + // ->where('plant_id', $plantId) + // ->where(function($query) { + // $query->whereNull('scanned_status') + // ->orWhere('scanned_status', ''); + // }) + // ->forceDelete(); + + // if ($deleted) + // { + // LocatorInvoiceValidation::create([ + // 'plant_id' => $plantId, + // 'invoice_number' => $invoiceNumber, + // 'serial_number' => $serialNumber, + // 'created_by' => $operatorName, + + // ]); + // $createdAny = true; + + // $this->form->fill([ + // 'plant_id' => $plantId, + // 'plant' => $plantId, + // 'invoice_number' => $invoiceNumber, + // 'serial_number' => null, + // 'sno_quantity' => $this->snoCount, + // 'created_by' => $operatorName, + // 'scanned_by' => $operatorName, + // ]); + + // $this->dispatch('loadData', $invoiceNumber, $plantId); + // } + + LocatorInvoiceValidation::create([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => $serialNumber, + 'created_by' => $operatorName, + ]); + + $createdAny = true; + + } + + if ($createdAny) + { + Notification::make() + ->title('Success: Invoice inserted successfully.') + ->success() + ->send(); + Notification::make() + ->title("Start the scanning process for imported invoice number '$invoiceNumber'!") + ->info() + ->send(); + if ($disk->exists($filePath)) + { + $disk->delete($filePath); + } + + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->count(); + + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + + $this->dispatch('loadData', $invoiceNumber, $plantId); + } + } + } + } + else if($updateStatus == 1) + { + $filename = $invoiceNumber . '.xlsx'; + + $folderPath = Configuration::where('c_name', 'INVOICE_FOLDER_PATH') + ->where('plant_id', $plantId) + ->value('c_value'); + + $fullFolderPath = "uploads/$folderPath"; + + $directory = $fullFolderPath; + $disk = Storage::disk('local'); + $filePath = $directory . '/' . $filename; + $fullPath = $disk->path($filePath); + + if ($disk->exists($filePath)) { + $fullPath = $disk->path($filePath); + } + else + { + Notification::make() + ->title('Updated Invoice File Not Found') + ->body("Import the updated 'Invoice' file to proceed..!") + ->danger() + ->seconds(2) + ->send(); + + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => null, + ]); + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + // session()->flash('invoice_valid', true); + + if ($fullPath && file_exists($fullPath)) + { + $rows = Excel::toArray(null, $fullPath)[0]; + + if((count($rows) - 1) <= 0) + { + Notification::make() + ->title('Invalid Updated Locator Invoice Found') + ->body('Uploaded excel sheet is empty or
contains no valid data.') + ->danger() + ->send(); + + if ($disk->exists($filePath)) + { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $invalidSerialCodes=[]; + $duplicateSerials = []; + $seenSerialNumbers = []; + $validRowsFound = false; + + foreach ($rows as $index => $row) + { + if ($index === 0) continue; // Skip header + + $serialNumber = trim((string) ($row[0] ?? '')); + + if (empty($serialNumber)) + { + continue; + } + else + { + if(Str::length($serialNumber) < 13 || !ctype_alnum($serialNumber)) + { + $invalidSerialCodes[] = $serialNumber; + } + else + { + if (in_array($serialNumber, $seenSerialNumbers)) { + $duplicateSerials[] = $serialNumber; + } + else + { + $seenSerialNumbers[] = $serialNumber; + $validRowsFound = true; + } + } + } + } + + $uniqueSerialCodes = array_unique($invalidSerialCodes); + + if (!empty($uniqueSerialCodes)) { + Notification::make() + ->title('Invalid Serial Numbers Found') + ->body('The following serial numbers should contain minimum 13 digit alpha numeric values:
' . implode(', ', $uniqueSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $duplicateSerialCodes = array_unique($duplicateSerials); + + if (!empty($duplicateSerialCodes)) { + Notification::make() + ->title('Duplicate Serial Numbers Found') + ->body('The following serial numbers are already exist in imported excel:
' . implode(', ', $duplicateSerialCodes)) + ->danger() + ->send(); + if ($disk->exists($filePath)) + { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + if (!$validRowsFound) { + Notification::make() + ->title('Invalid Updated Locator Invoice Found') + ->body('Uploaded excel sheet is empty or
contains no valid data.') + ->danger() + ->send(); + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $serialsToCheck = $seenSerialNumbers; + + $existingSerials = LocatorInvoiceValidation::whereIn('serial_number', $serialsToCheck) + ->where('invoice_number', '!=', $invoiceNumber) + ->where('plant_id', $plantId) + ->pluck('serial_number') + ->toArray(); + + if (!empty($existingSerials)) { + Notification::make() + ->title('Duplicate Serial Numbers Found') + ->body('The following serial numbers already exist with a different invoice number:
' . implode(', ', $existingSerials)) + ->danger() + ->send(); + if ($disk->exists($filePath)) { + $disk->delete($filePath); + } + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + $createdAny = false; + foreach ($seenSerialNumbers as $serialNumber) + { + $existingRecord = LocatorInvoiceValidation::where('invoice_number', $invoiceNumber) + ->where('serial_number', $serialNumber) + ->where('plant_id', $plantId) + ->first(); + + if ($existingRecord) { + if ($existingRecord->scanned_status != null && $existingRecord->scanned_status != '') { + continue; + } + $existingRecord->forceDelete(); + } + + LocatorInvoiceValidation::create([ + 'plant_id' => $plantId, + 'invoice_number' => $invoiceNumber, + 'serial_number' => $serialNumber, + 'created_by' => $operatorName, + 'updated_by' => $operatorName, + ]); + + $createdAny = true; + } + + if ($createdAny) + { + Notification::make() + ->title('Success: Locator invoice updated successfully.') + ->success() + ->send(); + Notification::make() + ->title("Start the scanning process for updated invoice number '$invoiceNumber'!") + ->info() + ->send(); + if ($disk->exists($filePath)) + { + $disk->delete($filePath); + } + + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->count(); + + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + } + + $this->dispatch('loadData', $invoiceNumber, $plantId); + } + } + } + else + { + Notification::make() + ->title("Start the scanning process for scanned invoice number '$invoiceNumber'!") + ->info() + ->send(); + + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->count(); + + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + + $this->dispatch('loadData', $invoiceNumber, $plantId); + } + + } + catch (\Exception $e) + { + Notification::make() + ->title('Error: Locator invoice insertion (or updation).') + ->body($e->getMessage()) + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->count(); + + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + } + } + + public function processPalletNo() + { + $plantId = $this->form->getState()['plant']; + + $this->plantId = $plantId; + + $palletNumber = trim($this->form->getState()['pallet_number']); + + $this->pallet_number = $palletNumber; + + $serialNumber = trim($this->form->getState()['serial_number']); + + $this->serial_number = $serialNumber; + + $invoiceNumber = trim($this->form->getState()['invoice_number']); + + $this->invoice_number = $invoiceNumber; + + $operatorName = Filament::auth()->user()->name; + + $updateLocatorStatus = $this->form->getState()['update_locator_invoice'] ?? null; + + $PalletSerialNumbers = []; + + $InvoiceSerialNumbers = []; + + $matchedSerialNumbers = []; + + $UnknownSerialNumbers = []; + + $invExist = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->first(); + if (!$invExist) + { + Notification::make() + ->title('Invoice Not Found') + ->body("Scanned invoice number '$invoiceNumber' does not exist in invoice table!
Import the scanned 'Invoice' file to proceed..!") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && $allScanned) { + Notification::make() + ->title('Completed: Locator Invoice') + ->body("Invoice number '$invoiceNumber' completed the scanning process.
Scan the next 'Locator Invoice' to proceed..!") + ->info() + ->send(); + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + } + + if ($palletNumber == '' || $palletNumber == null) + { + Notification::make() + ->title("Pallet number can't be empty!") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->count(); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->count(); + if (strlen($palletNumber) < 10) + { + Notification::make() + ->title("Pallet number '$palletNumber' must be at least 10 digits.") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $palletRecord = PalletValidation::where('plant_id', $plantId) + ->where('pallet_number', $palletNumber) + ->first(); + + if (!$palletRecord) + { + Notification::make() + ->title("Pallet number '{$palletNumber}' does not exist in pallet table.") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $palletRecords = PalletValidation::where('plant_id', $plantId) + ->where('pallet_number', $palletNumber) + ->get(); + + $allCompleted = true; + foreach ($palletRecords as $record) { + if ($record->pallet_status != 'Completed') { + $allCompleted = false; + break; + } + } + + if (!$allCompleted) + { + Notification::make() + ->title("Pallet number '{$palletNumber}' does not completed the master packing!") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + if ($allCompleted) + { + $PalletSerialNumbers = $palletRecords->pluck('serial_number') + ->map(function ($serial) { + return trim($serial); + }) + ->all(); + + $InvoiceSerialNumbers = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->where(function ($query) { + $query->where('scanned_status', '=', '') + ->orWhereNull('scanned_status'); + }) + ->pluck('serial_number') + ->all(); + + $matchedSerialNumbers = array_intersect($PalletSerialNumbers, $InvoiceSerialNumbers); + + if (empty($matchedSerialNumbers)) + { + Notification::make() + ->title("Scanned pallet number '$palletNumber' does not have invoice serial numbers.
Scan the valid exist pallet number to start the scanning process..!") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $UnknownSerialNumbers = array_diff($PalletSerialNumbers, $InvoiceSerialNumbers); + // $matchedSerialNumbers = array_unique(array_merge($InvoiceSerialNumbers, $PalletSerialNumbers)); + + if (!empty($UnknownSerialNumbers)) + { + //hereToContinue... + if($updateLocatorStatus == null || $updateLocatorStatus == 0) + { + // $missingSerialsString = "Missing serial numbers:\n" . implode(",\n", $missingSerialNumbers); + $missingSerialsString = "Scanned pallet number '$palletNumber' has '".count($PalletSerialNumbers)."' serial numbers.

But, below mentioned '".count($matchedSerialNumbers)."' serial numbers only exist in invoice,
".implode(", ", $matchedSerialNumbers)."

Press 'Yes' and Click 'Enter' in the pallet text box to proceed with existing serial number!

Press 'No' to cancel the scanning process!"; + + if (count($matchedSerialNumbers) > 10) + { + //$missingSerialsString = "Missing serial numbers: " . count($missingSerialNumbers); + $missingSerialsString = "Scanned pallet number '$palletNumber' has '".count($PalletSerialNumbers)."' serial numbers.

But, '".count($matchedSerialNumbers)."' serial numbers only exist in invoice,

Press 'Yes' and Click 'Enter' in the pallet text box to proceed with existing serial number!

Press 'No' to cancel the scanning process!"; + } + + // $body = "Scanned pallet number '$palletNumber' has ".$missingSerialsString."
Do you want to skip missing serial numbers?
Then Press 'Yes' and Click 'Enter'."; + + Notification::make() + ->title("Partial Pallet Serial Numbers Found") + ->body($missingSerialsString) + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => $palletNumber, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + } + } + else + { + $updLocNam = ''; + foreach ($matchedSerialNumbers as $serial) + { + $palletRecord = PalletValidation::where('plant_id', $plantId)->where('pallet_number', $palletNumber)->where('serial_number', $serial)->first(); + $invoiceRecord = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->where('serial_number', $serial)->first(); + + if ($invoiceRecord) + { + $invoiceRecord->scanned_status = 'Scanned'; + $invoiceRecord->pallet_number = $palletNumber; + $invoiceRecord->locator_number = $palletRecord->locator_number; + $invoiceRecord->scanned_at = now(); + $invoiceRecord->scanned_by = $operatorName; + $invoiceRecord->save(); + } + + if ($updLocNam == '' || $updLocNam == null) + { + $updLocNam = $palletRecord->locator_number; + } + + // PalletValidation::where('plant_id', $plantId)->where('pallet_number', $palletNumber)->where('serial_number', $serial)->forceDelete(); + $palletRecord->forceDelete(); + } + + if ($updLocNam != '' && $updLocNam != null) + { + $locator = Locator::where('locator_number', $updLocNam)->where('plant_id', $plantId) + ->first(); + + if ($locator && $locator->locator_quantity > 0) { + $locator->locator_quantity = $locator->locator_quantity - 1; + $locator->updated_at = now(); + $locator->operator_id = $operatorName; + $locator->save(); + } + + PalletValidation::where('plant_id', $plantId) + ->where('locator_number', $updLocNam) + ->update([ + 'locator_quantity' => $locator->locator_quantity, + 'updated_at' => now() + ]); + } + + Notification::make() + ->title("All Serial numbers are moved into invoice from the pallet number '$palletNumber'.
Scan the next exist pallet number to start the scanning process..!") + ->success() + ->send(); + + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && $allScanned) { + Notification::make() + ->title('Completed: Locator Invoice') + ->body("Invoice number '$invoiceNumber' completed the scanning process.
Scan the next 'Locator Invoice' to proceed..!") + ->info() + ->send(); + + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + } + } + + if($updateLocatorStatus == 1) + { + if ($allCompleted) + { + foreach ($matchedSerialNumbers as $serial) + { + $palletRecord = PalletValidation::where('plant_id', $plantId)->where('pallet_number', $palletNumber)->where('serial_number', $serial)->first(); + $invoiceRecord = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->where('serial_number', $serial)->first(); + + if ($invoiceRecord) + { + $invoiceRecord->scanned_status = 'Scanned'; + $invoiceRecord->pallet_number = $palletNumber; + $invoiceRecord->locator_number = $palletRecord->locator_number; + $invoiceRecord->scanned_at = now(); + $invoiceRecord->scanned_by = $operatorName; + $invoiceRecord->save(); + } + + // PalletValidation::where('plant_id', $plantId)->where('pallet_number', $palletNumber)->where('serial_number', $serial)->forceDelete(); + $palletRecord->forceDelete(); + } + + $succMsgStr = "Below mentioned '".count($matchedSerialNumbers)."' Serial numbers are moved into invoice from the pallet number '$palletNumber'.

".implode(", ", $matchedSerialNumbers)."

Scan the next exist pallet number to start the scanning process..!"; + + if (count($matchedSerialNumbers) > 10) + { + $succMsgStr = "'".count($matchedSerialNumbers)."' Serial numbers are moved into invoice from the pallet number '$palletNumber'.
Scan the next exist pallet number to start the scanning process..!"; + } + + Notification::make() + ->title($succMsgStr) + ->success() + ->send(); + + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && $allScanned) { + Notification::make() + ->title('Completed: Locator Invoice') + ->body("Invoice number '$invoiceNumber' completed the scanning process.
Scan the next 'Locator Invoice' to proceed..!") + ->info() + ->send(); + + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + } + else if($updateLocatorStatus == 0) + { + $updateLocatorStatus == null; + } + } + } + + public function processSerialNo() + { + $plantId = $this->form->getState()['plant']; + + $this->plantId = $plantId; + + $palletNumber = trim($this->form->getState()['pallet_number']); + + $this->pallet_number = $palletNumber; + + $serialNumber = trim($this->form->getState()['serial_number']); + + $this->serial_number = $serialNumber; + + $invoiceNumber = trim($this->form->getState()['invoice_number']); + + $this->invoice_number = $invoiceNumber; + + $operatorName = Filament::auth()->user()->name; + + $updateLocatorStatus = $this->form->getState()['update_locator_invoice'] ?? null; + + $existSerialNumber = ''; + + $InvoiceSerialNumber = ''; + + $invExist = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->first(); + if (!$invExist) + { + Notification::make() + ->title('Invoice Not Found') + ->body("Scanned invoice number '$invoiceNumber' does not exist in invoice table!
Import the scanned 'Invoice' file to proceed..!") + ->danger() + ->send(); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + $records = LocatorInvoiceValidation::where('plant_id', $plantId) + ->where('invoice_number', $invoiceNumber) + ->get(); + + $allScanned = true; + + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && $allScanned) { + Notification::make() + ->title('Completed: Locator Invoice') + ->body("Invoice number '$invoiceNumber' completed the scanning process.
Scan the next 'Locator Invoice' to proceed..!") + ->info() + ->send(); + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + } + + if ($serialNumber == '' || $serialNumber == null) + { + Notification::make() + ->title("Invalid: Serial Number") + ->body("Serial number can't be empty!") + ->danger() + ->send(); + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->count(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $snoCount = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->count(); + if (strlen($serialNumber) < 13) + { + Notification::make() + ->title("Invalid: Serial Number") + ->body("Serial number '$serialNumber' must be at least 13 digits and alpha-numeric value only allowed!") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $InvoiceSerialNumber = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->where('serial_number', $serialNumber)->first(); + + if (!$InvoiceSerialNumber) + { + Notification::make() + ->title("Unknown: Serial Number") + ->body("Serial number '{$serialNumber}' does not exist in invoice number '$invoiceNumber'.") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else if($InvoiceSerialNumber->scanned_status != null && $InvoiceSerialNumber->scanned_status != '') + { + Notification::make() + ->title("Completed: Serial Number") + ->body("Serial number '{$serialNumber}' already completed the scanning process for the invoice number '$invoiceNumber'.") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + + $existSerialNumber = PalletValidation::where('plant_id', $plantId)->where('serial_number', $serialNumber)->first(); + + $updLocQty = false; + $succMsg = "Scanned serial number '{$serialNumber}' is moved into invoice.

Scan the next exist serial number to start the scanning process..!"; + $existPallNum = $existSerialNumber->pallet_number ?? null; + $existPallStat = $existSerialNumber->pallet_status ?? null; + $existLocatNum = $existSerialNumber->locator_number ?? null; + if (!$existSerialNumber) + { + //skip update locator quantity + $updLocQty = false; + Notification::make() + ->title("Unknown: Serial Number") + ->body("Serial number '{$serialNumber}' does not exist in pallet table.") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else if ($existPallNum == null || $existPallNum == '') + { + //skip update locator quantity + $updLocQty = false; + $succMsg = "Scanned serial number '{$serialNumber}' is moved into invoice from the locator number '$existLocatNum'.

Scan the next exist serial number to start the scanning process..!"; + } + else if ($existLocatNum == null || $existLocatNum == '') + { + if ($existPallStat == null || $existPallStat == '') + { + //skip update locator quantity + $updLocQty = false; + $succMsg = "Scanned serial number '{$serialNumber}' is moved into invoice from the pallet number '$existPallNum'.

Scan the next exist serial number to start the scanning process..!"; + Notification::make() + ->title("Incompleted Pallet: Serial Number")//Pallet number '{$existPallNum}' does not completed the master packing! + ->body("Serial number '{$serialNumber}' exist in pallet number '$existPallNum' and it does not completed the master packing!") + ->danger() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + //skip update locator quantity + $updLocQty = false; + $succMsg = "Scanned serial number '{$serialNumber}' is moved into invoice from the pallet number '$existPallNum'.

Scan the next exist serial number to start the scanning process..!"; + } + } + else if ($existPallNum != null && $existPallNum != '' && $existLocatNum != null && $existLocatNum != '') + { + //update locator quantity based on condition + $snoCount = PalletValidation::where('plant_id', $plantId)->where('pallet_number', $existPallNum)->count(); + if ($snoCount > 0 && $snoCount == 1) + { + $updLocQty = true; + } + else + { + $updLocQty = false; + } + $succMsg = "Scanned serial number '{$serialNumber}' is moved into invoice from the pallet number '$existPallNum' in the locator number '$existLocatNum'.

Scan the next exist serial number to start the scanning process..!"; + } + + if ($InvoiceSerialNumber) + { + $InvoiceSerialNumber->pallet_number = $existPallNum; + $InvoiceSerialNumber->locator_number = $existLocatNum; + $InvoiceSerialNumber->scanned_status = 'Scanned'; + $InvoiceSerialNumber->scanned_at = now(); + $InvoiceSerialNumber->scanned_by = $operatorName; + $InvoiceSerialNumber->save(); + $existSerialNumber->forceDelete(); + + if ($updLocQty) + { + //hereToContinue + $locator = Locator::where('locator_number', $existLocatNum)->where('plant_id', $plantId)->first(); + + if ($locator && $locator->locator_quantity > 0) { + $locator->locator_quantity = $locator->locator_quantity - 1; + $locator->updated_at = now(); + $locator->operator_id = $operatorName; + $locator->save(); + } + + PalletValidation::where('plant_id', $plantId)->where('locator_number', $existLocatNum) + ->update([ + 'locator_quantity' => $locator->locator_quantity, + 'updated_at' => now() + ]); + } + + Notification::make() + ->title($succMsg) + ->success() + ->send(); + + $records = LocatorInvoiceValidation::where('plant_id', $plantId)->where('invoice_number', $invoiceNumber)->get(); + + $allScanned = true; + foreach ($records as $record) + { + if (($record->scanned_status == null) || trim($record->scanned_status) == '') { + $allScanned = false; + break; + } + } + + if (count($records) > 0 && $allScanned) { + Notification::make() + ->title('Completed: Locator Invoice') + ->body("Invoice number '$invoiceNumber' completed the scanning process.
Scan the next 'Locator Invoice' to proceed..!") + ->info() + ->send(); + + $this->dispatch('loadData', '', $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'update_invoice' => 0, + 'serial_number' => null, + 'sno_quantity' => null, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + else + { + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + } + else + { + Notification::make() + ->title("Failed to check Serial number '{$serialNumber}' existence.
Scan the valid serial number to proceed...") + ->success() + ->send(); + $this->dispatch('loadData', $invoiceNumber, $plantId); + $this->form->fill([ + 'plant_id' => $plantId, + 'plant' => $plantId, + 'invoice_number' => $invoiceNumber, + 'pallet_number' => null, + 'serial_number' => null, + 'sno_quantity' => $snoCount, + 'created_by' => $operatorName, + 'scanned_by' => $operatorName, + ]); + return; + } + } + + public function getFormActions(): array + { + return []; + } +} diff --git a/app/Filament/Resources/LocatorInvoiceValidationResource/Pages/EditLocatorInvoiceValidation.php b/app/Filament/Resources/LocatorInvoiceValidationResource/Pages/EditLocatorInvoiceValidation.php new file mode 100644 index 0000000..3a6db6b --- /dev/null +++ b/app/Filament/Resources/LocatorInvoiceValidationResource/Pages/EditLocatorInvoiceValidation.php @@ -0,0 +1,22 @@ +