= 2) { $shortNumber = $certParts[0]; // e.g., АЦСТ $certNumber = isset($certParts[1]) ? $certParts[1] : ''; // If there's a third part, combine with second if (count($certParts) >= 3) { $certNumber = $certParts[1]; // e.g., 20 or 161 $thirdPart = $certParts[2]; // e.g., 01934 or 00050 // Generate certificate patterns with different zero prefixes $certPatterns = [$thirdPart]; // Clean leading zeros and generate additional search patterns $trimmedCertNo = ltrim($thirdPart, '0'); if ($trimmedCertNo != $thirdPart && $trimmedCertNo != '') { $certPatterns[] = $trimmedCertNo; // Add versions with different numbers of leading zeros for ($i = 1; $i <= 5; $i++) { $certPatterns[] = str_pad($trimmedCertNo, $i, '0', STR_PAD_LEFT); } } // Try each pattern until we find a match foreach ($certPatterns as $certPattern) { // Format: short_number-certNumber-certPattern $searchData = "*{$shortNumber}-{$certNumber}-{$certPattern}*"; $searchData = str_replace("/", "*", $searchData); $searchData = str_replace(" ", "*", $searchData); $searchData = str_replace("\\", "*", $searchData); $path = "{$basePath}/{$searchData}"; $searchPDF = glob($path); if (!empty($searchPDF)) { Log::debug("Found with pattern", [ 'pattern' => $searchData, 'files' => count($searchPDF) ]); return $searchPDF; } } } else { // Format with only 2 parts: АЦСТ-161 $certPatterns = [$certNumber]; $trimmedCertNo = ltrim($certNumber, '0'); if ($trimmedCertNo != $certNumber && $trimmedCertNo != '') { $certPatterns[] = $trimmedCertNo; for ($i = 1; $i <= 5; $i++) { $certPatterns[] = str_pad($trimmedCertNo, $i, '0', STR_PAD_LEFT); } } foreach ($certPatterns as $certPattern) { $searchData = "*{$shortNumber}-{$certPattern}*"; $searchData = str_replace("/", "*", $searchData); $searchData = str_replace(" ", "*", $searchData); $searchData = str_replace("\\", "*", $searchData); $path = "{$basePath}/{$searchData}"; $searchPDF = glob($path); if (!empty($searchPDF)) { Log::debug("Found with 2-part pattern", [ 'pattern' => $searchData, 'files' => count($searchPDF) ]); return $searchPDF; } } } // Fallback: Try just the short_number $searchData = "*{$shortNumber}*"; $searchData = str_replace("/", "*", $searchData); $searchData = str_replace(" ", "*", $searchData); $searchData = str_replace("\\", "*", $searchData); $path = "{$basePath}/{$searchData}"; $searchPDF = glob($path); if (!empty($searchPDF)) { Log::debug("Found with short_number fallback", [ 'pattern' => $searchData, 'files' => count($searchPDF) ]); return $searchPDF; } } // Final fallback: Try exact certificate number $searchData = "*{$certificateNo}*"; $searchData = str_replace("/", "*", $searchData); $searchData = str_replace(" ", "*", $searchData); $searchData = str_replace("\\", "*", $searchData); $path = "{$basePath}/{$searchData}"; $searchPDF = glob($path); if (!empty($searchPDF)) { Log::debug("Found with exact match", [ 'pattern' => $searchData, 'files' => count($searchPDF) ]); return $searchPDF; } Log::warning("No files found for certificate", [ 'certificate' => $certificateNo, 'base_path' => $basePath ]); return $files; } public function process( array $weldLogData, array $document, Worksheet $sheet, int &$currentRow, array $settings ): int { $this->initialize($weldLogData, $document, $sheet, $currentRow, $settings); $wpsData = $settings['wps_data'] ?? null; if (!$wpsData || empty($wpsData->naks_certificate_no)) { $this->log("WPS Naks certificate not found", 'warning'); return $currentRow; } $naksCertificates = explode(" + ", $wpsData->naks_certificate_no); // Prepare certificates with dates for sorting $certificatesWithDates = []; foreach ($naksCertificates as $naksCertificate) { $certInfo = db("naks_certificates")->where("certificate_no", $naksCertificate)->first(); $certificatesWithDates[] = [ 'certificate_no' => $naksCertificate, 'date' => $certInfo->valid_from ?? '' ]; } // Sort by valid_from date (oldest first) - reverse insertion order usort($certificatesWithDates, function($a, $b) { $timestampA = !empty($a['date']) ? strtotime($a['date']) : 0; $timestampB = !empty($b['date']) ? strtotime($b['date']) : 0; return $timestampA <=> $timestampB; }); $this->log("Certificates sorted by date (oldest first for reverse insertion)"); foreach ($certificatesWithDates as $certData) { $naksCertificate = $certData['certificate_no']; try { Log::debug("Processing Naks certificate: " . $naksCertificate); // Try multiple search strategies for Cyrillic characters and URL encoding $search = []; $basePath = "storage/documents/{$document['path']}"; // Strategy 1: Try with URL decoded path $decodedPath = urldecode($basePath); $files = $this->searchFilesWithFallback($decodedPath, $naksCertificate); if (!empty($files)) { $search = $files; Log::debug("Found files with decoded path", ['count' => count($files), 'path' => $decodedPath]); } // Strategy 2: Try with original path if first strategy failed if (empty($search) && $decodedPath !== $basePath) { $files = $this->searchFilesWithFallback($basePath, $naksCertificate); if (!empty($files)) { $search = $files; Log::debug("Found files with original path", ['count' => count($files), 'path' => $basePath]); } } $document['title2'] = $naksCertificate; $this->document = $document; $newRow = $this->addRowToExcel( $search, $naksCertificate, $certData['date'] ); if ($newRow > $currentRow) { $currentRow = $newRow; } } catch (\Throwable $th) { $this->log("Error: {$th->getMessage()}", 'error'); continue; } } return $currentRow; } }