Compare commits

..

43 Commits

Author SHA1 Message Date
solocla 3e4a627ca7 fixed quotations 2025-09-20 22:00:16 +02:00
solocla 25d4519684 fixed quotations 2025-09-13 21:28:11 +02:00
solocla 34d4dc8660 quotations page 2025-09-13 12:31:31 +02:00
solocla 1510ef03f1 added level to collahge 2025-09-12 18:09:01 +02:00
solocla ce8c95921f remove .env from repository 2025-09-12 10:17:22 +02:00
solocla 095a6ae879 remove debug/log/json files from tracking 2025-09-12 10:03:50 +02:00
solocla 296143016a template mapping addes is visible as checkbox and is required as badge 2025-09-12 10:01:19 +02:00
solocla 3aa2504f3c fixed cut 2025-09-08 14:01:17 +02:00
solocla c1a396f246 added canvas functionality 2025-09-08 11:40:43 +02:00
solocla a45ba1c8b3 added cut 2025-09-08 10:26:15 +02:00
solocla 7a944a73f7 get_commessaweb 2025-09-08 08:42:05 +02:00
solocla 71595cc8de added speech functions 2025-09-06 18:48:38 +02:00
solocla f89dbd0c23 added save all 2025-09-06 12:29:29 +02:00
solocla 9ba859e15b Merge remote-tracking branch 'origin/bugfix/warning-text-and-logic-change' 2025-09-05 21:44:38 +02:00
solocla 672e448e9a fixed renumerate parts 2025-09-04 15:16:19 +02:00
solocla 0749032fbc added collage, fixed parts marker color, added ri number 2025-09-04 15:01:03 +02:00
kapsona777 d692614f70 warning fix 2025-09-01 19:56:08 +04:00
solocla 1303cff9fd added export to lims button 2025-08-29 15:36:55 +02:00
solocla 6b2bd0964b fixed dropdown selection 2025-08-28 10:25:12 +02:00
solocla 0d2cf13524 update historical trf 2025-08-28 09:36:16 +02:00
solocla f6ef9c39d2 added multi webcam functionality 2025-08-27 20:21:38 +02:00
solocla 7e4ed56f28 Merge feature/historical_imported_trf into main (kept main version for logs and import_edit2.php) 2025-08-27 12:16:41 +02:00
solocla 4d0644f46c metada classes 2025-08-27 08:09:42 +02:00
solocla 712042b8d8 update layout table import edit 2 and fix address photos in env 2025-08-26 15:22:27 +02:00
solocla efee12740d fixed mappiung template 2025-08-26 11:54:03 +02:00
solocla 14395810d0 fixed template mapping 2025-08-26 11:49:08 +02:00
solocla 03002a8938 gitignore edit 2025-08-26 10:51:52 +02:00
solocla 21fcee8ff5 Merge feature/added-some-features into main (ignore debug log conflicts) 2025-08-26 10:46:27 +02:00
kapsona777 1361340928 fixed annotation description placement 2025-08-25 19:59:22 +04:00
kapsona777 1bda30e957 fixed saving and modifying parts 2025-08-25 19:39:53 +04:00
kapsona777 a87423d879 fixed saving and modifying parts 2025-08-25 18:08:33 +04:00
kapsona777 24cda34681 added feature to update inserted information, fixed bug that was inserting new rows after each refresh of the page and optimized get_customfield_values , it was sending many requests and optimized to 1. 2025-08-21 20:39:31 +04:00
solocla 2c514a8ab6 added button on top page for historical 2025-08-21 11:38:23 +02:00
solocla b1ea728c15 added main field functionality 2025-08-21 09:27:21 +02:00
solocla caf5568779 git ignore edit 2025-08-20 17:37:22 +02:00
solocla 0728fd8f01 update main field and git ignore 2025-08-20 17:30:13 +02:00
kapsona777 9d5c20113f fixed arrows 2025-08-20 17:45:21 +04:00
kapsona777 47762a8557 added feature about unsaved changes 2025-08-20 16:49:10 +04:00
solocla 434bb0d993 added fill dropdown and save id 2025-08-19 16:33:11 +02:00
kapsona777 939a4fe03e added feature to save image into database and after upload it can be chose by dropdown 2025-08-18 19:45:38 +04:00
kapsona777 493de65892 fixed saving annotated photos 2025-08-18 19:02:57 +04:00
kapsona777 23ae8e1b1d fixed displaying photo 2025-08-18 14:31:58 +04:00
kapsona777 7ad20993d9 added controller for QR photo upload and inserted route for it. added functional for multiple photo upload. 2025-08-11 16:30:24 +04:00
99 changed files with 54519 additions and 22466 deletions
-45
View File
@@ -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
+16
View File
@@ -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']);
}
}
+1
View File
@@ -32,3 +32,4 @@ $langdatatables = [
"paginate_next" => "Next",
"paginate_previous" => "Previous"
];
$quotationstitle = "Quotations";
Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

View File
@@ -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;
}
}
-36
View File
@@ -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
File diff suppressed because one or more lines are too long
-36
View File
@@ -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
-35
View File
@@ -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
-38
View File
@@ -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
-18
View File
@@ -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"
-35
View File
@@ -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
File diff suppressed because one or more lines are too long
-108
View File
@@ -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}
+28
View File
@@ -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
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+7
View File
@@ -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
+39
View File
@@ -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()]);
}
+21 -11
View File
@@ -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([
+37
View File
@@ -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>';
}
+295 -148
View File
@@ -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>
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+157
View File
@@ -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;
+4 -4
View File
@@ -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>
+15 -1
View File
@@ -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>
-80
View File
@@ -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
+23
View File
@@ -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()]);
}
+10 -5
View File
@@ -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']);
}
+33
View File
@@ -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()]);
}
+286 -29
View File
@@ -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();
}
})
File diff suppressed because one or more lines are too long
+58 -5
View File
@@ -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>
+754 -364
View File
File diff suppressed because it is too large Load Diff
+801 -112
View File
File diff suppressed because it is too large Load Diff
+230 -29
View File
@@ -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">&times;</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%;">&times;</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>
+429
View File
@@ -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">&times;</span>
<div class="popup-content"></div>
</div>
</div>
</body>
</html>
+63
View File
@@ -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()
]);
}
+37 -9
View File
@@ -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()]);
}
+51 -15
View File
@@ -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());
}
+31 -10
View File
@@ -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()]);
}
+60
View File
@@ -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']);
}
+41
View File
@@ -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()]);
}
+26
View File
@@ -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']);
}
+48 -9
View File
@@ -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']);
+183 -42
View File
@@ -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>
+1
View File
@@ -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')
+8
View File
@@ -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');
View File