false, 'error' => 'Richiesta non valida']); exit; } $template_id = intval($input['template_id']); $importReferenceCode = (string)$input['importreferencecode']; $newFilename = (string)$input['filename']; $columns = $input['columns']; // array $batchRows = $input['batch_rows']; // array di righe (ognuna array di celle) $batchExcelrows = $input['batch_excelrows']; // array di excelrow paralleli a batchRows $user_id = $iduserlogin ?? 1; function normalizeColName($s): string { $s = (string)$s; $s = str_replace( ["\xC2\xA0", "\xE2\x80\xAF", "\xE2\x80\x87", "\xE2\x80\x89", "\xE2\x80\x8A", "\xEF\xBB\xBF"], ' ', $s ); $s = preg_replace('/\s+/u', ' ', $s); return trim((string)$s); } $db = DBHandlerSelect::getInstance(); $pdo = $db->getConnection(); // Recupera i mapping $stmt = $pdo->prepare("SELECT id, excel_column, data_type, has_list, 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)) { echo json_encode(['ok' => false, 'error' => 'Nessun mapping trovato per il template']); exit; } // idclient di default (una volta sola) $template_stmt = $pdo->prepare("SELECT idclient FROM excel_templates WHERE id = ?"); $template_stmt->execute([$template_id]); $tpl = $template_stmt->fetch(PDO::FETCH_ASSOC); $default_idclient = $tpl['idclient'] ?? null; // lims_user_id per il campo 244 (una volta sola) $stmtUser = $pdo->prepare("SELECT lims_user_id FROM auth_users WHERE id = ? LIMIT 1"); $stmtUser->execute([(int)$user_id]); $limsUserId = $stmtUser->fetchColumn(); $limsUserId = ($limsUserId !== false && $limsUserId !== null && $limsUserId !== '') ? (string)$limsUserId : ''; $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(); $insertedIds = []; $fixedMappings = []; try { $fxStmt = $pdo->prepare( "SELECT id, fixed_field_key, data_type, default_value, default_source, excel_column FROM template_fixed_mapping WHERE template_id = ?" ); $fxStmt->execute([$template_id]); $fixedMappings = $fxStmt->fetchAll(PDO::FETCH_ASSOC); } catch (Exception $e) { error_log("[FIXED] lettura template_fixed_mapping fallita: " . $e->getMessage()); } $savedBindings = []; $autoBindings = []; $pendingBindings = []; try { $pdo->beginTransaction(); $insDatadb = $pdo->prepare("INSERT INTO datadb (templateid, importreferencecode, filename_import, status, user_id, limscode, importdate, excelrow, idclient) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); $insDetail = $pdo->prepare("INSERT INTO import_data_details (id, mapping_id, field_value) VALUES (?, ?, ?)"); foreach ($batchRows as $i => $row) { $excelrow = $batchExcelrows[$i] ?? null; if ($row === null || $excelrow === null) { continue; } $insDatadb->execute([ $template_id, $importReferenceCode, $newFilename, 'i', $user_id, null, date('Y-m-d'), $excelrow, $default_idclient ]); $iddatadb = $pdo->lastInsertId(); $insertedIds[] = $iddatadb; foreach ($allMappings as $mapping) { $fieldValue = null; if (!$mapping['is_manual']) { $excelColumn = trim($mapping['excel_column']); $excelColumnIndex = array_search( normalizeColName($excelColumn), array_map('normalizeColName', $columns) ); if ($excelColumnIndex !== false && isset($row[$excelColumnIndex]) && $row[$excelColumnIndex] !== '') { $fieldValue = $row[$excelColumnIndex]; } else { $fieldValue = $mapping['manual_default'] ?? ''; } 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'); } } 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 ( binding_is_list_field($mapping) && $fieldValue !== null && trim((string) $fieldValue) !== '' ) { $fieldValue = binding_resolve_for_import( $pdo, $mapping, $template_id, (string) $fieldValue, (int) $iddatadb, (int) $user_id, $savedBindings, $autoBindings, $pendingBindings ); } $insDetail->execute([$iddatadb, $mapping['id'], $fieldValue]); } $fixedValues = []; foreach ($fixedMappings as $fm) { $fixedKey = (string) $fm['fixed_field_key']; $value = null; if (($fm['default_source'] ?? 'manual') === 'xls' && trim((string) ($fm['excel_column'] ?? '')) !== '') { $idx = binding_find_column_index((string) $fm['excel_column'], $columns); $raw = ($idx !== false && isset($row[$idx])) ? trim((string) $row[$idx]) : ''; if ($raw !== '') { $value = binding_resolve_fixed_for_import( $pdo, $fm, (int) $template_id, $raw, (int) $iddatadb, (int) $user_id, $savedBindings, $autoBindings, $pendingBindings ); } } if ($value === null || $value === '') { $default = binding_fixed_default($fm); $value = $default !== '' ? $default : null; } if ($value !== null && $value !== '') { $fixedValues[$fixedKey] = $value; } } if (!empty($fixedValues)) { binding_write_fixed_columns($pdo, (int) $iddatadb, $fixedValues); } // Campo 244 (Accettatore) con lims_user_id if ($limsUserId !== '' && $mappingId244 > 0) { $insDetail->execute([$iddatadb, $mappingId244, $limsUserId]); } } $pdo->commit(); $state = $_SESSION['pending_bindings'] ?? null; if (!is_array($state) || ($state['importref'] ?? null) !== $importReferenceCode) { $state = [ 'template_id' => $template_id, 'importref' => $importReferenceCode, 'items' => [], 'auto' => [], 'saved' => [], ]; } $state['items'] = binding_merge_buckets($state['items'], $pendingBindings); $state['auto'] = binding_merge_buckets($state['auto'], $autoBindings); $state['saved'] = binding_merge_buckets($state['saved'], $savedBindings); $_SESSION['pending_bindings'] = $state; echo json_encode([ 'ok' => true, 'inserted' => count($insertedIds), 'pending_bindings' => count($state['items']) ]); exit; } catch (Exception $e) { if ($pdo->inTransaction()) $pdo->rollBack(); error_log("[BATCH IMPORT] " . $e->getMessage()); echo json_encode([ 'ok' => false, 'error' => $e->getMessage() ]); exit; }