Compare commits

..

1 Commits

Author SHA1 Message Date
67bbd9bbbb export analyses 2026-04-21 00:09:59 +03:00
14 changed files with 170 additions and 458 deletions

View File

@ -3,9 +3,6 @@ ob_start();
session_start();
require_once '../../vendor/autoload.php';
Dotenv\Dotenv::createImmutable(dirname(__DIR__, 2))->safeLoad();
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'Europe/Rome');
$response = ['error' => '', 'rows' => [], 'columns' => [], 'template_id' => 0, 'filename' => '', 'excel_data' => []];
try {

View File

@ -3,9 +3,6 @@ require_once dirname(__DIR__, 3) . '/vendor/autoload.php';
use Dotenv\Dotenv;
Dotenv::createImmutable(dirname(__DIR__, 3))->safeLoad();
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'Europe/Rome');
class DBHandlerSelect
{
private static $instance = null;

View File

@ -17,8 +17,6 @@ try {
exit(1);
}
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'Europe/Rome');
// Recupera le variabili d'ambiente
$dbHost = $_ENV['DB_HOST'];
$dbName = $_ENV['DB_DATABASE'];

View File

@ -432,6 +432,71 @@ try {
$logFilePhotos = $logDir . "commessa_{$commessaId}_photos_step5_2_" . time() . ".txt";
$writeLog($logFilePhotos, $logContentPhotos, "STEP 6.2 - Photos (commessa={$commessaId})");
// 🔹 STEP 6.3: Add Analyses (AnalisiCampione) via Campione({id})/AddAnalisi bound action
$stmt = $pdo->prepare("
SELECT part_id, analysis_recordkey, analysis_name, analysis_method
FROM identification_parts_analyses
WHERE iddatadb = :iddatadb
ORDER BY part_id, id
");
$stmt->execute(['iddatadb' => $iddatadb]);
$analysesRows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$partIdToIndex = [];
foreach ($parts as $idx => $part) {
$partIdToIndex[(int)$part['part_id']] = $idx;
}
$totalAnalyses = count($analysesRows);
$addedAnalyses = 0;
$failedAnalyses = [];
$logContentStep63Analisi = "Analyses for iddatadb={$iddatadb}: total={$totalAnalyses}\n\n";
foreach ($analysesRows as $a) {
$partId = (int)$a['part_id'];
$recordKey = trim((string)($a['analysis_recordkey'] ?? ''));
$idx = $partIdToIndex[$partId] ?? null;
if ($idx === null || !isset($campioni[$idx]) || $recordKey === '') {
$logContentStep63Analisi .= "SKIP (no campione for part_id={$partId} / empty recordkey): '{$recordKey}'\n";
continue;
}
$campioneId = (int)($campioni[$idx]['IdCampione'] ?? 0);
if ($campioneId <= 0) {
$logContentStep63Analisi .= "SKIP (invalid IdCampione for part_id={$partId}): '{$recordKey}'\n";
continue;
}
$payload = ['RecordKey' => $recordKey];
$jsonPayload = json_encode($payload, JSON_UNESCAPED_SLASHES);
$logContentStep63Analisi .= "curl --location --request POST '{$apiBaseUrl}Campione({$campioneId})/AddAnalisi' \\\n" .
"--header 'Content-Type: application/json' \\\n" .
"--header 'Authorization: Bearer ••••••' \\\n" .
"--data '{$jsonPayload}'\n";
try {
$result = $api->post("Campione({$campioneId})/AddAnalisi", $payload);
$logContentStep63Analisi .= "OK (part_id={$partId}, campione={$campioneId}): " .
($a['analysis_name'] ?? '') . "\n---\n";
$addedAnalyses++;
} catch (Exception $e) {
$errMsg = $e->getMessage();
$logContentStep63Analisi .= "FAIL: {$errMsg}\n---\n";
$failedAnalyses[] = [
'part_id' => $partId,
'campione_id' => $campioneId,
'analysis_recordkey' => $recordKey,
'analysis_name' => $a['analysis_name'] ?? '',
'error' => $errMsg,
];
}
}
$logFileStep63Analisi = $logDir . "commessa_{$commessaId}_analyses_step63_" . time() . ".txt";
$writeLog($logFileStep63Analisi, $logContentStep63Analisi, "STEP 6.3 - AddAnalisi (commessa={$commessaId})");
// 🔹 STEP 7: Update Custom Fields for CommessaWeb
if (!empty($fieldValues)) {
// GET con espansione per CustomField
@ -542,23 +607,7 @@ try {
"RESPONSE:\n" . json_encode($commessaAfterPatch, JSON_PRETTY_PRINT);
$logFileStep10 = $logDir . "commessa_{$commessaId}_get_step10_" . time() . ".txt";
$writeLog($logFileStep10, $logContentStep10, "STEP 10 - GET verify (commessa={$commessaId})");
// 🔹 STEP 10.1: Save final CodiceCommessa into datadb.commessaweb
// After ImportaCommessa, the API returns the final LIMS job code in CodiceCommessa.
// Example: CodiceCommessa = 2614795, CodiceCommessaWeb = 26C0103.
$finalCodiceCommessa = trim((string)($commessaAfterPatch['CodiceCommessa'] ?? ''));
if ($finalCodiceCommessa !== '') {
$stmt = $pdo->prepare("
UPDATE datadb
SET commessaweb = :commessaweb,
status = 'l'
WHERE iddatadb = :iddatadb
");
$stmt->execute([
'commessaweb' => substr($finalCodiceCommessa, 0, 30),
'iddatadb' => $iddatadb
]);
}
// 🔹 STEP 11: Prepare final response
$finalCommessa = [
"Cliente" => $clienteId,
@ -573,17 +622,21 @@ try {
echo json_encode([
"success" => true,
"idcommessaweb" => $commessaId,
"commessaweb" => $finalCodiceCommessa ?: $commessaWebCode,
"commessaweb" => $commessaWebCode,
"commessaWeb" => $finalCommessa,
"commessaWebApiResponse" => $commessaWeb, // Incluso per debug
"totalCampioni" => count($campioni),
"totalCustomFields" => count($commessaAfterPatch["CommesseCustomFields"] ?? []),
"totalPhotos" => count($photos),
"totalAnalyses" => $totalAnalyses,
"addedAnalyses" => $addedAnalyses,
"failedAnalyses" => $failedAnalyses,
"message" => "Export successful",
"logFiles" => [
"step5_create" => $logFileStep5,
"step5_2_photos" => $logFilePhotos,
"step6_campioni" => $logFileStep6,
"step63_analyses" => $logFileStep63Analisi,
"step7_patch" => $logFileStep7 ?? null,
"step9_1_importa" => $logFileStep91,
"step10_get" => $logFileStep10
@ -599,6 +652,7 @@ try {
"step5_create" => $logFileStep5 ?? null,
"step5_2_photos" => $logFilePhotos ?? null,
"step6_campioni" => $logFileStep6 ?? null,
"step63_analyses" => $logFileStep63Analisi ?? null,
"step7_patch" => $logFileStep7 ?? null,
"step9_1_importa" => $logFileStep91 ?? null,
"step10_get" => $logFileStep10 ?? null

View File

@ -331,28 +331,6 @@
function createCell(col, rowIndex, cellIndex) {
const div = document.createElement("div");
div.className = "grid-cell editable-cell";
// Field color classification
// Schema/customfield fields are green.
// Fixed and standard fields stay white.
if (col.type === "detail" || col.type === "main_field") {
div.classList.add("schema-field");
} else if (col.type === "fixed") {
div.classList.add("fixed-field");
} else {
div.classList.add("standard-field");
}
// Required field classification.
// This comes from template_mapping.is_required or template_fixed_mapping.is_required.
if (
col.isRequired === true ||
col.isRequired === 1 ||
col.isRequired === "1"
) {
div.classList.add("required-field");
}
div.dataset.col = col.key;
div.dataset.colType = col.type;
div.dataset.row = rowIndex;
@ -766,27 +744,6 @@
columns.forEach((col, colIdx) => {
const cell = document.createElement("div");
cell.className = "grid-cell grid-top-cell";
// Field color classification for top propagation row
// Schema/customfield fields are green.
// Fixed and standard fields stay white.
if (col.type === "detail" || col.type === "main_field") {
cell.classList.add("schema-field");
} else if (col.type === "fixed") {
cell.classList.add("fixed-field");
} else {
cell.classList.add("standard-field");
}
// Required field classification also for the top propagation row.
if (
col.isRequired === true ||
col.isRequired === 1 ||
col.isRequired === "1"
) {
cell.classList.add("required-field");
}
cell.style.flex = `0 0 ${col.width}px`;
if (

View File

@ -10,125 +10,65 @@
<title>Template Buttons - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
<style>
/* Main buttons container */
.template-buttons {
/* Layout flessibile per gestire dimensioni diverse */
#templateButtons {
display: flex;
flex-wrap: wrap;
gap: 12px;
gap: 10px;
justify-content: flex-start;
padding: 10px 0;
/* Allinea a sinistra */
padding: 20px;
}
/* Button sizes */
/* Definizione delle dimensioni */
/* Definizione delle dimensioni */
.btn-small {
font-size: 12px;
padding: 6px 12px;
min-width: 100px;
min-height: 36px;
display: inline-flex;
min-height: 30px;
display: flex;
/* Aggiunto */
justify-content: center;
/* Aggiunto */
align-items: center;
gap: 8px;
border-radius: 8px;
text-align: center;
/* Aggiunto */
}
.btn-medium {
font-size: 16px;
padding: 10px 20px;
min-width: 140px;
min-height: 48px;
display: inline-flex;
min-width: 130px;
min-height: 45px;
display: flex;
/* Aggiunto */
justify-content: center;
/* Aggiunto */
align-items: center;
gap: 8px;
border-radius: 10px;
text-align: center;
/* Aggiunto */
}
.btn-large {
font-size: 20px;
padding: 14px 28px;
min-width: 190px;
min-height: 64px;
display: inline-flex;
min-width: 180px;
min-height: 60px;
display: flex;
/* Aggiunto */
justify-content: center;
/* Aggiunto */
align-items: center;
gap: 10px;
border-radius: 12px;
text-align: center;
/* Aggiunto */
}
.template-icon {
font-size: 18px;
line-height: 1;
}
.btn-large .template-icon {
font-size: 22px;
}
.btn-small .template-icon {
font-size: 15px;
}
/* Search box */
/* Stile della barra di ricerca */
#searchInput {
width: 100%;
padding: 10px 14px;
padding: 10px;
font-size: 16px;
margin-bottom: 18px;
border: 1px solid #d9d9d9;
border-radius: 8px;
outline: none;
}
#searchInput:focus {
border-color: #0d6efd;
box-shadow: 0 0 0 0.15rem rgba(13, 110, 253, 0.15);
}
/* Tabs */
.custom-tabs {
border-bottom: 1px solid #e5e5e5;
margin-bottom: 20px;
gap: 6px;
}
.custom-tabs .nav-link {
border: none;
border-radius: 10px 10px 0 0;
color: #555;
font-weight: 500;
display: flex;
align-items: center;
gap: 8px;
padding: 10px 18px;
}
.custom-tabs .nav-link:hover {
background: #f8f9fa;
color: #0d6efd;
}
.custom-tabs .nav-link.active {
background: #0d6efd;
color: #fff;
}
.tab-pane {
min-height: 140px;
}
.empty-message {
color: #6c757d;
font-style: italic;
padding: 10px 0;
}
.loading-message {
color: #6c757d;
padding: 10px 0;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 5px;
}
</style>
</head>
@ -147,54 +87,14 @@
<h6 class="mb-0">Active Templates</h6>
</div>
<div class="card-body">
<!-- Barra di ricerca -->
<input type="text" id="searchInput" placeholder="Search template...">
<ul class="nav nav-tabs custom-tabs" id="templateTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="xls-tab" data-bs-toggle="tab" data-bs-target="#xls-pane" type="button" role="tab" aria-controls="xls-pane" aria-selected="true">
<i class="bx bx-spreadsheet template-icon"></i>
XLS
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="api-tab" data-bs-toggle="tab" data-bs-target="#api-pane" type="button" role="tab" aria-controls="api-pane" aria-selected="false">
<i class="bx bx-transfer-alt template-icon"></i>
JSON/API
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="pdf-tab" data-bs-toggle="tab" data-bs-target="#pdf-pane" type="button" role="tab" aria-controls="pdf-pane" aria-selected="false">
<i class="bx bx-file-pdf template-icon"></i>
PDF
</button>
</li>
</ul>
<div class="tab-content" id="templateTabsContent">
<div class="tab-pane fade show active" id="xls-pane" role="tabpanel" aria-labelledby="xls-tab">
<div id="templateButtonsXLS" class="template-buttons">
<div class="loading-message">Loading XLS templates...</div>
<div id="templateButtons"></div>
</div>
</div>
<div class="tab-pane fade" id="api-pane" role="tabpanel" aria-labelledby="api-tab">
<div id="templateButtonsAPI" class="template-buttons">
<div class="loading-message">Loading API templates...</div>
</div>
</div>
<div class="tab-pane fade" id="pdf-pane" role="tabpanel" aria-labelledby="pdf-tab">
<div id="templateButtonsPDF" class="template-buttons">
<div class="loading-message">Loading PDF templates...</div>
</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'); ?>
@ -204,137 +104,46 @@
<script>
document.addEventListener("DOMContentLoaded", function() {
const allTemplates = [];
const containers = {
XLS: document.getElementById("templateButtonsXLS"),
API: document.getElementById("templateButtonsAPI"),
PDF: document.getElementById("templateButtonsPDF")
};
function getSizeClass(buttonSize) {
if (buttonSize === "small") return "btn-small";
if (buttonSize === "large") return "btn-large";
return "btn-medium";
}
function getTemplateIcon(sourceType) {
switch ((sourceType || '').toUpperCase()) {
case 'XLS':
return 'bx bx-spreadsheet';
case 'API':
return 'bx bx-transfer-alt';
case 'PDF':
return 'bx bx-file-pdf';
default:
return 'bx bx-file';
}
}
function createButton(template) {
const sizeClass = getSizeClass(template.button_size);
const sourceType = (template.source_type || '').toUpperCase();
const iconClass = getTemplateIcon(sourceType);
const btn = document.createElement("a");
btn.href = `import_xls2.php?id=${template.id}`;
btn.className = `btn ${sizeClass}`;
btn.style.backgroundColor = template.button_bg_color || '#0d6efd';
btn.style.color = template.button_text_color || '#ffffff';
btn.setAttribute("data-label", (template.button_label || '').toLowerCase());
btn.setAttribute("data-source-type", sourceType);
btn.innerHTML = `
<i class="${iconClass} template-icon"></i>
<span>${escapeHtml(template.button_label || 'Unnamed')}</span>
`;
return btn;
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
function clearContainers() {
Object.values(containers).forEach(container => {
container.innerHTML = '';
});
}
function renderTemplates(searchValue = '') {
clearContainers();
const grouped = {
XLS: [],
API: [],
PDF: []
};
allTemplates.forEach(template => {
const sourceType = (template.source_type || '').toUpperCase();
const label = (template.button_label || '').toLowerCase();
if (searchValue && !label.includes(searchValue)) {
return;
}
if (grouped[sourceType]) {
grouped[sourceType].push(template);
}
});
Object.keys(grouped).forEach(type => {
const container = containers[type];
if (!container) return;
if (grouped[type].length === 0) {
container.innerHTML = `<div class="empty-message">No templates found in this section.</div>`;
return;
}
grouped[type].forEach(template => {
container.appendChild(createButton(template));
});
});
}
fetch("load_active_templates.php")
.then(response => response.json())
.then(data => {
if (!data.success) {
console.error("Error loading templates:", data.message);
clearContainers();
Object.values(containers).forEach(container => {
container.innerHTML = `<div class="empty-message">Error loading templates.</div>`;
});
return;
}
if (!Array.isArray(data.data)) {
clearContainers();
Object.values(containers).forEach(container => {
container.innerHTML = `<div class="empty-message">Invalid response format.</div>`;
});
return;
}
let templateButtons = document.getElementById("templateButtons");
templateButtons.innerHTML = '';
allTemplates.push(...data.data);
renderTemplates();
data.data.forEach(template => {
let sizeClass = "btn-medium"; // Default
if (template.button_size === "small") sizeClass = "btn-small";
if (template.button_size === "large") sizeClass = "btn-large";
let btn = document.createElement("a");
btn.href = `import_xls2.php?id=${template.id}`;
btn.className = `btn ${sizeClass}`;
btn.style.backgroundColor = template.button_bg_color;
btn.style.color = template.button_text_color;
btn.textContent = template.button_label;
btn.setAttribute("data-label", template.button_label.toLowerCase()); // Attributo per ricerca
templateButtons.appendChild(btn);
});
})
.catch(error => {
console.error("Fetch error:", error);
clearContainers();
Object.values(containers).forEach(container => {
container.innerHTML = `<div class="empty-message">Fetch error while loading templates.</div>`;
});
});
.catch(error => console.error("Fetch error:", error));
// Funzione per la ricerca live
document.getElementById("searchInput").addEventListener("input", function() {
const searchValue = this.value.toLowerCase().trim();
renderTemplates(searchValue);
let searchValue = this.value.toLowerCase();
document.querySelectorAll("#templateButtons a").forEach(btn => {
let label = btn.getAttribute("data-label");
if (label.includes(searchValue)) {
btn.style.display = "inline-block";
} else {
btn.style.display = "none";
}
});
});
});
</script>

View File

@ -1,6 +1,10 @@
<?php
include('include/headscript.php');
// ✅ FIX timezone (Rome)
ini_set('date.timezone', 'Europe/Rome');
date_default_timezone_set('Europe/Rome');
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;

View File

@ -1,6 +1,10 @@
<?php
include('include/headscript.php');
// ✅ FIX timezone (Rome)
ini_set('date.timezone', 'Europe/Rome');
date_default_timezone_set('Europe/Rome');
$template_id = intval($_GET['id'] ?? 0);
if (!$template_id) {
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Template ID mancante"));
@ -370,10 +374,20 @@ $gridMeta = [
transition: background-color 0.3s ease;
}
input.auto-input,
select.auto-input {
background-color: #d4edda;
}
input.manual-input,
select.manual-input {
background-color: #fff3cd;
}
input.required-input,
select.required-input {
background-color: #f8d7da;
}
input.required-input,
select.required-input {
@ -412,9 +426,17 @@ $gridMeta = [
outline: none !important;
}
textarea.auto-input {
background-color: #d4edda;
}
textarea.manual-input {
background-color: #fff3cd;
}
textarea.required-input {
background-color: #f8d7da;
}
.status-badge {
display: inline-block;
@ -1022,7 +1044,11 @@ $gridMeta = [
font-style: italic;
}
.api-fixed-select.required-input:invalid,
.api-fixed-select[required]:not([value]):not([data-select2-id]) {
background-color: #f8d7da !important;
border-color: #dc3545 !important;
}
/* ── Pagination bar ── */
.pager-bar {
@ -1135,128 +1161,6 @@ $gridMeta = [
color: #adb5bd;
user-select: none;
}
/* =========================================================
FINAL GRID COLORS
Schema/customfield fields = green
Fixed/standard fields = white
Required fields = red border only
========================================================= */
/* Default: all fields white */
.grid-container input,
.grid-container select,
.grid-container textarea,
.grid-top input,
.grid-top select,
.grid-top textarea {
background-color: #ffffff !important;
color: #333 !important;
}
/* Schema/customfield fields: green background */
.grid-container .schema-field input,
.grid-container .schema-field select,
.grid-container .schema-field textarea,
.grid-top .schema-field input,
.grid-top .schema-field select,
.grid-top .schema-field textarea {
background-color: #dff3e3 !important;
}
/* Fixed and standard fields: white background */
.grid-container .fixed-field input,
.grid-container .fixed-field select,
.grid-container .fixed-field textarea,
.grid-container .standard-field input,
.grid-container .standard-field select,
.grid-container .standard-field textarea,
.grid-top .fixed-field input,
.grid-top .fixed-field select,
.grid-top .fixed-field textarea,
.grid-top .standard-field input,
.grid-top .standard-field select,
.grid-top .standard-field textarea {
background-color: #ffffff !important;
}
/* Required fields: red border only */
.grid-container .required-field input,
.grid-container .required-field select,
.grid-container .required-field textarea,
.grid-top .required-field input,
.grid-top .required-field select,
.grid-top .required-field textarea {
border: 2px solid #dc3545 !important;
box-shadow: 0 0 0 1px rgba(220, 53, 69, 0.15) !important;
}
/* Required schema/customfield fields: green + red border */
.grid-container .schema-field.required-field input,
.grid-container .schema-field.required-field select,
.grid-container .schema-field.required-field textarea,
.grid-top .schema-field.required-field input,
.grid-top .schema-field.required-field select,
.grid-top .schema-field.required-field textarea {
background-color: #dff3e3 !important;
border: 2px solid #dc3545 !important;
}
/* Required fixed/standard fields: white + red border */
.grid-container .fixed-field.required-field input,
.grid-container .fixed-field.required-field select,
.grid-container .fixed-field.required-field textarea,
.grid-container .standard-field.required-field input,
.grid-container .standard-field.required-field select,
.grid-container .standard-field.required-field textarea,
.grid-top .fixed-field.required-field input,
.grid-top .fixed-field.required-field select,
.grid-top .fixed-field.required-field textarea,
.grid-top .standard-field.required-field input,
.grid-top .standard-field.required-field select,
.grid-top .standard-field.required-field textarea {
background-color: #ffffff !important;
border: 2px solid #dc3545 !important;
}
/* Select2 - schema/customfield fields: green */
.grid-container .schema-field .select2-container--default .select2-selection--single,
.grid-top .schema-field .select2-container--default .select2-selection--single {
background-color: #dff3e3 !important;
}
/* Select2 - fixed/standard fields: white */
.grid-container .fixed-field .select2-container--default .select2-selection--single,
.grid-container .standard-field .select2-container--default .select2-selection--single,
.grid-top .fixed-field .select2-container--default .select2-selection--single,
.grid-top .standard-field .select2-container--default .select2-selection--single {
background-color: #ffffff !important;
}
/* Select2 - required fields: red border only */
.grid-container .required-field .select2-container--default .select2-selection--single,
.grid-top .required-field .select2-container--default .select2-selection--single {
border: 2px solid #dc3545 !important;
box-shadow: 0 0 0 1px rgba(220, 53, 69, 0.15) !important;
}
/* Remove old red background from required classes */
.grid-container input.required-input,
.grid-container select.required-input,
.grid-container textarea.required-input,
.grid-top input.required-input,
.grid-top select.required-input,
.grid-top textarea.required-input {
background-color: inherit !important;
}
/* Missing required cell: red outline only */
.grid-cell.missing-required {
background-color: inherit !important;
border-right: 1px solid #dee2e6 !important;
outline: 2px solid #dc3545 !important;
outline-offset: -2px;
}
</style>
<title>Edit Imported Data - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
</head>

View File

@ -10,9 +10,6 @@ error_reporting(E_ALL | E_STRICT);
include('../../extra/auth.php');
//require_once __DIR__ . '/extra/auth.php';
// Laravel bootstrap (loaded by auth.php) forces UTC via config/app.php — re-apply our TZ
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'Europe/Rome');
// Here we just check if user is not
// logged in, and in that case we redirect
// the user to vanguard login page.

View File

@ -13,10 +13,7 @@ try {
}
// Recupera solo i template attivi
$stmt = $pdo->query("SELECT id, button_label, button_size, button_bg_color, button_text_color, source_type
FROM excel_templates
WHERE status = 'active'
ORDER BY button_label ASC");
$stmt = $pdo->query("SELECT id, button_label, button_bg_color, button_text_color, button_size FROM excel_templates WHERE status = 'active'");
$templates = $stmt->fetchAll(PDO::FETCH_ASSOC);
$response["success"] = true;

View File

@ -10,9 +10,6 @@ session_start();
// Includi PHPSpreadsheet
require_once '../../vendor/autoload.php';
Dotenv\Dotenv::createImmutable(dirname(__DIR__, 2))->safeLoad();
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'Europe/Rome');
$response = ['error' => '', 'rows' => [], 'columns' => [], 'template_id' => 0, 'filename' => ''];
try {

View File

@ -653,7 +653,7 @@
"IdSchemaCustomFields": 163,
"ConteggioClienti": 0,
"Nome": "Devred",
"Descrizione": "Schema creato per cliente DEVRED\r\nGR 18\/03\/2024 aggiornato il 23\/04\/2026\r\n\r\n"
"Descrizione": "Schema creato per cliente DEVRED\r\nGR 18\/03\/2024\r\n\r\n"
},
{
"IdSchemaCustomFields": 164,

View File

@ -8,9 +8,6 @@ ini_set('log_errors', 1);
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
require_once __DIR__ . '/class/VisualLimsApiClient.class.php';
Dotenv\Dotenv::createImmutable(dirname(__DIR__, 2))->safeLoad();
date_default_timezone_set($_ENV['APP_TIMEZONE'] ?? 'Europe/Rome');
header('Content-Type: application/json');
try {

View File

@ -1,6 +1,10 @@
<?php
include('include/headscript.php');
// ✅ FIX timezone (Rome)
ini_set('date.timezone', 'Europe/Rome');
date_default_timezone_set('Europe/Rome');
$template_id = intval($_GET['id'] ?? 0);
if (!$template_id) {
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Template ID mancante"));