fixed import xls
This commit is contained in:
parent
57ab20ed1f
commit
32c0966801
File diff suppressed because one or more lines are too long
@ -5,9 +5,11 @@ ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log', __DIR__ . '/import_debug.log');
|
||||
if (!file_exists(__DIR__ . '/import_debug.log')) {
|
||||
file_put_contents(__DIR__ . '/import_debug.log', "Inizio importazione alle " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
|
||||
// Test iniziale del log
|
||||
// Log iniziale
|
||||
error_log("Inizio importazione alle " . date('Y-m-d H:i:s'));
|
||||
|
||||
include('include/headscript.php');
|
||||
@ -37,8 +39,8 @@ $pdo = $db->getConnection();
|
||||
// Genera un UUID univoco per importreferencecode
|
||||
$importReferenceCode = date('YmdHis') . '-' . uniqid();
|
||||
|
||||
// Recupera tutti i mapping dal template (automatici e manuali)
|
||||
$stmt = $pdo->prepare("SELECT id, field_id, field_id AS excel_column, field_id AS mysql_column, data_type, is_required, manual_default, is_manual, field_label FROM template_mapping WHERE template_id = ?");
|
||||
// Recupera tutti i mapping dal template
|
||||
$stmt = $pdo->prepare("SELECT id, excel_column, data_type, is_required, manual_default, is_manual, field_label FROM template_mapping WHERE template_id = ?");
|
||||
$stmt->execute([$template_id]);
|
||||
$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
@ -47,87 +49,20 @@ if (empty($allMappings)) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Separa i mapping automatici (is_manual = 0) da quelli manuali (is_manual = 1)
|
||||
$autoMappings = array_filter($allMappings, fn($m) => !$m['is_manual']);
|
||||
$manualMappings = array_filter($allMappings, fn($m) => $m['is_manual']);
|
||||
|
||||
// Inserisci le righe selezionate in datadb
|
||||
// Inserisci le righe selezionate in datadb (solo campi generici con templateid)
|
||||
$insertedIds = [];
|
||||
foreach ($selected_rows as $rowIndex) {
|
||||
$row = $rows[$rowIndex];
|
||||
$values = [];
|
||||
$placeholders = [];
|
||||
$columnsToInsert = [];
|
||||
|
||||
// Aggiungi i campi mappati dall'XLS (automatici)
|
||||
foreach ($autoMappings as $mapping) {
|
||||
$excelColumnIndex = array_search(trim($mapping['excel_column']), array_map('trim', $columns));
|
||||
if ($excelColumnIndex !== false) {
|
||||
$mysqlColumn = $mapping['mysql_column'];
|
||||
$value = $row[$excelColumnIndex] ?? $mapping['manual_default'];
|
||||
|
||||
if ($mapping['is_required'] && (is_null($value) || $value === '')) {
|
||||
$value = $mapping['manual_default'];
|
||||
if (is_null($value)) {
|
||||
header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Valore richiesto mancante per la colonna $mysqlColumn"));
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($mapping['data_type']) {
|
||||
case 'INT':
|
||||
$value = is_numeric($value) ? (int)$value : ($mapping['manual_default'] ?? 0);
|
||||
break;
|
||||
case 'DATE':
|
||||
$value = !empty($value) ? date('Y-m-d', strtotime($value)) : ($mapping['manual_default'] ?? null);
|
||||
if ($mapping['manual_default'] === 'today' && is_null($value)) {
|
||||
$value = date('Y-m-d');
|
||||
}
|
||||
break;
|
||||
case 'CHAR':
|
||||
$value = !empty($value) ? substr($value, 0, 1) : ($mapping['manual_default'] ?? '');
|
||||
break;
|
||||
case 'Testo':
|
||||
case 'VARCHAR':
|
||||
default:
|
||||
$value = !empty($value) ? htmlspecialchars($value) : ($mapping['manual_default'] ?? '');
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_null($value)) {
|
||||
$columnsToInsert[] = $mysqlColumn;
|
||||
$placeholders[] = '?';
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Aggiungi i campi generici
|
||||
$columnsToInsert[] = 'importreferencecode';
|
||||
$placeholders[] = '?';
|
||||
$values[] = $importReferenceCode;
|
||||
|
||||
$columnsToInsert[] = 'filename_import';
|
||||
$placeholders[] = '?';
|
||||
$values[] = $newFilename;
|
||||
|
||||
$columnsToInsert[] = 'status';
|
||||
$placeholders[] = '?';
|
||||
$values[] = 'i';
|
||||
|
||||
$columnsToInsert[] = 'user_id';
|
||||
$placeholders[] = '?';
|
||||
$values[] = $user_id;
|
||||
|
||||
$columnsToInsert[] = 'limscode';
|
||||
$placeholders[] = '?';
|
||||
$values[] = null;
|
||||
|
||||
$columnsToInsert[] = 'importdate';
|
||||
$placeholders[] = '?';
|
||||
$values[] = date('Y-m-d');
|
||||
|
||||
$sql = "INSERT INTO datadb (" . implode(', ', $columnsToInsert) . ") VALUES (" . implode(', ', $placeholders) . ")";
|
||||
$values = [
|
||||
$template_id, // templateid
|
||||
$importReferenceCode, // importreferencecode
|
||||
$newFilename, // filename_import
|
||||
'i', // status
|
||||
$user_id, // user_id
|
||||
null, // limscode
|
||||
date('Y-m-d') // importdate
|
||||
];
|
||||
$sql = "INSERT INTO datadb (templateid, importreferencecode, filename_import, status, user_id, limscode, importdate) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($values);
|
||||
|
||||
@ -191,7 +126,7 @@ $importedData = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Recupera i dettagli manuali da import_data_details
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT d.id AS detail_id, d.id AS datadb_id, d.mapping_id, d.field_value, m.field_id, m.data_type, m.is_required, m.manual_default
|
||||
SELECT d.id AS detail_id, d.id AS datadb_id, d.mapping_id, d.field_value, m.field_label, m.data_type, m.is_required, m.manual_default
|
||||
FROM import_data_details d
|
||||
JOIN template_mapping m ON d.mapping_id = m.id
|
||||
WHERE d.id IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ")
|
||||
@ -283,7 +218,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
.grid-cell select {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: гордичка 1px solid #ced4da;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
@ -447,43 +382,36 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
<div class="grid-cell" style="flex: 0 0 100px;"></div> <!-- Photos -->
|
||||
<div class="grid-cell" style="flex: 0 0 100px;"></div> <!-- Parts -->
|
||||
<?php
|
||||
$headerIndex = 0;
|
||||
// Colonne fisse di datadb (fino a importdate)
|
||||
$fixedColumns = ['importreferencecode', 'filename_import', 'status', 'user_id', 'limscode', 'importdate'];
|
||||
$fixedColumns = ['importreferencecode', 'filename_import', 'status', 'importdate'];
|
||||
foreach ($fixedColumns as $col) {
|
||||
$visible = !in_array($col, ['limscode', 'user_id']); // Nascondi limscode e user_id
|
||||
if ($visible) {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
}
|
||||
// Aggiungi spazi vuoti per i campi automatici (senza propagate-btn)
|
||||
foreach ($autoMappings as $autoMapping) {
|
||||
// Solo campi manuali (is_manual = 1) con propagate-btn
|
||||
$manualIndex = 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual']) {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
// Aggiungi gli input per i campi manuali con propagate-btn
|
||||
foreach ($manualMappings as $manualMapping) {
|
||||
$fieldValue = $manualMapping['manual_default'];
|
||||
if ($manualMapping['data_type'] === 'DATE' && $manualMapping['manual_default'] === 'today') {
|
||||
} else {
|
||||
$fieldValue = $mapping['manual_default'] ?? '';
|
||||
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
$requiredAttr = $manualMapping['is_required'] ? 'required' : '';
|
||||
$requiredAttr = $mapping['is_required'] ? 'required' : '';
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
if ($manualMapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' class='custom-field' data-column='$headerIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
} elseif ($manualMapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' class='custom-field' data-column='$headerIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
if ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' class='custom-field' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' class='custom-field' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
} else {
|
||||
echo "<input type='text' class='custom-field' data-column='$headerIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
echo "<input type='text' class='custom-field' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||
}
|
||||
echo "<button type='button' class='propagate-btn' data-column='$headerIndex'><i class='fas fa-arrow-down'></i></button>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex'><i class='fas fa-arrow-down'></i></button>";
|
||||
echo "</div>";
|
||||
$headerIndex++;
|
||||
$manualIndex++;
|
||||
}
|
||||
// Spazi per AWB e Tracking Info
|
||||
echo "<div class='grid-cell' style='flex: 0 0 200px;'></div>";
|
||||
echo "<div class='grid-cell' style='flex: 0 0 250px;'></div>";
|
||||
}
|
||||
echo "<div class='grid-cell' style='flex: 0 0 200px;'></div>"; // AWB
|
||||
echo "<div class='grid-cell' style='flex: 0 0 250px;'></div>"; // Tracking Info
|
||||
?>
|
||||
</div>
|
||||
|
||||
@ -496,27 +424,16 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
$headerIndex = 0;
|
||||
foreach ($fixedColumns as $col) {
|
||||
$displayName = $slugMapping[$col] ?? $col;
|
||||
$visible = !in_array($col, ['limscode', 'user_id']); // Nascondi limscode e user_id
|
||||
if ($visible) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>$displayName<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
}
|
||||
// Prima i campi automatici (excel_column non vuoto)
|
||||
foreach ($autoMappings as $mapping) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
// Poi i campi manuali
|
||||
foreach ($manualMappings as $mapping) {
|
||||
foreach ($allMappings as $mapping) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 200px; position: relative;'>AWB Number<div class='resizer'></div></div>";
|
||||
echo "<div class='grid-header' data-index='" . ($headerIndex + 1) . "' style='flex: 0 0 250px; position: relative;'>Tracking Info<div class='resizer'></div></div>";
|
||||
?>
|
||||
<div class="grid-header" data-index="<?= $headerIndex ?>" style="flex: 0 0 200px; position: relative;">AWB Number<div class="resizer"></div>
|
||||
</div>
|
||||
<div class="grid-header" data-index="<?= $headerIndex + 1 ?>" style="flex: 0 0 250px; position: relative;">Tracking Info<div class="resizer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Righe della tabella -->
|
||||
@ -534,8 +451,6 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
<?php
|
||||
$cellIndex = 0;
|
||||
foreach ($fixedColumns as $col) {
|
||||
$visible = !in_array($col, ['limscode', 'user_id']);
|
||||
if ($visible) {
|
||||
$value = $row[$col] ?? '';
|
||||
echo "<div class='grid-cell editable-cell' data-col='$col' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($col === 'importdate') {
|
||||
@ -547,46 +462,24 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
} elseif ($col === 'status') {
|
||||
echo "<span class='status-display status-" . htmlspecialchars($value ?? 'i') . "'>" . htmlspecialchars($value === 'i' ? 'Imported' : ($value === 'P' ? 'Progress' : 'LIMS')) . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value ?? 'i') . "'>";
|
||||
} elseif ($col === 'user_id') {
|
||||
echo "<span>" . htmlspecialchars($row['user_name'] ?? 'Utente Sconosciuto') . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
|
||||
} else {
|
||||
echo "<input type='text' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "' class='cell-input'>";
|
||||
}
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
}
|
||||
}
|
||||
// Aggiungi i campi automatici da import_data_details
|
||||
$rowDetails = array_filter($manualDetails, fn($d) => $d['datadb_id'] == $row['iddatadb']);
|
||||
foreach ($autoMappings as $mapping) {
|
||||
$manualIndex = 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
$detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']);
|
||||
$detail = reset($detail) ?: ['field_value' => $mapping['manual_default']];
|
||||
$fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? '';
|
||||
$requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : '';
|
||||
$requiredAttr = $mapping['is_required'] ? 'required' : '';
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='{$mapping['field_id']}' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
} else {
|
||||
echo "<input type='text' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
}
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
}
|
||||
// Aggiungi i campi manuali da import_data_details
|
||||
foreach ($manualMappings as $mapping) {
|
||||
$detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']);
|
||||
$detail = reset($detail) ?: ['field_value' => $mapping['manual_default']];
|
||||
$fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? '';
|
||||
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today' && empty($fieldValue)) {
|
||||
if ($mapping['is_manual'] && $mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today' && empty($fieldValue)) {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
$requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : '';
|
||||
$requiredAttr = $mapping['is_required'] ? 'required' : '';
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='{$mapping['field_id']}' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='manual_$manualIndex' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
@ -596,9 +489,9 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
}
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
if ($mapping['is_manual']) $manualIndex++;
|
||||
}
|
||||
?>
|
||||
<!-- Colonna AWB con tendina -->
|
||||
<div class="grid-cell" style="flex: 0 0 200px;">
|
||||
<select name="rows[<?= $index ?>][carrier]" class="carrier-select">
|
||||
<option value="tnt-it">TNT Italy</option>
|
||||
@ -647,7 +540,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
|
||||
const saveButtons = document.querySelectorAll('.save-btn');
|
||||
saveButtons.forEach(button => {
|
||||
button.addEventListener('click', functionтии) {
|
||||
button.addEventListener('click', function() {
|
||||
const rowIndex = this.getAttribute('data-row');
|
||||
const row = this.closest('.grid-row');
|
||||
const iddatadb = row.getAttribute('data-id');
|
||||
@ -656,9 +549,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
const inputs = row.querySelectorAll(`input[name^="rows[${rowIndex}]"], select[name^="rows[${rowIndex}]"]`);
|
||||
inputs.forEach(input => {
|
||||
const name = input.name.replace(`rows[${rowIndex}]`, '').replace(/\[|\]/g, '');
|
||||
if (name !== 'user_name') {
|
||||
formData.append(name, input.value);
|
||||
}
|
||||
});
|
||||
formData.append('iddatadb', iddatadb);
|
||||
|
||||
@ -684,35 +575,42 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
});
|
||||
});
|
||||
|
||||
// Propagazione del valore dall'input superiore
|
||||
const propagateButtons = document.querySelectorAll('.propagate-btn'); propagateButtons.forEach(button => {
|
||||
const propagateButtons = document.querySelectorAll('.propagate-btn');
|
||||
propagateButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const columnIndex = this.getAttribute('data-column');
|
||||
const columnIndex = this.getAttribute('data-column').replace('manual_', '');
|
||||
const input = this.previousElementSibling;
|
||||
const value = input.value;
|
||||
|
||||
const cells = document.querySelectorAll(`.grid-cell[data-index="${columnIndex}"]`);
|
||||
cells.forEach(cell => {
|
||||
const rowInput = cell.querySelector('input, select');
|
||||
if (rowInput) {
|
||||
if (rowInput.type === 'date') {
|
||||
rowInput.value = value;
|
||||
} else if (rowInput.tagName === 'SELECT') {
|
||||
rowInput.value = value;
|
||||
} else {
|
||||
rowInput.value = value;
|
||||
// Trova la colonna target nella griglia superiore e propaga solo verticalmente
|
||||
const gridTopCells = document.querySelector('.grid-top').querySelectorAll('.grid-cell');
|
||||
const targetTopIndex = Array.from(gridTopCells).findIndex(cell =>
|
||||
cell.querySelector('.propagate-btn') === button
|
||||
);
|
||||
|
||||
if (targetTopIndex !== -1) {
|
||||
const rows = document.querySelectorAll('.grid-row');
|
||||
rows.forEach(row => {
|
||||
const cells = row.querySelectorAll('.grid-cell');
|
||||
if (cells.length > targetTopIndex) {
|
||||
const targetInput = cells[targetTopIndex].querySelector('input, select');
|
||||
if (targetInput) {
|
||||
if (targetInput.type === 'date') targetInput.value = value;
|
||||
else if (targetInput.tagName === 'SELECT') targetInput.value = value;
|
||||
else targetInput.value = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Ridimensionamento colonne
|
||||
const resizers = document.querySelectorAll('.resizer');
|
||||
let currentResizer = null;
|
||||
let startX = 0;
|
||||
let startWidth = 0;
|
||||
let columnIndex = 0; resizers.forEach(resizer => {
|
||||
let columnIndex = 0;
|
||||
resizers.forEach(resizer => {
|
||||
resizer.addEventListener('mousedown', function(e) {
|
||||
currentResizer = resizer;
|
||||
const header = resizer.parentElement;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user