initialize($weldLogData, $document, $sheet, $currentRow, $settings); $this->log("Processing QA document: {$document['path']}"); // Get all joints with same line number $allJoints = apply_welded_filter( db("weld_logs")->where( $this->registerColumnBased, $this->weldLogData[$this->registerColumnBased] ) )->get(); $this->log("Found {$allJoints->count()} joints for processing"); // Check if this is a procedure document if (strpos($document['path'], "Procedure") !== false) { return $this->processProcedureDocuments($currentRow); } // Process NDT reports return $this->processNdtReports($allJoints, $currentRow); } /** * Process NDT (Non-Destructive Testing) reports */ private function processNdtReports($allJoints, int &$currentRow): int { $allReports = []; $uniqueReports = []; $duplicateCount = 0; // LAYER 1: Get reports from weld_logs (synced data) $this->log("Layer 1: Extracting reports from weld_logs"); foreach ($allJoints as $joint) { $jointArray = (array) $joint; $logTypes = array_keys(log_test_types()); foreach ($logTypes as $logType) { try { if (strpos(strtolower($this->document['path']), $logType) !== false) { $reportNoPrefix = $logType . "_report"; if ($logType == "pmi") { $reportNoPrefix = "no_of_testing_report"; } $reportNo = $jointArray[$reportNoPrefix] ?? ''; if (!empty($reportNo) && !in_array($reportNo, $uniqueReports)) { $uniqueReports[] = $reportNo; $allReports[] = [ 'report_no' => $reportNo, 'document_date' => $jointArray[$logType . '_test_date'] ?? '', 'log_type' => $logType, 'weld_log_array' => $jointArray ]; $this->log("Layer 1 - Report added: {$reportNo} ({$logType})"); } else if (!empty($reportNo)) { $duplicateCount++; } } } catch (\Throwable $th) { Log::error("Error processing test type: {$logType}", [ 'error' => $th->getMessage() ]); continue; } } } $this->log("Layer 1 complete: " . count($allReports) . " unique reports from weld_logs"); // Sort reports by joint number (A-Z) // Note: Excel rows are inserted in reverse (insertNewRowBefore), // so A-Z order becomes Z-A in Excel (correct order) usort($allReports, function($a, $b) { $jointNoA = $a['weld_log_array']['no_of_the_joint_as_per_as_built_survey'] ?? ''; $jointNoB = $b['weld_log_array']['no_of_the_joint_as_per_as_built_survey'] ?? ''; // Check if joint numbers are empty - throw error if (empty($jointNoA)) { throw new \Exception("Joint number is empty for report: {$a['report_no']}"); } if (empty($jointNoB)) { throw new \Exception("Joint number is empty for report: {$b['report_no']}"); } // Sort by joint number (natural/numeric order: 1, 2, 3, 10, 11) return strnatcmp($jointNoA, $jointNoB); }); $this->log("Total " . count($allReports) . " unique reports sorted by joint number (A-Z)"); $this->log("Duplicate reports skipped: {$duplicateCount}"); // Process sorted reports foreach ($allReports as $reportData) { try { $normalizedReportNo = $this->normalizeSearchTerm($reportData['report_no']); $search = $this->searchFiles("storage/documents/{$this->document['path']}/*{$normalizedReportNo}*.pdf"); $this->document['title2'] = $reportData['report_no']; // Get translation safely - handle array return $translationKey = $reportData['log_type'] . "_register_title"; $translatedValue = e2($translationKey); // Ensure we have a string, not an array if (is_array($translatedValue)) { $this->document['title4'] = $translationKey; // Use key as fallback Log::warning("Translation returned array for key: {$translationKey}, using key as fallback"); } else { $this->document['title4'] = (string) $translatedValue; } $lineNumber = $reportData['report_no']; $newRow = $this->addRowToExcel( $search, $lineNumber, $reportData['document_date'] ); if ($newRow > $currentRow) { $currentRow = $newRow; } } catch (\Throwable $th) { $this->log("Error processing report: {$reportData['report_no']} - {$th->getMessage()}", 'error'); continue; } } return $currentRow; } /** * Process procedure documents */ private function processProcedureDocuments(int &$currentRow): int { $this->log("Processing Document Procedure"); $documentProcedures = []; if (!empty($this->document['title2'])) { $customCertificates = array_map('trim', explode(",", $this->document['title2'])); $documentProcedures = $customCertificates; } foreach ($documentProcedures as $procedureNo) { try { $procedure = db("document_procedures") ->where("document_no", $procedureNo) ->first(); if ($procedure) { $this->log("Procedure found: {$procedure->document_no}"); $normalizedDocNo = $this->normalizeSearchTerm($procedure->document_no); $searchPath = "storage/documents/{$this->document['path']}/*{$normalizedDocNo}*.pdf"; $search = $this->searchFiles($searchPath); $documentDate = $procedure->publish_date ?? ''; $lineNumber = $procedure->document_no; $this->document['title2'] = $procedure->document_no; $newRow = $this->addRowToExcel( $search, $lineNumber, $documentDate ); if ($newRow > $currentRow) { $currentRow = $newRow; } } else { $this->log("Procedure not found: {$procedureNo}", 'warning'); } } catch (\Throwable $th) { $this->log("Error processing procedure: {$procedureNo} - {$th->getMessage()}", 'error'); continue; } } return $currentRow; } }