update template and edit import

This commit is contained in:
Claudio 2025-07-08 12:25:47 +02:00
parent b092abf8c7
commit c533973420
69 changed files with 1655 additions and 20 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

View File

@ -31,6 +31,6 @@ Content-Length: 51
< strict-transport-security: max-age=2592000
< x-powered-by: ASP.NET
< x-content-type-options: nosniff
< date: Mon, 07 Jul 2025 09:08:43 GMT
< date: Tue, 08 Jul 2025 10:12:39 GMT
<
* Connection #0 to host 93.43.5.102 left intact

View File

@ -15,11 +15,11 @@
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: 93.43.5.102]
* [HTTP/2] [1] [:path: /limsapi/api/odata/SchemaCustomField]
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MTg4NjUyMywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.63LcA-ce-Jf1aQdZwd_GWXNLJSGn38259WyoqzxUgRc]
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MTk3Njc1OSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.CgecorvqDyNuZYSU8FJSIb5kjPs0TnjXqoNbdMS0IzI]
* [HTTP/2] [1] [accept: application/json]
> GET /limsapi/api/odata/SchemaCustomField HTTP/2
Host: 93.43.5.102
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MTg4NjUyMywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.63LcA-ce-Jf1aQdZwd_GWXNLJSGn38259WyoqzxUgRc
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1MTk3Njc1OSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.CgecorvqDyNuZYSU8FJSIb5kjPs0TnjXqoNbdMS0IzI
Accept: application/json
< HTTP/2 200
@ -30,6 +30,6 @@ Accept: application/json
< odata-version: 4.0
< x-powered-by: ASP.NET
< x-content-type-options: nosniff
< date: Mon, 07 Jul 2025 09:08:43 GMT
< date: Tue, 08 Jul 2025 10:12:42 GMT
<
* Connection #0 to host 93.43.5.102 left intact

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"@odata.context":"https:\/\/93.43.5.102\/limsapi\/api\/odata\/$metadata#CustomField(CustomFieldsValues())\/$entity","IdCustomField":157,"TitoloTraduzione":"Stile: ","Titolo":"Stile: ","Descrizione":null,"Tipo":"Testo","Decimali":0,"Lunghezza":0,"Minimo":null,"Massimo":null,"ValoreDefault":null,"Elenco":true,"DefaultCurrDate":false,"ObbligatorioWeb":false,"CustomFieldsValues":[]}

View File

@ -0,0 +1,31 @@
<?php
require_once dirname(__DIR__, 2) . '/vendor/autoload.php'; // Torna al livello di public
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
header('Content-Type: application/json');
ini_set('display_errors', '0');
error_reporting(E_ALL);
try {
$api = VisualLimsApiClient::getInstance();
// ID del campo custom passato da GET oppure default
$customFieldId = isset($_GET['id']) && is_numeric($_GET['id']) ? intval($_GET['id']) : 150;
// Endpoint con $expand per ottenere i valori
$endpoint = "CustomField($customFieldId)?\$expand=CustomFieldsValues";
// Recupera i dati dal server
$data = $api->get($endpoint);
// Salva la risposta in un file per debug
file_put_contents(__DIR__ . '/customfield_values_response.json', json_encode($data));
// Output JSON al client
echo json_encode($data);
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'error' => $e->getMessage()
]);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,313 @@
<?php
include('include/headscript.php');
// Controlla se è stato passato un ID valido
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Invalid ID"));
exit;
}
$id = intval($_GET['id']); // Sanifica l'ID
// Recupera il template dal database
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
$stmt = $pdo->prepare("SELECT * FROM excel_templates WHERE id = ?");
$stmt->execute([$id]);
$template = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$template) {
header("Location: template_dashboard.php?status=error&message=" . urlencode("Template not found"));
exit;
}
// Debug del template
error_log("Loaded template: " . print_r($template, true));
?>
<!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'); ?>
<style>
.table-container {
overflow-x: auto;
max-width: 100%;
margin-bottom: 20px;
}
.table {
width: 100%;
border-collapse: collapse;
}
.table th,
.table td {
padding: 10px;
text-align: left;
border: 1px solid #dee2e6;
min-width: 100px;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.table th:first-child,
.table td:first-child {
min-width: 50px;
max-width: 50px;
}
.table th {
background-color: #f8f9fa;
position: relative;
cursor: col-resize;
user-select: none;
}
.table th .resize-handle {
position: absolute;
top: 0;
right: 0;
width: 5px;
height: 100%;
cursor: col-resize;
background: transparent;
}
.table th .resize-handle:hover {
background: #007bff;
}
.search-container {
margin-bottom: 20px;
}
.search-container input {
width: 300px;
padding: 8px;
border: 1px solid #ced4da;
border-radius: 5px;
}
.loader {
display: none;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: 10px auto;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<title><?= htmlspecialchars($template['name']) ?> - <?= 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"><?= htmlspecialchars($template['name']) ?></h6>
<small>Template ID: <?= $id ?>, Start Row: <?= $template['header_row'] ?>, Start Column: <?= $template['start_column'] ?></small>
</div>
</div>
</div>
<div class="card-body">
<!-- Form per caricare il file -->
<form id="uploadForm" enctype="multipart/form-data" class="mb-4">
<div class="mb-3">
<label for="excel_file" class="form-label">Upload XLS File</label>
<input type="file" class="form-control" id="excel_file" name="excel_file" accept=".xls,.xlsx" required>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
<div class="loader" id="loader"></div>
</form>
<!-- Contenitore per messaggi di errore -->
<div id="errorContainer" class="alert alert-danger mt-3" style="display: none;"></div>
<!-- Contenitore per la tabella -->
<div id="tableContainer"></div>
</div>
</div>
</div>
</div>
<!--end page wrapper -->
<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>
<!--end wrapper-->
<!-- search modal -->
<?php //include('include/searchmodal.php');
?>
<!-- end search modal -->
<!--start switcher-->
<?php //include('include/themeswitcher.php');
?>
<!--end switcher-->
<?php include('jsinclude.php'); ?>
<script>
document.addEventListener("DOMContentLoaded", function() {
const form = document.getElementById('uploadForm');
const loader = document.getElementById('loader');
const errorContainer = document.getElementById('errorContainer');
const tableContainer = document.getElementById('tableContainer');
form.addEventListener('submit', function(e) {
e.preventDefault();
loader.style.display = 'block';
errorContainer.style.display = 'none';
tableContainer.innerHTML = '';
const formData = new FormData(this);
const templateId = <?= $id ?>;
console.log('Template ID passed to formData:', templateId);
formData.append('template_id', templateId);
formData.append('header_row', <?= $template['header_row'] ?>);
formData.append('start_column', <?= $template['start_column'] ?>);
fetch('process_import_xls2.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
loader.style.display = 'none';
if (data.error) {
errorContainer.textContent = data.error;
errorContainer.style.display = 'block';
} else {
let html = `
<form id="selectRowsForm" action="import_edit2.php" method="POST">
<input type="hidden" name="template_id" value="${data.template_id}">
<input type="hidden" name="columns" value='${JSON.stringify(data.columns)}'>
<input type="hidden" name="rows" value='${JSON.stringify(data.rows)}'>
<input type="hidden" name="filename" value="${data.filename}">
<div class="search-container">
<input type="text" id="searchInput" class="form-control" placeholder="Cerca nelle righe...">
</div>
<div class="table-container">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Seleziona</th>
${data.columns.map(col => `<th>${col || 'Colonna senza nome'}<div class="resize-handle"></div></th>`).join('')}
</tr>
</thead>
<tbody>
${data.rows.map((row, index) => `
<tr>
<td><input type="checkbox" class="row-checkbox" name="selected_rows[]" value="${index}"></td>
${row.map(cell => `<td>${cell}</td>`).join('')}
</tr>
`).join('')}
</tbody>
</table>
</div>
<button type="submit" class="btn btn-primary mt-3" id="proceedButton" disabled>Prosegui</button>
</form>
`;
tableContainer.innerHTML = html;
// Inizializza le variabili dopo aver inserito la tabella
const proceedButton = document.getElementById('proceedButton');
const checkboxes = document.querySelectorAll('.row-checkbox');
// Aggiungi logica per il ridimensionamento delle colonne
const thElements = document.querySelectorAll('.table th');
thElements.forEach((th, index) => {
if (index === 0) return;
const resizeHandle = th.querySelector('.resize-handle');
if (resizeHandle) {
resizeHandle.addEventListener('mousedown', (e) => {
e.preventDefault();
const startX = e.clientX;
const startWidth = th.offsetWidth;
const onMouseMove = (e) => {
const newWidth = Math.max(50, startWidth + (e.clientX - startX));
th.style.width = `${newWidth}px`;
th.style.minWidth = `${newWidth}px`;
th.style.maxWidth = `${newWidth}px`;
const cells = document.querySelectorAll(`.table td:nth-child(${index + 1})`);
cells.forEach(cell => {
cell.style.width = `${newWidth}px`;
cell.style.minWidth = `${newWidth}px`;
cell.style.maxWidth = `${newWidth}px`;
});
};
const onMouseUp = () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
}
});
// Aggiungi event listener per la ricerca
const searchInput = document.getElementById('searchInput');
const rows = document.querySelectorAll('.table tbody tr');
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
rows.forEach(row => {
const text = Array.from(row.cells).slice(1).map(cell => cell.textContent.toLowerCase()).join(' ');
row.style.display = text.includes(searchTerm) ? '' : 'none';
});
});
// Aggiungi event listener per i checkbox
checkboxes.forEach(checkbox => {
checkbox.addEventListener('change', function() {
console.log('Checkbox changed, checked: ', this.checked); // Debug
proceedButton.disabled = !Array.from(checkboxes).some(cb => cb.checked);
});
});
// Abilita il pulsante se ci sono checkbox selezionate all'inizio
proceedButton.disabled = !Array.from(checkboxes).some(cb => cb.checked);
}
})
.catch(error => {
loader.style.display = 'none';
errorContainer.textContent = 'Errore durante il caricamento del file: ' + error.message;
errorContainer.style.display = 'block';
});
});
});
</script>
</body>
</html>

View File

@ -59,3 +59,10 @@ https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
https://93.43.5.102/limsapi/api/odata/SchemaCustomField

View File

@ -180,8 +180,8 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
type: 'array'
});
let sheet = workbook.Sheets[workbook.SheetNames[0]];
let rowIndex = parseInt(document.getElementById('headerRow').textContent) || 1;
let startColumn = parseInt(document.getElementById('startColumn').textContent.charCodeAt(0) - 64) || 1;
let rowIndex = parseInt(document.getElementById('headerRow').textContent) || 1; // Usa header_row dal template
let startColumn = parseInt(document.getElementById('startColumn').textContent) || 1; // Usa start_column come numero
let sheetData = XLSX.utils.sheet_to_json(sheet, {
header: 1,
@ -189,16 +189,19 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
raw: false,
range: 0
});
console.log("Dati della riga " + rowIndex + ":", sheetData[rowIndex - 1]); // Debug: stampa la riga delle intestazioni
if (!sheetData[rowIndex - 1]) {
document.getElementById('schemaFieldsBody').querySelectorAll('select.xls-columns').forEach(select => {
select.innerHTML = '<option value="">No headers found</option>';
select.innerHTML = '<option value="">Nessuna intestazione trovata</option>';
});
return;
}
let headers = sheetData[rowIndex - 1].slice(startColumn - 1).filter(header => header !== undefined && header.trim() !== "");
// Estrai le intestazioni a partire dalla colonna specificata, includendo le vuote
let headers = sheetData[rowIndex - 1].slice(startColumn - 1).map(header => header === undefined ? "" : header);
console.log("Intestazioni estratte:", headers); // Debug: stampa le intestazioni estratte
availableXlsColumns = [...headers];
usedColumnsFromDB = []; // Resetta le colonne usate dal DB dopo un nuovo caricamento
usedColumnsFromDB = []; // Resetta le colonne usate dopo un nuovo caricamento
saveXlsHeaders(headers);
updateXlsDropdowns();
};

View File

@ -0,0 +1,139 @@
<?php
// Sopprime eventuali output di errori (li logghiamo invece di mostrarli)
ob_start();
ini_set('display_errors', 0); // Disattiva l'output degli errori a schermo
error_reporting(E_ALL);
// Inizia la sessione
session_start();
// Includi PHPSpreadsheet e la classe DBHandler
require_once '../../vendor/autoload.php';
require_once __DIR__ . '/class/db-functions.php'; // Assumo che DBHandlerSelect sia qui
$response = ['error' => '', 'rows' => [], 'columns' => [], 'template_id' => 0, 'filename' => ''];
try {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['excel_file'])) {
$template_id = isset($_POST['template_id']) ? intval($_POST['template_id']) : 0;
$header_row = isset($_POST['header_row']) ? intval($_POST['header_row']) : 1;
$start_column = isset($_POST['start_column']) ? intval($_POST['start_column']) : 1;
// Debug del template_id ricevuto
error_log("Received template_id from POST: " . print_r($_POST['template_id'], true));
error_log("Converted template_id: $template_id");
$file = $_FILES['excel_file'];
$fileError = $file['error'];
if ($fileError === UPLOAD_ERR_OK) {
// Recupera l'ID dell'utente loggato
if (!isset($iduserlogin)) {
$iduserlogin = 1; // Valore di default
error_log("Warning: iduserlogin non definito, usando 1 come default");
}
// Genera il nome del file rinominato
$timestamp = date('YmdHis');
$originalFilename = basename($file['name']);
$newFilename = "{$iduserlogin}-{$timestamp}-{$originalFilename}";
$importFolder = __DIR__ . '/imported_trf/';
if (!file_exists($importFolder)) {
mkdir($importFolder, 0777, true);
}
$destination = $importFolder . $newFilename;
// Sposta il file
if (!move_uploaded_file($file['tmp_name'], $destination)) {
throw new Exception("Errore durante lo spostamento del file in $destination");
}
error_log("File spostato con successo in: $destination");
// Connessione al database
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
// Recupera il mapping da template_mapping
$stmt = $pdo->prepare("SELECT field_id AS excel_column, field_id AS mysql_column, data_type, is_required, default_value, is_manual FROM template_mapping WHERE template_id = ?");
$stmt->execute([$template_id]);
$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Debug dei mapping
error_log("Mappings found for template_id $template_id: " . print_r($mappings, true));
if (empty($mappings)) {
$response['error'] = "Nessun mapping trovato per il template con ID $template_id";
} else {
// Carica il file rinominato con PHPSpreadsheet
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($destination);
$worksheet = $spreadsheet->getActiveSheet();
$highestRow = $worksheet->getHighestRow();
$highestColumn = $worksheet->getHighestColumn();
$highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); // Corretto
$startRow = max(1, $header_row);
$startColumn = max(1, $start_column);
// Debug dei parametri
error_log("Processing - template_id: $template_id, startRow: $startRow, startColumn: $startColumn, highestRow: $highestRow, highestColumn: $highestColumn, highestColumnIndex: $highestColumnIndex");
// Validazione degli indici
if ($startRow > $highestRow) {
$response['error'] = "La riga di partenza ($startRow) supera il numero totale di righe ($highestRow).";
} elseif ($startColumn > $highestColumnIndex) {
$response['error'] = "La colonna di partenza ($startColumn) supera il numero totale di colonne ($highestColumnIndex).";
} else {
$excelData = [];
// Estrai la riga degli header
$headerRowData = [];
for ($col = $startColumn; $col <= $highestColumnIndex; $col++) {
$columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col);
$cell = $worksheet->getCell($columnLetter . $header_row);
$cellValue = $cell ? $cell->getCalculatedValue() : '';
$headerRowData[] = htmlspecialchars($cellValue ?: '');
}
// Estrai i dati a partire dalla riga successiva
for ($row = $startRow + 1; $row <= $highestRow; $row++) {
$rowData = [];
for ($col = $startColumn; $col <= $highestColumnIndex; $col++) {
$columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($col);
$cell = $worksheet->getCell($columnLetter . $row);
$cellValue = $cell ? $cell->getCalculatedValue() : '';
$rowData[] = htmlspecialchars($cellValue ?: '');
}
if (!empty(array_filter($rowData))) {
$excelData[] = $rowData;
}
}
// Salva i dati in sessione
$_SESSION['excel_data'] = $excelData;
$_SESSION['template_id'] = $template_id;
$_SESSION['headers'] = $headerRowData;
$_SESSION['mappings'] = $mappings; // Salva i mapping per l'importazione
$response['rows'] = $excelData;
$response['columns'] = $headerRowData; // Usa gli header reali
$response['template_id'] = $template_id;
$response['filename'] = $newFilename;
}
}
} else {
$response['error'] = "Errore nell'upload del file: Codice errore $fileError.";
}
} else {
$response['error'] = "Richiesta non valida.";
}
} catch (Exception $e) {
$response['error'] = "Errore durante il caricamento del file: " . $e->getMessage();
error_log("Exception in process_import_xls2.php: " . $e->getMessage());
}
// Pulisce qualsiasi output indesiderato
ob_end_clean();
// Invia la risposta JSON
header('Content-Type: application/json');
echo json_encode($response);
exit;

View File

@ -60,6 +60,11 @@
"IdSchemaCustomFields": 186,
"Nome": "TWINSET",
"Descrizione": "Schema per tutti i campioni di qualsiasi matrice escluso cuoio\/pelle\r\n\r\n"
},
{
"IdSchemaCustomFields": 188,
"Nome": "LEMAIRE",
"Descrizione": "Schema per tutti i campioni in cuoio\/pelle per i quali non \u00e8 specificato un destinatario.\r\n"
}
]
}

View File

View File

@ -13,7 +13,7 @@ try {
throw new Exception("Invalid request method.");
}
// Recupera i dati dal body JSON (non da $_POST direttamente)
// Recupera i dati dal body JSON
$input = json_decode(file_get_contents('php://input'), true);
$template_id = isset($input['template_id']) ? intval($input['template_id']) : null;
$schemajson = isset($input['schemajson']) ? trim($input['schemajson']) : '';
@ -33,22 +33,86 @@ try {
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
// Aggiorna il database
// Recupera il target_table e verifica l'esistenza del template
$stmt = $pdo->prepare("SELECT target_table FROM excel_templates WHERE id = ?");
$stmt->execute([$template_id]);
$template = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$template) {
throw new Exception("Template not found.");
}
$target_table = $template['target_table'];
// Inizia una transazione
$pdo->beginTransaction();
// Aggiorna il schemajson in excel_templates
$stmt = $pdo->prepare("UPDATE excel_templates
SET schemajson = ?, updated_at = NOW()
WHERE id = ?");
$stmt->execute([
$schemajson,
$template_id
]);
$stmt->execute([$schemajson, $template_id]);
if ($stmt->rowCount() > 0) {
$response["message"] = "Schema JSON updated successfully!";
} else {
$response["message"] = "No changes detected, but operation completed.";
// Estrai i campi dallo schema
$schema_id = $decoded_json['IdSchemaCustomFields'] ?? null;
$schema_fields = $decoded_json['SchemiCustomFieldsDettagli'] ?? [];
if (empty($schema_id)) {
throw new Exception("Schema ID not found in schemajson.");
}
if (empty($schema_fields)) {
throw new Exception("No fields found in schema.");
}
// Prepara la query per l'inserimento condizionato in template_mapping
$insert_stmt = $pdo->prepare("
INSERT INTO template_mapping (
template_id, schema_id, field_id, data_type, is_required, default_value,
has_list, length, decimals, min_value, max_value, default_curr_date,
tablename, field_label
)
SELECT :template_id, :schema_id, :field_id, :data_type, :is_required, :default_value,
:has_list, :length, :decimals, :min_value, :max_value, :default_curr_date,
:tablename, :field_label
WHERE NOT EXISTS (
SELECT 1 FROM template_mapping
WHERE template_id = :template_id_check AND field_id = :field_id_check
)
");
// Itera sui campi dello schema e inserisci quelli mancanti
foreach ($schema_fields as $field) {
$custom_field = $field['CustomField'] ?? [];
if (empty($custom_field['IdCustomField'])) {
continue; // Salta se manca l'ID del campo
}
$insert_stmt->execute([
':template_id' => $template_id,
':schema_id' => $schema_id,
':field_id' => $custom_field['IdCustomField'],
':data_type' => $custom_field['Tipo'] ?? 'Testo',
':is_required' => $custom_field['ObbligatorioWeb'] ? 1 : 0,
':default_value' => $custom_field['ValoreDefault'] ?? null,
':has_list' => $custom_field['Elenco'] ? 1 : 0,
':length' => $custom_field['Lunghezza'] ?? 0,
':decimals' => $custom_field['Decimali'] ?? 0,
':min_value' => $custom_field['Minimo'] ?? null,
':max_value' => $custom_field['Massimo'] ?? null,
':default_curr_date' => $custom_field['DefaultCurrDate'] ? 1 : 0,
':tablename' => $target_table,
':field_label' => $custom_field['TitoloTraduzione'] ?? '',
':template_id_check' => $template_id,
':field_id_check' => $custom_field['IdCustomField']
]);
}
// Commit della transazione
$pdo->commit();
$response["success"] = true;
$response["message"] = "Schema JSON updated and template mappings created successfully!";
} catch (Exception $e) {
if (isset($pdo) && $pdo->inTransaction()) {
$pdo->rollback();
}
$response["message"] = $e->getMessage();
}