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

209 lines
7.7 KiB
PHP

<?php
namespace App\Services\TpCreator;
use App\Services\RegisterCreator\ExcelHandler;
use App\Services\RegisterCreator\PdfConverter;
use App\Services\TpCreator\DocumentProcessors\TpDocumentProcessorFactory;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Storage;
use PhpOffice\PhpSpreadsheet\IOFactory;
use Exception;
class TpCreatorService
{
private ExcelHandler $excelHandler;
private PdfConverter $pdfConverter;
public function __construct()
{
$this->excelHandler = new ExcelHandler();
$this->pdfConverter = new PdfConverter();
}
/**
* Process single TP line
*/
public function processLine(array $lineData, array $documents, array $settings): array
{
$startTime = microtime(true);
$jobId = $settings['job_id'];
$testPackageNo = $lineData['test_package_number'];
$path = $settings['path'] ?? '';
$override = $settings['override'] ?? true;
$this->updateProgress($jobId, 0, "Starting TP: $testPackageNo");
// 1. Prepare Data
$testPackage = db("test_pack_base_statuses")
->where("test_package_no", $testPackageNo)
->first();
if(!$testPackage) {
throw new Exception("Test Package not found: $testPackageNo");
}
// 2. Prepare Folders
$basePath = "storage/documents/$path";
$fullFolder = "$basePath/$testPackageNo/";
$justFolder = "$path/$testPackageNo/";
if (!file_exists($fullFolder)) {
mkdir($fullFolder, 0777, true);
}
// Initialize Log File and Create Info File
$this->initializeLogFile($fullFolder, $testPackageNo);
$this->createInfoFile($fullFolder, $testPackageNo, $settings);
// 3. Load Template
$documentInfo = document_template("register");
if (!$documentInfo) {
throw new Exception("Register template not found!");
}
$this->excelHandler->loadTemplate($documentInfo->files);
$sheet = $this->excelHandler->getSheet();
// 4. Initial Setup
$startRow = setting("register_creator_start_row") ?: 16;
$currentRow = $startRow;
$rowNo = 1;
// 5. Process Documents
$totalDocs = count($documents);
$processedDocs = 0;
foreach($documents as $doc) {
$docType = $doc['type'];
$docPath = $doc['path'];
$docTitle = $doc['title2'] ?? '';
$this->updateProgress($jobId, round(($processedDocs / $totalDocs) * 90), "Processing $docTitle");
try {
// Use Factory to get appropriate processor
$processor = TpDocumentProcessorFactory::make($docType, $docPath);
// Prepare settings for processor
$processorSettings = [
'override' => $override,
'full_folder' => $fullFolder,
'row_no' => $rowNo,
// Add other settings if needed by specific processors
];
// Process document
$newRow = $processor->process(
$lineData,
$doc,
$sheet,
$currentRow,
$rowNo,
$fullFolder,
$testPackageNo,
$override
);
// If rows were added, update currentRow and rowNo
// The processor returns the *next* row number (e.g., if it added 2 rows, it returns currentRow + 2)
// Actually, my interface implementation returns the new rowNo/count.
// Let's standardize: Processors should return the new currentRow index in Excel.
// Wait, QaTpProcessor returns rowNo (count) not currentRow (Excel index).
// Let's re-check the AbstractTpDocumentProcessor and implementations.
// QaTpProcessor returns $rowNo (the counter, not Excel row index).
// WdbTpProcessor returns $rowNo.
// AbstractTpDocumentProcessor adds rows and increments currentRow and rowNo by reference passed to addRow helper.
// But rowNo is passed by value to process() method unless specified otherwise.
// CORRECTION: In my implementation of processors, I passed $rowNo by value.
// And process() returns int. QaTpProcessor returns $rowNo.
// This means the returned value is the new Row Number counter.
// I need to calculate how many rows were added to update $currentRow.
// Let's assume process() returns the new $rowNo.
// Then diff = $newRowNo - $oldRowNo.
// $currentRow += diff.
// Let's verify AbstractTpDocumentProcessor signature I wrote:
// public function process(..., int $rowNo, ...): int
$oldRowNo = $rowNo;
$rowNo = $newRow; // Update global row counter
$rowsAdded = $rowNo - $oldRowNo;
$currentRow += $rowsAdded;
} catch (Exception $e) {
Log::error("Error processing document type $docType: " . $e->getMessage());
// Continue to next document
}
$processedDocs++;
}
// 6. Save & Convert
$registerFileName = $justFolder . "Register.xlsx";
$this->excelHandler->save($registerFileName, $override);
$this->pdfConverter->convert($registerFileName, $justFolder, $override);
$this->updateProgress($jobId, 100, "Completed");
return ['status' => 'success'];
}
private function updateProgress($jobId, $percent, $desc) {
$queue = Cache::get('tp-creator-queue', []);
if(isset($queue[$jobId])) {
$queue[$jobId]['progress'] = $percent;
$queue[$jobId]['description'] = $desc;
Cache::put('tp-creator-queue', $queue, now()->addHours(24));
}
}
/**
* Initialize log file
*/
private function initializeLogFile(string $fullFolder, string $lineIdentifier): void
{
$logPath = $fullFolder . 'log.txt';
if (file_exists($logPath)) {
unlink($logPath);
}
$header = str_repeat("🚀", 30) . "\n";
$header .= "TP CREATOR LOG FILE\n";
$header .= "Line: {$lineIdentifier}\n";
$header .= "Started: " . now()->toDateTimeString() . "\n";
$header .= str_repeat("🚀", 30) . "\n\n";
file_put_contents($logPath, $header);
}
/**
* Create info.txt file with user information (JSON format)
*/
private function createInfoFile(string $fullFolder, string $lineIdentifier, array $settings): void
{
$infoPath = $fullFolder . 'info.txt';
// Delete old info file if exists
if (file_exists($infoPath)) {
unlink($infoPath);
}
// Create simple JSON with user information
$infoData = [
'user_name' => $settings['user_name'] ?? 'Unknown',
'user_id' => $settings['user_id'] ?? null,
'created_at' => now()->format('Y-m-d H:i:s'),
'line_identifier' => $lineIdentifier
];
file_put_contents($infoPath, json_encode($infoData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
}
}