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);
|
error_reporting(E_ALL);
|
||||||
ini_set('log_errors', 1);
|
ini_set('log_errors', 1);
|
||||||
ini_set('error_log', __DIR__ . '/import_debug.log');
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log iniziale
|
||||||
// Test iniziale del log
|
|
||||||
error_log("Inizio importazione alle " . date('Y-m-d H:i:s'));
|
error_log("Inizio importazione alle " . date('Y-m-d H:i:s'));
|
||||||
|
|
||||||
include('include/headscript.php');
|
include('include/headscript.php');
|
||||||
@ -37,8 +39,8 @@ $pdo = $db->getConnection();
|
|||||||
// Genera un UUID univoco per importreferencecode
|
// Genera un UUID univoco per importreferencecode
|
||||||
$importReferenceCode = date('YmdHis') . '-' . uniqid();
|
$importReferenceCode = date('YmdHis') . '-' . uniqid();
|
||||||
|
|
||||||
// Recupera tutti i mapping dal template (automatici e manuali)
|
// Recupera tutti i mapping dal template
|
||||||
$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 = ?");
|
$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]);
|
$stmt->execute([$template_id]);
|
||||||
$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
@ -47,87 +49,20 @@ if (empty($allMappings)) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Separa i mapping automatici (is_manual = 0) da quelli manuali (is_manual = 1)
|
// Inserisci le righe selezionate in datadb (solo campi generici con templateid)
|
||||||
$autoMappings = array_filter($allMappings, fn($m) => !$m['is_manual']);
|
|
||||||
$manualMappings = array_filter($allMappings, fn($m) => $m['is_manual']);
|
|
||||||
|
|
||||||
// Inserisci le righe selezionate in datadb
|
|
||||||
$insertedIds = [];
|
$insertedIds = [];
|
||||||
foreach ($selected_rows as $rowIndex) {
|
foreach ($selected_rows as $rowIndex) {
|
||||||
$row = $rows[$rowIndex];
|
$row = $rows[$rowIndex];
|
||||||
$values = [];
|
$values = [
|
||||||
$placeholders = [];
|
$template_id, // templateid
|
||||||
$columnsToInsert = [];
|
$importReferenceCode, // importreferencecode
|
||||||
|
$newFilename, // filename_import
|
||||||
// Aggiungi i campi mappati dall'XLS (automatici)
|
'i', // status
|
||||||
foreach ($autoMappings as $mapping) {
|
$user_id, // user_id
|
||||||
$excelColumnIndex = array_search(trim($mapping['excel_column']), array_map('trim', $columns));
|
null, // limscode
|
||||||
if ($excelColumnIndex !== false) {
|
date('Y-m-d') // importdate
|
||||||
$mysqlColumn = $mapping['mysql_column'];
|
];
|
||||||
$value = $row[$excelColumnIndex] ?? $mapping['manual_default'];
|
$sql = "INSERT INTO datadb (templateid, importreferencecode, filename_import, status, user_id, limscode, importdate) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
|
||||||
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) . ")";
|
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
$stmt->execute($values);
|
$stmt->execute($values);
|
||||||
|
|
||||||
@ -191,7 +126,7 @@ $importedData = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
|
|
||||||
// Recupera i dettagli manuali da import_data_details
|
// Recupera i dettagli manuali da import_data_details
|
||||||
$stmt = $pdo->prepare("
|
$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
|
FROM import_data_details d
|
||||||
JOIN template_mapping m ON d.mapping_id = m.id
|
JOIN template_mapping m ON d.mapping_id = m.id
|
||||||
WHERE d.id IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ")
|
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 {
|
.grid-cell select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: гордичка 1px solid #ced4da;
|
border: 1px solid #ced4da;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
font-size: 14px;
|
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> <!-- Photos -->
|
||||||
<div class="grid-cell" style="flex: 0 0 100px;"></div> <!-- Parts -->
|
<div class="grid-cell" style="flex: 0 0 100px;"></div> <!-- Parts -->
|
||||||
<?php
|
<?php
|
||||||
$headerIndex = 0;
|
$fixedColumns = ['importreferencecode', 'filename_import', 'status', 'importdate'];
|
||||||
// Colonne fisse di datadb (fino a importdate)
|
|
||||||
$fixedColumns = ['importreferencecode', 'filename_import', 'status', 'user_id', 'limscode', 'importdate'];
|
|
||||||
foreach ($fixedColumns as $col) {
|
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) {
|
|
||||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||||
$headerIndex++;
|
|
||||||
}
|
}
|
||||||
// Aggiungi gli input per i campi manuali con propagate-btn
|
// Solo campi manuali (is_manual = 1) con propagate-btn
|
||||||
foreach ($manualMappings as $manualMapping) {
|
$manualIndex = 0;
|
||||||
$fieldValue = $manualMapping['manual_default'];
|
foreach ($allMappings as $mapping) {
|
||||||
if ($manualMapping['data_type'] === 'DATE' && $manualMapping['manual_default'] === 'today') {
|
if (!$mapping['is_manual']) {
|
||||||
$fieldValue = date('Y-m-d');
|
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||||
}
|
|
||||||
$requiredAttr = $manualMapping['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>";
|
|
||||||
} else {
|
} else {
|
||||||
echo "<input type='text' class='custom-field' data-column='$headerIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
$fieldValue = $mapping['manual_default'] ?? '';
|
||||||
|
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') {
|
||||||
|
$fieldValue = date('Y-m-d');
|
||||||
|
}
|
||||||
|
$requiredAttr = $mapping['is_required'] ? 'required' : '';
|
||||||
|
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||||
|
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='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
|
||||||
|
}
|
||||||
|
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex'><i class='fas fa-arrow-down'></i></button>";
|
||||||
|
echo "</div>";
|
||||||
|
$manualIndex++;
|
||||||
}
|
}
|
||||||
echo "<button type='button' class='propagate-btn' data-column='$headerIndex'><i class='fas fa-arrow-down'></i></button>";
|
|
||||||
echo "</div>";
|
|
||||||
$headerIndex++;
|
|
||||||
}
|
}
|
||||||
// Spazi per AWB e Tracking Info
|
echo "<div class='grid-cell' style='flex: 0 0 200px;'></div>"; // AWB
|
||||||
echo "<div class='grid-cell' style='flex: 0 0 200px;'></div>";
|
echo "<div class='grid-cell' style='flex: 0 0 250px;'></div>"; // Tracking Info
|
||||||
echo "<div class='grid-cell' style='flex: 0 0 250px;'></div>";
|
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -496,27 +424,16 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
|||||||
$headerIndex = 0;
|
$headerIndex = 0;
|
||||||
foreach ($fixedColumns as $col) {
|
foreach ($fixedColumns as $col) {
|
||||||
$displayName = $slugMapping[$col] ?? $col;
|
$displayName = $slugMapping[$col] ?? $col;
|
||||||
$visible = !in_array($col, ['limscode', 'user_id']); // Nascondi limscode e user_id
|
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>$displayName<div class='resizer'></div></div>";
|
||||||
if ($visible) {
|
$headerIndex++;
|
||||||
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 ($allMappings as $mapping) {
|
||||||
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) {
|
|
||||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
|
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++;
|
$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>
|
</div>
|
||||||
|
|
||||||
<!-- Righe della tabella -->
|
<!-- Righe della tabella -->
|
||||||
@ -534,59 +451,35 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
|||||||
<?php
|
<?php
|
||||||
$cellIndex = 0;
|
$cellIndex = 0;
|
||||||
foreach ($fixedColumns as $col) {
|
foreach ($fixedColumns as $col) {
|
||||||
$visible = !in_array($col, ['limscode', 'user_id']);
|
$value = $row[$col] ?? '';
|
||||||
if ($visible) {
|
echo "<div class='grid-cell editable-cell' data-col='$col' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||||
$value = $row[$col] ?? '';
|
if ($col === 'importdate') {
|
||||||
echo "<div class='grid-cell editable-cell' data-col='$col' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
echo "<span>" . htmlspecialchars($value) . "</span>";
|
||||||
if ($col === 'importdate') {
|
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
|
||||||
echo "<span>" . htmlspecialchars($value) . "</span>";
|
} elseif ($col === 'filename_import') {
|
||||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
|
echo "<a href='imported_trf/" . htmlspecialchars($value) . "' target='_blank'>File</a>";
|
||||||
} elseif ($col === 'filename_import') {
|
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
|
||||||
echo "<a href='imported_trf/" . htmlspecialchars($value) . "' target='_blank'>File</a>";
|
} elseif ($col === 'status') {
|
||||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
|
echo "<span class='status-display status-" . htmlspecialchars($value ?? 'i') . "'>" . htmlspecialchars($value === 'i' ? 'Imported' : ($value === 'P' ? 'Progress' : 'LIMS')) . "</span>";
|
||||||
} elseif ($col === 'status') {
|
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value ?? 'i') . "'>";
|
||||||
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) {
|
|
||||||
$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 {
|
} else {
|
||||||
echo "<input type='text' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
echo "<input type='text' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "' class='cell-input'>";
|
||||||
}
|
}
|
||||||
echo "</div>";
|
echo "</div>";
|
||||||
$cellIndex++;
|
$cellIndex++;
|
||||||
}
|
}
|
||||||
// Aggiungi i campi manuali da import_data_details
|
$rowDetails = array_filter($manualDetails, fn($d) => $d['datadb_id'] == $row['iddatadb']);
|
||||||
foreach ($manualMappings as $mapping) {
|
$manualIndex = 0;
|
||||||
|
foreach ($allMappings as $mapping) {
|
||||||
$detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']);
|
$detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']);
|
||||||
$detail = reset($detail) ?: ['field_value' => $mapping['manual_default']];
|
$detail = reset($detail) ?: ['field_value' => $mapping['manual_default']];
|
||||||
$fieldValue = $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');
|
$fieldValue = date('Y-m-d');
|
||||||
}
|
}
|
||||||
$requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : '';
|
$requiredClass = ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : '';
|
||||||
$requiredAttr = $mapping['is_required'] ? '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') {
|
if ($mapping['data_type'] === 'DATE') {
|
||||||
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
echo "<input type='date' name='rows[$index][details][{$mapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input' $requiredAttr>";
|
||||||
} elseif ($mapping['data_type'] === 'INT') {
|
} elseif ($mapping['data_type'] === 'INT') {
|
||||||
@ -596,9 +489,9 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
|||||||
}
|
}
|
||||||
echo "</div>";
|
echo "</div>";
|
||||||
$cellIndex++;
|
$cellIndex++;
|
||||||
|
if ($mapping['is_manual']) $manualIndex++;
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<!-- Colonna AWB con tendina -->
|
|
||||||
<div class="grid-cell" style="flex: 0 0 200px;">
|
<div class="grid-cell" style="flex: 0 0 200px;">
|
||||||
<select name="rows[<?= $index ?>][carrier]" class="carrier-select">
|
<select name="rows[<?= $index ?>][carrier]" class="carrier-select">
|
||||||
<option value="tnt-it">TNT Italy</option>
|
<option value="tnt-it">TNT Italy</option>
|
||||||
@ -647,101 +540,106 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
|||||||
|
|
||||||
const saveButtons = document.querySelectorAll('.save-btn');
|
const saveButtons = document.querySelectorAll('.save-btn');
|
||||||
saveButtons.forEach(button => {
|
saveButtons.forEach(button => {
|
||||||
button.addEventListener('click', functionтии) {
|
button.addEventListener('click', function() {
|
||||||
const rowIndex = this.getAttribute('data-row');
|
const rowIndex = this.getAttribute('data-row');
|
||||||
const row = this.closest('.grid-row');
|
const row = this.closest('.grid-row');
|
||||||
const iddatadb = row.getAttribute('data-id');
|
const iddatadb = row.getAttribute('data-id');
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
const inputs = row.querySelectorAll(`input[name^="rows[${rowIndex}]"], select[name^="rows[${rowIndex}]"]`);
|
const inputs = row.querySelectorAll(`input[name^="rows[${rowIndex}]"], select[name^="rows[${rowIndex}]"]`);
|
||||||
inputs.forEach(input => {
|
inputs.forEach(input => {
|
||||||
const name = input.name.replace(`rows[${rowIndex}]`, '').replace(/\[|\]/g, '');
|
const name = input.name.replace(`rows[${rowIndex}]`, '').replace(/\[|\]/g, '');
|
||||||
if (name !== 'user_name') {
|
formData.append(name, input.value);
|
||||||
formData.append(name, input.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
formData.append('iddatadb', iddatadb);
|
|
||||||
|
|
||||||
fetch('save_edited_row.php', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
const cells = row.querySelectorAll('.grid-cell');
|
|
||||||
cells.forEach(cell => {
|
|
||||||
cell.classList.remove('flash-success');
|
|
||||||
void cell.offsetWidth;
|
|
||||||
cell.classList.add('flash-success');
|
|
||||||
});
|
|
||||||
setTimeout(() => cells.forEach(cell => cell.classList.remove('flash-success')), 500);
|
|
||||||
} else {
|
|
||||||
alert('Errore durante il salvataggio: ' + data.message);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => alert('Errore durante il salvataggio: ' + error.message));
|
|
||||||
});
|
});
|
||||||
|
formData.append('iddatadb', iddatadb);
|
||||||
|
|
||||||
|
fetch('save_edited_row.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
const cells = row.querySelectorAll('.grid-cell');
|
||||||
|
cells.forEach(cell => {
|
||||||
|
cell.classList.remove('flash-success');
|
||||||
|
void cell.offsetWidth;
|
||||||
|
cell.classList.add('flash-success');
|
||||||
|
});
|
||||||
|
setTimeout(() => cells.forEach(cell => cell.classList.remove('flash-success')), 500);
|
||||||
|
} else {
|
||||||
|
alert('Errore durante il salvataggio: ' + data.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => alert('Errore durante il salvataggio: ' + error.message));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Propagazione del valore dall'input superiore
|
const propagateButtons = document.querySelectorAll('.propagate-btn');
|
||||||
const propagateButtons = document.querySelectorAll('.propagate-btn'); propagateButtons.forEach(button => {
|
propagateButtons.forEach(button => {
|
||||||
button.addEventListener('click', function() {
|
button.addEventListener('click', function() {
|
||||||
const columnIndex = this.getAttribute('data-column');
|
const columnIndex = this.getAttribute('data-column').replace('manual_', '');
|
||||||
const input = this.previousElementSibling;
|
const input = this.previousElementSibling;
|
||||||
const value = input.value;
|
const value = input.value;
|
||||||
|
|
||||||
const cells = document.querySelectorAll(`.grid-cell[data-index="${columnIndex}"]`);
|
// Trova la colonna target nella griglia superiore e propaga solo verticalmente
|
||||||
cells.forEach(cell => {
|
const gridTopCells = document.querySelector('.grid-top').querySelectorAll('.grid-cell');
|
||||||
const rowInput = cell.querySelector('input, select');
|
const targetTopIndex = Array.from(gridTopCells).findIndex(cell =>
|
||||||
if (rowInput) {
|
cell.querySelector('.propagate-btn') === button
|
||||||
if (rowInput.type === 'date') {
|
);
|
||||||
rowInput.value = value;
|
|
||||||
} else if (rowInput.tagName === 'SELECT') {
|
if (targetTopIndex !== -1) {
|
||||||
rowInput.value = value;
|
const rows = document.querySelectorAll('.grid-row');
|
||||||
} else {
|
rows.forEach(row => {
|
||||||
rowInput.value = value;
|
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');
|
||||||
const resizers = document.querySelectorAll('.resizer');
|
let currentResizer = null;
|
||||||
let currentResizer = null;
|
let startX = 0;
|
||||||
let startX = 0;
|
let startWidth = 0;
|
||||||
let startWidth = 0;
|
let columnIndex = 0;
|
||||||
let columnIndex = 0; resizers.forEach(resizer => {
|
resizers.forEach(resizer => {
|
||||||
resizer.addEventListener('mousedown', function(e) {
|
resizer.addEventListener('mousedown', function(e) {
|
||||||
currentResizer = resizer;
|
currentResizer = resizer;
|
||||||
const header = resizer.parentElement;
|
const header = resizer.parentElement;
|
||||||
columnIndex = header.getAttribute('data-index');
|
columnIndex = header.getAttribute('data-index');
|
||||||
startX = e.pageX;
|
startX = e.pageX;
|
||||||
startWidth = header.offsetWidth;
|
startWidth = header.offsetWidth;
|
||||||
document.addEventListener('mousemove', resize);
|
document.addEventListener('mousemove', resize);
|
||||||
document.addEventListener('mouseup', stopResize);
|
document.addEventListener('mouseup', stopResize);
|
||||||
|
});
|
||||||
|
|
||||||
|
function resize(e) {
|
||||||
|
if (currentResizer) {
|
||||||
|
const dx = e.pageX - startX;
|
||||||
|
const newWidth = startWidth + dx;
|
||||||
|
const headers = document.querySelectorAll(`.grid-header[data-index="${columnIndex}"]`);
|
||||||
|
const cells = document.querySelectorAll(`.grid-cell[data-index="${columnIndex}"]`);
|
||||||
|
headers.forEach(header => header.style.flex = `0 0 ${newWidth}px`);
|
||||||
|
cells.forEach(cell => cell.style.flex = `0 0 ${newWidth}px`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopResize() {
|
||||||
|
if (currentResizer) {
|
||||||
|
document.removeEventListener('mousemove', resize);
|
||||||
|
document.removeEventListener('mouseup', stopResize);
|
||||||
|
currentResizer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function resize(e) {
|
|
||||||
if (currentResizer) {
|
|
||||||
const dx = e.pageX - startX;
|
|
||||||
const newWidth = startWidth + dx;
|
|
||||||
const headers = document.querySelectorAll(`.grid-header[data-index="${columnIndex}"]`);
|
|
||||||
const cells = document.querySelectorAll(`.grid-cell[data-index="${columnIndex}"]`);
|
|
||||||
headers.forEach(header => header.style.flex = `0 0 ${newWidth}px`);
|
|
||||||
cells.forEach(cell => cell.style.flex = `0 0 ${newWidth}px`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopResize() {
|
|
||||||
if (currentResizer) {
|
|
||||||
document.removeEventListener('mousemove', resize);
|
|
||||||
document.removeEventListener('mouseup', stopResize);
|
|
||||||
currentResizer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
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