theloftstore/public/userarea/import_edit2 - bck080725.php
2025-07-08 21:03:33 +02:00

1072 lines
50 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// Abilita errori per debug
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Configura il log per Windows
ini_set('error_log', 'C:\\xampp\\htdocs\\trf_certest\\tmp\\import_debug.log');
ini_set('log_errors', 1);
// Test iniziale del log
error_log("Inizio importazione alle " . date('Y-m-d H:i:s'));
include('include/headscript.php');
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['template_id']) || !isset($_POST['selected_rows']) || !isset($_POST['filename'])) {
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Richiesta non valida"));
exit;
}
$template_id = intval($_POST['template_id']);
$selected_rows = $_POST['selected_rows'];
$columns = json_decode($_POST['columns'], true); // Header dell'XLS
$rows = json_decode($_POST['rows'], true); // Dati dell'XLS
$newFilename = htmlspecialchars($_POST['filename']);
// Log dei dati ricevuti
error_log("Received Data - Template ID: $template_id, Selected Rows: " . json_encode($selected_rows));
error_log("Columns: " . json_encode($columns));
error_log("Rows: " . json_encode($rows));
// Recupera l'ID dell'utente loggato
$user_id = $iduserlogin ?? 1; // Default a 1 se non definito
$db = DBHandlerSelect::getInstance();
$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 = ?");
$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;
}
// 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
$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) . ")";
$stmt = $pdo->prepare($sql);
$stmt->execute($values);
$iddatadb = $pdo->lastInsertId();
$insertedIds[] = $iddatadb;
// Inserisci tutti i campi (automatici e manuali) in import_data_details
foreach ($allMappings as $mapping) {
$fieldValue = '';
if (!$mapping['is_manual']) { // Campi automatici dall'XLS
$excelColumnIndex = array_search(trim($mapping['excel_column']), array_map('trim', $columns));
if ($excelColumnIndex !== false) {
$fieldValue = $row[$excelColumnIndex] ?? $mapping['manual_default'];
} 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'] ?? '');
if ($mapping['manual_default'] === 'today' && empty($fieldValue)) {
$fieldValue = date('Y-m-d');
}
break;
case 'CHAR':
$fieldValue = !empty($fieldValue) ? substr($fieldValue, 0, 1) : ($mapping['manual_default'] ?? '');
break;
case 'Testo':
case 'VARCHAR':
default:
$fieldValue = !empty($fieldValue) ? htmlspecialchars($fieldValue) : ($mapping['manual_default'] ?? '');
break;
}
} else { // Campi manuali
$fieldValue = $mapping['manual_default'] ?? '';
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') {
$fieldValue = date('Y-m-d');
} elseif (!empty($mapping['manual_default'])) {
$fieldValue = $mapping['manual_default'];
}
}
// Log dettagliato prima dell'inserimento
error_log("Inserting - 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]);
// Log della query eseguita
error_log("Executed Query for ID $iddatadb, Mapping ID: " . $mapping['id'] . ", Field Value: " . $fieldValue);
}
}
// Recupera i dati appena inseriti con i nomi degli utenti
$stmt = $pdo->prepare("
SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name
FROM datadb d
LEFT JOIN auth_users u ON d.user_id = u.id
WHERE d.iddatadb IN (" . implode(',', array_fill(0, count($insertedIds), '?')) . ")
");
$stmt->execute($insertedIds);
$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
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), '?')) . ")
");
$stmt->execute($insertedIds);
$manualDetails = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Recupera il mapping globale per mostrare gli slug leggibili
$stmt = $pdo->query("SELECT mysql_column_name, user_friendly_slug FROM column_mapping");
$slugMapping = [];
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
$slugMapping[$row['mysql_column_name']] = $row['user_friendly_slug'];
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2Lw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
.grid-container {
overflow-x: auto;
max-width: 100%;
margin-bottom: 20px;
border: 1px solid #dee2e6;
border-radius: 0.25rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.grid-row {
display: flex;
align-items: center;
padding: 0;
border-bottom: 1px solid #dee2e6;
}
.grid-row:last-child {
border-bottom: none;
}
.grid-row:nth-child(even) {
background-color: #f8f9fa;
}
.grid-row:hover {
background-color: #e9ecef;
}
.grid-header,
.grid-cell {
flex: 1;
min-width: 100px;
padding: 12px 15px;
border-right: 1px solid #dee2e6;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
transition: max-width 0.3s ease;
box-sizing: border-box;
}
.grid-header {
font-weight: 600;
background-color: #e9ecef;
color: #495057;
border-bottom: 2px solid #dee2e6;
position: relative;
}
.grid-header:last-child,
.grid-cell:last-child {
border-right: none;
}
.grid-cell.expanded {
max-width: 500px !important;
white-space: normal !important;
overflow-wrap: break-word !important;
background-color: #e0f7fa !important;
flex: 0 0 500px !important;
}
.grid-cell input,
.grid-cell select {
width: 100%;
box-sizing: border-box;
border: 1px solid #ced4da;
border-radius: 4px;
padding: 5px;
font-size: 14px;
}
.resizer {
width: 5px;
height: 100%;
background: #ddd;
cursor: col-resize;
position: absolute;
right: 0;
top: 0;
bottom: 0;
}
.resizer:hover {
background: #999;
}
.grid-top {
display: flex;
align-items: flex-start;
background-color: #f1f3f5;
padding: 10px 0;
border-bottom: 1px solid #dee2e6;
}
.grid-top .grid-cell {
padding: 5px 10px;
flex: 0 0 150px;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
}
.propagate-btn {
background: none;
border: none;
cursor: pointer;
color: #666;
font-size: 14px;
margin-top: 5px;
padding: 2px 5px;
border-radius: 3px;
transition: color 0.3s ease;
}
.propagate-btn:hover {
color: #28a745;
}
.awb-input {
width: 40% !important;
display: inline-block;
margin-right: 5px;
}
.carrier-select {
width: 40% !important;
display: inline-block;
border: 1px solid #ced4da;
border-radius: 4px;
padding: 5px;
font-size: 14px;
margin-right: 5px;
}
.go-btn {
width: 15% !important;
display: inline-block;
}
.tracking-info .tracking-result {
font-size: 12px;
color: #495057;
}
.modal {
display: none;
position: fixed;
z-index: 1050;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
}
#partsModal {
z-index: 1200 !important;
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
max-width: 600px;
border-radius: 8px;
position: relative;
}
.close-btn {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close-btn:hover,
.close-btn:focus {
color: #000;
text-decoration: none;
}
.photo-item {
transition: background-color 0.3s;
}
.photo-item:hover {
background-color: #f8f9fa;
}
#dropArea.highlight {
border-color: #28a745;
background-color: #e9ecef;
}
.image-modal {
display: none;
position: fixed;
z-index: 1100;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.8);
}
.image-modal-content {
margin: auto;
display: block;
max-width: 90%;
max-height: 90vh;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.image-modal-close {
position: absolute;
top: 15px;
right: 35px;
color: #fff;
font-size: 40px;
font-weight: bold;
cursor: pointer;
}
.image-modal-close:hover,
.image-modal-close:focus {
color: #bbb;
text-decoration: none;
}
.overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1049;
}
</style>
<title>Edit Imported Data - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<?php include('top_stat_widget.php'); ?>
<div class="card radius-10">
<div class="card-header">
<div class="d-flex align-items-center">
<div>
<h6 class="mb-0">Modifica Dati Importati</h6>
</div>
</div>
</div>
<div class="card-body">
<form id="editForm">
<div class="grid-container">
<!-- Riga superiore per gli input dei campi manuali -->
<div class="grid-top">
<div class="grid-cell" style="flex: 0 0 100px;"></div> <!-- Save -->
<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'];
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>";
$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') {
$fieldValue = date('Y-m-d');
}
$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 {
echo "<input type='text' class='custom-field' data-column='$headerIndex' value='" . htmlspecialchars($fieldValue) . "' $requiredAttr>";
}
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>";
echo "<div class='grid-cell' style='flex: 0 0 250px;'></div>";
?>
</div>
<!-- Header della tabella -->
<div class="grid-row">
<div class="grid-header" style="flex: 0 0 100px;">Save</div>
<div class="grid-header" style="flex: 0 0 100px;">Photos</div>
<div class="grid-header" style="flex: 0 0 100px;">Parts</div>
<?php
$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) {
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++;
}
?>
<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 -->
<?php foreach ($importedData as $index => $row): ?>
<div class="grid-row" data-id="<?= $row['iddatadb'] ?>">
<div class="grid-cell" style="flex: 0 0 100px; position: relative;">
<button type="button" class="save-btn" data-row="<?= $index ?>"><i class="fas fa-save"></i></button>
</div>
<div class="grid-cell" style="flex: 0 0 100px; position: relative;">
<button type="button" class="photos-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>"><i class="fas fa-camera"></i></button>
</div>
<div class="grid-cell" style="flex: 0 0 100px; position: relative;">
<button type="button" class="parts-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>"><i class="fas fa-puzzle-piece"></i></button>
</div>
<?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') {
echo "<span>" . htmlspecialchars($value) . "</span>";
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
} elseif ($col === 'filename_import') {
echo "<a href='imported_trf/" . htmlspecialchars($value) . "' target='_blank'>File</a>";
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
} 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) {
$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'];
$requiredAttr = $mapping['is_required'] ? 'required' : '';
echo "<div class='grid-cell editable-cell' 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)) {
$fieldValue = date('Y-m-d');
}
$requiredAttr = $mapping['is_required'] ? 'required' : '';
echo "<div class='grid-cell editable-cell' 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++;
}
?>
<!-- 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>
<option value="dhl">DHL</option>
<option value="gls">GLS</option>
<option value="sda">SDA</option>
<option value="ups">UPS</option>
</select>
<input type="text" name="rows[<?= $index ?>][awb_number]" class="cell-input awb-input" placeholder="Inserisci AWB Number">
<button type="button" class="go-btn" data-row="<?= $index ?>"><i class="fas fa-play"></i></button>
</div>
<div class="grid-cell tracking-info" data-row="<?= $index ?>" style="flex: 0 0 250px;">
<span class="tracking-result">Shipment Info</span>
<input type="hidden" name="rows[<?= $index ?>][tracking_info]" class="tracking-hidden">
</div>
</div>
<?php endforeach; ?>
</div>
</form>
<?php include 'modal_parts.php'; ?>
<div id="photosModal" class="modal">
<div class="modal-content">
<span class="close-btn">×</span>
<div id="popupContent">
<p>Loading...</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="overlay toggle-icon"></div>
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
<?php include('include/footer.php'); ?>
</div>
<?php include('jsinclude.php'); ?>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="parts.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
const inputs = document.querySelectorAll('.cell-input');
inputs.forEach(input => {
input.addEventListener('focus', function() {
this.closest('.grid-cell').classList.add('expanded');
});
input.addEventListener('blur', function() {
this.closest('.grid-cell').classList.remove('expanded');
});
});
const saveButtons = document.querySelectorAll('.save-btn');
saveButtons.forEach(button => {
button.addEventListener('click', function() {
const rowIndex = this.getAttribute('data-row');
const row = this.closest('.grid-row');
const iddatadb = row.getAttribute('data-id');
const formData = new FormData();
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);
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');
propagateButtons.forEach(button => {
button.addEventListener('click', function() {
const columnIndex = this.getAttribute('data-column');
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;
}
}
});
});
});
// Ridimensionamento colonne
const resizers = document.querySelectorAll('.resizer');
let currentResizer = null;
let startX = 0;
let startWidth = 0;
let columnIndex = 0;
resizers.forEach(resizer => {
resizer.addEventListener('mousedown', function(e) {
currentResizer = resizer;
const header = resizer.parentElement;
columnIndex = header.getAttribute('data-index');
startX = e.pageX;
startWidth = header.offsetWidth;
document.addEventListener('mousemove', resize);
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;
}
}
});
// Gestione del popup per le foto
async function loadPopupContent(iddatadb) {
const popupContent = document.getElementById('popupContent');
try {
const response = await fetch(`photos_popup.php?iddatadb=${iddatadb}`);
popupContent.innerHTML = await response.text();
// Dopo aver caricato il contenuto, associa gli event listener
attachPhotoEventListeners(iddatadb);
} catch (error) {
popupContent.innerHTML = `<p>Errore durante il caricamento: ${error.message}</p>`;
}
}
function attachPhotoEventListeners(iddatadb) {
const dropArea = document.getElementById('dropArea');
const photoInput = document.getElementById('photoInput');
if (!dropArea || !photoInput) {
console.error('Elementi dropArea o photoInput non trovati nel DOM');
return;
}
console.log('Associando event listener per drag-and-drop'); // Debug
// Gestione drag-and-drop
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(eventName => {
dropArea.addEventListener(eventName, () => {
console.log('Drag enter/over'); // Debug
dropArea.classList.add('highlight');
}, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, () => {
console.log('Drag leave/drop'); // Debug
dropArea.classList.remove('highlight');
}, false);
});
dropArea.addEventListener('drop', (e) => {
console.log('File droppato'); // Debug
const files = e.dataTransfer.files;
handleFiles(files, iddatadb);
}, false);
dropArea.addEventListener('click', () => {
console.log('Click su dropArea'); // Debug
photoInput.click();
}, false);
photoInput.addEventListener('change', () => {
console.log('File selezionato tramite input'); // Debug
handleFiles(photoInput.files, iddatadb);
}, false);
// Gestione della rimozione delle foto
const deleteButtons = document.querySelectorAll('.delete-photo-btn');
deleteButtons.forEach(button => {
button.addEventListener('click', async function() {
const photoId = this.getAttribute('data-photo-id');
if (confirm('Sei sicuro di voler eliminare questa foto?')) {
try {
const response = await fetch('delete_photo.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `photo_id=${photoId}`
});
const result = await response.json();
if (result.success) {
// Ricarica il contenuto del popup
loadPopupContent(iddatadb);
} else {
alert('Errore durante l\'eliminazione: ' + result.message);
}
} catch (error) {
alert('Errore durante l\'eliminazione: ' + error.message);
}
}
});
});
// Gestione del click sulle immagini per ingrandirle
document.querySelectorAll('.thumbnail').forEach(img => {
img.addEventListener('click', function() {
const modal = document.getElementById('imageModal');
const enlargedImage = document.getElementById('enlargedImage');
enlargedImage.src = this.src;
modal.style.display = 'block';
});
});
// Gestione della chiusura del modal immagine
const imageModal = document.getElementById('imageModal');
const imageCloseBtn = document.querySelector('.image-modal-close');
if (imageCloseBtn) {
imageCloseBtn.addEventListener('click', function() {
imageModal.style.display = 'none';
});
}
if (imageModal) {
imageModal.addEventListener('click', function(event) {
if (event.target === imageModal) {
imageModal.style.display = 'none';
}
});
}
}
async function handleFiles(files, iddatadb) {
for (const file of files) {
if (!file.type.startsWith('image/')) {
alert('Per favore, carica solo immagini!');
continue;
}
const formData = new FormData();
formData.append('photo', file);
formData.append('iddatadb', iddatadb);
try {
const response = await fetch('upload_photo.php', {
method: 'POST',
body: formData
});
const result = await response.json();
if (result.success) {
// Ricarica il contenuto del popup
loadPopupContent(iddatadb);
} else {
alert('Errore durante il caricamento: ' + result.message);
}
} catch (error) {
alert('Errore durante il caricamento: ' + error.message);
}
}
}
// Gestione del popup per le foto
const photosButtons = document.querySelectorAll('.photos-btn');
const photosModal = document.getElementById('photosModal');
const closeBtn = document.querySelector('.close-btn');
photosButtons.forEach(button => {
button.addEventListener('click', function() {
const iddatadb = this.getAttribute('data-iddatadb');
loadPopupContent(iddatadb);
photosModal.style.display = 'block';
document.querySelector('.overlay').style.display = 'none'; // Nascondi overlay
});
});
if (closeBtn) {
closeBtn.addEventListener('click', function() {
photosModal.style.display = 'none';
document.querySelector('.overlay').style.display = 'none'; // Assicurati che l'overlay sia nascosto
// Forza la riattivazione della pagina sottostante
document.body.style.pointerEvents = 'auto';
});
}
if (photosModal) {
window.addEventListener('click', function(event) {
if (event.target === photosModal) {
photosModal.style.display = 'none';
document.querySelector('.overlay').style.display = 'none'; // Nascondi overlay
document.body.style.pointerEvents = 'auto'; // Riattiva la pagina
}
});
}
// Gestione del popup per le parti
const partsButtons = document.querySelectorAll('.parts-btn');
const partsModal = document.getElementById('partsModal');
partsButtons.forEach(button => {
button.addEventListener('click', function() {
const iddatadb = this.getAttribute('data-iddatadb');
// Carica il contenuto del modal Parts (da parts.js o altro)
if (partsModal) {
partsModal.style.display = 'block';
document.querySelector('.overlay').style.display = 'none'; // Nascondi overlay
// Assicurati che parts.js gestisca il contenuto specifico
} else {
console.error('Modal Parts non trovato');
}
});
});
// Gestione della chiusura del modal Parts
const partsCloseBtn = document.querySelector('#partsModal .close-btn');
if (partsCloseBtn) {
partsCloseBtn.addEventListener('click', function() {
partsModal.style.display = 'none';
document.querySelector('.overlay').style.display = 'none'; // Nascondi overlay
document.body.style.pointerEvents = 'auto'; // Riattiva la pagina
});
}
if (partsModal) {
window.addEventListener('click', function(event) {
if (event.target === partsModal) {
partsModal.style.display = 'none';
document.querySelector('.overlay').style.display = 'none'; // Nascondi overlay
document.body.style.pointerEvents = 'auto'; // Riattiva la pagina
}
});
}
// Gestione del tracking
document.querySelectorAll('.go-btn').forEach(button => {
button.addEventListener('click', async function() {
const rowIndex = this.getAttribute('data-row');
const awbInput = document.querySelector(`input[name="rows[${rowIndex}][awb_number]"]`);
const carrierSelect = document.querySelector(`select[name="rows[${rowIndex}][carrier]"]`);
const trackingResult = document.querySelector(`.tracking-info[data-row="${rowIndex}"] .tracking-result`);
const trackingHidden = document.querySelector(`input[name="rows[${rowIndex}][tracking_info]"]`);
const trackingNumber = awbInput.value.trim();
const carrierCode = carrierSelect.value;
if (!trackingNumber) {
alert('Inserisci un numero AWB valido!');
return;
}
try {
trackingResult.textContent = 'Caricamento...';
this.disabled = true;
const formData = new FormData();
formData.append('tracking_number', trackingNumber);
formData.append('courier_code', carrierCode);
const response = await fetch('fetch_tracking_info.php', {
method: 'POST',
body: formData
});
const result = await response.json();
if (!result.success) throw new Error(result.message);
const trackingText = `Date: ${result.deliveryDate}, Signed by: ${result.signedBy}, Courier: ${result.carrierName}`;
trackingResult.textContent = trackingText;
trackingHidden.value = JSON.stringify({
deliveryDate: result.deliveryDate,
signedBy: result.signedBy,
carrierName: result.carrierName
});
} catch (error) {
console.error('Errore:', error);
trackingResult.textContent = 'Errore: ' + error.message;
trackingHidden.value = '';
} finally {
this.disabled = false;
}
});
});
});
</script>
</body>
</html>