new template schema
This commit is contained in:
@@ -1,46 +1,412 @@
|
||||
<?php
|
||||
header('Content-Type: application/json'); // Forza la risposta JSON
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
<?php include('include/headscript.php');
|
||||
|
||||
require_once(__DIR__ . '/class/db-functions.php'); // Include la classe di connessione
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
die("Invalid template ID");
|
||||
}
|
||||
|
||||
$id = intval($_GET['id']);
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection(); // Ottieni la connessione
|
||||
$pdo = $db->getConnection();
|
||||
$stmt = $pdo->prepare("SELECT name, header_row, start_column, target_table, sample_xlsx, idclient, clientname, idschema, schemaname, schemajson FROM excel_templates WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$template = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$data = json_decode(file_get_contents("php://input"), true);
|
||||
|
||||
if (!$data) {
|
||||
echo json_encode(["success" => false, "message" => "Invalid JSON input"]);
|
||||
exit;
|
||||
if (!$template) {
|
||||
die("Template not found");
|
||||
}
|
||||
|
||||
if (!isset($data['template_id'], $data['tablename'], $data['excel_column'], $data['mysql_column'])) {
|
||||
echo json_encode(["success" => false, "message" => "Missing required fields"]);
|
||||
exit;
|
||||
}
|
||||
$clientName = $template['clientname'] ?: '';
|
||||
$schemaName = $template['schemaname'] ?: '';
|
||||
$schemajson = $template['schemajson'] ? json_decode($template['schemajson'], true) : [];
|
||||
$isSchemajsonEmpty = empty(trim($template['schemajson']));
|
||||
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO excel_column_mappings
|
||||
(template_id, tablename, excel_column, mysql_column, data_type, is_required, default_value, headerexcel)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||
");
|
||||
$result = $stmt->execute([
|
||||
$data['template_id'],
|
||||
$data['tablename'],
|
||||
$data['excel_column'],
|
||||
$data['mysql_column'],
|
||||
$data['data_type'],
|
||||
$data['is_required'],
|
||||
$data['default_value'],
|
||||
$data['headerexcel']
|
||||
]);
|
||||
// Recupera i campi dalla tabella template_mapping
|
||||
$stmt = $pdo->prepare("SELECT id, field_id, excel_column, is_manual, manual_default, data_type, is_required, default_value, has_list, length, decimals, min_value, max_value, default_curr_date, tablename, field_label FROM template_mapping WHERE template_id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
?>
|
||||
|
||||
if (!$result) {
|
||||
echo json_encode(["success" => false, "message" => "Database insert failed"]);
|
||||
exit;
|
||||
}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
echo json_encode(["success" => true]);
|
||||
exit;
|
||||
<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'); ?>
|
||||
<title>Configure Template <?= htmlspecialchars($template['name'], ENT_QUOTES, 'UTF-8'); ?></title>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
|
||||
</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">Configure Template: <span id="templateName"><?php echo htmlspecialchars($template['name']); ?></span></h6>
|
||||
<p>
|
||||
Client: <span id="clientName"><?php echo htmlspecialchars($clientName); ?></span> |
|
||||
Schema: <span id="schemaName"><?php echo htmlspecialchars($schemaName); ?></span> |
|
||||
Header Row: <span id="headerRow"><?php echo $template['header_row']; ?></span> |
|
||||
Start Column: <span id="startColumn"><?php echo htmlspecialchars($template['start_column']); ?></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-4">
|
||||
<label class="form-label">Upload XLS Example:</label>
|
||||
<input type="file" id="xlsUpload" class="form-control">
|
||||
<small id="uploadStatus">
|
||||
<?php if (!empty($template['sample_xlsx'])): ?>
|
||||
✅ Current file: <a href="xlstemplates/<?php echo htmlspecialchars($template['sample_xlsx']); ?>" target="_blank"><?php echo htmlspecialchars($template['sample_xlsx']); ?></a>
|
||||
<?php else: ?>
|
||||
No file uploaded yet.
|
||||
<?php endif; ?>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<h5>Schema Fields Configuration</h5>
|
||||
<button id="updateSchemaButton" class="btn btn-primary ms-2" data-empty="<?php echo $isSchemajsonEmpty ? 'true' : 'false'; ?>">
|
||||
<?php echo $isSchemajsonEmpty ? 'Load Schema Details' : 'Update Schema Details'; ?>
|
||||
</button>
|
||||
</div>
|
||||
<table id="schemaFieldsTable" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>ID</th>
|
||||
<th>Type</th>
|
||||
<th>Mapping</th>
|
||||
<th>Default Value</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="schemaFieldsBody">
|
||||
<?php foreach ($mappings as $mapping): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($mapping['field_label'] ?? 'N/A'); ?></td>
|
||||
<td><?php echo htmlspecialchars($mapping['field_id'] ?? 'N/A'); ?></td>
|
||||
<td><?php echo htmlspecialchars($mapping['data_type'] ?? 'N/A'); ?></td>
|
||||
<td>
|
||||
<select class="form-select mapping-select" data-id="<?php echo $mapping['id']; ?>" data-field-id="<?php echo $mapping['field_id']; ?>">
|
||||
<option value="">Select Option</option>
|
||||
<option value="xls" <?php echo !$mapping['is_manual'] && $mapping['excel_column'] ? 'selected' : ''; ?>>Map to XLS Column</option>
|
||||
<option value="manual" <?php echo $mapping['is_manual'] ? 'selected' : ''; ?>>Manual Entry</option>
|
||||
</select>
|
||||
<select class="form-select xls-columns" style="display:<?php echo !$mapping['is_manual'] && $mapping['excel_column'] ? 'block' : 'none'; ?>" data-id="<?php echo $mapping['id']; ?>"></select>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" class="form-control manual-default" placeholder="Default value" value="<?php echo htmlspecialchars($mapping['manual_default'] ?? ''); ?>" style="display:<?php echo $mapping['is_manual'] ? 'block' : 'none'; ?>" data-field-id="<?php echo $mapping['field_id']; ?>">
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($mapping['excel_column']): ?>
|
||||
<button class="btn btn-danger btn-sm remove-association" data-id="<?php echo $mapping['id']; ?>">Remove</button>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<h5>Current Configurations</h5>
|
||||
<ul id="configurationsList" class="list-group border p-3"></ul>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-end">
|
||||
<a href="templates_dashboard.php" class="btn btn-primary">⬅ Back to Template Dashboard</a>
|
||||
</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>
|
||||
let availableXlsColumns = [];
|
||||
|
||||
document.getElementById('xlsUpload').addEventListener('change', function(event) {
|
||||
let file = event.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
let formData = new FormData();
|
||||
formData.append("xls_file", file);
|
||||
formData.append("template_id", <?php echo $id; ?>);
|
||||
|
||||
let statusText = document.getElementById('uploadStatus');
|
||||
statusText.innerText = "Uploading...";
|
||||
|
||||
fetch('upload_xls_example.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!data.success) {
|
||||
statusText.innerText = "❌ Upload failed: " + data.message;
|
||||
return;
|
||||
}
|
||||
statusText.innerHTML = `✅ File uploaded: <a href="xlstemplates/${data.filename}" target="_blank">${data.filename}</a>`;
|
||||
processXLSX(file);
|
||||
})
|
||||
.catch(error => {
|
||||
statusText.innerText = "❌ Upload failed. Check console.";
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
|
||||
function processXLSX(file) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
let data = new Uint8Array(e.target.result);
|
||||
let workbook = XLSX.read(data, {
|
||||
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 sheetData = XLSX.utils.sheet_to_json(sheet, {
|
||||
header: 1,
|
||||
defval: "",
|
||||
raw: false,
|
||||
range: 0
|
||||
});
|
||||
if (!sheetData[rowIndex - 1]) {
|
||||
document.getElementById('schemaFieldsBody').querySelectorAll('select.xls-columns').forEach(select => {
|
||||
select.innerHTML = '<option value="">No headers found</option>';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let headers = sheetData[rowIndex - 1].slice(startColumn - 1).filter(header => header !== undefined && header.trim() !== "");
|
||||
availableXlsColumns = [...headers]; // Memorizza tutte le colonne disponibili
|
||||
updateXlsDropdowns();
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
|
||||
function updateXlsDropdowns() {
|
||||
let usedColumns = Array.from(document.querySelectorAll('select.xls-columns'))
|
||||
.filter(select => select.style.display === 'block' && select.value)
|
||||
.map(select => select.value);
|
||||
|
||||
document.querySelectorAll('select.xls-columns').forEach(select => {
|
||||
let currentValue = select.value || select.dataset.currentXls || '';
|
||||
let options = availableXlsColumns
|
||||
.filter(col => !usedColumns.includes(col) || col === currentValue)
|
||||
.map(col => `<option value="${col}" ${col === currentValue ? 'selected' : ''}>${col}</option>`)
|
||||
.join('');
|
||||
select.innerHTML = '<option value="">Select XLS Column</option>' + options;
|
||||
select.dataset.currentXls = currentValue;
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
let templateId = <?php echo $id; ?>;
|
||||
let schemaId = <?php echo json_encode($template['idschema'] ?? 0); ?>;
|
||||
let isSchemajsonEmpty = <?php echo json_encode($isSchemajsonEmpty); ?>;
|
||||
|
||||
async function loadClientAndSchemaNames() {
|
||||
if (<?php echo json_encode($template['idclient'] ?? 0); ?> > 0) {
|
||||
let response = await fetch(`get_clienti.php?id=<?php echo $template['idclient']; ?>`);
|
||||
let data = await response.json();
|
||||
if (response.ok && data.value?.length) document.getElementById('clientName').textContent = data.value[0].Nominativo || 'N/A';
|
||||
}
|
||||
if (schemaId > 0) {
|
||||
let response = await fetch(`get_schemi.php?id=${schemaId}`);
|
||||
let data = await response.json();
|
||||
if (response.ok && data.value?.length) document.getElementById('schemaName').textContent = data.value[0].Nome || 'N/A';
|
||||
}
|
||||
}
|
||||
|
||||
loadClientAndSchemaNames();
|
||||
|
||||
async function updateSchemaDetails() {
|
||||
if (!schemaId) {
|
||||
document.getElementById('schemaFieldsBody').innerHTML = '<tr><td colspan="6" class="text-warning">No schema associated.</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
let updateSchemaButton = document.getElementById('updateSchemaButton');
|
||||
updateSchemaButton.disabled = true;
|
||||
updateSchemaButton.textContent = 'Loading...';
|
||||
|
||||
try {
|
||||
let response = await fetch(`get_schema_details.php?id=${schemaId}`);
|
||||
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
let data = JSON.parse(await response.text());
|
||||
if (!data.SchemiCustomFieldsDettagli) throw new Error('Missing "SchemiCustomFieldsDettagli"');
|
||||
|
||||
await saveSchemaJson(templateId, JSON.stringify(data));
|
||||
alert('Schema updated successfully. Refresh the page to see changes.');
|
||||
} catch (error) {
|
||||
document.getElementById('schemaFieldsBody').innerHTML = '<tr><td colspan="6" class="text-danger">Error: ' + error.message + '</td></tr>';
|
||||
} finally {
|
||||
updateSchemaButton.disabled = false;
|
||||
updateSchemaButton.textContent = 'Update Schema Details';
|
||||
}
|
||||
}
|
||||
|
||||
async function saveSchemaJson(templateId, schemaJson) {
|
||||
let response = await fetch('update_schemajson.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
template_id: templateId,
|
||||
schemajson: schemaJson
|
||||
})
|
||||
});
|
||||
let data = await response.json();
|
||||
if (!data.success) throw new Error(data.message || 'Failed to save schema JSON');
|
||||
}
|
||||
|
||||
document.getElementById('updateSchemaButton').addEventListener('click', updateSchemaDetails);
|
||||
|
||||
function loadConfigurations() {
|
||||
fetch('load_mappings.php?template_id=' + templateId)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!data.success) return;
|
||||
let configurationsList = document.getElementById('configurationsList');
|
||||
configurationsList.innerHTML = '';
|
||||
data.mappings.forEach(mapping => {
|
||||
let li = document.createElement('li');
|
||||
li.className = 'list-group-item d-flex justify-content-between align-items-center';
|
||||
li.innerHTML = `${mapping.field_label} (${mapping.field_id}) → ${mapping.excel_column || 'Manual: ' + (mapping.manual_default || 'N/A')} <button class="btn btn-danger btn-sm removeMapping" data-id="${mapping.id}">X</button>`;
|
||||
configurationsList.appendChild(li);
|
||||
});
|
||||
})
|
||||
.catch(error => console.error("❌ Error fetching mappings:", error));
|
||||
}
|
||||
|
||||
document.getElementById('schemaFieldsBody').addEventListener('change', function(event) {
|
||||
if (event.target.classList.contains('mapping-select')) {
|
||||
let tr = event.target.closest('tr');
|
||||
let mappingId = event.target.getAttribute('data-id');
|
||||
let xlsSelect = tr.querySelector('.xls-columns');
|
||||
let manualInput = tr.querySelector('.manual-default');
|
||||
let removeBtn = tr.querySelector('.remove-association');
|
||||
if (event.target.value === 'xls') {
|
||||
xlsSelect.style.display = 'block';
|
||||
manualInput.style.display = 'none';
|
||||
manualInput.value = '';
|
||||
removeBtn.style.display = xlsSelect.value ? 'inline-block' : 'none';
|
||||
} else if (event.target.value === 'manual') {
|
||||
xlsSelect.style.display = 'none';
|
||||
manualInput.style.display = 'block';
|
||||
removeBtn.style.display = 'none';
|
||||
} else {
|
||||
xlsSelect.style.display = 'none';
|
||||
manualInput.style.display = 'none';
|
||||
manualInput.value = '';
|
||||
removeBtn.style.display = 'none';
|
||||
}
|
||||
saveMapping(mappingId, event.target.value, manualInput.value, xlsSelect.value);
|
||||
updateXlsDropdowns();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('schemaFieldsBody').addEventListener('change', function(event) {
|
||||
if (event.target.classList.contains('xls-columns')) {
|
||||
let tr = event.target.closest('tr');
|
||||
let mappingId = event.target.getAttribute('data-id');
|
||||
let manualInput = tr.querySelector('.manual-default');
|
||||
let removeBtn = tr.querySelector('.remove-association');
|
||||
removeBtn.style.display = event.target.value ? 'inline-block' : 'none';
|
||||
saveMapping(mappingId, 'xls', manualInput.value, event.target.value);
|
||||
updateXlsDropdowns();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('schemaFieldsBody').addEventListener('input', function(event) {
|
||||
if (event.target.classList.contains('manual-default')) {
|
||||
let tr = event.target.closest('tr');
|
||||
let mappingId = tr.querySelector('.mapping-select').getAttribute('data-id');
|
||||
let xlsSelect = tr.querySelector('.xls-columns');
|
||||
saveMapping(mappingId, 'manual', event.target.value, xlsSelect.value);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('schemaFieldsBody').addEventListener('click', function(event) {
|
||||
if (event.target.classList.contains('remove-association')) {
|
||||
let mappingId = event.target.getAttribute('data-id');
|
||||
let tr = event.target.closest('tr');
|
||||
let xlsSelect = tr.querySelector('.xls-columns');
|
||||
xlsSelect.value = '';
|
||||
xlsSelect.style.display = 'none';
|
||||
tr.querySelector('.mapping-select').value = '';
|
||||
event.target.style.display = 'none';
|
||||
saveMapping(mappingId, '', '', null);
|
||||
updateXlsDropdowns();
|
||||
}
|
||||
});
|
||||
|
||||
function saveMapping(mappingId, mappingType, defaultValue, excelColumn) {
|
||||
fetch('save_mapping_json.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: mappingId,
|
||||
mapping_type: mappingType,
|
||||
excel_column: mappingType === 'xls' ? excelColumn : null,
|
||||
manual_default: mappingType === 'manual' ? defaultValue : null,
|
||||
tablename: "<?php echo $template['target_table']; ?>"
|
||||
})
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) loadConfigurations();
|
||||
else console.error("❌ Error saving mapping:", data.message);
|
||||
})
|
||||
.catch(error => console.error("❌ Fetch error:", error));
|
||||
}
|
||||
|
||||
document.getElementById('configurationsList').addEventListener('click', function(event) {
|
||||
if (event.target.classList.contains('removeMapping')) {
|
||||
let mappingId = event.target.getAttribute('data-id');
|
||||
fetch('remove_mapping.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: mappingId
|
||||
})
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
loadConfigurations();
|
||||
updateXlsDropdowns(); // Aggiorna la tendina dopo la rimozione
|
||||
} else console.error("❌ Error removing mapping:", data.message);
|
||||
})
|
||||
.catch(error => console.error("❌ Fetch error:", error));
|
||||
}
|
||||
});
|
||||
|
||||
loadConfigurations();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user