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; } }