edit templtae lingue e colori
This commit is contained in:
@@ -40,10 +40,13 @@ yarn-error.log
|
|||||||
/public/userarea/logaspi/
|
/public/userarea/logaspi/
|
||||||
/public/userarea/logs/api/
|
/public/userarea/logs/api/
|
||||||
/public/userarea/logs/api/**
|
/public/userarea/logs/api/**
|
||||||
|
/public/userarea/logs/
|
||||||
|
/public/userarea/logs/**
|
||||||
/public/userarea/photostrf/
|
/public/userarea/photostrf/
|
||||||
/public/userarea/class/*.log
|
/public/userarea/class/*.log
|
||||||
/public/userarea/class/curl_auth_debug.log
|
/public/userarea/class/curl_auth_debug.log
|
||||||
/public/userarea/class/curl_request_debug.log
|
/public/userarea/class/curl_request_debug.log
|
||||||
|
/public/userarea/schema_dettagli_response.json
|
||||||
|
|
||||||
# File XLSX temporanei importati
|
# File XLSX temporanei importati
|
||||||
/public/userarea/imported_trf/*.xlsx
|
/public/userarea/imported_trf/*.xlsx
|
||||||
|
|||||||
@@ -255,4 +255,39 @@ class VisualLimsApiClient
|
|||||||
{
|
{
|
||||||
return $this->baseUrl;
|
return $this->baseUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupera contenuto binario - Adattato per https://bvcpsitaly-elims.com/limsapi
|
||||||
|
*/
|
||||||
|
public function getRaw($endpoint)
|
||||||
|
{
|
||||||
|
$token = $this->getToken();
|
||||||
|
|
||||||
|
// IMPORTANTE: usa /odata/ e NON /api/odata/
|
||||||
|
$url = "{$this->baseUrl}/odata/{$endpoint}";
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||||
|
"Authorization: Bearer {$token}",
|
||||||
|
"Accept: */*"
|
||||||
|
]);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$curl_error = curl_error($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
if ($response === false) {
|
||||||
|
throw new Exception("Errore cURL: " . $curl_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($http_code !== 200) {
|
||||||
|
throw new Exception("HTTP {$http_code} su endpoint: " . $url);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uso:
|
||||||
|
* download_rapporto_file.php?id=123
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
|
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||||
|
|
||||||
|
if (!$id) {
|
||||||
|
throw new Exception("ID RapportoFile mancante");
|
||||||
|
}
|
||||||
|
|
||||||
|
$debugDir = __DIR__ . '/logs/lims_get_commessa/';
|
||||||
|
|
||||||
|
if (!is_dir($debugDir)) {
|
||||||
|
mkdir($debugDir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupero il record RapportoFile.
|
||||||
|
*/
|
||||||
|
$data = $api->get("RapportoFile({$id})", []);
|
||||||
|
|
||||||
|
file_put_contents(
|
||||||
|
$debugDir . "rapporto_file_{$id}.json",
|
||||||
|
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provo vari nomi campo possibili per il contenuto PDF.
|
||||||
|
* Dopo il primo test potremo adattarlo al nome esatto.
|
||||||
|
*/
|
||||||
|
$possibleContentFields = [
|
||||||
|
'File',
|
||||||
|
'file',
|
||||||
|
'Content',
|
||||||
|
'content',
|
||||||
|
'FileContent',
|
||||||
|
'fileContent',
|
||||||
|
'Contenuto',
|
||||||
|
'contenuto',
|
||||||
|
'Bytes',
|
||||||
|
'bytes'
|
||||||
|
];
|
||||||
|
|
||||||
|
$base64 = null;
|
||||||
|
|
||||||
|
foreach ($possibleContentFields as $field) {
|
||||||
|
if (!empty($data[$field])) {
|
||||||
|
$base64 = $data[$field];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$base64) {
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Record RapportoFile recuperato, ma non ho trovato un campo base64 del PDF.',
|
||||||
|
'hint' => 'Apri logs/lims_get_commessa/rapporto_file_' . $id . '.json e controlla il nome reale del campo file.',
|
||||||
|
'data' => $data
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Se il contenuto ha prefisso data URI, lo pulisco.
|
||||||
|
*/
|
||||||
|
if (strpos($base64, 'base64,') !== false) {
|
||||||
|
$parts = explode('base64,', $base64);
|
||||||
|
$base64 = end($parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdfBinary = base64_decode($base64, true);
|
||||||
|
|
||||||
|
if ($pdfBinary === false) {
|
||||||
|
throw new Exception("Il contenuto trovato non è un base64 valido");
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = $data['NomeFile']
|
||||||
|
?? $data['nomeFile']
|
||||||
|
?? $data['FileName']
|
||||||
|
?? $data['fileName']
|
||||||
|
?? "rapporto_{$id}.pdf";
|
||||||
|
|
||||||
|
if (!str_ends_with(strtolower($filename), '.pdf')) {
|
||||||
|
$filename .= '.pdf';
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . basename($filename) . '"');
|
||||||
|
header('Content-Length: ' . strlen($pdfBinary));
|
||||||
|
|
||||||
|
echo $pdfBinary;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
@@ -25,6 +25,41 @@ if (!$template) {
|
|||||||
$stmt = $pdo->prepare("SELECT * FROM routine");
|
$stmt = $pdo->prepare("SELECT * FROM routine");
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
$routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$buttonBgPalette = [
|
||||||
|
'#0d6efd' => 'Blue',
|
||||||
|
'#6610f2' => 'Indigo',
|
||||||
|
'#6f42c1' => 'Purple',
|
||||||
|
'#d63384' => 'Pink',
|
||||||
|
'#dc3545' => 'Red',
|
||||||
|
'#fd7e14' => 'Orange',
|
||||||
|
'#ffc107' => 'Yellow',
|
||||||
|
'#198754' => 'Green',
|
||||||
|
'#20c997' => 'Teal',
|
||||||
|
'#0dcaf0' => 'Cyan',
|
||||||
|
'#212529' => 'Dark',
|
||||||
|
'#6c757d' => 'Gray',
|
||||||
|
'#495057' => 'Slate',
|
||||||
|
'#795548' => 'Brown',
|
||||||
|
'#2f5d50' => 'Sage Green',
|
||||||
|
];
|
||||||
|
|
||||||
|
$buttonTextPalette = [
|
||||||
|
'#ffffff' => 'White',
|
||||||
|
'#6c757d' => 'Gray',
|
||||||
|
'#000000' => 'Black',
|
||||||
|
];
|
||||||
|
|
||||||
|
$currentButtonBgColor = strtolower($template['button_bg_color'] ?? '#007bff');
|
||||||
|
$currentButtonTextColor = strtolower($template['button_text_color'] ?? '#ffffff');
|
||||||
|
|
||||||
|
if (!array_key_exists($currentButtonBgColor, array_change_key_case($buttonBgPalette, CASE_LOWER))) {
|
||||||
|
$currentButtonBgColor = '#0d6efd';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($currentButtonTextColor, array_change_key_case($buttonTextPalette, CASE_LOWER))) {
|
||||||
|
$currentButtonTextColor = '#ffffff';
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@@ -35,6 +70,64 @@ $routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
||||||
<?php include('cssinclude.php'); ?>
|
<?php include('cssinclude.php'); ?>
|
||||||
|
<style>
|
||||||
|
.color-palette {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-option {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-option input {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-swatch {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid #d6dbe0;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
|
||||||
|
transition: all 0.18s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-option input:checked+.color-swatch {
|
||||||
|
border: 3px solid #111827;
|
||||||
|
transform: scale(1.08);
|
||||||
|
box-shadow: 0 0 0 4px rgba(13, 110, 253, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-swatch .check-mark {
|
||||||
|
display: none;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #ffffff;
|
||||||
|
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-option input:checked+.color-swatch .check-mark {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-name {
|
||||||
|
display: block;
|
||||||
|
font-size: 11px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 4px;
|
||||||
|
color: #555;
|
||||||
|
max-width: 55px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||||
<title>Edit Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
<title>Edit Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
||||||
@@ -123,12 +216,46 @@ $routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Button Background Color</label>
|
<label class="form-label">Button Background Color</label>
|
||||||
<input type="color" name="button_bg_color" class="form-control form-control-color" value="<?php echo htmlspecialchars($template['button_bg_color'] ?? '#007bff'); ?>">
|
|
||||||
|
<div class="color-palette">
|
||||||
|
<?php foreach ($buttonBgPalette as $colorValue => $colorLabel): ?>
|
||||||
|
<?php $isChecked = strtolower($colorValue) === $currentButtonBgColor; ?>
|
||||||
|
|
||||||
|
<label class="color-option" title="<?= htmlspecialchars($colorLabel, ENT_QUOTES, 'UTF-8'); ?>">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="button_bg_color"
|
||||||
|
value="<?= htmlspecialchars($colorValue, ENT_QUOTES, 'UTF-8'); ?>"
|
||||||
|
<?= $isChecked ? 'checked' : ''; ?>>
|
||||||
|
<span class="color-swatch" style="background-color: <?= htmlspecialchars($colorValue, ENT_QUOTES, 'UTF-8'); ?>;">
|
||||||
|
<span class="check-mark">✓</span>
|
||||||
|
</span>
|
||||||
|
<span class="color-name"><?= htmlspecialchars($colorLabel, ENT_QUOTES, 'UTF-8'); ?></span>
|
||||||
|
</label>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Button Text Color</label>
|
<label class="form-label">Button Text Color</label>
|
||||||
<input type="color" name="button_text_color" class="form-control form-control-color" value="<?php echo htmlspecialchars($template['button_text_color'] ?? '#ffffff'); ?>">
|
|
||||||
|
<div class="color-palette">
|
||||||
|
<?php foreach ($buttonTextPalette as $colorValue => $colorLabel): ?>
|
||||||
|
<?php $isChecked = strtolower($colorValue) === $currentButtonTextColor; ?>
|
||||||
|
|
||||||
|
<label class="color-option" title="<?= htmlspecialchars($colorLabel, ENT_QUOTES, 'UTF-8'); ?>">
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="button_text_color"
|
||||||
|
value="<?= htmlspecialchars($colorValue, ENT_QUOTES, 'UTF-8'); ?>"
|
||||||
|
<?= $isChecked ? 'checked' : ''; ?>>
|
||||||
|
<span class="color-swatch" style="background-color: <?= htmlspecialchars($colorValue, ENT_QUOTES, 'UTF-8'); ?>;">
|
||||||
|
<span class="check-mark">✓</span>
|
||||||
|
</span>
|
||||||
|
<span class="color-name"><?= htmlspecialchars($colorLabel, ENT_QUOTES, 'UTF-8'); ?></span>
|
||||||
|
</label>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@@ -258,6 +385,16 @@ $routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
sourceType.addEventListener('change', updateSourceFields);
|
sourceType.addEventListener('change', updateSourceFields);
|
||||||
updateSourceFields();
|
updateSourceFields();
|
||||||
|
|
||||||
|
function formatClientLabel(client) {
|
||||||
|
const nome = client.Nominativo || "Name not available";
|
||||||
|
const id = client.IdCliente || "";
|
||||||
|
const codiceCliente = (client.CodiceCliente ?? client.codiceCliente ?? "").toString().trim();
|
||||||
|
const suffix = (codiceCliente.split("_")[1] || "").trim();
|
||||||
|
const shortCode = suffix || (codiceCliente ? codiceCliente.charAt(0) : "--");
|
||||||
|
|
||||||
|
return `${nome.trim()} - ${shortCode} (ID: ${id})`;
|
||||||
|
}
|
||||||
|
|
||||||
async function loadClients() {
|
async function loadClients() {
|
||||||
try {
|
try {
|
||||||
clientLoadingStatus.style.display = 'inline';
|
clientLoadingStatus.style.display = 'inline';
|
||||||
@@ -280,9 +417,8 @@ $routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
select.innerHTML = '<option value="">Select a client...</option>';
|
select.innerHTML = '<option value="">Select a client...</option>';
|
||||||
|
|
||||||
data.value.forEach(client => {
|
data.value.forEach(client => {
|
||||||
const nome = client.Nominativo || "Name not available";
|
|
||||||
const id = client.IdCliente || "";
|
const id = client.IdCliente || "";
|
||||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
const option = new Option(formatClientLabel(client), id);
|
||||||
|
|
||||||
if (parseInt(id) === parseInt(selectedClientId)) {
|
if (parseInt(id) === parseInt(selectedClientId)) {
|
||||||
option.selected = true;
|
option.selected = true;
|
||||||
|
|||||||
@@ -328,3 +328,6 @@
|
|||||||
2026-03-26 10:57:41 [MoltiplicatorePrezzo] Autenticazione fallita: HTTP 500, Errore cURL: , Risposta: {"title":"Internal Server Error","status":500,"detail":"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.","instance":"POST /api/authentication/authenticate","errorCode":"63ab532c6"}
|
2026-03-26 10:57:41 [MoltiplicatorePrezzo] Autenticazione fallita: HTTP 500, Errore cURL: , Risposta: {"title":"Internal Server Error","status":500,"detail":"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.","instance":"POST /api/authentication/authenticate","errorCode":"63ab532c6"}
|
||||||
2026-03-26 10:57:56 [AnagraficaCertestObject] Autenticazione fallita: HTTP 500, Errore cURL: , Risposta: {"title":"Internal Server Error","status":500,"detail":"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.","instance":"POST /api/authentication/authenticate","errorCode":"63ab532c6"}
|
2026-03-26 10:57:56 [AnagraficaCertestObject] Autenticazione fallita: HTTP 500, Errore cURL: , Risposta: {"title":"Internal Server Error","status":500,"detail":"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.","instance":"POST /api/authentication/authenticate","errorCode":"63ab532c6"}
|
||||||
2026-03-26 10:58:11 [AnagraficaCertestService] Autenticazione fallita: HTTP 500, Errore cURL: , Risposta: {"title":"Internal Server Error","status":500,"detail":"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.","instance":"POST /api/authentication/authenticate","errorCode":"63ab532c6"}
|
2026-03-26 10:58:11 [AnagraficaCertestService] Autenticazione fallita: HTTP 500, Errore cURL: , Risposta: {"title":"Internal Server Error","status":500,"detail":"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.","instance":"POST /api/authentication/authenticate","errorCode":"63ab532c6"}
|
||||||
|
2026-04-30 15:01:25 - Errore nel recupero dati: HTTP 404, Risposta: {"title":"Not Found","status":404,"detail":"Not Found","instance":"GET /api/odata/Rapporto(2621521)","errorCode":"d25cbd678"}
|
||||||
|
2026-04-30 15:02:04 - Errore nel recupero dati: HTTP 404, Risposta:
|
||||||
|
2026-04-30 15:03:19 - Errore nella richiesta: URL rejected: Malformed input to a URL function
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uso:
|
||||||
|
* rapporto_full_by_codice.php?codice=2621521
|
||||||
|
* rapporto_full_by_codice.php?codice=2621521&download=1
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
|
$codiceRapporto = trim($_GET['codice'] ?? '');
|
||||||
|
$downloadPdf = isset($_GET['download']) && $_GET['download'] == '1';
|
||||||
|
|
||||||
|
if ($codiceRapporto === '') {
|
||||||
|
throw new Exception("Parametro codice mancante. Usa ?codice=2621521");
|
||||||
|
}
|
||||||
|
|
||||||
|
$debugDir = __DIR__ . '/logs/lims_rapporti/';
|
||||||
|
$pdfDir = __DIR__ . '/pdf/rapporti/';
|
||||||
|
|
||||||
|
if (!is_dir($debugDir)) mkdir($debugDir, 0755, true);
|
||||||
|
if (!is_dir($pdfDir)) mkdir($pdfDir, 0755, true);
|
||||||
|
|
||||||
|
$codiceRapportoSafe = str_replace("'", "''", $codiceRapporto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STEP 1 - Search IdRapporto
|
||||||
|
*/
|
||||||
|
$searchParams = [
|
||||||
|
'$filter' => "CodiceRapporto eq '{$codiceRapportoSafe}'",
|
||||||
|
'$select' => 'IdRapporto,CodiceRapporto,Data,Versione,Firmato,DataStampa',
|
||||||
|
'$top' => 1
|
||||||
|
];
|
||||||
|
|
||||||
|
$searchEndpoint = "Rapporto?" . http_build_query($searchParams);
|
||||||
|
$searchData = $api->get($searchEndpoint);
|
||||||
|
|
||||||
|
$rapporti = $searchData['value'] ?? [];
|
||||||
|
|
||||||
|
if (empty($rapporti)) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Nessun rapporto trovato per questo CodiceRapporto.',
|
||||||
|
'codice_rapporto' => $codiceRapporto
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rapportoBase = $rapporti[0];
|
||||||
|
$idRapporto = intval($rapportoBase['IdRapporto'] ?? 0);
|
||||||
|
|
||||||
|
if (!$idRapporto) {
|
||||||
|
throw new Exception("IdRapporto non trovato nella risposta.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STEP 2 - Dettaglio Rapporto
|
||||||
|
*/
|
||||||
|
$clienteExpandError = null;
|
||||||
|
$detailEndpoint = "Rapporto({$idRapporto})?\$expand=Cliente,RapportiFiles,CampioniDatiRapporto";
|
||||||
|
|
||||||
|
try {
|
||||||
|
$detailData = $api->get($detailEndpoint);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$clienteExpandError = $e->getMessage();
|
||||||
|
$detailEndpoint = "Rapporto({$idRapporto})?\$expand=RapportiFiles,CampioniDatiRapporto";
|
||||||
|
$detailData = $api->get($detailEndpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
file_put_contents(
|
||||||
|
$debugDir . "rapporto_{$codiceRapportoSafe}_light.json",
|
||||||
|
json_encode($detailData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
|
||||||
|
);
|
||||||
|
|
||||||
|
$cliente = $detailData['Cliente'] ?? null;
|
||||||
|
$rapportiFiles = $detailData['RapportiFiles'] ?? [];
|
||||||
|
$campioniDatiRapporto = $detailData['CampioniDatiRapporto'] ?? [];
|
||||||
|
|
||||||
|
// ====================== CLIENTE ======================
|
||||||
|
$clienteInfo = [
|
||||||
|
'found' => is_array($cliente),
|
||||||
|
'id_cliente' => $cliente['IdCliente'] ?? $cliente['Id'] ?? null,
|
||||||
|
'codice_cliente' => $cliente['CodiceCliente'] ?? $cliente['Codice'] ?? null,
|
||||||
|
'nome_cliente' => $cliente['Nominativo'] ?? $cliente['RagioneSociale'] ?? $cliente['Nome'] ?? $cliente['Descrizione'] ?? null,
|
||||||
|
'partita_iva' => $cliente['PartitaIva'] ?? null,
|
||||||
|
'codice_fiscale' => $cliente['CodiceFiscale'] ?? null
|
||||||
|
];
|
||||||
|
|
||||||
|
// ====================== FILE PDF ======================
|
||||||
|
$selectedRapportoFile = null;
|
||||||
|
$idRapportoFile = null;
|
||||||
|
$pdfFileName = $codiceRapporto . '.pdf';
|
||||||
|
$pdfFullPath = $pdfDir . $pdfFileName;
|
||||||
|
|
||||||
|
if (is_array($rapportiFiles) && count($rapportiFiles) > 0) {
|
||||||
|
foreach ($rapportiFiles as $file) {
|
||||||
|
$fileName = $file['FileName'] ?? '';
|
||||||
|
$tipoRapporto = $file['TipoRapporto'] ?? '';
|
||||||
|
$categoria = $file['Categoria'] ?? '';
|
||||||
|
|
||||||
|
if (
|
||||||
|
stripos($fileName, '.pdf') !== false ||
|
||||||
|
stripos($tipoRapporto, 'Rapporto') !== false ||
|
||||||
|
stripos($categoria, 'Rapporti') !== false
|
||||||
|
) {
|
||||||
|
$selectedRapportoFile = $file;
|
||||||
|
$idRapportoFile = $file['IdRapportoFile'] ?? null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$selectedRapportoFile && count($rapportiFiles) > 0) {
|
||||||
|
$selectedRapportoFile = $rapportiFiles[0];
|
||||||
|
$idRapportoFile = $rapportiFiles[0]['IdRapportoFile'] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================== DOWNLOAD PDF - DEBUG AVANZATO ======================
|
||||||
|
$pdfDownloaded = false;
|
||||||
|
$pdfError = null;
|
||||||
|
$endpointUsato = null;
|
||||||
|
|
||||||
|
if ($downloadPdf && $idRapportoFile) {
|
||||||
|
|
||||||
|
$tentativi = [
|
||||||
|
"RapportoFile({$idRapportoFile})/\$value",
|
||||||
|
"RapportoFile({$idRapportoFile})/Contenuto/\$value",
|
||||||
|
"RapportoFile({$idRapportoFile})/File/\$value",
|
||||||
|
"Rapporto({$idRapporto})/RapportiFiles({$idRapportoFile})/\$value",
|
||||||
|
"Rapporto({$idRapporto})/RapportoFile/\$value",
|
||||||
|
"GetRapportoFile?IdRapportoFile={$idRapportoFile}",
|
||||||
|
"RapportoFile/Download?Id={$idRapportoFile}",
|
||||||
|
"Rapporto/DownloadFile?IdRapporto={$idRapporto}"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($tentativi as $ep) {
|
||||||
|
try {
|
||||||
|
$pdfContent = $api->getRaw($ep);
|
||||||
|
|
||||||
|
if (strlen($pdfContent) > 2000) { // PDF decente deve essere più grande
|
||||||
|
file_put_contents($pdfFullPath, $pdfContent);
|
||||||
|
$pdfDownloaded = true;
|
||||||
|
$endpointUsato = $ep;
|
||||||
|
$pdfError = "SUCCESSO con: " . $ep;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
$pdfError = "Contenuto troppo piccolo con: " . $ep;
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$pdfError = "Fallito con " . $ep . " → " . $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================== CAMPIONI + RATING (ripristinato dal tuo originale) ======================
|
||||||
|
$campioniSintesi = [];
|
||||||
|
$ratingFinale = null;
|
||||||
|
$ratingSource = null;
|
||||||
|
$hasIrregolare = false;
|
||||||
|
$hasPositiveResults = false;
|
||||||
|
|
||||||
|
if (is_array($campioniDatiRapporto)) {
|
||||||
|
foreach ($campioniDatiRapporto as $campione) {
|
||||||
|
$giudizioRapporto = $campione['GiudizioRapporto'] ?? null;
|
||||||
|
$giudizioCertificato = $campione['GiudizioCertificato'] ?? null;
|
||||||
|
$esitoGiudizioLMR = $campione['EsitoGiudizioLMR'] ?? null;
|
||||||
|
$esitoGiudizioImpiego = $campione['EsitoGiudizioImpiego'] ?? null;
|
||||||
|
$risultatiIrregolari = ($campione['RisultatiIrregolari'] ?? false) === true;
|
||||||
|
$risultatiPositivi = ($campione['RisultatiPositivi'] ?? false) === true;
|
||||||
|
|
||||||
|
$campioniSintesi[] = [
|
||||||
|
'id_campione_dati_rapporto' => $campione['IdCampioneDatiRapporto'] ?? null,
|
||||||
|
'codice_campione' => $campione['CodiceCampione'] ?? null,
|
||||||
|
'stato_campione' => $campione['StatoCampione'] ?? null,
|
||||||
|
'stato_campione_web' => $campione['StatoCampioneWeb'] ?? null,
|
||||||
|
'matrice' => $campione['Matrice'] ?? null,
|
||||||
|
'macro_matrice' => $campione['MacroMatrice'] ?? null,
|
||||||
|
'giudizio_rapporto' => $giudizioRapporto,
|
||||||
|
'giudizio_certificato' => $giudizioCertificato,
|
||||||
|
'esito_giudizio_lmr' => $esitoGiudizioLMR,
|
||||||
|
'esito_giudizio_impiego' => $esitoGiudizioImpiego,
|
||||||
|
'risultati_positivi' => $risultatiPositivi,
|
||||||
|
'risultati_irregolari' => $risultatiIrregolari
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!$ratingFinale && !empty($giudizioRapporto)) {
|
||||||
|
$ratingFinale = $giudizioRapporto;
|
||||||
|
$ratingSource = 'CampioniDatiRapporto.GiudizioRapporto';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$ratingFinale && !empty($giudizioCertificato)) {
|
||||||
|
$ratingFinale = $giudizioCertificato;
|
||||||
|
$ratingSource = 'CampioniDatiRapporto.GiudizioCertificato';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($risultatiIrregolari) $hasIrregolare = true;
|
||||||
|
if ($risultatiPositivi) $hasPositiveResults = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback rating
|
||||||
|
if (!$ratingFinale) {
|
||||||
|
if ($hasIrregolare) {
|
||||||
|
$ratingFinale = 'Irregolare';
|
||||||
|
$ratingSource = 'RisultatiIrregolari';
|
||||||
|
} elseif ($hasPositiveResults || count($campioniSintesi) > 0) {
|
||||||
|
$ratingFinale = 'Regolare';
|
||||||
|
$ratingSource = 'fallback';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================== RISPOSTA FINALE ======================
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
|
||||||
|
'codice_rapporto' => $codiceRapporto,
|
||||||
|
'id_rapporto' => $idRapporto,
|
||||||
|
|
||||||
|
'search_endpoint' => $searchEndpoint,
|
||||||
|
'detail_endpoint' => $detailEndpoint,
|
||||||
|
'cliente_expand_error' => $clienteExpandError,
|
||||||
|
|
||||||
|
'rapporto_base' => $rapportoBase,
|
||||||
|
'cliente' => $clienteInfo,
|
||||||
|
|
||||||
|
'rating_finale' => $ratingFinale,
|
||||||
|
'rating_source' => $ratingSource,
|
||||||
|
|
||||||
|
'rapporti_files_count' => count($rapportiFiles),
|
||||||
|
'selected_rapporto_file' => $selectedRapportoFile,
|
||||||
|
|
||||||
|
'pdf_file_name' => $pdfFileName,
|
||||||
|
'pdf_path' => $pdfDownloaded ? $pdfFullPath : null,
|
||||||
|
'pdf_downloaded' => $pdfDownloaded,
|
||||||
|
'pdf_error' => $pdfError,
|
||||||
|
|
||||||
|
'campioni_count' => count($campioniSintesi),
|
||||||
|
'campioni_sintesi' => $campioniSintesi,
|
||||||
|
|
||||||
|
'download_requested' => $downloadPdf
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
|
$commessa = trim($_GET['commessa'] ?? '');
|
||||||
|
|
||||||
|
if ($commessa === '') {
|
||||||
|
throw new Exception("Parametro commessa mancante");
|
||||||
|
}
|
||||||
|
|
||||||
|
$debugDir = __DIR__ . '/logs/lims_rapporto/';
|
||||||
|
if (!is_dir($debugDir)) {
|
||||||
|
mkdir($debugDir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STEP 1
|
||||||
|
* Provo a cercare il rapporto con filtri leggeri.
|
||||||
|
* NIENTE expand pesanti.
|
||||||
|
*/
|
||||||
|
$attempts = [];
|
||||||
|
|
||||||
|
$filters = [
|
||||||
|
'CodiceCommessa' => "CodiceCommessa eq '{$commessa}'",
|
||||||
|
'Commessa_CodiceCommessa' => "Commessa/CodiceCommessa eq '{$commessa}'",
|
||||||
|
'Commessa_IdCommessa' => is_numeric($commessa) ? "Commessa/IdCommessa eq {$commessa}" : null,
|
||||||
|
'Codice' => "Codice eq '{$commessa}'"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($filters as $label => $filter) {
|
||||||
|
if (!$filter) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$options = [
|
||||||
|
'$filter' => $filter,
|
||||||
|
'$top' => 10
|
||||||
|
];
|
||||||
|
|
||||||
|
$data = $api->get('Rapporto', $options);
|
||||||
|
|
||||||
|
$attempts[$label] = [
|
||||||
|
'success' => true,
|
||||||
|
'filter' => $filter,
|
||||||
|
'records' => isset($data['value']) && is_array($data['value']) ? count($data['value']) : null,
|
||||||
|
'data' => $data
|
||||||
|
];
|
||||||
|
|
||||||
|
file_put_contents(
|
||||||
|
$debugDir . "rapporto_{$commessa}_{$label}.json",
|
||||||
|
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$attempts[$label] = [
|
||||||
|
'success' => false,
|
||||||
|
'filter' => $filter,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STEP 2
|
||||||
|
* Prendo solo eventuali rapporti trovati.
|
||||||
|
*/
|
||||||
|
$rapportiFound = [];
|
||||||
|
|
||||||
|
foreach ($attempts as $label => $attempt) {
|
||||||
|
if (!$attempt['success']) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = $attempt['data']['value'] ?? [];
|
||||||
|
|
||||||
|
if (!is_array($items)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$rapportiFound[] = [
|
||||||
|
'matched_by' => $label,
|
||||||
|
'rapporto' => $item
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'input_commessa' => $commessa,
|
||||||
|
'message' => 'Ricerca leggera su Rapporto completata. Se trovi un rapporto, poi recuperiamo RapportiFiles solo per quello.',
|
||||||
|
'rapporti_found_count' => count($rapportiFound),
|
||||||
|
'rapporti_found' => $rapportiFound,
|
||||||
|
'attempts_summary' => array_map(function ($a) {
|
||||||
|
return [
|
||||||
|
'success' => $a['success'],
|
||||||
|
'filter' => $a['filter'],
|
||||||
|
'records' => $a['records'] ?? null,
|
||||||
|
'error' => $a['error'] ?? null
|
||||||
|
];
|
||||||
|
}, $attempts)
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
@@ -2,25 +2,140 @@
|
|||||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
ini_set('display_errors', '0');
|
ini_set('display_errors', '0');
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$api = VisualLimsApiClient::getInstance();
|
$api = VisualLimsApiClient::getInstance();
|
||||||
$rapporto_id = 533329;
|
|
||||||
|
|
||||||
// Costruzione manuale dell'endpoint con espansione annidata
|
// Esempi:
|
||||||
$endpoint = "Rapporto($rapporto_id)?\$expand=CampioniDatiRapporto(\$expand=AnalisiDatiRapporto,CustomFieldsDatiRapporto)";
|
// rapporto_by_codice_expand_step.php?codice=2541111&step=base
|
||||||
|
// rapporto_by_codice_expand_step.php?codice=2541111&step=files
|
||||||
|
// rapporto_by_codice_expand_step.php?codice=2541111&step=campioni
|
||||||
|
// rapporto_by_codice_expand_step.php?codice=2541111&step=files_campioni
|
||||||
|
|
||||||
// Non passiamo options, già incluso nell'endpoint
|
$codiceRapporto = trim($_GET['codice'] ?? '');
|
||||||
$data = $api->get($endpoint);
|
$step = trim($_GET['step'] ?? 'base');
|
||||||
|
|
||||||
file_put_contents(__DIR__ . '/rapporto_expanded.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
if ($codiceRapporto === '') {
|
||||||
echo json_encode($data);
|
throw new Exception("Parametro codice mancante. Usa ?codice=2541111");
|
||||||
|
}
|
||||||
|
|
||||||
|
$allowedSteps = [
|
||||||
|
'base' => '',
|
||||||
|
'files' => 'RapportiFiles',
|
||||||
|
'allegati' => 'RapportiAllegati',
|
||||||
|
'campioni' => 'CampioniDatiRapporto',
|
||||||
|
'files_campioni' => 'RapportiFiles,CampioniDatiRapporto'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!array_key_exists($step, $allowedSteps)) {
|
||||||
|
throw new Exception("Step non valido. Usa: " . implode(', ', array_keys($allowedSteps)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape OData per eventuali apostrofi
|
||||||
|
$codiceRapportoSafe = str_replace("'", "''", $codiceRapporto);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* STEP 1 - Trova IdRapporto partendo da CodiceRapporto.
|
||||||
|
* Query leggera, con $select e $top=1.
|
||||||
|
*/
|
||||||
|
$searchParams = [
|
||||||
|
'$filter' => "CodiceRapporto eq '{$codiceRapportoSafe}'",
|
||||||
|
'$select' => 'IdRapporto,CodiceRapporto,Data,Versione,Firmato,DataStampa',
|
||||||
|
'$top' => 1
|
||||||
|
];
|
||||||
|
|
||||||
|
$searchEndpoint = "Rapporto?" . http_build_query($searchParams);
|
||||||
|
|
||||||
|
$searchData = $api->get($searchEndpoint);
|
||||||
|
|
||||||
|
$items = $searchData['value'] ?? [];
|
||||||
|
|
||||||
|
if (!is_array($items) || count($items) === 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Nessun rapporto trovato per questo CodiceRapporto.',
|
||||||
|
'codice_rapporto' => $codiceRapporto,
|
||||||
|
'search_endpoint' => $searchEndpoint,
|
||||||
|
'search_data' => $searchData
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$rapportoBase = $items[0];
|
||||||
|
$rapportoId = intval($rapportoBase['IdRapporto'] ?? 0);
|
||||||
|
|
||||||
|
if (!$rapportoId) {
|
||||||
|
throw new Exception("IdRapporto non trovato nella risposta.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* STEP 2 - Se step=base, restituisco solo la ricerca base.
|
||||||
|
*/
|
||||||
|
if ($step === 'base') {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'codice_rapporto' => $codiceRapporto,
|
||||||
|
'id_rapporto' => $rapportoId,
|
||||||
|
'step' => $step,
|
||||||
|
'search_endpoint' => $searchEndpoint,
|
||||||
|
'rapporto_base' => $rapportoBase
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* STEP 3 - Espande SOLO il rapporto trovato.
|
||||||
|
*/
|
||||||
|
$expandValue = $allowedSteps[$step];
|
||||||
|
|
||||||
|
$detailParams = [
|
||||||
|
'$expand' => $expandValue
|
||||||
|
];
|
||||||
|
|
||||||
|
$detailEndpoint = "Rapporto({$rapportoId})?" . http_build_query($detailParams);
|
||||||
|
|
||||||
|
file_put_contents(
|
||||||
|
__DIR__ . '/last_rapporto_by_codice_expand_endpoint.txt',
|
||||||
|
'[' . date('Y-m-d H:i:s') . '] SEARCH: ' . $searchEndpoint . PHP_EOL .
|
||||||
|
'[' . date('Y-m-d H:i:s') . '] DETAIL: ' . $detailEndpoint . PHP_EOL,
|
||||||
|
FILE_APPEND
|
||||||
|
);
|
||||||
|
|
||||||
|
$detailData = $api->get($detailEndpoint);
|
||||||
|
|
||||||
|
file_put_contents(
|
||||||
|
__DIR__ . "/rapporto_codice_{$codiceRapportoSafe}_{$step}.json",
|
||||||
|
json_encode([
|
||||||
|
'search' => $searchData,
|
||||||
|
'detail' => $detailData
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
|
||||||
|
);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'codice_rapporto' => $codiceRapporto,
|
||||||
|
'id_rapporto' => $rapportoId,
|
||||||
|
'step' => $step,
|
||||||
|
'search_endpoint' => $searchEndpoint,
|
||||||
|
'detail_endpoint' => $detailEndpoint,
|
||||||
|
'rapporto_base' => $rapportoBase,
|
||||||
|
'data' => $detailData
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
file_put_contents(
|
||||||
|
__DIR__ . '/error_log.txt',
|
||||||
|
date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL,
|
||||||
|
FILE_APPEND
|
||||||
|
);
|
||||||
|
|
||||||
http_response_code(500);
|
http_response_code(500);
|
||||||
echo json_encode(['error' => $e->getMessage()]);
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,20 @@
|
|||||||
// ── Client data (AJAX Select2, no bulk loading) ──────────────────────
|
// ── Client data (AJAX Select2, no bulk loading) ──────────────────────
|
||||||
|
|
||||||
function formatClientLabel(client) {
|
function formatClientLabel(client) {
|
||||||
return (client.Nominativo || "").trim();
|
const nome = client.Nominativo || client.text || "Nome non disponibile";
|
||||||
|
const id = client.IdCliente || client.id || "";
|
||||||
|
const codiceCliente = (
|
||||||
|
client.CodiceCliente ??
|
||||||
|
client.codiceCliente ??
|
||||||
|
""
|
||||||
|
)
|
||||||
|
.toString()
|
||||||
|
.trim();
|
||||||
|
const suffix = (codiceCliente.split("_")[1] || "").trim();
|
||||||
|
const shortCode =
|
||||||
|
suffix || (codiceCliente ? codiceCliente.charAt(0) : "--");
|
||||||
|
|
||||||
|
return `${nome.trim()} - ${shortCode} (ID: ${id})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache of resolved client names: id → name
|
// Cache of resolved client names: id → name
|
||||||
@@ -102,7 +115,9 @@
|
|||||||
);
|
);
|
||||||
const json = await resp.json();
|
const json = await resp.json();
|
||||||
const item = (json.results || [])[0];
|
const item = (json.results || [])[0];
|
||||||
if (item) clientNameCache[id] = item.text;
|
if (item) {
|
||||||
|
clientNameCache[id] = formatClientLabel(item);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
/* ignore */
|
/* ignore */
|
||||||
}
|
}
|
||||||
@@ -125,7 +140,12 @@
|
|||||||
return { q: params.term || "", limit: 20 };
|
return { q: params.term || "", limit: 20 };
|
||||||
},
|
},
|
||||||
processResults: function (data) {
|
processResults: function (data) {
|
||||||
return { results: data.results || [] };
|
const results = (data.results || []).map((item) => ({
|
||||||
|
...item,
|
||||||
|
text: formatClientLabel(item),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return { results: results };
|
||||||
},
|
},
|
||||||
cache: true,
|
cache: true,
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
set_time_limit(20);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
|
$start = microtime(true);
|
||||||
|
|
||||||
|
// Chiamata minima: 1 solo record, 1 solo campo
|
||||||
|
$data = $api->get('Rapporto', [
|
||||||
|
'$top' => 1,
|
||||||
|
'$select' => 'IdRapporto'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$elapsed = round(microtime(true) - $start, 3);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'elapsed_seconds' => $elapsed,
|
||||||
|
'data' => $data
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
@@ -16,9 +16,11 @@ if (!$data || !isset($data['id'])) {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
$mappingId = $data['id'];
|
$mappingId = (int)$data['id'];
|
||||||
$mappingType = $data['mapping_type'] ?? '';
|
$mappingType = $data['mapping_type'] ?? '';
|
||||||
|
|
||||||
$excelColumn = $data['excel_column'] ?? null;
|
$excelColumn = $data['excel_column'] ?? null;
|
||||||
|
$jsonNode = $data['json_node'] ?? null;
|
||||||
$manualDefault = $data['manual_default'] ?? null;
|
$manualDefault = $data['manual_default'] ?? null;
|
||||||
|
|
||||||
$autoValue = $data['auto_value'] ?? 'none';
|
$autoValue = $data['auto_value'] ?? 'none';
|
||||||
@@ -26,7 +28,7 @@ $tablename = $data['tablename'] ?? '';
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Normalize mapping type
|
// Normalize mapping type
|
||||||
$allowedTypes = ['', 'xls', 'manual', 'auto'];
|
$allowedTypes = ['', 'xls', 'json', 'manual', 'auto'];
|
||||||
if (!in_array($mappingType, $allowedTypes, true)) {
|
if (!in_array($mappingType, $allowedTypes, true)) {
|
||||||
echo json_encode(["success" => false, "message" => "Invalid mapping_type"]);
|
echo json_encode(["success" => false, "message" => "Invalid mapping_type"]);
|
||||||
exit;
|
exit;
|
||||||
@@ -41,43 +43,67 @@ try {
|
|||||||
// Decide what to persist based on mapping_type
|
// Decide what to persist based on mapping_type
|
||||||
$isManual = 0;
|
$isManual = 0;
|
||||||
$excelToSave = null;
|
$excelToSave = null;
|
||||||
|
$jsonNodeToSave = null;
|
||||||
$manualToSave = null;
|
$manualToSave = null;
|
||||||
$autoToSave = 'none';
|
$autoToSave = 'none';
|
||||||
|
|
||||||
if ($mappingType === 'xls') {
|
if ($mappingType === 'xls') {
|
||||||
|
|
||||||
$isManual = 0;
|
$isManual = 0;
|
||||||
$excelToSave = $excelColumn ?: null;
|
$excelToSave = $excelColumn ?: null;
|
||||||
|
$jsonNodeToSave = null;
|
||||||
|
$manualToSave = null;
|
||||||
|
$autoToSave = 'none';
|
||||||
|
} elseif ($mappingType === 'json') {
|
||||||
|
|
||||||
|
$isManual = 0;
|
||||||
|
$excelToSave = null;
|
||||||
|
$jsonNodeToSave = $jsonNode ?: null;
|
||||||
$manualToSave = null;
|
$manualToSave = null;
|
||||||
$autoToSave = 'none';
|
$autoToSave = 'none';
|
||||||
} elseif ($mappingType === 'manual') {
|
} elseif ($mappingType === 'manual') {
|
||||||
|
|
||||||
$isManual = 1;
|
$isManual = 1;
|
||||||
$excelToSave = null;
|
$excelToSave = null;
|
||||||
|
$jsonNodeToSave = null;
|
||||||
$manualToSave = $manualDefault;
|
$manualToSave = $manualDefault;
|
||||||
$autoToSave = 'none';
|
$autoToSave = 'none';
|
||||||
} elseif ($mappingType === 'auto') {
|
} elseif ($mappingType === 'auto') {
|
||||||
|
|
||||||
$isManual = 0;
|
$isManual = 0;
|
||||||
$excelToSave = null;
|
$excelToSave = null;
|
||||||
|
$jsonNodeToSave = null;
|
||||||
$manualToSave = null;
|
$manualToSave = null;
|
||||||
$autoToSave = $autoValue ?: 'none';
|
$autoToSave = $autoValue ?: 'none';
|
||||||
} else {
|
} else {
|
||||||
// reset
|
|
||||||
|
// Reset mapping
|
||||||
$isManual = 0;
|
$isManual = 0;
|
||||||
$excelToSave = null;
|
$excelToSave = null;
|
||||||
|
$jsonNodeToSave = null;
|
||||||
$manualToSave = null;
|
$manualToSave = null;
|
||||||
$autoToSave = 'none';
|
$autoToSave = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare("
|
$stmt = $pdo->prepare("
|
||||||
UPDATE template_mapping
|
UPDATE template_mapping
|
||||||
SET
|
SET
|
||||||
is_manual = ?,
|
is_manual = ?,
|
||||||
excel_column = ?,
|
excel_column = ?,
|
||||||
manual_default = ?,
|
json_node = ?,
|
||||||
auto_value = ?
|
manual_default = ?,
|
||||||
WHERE id = ?
|
auto_value = ?
|
||||||
");
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
$result = $stmt->execute([$isManual, $excelToSave, $manualToSave, $autoToSave, $mappingId]);
|
$result = $stmt->execute([
|
||||||
|
$isManual,
|
||||||
|
$excelToSave,
|
||||||
|
$jsonNodeToSave,
|
||||||
|
$manualToSave,
|
||||||
|
$autoToSave,
|
||||||
|
$mappingId
|
||||||
|
]);
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
echo json_encode(["success" => false, "message" => "Database update failed"]);
|
echo json_encode(["success" => false, "message" => "Database update failed"]);
|
||||||
@@ -88,15 +114,17 @@ try {
|
|||||||
"success" => true,
|
"success" => true,
|
||||||
"message" => "Mapping updated successfully",
|
"message" => "Mapping updated successfully",
|
||||||
"saved" => [
|
"saved" => [
|
||||||
"id" => (int)$mappingId,
|
"id" => $mappingId,
|
||||||
"mapping_type" => $mappingType,
|
"mapping_type" => $mappingType,
|
||||||
"is_manual" => $isManual,
|
"is_manual" => $isManual,
|
||||||
"excel_column" => $excelToSave,
|
"excel_column" => $excelToSave,
|
||||||
|
"json_node" => $jsonNodeToSave,
|
||||||
"manual_default" => $manualToSave,
|
"manual_default" => $manualToSave,
|
||||||
"auto_value" => $autoToSave
|
"auto_value" => $autoToSave
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
} catch (Exception $e) {
|
} catch (Throwable $e) {
|
||||||
echo json_encode(["success" => false, "message" => "Error: " . $e->getMessage()]);
|
echo json_encode(["success" => false, "message" => "Error: " . $e->getMessage()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -2,7 +2,12 @@
|
|||||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
require_once __DIR__ . '/class/db-functions.php';
|
require_once __DIR__ . '/class/db-functions.php';
|
||||||
include dirname(__DIR__) . '/../extra/auth.php';
|
include dirname(__DIR__) . '/../extra/auth.php';
|
||||||
if (!Auth::check()) { http_response_code(401); echo json_encode(['error' => 'Unauthorized']); exit; }
|
|
||||||
|
if (!Auth::check()) {
|
||||||
|
http_response_code(401);
|
||||||
|
echo json_encode(['error' => 'Unauthorized']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/class/VisualLimsApiClient.class.php';
|
require_once __DIR__ . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
@@ -14,44 +19,95 @@ $q = mb_strtolower(trim($_GET['q'] ?? ''));
|
|||||||
$limit = max(1, min(50, intval($_GET['limit'] ?? 20)));
|
$limit = max(1, min(50, intval($_GET['limit'] ?? 20)));
|
||||||
$id = isset($_GET['id']) ? intval($_GET['id']) : null;
|
$id = isset($_GET['id']) ? intval($_GET['id']) : null;
|
||||||
|
|
||||||
|
function formatClientLabel(array $client): string
|
||||||
|
{
|
||||||
|
$name = trim($client['Nominativo'] ?? '');
|
||||||
|
$id = trim((string)($client['IdCliente'] ?? ''));
|
||||||
|
$code = trim((string)($client['CodiceCliente'] ?? ''));
|
||||||
|
|
||||||
|
$parts = explode('_', $code);
|
||||||
|
$suffix = trim($parts[1] ?? '');
|
||||||
|
|
||||||
|
if ($suffix === '' && $code !== '') {
|
||||||
|
$suffix = substr($code, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($suffix === '') {
|
||||||
|
$suffix = '--';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $name . ' - ' . $suffix . ' (ID: ' . $id . ')';
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Load from cache or API
|
// Load from cache or API
|
||||||
$cacheFile = __DIR__ . '/cache/clienti.json';
|
$cacheFile = __DIR__ . '/cache/clienti.json';
|
||||||
|
|
||||||
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 3600)) {
|
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 3600)) {
|
||||||
$data = json_decode(file_get_contents($cacheFile), true);
|
$data = json_decode(file_get_contents($cacheFile), true);
|
||||||
} else {
|
} else {
|
||||||
$api = VisualLimsApiClient::getInstance();
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'$select' => 'IdCliente,Nominativo,CodiceCliente',
|
'$select' => 'IdCliente,Nominativo,CodiceCliente',
|
||||||
'$orderby' => 'Nominativo asc'
|
'$orderby' => 'Nominativo asc'
|
||||||
];
|
];
|
||||||
|
|
||||||
$data = $api->get("Cliente?" . http_build_query($params));
|
$data = $api->get("Cliente?" . http_build_query($params));
|
||||||
if (!is_dir(__DIR__ . '/cache')) mkdir(__DIR__ . '/cache', 0777, true);
|
|
||||||
|
if (!is_dir(__DIR__ . '/cache')) {
|
||||||
|
mkdir(__DIR__ . '/cache', 0777, true);
|
||||||
|
}
|
||||||
|
|
||||||
file_put_contents($cacheFile, json_encode($data));
|
file_put_contents($cacheFile, json_encode($data));
|
||||||
}
|
}
|
||||||
|
|
||||||
$clients = $data['value'] ?? [];
|
$clients = $data['value'] ?? [];
|
||||||
|
|
||||||
// If requesting by specific ID (for loading selected value)
|
// If requesting by specific ID, used for loading selected value
|
||||||
if ($id !== null) {
|
if ($id !== null) {
|
||||||
foreach ($clients as $c) {
|
foreach ($clients as $c) {
|
||||||
if ((int)$c['IdCliente'] === $id) {
|
if ((int)$c['IdCliente'] === $id) {
|
||||||
echo json_encode(['results' => [['id' => $c['IdCliente'], 'text' => trim($c['Nominativo'] ?? '')]]]);
|
echo json_encode([
|
||||||
|
'results' => [[
|
||||||
|
'id' => $c['IdCliente'],
|
||||||
|
'text' => formatClientLabel($c),
|
||||||
|
'IdCliente' => $c['IdCliente'],
|
||||||
|
'Nominativo' => trim($c['Nominativo'] ?? ''),
|
||||||
|
'CodiceCliente' => trim($c['CodiceCliente'] ?? '')
|
||||||
|
]]
|
||||||
|
]);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo json_encode(['results' => []]);
|
echo json_encode(['results' => []]);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search by query
|
// Search by query
|
||||||
$results = [];
|
$results = [];
|
||||||
|
|
||||||
foreach ($clients as $c) {
|
foreach ($clients as $c) {
|
||||||
$name = trim($c['Nominativo'] ?? '');
|
$name = trim($c['Nominativo'] ?? '');
|
||||||
$code = trim($c['CodiceCliente'] ?? '');
|
$code = trim($c['CodiceCliente'] ?? '');
|
||||||
if ($q === '' || mb_strpos(mb_strtolower($name), $q) !== false || mb_strpos(mb_strtolower($code), $q) !== false) {
|
|
||||||
$results[] = ['id' => $c['IdCliente'], 'text' => $name];
|
if (
|
||||||
if (count($results) >= $limit) break;
|
$q === '' ||
|
||||||
|
mb_strpos(mb_strtolower($name), $q) !== false ||
|
||||||
|
mb_strpos(mb_strtolower($code), $q) !== false
|
||||||
|
) {
|
||||||
|
$results[] = [
|
||||||
|
'id' => $c['IdCliente'],
|
||||||
|
'text' => formatClientLabel($c),
|
||||||
|
'IdCliente' => $c['IdCliente'],
|
||||||
|
'Nominativo' => $name,
|
||||||
|
'CodiceCliente' => $code
|
||||||
|
];
|
||||||
|
|
||||||
|
if (count($results) >= $limit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
|
// Esempio: search_rapporto_min.php?codice=2621716
|
||||||
|
$codice = trim($_GET['codice'] ?? '');
|
||||||
|
|
||||||
|
if ($codice === '') {
|
||||||
|
throw new Exception("Parametro codice mancante. Usa ?codice=2621716");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minimal:
|
||||||
|
* - niente expand
|
||||||
|
* - max 5 record
|
||||||
|
* - pochi campi
|
||||||
|
*
|
||||||
|
* Se il campo Codice non è quello giusto, sotto proviamo anche CodiceRapporto.
|
||||||
|
*/
|
||||||
|
$attempts = [];
|
||||||
|
|
||||||
|
$filters = [
|
||||||
|
'Codice' => "Codice eq '{$codice}'",
|
||||||
|
'CodiceRapporto' => "CodiceRapporto eq '{$codice}'",
|
||||||
|
'Numero' => "Numero eq '{$codice}'"
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($filters as $label => $filter) {
|
||||||
|
try {
|
||||||
|
$data = $api->get('Rapporto', [
|
||||||
|
'$filter' => $filter,
|
||||||
|
'$top' => 5,
|
||||||
|
'$select' => 'IdRapporto,Codice,CodiceRapporto,Numero,Data,Versione,Cliente'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$attempts[$label] = [
|
||||||
|
'success' => true,
|
||||||
|
'filter' => $filter,
|
||||||
|
'records' => isset($data['value']) && is_array($data['value']) ? count($data['value']) : null,
|
||||||
|
'data' => $data
|
||||||
|
];
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$attempts[$label] = [
|
||||||
|
'success' => false,
|
||||||
|
'filter' => $filter,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'input_codice' => $codice,
|
||||||
|
'attempts' => $attempts
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage()
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
|
ini_set('display_errors', '1');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
set_time_limit(60);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uso: get_pdf.php?id=591749
|
||||||
|
*/
|
||||||
|
|
||||||
|
try {
|
||||||
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
|
$idRapportoFile = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||||
|
|
||||||
|
if (!$idRapportoFile) {
|
||||||
|
throw new Exception("Parametro id mancante. Usa ?id=591749");
|
||||||
|
}
|
||||||
|
|
||||||
|
// STEP 1: leggi metadati entita
|
||||||
|
$entityData = $api->get("RapportoFile(" . $idRapportoFile . ")");
|
||||||
|
|
||||||
|
$pdfBody = null;
|
||||||
|
$strategyUsed = null;
|
||||||
|
$debugLog = array();
|
||||||
|
|
||||||
|
// Strategia A - campo FileContent base64
|
||||||
|
if (!empty($entityData['FileContent'])) {
|
||||||
|
$decoded = base64_decode($entityData['FileContent'], true);
|
||||||
|
if ($decoded !== false && substr($decoded, 0, 4) === '%PDF') {
|
||||||
|
$pdfBody = $decoded;
|
||||||
|
$strategyUsed = 'A: FileContent base64';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strategia B - campo Contenuto base64
|
||||||
|
if (!$pdfBody && !empty($entityData['Contenuto'])) {
|
||||||
|
$decoded = base64_decode($entityData['Contenuto'], true);
|
||||||
|
if ($decoded !== false && substr($decoded, 0, 4) === '%PDF') {
|
||||||
|
$pdfBody = $decoded;
|
||||||
|
$strategyUsed = 'B: Contenuto base64';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recupera token e baseUrl dalla classe
|
||||||
|
$token = $api->getToken();
|
||||||
|
$baseUrl = rtrim($api->getBaseUrl(), '/');
|
||||||
|
|
||||||
|
$rawEndpoints = array(
|
||||||
|
'C: $value' => $baseUrl . '/api/odata/RapportoFile(' . $idRapportoFile . ')/$value',
|
||||||
|
'D: FileContent/$value' => $baseUrl . '/api/odata/RapportoFile(' . $idRapportoFile . ')/FileContent/$value',
|
||||||
|
'E: Contenuto/$value' => $baseUrl . '/api/odata/RapportoFile(' . $idRapportoFile . ')/Contenuto/$value',
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rawEndpoints as $label => $url) {
|
||||||
|
if ($pdfBody) break;
|
||||||
|
|
||||||
|
$ch = curl_init($url);
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||||
|
'Authorization: Bearer ' . $token,
|
||||||
|
'Accept: application/pdf, application/octet-stream, */*',
|
||||||
|
));
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||||
|
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||||
|
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||||
|
|
||||||
|
$body = curl_exec($ch);
|
||||||
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
$ct = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
$debugLog[$label] = array(
|
||||||
|
'url' => $url,
|
||||||
|
'http_code' => $httpCode,
|
||||||
|
'content_type' => $ct,
|
||||||
|
'body_start' => substr((string)$body, 0, 300),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($httpCode === 200 && is_string($body) && substr($body, 0, 4) === '%PDF') {
|
||||||
|
$pdfBody = $body;
|
||||||
|
$strategyUsed = $label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RISPOSTA
|
||||||
|
if ($pdfBody) {
|
||||||
|
$fileName = isset($entityData['FileName']) ? $entityData['FileName'] : 'rapporto_' . $idRapportoFile . '.pdf';
|
||||||
|
header('Content-Type: application/pdf');
|
||||||
|
header('Content-Disposition: inline; filename="' . $fileName . '"');
|
||||||
|
header('Content-Length: ' . strlen($pdfBody));
|
||||||
|
header('Cache-Control: private, max-age=0, must-revalidate');
|
||||||
|
echo $pdfBody;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nessuna strategia ha funzionato
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
echo json_encode(array(
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Nessuna strategia ha restituito un PDF valido.',
|
||||||
|
'id_rapporto_file' => $idRapportoFile,
|
||||||
|
'entity_fields' => array_keys($entityData ? $entityData : array()),
|
||||||
|
'entity_data' => $entityData,
|
||||||
|
'strategies_debug' => $debugLog,
|
||||||
|
), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
echo json_encode(array(
|
||||||
|
'success' => false,
|
||||||
|
'error' => $e->getMessage(),
|
||||||
|
), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$input = json_decode(file_get_contents('php://input'), true);
|
||||||
|
|
||||||
|
if (!$input) {
|
||||||
|
throw new Exception('Invalid JSON payload');
|
||||||
|
}
|
||||||
|
|
||||||
|
$templateId = isset($input['template_id']) ? (int)$input['template_id'] : 0;
|
||||||
|
$apiSampleJson = $input['api_sample_json'] ?? '';
|
||||||
|
$jsonNodes = $input['json_nodes'] ?? '';
|
||||||
|
|
||||||
|
if ($templateId <= 0) {
|
||||||
|
throw new Exception('Invalid template ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trim($apiSampleJson) === '') {
|
||||||
|
throw new Exception('API sample JSON is empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
json_decode($apiSampleJson, true);
|
||||||
|
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
throw new Exception('Invalid API sample JSON: ' . json_last_error_msg());
|
||||||
|
}
|
||||||
|
|
||||||
|
$decodedNodes = json_decode($jsonNodes, true);
|
||||||
|
|
||||||
|
if (!is_array($decodedNodes)) {
|
||||||
|
throw new Exception('Invalid JSON nodes array');
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE excel_templates
|
||||||
|
SET
|
||||||
|
api_sample_json = ?,
|
||||||
|
json_nodes = ?
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$apiSampleJson,
|
||||||
|
json_encode($decodedNodes, JSON_UNESCAPED_UNICODE),
|
||||||
|
$templateId
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'nodes_count' => count($decodedNodes)
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user