mapping. * Risolve alla radice i mismatch causati da caratteri invisibili: * - non-breaking space (U+00A0), narrow NBSP (U+202F), figure space (U+2007), ecc. -> spazio normale * - tab, newline e altri whitespace -> spazio normale * - spazi multipli consecutivi -> un solo spazio * - trim ai bordi * NB: usata SOLO per il matching, non altera i valori importati. */ function normalizeColName($s): string { $s = (string)$s; // Converte i principali spazi Unicode "insidiosi" in spazio normale $s = str_replace( ["\xC2\xA0", "\xE2\x80\xAF", "\xE2\x80\x87", "\xE2\x80\x89", "\xE2\x80\x8A", "\xEF\xBB\xBF"], ' ', $s ); // Qualsiasi sequenza di whitespace (spazi, tab, newline) -> singolo spazio $s = preg_replace('/\s+/u', ' ', $s); return trim((string)$s); } $db = DBHandlerSelect::getInstance(); $pdo = $db->getConnection(); // Genera un UUID univoco per importreferencecode $importReferenceCode = date('YmdHis') . '-' . uniqid(); // Recupera tutti i mapping dal template $stmt = $pdo->prepare("SELECT id, excel_column, data_type, is_required, manual_default, is_manual, field_label, field_id, main_field, auto_value FROM template_mapping WHERE template_id = ?"); $stmt->execute([$template_id]); $allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($allMappings)) { header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Nessun mapping trovato per il template")); exit; } // Trova il campo main_field $mainFieldMapping = null; foreach ($allMappings as $mapping) { if ($mapping['main_field'] == 1) { $mainFieldMapping = $mapping; break; } } // Inserisci le righe selezionate in datadb $insertedIds = []; foreach ($selected_rows as $rowIndex) { $row = $rows[$rowIndex] ?? null; $excelrow = $excelrows[$rowIndex] ?? null; if ($row === null || $excelrow === null) { error_log("Errore: riga o excelrow mancante per rowIndex $rowIndex"); continue; } // Recupera l'idclient di default dal template $template_stmt = $pdo->prepare("SELECT idclient FROM excel_templates WHERE id = ?"); $template_stmt->execute([$template_id]); $template = $template_stmt->fetch(PDO::FETCH_ASSOC); $default_idclient = $template['idclient'] ?? null; $values = [ $template_id, $importReferenceCode, $newFilename, 'i', $user_id, null, date('Y-m-d'), $excelrow, $default_idclient // Aggiungi idclient ]; $sql = "INSERT INTO datadb (templateid, importreferencecode, filename_import, status, user_id, limscode, importdate, excelrow, idclient) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; $stmt = $pdo->prepare($sql); $stmt->execute($values); $iddatadb = $pdo->lastInsertId(); $insertedIds[] = $iddatadb; // Inserisci tutti i campi in import_data_details foreach ($allMappings as $mapping) { $fieldValue = null; if (!$mapping['is_manual']) { $excelColumn = trim($mapping['excel_column']); // Match robusto: normalizza header e mapping (NBSP, spazi doppi, tab...) // così un solo/doppio spazio o un non-breaking space non rompono il confronto. $excelColumnIndex = array_search( normalizeColName($excelColumn), array_map('normalizeColName', $columns) ); if ($excelColumnIndex !== false && isset($row[$excelColumnIndex]) && $row[$excelColumnIndex] !== '') { $fieldValue = $row[$excelColumnIndex]; error_log("Found Excel column '$excelColumn' at index $excelColumnIndex, value: " . var_export($fieldValue, true)); } else { $fieldValue = $mapping['manual_default'] ?? ''; error_log("Excel column '$excelColumn' not found or empty, using default: " . var_export($fieldValue, true)); } switch ($mapping['data_type']) { case 'INT': $fieldValue = is_numeric($fieldValue) ? (int)$fieldValue : ($mapping['manual_default'] ?? 0); break; case 'DATE': $fieldValue = !empty($fieldValue) ? date('Y-m-d', strtotime($fieldValue)) : ($mapping['manual_default'] === 'today' ? date('Y-m-d') : ($mapping['manual_default'] ?? '')); break; case 'CHAR': $fieldValue = !empty($fieldValue) ? substr((string)$fieldValue, 0, 1) : ($mapping['manual_default'] ?? ''); break; case 'Testo': case 'VARCHAR': default: $fieldValue = !empty($fieldValue) ? (string)$fieldValue : ($mapping['manual_default'] ?? ''); break; } } else { $fieldValue = $mapping['manual_default'] ?? ''; if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') { $fieldValue = date('Y-m-d'); } } // Apply auto_value if field is still empty if (($fieldValue === null || $fieldValue === '') && !empty($mapping['auto_value']) && $mapping['auto_value'] !== 'none') { if ($mapping['auto_value'] === 'import_date') { $fieldValue = date('Y-m-d'); } elseif ($mapping['auto_value'] === 'import_time') { $fieldValue = date('H:i'); } } if ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) { error_log("Required field missing for mapping ID: " . $mapping['id'] . ", field: " . $mapping['field_label']); } error_log("Inserting into import_data_details - Mapping ID: " . $mapping['id'] . ", Field Value: " . var_export($fieldValue, true) . ", Is Manual: " . $mapping['is_manual'] . ", Excel Column: " . ($mapping['excel_column'] ?? 'N/A') . ", Manual Default: " . ($mapping['manual_default'] ?? 'N/A')); $stmt = $pdo->prepare("INSERT INTO import_data_details (id, mapping_id, field_value) VALUES (?, ?, ?)"); $stmt->execute([$iddatadb, $mapping['id'], $fieldValue]); error_log("Inserted into import_data_details for ID $iddatadb, Mapping ID: " . $mapping['id'] . ", Field Value: " . var_export($fieldValue, true)); } } // ------------------------------------------------------------ // AUTO SET: schema field_id = 244 (Accettatore) con auth_users.lims_user_id // Spostato dal vecchio flusso (import_edit.php) al flusso nuovo. // Autocompila il custom field 244 con il lims_user_id dell'utente loggato. // ------------------------------------------------------------ try { // 1) Leggi il lims_user_id dell'utente loggato $stmtUser = $pdo->prepare("SELECT lims_user_id FROM auth_users WHERE id = ? LIMIT 1"); $stmtUser->execute([(int)$user_id]); $limsUserId = $stmtUser->fetchColumn(); // normalize $limsUserId = ($limsUserId !== false && $limsUserId !== null && $limsUserId !== '') ? (string)$limsUserId : ''; if ($limsUserId !== '' && !empty($insertedIds)) { // 2) Trova il mapping_id per field_id = 244 in questo template $stmtMap = $pdo->prepare("SELECT id FROM template_mapping WHERE template_id = ? AND field_id = 244 LIMIT 1"); $stmtMap->execute([(int)$template_id]); $mappingId244 = (int)$stmtMap->fetchColumn(); if ($mappingId244 > 0) { // 3) Upsert del valore in import_data_details per ogni riga inserita $pdo->beginTransaction(); $updStmt = $pdo->prepare("UPDATE import_data_details SET field_value = ? WHERE id = ? AND mapping_id = ?"); $insStmt = $pdo->prepare("INSERT INTO import_data_details (id, mapping_id, field_value) VALUES (?, ?, ?)"); foreach ($insertedIds as $iddatadb) { $iddatadb = (int)$iddatadb; if ($iddatadb <= 0) continue; $updStmt->execute([$limsUserId, $iddatadb, $mappingId244]); if ($updStmt->rowCount() === 0) { $insStmt->execute([$iddatadb, $mappingId244, $limsUserId]); } } $pdo->commit(); } else { error_log("[AUTO FIELD 244] Nessun mapping field_id=244 per template $template_id"); } } else { error_log("[AUTO FIELD 244] limsUserId vuoto per user_id=$user_id o nessuna riga inserita"); } } catch (Exception $e) { // Non bloccare l'import se questo fallisce; logga soltanto error_log("[AUTO FIELD 244] " . $e->getMessage()); if ($pdo->inTransaction()) $pdo->rollBack(); } $_SESSION['inserted_ids'] = $insertedIds; header("Location: imported.php?id=" . urlencode($template_id) . "&importref=" . urlencode($importReferenceCode)); exit;