234 lines
7.9 KiB
PHP
234 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\RegisterCreator\DocumentProcessors;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class DynamicMappingProcessor extends AbstractDocumentProcessor
|
|
{
|
|
public function process(
|
|
array $weldLogData,
|
|
array $document,
|
|
Worksheet $sheet,
|
|
int &$currentRow,
|
|
array $settings
|
|
): int {
|
|
$this->initialize($weldLogData, $document, $sheet, $currentRow, $settings);
|
|
|
|
$this->log("Processing dynamic mapped document: {$document['title2']}");
|
|
|
|
// Check if this document has SQL query configuration
|
|
if (empty($document['sql_query'])) {
|
|
$this->log("No SQL query found for dynamic document", 'warning');
|
|
return $currentRow;
|
|
}
|
|
|
|
return $this->processSqlBasedMapping($currentRow);
|
|
}
|
|
|
|
private function processSqlBasedMapping(int &$currentRow): int
|
|
{
|
|
try {
|
|
// Execute SQL query with placeholder replacement
|
|
$results = $this->executeSqlQuery();
|
|
|
|
if (empty($results)) {
|
|
$this->log("SQL query returned no results", 'warning');
|
|
return $currentRow;
|
|
}
|
|
|
|
$this->log("Found " . count($results) . " records from SQL query");
|
|
|
|
// Process each result
|
|
foreach ($results as $result) {
|
|
try {
|
|
$identifier = $result['identifier'];
|
|
$recordData = $result['data'];
|
|
$documentDate = $result['document_date'];
|
|
|
|
// Generate row title using pattern
|
|
$rowTitle = $this->generateRowTitle($recordData);
|
|
|
|
// Generate file search pattern
|
|
$searchPattern = $this->generateFileSearchPattern($recordData);
|
|
$fullPath = "storage/documents/{$this->document['path']}/{$searchPattern}";
|
|
|
|
// Search for files
|
|
$files = $this->searchFiles($fullPath);
|
|
|
|
if (empty($files)) {
|
|
$this->log("No files found for: {$identifier} (pattern: {$searchPattern})", 'warning');
|
|
continue;
|
|
}
|
|
|
|
$this->log("✓ Found " . count($files) . " files for: {$identifier}");
|
|
|
|
// Update document titles
|
|
$this->document['title2'] = $identifier;
|
|
$this->document['title4'] = $rowTitle;
|
|
|
|
// Add row to Excel
|
|
$newRow = $this->addRowToExcel(
|
|
$files,
|
|
$identifier,
|
|
$documentDate
|
|
);
|
|
|
|
if ($newRow > $currentRow) {
|
|
$currentRow = $newRow;
|
|
}
|
|
|
|
$this->log("✓ Processed: {$identifier} (from SQL query)");
|
|
|
|
} catch (\Throwable $th) {
|
|
$this->log("Error processing SQL result: {$th->getMessage()}", 'error');
|
|
Log::error("Dynamic mapping result processing error", [
|
|
'identifier' => $result['identifier'] ?? 'unknown',
|
|
'error' => $th->getMessage(),
|
|
'trace' => $th->getTraceAsString()
|
|
]);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return $currentRow;
|
|
|
|
} catch (\Throwable $th) {
|
|
$this->log("SQL query execution error: {$th->getMessage()}", 'error');
|
|
Log::error("Dynamic mapping SQL execution error", [
|
|
'sql_query' => $this->document['sql_query'] ?? 'N/A',
|
|
'error' => $th->getMessage(),
|
|
'trace' => $th->getTraceAsString()
|
|
]);
|
|
throw $th;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Execute SQL query with placeholder replacement
|
|
*/
|
|
private function executeSqlQuery(): array
|
|
{
|
|
$sqlQuery = $this->document['sql_query'] ?? '';
|
|
|
|
if (empty($sqlQuery)) {
|
|
throw new \Exception("No SQL query defined for dynamic document");
|
|
}
|
|
|
|
// Replace placeholders
|
|
$executedQuery = $this->replacePlaceholders($sqlQuery);
|
|
|
|
Log::info("Executing dynamic SQL query", [
|
|
'original_query' => $sqlQuery,
|
|
'executed_query' => $executedQuery
|
|
]);
|
|
|
|
try {
|
|
$startTime = microtime(true);
|
|
$results = DB::select($executedQuery);
|
|
$executionTime = round((microtime(true) - $startTime) * 1000, 2);
|
|
|
|
Log::info("Dynamic SQL query executed successfully", [
|
|
'record_count' => count($results),
|
|
'execution_time' => $executionTime . 'ms'
|
|
]);
|
|
|
|
return $this->formatResults($results);
|
|
|
|
} catch (\Throwable $th) {
|
|
Log::error("Dynamic SQL query execution failed", [
|
|
'query' => $executedQuery,
|
|
'error' => $th->getMessage()
|
|
]);
|
|
|
|
throw $th;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Replace :placeholder with actual values from register data
|
|
*/
|
|
private function replacePlaceholders(string $query): string
|
|
{
|
|
$result = $query;
|
|
|
|
// Find all :placeholder patterns
|
|
preg_match_all('/:(\w+)/', $query, $matches);
|
|
|
|
foreach ($matches[1] as $placeholder) {
|
|
$value = $this->weldLogData[$placeholder] ?? null;
|
|
|
|
if ($value !== null) {
|
|
// Escape value for SQL
|
|
$escapedValue = DB::getPdo()->quote($value);
|
|
$result = str_replace(":{$placeholder}", $escapedValue, $result);
|
|
} else {
|
|
Log::warning("Placeholder value not found", [
|
|
'placeholder' => $placeholder,
|
|
'available_fields' => array_keys($this->weldLogData)
|
|
]);
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Format SQL results to standard structure
|
|
*/
|
|
private function formatResults(array $results): array
|
|
{
|
|
$identifierField = $this->document['identifier_field'] ?? 'identifier';
|
|
$dateField = $this->document['date_field'] ?? 'document_date';
|
|
|
|
$formatted = [];
|
|
|
|
foreach ($results as $result) {
|
|
$recordArray = (array) $result;
|
|
|
|
$identifier = $recordArray[$identifierField] ?? $recordArray['id'] ?? 'unknown';
|
|
$date = $recordArray[$dateField] ?? '';
|
|
|
|
$formatted[] = [
|
|
'identifier' => $identifier,
|
|
'document_date' => $date,
|
|
'data' => $recordArray
|
|
];
|
|
}
|
|
|
|
return $formatted;
|
|
}
|
|
|
|
/**
|
|
* Generate file search pattern with field replacements
|
|
*/
|
|
private function generateFileSearchPattern(array $recordData): string
|
|
{
|
|
$pattern = $this->document['file_search_pattern'] ?? '*{identifier}*.pdf';
|
|
|
|
// Replace {field_name} with actual values
|
|
foreach ($recordData as $key => $value) {
|
|
$pattern = str_replace("{{$key}}", $value, $pattern);
|
|
}
|
|
|
|
return $pattern;
|
|
}
|
|
|
|
/**
|
|
* Generate row title with pattern
|
|
*/
|
|
private function generateRowTitle(array $recordData): string
|
|
{
|
|
$pattern = $this->document['title4_pattern'] ?? '{identifier}';
|
|
|
|
// Replace {field_name} with actual values
|
|
foreach ($recordData as $key => $value) {
|
|
$pattern = str_replace("{{$key}}", $value, $pattern);
|
|
}
|
|
|
|
return $pattern;
|
|
}
|
|
}
|