Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e4a627ca7 | |||
| 25d4519684 | |||
| 34d4dc8660 | |||
| 1510ef03f1 | |||
| ce8c95921f | |||
| 095a6ae879 | |||
| 296143016a | |||
| 3aa2504f3c | |||
| c1a396f246 | |||
| a45ba1c8b3 | |||
| 7a944a73f7 | |||
| 71595cc8de | |||
| f89dbd0c23 | |||
| 9ba859e15b | |||
| 672e448e9a | |||
| 0749032fbc | |||
| d692614f70 | |||
| 1303cff9fd | |||
| 6b2bd0964b | |||
| 0d2cf13524 | |||
| f6ef9c39d2 | |||
| 7e4ed56f28 | |||
| 4d0644f46c | |||
| 712042b8d8 | |||
| efee12740d | |||
| 14395810d0 | |||
| 03002a8938 | |||
| 21fcee8ff5 | |||
| 1361340928 | |||
| 1bda30e957 | |||
| a87423d879 | |||
| 24cda34681 | |||
| 2c514a8ab6 | |||
| b1ea728c15 | |||
| caf5568779 | |||
| 0728fd8f01 | |||
| 9d5c20113f | |||
| 47762a8557 | |||
| 434bb0d993 | |||
| 939a4fe03e | |||
| 493de65892 | |||
| 23ae8e1b1d | |||
| 7ad20993d9 |
@@ -1,45 +0,0 @@
|
||||
APP_ENV=production
|
||||
APP_DEBUG=true
|
||||
APP_KEY=base64:C+sutHm6xP5sE4QXhoZFhYjArlVN11s2mDU1F8beUkM=
|
||||
APP_URL=http://vanguard.test
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST="localhost"
|
||||
DB_DATABASE="trfcertest"
|
||||
DB_USERNAME="solocla"
|
||||
DB_PASSWORD="!Massarosa2"
|
||||
DB_PREFIX="auth_"
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=mail
|
||||
MAIL_FROM_NAME=Vanguard
|
||||
MAIL_FROM_ADDRESS=vanguard@test.dev
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# Credenziali API VisualLims
|
||||
API_BASE_URL=https://93.43.5.102/limsapi
|
||||
API_USERNAME=WebApiUser
|
||||
API_PASSWORD=webapiuser01
|
||||
@@ -36,3 +36,19 @@ auth.json
|
||||
# Ignora cartelle di foto generate
|
||||
/public/photostrf/
|
||||
/public/photostrf/qrcodes/
|
||||
public/userarea/import_debug.log
|
||||
public/userarea/last_url.txt
|
||||
public/userarea/class/curl_auth_debug.log
|
||||
public/userarea/class/curl_request_debug.log
|
||||
public/userarea/last_url.txt
|
||||
public/userarea/class/curl_auth_debug.log
|
||||
public/userarea/class/curl_request_debug.log
|
||||
|
||||
# Ignora tutti i log
|
||||
*.log
|
||||
|
||||
|
||||
# Ignora cartella photostrf in public/userarea
|
||||
/public/userarea/photostrf/
|
||||
public/userarea/customfield_values_response.json
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Userarea;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class UploadPhotosMobileController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$iddatadb = $request->query('iddatadb');
|
||||
|
||||
if (empty($iddatadb)) {
|
||||
return response('ID riga non fornito', 400);
|
||||
}
|
||||
|
||||
// Show the upload form
|
||||
return view('userarea.upload_photos_mobile', [
|
||||
'iddatadb' => $iddatadb
|
||||
]);
|
||||
}
|
||||
|
||||
public function upload(Request $request)
|
||||
{
|
||||
// Validation
|
||||
$request->validate([
|
||||
'photo' => 'required|file|mimes:jpeg,png,gif,heic,heif|max:5120', // 5MB
|
||||
'iddatadb' => 'required|integer'
|
||||
]);
|
||||
|
||||
$iddatadb = $request->input('iddatadb');
|
||||
$photo = $request->file('photo');
|
||||
$iduserlogin = auth()->id(); // assuming Laravel authentication
|
||||
|
||||
// Check if user exists
|
||||
$userExists = DB::table('auth_users')->where('id', $iduserlogin)->exists();
|
||||
if (!$userExists) {
|
||||
return response()->json(['success' => false, 'message' => 'Utente non valido']);
|
||||
}
|
||||
|
||||
// Upload folder
|
||||
$uploadDir = public_path('photostrf');
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
if (!is_writable($uploadDir)) {
|
||||
return response()->json(['success' => false, 'message' => 'La cartella photostrf non è scrivibile']);
|
||||
}
|
||||
|
||||
// New filename
|
||||
$timestamp = now()->format('YmdHis');
|
||||
$originalName = pathinfo($photo->getClientOriginalName(), PATHINFO_FILENAME);
|
||||
$extension = strtolower($photo->getClientOriginalExtension());
|
||||
|
||||
$newFileName = "{$iddatadb}-{$timestamp}-{$originalName}.{$extension}";
|
||||
$destination = $uploadDir . '/' . $newFileName;
|
||||
|
||||
// Move uploaded file
|
||||
$photo->move($uploadDir, $newFileName);
|
||||
|
||||
// Save DB record
|
||||
DB::table('datadb_photos')->insert([
|
||||
'iddatadb' => $iddatadb,
|
||||
'file_path' => $newFileName,
|
||||
'file_name' => $newFileName,
|
||||
'uploaded_by' => $iduserlogin
|
||||
]);
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Foto caricata con successo']);
|
||||
}
|
||||
}
|
||||
@@ -32,3 +32,4 @@ $langdatatables = [
|
||||
"paginate_next" => "Next",
|
||||
"paginate_previous" => "Previous"
|
||||
];
|
||||
$quotationstitle = "Quotations";
|
||||
|
||||
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 451 B |
|
After Width: | Height: | Size: 510 B |
|
After Width: | Height: | Size: 462 B |
|
After Width: | Height: | Size: 443 B |
|
After Width: | Height: | Size: 460 B |
|
After Width: | Height: | Size: 454 B |
|
After Width: | Height: | Size: 456 B |
|
After Width: | Height: | Size: 460 B |
|
After Width: | Height: | Size: 457 B |
|
After Width: | Height: | Size: 454 B |
|
After Width: | Height: | Size: 455 B |
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
class VisualLimsApiClientXml
|
||||
{
|
||||
private static $instance = null;
|
||||
private $baseUrl;
|
||||
private $username;
|
||||
private $password;
|
||||
private $token = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$dotenv = Dotenv::createImmutable(dirname(__DIR__, 3));
|
||||
$dotenv->load();
|
||||
|
||||
$this->baseUrl = $_ENV['API_BASE_URL'];
|
||||
$this->username = $_ENV['API_USERNAME'];
|
||||
$this->password = $_ENV['API_PASSWORD'];
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new VisualLimsApiClientXml();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function authenticate()
|
||||
{
|
||||
$ch = curl_init("{$this->baseUrl}/api/authentication/authenticate");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
||||
'Username' => $this->username,
|
||||
'Password' => $this->password
|
||||
]));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Accept: application/json'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_auth_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false || $http_code != 200) {
|
||||
throw new Exception("Autenticazione fallita: HTTP {$http_code}, Errore cURL: {$curl_error}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
$token_data = json_decode($response, true);
|
||||
$this->token = null;
|
||||
|
||||
if (is_array($token_data) && isset($token_data['token'])) {
|
||||
$this->token = $token_data['token'];
|
||||
} elseif (is_string($token_data) && !empty($token_data)) {
|
||||
$this->token = trim($token_data, '"');
|
||||
} elseif (is_string($response) && !empty($response)) {
|
||||
$this->token = trim($response, '"');
|
||||
}
|
||||
|
||||
if (empty($this->token)) {
|
||||
throw new Exception("Token non ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
private function getToken()
|
||||
{
|
||||
if ($this->token === null) {
|
||||
$this->authenticate();
|
||||
}
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
public function get($endpoint, $options = [])
|
||||
{
|
||||
$token = $this->getToken();
|
||||
$query = http_build_query($options);
|
||||
$url = "{$this->baseUrl}/api/odata/{$endpoint}" . ($query ? '?' . $query : '');
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer {$token}",
|
||||
"Accept: application/xml"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_request_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception("Errore nella richiesta: {$curl_error}");
|
||||
}
|
||||
|
||||
if ($http_code !== 200) {
|
||||
throw new Exception("Errore nel recupero dati: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
// Verifica che la risposta sia XML
|
||||
if (strpos($response, '<?xml') !== 0) {
|
||||
throw new Exception("Risposta non valida: atteso formato XML, ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
class VisualLimsApiClientXml
|
||||
{
|
||||
private static $instance = null;
|
||||
private $baseUrl;
|
||||
private $username;
|
||||
private $password;
|
||||
private $token = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$dotenv = Dotenv::createImmutable(dirname(__DIR__, 3));
|
||||
$dotenv->load();
|
||||
|
||||
$this->baseUrl = $_ENV['API_BASE_URL'];
|
||||
$this->username = $_ENV['API_USERNAME'];
|
||||
$this->password = $_ENV['API_PASSWORD'];
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new VisualLimsApiClientXml();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function authenticate()
|
||||
{
|
||||
$ch = curl_init("{$this->baseUrl}/api/authentication/authenticate");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
||||
'Username' => $this->username,
|
||||
'Password' => $this->password
|
||||
]));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Accept: application/json'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_auth_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false || $http_code != 200) {
|
||||
throw new Exception("Autenticazione fallita: HTTP {$http_code}, Errore cURL: {$curl_error}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
$token_data = json_decode($response, true);
|
||||
$this->token = null;
|
||||
|
||||
if (is_array($token_data) && isset($token_data['token'])) {
|
||||
$this->token = $token_data['token'];
|
||||
} elseif (is_string($token_data) && !empty($token_data)) {
|
||||
$this->token = trim($token_data, '"');
|
||||
} elseif (is_string($response) && !empty($response)) {
|
||||
$this->token = trim($response, '"');
|
||||
}
|
||||
|
||||
if (empty($this->token)) {
|
||||
throw new Exception("Token non ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
private function getToken()
|
||||
{
|
||||
if ($this->token === null) {
|
||||
$this->authenticate();
|
||||
}
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
public function get($endpoint, $options = [])
|
||||
{
|
||||
$token = $this->getToken();
|
||||
$query = http_build_query($options);
|
||||
$url = "{$this->baseUrl}/api/odata/{$endpoint}" . ($query ? '?' . $query : '');
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer {$token}",
|
||||
"Accept: application/xml"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_request_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception("Errore nella richiesta: {$curl_error}");
|
||||
}
|
||||
|
||||
if ($http_code !== 200) {
|
||||
throw new Exception("Errore nel recupero dati: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
// Verifica che la risposta sia XML
|
||||
if (strpos($response, '<?xml') !== 0) {
|
||||
throw new Exception("Risposta non valida: atteso formato XML, ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/authentication/authenticate
|
||||
* [HTTP/2] [1] [:method: POST]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/authentication/authenticate]
|
||||
* [HTTP/2] [1] [content-type: application/json]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
* [HTTP/2] [1] [content-length: 51]
|
||||
> POST /limsapi/api/authentication/authenticate HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
Content-Length: 51
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Thu, 21 Aug 2025 10:23:44 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1NTc3OTAyNSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.bBV1z1uaxZeUuw-2YS2gLGaxTCQJAHTieM82KVJb5nw]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1NTc3OTAyNSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.bBV1z1uaxZeUuw-2YS2gLGaxTCQJAHTieM82KVJb5nw
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< odata-version: 4.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Thu, 21 Aug 2025 10:23:44 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,36 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/authentication/authenticate
|
||||
* [HTTP/2] [1] [:method: POST]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/authentication/authenticate]
|
||||
* [HTTP/2] [1] [content-type: application/json]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
* [HTTP/2] [1] [content-length: 51]
|
||||
> POST /limsapi/api/authentication/authenticate HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
Content-Length: 51
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 15:07:55 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/Cliente
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/Cliente]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1OTY5MiwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.O60U9XXapZOj0U3GuOIU0eiwgcUkzXTW6Eqy5f6q9D8]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/Cliente HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1OTY5MiwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.O60U9XXapZOj0U3GuOIU0eiwgcUkzXTW6Eqy5f6q9D8
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< odata-version: 4.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 12:08:45 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,38 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/authentication/authenticate
|
||||
* [HTTP/2] [1] [:method: POST]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: iftm.it]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/authentication/authenticate]
|
||||
* [HTTP/2] [1] [content-type: application/json]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
* [HTTP/2] [1] [user-agent: Mozilla/5.0 (compatible; PHP cURL)]
|
||||
* [HTTP/2] [1] [content-length: 51]
|
||||
> POST /limsapi/api/authentication/authenticate HTTP/2
|
||||
Host: iftm.it
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
User-Agent: Mozilla/5.0 (compatible; PHP cURL)
|
||||
Content-Length: 51
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 10:19:09 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,18 +0,0 @@
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTAyMSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.KntKk8Up-9owFjy7onziK2BfncEnSNhizyNX9S-QHaw"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTEyNSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.IWjzzBg0kQ3lq4aK2ByMlY7Bwzb7Qq-6ziXV8kkZ2J0"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTI2NSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.UgVz6PTF9dmbFYdgyRZS0TcI0pvLEIQ3yMjPiicF1vs"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTMwNywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.PolfU_FWuVMd-YfonBYTo0i0qIl6kn6nUkCWCEBvZuA"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTQ0OSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.CGZ-9KbMmW19JYTVGfjIcbNscSsGB4dwoHCJkHHs_4M"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTc1MCwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.FCAm5sWed1Q-QiIsctMgSBfEd4sfN3kfVR3Mqd3XQz0"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/Cliente(5860)?$expand=SchemiAbilitati
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/Cliente(5860)?$expand=SchemiAbilitati]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk3MDQ3NSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.vABzuZkQE9luU_uc4e18AYiM5c2Jnf-z1Q3sofbz6O0]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/Cliente(5860)?$expand=SchemiAbilitati HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk3MDQ3NSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.vABzuZkQE9luU_uc4e18AYiM5c2Jnf-z1Q3sofbz6O0
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< odata-version: 4.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 15:07:56 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/Cliente(0)?$expand=SchemiAbilitati
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/Cliente(0)?$expand=SchemiAbilitati]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk2NTQ4MywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.oSwFJRuj0lDD7D6dOLIZWhn_Lzma0b38dLPEDIOMD7o]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/Cliente(0)?$expand=SchemiAbilitati HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk2NTQ4MywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.oSwFJRuj0lDD7D6dOLIZWhn_Lzma0b38dLPEDIOMD7o
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 404
|
||||
< cache-control: no-cache,no-store,max-age=0
|
||||
< pragma: no-cache
|
||||
< content-type: application/problem+json
|
||||
< expires: -1
|
||||
< server: Microsoft-IIS/10.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 13:44:44 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,108 +0,0 @@
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"}}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"},"success":false,"http_code":400}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings?tracking_numbers=750000810057432004040056&courier_code=tnt-it
|
||||
Request Data: []
|
||||
Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[]}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Get Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[],"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"}}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"},"success":false,"http_code":400}
|
||||
Request URL: https://api.trackingmore.com/v4/get?tracking_numbers=750000810057432004040056&courier_code=tnt-it
|
||||
Request Data: []
|
||||
Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[]}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Get Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[],"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"}}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"},"success":false,"http_code":400}
|
||||
Request URL: https://api.trackingmore.com/v4/get?tracking_numbers=750000810057432004040056
|
||||
Request Data: []
|
||||
Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[]}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Get Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[],"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e85f77564ba2d1b2d35c7b28c72e62b","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T09:43:15+00:00","update_at":"2025-03-26T09:01:02+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e85f77564ba2d1b2d35c7b28c72e62b","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T09:43:15+00:00","update_at":"2025-03-26T09:01:02+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8601d0116ffa9f4abe6fa609f27214","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T10:12:12+00:00","update_at":"2025-03-26T09:43:15+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8601d0116ffa9f4abe6fa609f27214","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T10:12:12+00:00","update_at":"2025-03-26T09:43:15+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "75000",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"75000","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e88676cc0b94ee0270add7c597d0cb0","tracking_number":"75000","courier_code":"tnt-it","order_number":"75000","order_date":null,"created_at":"2025-03-27T14:47:59+00:00","update_at":null,"delivery_status":"pending","archived":"tracking","updating":true,"source":"API","destination_country":null,"destination_state":null,"destination_city":null,"origin_country":null,"origin_state":null,"origin_city":null,"tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":null,"service_code":null,"weight":null,"weight_kg":null,"product_type":null,"pieces":null,"dimension":null,"previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"pending002","status_info":null,"latest_event":null,"latest_checkpoint_time":null,"transit_time":0,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e88676cc0b94ee0270add7c597d0cb0","tracking_number":"75000","courier_code":"tnt-it","order_number":"75000","order_date":null,"created_at":"2025-03-27T14:47:59+00:00","update_at":null,"delivery_status":"pending","archived":"tracking","updating":true,"source":"API","destination_country":null,"destination_state":null,"destination_city":null,"origin_country":null,"origin_state":null,"origin_city":null,"tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":null,"service_code":null,"weight":null,"weight_kg":null,"product_type":null,"pieces":null,"dimension":null,"previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"pending002","status_info":null,"latest_event":null,"latest_checkpoint_time":null,"transit_time":0,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8867d062b0ddfac8655e3d81b289af","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-27T14:49:04+00:00","update_at":"2025-03-26T10:12:12+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8867d062b0ddfac8655e3d81b289af","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-27T14:49:04+00:00","update_at":"2025-03-26T10:12:12+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "123",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"123","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4110,"message":"The value of tracking_number is invalid."},"data":null}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4110,"message":"The value of tracking_number is invalid."},"data":null,"success":false,"http_code":400}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e9652c58e37fc7c8c9b08e9f2eb8f8e","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-04-03T12:51:49+00:00","update_at":"2025-04-01T09:02:08+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e9652c58e37fc7c8c9b08e9f2eb8f8e","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-04-03T12:51:49+00:00","update_at":"2025-04-01T09:02:08+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$partId = $data['part_id'] ?? null;
|
||||
|
||||
if (!$partId) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID parte mancante']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("DELETE FROM identification_parts WHERE id = :part_id");
|
||||
$stmt->execute([':part_id' => $partId]);
|
||||
$rowCount = $stmt->rowCount();
|
||||
if ($rowCount > 0) {
|
||||
echo json_encode(['success' => true, 'message' => 'Parte eliminata con successo']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Nessuna parte trovata con ID ' . $partId]);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nell\'eliminazione: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Swagger Codegen Ignore
|
||||
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1 @@
|
||||
3.0.34
|
||||
@@ -5,3 +5,10 @@
|
||||
2025-07-04 10:42:49 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-07-04 10:44:13 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-07-04 10:48:07 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-08-19 16:29:25 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-08-26 16:47:19 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:48:15 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:48:44 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:49:24 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:50:23 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-09-08 08:39:17 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', '0');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// ID della CommessaWeb specifica (cambialo di volta in volta)
|
||||
$id = 529435; // TODO: Cambia questo valore con l'ID desiderato
|
||||
|
||||
// Endpoint per recuperare la CommessaWeb specifica con espansione dello schema custom
|
||||
$endpoint = "CommessaWeb({$id})";
|
||||
|
||||
// Opzioni per l'espansione: includi OrderCustomFields per ottenere i campi custom dello schema assegnato all'ordine
|
||||
$options = ['$expand' => 'OrderCustomFields'];
|
||||
|
||||
// Debug: salva URL usato
|
||||
$base_url = 'https://93.43.5.102/limsapi/api/odata/';
|
||||
$query = http_build_query($options);
|
||||
$full_url = $base_url . $endpoint . ($query ? '?' . $query : '');
|
||||
file_put_contents(__DIR__ . '/last_url.txt', $full_url . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Chiamata API
|
||||
$data = $api->get($endpoint, $options);
|
||||
|
||||
// Salva il JSON in locale
|
||||
file_put_contents(__DIR__ . '/commessaweb_schema_response.json', json_encode($data, JSON_PRETTY_PRINT));
|
||||
|
||||
echo json_encode($data);
|
||||
} catch (Exception $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php'; // Torna al livello di public
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
@@ -9,20 +9,30 @@ error_reporting(E_ALL);
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// ID del campo custom passato da GET oppure default
|
||||
$customFieldId = isset($_GET['field_id']) && is_numeric($_GET['field_id']) ? intval($_GET['field_id']) : 156;
|
||||
// მივიღოთ მრავლობითი field_ids
|
||||
$fieldIds = [];
|
||||
if (isset($_GET['field_ids'])) {
|
||||
$fieldIds = array_filter(array_map('intval', explode(',', $_GET['field_ids'])));
|
||||
}
|
||||
|
||||
// Endpoint con $expand per ottenere i valori
|
||||
$endpoint = "CustomField($customFieldId)?\$expand=CustomFieldsValues";
|
||||
// თუ არ გადმოგვცეს -> ერთი default
|
||||
if (empty($fieldIds)) {
|
||||
$fieldIds = [156];
|
||||
}
|
||||
|
||||
// Recupera i dati dal server
|
||||
$data = $api->get($endpoint);
|
||||
$results = [];
|
||||
|
||||
// Salva la risposta in un file per debug
|
||||
file_put_contents(__DIR__ . '/customfield_values_response.json', json_encode($data));
|
||||
foreach ($fieldIds as $customFieldId) {
|
||||
$endpoint = "CustomField($customFieldId)?\$expand=CustomFieldsValues";
|
||||
$data = $api->get($endpoint);
|
||||
|
||||
// Output JSON al client
|
||||
echo json_encode($data);
|
||||
$results[$customFieldId] = $data['CustomFieldsValues'] ?? [];
|
||||
}
|
||||
|
||||
// Debug ფაილი
|
||||
file_put_contents(__DIR__ . '/customfield_values_response.json', json_encode($results));
|
||||
|
||||
echo json_encode($results);
|
||||
} catch (Exception $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClientXml.class.php';
|
||||
|
||||
header('Content-Type: application/xml; charset=utf-8');
|
||||
|
||||
ini_set('display_errors', '0');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
try {
|
||||
$api = VisualLimsApiClientXml::getInstance();
|
||||
|
||||
// Endpoint per i metadata
|
||||
$endpoint = '$metadata';
|
||||
|
||||
// Nessun parametro aggiuntivo necessario
|
||||
$options = [];
|
||||
|
||||
// Debug: salva URL usato
|
||||
$base_url = 'https://93.43.5.102/limsapi/api/odata/';
|
||||
$query = http_build_query($options);
|
||||
$full_url = $base_url . $endpoint . ($query ? '?' . $query : '');
|
||||
file_put_contents(__DIR__ . '/last_url.txt', $full_url . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Chiamata API
|
||||
$data = $api->get($endpoint, $options);
|
||||
|
||||
// Salva il file XML in locale
|
||||
file_put_contents(__DIR__ . '/metadata_response.xml', $data);
|
||||
|
||||
// Restituisci il contenuto XML
|
||||
echo $data;
|
||||
} catch (Exception $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
http_response_code(500);
|
||||
echo '<?xml version="1.0" encoding="utf-8"?><error>' . htmlspecialchars($e->getMessage()) . '</error>';
|
||||
}
|
||||
@@ -499,6 +499,22 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
.proceed-btn {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.grid-cell.button-cell,
|
||||
.grid-header.button-header {
|
||||
min-width: 210px !important;
|
||||
flex: 0 0 210px !important;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 6px 8px;
|
||||
margin-right: 5px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
width: 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
<title>Dati Storici - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
||||
</head>
|
||||
@@ -610,142 +626,190 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
</div>
|
||||
<div id="noResults" class="text-danger" style="display:none;">Nessun risultato trovato</div>
|
||||
<div class="scrollbar-container"></div>
|
||||
|
||||
<form id="editForm">
|
||||
<div class="grid-container">
|
||||
<?php $fixedColumns = ['filename_import', 'status', 'importdate']; ?>
|
||||
<?php if ($status === 'i'): ?>
|
||||
<div class="grid-top">
|
||||
<div class="grid-cell" style="flex: 0 0 100px;"></div>
|
||||
<div class="grid-cell" style="flex: 0 0 100px;"></div>
|
||||
<div class="grid-cell" style="flex: 0 0 100px;"></div>
|
||||
<div class="grid-cell" style="flex: 0 0 150px;"></div>
|
||||
<?php
|
||||
foreach ($fixedColumns as $col) {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
}
|
||||
$autoIndex = 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual']) {
|
||||
$inputClass = 'auto-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
echo "<select class='custom-field dropdown-select $inputClass' data-column='auto_$autoIndex' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='auto_$autoIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
echo "</div>";
|
||||
} else {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
}
|
||||
$autoIndex++;
|
||||
<div class="grid-top">
|
||||
<div class="grid-cell actions-cell" style="flex: 0 0 200px;"></div>
|
||||
<?php
|
||||
// Campo con main_field = 1
|
||||
if ($mainFieldMapping) {
|
||||
$inputClass = $mainFieldMapping['is_manual'] ? 'manual-input' : 'auto-input';
|
||||
if ($mainFieldMapping['is_required']) $inputClass .= ' required-input';
|
||||
$index = $mainFieldMapping['is_manual'] ? "manual_0" : "auto_0";
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
if ($mainFieldMapping['data_type'] === 'SceltaMultipla') {
|
||||
$fieldValue = $mainFieldMapping['manual_default'] ?? '';
|
||||
echo "<select class='custom-field dropdown-select $inputClass' data-column='$index' data-field-id='{$mainFieldMapping['field_id']}' data-selected-value='" . htmlspecialchars($fieldValue) . "' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='$index' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
} else {
|
||||
$fieldValue = $mainFieldMapping['manual_default'] ?? '';
|
||||
if ($mainFieldMapping['data_type'] === 'DATE' && $mainFieldMapping['manual_default'] === 'today') {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
if ($mainFieldMapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' class='custom-field $inputClass' data-column='$index' value='" . htmlspecialchars($fieldValue) . "' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
} elseif ($mainFieldMapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' class='custom-field $inputClass' data-column='$index' value='" . htmlspecialchars($fieldValue) . "' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
} else {
|
||||
echo "<input type='text' class='custom-field $inputClass' data-column='$index' value='" . htmlspecialchars($fieldValue) . "' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
}
|
||||
echo "<button type='button' class='propagate-btn' data-column='$index' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
}
|
||||
$manualIndex = 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if ($mapping['is_manual']) {
|
||||
echo "</div>";
|
||||
} else {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
}
|
||||
// Campi automatici (escluso main_field)
|
||||
$autoIndex = ($mainFieldMapping && !$mainFieldMapping['is_manual']) ? 1 : 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual'] && $mapping['main_field'] != 1) {
|
||||
$inputClass = 'auto-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
$fieldValue = $mapping['manual_default'] ?? '';
|
||||
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
$inputClass = 'manual-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select class='custom-field dropdown-select $inputClass' data-column='manual_$manualIndex' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
} elseif ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
} else {
|
||||
echo "<input type='text' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
}
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
echo "</div>";
|
||||
$manualIndex++;
|
||||
echo "<select class='custom-field dropdown-select $inputClass' data-column='auto_$autoIndex' data-field-id='{$mapping['field_id']}' data-selected-value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='auto_$autoIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
} else {
|
||||
echo "<div style='height: 34px;'></div>";
|
||||
}
|
||||
echo "</div>";
|
||||
$autoIndex++;
|
||||
}
|
||||
echo "<div class='grid-cell' style='flex: 0 0 200px;'></div>";
|
||||
echo "<div class='grid-cell' style='flex: 0 0 250px;'></div>";
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
}
|
||||
// Campi manuali (escluso main_field)
|
||||
$manualIndex = ($mainFieldMapping && $mainFieldMapping['is_manual']) ? 1 : 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if ($mapping['is_manual'] && $mapping['main_field'] != 1) {
|
||||
$fieldValue = $mapping['manual_default'] ?? '';
|
||||
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
$inputClass = 'manual-input';
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select class='custom-field dropdown-select $inputClass' data-column='manual_$manualIndex' data-field-id='{$mapping['field_id']}' data-selected-value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
} elseif ($mapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
} elseif ($mapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
} else {
|
||||
echo "<input type='text' class='custom-field $inputClass' data-column='manual_$manualIndex' value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<button type='button' class='propagate-btn' data-column='manual_$manualIndex' " . ($is_readonly ? 'disabled' : '') . "><i class='fas fa-arrow-down'></i></button>";
|
||||
}
|
||||
echo "</div>";
|
||||
$manualIndex++;
|
||||
}
|
||||
}
|
||||
// Colonne status, Import Reference Code, filename_import
|
||||
$fixedColumnsReduced = ['status'];
|
||||
foreach ($fixedColumnsReduced as $col) {
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>";
|
||||
}
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>"; // Import Reference Code
|
||||
echo "<div class='grid-cell' style='flex: 0 0 150px;'></div>"; // filename_import
|
||||
// AWB Number e Tracking Info
|
||||
echo "<div class='grid-cell' style='flex: 0 0 200px;'></div>";
|
||||
echo "<div class='grid-cell' style='flex: 0 0 250px;'></div>";
|
||||
?>
|
||||
</div>
|
||||
<div class="grid-row">
|
||||
<div class="grid-header" style="flex: 0 0 100px;">Save</div>
|
||||
<div class="grid-header" style="flex: 0 0 100px;">Photos</div>
|
||||
<div class="grid-header" style="flex: 0 0 100px;">Parts</div>
|
||||
<div class="grid-header" data-index="3" style="flex: 0 0 150px; position: relative;">Import Reference Code<div class="resizer"></div>
|
||||
<div class="grid-header actions-cell" style="flex: 0 0 200px; position: relative;">Azioni<div class="resizer"></div>
|
||||
</div>
|
||||
<?php
|
||||
$headerIndex = 4;
|
||||
foreach ($fixedColumns as $col) {
|
||||
// Header per il campo main_field = 1
|
||||
$headerIndex = 1;
|
||||
if ($mainFieldMapping) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mainFieldMapping['field_label']) . "<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
// Header per campi automatici (escluso main_field)
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual'] && $mapping['main_field'] != 1) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
}
|
||||
// Header per campi manuali (escluso main_field)
|
||||
foreach ($allMappings as $mapping) {
|
||||
if ($mapping['is_manual'] && $mapping['main_field'] != 1) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
}
|
||||
// Header per status, Import Reference Code, filename_import
|
||||
foreach ($fixedColumnsReduced as $col) {
|
||||
$displayName = $slugMapping[$col] ?? $col;
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>$displayName<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual']) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
}
|
||||
foreach ($allMappings as $mapping) {
|
||||
if ($mapping['is_manual']) {
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>" . htmlspecialchars($mapping['field_label']) . "<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
}
|
||||
}
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>Import Reference Code<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 150px; position: relative;'>File<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
// Header per AWB Number e Tracking Info
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 200px; position: relative;'>AWB Number<div class='resizer'></div></div>";
|
||||
echo "<div class='grid-header' data-index='" . ($headerIndex + 1) . "' style='flex: 0 0 250px; position: relative;'>Tracking Info<div class='resizer'></div></div>";
|
||||
$headerIndex++;
|
||||
echo "<div class='grid-header' data-index='$headerIndex' style='flex: 0 0 250px; position: relative;'>Tracking Info<div class='resizer'></div></div>";
|
||||
?>
|
||||
</div>
|
||||
<?php foreach ($importedData as $index => $row): ?>
|
||||
<div class="grid-row" data-id="<?= $row['iddatadb'] ?>">
|
||||
<div class="grid-cell" style="flex: 0 0 100px; position: relative;">
|
||||
<?php if (!$is_readonly): ?>
|
||||
<button type="button" class="save-btn action-btn" data-row="<?= $index ?>" style="background: #28a745; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; width: 100%; box-sizing: border-box;"><i class="fas fa-save"></i></button>
|
||||
<?php else: ?>
|
||||
<button type="button" class="save-btn action-btn" data-row="<?= $index ?>" style="background: #ccc; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: not-allowed; width: 100%; box-sizing: border-box;" disabled><i class="fas fa-save"></i></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="grid-cell" style="flex: 0 0 100px; position: relative;">
|
||||
<button type="button" class="photos-btn action-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>" style="background: #007bff; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; width: 100%; box-sizing: border-box;"><i class="fas fa-camera"></i></button>
|
||||
</div>
|
||||
<div class="grid-cell" style="flex: 0 0 100px; position: relative;">
|
||||
<button type="button" class="parts-btn action-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>" style="background: #ffc107; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; width: 100%; box-sizing: border-box;"><i class="fas fa-puzzle-piece"></i></button>
|
||||
<div class="grid-cell actions-cell" style="flex: 0 0 200px; position: relative;">
|
||||
<div style="display: flex; gap: 5px; justify-content: center;">
|
||||
<?php if (!$is_readonly): ?>
|
||||
<button type="button" class="save-btn action-btn" data-row="<?= $index ?>" style="background: #28a745; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; flex: 1;"><i class="fas fa-save"></i></button>
|
||||
<button type="button" class="photos-btn action-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>" style="background: #007bff; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; flex: 1;"><i class="fas fa-camera"></i></button>
|
||||
<button type="button" class="parts-btn action-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>" style="background: #ffc107; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; flex: 1;"><i class="fas fa-puzzle-piece"></i></button>
|
||||
<?php else: ?>
|
||||
<button type="button" class="save-btn action-btn" data-row="<?= $index ?>" style="background: #ccc; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: not-allowed; flex: 1;" disabled><i class="fas fa-save"></i></button>
|
||||
<button type="button" class="photos-btn action-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>" style="background: #ccc; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: not-allowed; flex: 1;" disabled><i class="fas fa-camera"></i></button>
|
||||
<button type="button" class="parts-btn action-btn" data-row="<?= $index ?>" data-iddatadb="<?= $row['iddatadb'] ?>" style="background: #ccc; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: not-allowed; flex: 1;" disabled><i class="fas fa-puzzle-piece"></i></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$cellIndex = 3;
|
||||
echo "<div class='grid-cell' data-col='importreferencecode' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
echo "<span>" . htmlspecialchars($row['importreferencecode']) . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][importreferencecode]' value='" . htmlspecialchars($row['importreferencecode']) . "'>";
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
foreach ($fixedColumns as $col) {
|
||||
$value = $row[$col] ?? '';
|
||||
echo "<div class='grid-cell editable-cell' data-col='$col' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($col === 'importdate') {
|
||||
echo "<span>" . htmlspecialchars($value) . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
|
||||
} elseif ($col === 'filename_import') {
|
||||
echo "<a href='imported_trf/" . htmlspecialchars($value) . "' target='_blank'>File</a>";
|
||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value) . "'>";
|
||||
} elseif ($col === 'status') {
|
||||
$badgeClass = $value === 'i' ? 'status-i' : ($value === 'P' ? 'status-P' : 'status-l');
|
||||
$badgeText = $value === 'i' ? 'Imported' : ($value === 'P' ? 'Progress' : 'LIMS');
|
||||
echo "<span class='status-badge $badgeClass'>" . htmlspecialchars($badgeText) . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value ?? 'i') . "'>";
|
||||
$cellIndex = 1;
|
||||
$rowDetails = array_filter($manualDetails, fn($d) => $d['datadb_id'] == $row['iddatadb']);
|
||||
// Campo con main_field = 1
|
||||
if ($mainFieldMapping) {
|
||||
$detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mainFieldMapping['id']);
|
||||
$detail = reset($detail) ?: ['field_value' => $mainFieldMapping['manual_default']];
|
||||
$fieldValue = $detail['field_value'] ?? $mainFieldMapping['manual_default'] ?? '';
|
||||
$requiredClass = ($mainFieldMapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) ? 'missing-required' : '';
|
||||
$inputClass = $mainFieldMapping['is_manual'] ? 'manual-input' : 'auto-input';
|
||||
if ($mainFieldMapping['is_required']) $inputClass .= ' required-input';
|
||||
$indexField = $mainFieldMapping['is_manual'] ? "manual_0" : "auto_0";
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='$indexField' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($mainFieldMapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select name='rows[$index][details][{$mainFieldMapping['id']}][field_value]' class='cell-input dropdown-select $inputClass' data-mapping-id='{$mainFieldMapping['id']}' data-field-id='{$mainFieldMapping['field_id']}' data-selected-value='" . htmlspecialchars($fieldValue) . "' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
} elseif ($mainFieldMapping['data_type'] === 'DATE') {
|
||||
echo "<input type='date' name='rows[$index][details][{$mainFieldMapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
} elseif ($mainFieldMapping['data_type'] === 'INT') {
|
||||
echo "<input type='number' name='rows[$index][details][{$mainFieldMapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
} else {
|
||||
echo "<input type='text' name='rows[$index][details][{$mainFieldMapping['id']}][field_value]' value='" . htmlspecialchars($fieldValue) . "' class='cell-input $inputClass' " . ($mainFieldMapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
}
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
}
|
||||
$rowDetails = array_filter($manualDetails, fn($d) => $d['datadb_id'] == $row['iddatadb']);
|
||||
$autoIndex = 0;
|
||||
// Campi automatici (escluso main_field)
|
||||
$autoIndex = ($mainFieldMapping && !$mainFieldMapping['is_manual']) ? 1 : 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual']) {
|
||||
if (!$mapping['is_manual'] && $mapping['main_field'] != 1) {
|
||||
$detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']);
|
||||
$detail = reset($detail) ?: ['field_value' => $mapping['manual_default']];
|
||||
$fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? '';
|
||||
@@ -754,7 +818,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='auto_$autoIndex' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select $inputClass' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select $inputClass' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' data-selected-value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
} elseif ($mapping['data_type'] === 'DATE') {
|
||||
@@ -769,9 +833,10 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
$autoIndex++;
|
||||
}
|
||||
}
|
||||
$manualIndex = 0;
|
||||
// Campi manuali (escluso main_field)
|
||||
$manualIndex = ($mainFieldMapping && $mainFieldMapping['is_manual']) ? 1 : 0;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if ($mapping['is_manual']) {
|
||||
if ($mapping['is_manual'] && $mapping['main_field'] != 1) {
|
||||
$detail = array_filter($rowDetails, fn($d) => $d['mapping_id'] == $mapping['id']);
|
||||
$detail = reset($detail) ?: ['field_value' => $mapping['manual_default']];
|
||||
$fieldValue = $detail['field_value'] ?? $mapping['manual_default'] ?? '';
|
||||
@@ -783,7 +848,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
if ($mapping['is_required']) $inputClass .= ' required-input';
|
||||
echo "<div class='grid-cell editable-cell $requiredClass' data-col='manual_$manualIndex' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($mapping['data_type'] === 'SceltaMultipla') {
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select $inputClass' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<select name='rows[$index][details][{$mapping['id']}][field_value]' class='cell-input dropdown-select $inputClass' data-mapping-id='{$mapping['id']}' data-field-id='{$mapping['field_id']}' data-selected-value='" . htmlspecialchars($fieldValue) . "' " . ($mapping['is_required'] ? 'required' : '') . ($is_readonly ? ' readonly' : '') . ">";
|
||||
echo "<option value=''>Seleziona...</option>";
|
||||
echo "</select>";
|
||||
} elseif ($mapping['data_type'] === 'DATE') {
|
||||
@@ -798,6 +863,32 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
$manualIndex++;
|
||||
}
|
||||
}
|
||||
// Colonna status
|
||||
$fixedColumnsReduced = ['status'];
|
||||
foreach ($fixedColumnsReduced as $col) {
|
||||
$value = $row[$col] ?? '';
|
||||
echo "<div class='grid-cell editable-cell' data-col='$col' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
if ($col === 'status') {
|
||||
$badgeClass = $value === 'i' ? 'status-i' : ($value === 'P' ? 'status-P' : 'status-l');
|
||||
$badgeText = $value === 'i' ? 'Imported' : ($value === 'P' ? 'Progress' : 'LIMS');
|
||||
echo "<span class='status-badge $badgeClass'>" . htmlspecialchars($badgeText) . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value ?? 'i') . "'>";
|
||||
}
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
}
|
||||
// Colonne Import Reference Code e filename_import
|
||||
echo "<div class='grid-cell' data-col='importreferencecode' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
echo "<span>" . htmlspecialchars($row['importreferencecode']) . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][importreferencecode]' value='" . htmlspecialchars($row['importreferencecode']) . "'>";
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
echo "<div class='grid-cell' data-col='filename_import' data-row='$index' data-index='$cellIndex' style='flex: 0 0 150px;'>";
|
||||
echo "<a href='imported_trf/" . htmlspecialchars($row['filename_import']) . "' target='_blank'>File</a>";
|
||||
echo "<input type='hidden' name='rows[$index][filename_import]' value='" . htmlspecialchars($row['filename_import']) . "'>";
|
||||
echo "</div>";
|
||||
$cellIndex++;
|
||||
// Colonne AWB Number e Tracking Info
|
||||
?>
|
||||
<div class="grid-cell" style="flex: 0 0 200px;">
|
||||
<select name="rows[<?= $index ?>][carrier]" class="carrier-select" <?= $is_readonly ? 'disabled' : '' ?>>
|
||||
@@ -833,6 +924,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
</ul>
|
||||
</nav>
|
||||
</form>
|
||||
|
||||
<?php
|
||||
if (file_exists('modal_parts.php')) {
|
||||
include 'modal_parts.php';
|
||||
@@ -856,6 +948,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
</div>
|
||||
<?php include('jsinclude.php'); ?>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
|
||||
<script src="photos.js"></script>
|
||||
<script src="parts.js"></script>
|
||||
<script src="tracking.js"></script>
|
||||
@@ -890,7 +983,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
const cells = row.querySelectorAll('td');
|
||||
let match = false;
|
||||
cells.forEach((cell, index) => {
|
||||
if (index >= 1 && index <= 3) {
|
||||
if (index >= 1 && index <= 4) { // Cerca in ID, main_field, importreferencecode, filename
|
||||
const text = cell.textContent.toLowerCase();
|
||||
if (text.includes(filter)) {
|
||||
match = true;
|
||||
@@ -934,6 +1027,18 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione eliminazione multipla
|
||||
const bulkActionForm = document.getElementById('bulkActionForm');
|
||||
bulkActionForm.addEventListener('submit', function(e) {
|
||||
const selectedCheckboxes = document.querySelectorAll('input[name="selected_ids[]"]:checked');
|
||||
if (selectedCheckboxes.length === 0) {
|
||||
e.preventDefault();
|
||||
alert('Seleziona almeno un record da eliminare.');
|
||||
} else if (!confirm('Sicuro di voler eliminare i record selezionati?')) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
<?php else: ?>
|
||||
// Gestione input e celle espandibili
|
||||
const inputs = document.querySelectorAll('.cell-input');
|
||||
@@ -961,8 +1066,13 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
inputs.forEach(input => {
|
||||
const name = input.name.replace(`rows[${rowIndex}]`, '').replace(/\[|\]/g, '');
|
||||
formData.append(name, input.value);
|
||||
// Aggiorna data-selected-value per i dropdown
|
||||
if (input.tagName === 'SELECT' && input.classList.contains('dropdown-select')) {
|
||||
input.setAttribute('data-selected-value', input.value);
|
||||
}
|
||||
});
|
||||
formData.append('iddatadb', iddatadb);
|
||||
formData.append('mapping', JSON.stringify(<?= json_encode($allMappings) ?>));
|
||||
fetch('save_edited_row.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
@@ -977,6 +1087,7 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
cell.classList.add('flash-success');
|
||||
});
|
||||
setTimeout(() => cells.forEach(cell => cell.classList.remove('flash-success')), 500);
|
||||
alert('Salvataggio avvenuto con successo!');
|
||||
} else {
|
||||
alert('Errore durante il salvataggio: ' + data.message);
|
||||
}
|
||||
@@ -990,12 +1101,12 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
propagateButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
if (this.hasAttribute('disabled')) return;
|
||||
const columnIndex = this.getAttribute('data-column').replace('manual_', '');
|
||||
const column = this.getAttribute('data-column');
|
||||
const input = this.previousElementSibling;
|
||||
const value = input.value;
|
||||
const gridTopCells = document.querySelector('.grid-top').querySelectorAll('.grid-cell');
|
||||
const targetTopIndex = Array.from(gridTopCells).findIndex(cell =>
|
||||
cell.querySelector('.propagate-btn') === button
|
||||
cell.querySelector('.propagate-btn[data-column="' + column + '"]')
|
||||
);
|
||||
if (targetTopIndex !== -1) {
|
||||
const rows = document.querySelectorAll('.grid-row');
|
||||
@@ -1004,9 +1115,12 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
if (cells.length > targetTopIndex) {
|
||||
const targetInput = cells[targetTopIndex].querySelector('input, select');
|
||||
if (targetInput && !targetInput.hasAttribute('readonly')) {
|
||||
if (targetInput.type === 'date') targetInput.value = value;
|
||||
else if (targetInput.tagName === 'SELECT') targetInput.value = value;
|
||||
else targetInput.value = value;
|
||||
targetInput.value = value;
|
||||
if (targetInput.tagName === 'SELECT') {
|
||||
targetInput.setAttribute('data-selected-value', value);
|
||||
const event = new Event('change');
|
||||
targetInput.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1123,47 +1237,80 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
async function populateDropdowns() {
|
||||
if (<?= json_encode($is_readonly) ?>) return;
|
||||
const dropdowns = document.querySelectorAll('.dropdown-select');
|
||||
if (dropdowns.length === 0) return;
|
||||
const uniqueFieldIds = [...new Set(Array.from(dropdowns).map(d => d.getAttribute('data-field-id')))].filter(fieldId => fieldId);
|
||||
for (const fieldId of uniqueFieldIds) {
|
||||
if (!dropdownData[fieldId]) {
|
||||
try {
|
||||
const response = await fetch(`get_customfield_values.php?field_id=${fieldId}`);
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
console.error('Errore per field_id', fieldId, ':', data.error);
|
||||
continue;
|
||||
}
|
||||
dropdownData[fieldId] = data.CustomFieldsValues || [];
|
||||
} catch (error) {
|
||||
console.error('Errore nel fetch per field_id', fieldId, ':', error);
|
||||
}
|
||||
}
|
||||
console.log('Dropdown trovati:', dropdowns.length);
|
||||
if (dropdowns.length === 0) {
|
||||
console.warn('Nessun dropdown trovato con classe .dropdown-select');
|
||||
return;
|
||||
}
|
||||
dropdowns.forEach(dropdown => {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
if (!fieldId || !dropdownData[fieldId]) {
|
||||
dropdown.innerHTML = '<option value="">Errore nel caricamento</option>';
|
||||
|
||||
const uniqueFieldIds = [...new Set(Array.from(dropdowns).map(d => d.getAttribute('data-field-id')))].filter(fieldId => fieldId);
|
||||
console.log('Field IDs unici:', uniqueFieldIds);
|
||||
const missingFieldIds = uniqueFieldIds.filter(fieldId => !dropdownData[fieldId]);
|
||||
|
||||
if (missingFieldIds.length > 0) {
|
||||
try {
|
||||
const response = await fetch(`get_customfield_values.php?field_ids=${missingFieldIds.join(',')}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Errore HTTP: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
console.log('Risposta da get_customfield_values.php:', data);
|
||||
|
||||
if (data.error) {
|
||||
console.error('Errore dal server:', data.error);
|
||||
dropdowns.forEach(dropdown => {
|
||||
dropdown.innerHTML = '<option value="">Errore server</option>';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
for (const fieldId of Object.keys(data)) {
|
||||
dropdownData[fieldId] = data[fieldId] || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Errore nel fetch dei valori dei dropdown:', error);
|
||||
dropdowns.forEach(dropdown => {
|
||||
dropdown.innerHTML = '<option value="">Errore caricamento</option>';
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dropdowns.forEach(dropdown => {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
const mappingId = dropdown.getAttribute('data-mapping-id');
|
||||
const selectedValue = dropdown.getAttribute('data-selected-value') || '';
|
||||
const currentValue = dropdown.value || '';
|
||||
console.log(`Popolamento dropdown field_id=${fieldId}, mapping_id=${mappingId}, valore corrente=${currentValue}, valore selezionato=${selectedValue}`);
|
||||
|
||||
if (!fieldId || !dropdownData[fieldId]) {
|
||||
dropdown.innerHTML = '<option value="">Nessun dato</option>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Preserva il valore corrente o usa quello salvato
|
||||
dropdown.innerHTML = '<option value="">Seleziona...</option>';
|
||||
dropdownData[fieldId].forEach(value => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value.IdCustomFieldsValue;
|
||||
option.textContent = value.Valore;
|
||||
if (dropdown.value === option.value) option.selected = true;
|
||||
// Dai priorità a data-selected-value per il caricamento iniziale
|
||||
if (selectedValue === String(value.IdCustomFieldsValue)) {
|
||||
option.selected = true;
|
||||
} else if (currentValue === String(value.IdCustomFieldsValue)) {
|
||||
option.selected = true;
|
||||
}
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
|
||||
// Verifica se il valore selezionato esiste tra le opzioni
|
||||
if ((selectedValue || currentValue) && dropdown.value !== (selectedValue || currentValue)) {
|
||||
dropdown.value = '';
|
||||
console.warn(`Valore ${selectedValue || currentValue} non trovato per fieldId ${fieldId}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
populateDropdowns();
|
||||
saveButtons.forEach(btn => {
|
||||
btn.addEventListener('click', function() {
|
||||
if (!this.hasAttribute('disabled')) {
|
||||
setTimeout(populateDropdowns, 100);
|
||||
}
|
||||
});
|
||||
});
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log', __DIR__ . '/import_debug.log');
|
||||
if (!file_exists(__DIR__ . '/import_debug.log')) {
|
||||
file_put_contents(__DIR__ . '/import_debug.log', "Inizio importazione alle " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
// Log iniziale
|
||||
error_log("Inizio importazione alle " . date('Y-m-d H:i:s'));
|
||||
|
||||
include('include/headscript.php');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['template_id']) || !isset($_POST['selected_rows']) || !isset($_POST['filename'])) {
|
||||
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Richiesta non valida"));
|
||||
exit;
|
||||
}
|
||||
$template_id = intval($_POST['template_id']);
|
||||
$selected_rows = $_POST['selected_rows'];
|
||||
$columns = json_decode($_POST['columns'], true); // Header dell'XLS
|
||||
$rows = json_decode($_POST['rows'], true); // Dati dell'XLS
|
||||
$newFilename = htmlspecialchars($_POST['filename']);
|
||||
|
||||
$_SESSION['template_id'] = $template_id;
|
||||
$_SESSION['selected_rows'] = $selected_rows;
|
||||
$_SESSION['columns'] = $columns;
|
||||
$_SESSION['rows'] = $rows;
|
||||
$_SESSION['filename'] = $newFilename;
|
||||
|
||||
error_log("Received Data - Template ID: $template_id, Selected Rows: " . json_encode($selected_rows));
|
||||
error_log("Columns: " . json_encode($columns));
|
||||
error_log("Rows: " . json_encode($rows));
|
||||
|
||||
$user_id = $iduserlogin ?? 1; // Default a 1 se non definito
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// Genera un UUID univoco per importreferencecode
|
||||
$importReferenceCode = date('YmdHis') . '-' . uniqid();
|
||||
|
||||
// Recupera tutti i mapping dal template
|
||||
$stmt = $pdo->prepare("SELECT id, excel_column, data_type, is_required, manual_default, is_manual, field_label, field_id, main_field FROM template_mapping WHERE template_id = ?");
|
||||
$stmt->execute([$template_id]);
|
||||
$allMappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if (empty($allMappings)) {
|
||||
header("Location: import_xls.php?id=$template_id&status=error&message=" . urlencode("Nessun mapping trovato per il template"));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Trova il campo main_field
|
||||
$mainFieldMapping = null;
|
||||
foreach ($allMappings as $mapping) {
|
||||
if ($mapping['main_field'] == 1) {
|
||||
$mainFieldMapping = $mapping;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Inserisci le righe selezionate in datadb (solo campi generici con templateid)
|
||||
$insertedIds = [];
|
||||
foreach ($selected_rows as $rowIndex) {
|
||||
$row = $rows[$rowIndex];
|
||||
$values = [
|
||||
$template_id, // templateid
|
||||
$importReferenceCode, // importreferencecode
|
||||
$newFilename, // filename_import
|
||||
'i', // status
|
||||
$user_id, // user_id
|
||||
null, // limscode
|
||||
date('Y-m-d') // importdate
|
||||
];
|
||||
$sql = "INSERT INTO datadb (templateid, importreferencecode, filename_import, status, user_id, limscode, importdate) VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($values);
|
||||
|
||||
$iddatadb = $pdo->lastInsertId();
|
||||
$insertedIds[] = $iddatadb;
|
||||
|
||||
// Inserisci tutti i campi (automatici e manuali) in import_data_details
|
||||
foreach ($allMappings as $mapping) {
|
||||
$fieldValue = null;
|
||||
if (!$mapping['is_manual']) { // Campi automatici dall'XLS
|
||||
$excelColumn = trim($mapping['excel_column']);
|
||||
$excelColumnIndex = array_search($excelColumn, array_map('trim', $columns));
|
||||
if ($excelColumnIndex !== false && isset($row[$excelColumnIndex]) && $row[$excelColumnIndex] !== '') {
|
||||
$fieldValue = $row[$excelColumnIndex];
|
||||
error_log("Found Excel column '$excelColumn' at index $excelColumnIndex, value: " . var_export($fieldValue, true));
|
||||
} else {
|
||||
$fieldValue = $mapping['manual_default'] ?? '';
|
||||
error_log("Excel column '$excelColumn' not found or empty, using default: " . var_export($fieldValue, true));
|
||||
}
|
||||
switch ($mapping['data_type']) {
|
||||
case 'INT':
|
||||
$fieldValue = is_numeric($fieldValue) ? (int)$fieldValue : ($mapping['manual_default'] ?? 0);
|
||||
break;
|
||||
case 'DATE':
|
||||
$fieldValue = !empty($fieldValue) ? date('Y-m-d', strtotime($fieldValue)) : ($mapping['manual_default'] === 'today' ? date('Y-m-d') : ($mapping['manual_default'] ?? ''));
|
||||
break;
|
||||
case 'CHAR':
|
||||
$fieldValue = !empty($fieldValue) ? substr((string)$fieldValue, 0, 1) : ($mapping['manual_default'] ?? '');
|
||||
break;
|
||||
case 'Testo':
|
||||
case 'VARCHAR':
|
||||
default:
|
||||
$fieldValue = !empty($fieldValue) ? htmlspecialchars((string)$fieldValue) : ($mapping['manual_default'] ?? '');
|
||||
break;
|
||||
}
|
||||
} else { // Campi manuali
|
||||
$fieldValue = $mapping['manual_default'] ?? '';
|
||||
if ($mapping['data_type'] === 'DATE' && $mapping['manual_default'] === 'today') {
|
||||
$fieldValue = date('Y-m-d');
|
||||
}
|
||||
}
|
||||
if ($mapping['is_required'] && (is_null($fieldValue) || $fieldValue === '')) {
|
||||
error_log("Required field missing for mapping ID: " . $mapping['id'] . ", field: " . $mapping['field_label']);
|
||||
}
|
||||
error_log("Inserting into import_data_details - Mapping ID: " . $mapping['id'] . ", Field Value: " . var_export($fieldValue, true) . ", Is Manual: " . $mapping['is_manual'] . ", Excel Column: " . ($mapping['excel_column'] ?? 'N/A') . ", Manual Default: " . ($mapping['manual_default'] ?? 'N/A'));
|
||||
$stmt = $pdo->prepare("INSERT INTO import_data_details (id, mapping_id, field_value) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$iddatadb, $mapping['id'], $fieldValue]);
|
||||
error_log("Inserted into import_data_details for ID $iddatadb, Mapping ID: " . $mapping['id'] . ", Field Value: " . var_export($fieldValue, true));
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION['inserted_ids'] = $insertedIds;
|
||||
|
||||
$params = [
|
||||
'template_id' => $template_id,
|
||||
'filename' => $newFilename,
|
||||
];
|
||||
|
||||
?>
|
||||
<form id="redirectForm" action="import_edit2.php" method="post">
|
||||
<input type="hidden" name="template_id" value="<?= htmlspecialchars($template_id) ?>">
|
||||
<input type="hidden" name="filename" value="<?= htmlspecialchars($newFilename) ?>">
|
||||
|
||||
<?php foreach ($selected_rows as $row): ?>
|
||||
<input type="hidden" name="selected_rows[]" value="<?= htmlspecialchars($row) ?>">
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php foreach ($insertedIds as $id): ?>
|
||||
<input type="hidden" name="inserted_ids[]" value="<?= htmlspecialchars($id) ?>">
|
||||
<?php endforeach; ?>
|
||||
|
||||
<input type="hidden" name="columns" value='<?= json_encode($columns) ?>'>
|
||||
<input type="hidden" name="rows" value='<?= json_encode($rows) ?>'>
|
||||
</form>
|
||||
<script>
|
||||
document.getElementById('redirectForm').submit();
|
||||
</script>
|
||||
<?php
|
||||
|
||||
exit;
|
||||
|
||||
@@ -169,12 +169,12 @@ error_log("Loaded template: " . print_r($template, true));
|
||||
<!--end wrapper-->
|
||||
|
||||
<!-- search modal -->
|
||||
<?php //include('include/searchmodal.php');
|
||||
<?php //include('include/searchmodal.php');
|
||||
?>
|
||||
<!-- end search modal -->
|
||||
|
||||
<!--start switcher-->
|
||||
<?php //include('include/themeswitcher.php');
|
||||
<?php //include('include/themeswitcher.php');
|
||||
?>
|
||||
<!--end switcher-->
|
||||
<?php include('jsinclude.php'); ?>
|
||||
@@ -210,7 +210,7 @@ error_log("Loaded template: " . print_r($template, true));
|
||||
errorContainer.style.display = 'block';
|
||||
} else {
|
||||
let html = `
|
||||
<form id="selectRowsForm" action="import_edit2.php" method="POST">
|
||||
<form id="selectRowsForm" action="import_insert.php" method="POST">
|
||||
<input type="hidden" name="template_id" value="${data.template_id}">
|
||||
<input type="hidden" name="columns" value='${JSON.stringify(data.columns)}'>
|
||||
<input type="hidden" name="rows" value='${JSON.stringify(data.rows)}'>
|
||||
@@ -331,4 +331,4 @@ error_log("Loaded template: " . print_r($template, true));
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -41,7 +41,21 @@
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>-->
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" class="has-arrow">
|
||||
<div class="parent-icon"><i class="bx bx-category"></i>
|
||||
</div>
|
||||
<div class="menu-title">Other Functions</div>
|
||||
</a>
|
||||
<ul>
|
||||
<li> <a href="quotations.php"><i class='bx bx-radio-circle'></i><?php echo $quotationstitle; ?></a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
https://93.43.5.102/limsapi/api/odata/Cliente(34)?expand=SchemiAbilitati
|
||||
https://93.43.5.102/limsapi/api/odata/Cliente(55)?expand=SchemiAbilitati
|
||||
https://93.43.5.102/limsapi/api/odata/Cliente(4202)?expand=SchemiAbilitati
|
||||
https://93.43.5.102/limsapi/api/odata/Cliente(4202)?expand=SchemiAbilitati
|
||||
https://93.43.5.102/limsapi/api/odata/Cliente(4202)?%24expand=SchemiAbilitati
|
||||
https://93.43.5.102/limsapi/api/odata/Cliente(4202)?%24expand=SchemiAbilitati
|
||||
https://93.43.5.102/limsapi/api/odata/Rapporto(2523026)?%24expand=CampioniDatiRapporto%2CAnalisiDatiRapporto%2CCustomFieldsDatiRapporto
|
||||
https://93.43.5.102/limsapi/api/odata/Cliente(4202)?%24expand=SchemiAbilitati
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
https://93.43.5.102/limsapi/api/odata/SchemaCustomField
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$idquotations = $_GET['idquotations'] ?? null;
|
||||
|
||||
if (!$idquotations) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID quotations mancante']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT id, idquotations, part_number, part_description FROM identification_parts WHERE idquotations = :idquotations ORDER BY part_number ASC");
|
||||
$stmt->execute([':idquotations' => $idquotations]);
|
||||
$parts = $stmt->fetchAll();
|
||||
|
||||
echo json_encode(['success' => true, 'parts' => $parts]);
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -14,13 +14,18 @@ if (!$iddatadb) {
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT file_path FROM datadb_photos WHERE iddatadb = :iddatadb LIMIT 1");
|
||||
// Adjust the query to select all photo paths for the given iddatadb
|
||||
$stmt = $pdo->prepare("SELECT file_path FROM datadb_photos WHERE iddatadb = :iddatadb");
|
||||
$stmt->execute([':iddatadb' => $iddatadb]);
|
||||
$photo = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($photo && $photo['file_path']) {
|
||||
$fullPath = '../photostrf/' . $photo['file_path']; // Assumi che le foto siano nella cartella photostrf
|
||||
echo json_encode(['success' => true, 'file_path' => $fullPath]);
|
||||
if ($photos && count($photos) > 0) {
|
||||
// Prepare an array of full file paths
|
||||
$photoPaths = array_map(function($photo) {
|
||||
return '../photostrf/' . $photo['file_path']; // Assuming the photos are stored in the "photostrf" folder
|
||||
}, $photos);
|
||||
|
||||
echo json_encode(['success' => true, 'photos' => $photoPaths]); // Return an array of photo paths
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Nessuna foto trovata']);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// load_photo_quotation.php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$idquotations = isset($_GET['idquotations']) ? intval($_GET['idquotations']) : null;
|
||||
|
||||
if (!$idquotations) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID quotation mancante']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// Seleziona le foto per il dato idquotations dalla tabella datadb_photos
|
||||
$stmt = $pdo->prepare("SELECT id, file_path FROM datadb_photos WHERE idquotations = ?");
|
||||
$stmt->execute([$idquotations]);
|
||||
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($photos && count($photos) > 0) {
|
||||
$photoPaths = array_map(function ($photo) {
|
||||
return '../photostrf/' . $photo['file_path'];
|
||||
}, $photos);
|
||||
echo json_encode(['success' => true, 'photos' => $photoPaths]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Nessuna foto trovata']);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nel caricamento: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -21,7 +21,7 @@ $schemajson = $template['schemajson'] ? json_decode($template['schemajson'], tru
|
||||
$isSchemajsonEmpty = empty(trim($template['schemajson']));
|
||||
|
||||
// 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 = $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, main_field, is_visible_import FROM template_mapping WHERE template_id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$mappings = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
@@ -42,6 +42,54 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
<?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>
|
||||
<style>
|
||||
.dropdown-select {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
appearance: none;
|
||||
background: white url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="%23333"><path d="M7.293 4.293a1 1 0 011.414 0L10 6.586l1.293-1.293a1 1 0 111.414 1.414l-2 2a1 1 0 01-1.414 0l-2-2a1 1 0 010-1.414z"/></svg>') no-repeat right 5px center;
|
||||
}
|
||||
|
||||
.dropdown-select:focus {
|
||||
outline: none;
|
||||
border-color: #80bdff;
|
||||
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
|
||||
}
|
||||
|
||||
#loading-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
z-index: 9999;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#loading-overlay div {
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
padding: 20px;
|
||||
background: #333;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
#schemaFieldsTable th:first-child,
|
||||
#schemaFieldsTable td:first-child,
|
||||
#schemaFieldsTable th:nth-child(2),
|
||||
#schemaFieldsTable td:nth-child(2) {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -90,8 +138,9 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
<table id="schemaFieldsTable" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Main</th>
|
||||
<th>Visible on Import</th>
|
||||
<th>Title</th>
|
||||
<th>ID</th>
|
||||
<th>Type</th>
|
||||
<th>Mapping</th>
|
||||
<th>Default Value</th>
|
||||
@@ -100,23 +149,45 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
<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>
|
||||
<input type="checkbox" class="main-field-checkbox" data-mapping-id="<?php echo $mapping['id']; ?>" <?php echo $mapping['main_field'] == 1 ? 'checked' : ''; ?>>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" class="visible-import-checkbox" data-mapping-id="<?php echo $mapping['id']; ?>" <?php echo (isset($mapping['is_visible_import']) ? $mapping['is_visible_import'] : 1) == 1 ? 'checked' : ''; ?>>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo htmlspecialchars($mapping['field_label'] ?? 'N/A'); ?>
|
||||
<?php if ($mapping['is_required'] == 1): ?>
|
||||
<span class="badge bg-danger ms-2">Required</span>
|
||||
<?php endif; ?>
|
||||
</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>
|
||||
<?php
|
||||
$isSceltaMultipla = $mapping['data_type'] === 'SceltaMultipla';
|
||||
$mappingValue = $isSceltaMultipla ? 'manual' : ($mapping['excel_column'] ? 'xls' : ($mapping['is_manual'] ? 'manual' : ''));
|
||||
?>
|
||||
<select class="form-select mapping-select" data-id="<?php echo $mapping['id']; ?>" data-field-id="<?php echo $mapping['field_id']; ?>" <?php echo $isSceltaMultipla ? 'disabled' : ''; ?>>
|
||||
<?php if (!$isSceltaMultipla): ?>
|
||||
<option value="">Select Option</option>
|
||||
<option value="xls" <?php echo $mappingValue === 'xls' ? 'selected' : ''; ?>>Map to XLS Column</option>
|
||||
<?php endif; ?>
|
||||
<option value="manual" <?php echo $mappingValue === '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']; ?>" <?php echo $mapping['excel_column'] ? 'data-current-xls="' . htmlspecialchars($mapping['excel_column']) . '"' : ''; ?>></select>
|
||||
<select class="form-select xls-columns" style="display:<?php echo $mappingValue === 'xls' ? 'block' : 'none'; ?>" data-id="<?php echo $mapping['id']; ?>" <?php echo $mapping['excel_column'] ? 'data-current-xls="' . htmlspecialchars($mapping['excel_column']) . '"' : ''; ?>></select>
|
||||
<?php if ($mapping['excel_column']): ?>
|
||||
<span class="mapped-column" style="margin-left: 5px;"><?php echo htmlspecialchars($mapping['excel_column']); ?></span>
|
||||
<button class="btn btn-danger btn-sm remove-xls" data-id="<?php echo $mapping['id']; ?>" style="margin-left: 5px;">X</button>
|
||||
<?php endif; ?>
|
||||
</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']; ?>">
|
||||
<?php if ($mapping['data_type'] === 'SceltaMultipla'): ?>
|
||||
<select class="form-select dropdown-select manual-default" data-id="<?php echo $mapping['id']; ?>" data-field-id="<?php echo $mapping['field_id']; ?>" data-manual-default="<?php echo htmlspecialchars($mapping['manual_default'] ?? ''); ?>" style="display:block;">
|
||||
<option value="">Seleziona...</option>
|
||||
</select>
|
||||
<?php else: ?>
|
||||
<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']; ?>">
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@@ -138,6 +209,7 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
</div>
|
||||
|
||||
<?php include('jsinclude.php'); ?>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script>
|
||||
let availableXlsColumns = <?php echo json_encode($xlsHeaders); ?> || [];
|
||||
let usedColumnsFromDB = <?php echo json_encode($usedColumnsFromDB); ?> || [];
|
||||
@@ -180,8 +252,8 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
type: 'array'
|
||||
});
|
||||
let sheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||
let rowIndex = parseInt(document.getElementById('headerRow').textContent) || 1; // Usa header_row dal template
|
||||
let startColumn = parseInt(document.getElementById('startColumn').textContent) || 1; // Usa start_column come numero
|
||||
let rowIndex = parseInt(document.getElementById('headerRow').textContent) || 1;
|
||||
let startColumn = parseInt(document.getElementById('startColumn').textContent) || 1;
|
||||
|
||||
let sheetData = XLSX.utils.sheet_to_json(sheet, {
|
||||
header: 1,
|
||||
@@ -189,7 +261,7 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
raw: false,
|
||||
range: 0
|
||||
});
|
||||
console.log("Dati della riga " + rowIndex + ":", sheetData[rowIndex - 1]); // Debug: stampa la riga delle intestazioni
|
||||
console.log("Dati della riga " + rowIndex + ":", sheetData[rowIndex - 1]);
|
||||
if (!sheetData[rowIndex - 1]) {
|
||||
document.getElementById('schemaFieldsBody').querySelectorAll('select.xls-columns').forEach(select => {
|
||||
select.innerHTML = '<option value="">Nessuna intestazione trovata</option>';
|
||||
@@ -197,11 +269,10 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
return;
|
||||
}
|
||||
|
||||
// Estrai le intestazioni a partire dalla colonna specificata, includendo le vuote
|
||||
let headers = sheetData[rowIndex - 1].slice(startColumn - 1).map(header => header === undefined ? "" : header);
|
||||
console.log("Intestazioni estratte:", headers); // Debug: stampa le intestazioni estratte
|
||||
console.log("Intestazioni estratte:", headers);
|
||||
availableXlsColumns = [...headers];
|
||||
usedColumnsFromDB = []; // Resetta le colonne usate dopo un nuovo caricamento
|
||||
usedColumnsFromDB = [];
|
||||
saveXlsHeaders(headers);
|
||||
updateXlsDropdowns();
|
||||
};
|
||||
@@ -229,18 +300,18 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
let usedColumns = Array.from(document.querySelectorAll('select.xls-columns'))
|
||||
.filter(select => select.style.display === 'block' && select.value)
|
||||
.map(select => select.value)
|
||||
.concat(usedColumnsFromDB); // Aggiunge le colonne già salvate nel DB
|
||||
.concat(usedColumnsFromDB);
|
||||
|
||||
document.querySelectorAll('select.xls-columns').forEach(select => {
|
||||
let currentValue = select.value || select.dataset.currentXls || '';
|
||||
let options = availableXlsColumns
|
||||
.filter(col => !usedColumns.includes(col) || col === currentValue) // Esclude colonne già usate, tranne la corrente
|
||||
.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;
|
||||
if (currentValue && !options.includes(currentValue)) {
|
||||
select.value = ''; // Reset se il valore non è più valido
|
||||
select.value = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -250,6 +321,105 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
let schemaId = <?php echo json_encode($template['idschema'] ?? 0); ?>;
|
||||
let isSchemajsonEmpty = <?php echo json_encode($isSchemajsonEmpty); ?>;
|
||||
|
||||
// Crea l'overlay di caricamento
|
||||
const loadingOverlay = document.createElement('div');
|
||||
loadingOverlay.id = 'loading-overlay';
|
||||
loadingOverlay.innerHTML = '<div>Loading Dropdown Options...</div>';
|
||||
document.body.appendChild(loadingOverlay);
|
||||
|
||||
async function populateDropdowns() {
|
||||
const dropdowns = document.querySelectorAll('.dropdown-select');
|
||||
if (dropdowns.length === 0) {
|
||||
console.warn('Nessun dropdown di tipo SceltaMultipla trovato.');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Trovati ${dropdowns.length} dropdown da popolare.`);
|
||||
|
||||
const uniqueFieldIds = [...new Set(Array.from(dropdowns).map(d => d.getAttribute('data-field-id')))].filter(fieldId => fieldId);
|
||||
|
||||
if (uniqueFieldIds.length === 0) {
|
||||
console.warn('Nessun field_id valido trovato per i dropdown.');
|
||||
dropdowns.forEach(dropdown => {
|
||||
dropdown.innerHTML = '<option value="">Nessun field_id valido</option>';
|
||||
dropdown.disabled = true;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Field IDs univoci:', uniqueFieldIds);
|
||||
|
||||
// Mostra l'overlay di caricamento
|
||||
const loadingOverlay = document.getElementById('loading-overlay');
|
||||
loadingOverlay.style.display = 'flex';
|
||||
|
||||
let dropdownData = {};
|
||||
|
||||
try {
|
||||
// Usa field_ids come previsto dal backend
|
||||
const fieldIdsQuery = uniqueFieldIds.join(',');
|
||||
console.log(`Recupero dati per field_ids: ${fieldIdsQuery}`);
|
||||
const response = await fetch(`get_customfield_values.php?field_ids=${fieldIdsQuery}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Errore HTTP: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
throw new Error(`Errore API: ${data.error}`);
|
||||
}
|
||||
dropdownData = data; // data è un oggetto come { "146": [], "156": [...] }
|
||||
console.log('Dati totali restituiti:', dropdownData);
|
||||
|
||||
// Popola i dropdown
|
||||
dropdowns.forEach(dropdown => {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
const manualDefault = dropdown.getAttribute('data-manual-default') || '';
|
||||
console.log(`Popolamento dropdown per field_id: ${fieldId}, manual_default: ${manualDefault}`);
|
||||
|
||||
dropdown.innerHTML = '<option value="">Seleziona...</option>';
|
||||
|
||||
if (!fieldId || !dropdownData[fieldId] || dropdownData[fieldId].length === 0) {
|
||||
console.warn(`Nessun dato disponibile per field_id ${fieldId}`);
|
||||
dropdown.innerHTML = `<option value="">Nessun valore (field_id ${fieldId} vuoto)</option>`;
|
||||
dropdown.disabled = true; // Disabilita per evitare selezioni inutili
|
||||
return;
|
||||
}
|
||||
|
||||
dropdownData[fieldId].forEach(value => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value.IdCustomFieldsValue;
|
||||
option.textContent = value.Valore;
|
||||
if (manualDefault && String(value.IdCustomFieldsValue) === String(manualDefault)) {
|
||||
option.selected = true;
|
||||
}
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
dropdown.disabled = false;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Errore generale nel caricamento dei dropdown:', error);
|
||||
dropdowns.forEach(dropdown => {
|
||||
dropdown.innerHTML = '<option value="">Errore nel caricamento</option>';
|
||||
dropdown.disabled = true;
|
||||
});
|
||||
} finally {
|
||||
console.log('Nascondo overlay di caricamento.');
|
||||
loadingOverlay.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Carica i dropdown con overlay
|
||||
async function loadDropdownsWithOverlay() {
|
||||
console.log('Inizio caricamento tendine');
|
||||
loadingOverlay.style.display = 'flex';
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
await populateDropdowns();
|
||||
console.log('Caricamento tendine completato');
|
||||
loadingOverlay.style.display = 'none';
|
||||
}
|
||||
|
||||
loadDropdownsWithOverlay();
|
||||
|
||||
async function loadClientAndSchemaNames() {
|
||||
if (<?php echo json_encode($template['idclient'] ?? 0); ?> > 0) {
|
||||
let response = await fetch(`get_clienti.php?id=<?php echo $template['idclient']; ?>`);
|
||||
@@ -267,7 +437,7 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
|
||||
async function updateSchemaDetails() {
|
||||
if (!schemaId) {
|
||||
document.getElementById('schemaFieldsBody').innerHTML = '<tr><td colspan="5" class="text-warning">No schema associated.</td></tr>';
|
||||
document.getElementById('schemaFieldsBody').innerHTML = '<tr><td colspan="6" class="text-warning">No schema associated.</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -284,7 +454,7 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
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="5" class="text-danger">Error: ' + error.message + '</td></tr>';
|
||||
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';
|
||||
@@ -336,9 +506,85 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
}
|
||||
saveMapping(mappingId, event.target.value, manualInput.value, xlsSelect.value);
|
||||
updateXlsDropdowns();
|
||||
} else if (event.target.classList.contains('main-field-checkbox')) {
|
||||
const checkbox = event.target;
|
||||
const mappingId = checkbox.dataset.mappingId;
|
||||
const value = checkbox.checked ? 1 : 0;
|
||||
|
||||
// Se checked, deseleziona tutti gli altri visivamente
|
||||
if (checkbox.checked) {
|
||||
document.querySelectorAll('.main-field-checkbox').forEach(cb => {
|
||||
if (cb !== checkbox) cb.checked = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Salva l'aggiornamento
|
||||
fetch('update_main_field.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
template_id: <?php echo $id; ?>,
|
||||
mapping_id: mappingId,
|
||||
value: value
|
||||
})
|
||||
}).then(response => response.json())
|
||||
.then(data => {
|
||||
if (!data.success) {
|
||||
console.error("❌ Error updating main_field:", data.message);
|
||||
checkbox.checked = !checkbox.checked;
|
||||
document.querySelectorAll('.main-field-checkbox').forEach(cb => {
|
||||
cb.checked = cb.dataset.originalChecked === 'true';
|
||||
});
|
||||
} else {
|
||||
document.querySelectorAll('.main-field-checkbox').forEach(cb => {
|
||||
cb.dataset.originalChecked = cb.checked;
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("❌ Fetch error:", error);
|
||||
checkbox.checked = !checkbox.checked;
|
||||
document.querySelectorAll('.main-field-checkbox').forEach(cb => {
|
||||
cb.checked = cb.dataset.originalChecked === 'true';
|
||||
});
|
||||
});
|
||||
} else if (event.target.classList.contains('visible-import-checkbox')) {
|
||||
const checkbox = event.target;
|
||||
const mappingId = checkbox.dataset.mappingId;
|
||||
const value = checkbox.checked ? 1 : 0;
|
||||
|
||||
fetch('update_visible_import.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
template_id: <?php echo $id; ?>,
|
||||
mapping_id: mappingId,
|
||||
value: value
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!data.success) {
|
||||
console.error("❌ Error updating is_visible_import:", data.message);
|
||||
checkbox.checked = !checkbox.checked;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("❌ Fetch error:", error);
|
||||
checkbox.checked = !checkbox.checked;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Salva lo stato originale dei checkbox al caricamento
|
||||
document.querySelectorAll('.main-field-checkbox').forEach(cb => {
|
||||
cb.dataset.originalChecked = cb.checked;
|
||||
});
|
||||
|
||||
document.getElementById('schemaFieldsBody').addEventListener('change', function(event) {
|
||||
if (event.target.classList.contains('xls-columns')) {
|
||||
let tr = event.target.closest('tr');
|
||||
@@ -347,12 +593,11 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
let mappedColumn = tr.querySelector('.mapped-column');
|
||||
let removeBtn = tr.querySelector('.remove-xls');
|
||||
|
||||
// Aggiungi dinamicamente mappedColumn e removeBtn se non esistono
|
||||
if (!mappedColumn) {
|
||||
mappedColumn = document.createElement('span');
|
||||
mappedColumn.className = 'mapped-column';
|
||||
mappedColumn.style.marginLeft = '5px';
|
||||
tr.querySelector('td:nth-child(4)').appendChild(mappedColumn);
|
||||
tr.querySelector('td:nth-child(5)').appendChild(mappedColumn);
|
||||
}
|
||||
if (!removeBtn) {
|
||||
removeBtn = document.createElement('button');
|
||||
@@ -360,9 +605,8 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
removeBtn.textContent = 'X';
|
||||
removeBtn.style.marginLeft = '5px';
|
||||
removeBtn.setAttribute('data-id', mappingId);
|
||||
tr.querySelector('td:nth-child(4)').appendChild(removeBtn);
|
||||
tr.querySelector('td:nth-child(5)').appendChild(removeBtn);
|
||||
|
||||
// Aggiungi l'event listener per il nuovo pulsante
|
||||
removeBtn.addEventListener('click', function(e) {
|
||||
let tr = e.target.closest('tr');
|
||||
let xlsSelect = tr.querySelector('.xls-columns');
|
||||
@@ -391,12 +635,25 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('schemaFieldsBody').addEventListener('change', function(event) {
|
||||
if (event.target.classList.contains('manual-default') && event.target.tagName === 'SELECT') {
|
||||
let tr = event.target.closest('tr');
|
||||
let mappingId = event.target.getAttribute('data-id');
|
||||
let xlsSelect = tr.querySelector('.xls-columns');
|
||||
console.log("Manual default dropdown changed:", {
|
||||
id: mappingId,
|
||||
value: event.target.value
|
||||
});
|
||||
saveMapping(mappingId, 'manual', event.target.value, xlsSelect.value);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('schemaFieldsBody').addEventListener('input', function(event) {
|
||||
if (event.target.classList.contains('manual-default')) {
|
||||
if (event.target.classList.contains('manual-default') && event.target.tagName === 'INPUT') {
|
||||
let tr = event.target.closest('tr');
|
||||
let mappingId = tr.querySelector('.mapping-select').getAttribute('data-id');
|
||||
let xlsSelect = tr.querySelector('.xls-columns');
|
||||
console.log("Manual default changed:", {
|
||||
console.log("Manual default input changed:", {
|
||||
id: mappingId,
|
||||
value: event.target.value
|
||||
});
|
||||
@@ -448,8 +705,8 @@ $xlsHeaders = $template['xls_headers'] ? json_decode($template['xls_headers'], t
|
||||
console.log("Save response:", data);
|
||||
if (!data.success) console.error("❌ Error saving mapping:", data.message);
|
||||
if (data.success && excelColumn) {
|
||||
usedColumnsFromDB = usedColumnsFromDB.filter(col => col !== excelColumn); // Rimuovi dalla lista se salvata
|
||||
usedColumnsFromDB.push(excelColumn); // Aggiungi la nuova colonna usata
|
||||
usedColumnsFromDB = usedColumnsFromDB.filter(col => col !== excelColumn);
|
||||
usedColumnsFromDB.push(excelColumn);
|
||||
updateXlsDropdowns();
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- Modal -->
|
||||
<!-- Modal modificato con pulsante per riconoscimento vocale -->
|
||||
<div class="modal fade" id="partsModal" tabindex="-1" aria-labelledby="partsModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl" style="max-width: 80% !important; width: 80% !important;">
|
||||
<div class="modal-content">
|
||||
@@ -9,7 +9,15 @@
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6>Elenco Parti</h6>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<h6 style="margin: 0; white-space: nowrap;">Elenco Parti</h6>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<input type="checkbox" id="showMixParts" name="showMixParts" style="margin-right: 5px;">
|
||||
<label for="showMixParts" style="font-size: 0.9rem; margin-right: 10px;">Mix</label>
|
||||
<button type="button" class="btn btn-info btn-sm" id="renumberPartsBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">Rinumera Parti</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm ms-2" id="toggleVoiceBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;"><i class="fas fa-microphone"></i> Voce</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul id="partsList" class="list-group"></ul>
|
||||
<table class="table table-striped table-sm mt-3" id="partsTable">
|
||||
<thead>
|
||||
@@ -36,6 +44,9 @@
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6>Foto del Campione</h6>
|
||||
<div id="photoSelectorContainer" style="display: none;">
|
||||
<!-- Dropdown or buttons for photo selection will appear here -->
|
||||
</div>
|
||||
<div style="position: relative; width: 100%; min-height: 400px;">
|
||||
<img id="samplePhoto" src="" alt="Foto del campione" style="max-width: 100%; max-height: 100%; object-fit: contain; position: absolute; top: 0; left: 0;">
|
||||
<canvas id="photoCanvas" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></canvas>
|
||||
@@ -47,7 +58,8 @@
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="addDescriptionsBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">Aggiungi Lista Descrizioni</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" id="removeAnnotationsBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">Rimuovi Annotazioni</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" id="removeAnnotationsBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">Rimuovi Descrizioni</button>
|
||||
<button type="button" class="btn btn-warning btn-sm" id="undoMarkerBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">Undo Marker</button>
|
||||
<button type="button" class="btn btn-success btn-sm" id="savePhotoBtn" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">Salva Foto con Nome</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal" style="padding: 0.1rem 0.5rem; font-size: 0.8rem;">Chiudi</button>
|
||||
</div>
|
||||
@@ -85,6 +97,11 @@
|
||||
font-size: 0.6rem !important;
|
||||
}
|
||||
|
||||
#partsModal {
|
||||
z-index: 1060 !important;
|
||||
/* Aumentato per superare il modale foto (z-index: 1050) */
|
||||
}
|
||||
|
||||
#partsModal .modal-content {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
@@ -96,12 +113,21 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
#partsList .list-group-item:hover {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
#partsList input[type="color"] {
|
||||
width: 30px;
|
||||
height: 24px;
|
||||
padding: 0;
|
||||
margin-left: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.draggable-description {
|
||||
position: absolute;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
@@ -118,8 +144,6 @@
|
||||
position: absolute;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: rgba(255, 0, 0, 0.5);
|
||||
border: 1px solid #ff0000;
|
||||
border-radius: 50%;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
@@ -142,4 +166,33 @@
|
||||
padding: 0.1rem 0.3rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
/* Normale Save button */
|
||||
#savePhotoBtn {
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
/* Unsaved changes */
|
||||
#savePhotoBtn.unsaved {
|
||||
background-color: #dc3545 !important;
|
||||
/* Rosso */
|
||||
border-color: #dc3545 !important;
|
||||
color: white !important;
|
||||
animation: pulse 1.2s infinite;
|
||||
}
|
||||
|
||||
/* Animazione pulsante */
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.7);
|
||||
}
|
||||
|
||||
70% {
|
||||
box-shadow: 0 0 10px 15px rgba(220, 53, 69, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(220, 53, 69, 0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,12 @@
|
||||
<?php
|
||||
// photos_popup.php
|
||||
include('include/headscript.php');
|
||||
// Includi Fabric.js solo per questa pagina
|
||||
?>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
|
||||
|
||||
<?php
|
||||
// Includi l'autoloader di Composer
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
@@ -11,52 +17,131 @@ use Endroid\QrCode\QrCode;
|
||||
use Endroid\QrCode\RoundBlockSizeMode;
|
||||
use Endroid\QrCode\Writer\PngWriter;
|
||||
|
||||
// Abilita logging per debug
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log', __DIR__ . '/photos_popup_debug.log');
|
||||
|
||||
// Log iniziale
|
||||
error_log("Richiesta a photos_popup.php: " . print_r($_GET, true));
|
||||
|
||||
// Carica le variabili d'ambiente
|
||||
try {
|
||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../../');
|
||||
$dotenv->load();
|
||||
} catch (Exception $e) {
|
||||
error_log("Errore nel caricamento del file .env: " . $e->getMessage());
|
||||
?>
|
||||
<div class="popup-content">
|
||||
<p>Errore: Impossibile caricare il file di configurazione.</p>
|
||||
</div>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verifica che BASE_URL sia definito
|
||||
if (!isset($_ENV['BASE_URL'])) {
|
||||
error_log("Errore: la variabile BASE_URL non è definita nel file .env");
|
||||
?>
|
||||
<div class="popup-content">
|
||||
<p>Errore: Variabile BASE_URL non definita.</p>
|
||||
</div>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// Verifica che l'iddatadb sia stato passato
|
||||
if (!isset($_GET['iddatadb']) || empty($_GET['iddatadb'])) {
|
||||
echo json_encode(['error' => 'ID riga non fornito']);
|
||||
// Verifica che almeno uno degli ID sia passato
|
||||
$iddatadb = isset($_GET['iddatadb']) && !empty($_GET['iddatadb']) ? intval($_GET['iddatadb']) : null;
|
||||
$idquotations = isset($_GET['idquotations']) && !empty($_GET['idquotations']) ? intval($_GET['idquotations']) : null;
|
||||
|
||||
if (!$iddatadb && !$idquotations) {
|
||||
error_log("Errore: ID riga o ID quotations non fornito");
|
||||
?>
|
||||
<div class="popup-content">
|
||||
<p>Errore: ID riga o ID quotations non fornito.</p>
|
||||
</div>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
|
||||
$iddatadb = intval($_GET['iddatadb']);
|
||||
|
||||
// Recupera i dettagli della riga (idriga e sample_code)
|
||||
$stmt = $pdo->prepare("SELECT iddatadb, sample_code FROM datadb WHERE iddatadb = ?");
|
||||
$stmt->execute([$iddatadb]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
echo json_encode(['error' => 'Riga non trovata']);
|
||||
if ($iddatadb && $idquotations) {
|
||||
error_log("Errore: Non è possibile specificare sia iddatadb che idquotations");
|
||||
?>
|
||||
<div class="popup-content">
|
||||
<p>Errore: Non è possibile specificare sia iddatadb che idquotations.</p>
|
||||
</div>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
|
||||
$idriga = $row['iddatadb'];
|
||||
$sampleCode = $row['sample_code'] ?? 'Non disponibile';
|
||||
// Determina quale ID e tabella usare
|
||||
$paramName = $iddatadb ? 'iddatadb' : 'id'; // Usa 'id' per quotations
|
||||
$paramValue = $iddatadb ?: $idquotations;
|
||||
$table = $iddatadb ? 'datadb' : 'quotations';
|
||||
$field = $iddatadb ? 'sample_code' : 'description'; // Usa 'description' per quotations
|
||||
$photoTable = 'datadb_photos'; // Usa sempre datadb_photos
|
||||
$photoParamName = $iddatadb ? 'iddatadb' : 'idquotations'; // Usa 'idquotations' per datadb_photos
|
||||
|
||||
// Recupera i dettagli della riga
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT {$paramName}, {$field} FROM {$table} WHERE {$paramName} = ?");
|
||||
$stmt->execute([$paramValue]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
error_log("Errore: Riga non trovata per {$paramName} = {$paramValue}");
|
||||
?>
|
||||
<div class="popup-content">
|
||||
<p>Errore: Riga non trovata.</p>
|
||||
</div>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log("Errore query dettagli riga: " . $e->getMessage());
|
||||
?>
|
||||
<div class="popup-content">
|
||||
<p>Errore: Impossibile recuperare i dettagli della riga.</p>
|
||||
</div>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = $row[$paramName];
|
||||
$code = $row[$field] ?? 'Non disponibile';
|
||||
|
||||
// Recupera le foto associate alla riga
|
||||
$stmt = $pdo->prepare("SELECT id, file_path, file_name, description, uploaded_at FROM datadb_photos WHERE iddatadb = ? ORDER BY uploaded_at DESC");
|
||||
$stmt->execute([$iddatadb]);
|
||||
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT id, file_path, file_name, description, uploaded_at FROM {$photoTable} WHERE {$photoParamName} = ? ORDER BY uploaded_at DESC");
|
||||
$stmt->execute([$paramValue]);
|
||||
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (Exception $e) {
|
||||
error_log("Errore query foto: " . $e->getMessage());
|
||||
$photos = []; // Imposta array vuoto in caso di errore
|
||||
}
|
||||
|
||||
// Definisci il percorso base per le foto
|
||||
$photoBasePath = '../photostrf/';
|
||||
|
||||
// Genera l'URL per il QR code
|
||||
$baseUrl = "http://localhost/trf_certest/public/userarea/"; // Sostituisci con il tuo dominio
|
||||
$uploadUrl = $baseUrl . "upload_photos_mobile.php?iddatadb=" . $iddatadb;
|
||||
// Usa la variabile d'ambiente BASE_URL
|
||||
$baseUrl = rtrim($_ENV['BASE_URL'], '/');
|
||||
$uploadUrl = $iddatadb
|
||||
? $baseUrl . "/upload_photos_mobile.php?iddatadb=" . $iddatadb
|
||||
: $baseUrl . "/upload_photos_mobile.php?idquotations=" . $idquotations;
|
||||
|
||||
// Genera il QR code con endroid/qr-code 6.0.6
|
||||
$qrCodeDir = '../photostrf/qrcodes/';
|
||||
if (!is_dir($qrCodeDir)) {
|
||||
mkdir($qrCodeDir, 0755, true);
|
||||
}
|
||||
$qrCodeFile = $qrCodeDir . "qrcode_{$iddatadb}.png";
|
||||
$qrCodeFile = $qrCodeDir . "qrcode_{$id}.png";
|
||||
|
||||
$writer = new PngWriter();
|
||||
|
||||
// Crea il QR code usando il costruttore
|
||||
$qrCode = new QrCode(
|
||||
data: $uploadUrl,
|
||||
encoding: new Encoding('UTF-8'),
|
||||
@@ -80,13 +165,13 @@ $result->saveToFile($qrCodeFile);
|
||||
</div>
|
||||
</div>
|
||||
<h3>Manage Photos</h3>
|
||||
<p><strong>ID Row:</strong> <?= htmlspecialchars($idriga) ?></p>
|
||||
<p><strong>Sample Code:</strong> <?= htmlspecialchars($sampleCode) ?></p>
|
||||
<p><strong>ID:</strong> <?= htmlspecialchars($id) ?></p>
|
||||
<p><strong>Code:</strong> <?= htmlspecialchars($code) ?></p>
|
||||
|
||||
<!-- QR Code per il caricamento da mobile -->
|
||||
<div style="text-align: center; margin-bottom: 20px;">
|
||||
<p>Scan the QR Code with the mobile to take photo with camera:</p>
|
||||
<img src="../photostrf/qrcodes/qrcode_<?= $iddatadb ?>.png" alt="QR Code" style="max-width: 150px;">
|
||||
<img src="../photostrf/qrcodes/qrcode_<?= htmlspecialchars($id) ?>.png" alt="QR Code" style="max-width: 150px;">
|
||||
<p style="margin-top: 10px;">
|
||||
<a href="<?= htmlspecialchars($uploadUrl) ?>" target="_blank"><?= htmlspecialchars($uploadUrl) ?></a>
|
||||
</p>
|
||||
@@ -100,6 +185,9 @@ $result->saveToFile($qrCodeFile);
|
||||
<!-- Area per la webcam -->
|
||||
<div id="webcamArea" style="display: none; text-align: center; margin-bottom: 20px;">
|
||||
<p>Webcam Preview</p>
|
||||
<select id="webcamSelect" style="margin-bottom: 10px; padding: 5px;">
|
||||
<option value="">Select a webcam</option>
|
||||
</select>
|
||||
<video id="webcamVideo" autoplay playsinline style="max-width: 100%; max-height: 300px;"></video>
|
||||
<div style="margin-top: 10px;">
|
||||
<button id="captureBtn" style="padding: 10px 20px; background: #28a745; color: white; border: none; cursor: pointer;">Capture Photo</button>
|
||||
@@ -110,7 +198,7 @@ $result->saveToFile($qrCodeFile);
|
||||
<!-- Elenco delle foto -->
|
||||
<div id="photosList">
|
||||
<?php if (empty($photos)): ?>
|
||||
<p>No Photos present.</p>
|
||||
<p>Nessuna foto presente.</p>
|
||||
<?php else: ?>
|
||||
<?php foreach ($photos as $photo): ?>
|
||||
<?php
|
||||
@@ -135,6 +223,8 @@ $result->saveToFile($qrCodeFile);
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<!-- Bottone Crea Collage -->
|
||||
<button id="createCollageBtn" style="padding: 10px 20px; background: #ffc107; color: white; border: none; cursor: pointer; margin-top: 20px;">Crea Collage</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
@@ -143,6 +233,52 @@ $result->saveToFile($qrCodeFile);
|
||||
<span class="image-modal-close">×</span>
|
||||
<img id="enlargedImage" class="image-modal-content" src="" alt="Immagine ingrandita">
|
||||
</div>
|
||||
|
||||
<!-- Modale per collage -->
|
||||
<div id="collageModal" class="modal" style="display: none; position: fixed; z-index: 1002; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0,0,0,0.8);">
|
||||
<div class="modal-content" style="background: white; margin: 5% auto; padding: 20px; width: 80%; max-width: 1200px; position: relative;">
|
||||
<span class="close-collage" style="position: absolute; top: 10px; right: 20px; font-size: 30px; font-weight: bold; color: #333; cursor: pointer; z-index: 1003; background: #fff; padding: 5px 10px; border-radius: 50%;">×</span>
|
||||
<h3>Crea Collage</h3>
|
||||
|
||||
<!-- Lista foto selezionabili -->
|
||||
<div id="collagePhotoList" style="max-height: 200px; overflow-y: auto; margin-bottom: 20px;">
|
||||
<?php foreach ($photos as $photo): ?>
|
||||
<div style="display: inline-block; margin: 10px;">
|
||||
<input type="checkbox" class="photo-checkbox" data-path="../photostrf/<?= htmlspecialchars($photo['file_path']) ?>">
|
||||
<img src="../photostrf/<?= htmlspecialchars($photo['file_path']) ?>" alt="" style="width: 80px; height: 80px;">
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<!-- Bottone per aggiungere selezionate al canvas -->
|
||||
<button id="addToCanvasBtn">Aggiungi Selezionate al Canvas</button>
|
||||
|
||||
<!-- Canvas per editing -->
|
||||
<canvas id="collageCanvas" width="800" height="600" style="border: 1px solid #ccc; margin-top: 20px;"></canvas>
|
||||
|
||||
<!-- Pannello dei livelli -->
|
||||
<div id="layersPanel" style="width: 120px; max-height: 600px; overflow-y: auto; background: #f8f9fa; padding: 10px; position: absolute; right: 0; top: 60px;">
|
||||
<h4 style="margin: 0 0 10px 0; font-size: 16px;">Livelli</h4>
|
||||
<ul id="layersList" style="list-style: none; padding: 0;"></ul>
|
||||
</div>
|
||||
|
||||
<!-- Bottoni azioni -->
|
||||
<div style="margin-top: 20px; display: flex; flex-wrap: wrap; gap: 5px;">
|
||||
<button id="saveCollageBtn" title="Salva il collage"><i class="fas fa-save"></i></button>
|
||||
<button id="bringToFrontBtn" title="Porta in primo piano"><i class="fas fa-arrow-up"></i></button>
|
||||
<button id="sendToBackBtn" title="Manda in fondo"><i class="fas fa-arrow-down"></i></button>
|
||||
<button id="bringForwardBtn" title="Sposta avanti di un livello"><i class="fas fa-arrow-circle-up"></i></button>
|
||||
<button id="sendBackwardBtn" title="Sposta indietro di un livello"><i class="fas fa-arrow-circle-down"></i></button>
|
||||
<button id="cropImageBtn" title="Ritaglia immagine selezionata" disabled><i class="fas fa-crop"></i></button>
|
||||
<button id="applyCropBtn" title="Applica ritaglio" disabled><i class="fas fa-crop"></i> Applica</button>
|
||||
<button id="cancelCropBtn" title="Annulla ritaglio" disabled><i class="fas fa-crop"></i> Annulla</button>
|
||||
<button id="removeBackgroundBtn" title="Rimuovi sfondo immagine selezionata" disabled><i class="fas fa-eraser"></i> Rimuovi Sfondo</button>
|
||||
<button id="removeImageBtn" title="Rimuovi immagine selezionata" disabled><i class="fas fa-trash-alt"></i> Rimuovi</button>
|
||||
<button id="undoBtn" title="Annulla ultima azione" disabled><i class="fas fa-undo"></i></button>
|
||||
<p id="backgroundRemovalInstruction" style="display: none; color: #007bff;">Clicca sull'immagine per selezionare il colore dello sfondo da rimuovere</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -159,7 +295,6 @@ $result->saveToFile($qrCodeFile);
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
|
||||
/* Stile per il modale dell'immagine ingrandita */
|
||||
.image-modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
@@ -199,7 +334,6 @@ $result->saveToFile($qrCodeFile);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Stili per il loader */
|
||||
.loader {
|
||||
display: none;
|
||||
position: fixed;
|
||||
@@ -224,4 +358,71 @@ $result->saveToFile($qrCodeFile);
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Stile per i pulsanti del modale collage */
|
||||
#collageModal button {
|
||||
padding: 8px 12px;
|
||||
margin: 5px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#saveCollageBtn {
|
||||
background: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#bringToFrontBtn,
|
||||
#sendToBackBtn,
|
||||
#bringForwardBtn,
|
||||
#sendBackwardBtn {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#cropImageBtn,
|
||||
#applyCropBtn,
|
||||
#cancelCropBtn,
|
||||
#removeBackgroundBtn,
|
||||
#removeImageBtn,
|
||||
#undoBtn {
|
||||
background: #ffc107;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#collageModal button:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
#collageModal button i {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Stile per il pannello dei livelli */
|
||||
#layersPanel {
|
||||
z-index: 1002;
|
||||
}
|
||||
|
||||
#layersPanel li {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#layersPanel img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 2px solid #ccc;
|
||||
cursor: pointer;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
#layersPanel img:hover {
|
||||
border-color: #007bff;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,429 @@
|
||||
<?php
|
||||
// Abilita errori per debug
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log', __DIR__ . '/quotations_debug.log');
|
||||
if (!file_exists(__DIR__ . '/quotations_debug.log')) {
|
||||
file_put_contents(__DIR__ . '/quotations_debug.log', "Inizio operazioni alle " . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
|
||||
}
|
||||
|
||||
// Log iniziale
|
||||
error_log("Inizio operazioni alle " . date('Y-m-d H:i:s'));
|
||||
|
||||
include('include/headscript.php');
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// Recupera l'ID dell'utente loggato
|
||||
$user_id = $iduserlogin ?? 1;
|
||||
|
||||
// Gestione creazione nuova quotation (crea record vuoto su conferma)
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'create') {
|
||||
$description = '';
|
||||
$customer = '';
|
||||
|
||||
$stmt = $pdo->prepare("INSERT INTO quotations (description, customer, iduser) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$description, $customer, $user_id]);
|
||||
$newId = $pdo->lastInsertId();
|
||||
|
||||
// Log creazione
|
||||
error_log("Creata nuova quotation ID: $newId");
|
||||
|
||||
// Reindirizza alla modifica della nuova quotation
|
||||
header("Location: quotations.php?edit_id=" . $newId . "&status=success&message=" . urlencode("Quotation creata con successo"));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Gestione modifica quotation
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update' && isset($_POST['id'])) {
|
||||
$id = intval($_POST['id']);
|
||||
$description = $_POST['description'] ?? '';
|
||||
$customer = $_POST['customer'] ?? '';
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE quotations SET description = ?, customer = ? WHERE id = ? AND iduser = ?");
|
||||
$stmt->execute([$description, $customer, $id, $user_id]);
|
||||
|
||||
// Log modifica
|
||||
error_log("Modificata quotation ID: $id");
|
||||
|
||||
// Reindirizza alla lista delle quotations
|
||||
header("Location: quotations.php?status=success&message=" . urlencode("Quotation modificata con successo"));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Gestione cancellazione quotation
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete' && isset($_POST['id'])) {
|
||||
$id = intval($_POST['id']);
|
||||
|
||||
$stmt = $pdo->prepare("DELETE FROM quotations WHERE id = ? AND iduser = ?");
|
||||
$stmt->execute([$id, $user_id]);
|
||||
|
||||
// Log cancellazione
|
||||
error_log("Cancellata quotation ID: $id");
|
||||
|
||||
header("Location: quotations.php?status=success&message=" . urlencode("Quotation cancellata con successo"));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Recupera tutte le quotations per l'utente
|
||||
$stmt = $pdo->prepare("SELECT * FROM quotations WHERE iduser = ? ORDER BY creation_date DESC");
|
||||
$stmt->execute([$user_id]);
|
||||
$quotations = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Verifica se è richiesta la modifica di una quotation
|
||||
$editQuotation = null;
|
||||
if (isset($_GET['edit_id'])) {
|
||||
$editId = intval($_GET['edit_id']);
|
||||
$stmt = $pdo->prepare("SELECT * FROM quotations WHERE id = ? AND iduser = ?");
|
||||
$stmt->execute([$editId, $user_id]);
|
||||
$editQuotation = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
?>
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2Lw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
|
||||
<style>
|
||||
/* Stili simili alla pagina fornita, adattati */
|
||||
.cell-changed {
|
||||
background-color: #fff3b0 !important;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
input.manual-input,
|
||||
select.manual-input {
|
||||
background-color: #fff3cd;
|
||||
}
|
||||
|
||||
input.required-input,
|
||||
select.required-input {
|
||||
background-color: #f8d7da;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 6px 8px;
|
||||
margin-right: 5px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
width: 35px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.photos-btn {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.parts-btn {
|
||||
background-color: #ffc107;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.form-group textarea {
|
||||
height: 100px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.flash-success {
|
||||
background-color: #d4edda !important;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.quotation-actions {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1050;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: #fefefe;
|
||||
margin: 15% auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
max-width: 600px;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.close-btn:hover,
|
||||
.close-btn:focus {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<title>Gestione Quotations - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<?php include('include/navbar.php'); ?>
|
||||
<?php include('include/topbar.php'); ?>
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content">
|
||||
<div class="card radius-10">
|
||||
<div class="card-header">
|
||||
<div class="d-flex align-items-center">
|
||||
<div>
|
||||
<h6 class="mb-0">Gestione Quotations</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php if ($editQuotation): ?>
|
||||
<!-- Modifica Quotation -->
|
||||
<h6 class="mb-3">Modifica Quotation ID: <?= $editQuotation['id'] ?></h6>
|
||||
<form id="editForm" method="post">
|
||||
<input type="hidden" name="action" value="update">
|
||||
<input type="hidden" name="id" value="<?= $editQuotation['id'] ?>">
|
||||
<div class="form-group">
|
||||
<label for="description">Descrizione</label>
|
||||
<textarea id="description" name="description" class="manual-input required-input" required><?= htmlspecialchars($editQuotation['description']) ?></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="customer">Cliente</label>
|
||||
<input type="text" id="customer" name="customer" class="manual-input required-input" value="<?= htmlspecialchars($editQuotation['customer']) ?>" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Salva Modifiche</button>
|
||||
<a href="quotations.php" class="btn btn-secondary">Torna alla Lista</a>
|
||||
</form>
|
||||
<div class="quotation-actions">
|
||||
<h6 class="mb-3">Azioni</h6>
|
||||
<button type="button" class="photos-btn action-btn" data-row="<?= $index ?>" data-idquotations="<?= $editQuotation['id'] ?>" style="background: #007bff; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; flex: 1;"><i class="fas fa-camera"></i></button>
|
||||
<button class="parts-btn" data-iddatadb="" data-idquotations="456" data-row="0">Parti</button>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<!-- Lista Quotations -->
|
||||
<div class="mb-3">
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#createModal">Crea Nuova Quotation</button>
|
||||
</div>
|
||||
<h6 class="mb-3">Quotations Esistenti</h6>
|
||||
<table id="quotationsTable" class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Data Creazione</th>
|
||||
<th>Descrizione</th>
|
||||
<th>Cliente</th>
|
||||
<th>Azioni</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($quotations as $row): ?>
|
||||
<tr data-id="<?= $row['id'] ?>">
|
||||
<td><?= htmlspecialchars($row['id']) ?></td>
|
||||
<td><?= htmlspecialchars($row['creation_date']) ?></td>
|
||||
<td>
|
||||
<textarea name="description" class="cell-input manual-input form-control"><?= htmlspecialchars($row['description']) ?></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="customer" class="cell-input manual-input form-control" value="<?= htmlspecialchars($row['customer']) ?>">
|
||||
</td>
|
||||
<!-- In quotations.php, nella tabella delle quotations -->
|
||||
<td>
|
||||
<button type="button" class="save-btn action-btn edit-btn" data-id="<?= $row['id'] ?>" title="Salva Modifiche"><i class="fas fa-save"></i></button>
|
||||
<button type="button" class="delete-btn action-btn" data-id="<?= $row['id'] ?>" title="Cancella" data-bs-toggle="modal" data-bs-target="#deleteModal"><i class="fas fa-trash"></i></button>
|
||||
<button type="button" class="photos-btn action-btn" data-entity-type="quotation" data-idquotations="<?= $row['id'] ?>" title="Photos"><i class="fas fa-camera"></i></button>
|
||||
<button type="button" class="parts-btn action-btn" data-entity-type="quotation" data-idquotations="<?= $row['id'] ?>" title="Parts"><i class="fas fa-puzzle-piece"></i></button>
|
||||
<a href="quotations.php?edit_id=<?= $row['id'] ?>" class="btn btn-secondary action-btn" title="Modifica Dettagliata"><i class="fas fa-edit"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal per conferma creazione nuova quotation -->
|
||||
<div class="modal fade" id="createModal" tabindex="-1" aria-labelledby="createModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="createModalLabel">Conferma Creazione Nuova Quotation</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Vuoi creare una nuova quotation?</p>
|
||||
<form id="createModalForm" method="post">
|
||||
<input type="hidden" name="action" value="create">
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||
<button type="button" class="btn btn-primary" id="confirmCreate">Conferma</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Modal per conferma cancellazione -->
|
||||
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="deleteModalLabel">Conferma Cancellazione</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Sicuro di voler cancellare questa quotation?</p>
|
||||
<form id="deleteForm" method="post">
|
||||
<input type="hidden" name="action" value="delete">
|
||||
<input type="hidden" name="id" id="deleteQuotationId">
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annulla</button>
|
||||
<button type="button" class="btn btn-danger" id="confirmDelete">Conferma</button>
|
||||
</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('modal_parts.php'); ?>
|
||||
<?php include('photos_functions.php'); ?>
|
||||
<?php include('jsinclude.php'); ?>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
|
||||
<script src="photos.js"></script>
|
||||
<script src="parts.js"></script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Inizializza DataTables se non siamo in modalità modifica
|
||||
if (!document.querySelector('#editForm')) {
|
||||
$('#quotationsTable').DataTable({
|
||||
"paging": true,
|
||||
"searching": true,
|
||||
"ordering": true,
|
||||
"info": true,
|
||||
"autoWidth": false,
|
||||
"responsive": true
|
||||
});
|
||||
}
|
||||
|
||||
// Gestione conferma creazione nel modal
|
||||
document.getElementById('confirmCreate').addEventListener('click', function() {
|
||||
document.getElementById('createModalForm').submit();
|
||||
});
|
||||
|
||||
// Gestione modifica inline e save nella lista
|
||||
document.querySelectorAll('.edit-btn').forEach(btn => {
|
||||
btn.addEventListener('click', function() {
|
||||
const row = this.closest('tr');
|
||||
const id = row.dataset.id;
|
||||
const description = row.querySelector('textarea[name="description"]').value;
|
||||
const customer = row.querySelector('input[name="customer"]').value;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('action', 'update');
|
||||
formData.append('id', id);
|
||||
formData.append('description', description);
|
||||
formData.append('customer', customer);
|
||||
|
||||
fetch('quotations.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
row.classList.add('flash-success');
|
||||
setTimeout(() => row.classList.remove('flash-success'), 500);
|
||||
alert('Quotation modificata con successo!');
|
||||
} else {
|
||||
alert('Errore durante la modifica.');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione apertura modal di cancellazione
|
||||
document.querySelectorAll('.delete-btn').forEach(btn => {
|
||||
btn.addEventListener('click', function() {
|
||||
const id = this.dataset.id;
|
||||
document.getElementById('deleteQuotationId').value = id;
|
||||
});
|
||||
});
|
||||
|
||||
// Gestione conferma cancellazione nel modal
|
||||
document.getElementById('confirmDelete').addEventListener('click', function() {
|
||||
document.getElementById('deleteForm').submit();
|
||||
});
|
||||
|
||||
// I bottoni photos e parts usano gli script esistenti (photos.js, parts.js), passando data-idquotations
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Modale per le foto in quotations.php -->
|
||||
<div class="modal" id="photosModal">
|
||||
<div class="modal-content">
|
||||
<span class="close-btn">×</span>
|
||||
<div class="popup-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$iddatadb = $data['iddatadb'] ?? null;
|
||||
$parts = $data['parts'] ?? [];
|
||||
|
||||
if (!$iddatadb || empty($parts)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Dati mancanti']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// Elimina tutte le parti esistenti per l'iddatadb per evitare conflitti di unicità
|
||||
$stmt = $pdo->prepare("DELETE FROM identification_parts WHERE iddatadb = :iddatadb");
|
||||
$stmt->execute([':iddatadb' => $iddatadb]);
|
||||
|
||||
// Prepara l'inserimento delle nuove parti
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO identification_parts
|
||||
(iddatadb, part_number, part_description, mix, created_at, updated_at)
|
||||
VALUES (:iddatadb, :part_number, :part_description, :mix, NOW(), NOW())
|
||||
");
|
||||
|
||||
$part_ids = [];
|
||||
foreach ($parts as $part) {
|
||||
$partNumber = $part['part_number'] ?? null;
|
||||
$partDescription = $part['part_description'] ?? '';
|
||||
$mix = $part['mix'] ?? 'N';
|
||||
|
||||
if (!$partNumber || !$partDescription) {
|
||||
throw new PDOException("Numero parte o descrizione mancante per parte: " . json_encode($part));
|
||||
}
|
||||
|
||||
$stmt->execute([
|
||||
':iddatadb' => $iddatadb,
|
||||
':part_number' => $partNumber,
|
||||
':part_description' => $partDescription,
|
||||
':mix' => $mix
|
||||
]);
|
||||
$part_ids[] = $pdo->lastInsertId();
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'part_ids' => $part_ids,
|
||||
'message' => 'Parti rinumerate con successo'
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
$pdo->rollBack();
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Errore nel salvataggio: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$idquotations = $data['idquotations'] ?? null;
|
||||
$parts = $data['parts'] ?? [];
|
||||
|
||||
if (!$idquotations || empty($parts)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Dati mancanti']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// Elimina tutte le parti esistenti per idquotations
|
||||
$stmt = $pdo->prepare("DELETE FROM identification_parts WHERE idquotations = :idquotations");
|
||||
$stmt->execute([':idquotations' => $idquotations]);
|
||||
|
||||
// Prepara l'inserimento delle nuove parti
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO identification_parts
|
||||
(idquotations, part_number, part_description, mix, created_at, updated_at)
|
||||
VALUES (:idquotations, :part_number, :part_description, :mix, NOW(), NOW())
|
||||
");
|
||||
|
||||
$part_ids = [];
|
||||
foreach ($parts as $part) {
|
||||
$partNumber = $part['part_number'] ?? null;
|
||||
$partDescription = $part['part_description'] ?? '';
|
||||
$mix = $part['mix'] ?? 'N';
|
||||
|
||||
if (!$partNumber || !$partDescription) {
|
||||
throw new PDOException("Numero parte o descrizione mancante per parte: " . json_encode($part));
|
||||
}
|
||||
|
||||
$stmt->execute([
|
||||
':idquotations' => $idquotations,
|
||||
':part_number' => $partNumber,
|
||||
':part_description' => $partDescription,
|
||||
':mix' => $mix
|
||||
]);
|
||||
$part_ids[] = $pdo->lastInsertId();
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'part_ids' => $part_ids,
|
||||
'message' => 'Parti rinumerate con successo'
|
||||
]);
|
||||
} catch (PDOException $e) {
|
||||
$pdo->rollBack();
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Errore nel salvataggio: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
@@ -1,25 +1,53 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
include('include/headscript.php');
|
||||
include('include/headscript.php'); // აქედან უნდა იყოს DB კავშირიც
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$dataURL = $_POST['dataURL'] ?? null;
|
||||
$filename = $_POST['filename'] ?? null;
|
||||
$dataURL = $_POST['dataURL'] ?? null;
|
||||
$filename = $_POST['filename'] ?? null;
|
||||
$iddatadb = $_POST['iddatadb'] ?? null; // 🟢 ახალი ველი
|
||||
|
||||
if (!$dataURL || !$filename) {
|
||||
if (!$dataURL || !$filename || !$iddatadb) {
|
||||
echo json_encode(['success' => false, 'message' => 'Dati mancanti']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// --- ფაილის შენახვა ---
|
||||
$data = explode(',', $dataURL)[1];
|
||||
$decodedData = base64_decode($data);
|
||||
$filePath = '../photostrf/annotated/' . $filename; // Crea una sottocartella 'annotated' per le foto modificate
|
||||
if (!file_exists('../photostrf/annotated')) {
|
||||
mkdir('../photostrf/annotated', 0777, true);
|
||||
|
||||
$dirPath = '../photostrf/annotated';
|
||||
if (!file_exists($dirPath)) {
|
||||
mkdir($dirPath, 0777, true);
|
||||
}
|
||||
|
||||
$filePath = $dirPath . '/' . $filename;
|
||||
file_put_contents($filePath, $decodedData);
|
||||
echo json_encode(['success' => true, 'file_path' => $filePath, 'message' => 'Foto salvata con successo']);
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// --- ბაზაში ჩაწერა ---
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO datadb_photos (iddatadb, file_path, file_name, uploaded_at, uploaded_by)
|
||||
VALUES (:iddatadb, :file_path, :file_name, NOW(), :uploaded_by)
|
||||
");
|
||||
$stmt->execute([
|
||||
':iddatadb' => $iddatadb,
|
||||
':file_path' => $filePath,
|
||||
':file_name' => $filename,
|
||||
':uploaded_by'=> $iduserlogin
|
||||
]);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'file_path' => $filePath,
|
||||
'message' => 'Foto salvata con successo e registrata nel DB'
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio: ' . $e->getMessage()]);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
include('include/headscript.php');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$dataURL = $_POST['dataURL'] ?? null;
|
||||
$filename = $_POST['filename'] ?? null;
|
||||
$idquotations = $_POST['idquotations'] ?? null;
|
||||
|
||||
if (!$dataURL || !$filename || !$idquotations) {
|
||||
echo json_encode(['success' => false, 'message' => 'Dati mancanti']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
// Verifica che idquotations esista nella tabella quotations
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
$stmt = $pdo->prepare("SELECT idquotations FROM quotations WHERE idquotations = :idquotations");
|
||||
$stmt->execute([':idquotations' => $idquotations]);
|
||||
if (!$stmt->fetch()) {
|
||||
echo json_encode(['success' => false, 'message' => 'idquotations non valido']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Salva l'immagine
|
||||
$data = explode(',', $dataURL)[1];
|
||||
$decodedData = base64_decode($data);
|
||||
|
||||
$dirPath = '../photostrf/annotated';
|
||||
if (!file_exists($dirPath)) {
|
||||
mkdir($dirPath, 0777, true);
|
||||
}
|
||||
|
||||
$filePath = $dirPath . '/' . $filename;
|
||||
file_put_contents($filePath, $decodedData);
|
||||
|
||||
// Registra nel database
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO datadb_photos (idquotations, file_path, file_name, uploaded_at, uploaded_by)
|
||||
VALUES (:idquotations, :file_path, :file_name, NOW(), :uploaded_by)
|
||||
");
|
||||
$stmt->execute([
|
||||
':idquotations' => $idquotations,
|
||||
':file_path' => $filePath,
|
||||
':file_name' => $filename,
|
||||
':uploaded_by' => $iduserlogin
|
||||
]);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'file_path' => $filePath,
|
||||
'message' => 'Foto salvata con successo e registrata nel DB'
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -14,28 +14,64 @@ try {
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// Prepara i dati da aggiornare
|
||||
$updates = [];
|
||||
$values = [];
|
||||
foreach ($_POST as $key => $value) {
|
||||
if ($key !== 'iddatadb') {
|
||||
$updates[] = "$key = ?";
|
||||
$values[] = htmlspecialchars($value);
|
||||
$data = $_POST;
|
||||
$details = [];
|
||||
|
||||
// 1. POST-დან ამოვიღოთ მხოლოდ details
|
||||
foreach ($data as $key => $value) {
|
||||
if (preg_match('/^details(\d+)field_value$/', $key, $matches)) {
|
||||
$id = $matches[1];
|
||||
$details[$id] = $value;
|
||||
}
|
||||
}
|
||||
$values[] = $iddatadb;
|
||||
|
||||
if (empty($updates)) {
|
||||
throw new Exception('Nessun dato da aggiornare');
|
||||
// 2. DB-დან წამოვიღოთ არსებული მნიშვნელობები
|
||||
$stmt = $pdo->prepare("SELECT mapping_id, field_value FROM import_data_details WHERE id = ?");
|
||||
$stmt->execute([$iddatadb]);
|
||||
|
||||
$currentValues = [];
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$currentValues[$row['mapping_id']] = $row['field_value'];
|
||||
}
|
||||
|
||||
$sql = "UPDATE datadb SET " . implode(', ', $updates) . " WHERE iddatadb = ?";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($values);
|
||||
// 3. შევადაროთ POST-ს და DB-ს
|
||||
$changed = [];
|
||||
foreach ($details as $id => $newValue) {
|
||||
$oldValue = $currentValues[$id] ?? null;
|
||||
if ($oldValue !== $newValue) {
|
||||
$changed[$id] = [
|
||||
'old' => $oldValue,
|
||||
'new' => $newValue
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// 4. თუ არის ცვლილებები → UPDATE
|
||||
if (!empty($changed)) {
|
||||
$updateStmt = $pdo->prepare("
|
||||
UPDATE import_data_details
|
||||
SET field_value = :newValue
|
||||
WHERE id = :iddatadb AND mapping_id = :mappingId
|
||||
");
|
||||
|
||||
foreach ($changed as $mappingId => $values) {
|
||||
$updateStmt->execute([
|
||||
':newValue' => $values['new'],
|
||||
':iddatadb' => $iddatadb,
|
||||
':mappingId' => $mappingId
|
||||
]);
|
||||
}
|
||||
|
||||
$response['success'] = true;
|
||||
$response['message'] = "Updated successfully";
|
||||
$response['changed'] = $changed; // Debug / optional
|
||||
} else {
|
||||
$response['success'] = true;
|
||||
$response['message'] = "No changes found";
|
||||
}
|
||||
|
||||
$response['success'] = true;
|
||||
$response['message'] = 'Riga aggiornata con successo';
|
||||
} catch (Exception $e) {
|
||||
$response['success'] = false;
|
||||
$response['message'] = $e->getMessage();
|
||||
error_log("Errore in save_edited_row.php: " . $e->getMessage());
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
@@ -17,20 +16,42 @@ if (!$iddatadb || empty($parts)) {
|
||||
}
|
||||
|
||||
$part = $parts[0];
|
||||
$partId = $part['id'] ?? null; // part_id თუ არსებობს
|
||||
$partNumber = $part['part_number'] ?? null;
|
||||
$partDescription = $part['part_description'] ?? '';
|
||||
$mix = $part['mix'] ?? 'N'; // Aggiunto per gestire il campo mix
|
||||
$mix = $part['mix'] ?? 'N';
|
||||
|
||||
if ($partDescription) {
|
||||
try {
|
||||
$stmt = $pdo->prepare("INSERT INTO identification_parts (iddatadb, part_number, part_description, mix, created_at, updated_at) VALUES (:iddatadb, :part_number, :part_description, :mix, NOW(), NOW())");
|
||||
$stmt->execute([
|
||||
':iddatadb' => $iddatadb,
|
||||
':part_number' => $partNumber,
|
||||
':part_description' => $partDescription,
|
||||
':mix' => $mix
|
||||
]);
|
||||
echo json_encode(['success' => true, 'message' => 'Parte salvata con successo']);
|
||||
if ($partId) {
|
||||
// UPDATE თუ უკვე არსებობს part
|
||||
$stmt = $pdo->prepare("UPDATE identification_parts
|
||||
SET part_number = :part_number,
|
||||
part_description = :part_description,
|
||||
mix = :mix,
|
||||
updated_at = NOW()
|
||||
WHERE id = :id");
|
||||
$stmt->execute([
|
||||
':id' => $partId,
|
||||
':part_number' => $partNumber,
|
||||
':part_description' => $partDescription,
|
||||
':mix' => $mix
|
||||
]);
|
||||
echo json_encode(['success' => true, 'part_id' => $partId, 'part_number'=>$partNumber, 'message' => 'Parte aggiornata con successo']);
|
||||
} else {
|
||||
// INSERT თუ ახალია
|
||||
$stmt = $pdo->prepare("INSERT INTO identification_parts
|
||||
(iddatadb, part_number, part_description, mix, created_at, updated_at)
|
||||
VALUES (:iddatadb, :part_number, :part_description, :mix, NOW(), NOW())");
|
||||
$stmt->execute([
|
||||
':iddatadb' => $iddatadb,
|
||||
':part_number' => $partNumber,
|
||||
':part_description' => $partDescription,
|
||||
':mix' => $mix
|
||||
]);
|
||||
$newId = $pdo->lastInsertId();
|
||||
echo json_encode(['success' => true, 'part_id' => $newId, 'part_number'=>$partNumber, 'message' => 'Parte salvata con successo']);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio: ' . $e->getMessage()]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$idquotations = $data['idquotations'] ?? null;
|
||||
$parts = $data['parts'] ?? [];
|
||||
|
||||
if (!$idquotations || empty($parts)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Dati mancanti']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$part = $parts[0];
|
||||
$partId = $part['id'] ?? null;
|
||||
$partNumber = $part['part_number'] ?? null;
|
||||
$partDescription = $part['part_description'] ?? '';
|
||||
$mix = $part['mix'] ?? 'N';
|
||||
|
||||
if ($partDescription) {
|
||||
try {
|
||||
if ($partId) {
|
||||
// UPDATE se esiste già la parte
|
||||
$stmt = $pdo->prepare("UPDATE identification_parts
|
||||
SET part_number = :part_number,
|
||||
part_description = :part_description,
|
||||
mix = :mix,
|
||||
updated_at = NOW()
|
||||
WHERE id = :id");
|
||||
$stmt->execute([
|
||||
':id' => $partId,
|
||||
':part_number' => $partNumber,
|
||||
':part_description' => $partDescription,
|
||||
':mix' => $mix
|
||||
]);
|
||||
echo json_encode(['success' => true, 'part_id' => $partId, 'part_number' => $partNumber, 'message' => 'Parte aggiornata con successo']);
|
||||
} else {
|
||||
// INSERT se è nuova
|
||||
$stmt = $pdo->prepare("INSERT INTO identification_parts
|
||||
(idquotations, part_number, part_description, mix, created_at, updated_at)
|
||||
VALUES (:idquotations, :part_number, :part_description, :mix, NOW(), NOW())");
|
||||
$stmt->execute([
|
||||
':idquotations' => $idquotations,
|
||||
':part_number' => $partNumber,
|
||||
':part_description' => $partDescription,
|
||||
':mix' => $mix
|
||||
]);
|
||||
$newId = $pdo->lastInsertId();
|
||||
echo json_encode(['success' => true, 'part_id' => $newId, 'part_number' => $partNumber, 'message' => 'Parte salvata con successo']);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nel salvataggio: ' . $e->getMessage()]);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Descrizione mancante']);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
include('include/headscript.php'); // Assumi che questo includa la connessione DB
|
||||
|
||||
// Recupera il payload JSON
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$template_id = intval($data['template_id']);
|
||||
$mapping_id = intval($data['mapping_id']);
|
||||
$value = intval($data['value']);
|
||||
|
||||
if ($template_id <= 0 || $mapping_id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid IDs']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
|
||||
if ($value === 1) {
|
||||
// Setta tutti main_field a 0 per questo template
|
||||
$stmt = $pdo->prepare("UPDATE template_mapping SET main_field = 0 WHERE template_id = ?");
|
||||
$stmt->execute([$template_id]);
|
||||
}
|
||||
|
||||
// Setta il valore per questo mapping
|
||||
$stmt = $pdo->prepare("UPDATE template_mapping SET main_field = ? WHERE id = ? AND template_id = ?");
|
||||
$stmt->execute([$value, $mapping_id, $template_id]);
|
||||
|
||||
$pdo->commit();
|
||||
echo json_encode(['success' => true]);
|
||||
} catch (Exception $e) {
|
||||
$pdo->rollBack();
|
||||
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
require_once 'include/headscript.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
$template_id = $data['template_id'] ?? null;
|
||||
$mapping_id = $data['mapping_id'] ?? null;
|
||||
$value = $data['value'] ?? null;
|
||||
|
||||
if (!$template_id || !$mapping_id || !isset($value)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid input']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
$stmt = $pdo->prepare("UPDATE template_mapping SET is_visible_import = ? WHERE id = ? AND template_id = ?");
|
||||
$result = $stmt->execute([$value, $mapping_id, $template_id]);
|
||||
|
||||
if ($result) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to update is_visible_import']);
|
||||
}
|
||||
@@ -4,13 +4,23 @@ include('include/headscript.php');
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES['photo']) || !isset($_POST['iddatadb'])) {
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_FILES['photo']) || (!isset($_POST['iddatadb']) && !isset($_POST['idquotations']))) {
|
||||
echo json_encode(['success' => false, 'message' => 'Richiesta non valida']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$iddatadb = intval($_POST['iddatadb']);
|
||||
$photo = $_FILES['photo'];
|
||||
$iddatadb = isset($_POST['iddatadb']) ? intval($_POST['iddatadb']) : null;
|
||||
$idquotations = isset($_POST['idquotations']) ? intval($_POST['idquotations']) : null;
|
||||
|
||||
if ($iddatadb && $idquotations) {
|
||||
echo json_encode(['success' => false, 'message' => 'Non è possibile specificare sia iddatadb che idquotations']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$iddatadb && !$idquotations) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID TRF o ID quotations mancante']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verifica che l'utente loggato esista in auth_users
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
@@ -25,6 +35,28 @@ if (!$userExists) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verifica l'esistenza dell'ID nella tabella corrispondente
|
||||
try {
|
||||
if ($iddatadb) {
|
||||
$stmt = $pdo->prepare("SELECT iddatadb FROM datadb WHERE iddatadb = ?");
|
||||
$stmt->execute([$iddatadb]);
|
||||
if (!$stmt->fetch()) {
|
||||
echo json_encode(['success' => false, 'message' => 'iddatadb non valido']);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$stmt = $pdo->prepare("SELECT id FROM quotations WHERE id = ?");
|
||||
$stmt->execute([$idquotations]);
|
||||
if (!$stmt->fetch()) {
|
||||
echo json_encode(['success' => false, 'message' => 'idquotations non valido']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nella validazione: ' . $e->getMessage()]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Usa un percorso assoluto per la cartella photostrf
|
||||
$uploadDir = realpath(__DIR__ . '/../photostrf') . '/';
|
||||
if (!is_dir($uploadDir)) {
|
||||
@@ -41,6 +73,7 @@ if (!is_writable($uploadDir)) {
|
||||
}
|
||||
|
||||
// Verifica che il file sia un'immagine (inclusi HEIC/HEIF)
|
||||
$photo = $_FILES['photo'];
|
||||
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/heic', 'image/heif'];
|
||||
if (!in_array($photo['type'], $allowedTypes)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Il file deve essere un\'immagine (JPEG, PNG, GIF, HEIC)']);
|
||||
@@ -53,10 +86,11 @@ if (!file_exists($photo['tmp_name']) || !is_uploaded_file($photo['tmp_name'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Rinomina il file: idriga-timestamp-nomeoriginale.estensione
|
||||
// Rinomina il file: id-timestamp-nomeoriginale.estensione
|
||||
$timestamp = date('YmdHis');
|
||||
$originalName = pathinfo($photo['name'], PATHINFO_FILENAME);
|
||||
$extension = strtolower(pathinfo($photo['name'], PATHINFO_EXTENSION));
|
||||
$id = $iddatadb ?: $idquotations;
|
||||
|
||||
// Se il file è HEIC/HEIF, convertilo in JPEG
|
||||
if (in_array($photo['type'], ['image/heic', 'image/heif'])) {
|
||||
@@ -74,11 +108,11 @@ if (in_array($photo['type'], ['image/heic', 'image/heif'])) {
|
||||
}
|
||||
|
||||
// Crea un nuovo nome per il file JPEG
|
||||
$newFileName = "{$iddatadb}-{$timestamp}-{$originalName}.jpg";
|
||||
$newFileName = "{$id}-{$timestamp}-{$originalName}.jpg";
|
||||
$destination = $uploadDir . $newFileName;
|
||||
|
||||
// Salva l'immagine come JPEG
|
||||
if (!imagejpeg($image, $destination, 90)) { // 90 è la qualità JPEG
|
||||
if (!imagejpeg($image, $destination, 90)) {
|
||||
imagedestroy($image);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore durante la conversione del file HEIC in JPEG']);
|
||||
exit;
|
||||
@@ -88,7 +122,7 @@ if (in_array($photo['type'], ['image/heic', 'image/heif'])) {
|
||||
imagedestroy($image);
|
||||
} else {
|
||||
// Per i formati non HEIC, usa il nome e l'estensione originali
|
||||
$newFileName = "{$iddatadb}-{$timestamp}-{$originalName}.{$extension}";
|
||||
$newFileName = "{$id}-{$timestamp}-{$originalName}.{$extension}";
|
||||
$destination = $uploadDir . $newFileName;
|
||||
|
||||
// Salva il file
|
||||
@@ -105,7 +139,12 @@ error_log("Destination: $destination");
|
||||
error_log("Temp file: " . $photo['tmp_name']);
|
||||
|
||||
// Salva il riferimento nel database
|
||||
$stmt = $pdo->prepare("INSERT INTO datadb_photos (iddatadb, file_path, file_name, uploaded_by) VALUES (?, ?, ?, ?)");
|
||||
$stmt->execute([$iddatadb, $newFileName, $newFileName, $iduserlogin]);
|
||||
try {
|
||||
$stmt = $pdo->prepare("INSERT INTO datadb_photos (iddatadb, idquotations, file_path, file_name, uploaded_by) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$iddatadb, $idquotations, $newFileName, $newFileName, $iduserlogin]);
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore durante il salvataggio nel database: ' . $e->getMessage()]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Foto caricata con successo']);
|
||||
|
||||
@@ -5,24 +5,41 @@ include('include/headscript.php');
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
|
||||
// Verifica che l'iddatadb sia stato passato
|
||||
if (!isset($_GET['iddatadb']) || empty($_GET['iddatadb'])) {
|
||||
die('ID riga non fornito');
|
||||
// Verifica che almeno uno degli ID sia passato
|
||||
$iddatadb = isset($_GET['iddatadb']) && !empty($_GET['iddatadb']) ? intval($_GET['iddatadb']) : null;
|
||||
$idquotations = isset($_GET['idquotations']) && !empty($_GET['idquotations']) ? intval($_GET['idquotations']) : null;
|
||||
|
||||
if (!$iddatadb && !$idquotations) {
|
||||
die('ID riga o ID quotations non fornito');
|
||||
}
|
||||
|
||||
$iddatadb = intval($_GET['iddatadb']);
|
||||
if ($iddatadb && $idquotations) {
|
||||
die('Non è possibile specificare sia iddatadb che idquotations');
|
||||
}
|
||||
|
||||
// Recupera i dettagli della riga (idriga e sample_code)
|
||||
$stmt = $pdo->prepare("SELECT iddatadb, sample_code FROM datadb WHERE iddatadb = ?");
|
||||
$stmt->execute([$iddatadb]);
|
||||
// Verifica che l'utente loggato esista
|
||||
$stmt = $pdo->prepare("SELECT id FROM auth_users WHERE id = ?");
|
||||
$stmt->execute([$iduserlogin]);
|
||||
if (!$stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
die('Utente non valido');
|
||||
}
|
||||
|
||||
// Determina quale ID usare e verifica l'esistenza
|
||||
$paramName = $iddatadb ? 'iddatadb' : 'idquotations';
|
||||
$paramValue = $iddatadb ?: $idquotations;
|
||||
$table = $iddatadb ? 'datadb' : 'quotations';
|
||||
$field = $iddatadb ? 'sample_code' : 'quotation_code';
|
||||
|
||||
$stmt = $pdo->prepare("SELECT {$paramName}, {$field} FROM {$table} WHERE {$paramName} = ?");
|
||||
$stmt->execute([$paramValue]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$row) {
|
||||
die('Riga non trovata');
|
||||
}
|
||||
|
||||
$idriga = $row['iddatadb'];
|
||||
$sampleCode = $row['sample_code'] ?? 'Non disponibile';
|
||||
$id = $row[$paramName];
|
||||
$code = $row[$field] ?? 'Non disponibile';
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
@@ -32,17 +49,23 @@ $sampleCode = $row['sample_code'] ?? 'Non disponibile';
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Carica Foto da Mobile</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
background: #f4f4f4;
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
border: 2px dashed #ccc;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
margin: 20px auto;
|
||||
max-width: 500px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.upload-area.highlight {
|
||||
@@ -56,57 +79,121 @@ $sampleCode = $row['sample_code'] ?? 'Non disponibile';
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding-bottom: 10px;
|
||||
max-width: 500px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.photo-item img {
|
||||
max-width: 100px;
|
||||
max-height: 100px;
|
||||
margin-right: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.loader {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.loader i {
|
||||
font-size: 40px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: red;
|
||||
margin: 10px 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
button.delete-photo-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #dc3545;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Carica Foto per ID Riga: <?= htmlspecialchars($idriga) ?></h2>
|
||||
<p><strong>Sample Code:</strong> <?= htmlspecialchars($sampleCode) ?></p>
|
||||
|
||||
<h2>Carica Foto per ID: <?= htmlspecialchars($id) ?></h2>
|
||||
<p><strong>Codice:</strong> <?= htmlspecialchars($code) ?></p>
|
||||
<div class="loader" id="loader">
|
||||
<div>
|
||||
<i class="fas fa-spinner fa-spin"></i>
|
||||
<p>Caricamento in corso...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="error-message" id="errorMessage"></div>
|
||||
<div class="upload-area" id="uploadArea">
|
||||
<p>Scatta una foto o seleziona un'immagine</p>
|
||||
<input type="file" id="photoInput" accept="image/*" capture="camera">
|
||||
</div>
|
||||
|
||||
<div id="photosList">
|
||||
<!-- Le foto verranno caricate dinamicamente -->
|
||||
<p>Scatta una foto o seleziona immagini</p>
|
||||
<input type="file" id="photoInput" accept="image/*" capture="camera" multiple style="display: none;">
|
||||
</div>
|
||||
<div id="photosList"></div>
|
||||
|
||||
<script>
|
||||
const uploadArea = document.getElementById('uploadArea');
|
||||
const photoInput = document.getElementById('photoInput');
|
||||
const photosList = document.getElementById('photosList');
|
||||
const loader = document.getElementById('loader');
|
||||
const errorMessage = document.getElementById('errorMessage');
|
||||
const iddatadb = '<?= $iddatadb ?>';
|
||||
const idquotations = '<?= $idquotations ?>';
|
||||
const endpoint = idquotations ? 'load_photo_quotation.php' : 'load_photo.php';
|
||||
const dataParam = idquotations ? {
|
||||
idquotations: idquotations
|
||||
} : {
|
||||
iddatadb: iddatadb
|
||||
};
|
||||
|
||||
// Carica le foto esistenti all'avvio
|
||||
loadPhotos();
|
||||
|
||||
// Gestione del click sull'area di upload
|
||||
uploadArea.addEventListener('click', () => {
|
||||
photoInput.click();
|
||||
// Gestione drag-and-drop
|
||||
uploadArea.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
uploadArea.classList.add('highlight');
|
||||
});
|
||||
uploadArea.addEventListener('dragleave', () => {
|
||||
uploadArea.classList.remove('highlight');
|
||||
});
|
||||
uploadArea.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
uploadArea.classList.remove('highlight');
|
||||
handleFiles(e.dataTransfer.files);
|
||||
});
|
||||
|
||||
// Gestione del caricamento delle foto
|
||||
photoInput.addEventListener('change', () => {
|
||||
handleFiles(photoInput.files);
|
||||
});
|
||||
// Gestione click sull'area di upload
|
||||
uploadArea.addEventListener('click', () => photoInput.click());
|
||||
|
||||
// Gestione caricamento foto
|
||||
photoInput.addEventListener('change', () => handleFiles(photoInput.files));
|
||||
|
||||
async function handleFiles(files) {
|
||||
loader.style.display = 'flex';
|
||||
errorMessage.style.display = 'none';
|
||||
for (const file of files) {
|
||||
if (!file.type.startsWith('image/')) {
|
||||
alert('Per favore, carica solo immagini!');
|
||||
showError('Per favore, carica solo immagini!');
|
||||
continue;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('photo', file);
|
||||
formData.append('iddatadb', '<?= $iddatadb ?>');
|
||||
if (iddatadb) formData.append('iddatadb', iddatadb);
|
||||
if (idquotations) formData.append('idquotations', idquotations);
|
||||
|
||||
try {
|
||||
const response = await fetch('upload_photo.php', {
|
||||
@@ -114,31 +201,85 @@ $sampleCode = $row['sample_code'] ?? 'Non disponibile';
|
||||
body: formData
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
loadPhotos(); // Ricarica le foto
|
||||
} else {
|
||||
alert('Errore durante il caricamento: ' + result.message);
|
||||
if (!result.success) {
|
||||
showError('Errore durante il caricamento: ' + result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Errore durante il caricamento: ' + error.message);
|
||||
showError('Errore di rete: ' + error.message);
|
||||
}
|
||||
}
|
||||
loadPhotos();
|
||||
loader.style.display = 'none';
|
||||
}
|
||||
|
||||
// Funzione per caricare le foto esistenti
|
||||
async function loadPhotos() {
|
||||
loader.style.display = 'flex';
|
||||
errorMessage.style.display = 'none';
|
||||
try {
|
||||
const response = await fetch(`photos_popup.php?iddatadb=<?= $iddatadb ?>`);
|
||||
const html = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
const photosListContent = doc.querySelector('#photosList').innerHTML;
|
||||
photosList.innerHTML = photosListContent;
|
||||
const response = await fetch(`${endpoint}?${new URLSearchParams(dataParam)}`);
|
||||
const result = await response.json();
|
||||
photosList.innerHTML = '';
|
||||
if (result.success && result.photos && result.photos.length > 0) {
|
||||
for (const photo of result.photos) {
|
||||
const photoName = photo.split('/').pop();
|
||||
const photoItem = document.createElement('div');
|
||||
photoItem.className = 'photo-item';
|
||||
photoItem.innerHTML = `
|
||||
<img src="${photo}" alt="${photoName}">
|
||||
<div style="flex: 1; text-align: left;">
|
||||
<strong>Nome:</strong> ${photoName}<br>
|
||||
<strong>Caricata il:</strong> Non disponibile
|
||||
</div>
|
||||
<button class="delete-photo-btn" data-photo-path="${photo}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>`;
|
||||
photosList.appendChild(photoItem);
|
||||
}
|
||||
} else {
|
||||
photosList.innerHTML = '<p>Nessuna foto presente.</p>';
|
||||
}
|
||||
} catch (error) {
|
||||
photosList.innerHTML = `<p>Errore durante il caricamento delle foto: ${error.message}</p>`;
|
||||
showError('Errore durante il caricamento delle foto: ' + error.message);
|
||||
}
|
||||
loader.style.display = 'none';
|
||||
}
|
||||
|
||||
function showError(message) {
|
||||
errorMessage.textContent = message;
|
||||
errorMessage.style.display = 'block';
|
||||
setTimeout(() => errorMessage.style.display = 'none', 5000);
|
||||
}
|
||||
|
||||
// Gestione eliminazione foto
|
||||
photosList.addEventListener('click', async (e) => {
|
||||
if (e.target.closest('.delete-photo-btn')) {
|
||||
const button = e.target.closest('.delete-photo-btn');
|
||||
const photoPath = button.dataset.photoPath;
|
||||
if (confirm('Sei sicuro di voler eliminare questa foto?')) {
|
||||
loader.style.display = 'flex';
|
||||
try {
|
||||
const response = await fetch('delete_photo.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
file_path: photoPath
|
||||
})
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
loadPhotos();
|
||||
} else {
|
||||
showError('Errore durante l\'eliminazione: ' + result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
showError('Errore durante l\'eliminazione: ' + error.message);
|
||||
}
|
||||
loader.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
|
||||
<script src="{{ url(mix('assets/js/vendor.js')) }}"></script>
|
||||
<script src="{{ url('assets/js/as/app.js') }}"></script>
|
||||
<script src="{{ url('assets/js/alpinejs.js') }}"></script>
|
||||
@yield('scripts')
|
||||
|
||||
@hook('app:scripts')
|
||||
|
||||
@@ -188,3 +188,11 @@ Route::group(['prefix' => 'install'], function () {
|
||||
Route::get('complete', 'InstallController@complete')->name('install.complete');
|
||||
Route::get('error', 'InstallController@error')->name('install.error');
|
||||
});
|
||||
|
||||
use App\Vanguard\Http\Controllers\Userarea\UploadPhotosMobileController;
|
||||
|
||||
Route::get('/userarea/upload-photos-mobile', [UploadPhotosMobileController::class, 'index'])
|
||||
->name('userarea.upload-photos-mobile.index');
|
||||
|
||||
Route::post('/userarea/upload-photos-mobile', [UploadPhotosMobileController::class, 'upload'])
|
||||
->name('userarea.upload-photos-mobile.upload');
|
||||
|
||||