Files
citrus-cms/app/Services/RegisterCreator/DocumentProcessors/QaDocumentProcessor.php
T
2026-04-28 21:14:25 +03:00

210 lines
8.1 KiB
PHP

<?php
namespace App\Services\RegisterCreator\DocumentProcessors;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Illuminate\Support\Facades\Log;
class QaDocumentProcessor extends AbstractDocumentProcessor
{
/**
* Process QA type documents (NDT reports, procedures, etc.)
*/
public function process(
array $weldLogData,
array $document,
Worksheet $sheet,
int &$currentRow,
array $settings
): int {
$this->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;
}
}