Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9969cc9edc | |||
| 8d6fe92481 | |||
| dbc66723a6 | |||
| 218fc14462 | |||
| 29e4b41874 | |||
| eef9ae8d36 | |||
| 68c867a3f4 | |||
| a9827e4e81 | |||
| b51936f784 | |||
| 15b6f38e8b | |||
| 12c6cc5f95 | |||
| a0b12463c0 | |||
| 07ddcafd3f | |||
| 7843d4b1fc | |||
| 4eae855e23 | |||
| c709f64a17 | |||
| d5f0690f59 | |||
| 6bbd3fcae9 | |||
| 9e19e9e1d4 | |||
| 7caee9c994 | |||
| f8320315f7 | |||
| 7397d86bc2 | |||
| 2deb1f101a | |||
| ed4467337f | |||
| 864714d198 | |||
| 33aacfb469 | |||
| e0e262fd32 | |||
| 5d6302fa9c | |||
| 3da8ff81c9 | |||
| a36dd02771 | |||
| 0a6fb98476 | |||
| 57ddd4bb5a | |||
| df5e6d5656 | |||
| 78495880ca | |||
| 960832efb1 | |||
| 447a0d1dea | |||
| 5b47416841 | |||
| 3e4a627ca7 | |||
| 420b0a0405 | |||
| b39d601ec9 | |||
| 89d13699b4 | |||
| 9826331545 | |||
| 9d8718d110 | |||
| 16e00f8573 | |||
| baf3f6da32 | |||
| 62bf4ebd92 | |||
| 6e465e3010 | |||
| 8b08969c69 | |||
| 25d4519684 | |||
| 34d4dc8660 | |||
| 1510ef03f1 | |||
| ce8c95921f | |||
| 095a6ae879 | |||
| 296143016a | |||
| 412dce8941 | |||
| 586226ceaf | |||
| ac09d8d0eb | |||
| 33e3ae059d | |||
| 3aa2504f3c | |||
| c1a396f246 | |||
| a45ba1c8b3 | |||
| 7a944a73f7 | |||
| 71595cc8de | |||
| f89dbd0c23 | |||
| 9ba859e15b | |||
| 672e448e9a | |||
| 0749032fbc | |||
| d692614f70 | |||
| 1303cff9fd | |||
| 6b2bd0964b | |||
| 0d2cf13524 | |||
| f6ef9c39d2 | |||
| 7e4ed56f28 | |||
| 4d0644f46c | |||
| 712042b8d8 | |||
| efee12740d | |||
| 14395810d0 | |||
| 03002a8938 | |||
| 21fcee8ff5 | |||
| 1361340928 | |||
| 1bda30e957 | |||
| a87423d879 | |||
| 24cda34681 | |||
| 2c514a8ab6 | |||
| b1ea728c15 | |||
| caf5568779 | |||
| 0728fd8f01 | |||
| 9d5c20113f | |||
| 47762a8557 | |||
| 434bb0d993 | |||
| 939a4fe03e | |||
| 493de65892 | |||
| 23ae8e1b1d | |||
| 7ad20993d9 |
@@ -1,45 +0,0 @@
|
||||
APP_ENV=production
|
||||
APP_DEBUG=true
|
||||
APP_KEY=base64:C+sutHm6xP5sE4QXhoZFhYjArlVN11s2mDU1F8beUkM=
|
||||
APP_URL=http://vanguard.test
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST="localhost"
|
||||
DB_DATABASE="trfcertest"
|
||||
DB_USERNAME="solocla"
|
||||
DB_PASSWORD="!Massarosa2"
|
||||
DB_PREFIX="auth_"
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=mail
|
||||
MAIL_FROM_NAME=Vanguard
|
||||
MAIL_FROM_ADDRESS=vanguard@test.dev
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# Credenziali API VisualLims
|
||||
API_BASE_URL=https://93.43.5.102/limsapi
|
||||
API_USERNAME=WebApiUser
|
||||
API_PASSWORD=webapiuser01
|
||||
@@ -1,16 +1,16 @@
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_KEY=base64:C+sutHm6xP5sE4QXhoZFhYjArlVN11s2mDU1F8beUkM=
|
||||
APP_URL=http://vanguard.test
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=vanguard
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
DB_PREFIX=vg_
|
||||
DB_HOST="localhost"
|
||||
DB_DATABASE="trfcertest"
|
||||
DB_USERNAME="solocla"
|
||||
DB_PASSWORD="xxxxxxx"
|
||||
DB_PREFIX="auth_"
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
@@ -39,3 +39,21 @@ PUSHER_APP_CLUSTER=mt1
|
||||
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# Credenziali API VisualLims
|
||||
SIMULATE_EXPORT_LIMS=true
|
||||
API_BASE_URL=https://93.43.5.102/limsapi
|
||||
API_USERNAME=xxxx
|
||||
API_PASSWORD=XXXX
|
||||
|
||||
BASE_URL=http://localhost:8000/userarea/
|
||||
|
||||
# Credenziali ENTRAID
|
||||
|
||||
AZURE_CLIENT_ID=your-client-id
|
||||
AZURE_CLIENT_SECRET=your-client-secret
|
||||
AZURE_REDIRECT_URI=https://your-app.com/auth/azure/callback
|
||||
AZURE_TENANT_ID=
|
||||
|
||||
MICROSOFT_CLIENT_ID=your_client_id_here
|
||||
MICROSOFT_CLIENT_SECRET=your_client_secret_here
|
||||
MICROSOFT_REDIRECT_URI="${APP_URL}/auth/microsoft/callback"
|
||||
@@ -36,3 +36,31 @@ 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
|
||||
/public/userarea/logaspi/
|
||||
|
||||
public/userarea/logsapi/campione_762_1.json
|
||||
public/userarea/logsapi/campione_763_1.json
|
||||
public/userarea/logsapi/campione_762_2.json
|
||||
public/userarea/logsapi/campione_763_2.json
|
||||
public/userarea/logsapi/commessaweb_create_762.json
|
||||
public/userarea/logsapi/commessaweb_create_763.json
|
||||
public/userarea/logsapi/commessaweb_customfields_762.json
|
||||
public/userarea/logsapi/commessaweb_customfields_763.json
|
||||
public/userarea/logsapi/commessaweb_invia_762.json
|
||||
public/userarea/logsapi/commessaweb_invia_763.json
|
||||
public/userarea/logsapi/last_auth_url.txt
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
}
|
||||
@@ -28,10 +28,21 @@ class AppServiceProvider extends ServiceProvider
|
||||
\Illuminate\Database\Schema\Builder::defaultStringLength(191);
|
||||
|
||||
Factory::guessFactoryNamesUsing(function (string $modelName) {
|
||||
return 'Database\Factories\\'.class_basename($modelName).'Factory';
|
||||
return 'Database\Factories\\' . class_basename($modelName) . 'Factory';
|
||||
});
|
||||
|
||||
\Illuminate\Pagination\Paginator::useBootstrap();
|
||||
|
||||
// Register Microsoft Socialite driver
|
||||
$this->app->make('Laravel\Socialite\Contracts\Factory')->extend('microsoft', function ($app) {
|
||||
$config = $app['config']['services.microsoft'];
|
||||
return new \SocialiteProviders\Microsoft\Provider(
|
||||
$app['request'],
|
||||
$config['client_id'],
|
||||
$config['client_secret'],
|
||||
$config['redirect']
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,9 @@ class EventServiceProvider extends ServiceProvider
|
||||
Verified::class => [
|
||||
ActivateUser::class,
|
||||
],
|
||||
\SocialiteProviders\Manager\SocialiteWasMapped::class => [
|
||||
\SocialiteProviders\Microsoft\MicrosoftExtendSocialite::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
realpath(__DIR__.'/../')
|
||||
realpath(__DIR__ . '/../')
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
@@ -38,12 +38,13 @@
|
||||
"laravel/fortify": "^1.21",
|
||||
"laravel/framework": "^11.0",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/socialite": "^5.0",
|
||||
"laravel/socialite": "^5.16",
|
||||
"laravel/tinker": "^2.7",
|
||||
"laravel/ui": "^4.0",
|
||||
"phpmailer/phpmailer": "^6.9",
|
||||
"phpoffice/phpspreadsheet": "^4.1",
|
||||
"proengsoft/laravel-jsvalidation": "^4.0.0",
|
||||
"socialiteproviders/microsoft": "^4.7",
|
||||
"spatie/laravel-query-builder": "^5.0",
|
||||
"vanguardapp/activity-log": "^6.0",
|
||||
"vanguardapp/announcements": "^6.0",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ef3e05e7260284f5b7c7b4b6f93b252b",
|
||||
"content-hash": "9c4f1e3bc3ee2180211c055e70635aef",
|
||||
"packages": [
|
||||
{
|
||||
"name": "akaunting/laravel-setting",
|
||||
@@ -2240,16 +2240,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/socialite",
|
||||
"version": "v5.15.1",
|
||||
"version": "v5.16.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/socialite.git",
|
||||
"reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029"
|
||||
"reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/socialite/zipball/cc02625f0bd1f95dc3688eb041cce0f1e709d029",
|
||||
"reference": "cc02625f0bd1f95dc3688eb041cce0f1e709d029",
|
||||
"url": "https://api.github.com/repos/laravel/socialite/zipball/40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
|
||||
"reference": "40a2dc98c53d9dc6d55eadb0d490d3d72b73f1bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2271,16 +2271,16 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Laravel\\Socialite\\SocialiteServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"Socialite": "Laravel\\Socialite\\Facades\\Socialite"
|
||||
}
|
||||
},
|
||||
"providers": [
|
||||
"Laravel\\Socialite\\SocialiteServiceProvider"
|
||||
]
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-master": "5.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2308,7 +2308,7 @@
|
||||
"issues": "https://github.com/laravel/socialite/issues",
|
||||
"source": "https://github.com/laravel/socialite"
|
||||
},
|
||||
"time": "2024-06-28T20:09:34+00:00"
|
||||
"time": "2024-09-03T09:46:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/tinker",
|
||||
@@ -4980,6 +4980,131 @@
|
||||
],
|
||||
"time": "2024-04-27T21:32:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/manager",
|
||||
"version": "v4.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SocialiteProviders/Manager.git",
|
||||
"reference": "8180ec14bef230ec2351cff993d5d2d7ca470ef4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/8180ec14bef230ec2351cff993d5d2d7ca470ef4",
|
||||
"reference": "8180ec14bef230ec2351cff993d5d2d7ca470ef4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0",
|
||||
"laravel/socialite": "^5.5",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.2",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"SocialiteProviders\\Manager\\ServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SocialiteProviders\\Manager\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Andy Wendt",
|
||||
"email": "andy@awendt.com"
|
||||
},
|
||||
{
|
||||
"name": "Anton Komarev",
|
||||
"email": "a.komarev@cybercog.su"
|
||||
},
|
||||
{
|
||||
"name": "Miguel Piedrafita",
|
||||
"email": "soy@miguelpiedrafita.com"
|
||||
},
|
||||
{
|
||||
"name": "atymic",
|
||||
"email": "atymicq@gmail.com",
|
||||
"homepage": "https://atymic.dev"
|
||||
}
|
||||
],
|
||||
"description": "Easily add new or override built-in providers in Laravel Socialite.",
|
||||
"homepage": "https://socialiteproviders.com",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"manager",
|
||||
"oauth",
|
||||
"providers",
|
||||
"socialite"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/socialiteproviders/manager/issues",
|
||||
"source": "https://github.com/socialiteproviders/manager"
|
||||
},
|
||||
"time": "2025-02-24T19:33:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/microsoft",
|
||||
"version": "4.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SocialiteProviders/Microsoft.git",
|
||||
"reference": "824ef97a4f6e3f363c21702b76676d54e8265573"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SocialiteProviders/Microsoft/zipball/824ef97a4f6e3f363c21702b76676d54e8265573",
|
||||
"reference": "824ef97a4f6e3f363c21702b76676d54e8265573",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"firebase/php-jwt": "^6.8",
|
||||
"php": "^8.0",
|
||||
"socialiteproviders/manager": "^4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SocialiteProviders\\Microsoft\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Faust",
|
||||
"email": "hello@brianfaust.de"
|
||||
}
|
||||
],
|
||||
"description": "Microsoft OAuth2 Provider for Laravel Socialite",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"microsoft",
|
||||
"oauth",
|
||||
"provider",
|
||||
"socialite"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://socialiteproviders.com/microsoft",
|
||||
"issues": "https://github.com/socialiteproviders/providers/issues",
|
||||
"source": "https://github.com/socialiteproviders/providers"
|
||||
},
|
||||
"time": "2025-07-06T00:25:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/laravel-package-tools",
|
||||
"version": "1.16.4",
|
||||
|
||||
@@ -228,6 +228,7 @@ return [
|
||||
Proengsoft\JsValidation\JsValidationServiceProvider::class,
|
||||
Anhskohbo\NoCaptcha\NoCaptchaServiceProvider::class,
|
||||
Laravel\Socialite\SocialiteServiceProvider::class,
|
||||
\SocialiteProviders\Manager\ServiceProvider::class,
|
||||
Webpatser\Countries\CountriesServiceProvider::class,
|
||||
Intervention\Image\ImageServiceProvider::class,
|
||||
Jenssegers\Agent\AgentServiceProvider::class,
|
||||
|
||||
@@ -11,9 +11,9 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
// 'social' => [
|
||||
// 'providers' => ['facebook', 'twitter', 'google'],
|
||||
// ],
|
||||
'social' => [
|
||||
'providers' => ['microsoft'],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -64,9 +64,15 @@ return [
|
||||
'redirect' => env('GOOGLE_CALLBACK_URI'),
|
||||
],
|
||||
|
||||
// 'authy' => [
|
||||
// 'key' => env('AUTHY_KEY'),
|
||||
// ],
|
||||
'microsoft' => [
|
||||
'client_id' => env('MICROSOFT_CLIENT_ID'),
|
||||
'client_secret' => env('MICROSOFT_CLIENT_SECRET'),
|
||||
'redirect' => env('MICROSOFT_REDIRECT_URI'),
|
||||
],
|
||||
|
||||
// 'authy' => [
|
||||
// 'key' => env('AUTHY_KEY'),
|
||||
// ],
|
||||
|
||||
'resend' => [
|
||||
'key' => env('RESEND_KEY'),
|
||||
|
||||
@@ -32,3 +32,4 @@ $langdatatables = [
|
||||
"paginate_next" => "Next",
|
||||
"paginate_previous" => "Previous"
|
||||
];
|
||||
$quotationstitle = "Quotations";
|
||||
|
||||
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 451 B |
|
After Width: | Height: | Size: 510 B |
|
After Width: | Height: | Size: 462 B |
|
After Width: | Height: | Size: 443 B |
|
After Width: | Height: | Size: 460 B |
|
After Width: | Height: | Size: 454 B |
|
After Width: | Height: | Size: 456 B |
|
After Width: | Height: | Size: 460 B |
|
After Width: | Height: | Size: 457 B |
|
After Width: | Height: | Size: 454 B |
|
After Width: | Height: | Size: 455 B |
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
ob_start();
|
||||
session_start();
|
||||
require_once '../../vendor/autoload.php';
|
||||
|
||||
$response = ['error' => '', 'rows' => [], 'columns' => [], 'template_id' => 0, 'filename' => '', 'excel_data' => []];
|
||||
|
||||
try {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
$template_id = isset($input['template_id']) ? intval($input['template_id']) : 0;
|
||||
$filename = $input['routine_data']['filename'] ?? '';
|
||||
$headerrow = $input['routine_data']['headerrow'] ?? 1;
|
||||
$excelData = $input['excel_data'] ?? [];
|
||||
$routineData = $input['routine_data'] ?? [];
|
||||
|
||||
if (!$filename || empty($excelData)) {
|
||||
throw new Exception("Dati della routine mancanti.");
|
||||
}
|
||||
|
||||
$routineFile = __DIR__ . '/routines/' . $filename;
|
||||
if (file_exists($routineFile)) {
|
||||
include_once $routineFile;
|
||||
$routineData['xls_headers'] = $_SESSION['headers'] ?? [];
|
||||
applyRoutine($excelData, $routineData); // Modifica $excelData in place
|
||||
error_log("Routine {$routineData['name']} applicata (file: {$filename}) per template {$template_id}, header row: {$headerrow}");
|
||||
} else {
|
||||
throw new Exception("File della routine non trovato: $routineFile");
|
||||
}
|
||||
|
||||
// Aggiorna la sessione con i dati modificati
|
||||
$_SESSION['excel_data'] = $excelData;
|
||||
|
||||
$response['excel_data'] = $excelData;
|
||||
$response['rows'] = array_column($excelData, 'data');
|
||||
$response['columns'] = $_SESSION['headers'];
|
||||
$response['template_id'] = $template_id;
|
||||
$response['filename'] = $input['filename'] ?? '';
|
||||
} else {
|
||||
$response['error'] = "Richiesta non valida.";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$response['error'] = "Errore durante l'applicazione della routine: " . $e->getMessage();
|
||||
error_log("Exception in apply_routine.php: " . $e->getMessage());
|
||||
}
|
||||
|
||||
ob_end_clean();
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
require_once "class/VisualLimsApiClient.class.php";
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// 🔹 Configura directory log (creala se non esiste)
|
||||
$logDir = __DIR__ . '/logs/api/';
|
||||
if (!is_dir($logDir)) {
|
||||
mkdir($logDir, 0755, true);
|
||||
}
|
||||
|
||||
// 🔹 Base URL API
|
||||
$apiBaseUrl = 'https://93.43.5.102/limsapi/api/odata/';
|
||||
|
||||
// 🔹 Hardcoded values
|
||||
$iddatadb = 846;
|
||||
$commessaId = 533357;
|
||||
|
||||
try {
|
||||
// 🔹 STEP 4: Fetch Field Values with Labels (usa dati reali per iddatadb=845)
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT
|
||||
idd.field_value,
|
||||
m.field_label,
|
||||
m.schema_id,
|
||||
m.field_id
|
||||
FROM
|
||||
import_data_details as idd
|
||||
JOIN template_mapping m ON idd.mapping_id = m.id
|
||||
WHERE idd.id = :iddatadb
|
||||
");
|
||||
$stmt->execute(['iddatadb' => $iddatadb]);
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$fieldValues = [];
|
||||
$valueMap = []; // Mappa per field_id -> valore
|
||||
foreach ($rows as $row) {
|
||||
$fieldValues[] = [
|
||||
"IdCommesseCustomFields" => (int) $row['field_id'],
|
||||
"Valore" => $row['field_value'],
|
||||
"FieldLabel" => $row['field_label']
|
||||
];
|
||||
$valueMap[(int) $row['field_id']] = $row['field_value']; // Mappa per ID definizione
|
||||
}
|
||||
|
||||
// Logga i fieldValues in error_log
|
||||
$logFieldValues = "FieldValues dal DB (iddatadb={$iddatadb}):\n" . json_encode($fieldValues, JSON_PRETTY_PRINT);
|
||||
error_log($logFieldValues);
|
||||
|
||||
// 🔹 Initialize API client
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// 🔹 STEP A: GET iniziale per CommesseCustomFields con espansione CustomField
|
||||
$expand = "CommesseCustomFields(\$expand=CustomField)"; // Espansione come da istruzioni fornitore
|
||||
$commessaWithFields = $api->get("CommessaWeb(" . $commessaId . ")?\$expand=" . $expand);
|
||||
|
||||
// 🔹 STEP B: Prepara payload PATCH (tutti i campi, sovrascrivi se match su CustomField.IdCustomField == field_id)
|
||||
$commessaCustomFields = [];
|
||||
foreach ($commessaWithFields["CommesseCustomFields"] as $customField) {
|
||||
$definitionId = (int) ($customField["CustomField"]["IdCustomField"] ?? 0); // Usa IdCustomField dal CustomField
|
||||
$currentValue = $customField["Valore"] ?? '';
|
||||
$newValue = isset($valueMap[$definitionId]) ? $valueMap[$definitionId] : $currentValue;
|
||||
|
||||
$commessaCustomFields[] = [
|
||||
"IdCommesseCustomFields" => (int) $customField["IdCommesseCustomFields"],
|
||||
"Valore" => $newValue
|
||||
];
|
||||
}
|
||||
|
||||
// 🔹 Unico file di log per tutto
|
||||
$logFile = $logDir . "commessa_{$commessaId}_patch_and_get_" . time() . ".txt";
|
||||
$logContent = "FieldValues dal DB (iddatadb={$iddatadb}):\n" . json_encode($fieldValues, JSON_PRETTY_PRINT) . "\n\n";
|
||||
|
||||
// Log curl-like per GET iniziale
|
||||
$logContent .= "GET iniziale:\n" .
|
||||
"curl --location --request GET '{$apiBaseUrl}CommessaWeb({$commessaId})?\$expand=CommesseCustomFields(\$expand=CustomField)' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••'\n\n" .
|
||||
"RESPONSE:\n" . json_encode($commessaWithFields, JSON_PRETTY_PRINT) . "\n\n---\n";
|
||||
|
||||
if (!empty($commessaCustomFields)) {
|
||||
$updatePayload = ["CommesseCustomFields" => $commessaCustomFields];
|
||||
|
||||
// Log curl-like per PATCH
|
||||
$jsonPayload = json_encode($updatePayload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
$logContent .= "PATCH:\n" .
|
||||
"curl --location --request PATCH '{$apiBaseUrl}CommessaWeb({$commessaId})' \\\n" .
|
||||
"--header 'Content-Type: application/json' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••' \\\n" .
|
||||
"--data '{$jsonPayload}'\n\n";
|
||||
|
||||
$patchResponse = $api->patch("CommessaWeb({$commessaId})", $updatePayload);
|
||||
|
||||
$logContent .= "PATCH RESPONSE:\n" . json_encode($patchResponse, JSON_PRETTY_PRINT) . "\n\n---\n";
|
||||
} else {
|
||||
$logContent .= "PATCH: Nessun campo custom da aggiornare\n\n---\n";
|
||||
}
|
||||
|
||||
// 🔹 STEP C: GET di controllo post-PATCH
|
||||
$commessaAfterPatch = $api->get("CommessaWeb(" . $commessaId . ")?\$expand=" . $expand);
|
||||
|
||||
// Log curl-like per GET di controllo
|
||||
$logContent .= "GET di controllo:\n" .
|
||||
"curl --location --request GET '{$apiBaseUrl}CommessaWeb({$commessaId})?\$expand=CommesseCustomFields(\$expand=CustomField)' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••'\n\n" .
|
||||
"RESPONSE:\n" . json_encode($commessaAfterPatch, JSON_PRETTY_PRINT);
|
||||
|
||||
// Salva log unico
|
||||
file_put_contents($logFile, $logContent);
|
||||
|
||||
// 🔹 Output a schermo
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => "PATCH eseguito su commessa {$commessaId} con dati da iddatadb {$iddatadb}",
|
||||
"commessaAfterPatch" => $commessaAfterPatch,
|
||||
"totalCustomFieldsUpdated" => count($commessaCustomFields),
|
||||
"fieldValues" => $fieldValues,
|
||||
"logFile" => $logFile
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
error_log("Patch Error: " . $e->getMessage() . "\nTrace: " . $e->getTraceAsString());
|
||||
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Patch failed: " . $e->getMessage(),
|
||||
"logFile" => $logFile ?? 'Nessun log generato'
|
||||
]);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class VisualLimsApiClient
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function authenticate()
|
||||
private function authenticate($retryCount = 0, $maxRetries = 3)
|
||||
{
|
||||
$ch = curl_init("{$this->baseUrl}/api/authentication/authenticate");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
@@ -45,16 +45,22 @@ class VisualLimsApiClient
|
||||
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.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
$log = fopen(__DIR__ . '/curl_auth_debug.log', 'a') ?: 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);
|
||||
$log_message = date('Y-m-d H:i:s') . " - Auth attempt {$retryCount}: HTTP {$http_code}, Error: {$curl_error}, Response: " . substr($response, 0, 1000) . "\n";
|
||||
fwrite($log, $log_message);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false || $http_code != 200) {
|
||||
if ($http_code === 400 && strpos($response, 'Cannot persist the object') !== false && $retryCount < $maxRetries) {
|
||||
usleep(500000); // Ritardo di 500ms
|
||||
return $this->authenticate($retryCount + 1, $maxRetries); // Riprova
|
||||
}
|
||||
throw new Exception("Autenticazione fallita: HTTP {$http_code}, Errore cURL: {$curl_error}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
@@ -120,4 +126,75 @@ class VisualLimsApiClient
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function post($endpoint, $payload)
|
||||
{
|
||||
$token = $this->getToken();
|
||||
$url = "{$this->baseUrl}/api/odata/{$endpoint}";
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer {$token}",
|
||||
"Content-Type: application/json",
|
||||
"Accept: application/json"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception("Errore nella richiesta POST: {$curl_error}");
|
||||
}
|
||||
|
||||
if ($http_code < 200 || $http_code >= 300) {
|
||||
throw new Exception("POST fallito: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
return json_decode($response, true);
|
||||
}
|
||||
|
||||
public function patch($endpoint, $payload)
|
||||
{
|
||||
$token = $this->getToken();
|
||||
$url = "{$this->baseUrl}/api/odata/{$endpoint}";
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer {$token}",
|
||||
"Content-Type: application/json",
|
||||
"Accept: application/json"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception("Errore nella richiesta PATCH: {$curl_error}");
|
||||
}
|
||||
|
||||
if ($http_code < 200 || $http_code >= 300) {
|
||||
throw new Exception("PATCH fallito: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
return json_decode($response, true);
|
||||
}
|
||||
|
||||
public function getBaseUrl()
|
||||
{
|
||||
return $this->baseUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
class VisualLimsApiClientXml
|
||||
{
|
||||
private static $instance = null;
|
||||
private $baseUrl;
|
||||
private $username;
|
||||
private $password;
|
||||
private $token = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$dotenv = Dotenv::createImmutable(dirname(__DIR__, 3));
|
||||
$dotenv->load();
|
||||
|
||||
$this->baseUrl = $_ENV['API_BASE_URL'];
|
||||
$this->username = $_ENV['API_USERNAME'];
|
||||
$this->password = $_ENV['API_PASSWORD'];
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new VisualLimsApiClientXml();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function authenticate()
|
||||
{
|
||||
$ch = curl_init("{$this->baseUrl}/api/authentication/authenticate");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
||||
'Username' => $this->username,
|
||||
'Password' => $this->password
|
||||
]));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Accept: application/json'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_auth_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false || $http_code != 200) {
|
||||
throw new Exception("Autenticazione fallita: HTTP {$http_code}, Errore cURL: {$curl_error}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
$token_data = json_decode($response, true);
|
||||
$this->token = null;
|
||||
|
||||
if (is_array($token_data) && isset($token_data['token'])) {
|
||||
$this->token = $token_data['token'];
|
||||
} elseif (is_string($token_data) && !empty($token_data)) {
|
||||
$this->token = trim($token_data, '"');
|
||||
} elseif (is_string($response) && !empty($response)) {
|
||||
$this->token = trim($response, '"');
|
||||
}
|
||||
|
||||
if (empty($this->token)) {
|
||||
throw new Exception("Token non ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
private function getToken()
|
||||
{
|
||||
if ($this->token === null) {
|
||||
$this->authenticate();
|
||||
}
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
public function get($endpoint, $options = [])
|
||||
{
|
||||
$token = $this->getToken();
|
||||
$query = http_build_query($options);
|
||||
$url = "{$this->baseUrl}/api/odata/{$endpoint}" . ($query ? '?' . $query : '');
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer {$token}",
|
||||
"Accept: application/xml"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_request_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception("Errore nella richiesta: {$curl_error}");
|
||||
}
|
||||
|
||||
if ($http_code !== 200) {
|
||||
throw new Exception("Errore nel recupero dati: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
// Verifica che la risposta sia XML
|
||||
if (strpos($response, '<?xml') !== 0) {
|
||||
throw new Exception("Risposta non valida: atteso formato XML, ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
class VisualLimsApiClientXml
|
||||
{
|
||||
private static $instance = null;
|
||||
private $baseUrl;
|
||||
private $username;
|
||||
private $password;
|
||||
private $token = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$dotenv = Dotenv::createImmutable(dirname(__DIR__, 3));
|
||||
$dotenv->load();
|
||||
|
||||
$this->baseUrl = $_ENV['API_BASE_URL'];
|
||||
$this->username = $_ENV['API_USERNAME'];
|
||||
$this->password = $_ENV['API_PASSWORD'];
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new VisualLimsApiClientXml();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
private function authenticate()
|
||||
{
|
||||
$ch = curl_init("{$this->baseUrl}/api/authentication/authenticate");
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
||||
'Username' => $this->username,
|
||||
'Password' => $this->password
|
||||
]));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Accept: application/json'
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_auth_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false || $http_code != 200) {
|
||||
throw new Exception("Autenticazione fallita: HTTP {$http_code}, Errore cURL: {$curl_error}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
$token_data = json_decode($response, true);
|
||||
$this->token = null;
|
||||
|
||||
if (is_array($token_data) && isset($token_data['token'])) {
|
||||
$this->token = $token_data['token'];
|
||||
} elseif (is_string($token_data) && !empty($token_data)) {
|
||||
$this->token = trim($token_data, '"');
|
||||
} elseif (is_string($response) && !empty($response)) {
|
||||
$this->token = trim($response, '"');
|
||||
}
|
||||
|
||||
if (empty($this->token)) {
|
||||
throw new Exception("Token non ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
}
|
||||
|
||||
private function getToken()
|
||||
{
|
||||
if ($this->token === null) {
|
||||
$this->authenticate();
|
||||
}
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
public function get($endpoint, $options = [])
|
||||
{
|
||||
$token = $this->getToken();
|
||||
$query = http_build_query($options);
|
||||
$url = "{$this->baseUrl}/api/odata/{$endpoint}" . ($query ? '?' . $query : '');
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer {$token}",
|
||||
"Accept: application/xml"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
||||
$log = fopen(__DIR__ . '/curl_request_debug_xml.log', 'w') ?: fopen('php://stderr', 'w');
|
||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$curl_error = curl_error($ch);
|
||||
fclose($log);
|
||||
curl_close($ch);
|
||||
|
||||
if ($response === false) {
|
||||
throw new Exception("Errore nella richiesta: {$curl_error}");
|
||||
}
|
||||
|
||||
if ($http_code !== 200) {
|
||||
throw new Exception("Errore nel recupero dati: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
// Verifica che la risposta sia XML
|
||||
if (strpos($response, '<?xml') !== 0) {
|
||||
throw new Exception("Risposta non valida: atteso formato XML, ricevuto: " . substr($response, 0, 1000));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/authentication/authenticate
|
||||
* [HTTP/2] [1] [:method: POST]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/authentication/authenticate]
|
||||
* [HTTP/2] [1] [content-type: application/json]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
* [HTTP/2] [1] [content-length: 51]
|
||||
> POST /limsapi/api/authentication/authenticate HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
Content-Length: 51
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Thu, 21 Aug 2025 10:23:44 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1NTc3OTAyNSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.bBV1z1uaxZeUuw-2YS2gLGaxTCQJAHTieM82KVJb5nw]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/CustomField(1083)?$expand=CustomFieldsValues HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc1NTc3OTAyNSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.bBV1z1uaxZeUuw-2YS2gLGaxTCQJAHTieM82KVJb5nw
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< odata-version: 4.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Thu, 21 Aug 2025 10:23:44 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 3) . '/vendor/autoload.php'; // Risale a root/vendor/
|
||||
require_once dirname(__FILE__) . '/../class/VisualLimsApiClient.class.php'; // In root/public/userarea/class/
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
// Debug: Log the path where we expect the .env file
|
||||
$envPath = dirname(__DIR__, 3);
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Expected .env path: ' . $envPath . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Carica il file .env dalla root del progetto
|
||||
try {
|
||||
$dotenv = Dotenv::createImmutable($envPath);
|
||||
$dotenv->load();
|
||||
} catch (Exception $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore caricamento .env: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Recupera le variabili d'ambiente
|
||||
$dbHost = $_ENV['DB_HOST'];
|
||||
$dbName = $_ENV['DB_DATABASE'];
|
||||
$dbUser = $_ENV['DB_USERNAME'];
|
||||
$dbPass = $_ENV['DB_PASSWORD'];
|
||||
$dbPrefix = $_ENV['DB_PREFIX'];
|
||||
|
||||
// Debug: Log database connection details (excluding password)
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . " - DB Connection: host=$dbHost, dbname=$dbName, user=$dbUser, prefix=$dbPrefix" . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Connessione al database MySQL
|
||||
try {
|
||||
$pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (PDOException $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore connessione DB: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// Endpoint per recuperare le Matrici
|
||||
$endpoint = 'Matrice';
|
||||
|
||||
// (Opzionale) aggiungi parametri
|
||||
$options = []; // es. ['$top' => 100]
|
||||
|
||||
// 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);
|
||||
|
||||
// Debug: Log the API response size
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - API response received, value count: ' . (isset($data['value']) ? count($data['value']) : 0) . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Salva il JSON in locale (opzionale, per debug)
|
||||
file_put_contents(__DIR__ . '/matrici_response.json', json_encode($data, JSON_PRETTY_PRINT));
|
||||
|
||||
// Svuota la tabella (dump rapido)
|
||||
$pdo->exec("TRUNCATE TABLE {$dbPrefix}matrici");
|
||||
|
||||
// Debug: Log after truncate
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Table truncated: ' . $dbPrefix . 'matrici' . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Prepara l'insert
|
||||
$stmt = $pdo->prepare("
|
||||
INSERT INTO {$dbPrefix}matrici (
|
||||
IdMatrice, NomeMatriceTraduzione, DescrizioneTraduzione, MacroMatrice, NomeMatrice, Descrizione
|
||||
) VALUES (
|
||||
:IdMatrice, :NomeMatriceTraduzione, :DescrizioneTraduzione, :MacroMatrice, :NomeMatrice, :Descrizione
|
||||
)
|
||||
");
|
||||
|
||||
// Inserisci i dati
|
||||
$insertedRows = 0;
|
||||
if (isset($data['value']) && is_array($data['value'])) {
|
||||
foreach ($data['value'] as $item) {
|
||||
$stmt->execute([
|
||||
':IdMatrice' => $item['IdMatrice'],
|
||||
':NomeMatriceTraduzione' => $item['NomeMatriceTraduzione'],
|
||||
':DescrizioneTraduzione' => $item['DescrizioneTraduzione'] ?? null,
|
||||
':MacroMatrice' => $item['MacroMatrice'] ?? null,
|
||||
':NomeMatrice' => $item['NomeMatrice'],
|
||||
':Descrizione' => $item['Descrizione'] ?? null,
|
||||
]);
|
||||
$insertedRows++;
|
||||
// Debug: Log each inserted row
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Inserted row with IdMatrice: ' . $item['IdMatrice'] . PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
// Log successo
|
||||
file_put_contents(__DIR__ . '/success_log.txt', date('Y-m-d H:i:s') . ' - Aggiornamento completato: ' . $insertedRows . ' record inseriti.' . PHP_EOL, FILE_APPEND);
|
||||
} catch (Exception $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0); // Esci con successo per cron
|
||||
@@ -1,36 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/authentication/authenticate
|
||||
* [HTTP/2] [1] [:method: POST]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/authentication/authenticate]
|
||||
* [HTTP/2] [1] [content-type: application/json]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
* [HTTP/2] [1] [content-length: 51]
|
||||
> POST /limsapi/api/authentication/authenticate HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
Content-Length: 51
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 15:07:55 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/Cliente
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/Cliente]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1OTY5MiwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.O60U9XXapZOj0U3GuOIU0eiwgcUkzXTW6Eqy5f6q9D8]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/Cliente HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1OTY5MiwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.O60U9XXapZOj0U3GuOIU0eiwgcUkzXTW6Eqy5f6q9D8
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< odata-version: 4.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 12:08:45 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,38 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/authentication/authenticate
|
||||
* [HTTP/2] [1] [:method: POST]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: iftm.it]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/authentication/authenticate]
|
||||
* [HTTP/2] [1] [content-type: application/json]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
* [HTTP/2] [1] [user-agent: Mozilla/5.0 (compatible; PHP cURL)]
|
||||
* [HTTP/2] [1] [content-length: 51]
|
||||
> POST /limsapi/api/authentication/authenticate HTTP/2
|
||||
Host: iftm.it
|
||||
Content-Type: application/json
|
||||
Accept: application/json
|
||||
User-Agent: Mozilla/5.0 (compatible; PHP cURL)
|
||||
Content-Length: 51
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 10:19:09 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,18 +0,0 @@
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTAyMSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.KntKk8Up-9owFjy7onziK2BfncEnSNhizyNX9S-QHaw"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTEyNSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.IWjzzBg0kQ3lq4aK2ByMlY7Bwzb7Qq-6ziXV8kkZ2J0"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTI2NSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.UgVz6PTF9dmbFYdgyRZS0TcI0pvLEIQ3yMjPiicF1vs"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTMwNywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.PolfU_FWuVMd-YfonBYTo0i0qIl6kn6nUkCWCEBvZuA"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTQ0OSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.CGZ-9KbMmW19JYTVGfjIcbNscSsGB4dwoHCJkHHs_4M"
|
||||
|
||||
HTTP Code: 200
|
||||
Response: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk1MTc1MCwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.FCAm5sWed1Q-QiIsctMgSBfEd4sfN3kfVR3Mqd3XQz0"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/Cliente(5860)?$expand=SchemiAbilitati
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/Cliente(5860)?$expand=SchemiAbilitati]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk3MDQ3NSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.vABzuZkQE9luU_uc4e18AYiM5c2Jnf-z1Q3sofbz6O0]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/Cliente(5860)?$expand=SchemiAbilitati HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk3MDQ3NSwiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.vABzuZkQE9luU_uc4e18AYiM5c2Jnf-z1Q3sofbz6O0
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 200
|
||||
< cache-control: max-age=0
|
||||
< content-type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
|
||||
< server: Microsoft-IIS/10.0
|
||||
< strict-transport-security: max-age=2592000
|
||||
< odata-version: 4.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 15:07:56 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,35 +0,0 @@
|
||||
* Trying 93.43.5.102:443...
|
||||
* Connected to 93.43.5.102 (93.43.5.102) port 443
|
||||
* ALPN: curl offers h2,http/1.1
|
||||
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
|
||||
* ALPN: server accepted h2
|
||||
* Server certificate:
|
||||
* subject: C=FR; ST=Île-de-France; O=Bureau Veritas; CN=bvcpsitaly-elims.it
|
||||
* start date: Feb 17 00:00:00 2025 GMT
|
||||
* expire date: Feb 17 23:59:59 2026 GMT
|
||||
* issuer: C=US; O=Corporation Service Company; CN=Corporation Service Company RSA OV SSL CA
|
||||
* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
|
||||
* using HTTP/2
|
||||
* [HTTP/2] [1] OPENED stream for https://93.43.5.102/limsapi/api/odata/Cliente(0)?$expand=SchemiAbilitati
|
||||
* [HTTP/2] [1] [:method: GET]
|
||||
* [HTTP/2] [1] [:scheme: https]
|
||||
* [HTTP/2] [1] [:authority: 93.43.5.102]
|
||||
* [HTTP/2] [1] [:path: /limsapi/api/odata/Cliente(0)?$expand=SchemiAbilitati]
|
||||
* [HTTP/2] [1] [authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk2NTQ4MywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.oSwFJRuj0lDD7D6dOLIZWhn_Lzma0b38dLPEDIOMD7o]
|
||||
* [HTTP/2] [1] [accept: application/json]
|
||||
> GET /limsapi/api/odata/Cliente(0)?$expand=SchemiAbilitati HTTP/2
|
||||
Host: 93.43.5.102
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjQ5MiIsIlhhZlNlY3VyaXR5QXV0aFBhc3NlZCI6IlhhZlNlY3VyaXR5QXV0aFBhc3NlZCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJXZWJBcGlVc2VyIiwiWGFmU2VjdXJpdHkiOiJYYWZTZWN1cml0eSIsIlhhZkxvZ29uUGFyYW1zIjoicTFZS0xVNHQ4a3ZNVFZXeVVncFBUWElzeUFRSktPa29CU1FXRjVmbkY2VUF4Y3RUa3hJTE1rdUI0Z2FHU3JVQSIsImV4cCI6MTc0ODk2NTQ4MywiaXNzIjoiTXkiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjQyMDAifQ.oSwFJRuj0lDD7D6dOLIZWhn_Lzma0b38dLPEDIOMD7o
|
||||
Accept: application/json
|
||||
|
||||
< HTTP/2 404
|
||||
< cache-control: no-cache,no-store,max-age=0
|
||||
< pragma: no-cache
|
||||
< content-type: application/problem+json
|
||||
< expires: -1
|
||||
< server: Microsoft-IIS/10.0
|
||||
< x-powered-by: ASP.NET
|
||||
< x-content-type-options: nosniff
|
||||
< date: Tue, 03 Jun 2025 13:44:44 GMT
|
||||
<
|
||||
* Connection #0 to host 93.43.5.102 left intact
|
||||
@@ -1,108 +0,0 @@
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"}}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"},"success":false,"http_code":400}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings?tracking_numbers=750000810057432004040056&courier_code=tnt-it
|
||||
Request Data: []
|
||||
Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[]}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Get Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[],"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"}}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"},"success":false,"http_code":400}
|
||||
Request URL: https://api.trackingmore.com/v4/get?tracking_numbers=750000810057432004040056&courier_code=tnt-it
|
||||
Request Data: []
|
||||
Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[]}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Get Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[],"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"}}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4101,"message":"Tracking No. already exists."},"data":{"id":"9e85e85acd18a1c92d9fa1f6fede8a23","tracking_number":"750000810057432004040056","courier_code":"tnt-it"},"success":false,"http_code":400}
|
||||
Request URL: https://api.trackingmore.com/v4/get?tracking_numbers=750000810057432004040056
|
||||
Request Data: []
|
||||
Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[]}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Get Response: {"meta":{"code":200,"type":"Success","message":"The request was successful."},"data":[],"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e85f77564ba2d1b2d35c7b28c72e62b","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T09:43:15+00:00","update_at":"2025-03-26T09:01:02+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e85f77564ba2d1b2d35c7b28c72e62b","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T09:43:15+00:00","update_at":"2025-03-26T09:01:02+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8601d0116ffa9f4abe6fa609f27214","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T10:12:12+00:00","update_at":"2025-03-26T09:43:15+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8601d0116ffa9f4abe6fa609f27214","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-26T10:12:12+00:00","update_at":"2025-03-26T09:43:15+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "75000",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"75000","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e88676cc0b94ee0270add7c597d0cb0","tracking_number":"75000","courier_code":"tnt-it","order_number":"75000","order_date":null,"created_at":"2025-03-27T14:47:59+00:00","update_at":null,"delivery_status":"pending","archived":"tracking","updating":true,"source":"API","destination_country":null,"destination_state":null,"destination_city":null,"origin_country":null,"origin_state":null,"origin_city":null,"tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":null,"service_code":null,"weight":null,"weight_kg":null,"product_type":null,"pieces":null,"dimension":null,"previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"pending002","status_info":null,"latest_event":null,"latest_checkpoint_time":null,"transit_time":0,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e88676cc0b94ee0270add7c597d0cb0","tracking_number":"75000","courier_code":"tnt-it","order_number":"75000","order_date":null,"created_at":"2025-03-27T14:47:59+00:00","update_at":null,"delivery_status":"pending","archived":"tracking","updating":true,"source":"API","destination_country":null,"destination_state":null,"destination_city":null,"origin_country":null,"origin_state":null,"origin_city":null,"tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":null,"service_code":null,"weight":null,"weight_kg":null,"product_type":null,"pieces":null,"dimension":null,"previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"pending002","status_info":null,"latest_event":null,"latest_checkpoint_time":null,"transit_time":0,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8867d062b0ddfac8655e3d81b289af","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-27T14:49:04+00:00","update_at":"2025-03-26T10:12:12+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e8867d062b0ddfac8655e3d81b289af","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-03-27T14:49:04+00:00","update_at":"2025-03-26T10:12:12+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "123",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"123","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":4110,"message":"The value of tracking_number is invalid."},"data":null}
|
||||
HTTP Code: 400
|
||||
Error:
|
||||
Create Response: {"meta":{"code":4110,"message":"The value of tracking_number is invalid."},"data":null,"success":false,"http_code":400}
|
||||
Encoded JSON Data: {
|
||||
"tracking_number": "750000810057432004040056",
|
||||
"courier_code": "tnt-it"
|
||||
}
|
||||
Request URL: https://api.trackingmore.com/v4/trackings/create
|
||||
Request Data: {"tracking_number":"750000810057432004040056","courier_code":"tnt-it"}
|
||||
Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e9652c58e37fc7c8c9b08e9f2eb8f8e","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-04-03T12:51:49+00:00","update_at":"2025-04-01T09:02:08+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}}}
|
||||
HTTP Code: 200
|
||||
Error:
|
||||
Create Response: {"meta":{"code":200,"message":"Request response is successful"},"data":{"id":"9e9652c58e37fc7c8c9b08e9f2eb8f8e","tracking_number":"750000810057432004040056","courier_code":"tnt-it","order_number":"750000810057432004040056","order_date":null,"created_at":"2025-04-03T12:51:49+00:00","update_at":"2025-04-01T09:02:08+00:00","delivery_status":"delivered","archived":"tracking","updating":false,"source":"API","destination_country":"IT","destination_state":"MB","destination_city":"MEDA","origin_country":null,"origin_state":"BS","origin_city":"BRESCIA","tracking_postal_code":null,"tracking_ship_date":null,"tracking_destination_country":null,"tracking_origin_country":null,"tracking_key":null,"tracking_courier_account":null,"customer_name":null,"customer_email":null,"customer_sms":null,"recipient_postcode":null,"order_id":null,"title":null,"logistics_channel":null,"note":null,"label":null,"signed_by":"SIRONI","service_code":"Express","weight":"0,020","weight_kg":null,"product_type":null,"pieces":"1","dimension":"0,001","previously":null,"destination_track_number":null,"exchange_number":null,"scheduled_delivery_date":null,"scheduled_address":null,"substatus":"delivered003","status_info":null,"latest_event":"Spedizione consegnata,COMO,2025-03-25 11:12:00","latest_checkpoint_time":"2025-03-25T11:12:00","transit_time":1,"origin_info":{"courier_code":"tnt-it","courier_phone":"+39 199 803 868","weblink":"http:\/\/www.tnt.it\/","tracking_link":"https:\/\/www.tnt.it\/tracking\/Tracking.do","reference_number":"MY01818480","milestone_date":{"inforeceived_date":null,"pickup_date":"2025-03-24T17:35:00","outfordelivery_date":"2025-03-25T09:31:00","delivery_date":"2025-03-25T11:12:00","returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[{"checkpoint_date":"2025-03-25T11:12:00","checkpoint_delivery_status":"delivered","checkpoint_delivery_substatus":"delivered003","tracking_detail":"Spedizione consegnata","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T09:31:00","checkpoint_delivery_status":"pickup","checkpoint_delivery_substatus":"pickup001","tracking_detail":"La spedizione e' in consegna in data odierna","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-25T01:11:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' in transito","location":"COMO","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null},{"checkpoint_date":"2025-03-24T17:35:00","checkpoint_delivery_status":"transit","checkpoint_delivery_substatus":"transit001","tracking_detail":"La spedizione e' regolarmente partita","location":"BRESCIA","country_iso2":null,"state":null,"city":null,"zip":null,"raw_status":null}]},"destination_info":{"courier_code":null,"courier_phone":null,"weblink":null,"tracking_link":null,"reference_number":null,"milestone_date":{"inforeceived_date":null,"pickup_date":null,"outfordelivery_date":null,"delivery_date":null,"returning_date":null,"returned_date":null},"pickup_date":null,"departed_airport_date":null,"arrived_abroad_date":null,"customs_received_date":null,"trackinfo":[]}},"success":true,"http_code":200}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
$partId = $data['part_id'] ?? null;
|
||||
|
||||
if (!$partId) {
|
||||
echo json_encode(['success' => false, 'message' => 'ID parte mancante']);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("DELETE FROM identification_parts WHERE id = :part_id");
|
||||
$stmt->execute([':part_id' => $partId]);
|
||||
$rowCount = $stmt->rowCount();
|
||||
if ($rowCount > 0) {
|
||||
echo json_encode(['success' => true, 'message' => 'Parte eliminata con successo']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Nessuna parte trovata con ID ' . $partId]);
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nell\'eliminazione: ' . $e->getMessage()]);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Swagger Codegen Ignore
|
||||
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||
|
||||
# Use this file to prevent files from being overwritten by the generator.
|
||||
# The patterns follow closely to .gitignore or .dockerignore.
|
||||
|
||||
# As an example, the C# client generator defines ApiClient.cs.
|
||||
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||
#ApiClient.cs
|
||||
|
||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||
#foo/*/qux
|
||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||
|
||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||
#foo/**/qux
|
||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||
|
||||
# You can also negate patterns with an exclamation (!).
|
||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||
#docs/*.md
|
||||
# Then explicitly reverse the ignore rule for a single file:
|
||||
#!docs/README.md
|
||||
@@ -0,0 +1 @@
|
||||
3.0.34
|
||||
@@ -20,17 +20,10 @@ if (!$template) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Debug del JSON
|
||||
$clientSpecificFieldsJson = $template['client_specific_fields'] ?? '{}';
|
||||
error_log("Raw client_specific_fields JSON: " . $clientSpecificFieldsJson);
|
||||
|
||||
$clientSpecificFields = json_decode($clientSpecificFieldsJson, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
error_log("JSON decode error: " . json_last_error_msg());
|
||||
$clientSpecificFields = [];
|
||||
} else {
|
||||
error_log("Decoded client_specific_fields: " . print_r($clientSpecificFields, true));
|
||||
}
|
||||
// Recupera tutte le routine dal database
|
||||
$stmt = $pdo->prepare("SELECT * FROM routine");
|
||||
$stmt->execute();
|
||||
$routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
@@ -41,28 +34,9 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<style>
|
||||
.client-field-row .row {
|
||||
margin-bottom: 0 !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.client-field-row .col-md-1,
|
||||
.client-field-row .col-md-2,
|
||||
.client-field-row .col-md-3 {
|
||||
padding: 0 5px;
|
||||
overflow: hidden;
|
||||
max-width: 100%;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.client-field-row input,
|
||||
.client-field-row select {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
<!-- Include jQuery prima di Select2 -->
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<title>Edit Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
||||
</head>
|
||||
|
||||
@@ -74,7 +48,7 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
<div class="page-content">
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">UpdateXLS Template</h5>
|
||||
<h5 class="mb-0">Update XLS Template</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="mb-2">Edit the following form in order to update the selected import XLS template</p>
|
||||
@@ -82,7 +56,7 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
<ul class="mb-0">
|
||||
<li>Template Name</li>
|
||||
<li>Row Header and Column Header: where the title of the excel starts</li>
|
||||
<li>Cheme</li>
|
||||
<li>Schema</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,96 +98,67 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
<label class="form-label"><?= htmlspecialchars($desttable, ENT_QUOTES, 'UTF-8'); ?>*</label>
|
||||
<input type="text" name="target_table" class="form-control" value="<?php echo htmlspecialchars($template['target_table']); ?>" readonly required>
|
||||
</div>
|
||||
<!-- Aggiungi il campo per selezionare il cliente -->
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Button Size</label>
|
||||
<select name="button_size" class="form-control">
|
||||
<option value="small" <?php echo ($template['button_size'] ?? 'medium') === 'small' ? 'selected' : ''; ?>>Small</option>
|
||||
<option value="medium" <?php echo ($template['button_size'] ?? 'medium') === 'medium' ? 'selected' : ''; ?>>Medium</option>
|
||||
<option value="large" <?php echo ($template['button_size'] ?? 'medium') === 'large' ? 'selected' : ''; ?>>Large</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Button Background Color</label>
|
||||
<input type="color" name="button_bg_color" class="form-control" value="<?php echo htmlspecialchars($template['button_bg_color'] ?? '#007bff'); ?>">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Button Text Color</label>
|
||||
<input type="color" name="button_text_color" class="form-control" value="<?php echo htmlspecialchars($template['button_text_color'] ?? '#ffffff'); ?>">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Button Label</label>
|
||||
<input type="text" name="button_label" class="form-control" value="<?php echo htmlspecialchars($template['button_label'] ?? 'Click Me'); ?>">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Select Client *</label>
|
||||
<select name="client_id" id="clientSelect" class="form-control" required>
|
||||
<option value="">Select a client...</option>
|
||||
<!-- Le opzioni verranno popolate tramite JavaScript -->
|
||||
</select>
|
||||
<span id="clientLoadingStatus" class="text-muted" style="margin-left: 10px; display: none;">Recupero clienti in corso...</span>
|
||||
</div>
|
||||
<!-- Aggiungi il campo per selezionare lo schema -->
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Select Schema *</label>
|
||||
<select name="schema_id" id="schemaSelect" class="form-control" required>
|
||||
<option value="">Select a schema...</option>
|
||||
<!-- Le opzioni verranno popolate tramite JavaScript -->
|
||||
</select>
|
||||
<span id="schemaLoadingStatus" class="text-muted" style="margin-left: 10px; display: none;">Caricamento schemi in corso...</span>
|
||||
</div>
|
||||
<!-- Sezione per i campi specifici del cliente -->
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Client-Specific Fields</label>
|
||||
|
||||
<!-- Intestazioni colonne -->
|
||||
<div class="row fw-bold text-secondary mb-1">
|
||||
<div class="col-md-3">Field Name</div>
|
||||
<div class="col-md-2">Type</div>
|
||||
<div class="col-md-2">Possible Values</div>
|
||||
<div class="col-md-1">Required</div>
|
||||
<div class="col-md-2">Export Column Name</div>
|
||||
<div class="col-md-1">Default Value</div>
|
||||
<div class="col-md-1">Actions</div>
|
||||
<label class="form-label">Select Routine</label>
|
||||
<select name="idroutine" id="routineSelect" class="form-control">
|
||||
<option value="">Select a routine...</option>
|
||||
<?php foreach ($routines as $routine): ?>
|
||||
<option value="<?php echo $routine['idroutine']; ?>" <?php echo ($template['idroutine'] ?? '') == $routine['idroutine'] ? 'selected' : ''; ?>>
|
||||
<?php echo htmlspecialchars($routine['name']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div id="routineDetails" class="mt-2" style="display: none;">
|
||||
<h6>Routine Details</h6>
|
||||
<p><strong>Name:</strong> <span id="routineName"></span></p>
|
||||
<p><strong>Description:</strong> <span id="routineDescription"></span></p>
|
||||
<p><strong>Action 1:</strong> <span id="routineAction1"></span></p>
|
||||
<p><strong>Action 2:</strong> <span id="routineAction2"></span></p>
|
||||
<p><strong>Action 3:</strong> <span id="routineAction3"></span></p>
|
||||
</div>
|
||||
|
||||
<div id="clientSpecificFields">
|
||||
<?php
|
||||
$index = 0;
|
||||
if (!empty($clientSpecificFields) && is_array($clientSpecificFields)) {
|
||||
foreach ($clientSpecificFields as $fieldName => $fieldData) {
|
||||
if (is_array($fieldData)) {
|
||||
$type = $fieldData['type'] ?? 'text';
|
||||
$possibleValues = implode(', ', $fieldData['possible_values'] ?? []);
|
||||
$isRequired = isset($fieldData['is_required']) && $fieldData['is_required'] ? '1' : '0';
|
||||
$exportColumnName = $fieldData['export_column_name'] ?? '';
|
||||
$defaultValue = $fieldData['default_value'] ?? '';
|
||||
?>
|
||||
<div class="client-field-row mb-2">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="specific_fields[<?php echo $index; ?>][name]" class="form-control" value="<?php echo htmlspecialchars($fieldName); ?>" placeholder="Field Name (e.g., SKU)">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select name="specific_fields[<?php echo $index; ?>][type]" class="form-control" onchange="toggleDropdownValues(this)">
|
||||
<option value="text" <?php echo $type === 'text' ? 'selected' : ''; ?>>Text</option>
|
||||
<option value="dropdown" <?php echo $type === 'dropdown' ? 'selected' : ''; ?>>Dropdown</option>
|
||||
<option value="date" <?php echo $type === 'date' ? 'selected' : ''; ?>>Date</option>
|
||||
<option value="boolean" <?php echo $type === 'boolean' ? 'selected' : ''; ?>>Yes/No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2 dropdown-values" style="<?php echo $type === 'dropdown' ? 'visibility: visible;' : 'visibility: hidden;'; ?>">
|
||||
<input type="text" name="specific_fields[<?php echo $index; ?>][possible_values]" class="form-control" value="<?php echo htmlspecialchars($possibleValues); ?>" placeholder="Values (e.g., Red, Blue, Green)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<select name="specific_fields[<?php echo $index; ?>][required]" class="form-control">
|
||||
<option value="1" <?php echo $isRequired === '1' ? 'selected' : ''; ?>>Yes</option>
|
||||
<option value="0" <?php echo $isRequired === '0' ? 'selected' : ''; ?>>No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="specific_fields[<?php echo $index; ?>][export_column_name]" class="form-control" value="<?php echo htmlspecialchars($exportColumnName); ?>" placeholder="Export Column Name (e.g., MONCLER_SKU)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<input type="text" name="specific_fields[<?php echo $index; ?>][default_value]" class="form-control" value="<?php echo htmlspecialchars($defaultValue); ?>" placeholder="Default Value (optional)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-danger remove-field">-</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary mt-2" id="addField">Add Field</button>
|
||||
</div>
|
||||
|
||||
|
||||
<br>
|
||||
<button type="submit" class="btn btn-primary"><?= htmlspecialchars($savechanges, ENT_QUOTES, 'UTF-8'); ?></button>
|
||||
<a href="templates_dashboard.php" class="btn btn-secondary">Cancel</a>
|
||||
@@ -223,132 +168,78 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end page wrapper -->
|
||||
<!--start overlay-->
|
||||
<div class="overlay toggle-icon"></div>
|
||||
<!--end overlay-->
|
||||
<!--Start Back To Top Button-->
|
||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
||||
<!--End Back To Top Button-->
|
||||
<?php include('include/footer.php'); ?>
|
||||
</div>
|
||||
<!--end wrapper-->
|
||||
|
||||
<!-- search modal -->
|
||||
<?php //include('include/searchmodal.php');
|
||||
?>
|
||||
<!-- end search modal -->
|
||||
|
||||
<!--start switcher-->
|
||||
<?php //include('include/themeswitcher.php');
|
||||
?>
|
||||
<!--end switcher-->
|
||||
<!-- Temporaneamente disabilitato jsinclude.php per test -->
|
||||
<!-- <?php include('jsinclude.php'); ?> -->
|
||||
<!-- Includi jQuery e Select2 -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
|
||||
<script>
|
||||
// Dati del cliente e dello schema associati al template
|
||||
const templateClientId = <?php echo json_encode($template['idclient'] ?? 0); ?>;
|
||||
const templateSchemaId = <?php echo json_encode($template['idschema'] ?? 0); ?>;
|
||||
const templateSchemaName = "<?php echo htmlspecialchars($template['schemaname'] ?? ''); ?>";
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Verifica che jQuery sia caricato
|
||||
if (typeof jQuery === 'undefined') {
|
||||
alert("Errore: jQuery non è caricato. Contatta l'amministratore.");
|
||||
return;
|
||||
}
|
||||
|
||||
const form = document.getElementById("editTemplateForm");
|
||||
const addFieldButton = document.getElementById("addField");
|
||||
const container = document.getElementById("clientSpecificFields");
|
||||
const clientLoadingStatus = document.getElementById("clientLoadingStatus");
|
||||
const schemaLoadingStatus = document.getElementById("schemaLoadingStatus");
|
||||
const routineSelect = document.getElementById("routineSelect");
|
||||
const routineDetails = document.getElementById("routineDetails");
|
||||
const routineName = document.getElementById("routineName");
|
||||
const routineDescription = document.getElementById("routineDescription");
|
||||
const routineAction1 = document.getElementById("routineAction1");
|
||||
const routineAction2 = document.getElementById("routineAction2");
|
||||
const routineAction3 = document.getElementById("routineAction3");
|
||||
|
||||
if (!form || !addFieldButton || !container || !clientLoadingStatus || !schemaLoadingStatus) {
|
||||
console.error("One or more DOM elements not found:", {
|
||||
form,
|
||||
addFieldButton,
|
||||
container,
|
||||
clientLoadingStatus,
|
||||
schemaLoadingStatus
|
||||
});
|
||||
if (!form || !clientLoadingStatus || !schemaLoadingStatus || !routineSelect || !routineDetails) {
|
||||
alert("Errore: Uno o più elementi della pagina non sono stati trovati. Contatta l'amministratore.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("All DOM elements found");
|
||||
|
||||
// Controllo che jQuery sia caricato
|
||||
if (typeof jQuery === 'undefined') {
|
||||
console.error("jQuery non è caricato!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Inizializza Select2 sulla tendina dei clienti
|
||||
// Inizializza Select2
|
||||
$('#clientSelect').select2({
|
||||
placeholder: "Search for a client...",
|
||||
allowClear: true
|
||||
}).on('select2:open', function() {
|
||||
console.log("Select2 initialized successfully for clientSelect");
|
||||
}).on('select2:select', function(e) {
|
||||
console.log("Client selected:", e.params.data.id, e.params.data.text);
|
||||
});
|
||||
|
||||
// Inizializza Select2 sulla tendina degli schemi
|
||||
$('#schemaSelect').select2({
|
||||
placeholder: "Search for a schema...",
|
||||
allowClear: true
|
||||
}).on('select2:open', function() {
|
||||
console.log("Select2 initialized successfully for schemaSelect");
|
||||
}).on('select2:select', function(e) {
|
||||
console.log("Schema selected:", e.params.data.id, e.params.data.text);
|
||||
});
|
||||
|
||||
// Carica i clienti al caricamento della pagina
|
||||
$('#routineSelect').select2({
|
||||
placeholder: "Select a routine...",
|
||||
allowClear: true
|
||||
});
|
||||
|
||||
// Carica i clienti
|
||||
async function loadClients() {
|
||||
try {
|
||||
clientLoadingStatus.style.display = 'inline';
|
||||
clientLoadingStatus.textContent = 'Recupero clienti in corso...';
|
||||
|
||||
const response = await fetch("get_clienti.php", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
console.log("Risposta raw (clienti):", text);
|
||||
const data = JSON.parse(text);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || `Errore HTTP: ${response.status}`);
|
||||
}
|
||||
|
||||
if (data.value && Array.isArray(data.value)) {
|
||||
const select = document.getElementById("clientSelect");
|
||||
select.innerHTML = '<option value="">Select a client...</option>';
|
||||
data.value.forEach(client => {
|
||||
const nome = client.Nominativo || "Nome non disponibile";
|
||||
const id = client.IdCliente || "ID non disponibile";
|
||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
||||
if (parseInt(id) === parseInt(templateClientId)) {
|
||||
option.selected = true;
|
||||
}
|
||||
select.add(option);
|
||||
});
|
||||
$(select).trigger('change');
|
||||
console.log("Clienti caricati con successo.");
|
||||
clientLoadingStatus.textContent = "Clienti caricati.";
|
||||
} else {
|
||||
console.error("Nessun cliente trovato o formato dati non valido.", data);
|
||||
clientLoadingStatus.textContent = "Nessun cliente trovato.";
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Nessun cliente trovato o formato dati non valido.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
}
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.error || `Errore HTTP: ${response.status}`);
|
||||
const select = document.getElementById("clientSelect");
|
||||
select.innerHTML = '<option value="">Select a client...</option>';
|
||||
data.value.forEach(client => {
|
||||
const nome = client.Nominativo || "Nome non disponibile";
|
||||
const id = client.IdCliente || "ID non disponibile";
|
||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
||||
if (parseInt(id) === parseInt(<?php echo json_encode($template['idclient'] ?? 0); ?>)) {
|
||||
option.selected = true;
|
||||
}
|
||||
select.add(option);
|
||||
});
|
||||
$(select).trigger('change');
|
||||
clientLoadingStatus.textContent = "Clienti caricati.";
|
||||
} catch (error) {
|
||||
console.error("Errore nel caricamento dei clienti:", error);
|
||||
clientLoadingStatus.textContent = "Errore nel caricamento.";
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
@@ -357,50 +248,37 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
clientLoadingStatus.style.display = 'none';
|
||||
}, 2000);
|
||||
setTimeout(() => clientLoadingStatus.style.display = 'none', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Carica gli schemi al caricamento della pagina
|
||||
// Carica gli schemi
|
||||
async function loadSchemas() {
|
||||
try {
|
||||
schemaLoadingStatus.style.display = 'inline';
|
||||
schemaLoadingStatus.textContent = 'Caricamento schemi in corso...';
|
||||
|
||||
const response = await fetch("get_schemi.php", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
console.log("Risposta raw (schemi):", text);
|
||||
const data = JSON.parse(text);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || `Errore HTTP: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.error || `Errore HTTP: ${response.status}`);
|
||||
const select = document.getElementById("schemaSelect");
|
||||
select.innerHTML = '<option value="">Select a schema...</option>';
|
||||
data.value.forEach(schema => {
|
||||
const nome = schema.Nome || "Nome non disponibile";
|
||||
const id = schema.IdSchemaCustomFields || "ID non disponibile";
|
||||
const optionText = `${nome.trim()} (ID: ${id})`;
|
||||
const option = new Option(optionText, id);
|
||||
if (parseInt(id) === parseInt(templateSchemaId)) {
|
||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
||||
if (parseInt(id) === parseInt(<?php echo json_encode($template['idschema'] ?? 0); ?>)) {
|
||||
option.selected = true;
|
||||
}
|
||||
select.add(option);
|
||||
});
|
||||
$(select).trigger('change');
|
||||
console.log("Schemi caricati con successo.");
|
||||
schemaLoadingStatus.textContent = "Schemi caricati.";
|
||||
} catch (error) {
|
||||
console.error("Errore nel caricamento degli schemi:", error);
|
||||
schemaLoadingStatus.textContent = "Errore nel caricamento.";
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
@@ -409,169 +287,68 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
schemaLoadingStatus.style.display = 'none';
|
||||
}, 2000);
|
||||
setTimeout(() => schemaLoadingStatus.style.display = 'none', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Carica i dati in sequenza
|
||||
// Carica i dati
|
||||
async function loadData() {
|
||||
try {
|
||||
await loadClients();
|
||||
await loadSchemas();
|
||||
} catch (error) {
|
||||
console.error("Errore nel caricamento dei dati:", error);
|
||||
}
|
||||
}
|
||||
|
||||
loadData();
|
||||
|
||||
// Debug iniziale del DOM
|
||||
const debugDom = () => {
|
||||
const initialRows = container.getElementsByClassName("client-field-row");
|
||||
console.log("Initial number of rows:", initialRows.length);
|
||||
for (let i = 0; i < initialRows.length; i++) {
|
||||
const inputs = initialRows[i].querySelectorAll("input, select");
|
||||
const buttons = initialRows[i].querySelectorAll("button");
|
||||
console.log(`Row ${i + 1} - Total inputs: ${inputs.length}, Total buttons: ${buttons.length}`);
|
||||
inputs.forEach(input => console.log(`Input name: ${input.name}, value: ${input.value}, placeholder: ${input.placeholder}`));
|
||||
buttons.forEach(button => console.log(`Button type: ${button.type}`));
|
||||
}
|
||||
};
|
||||
|
||||
debugDom();
|
||||
|
||||
// Pulizia del DOM da input extra
|
||||
const cleanDom = () => {
|
||||
const rows = container.getElementsByClassName("client-field-row");
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const inputs = rows[i].querySelectorAll("input, select");
|
||||
if (inputs.length > 6) { // 6 input/select attesi
|
||||
console.warn(`Row ${i + 1}: Extra inputs detected, removing excess...`);
|
||||
inputs.forEach((input, index) => {
|
||||
if (index >= 6) {
|
||||
console.log(`Removing extra input: ${input.name}`);
|
||||
input.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cleanDom();
|
||||
|
||||
// Osservatore del DOM per rilevare modifiche
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach(mutation => {
|
||||
if (mutation.addedNodes.length) {
|
||||
console.log("DOM modified: New nodes added", mutation.addedNodes);
|
||||
cleanDom(); // Pulisce il DOM ogni volta che viene modificato
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(container, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
|
||||
// Gestione dinamica dei campi specifici
|
||||
addFieldButton.addEventListener("click", function() {
|
||||
console.log("Add Field button clicked");
|
||||
const fieldCount = container.getElementsByClassName("client-field-row").length;
|
||||
const newField = document.createElement("div");
|
||||
newField.className = "client-field-row mb-2";
|
||||
newField.innerHTML = `
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="specific_fields[${fieldCount}][name]" class="form-control" placeholder="Field Name (e.g., SKU)">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select name="specific_fields[${fieldCount}][type]" class="form-control" onchange="toggleDropdownValues(this)">
|
||||
<option value="text">Text</option>
|
||||
<option value="dropdown">Dropdown</option>
|
||||
<option value="date">Date</option>
|
||||
<option value="boolean">Yes/No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2 dropdown-values" style="visibility: hidden;">
|
||||
<input type="text" name="specific_fields[${fieldCount}][possible_values]" class="form-control" placeholder="Values (e.g., Red, Blue, Green)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<select name="specific_fields[${fieldCount}][required]" class="form-control">
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="specific_fields[${fieldCount}][export_column_name]" class="form-control" placeholder="Export Column Name (e.g., MONCLER_SKU)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<input type="text" name="specific_fields[${fieldCount}][default_value]" class="form-control" placeholder="Default Value (optional)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-danger remove-field">-</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(newField);
|
||||
|
||||
newField.querySelector(".remove-field").addEventListener("click", function() {
|
||||
console.log("Remove Field button clicked");
|
||||
container.removeChild(newField);
|
||||
updateFieldIndices();
|
||||
});
|
||||
});
|
||||
|
||||
// Funzione per mostrare/nascondere il campo dei valori possibili per i dropdown
|
||||
window.toggleDropdownValues = function(selectElement) {
|
||||
console.log("Toggling dropdown values for:", selectElement.value);
|
||||
const row = selectElement.closest(".row");
|
||||
const dropdownValues = row.querySelector(".dropdown-values");
|
||||
if (selectElement.value === "dropdown") {
|
||||
dropdownValues.style.visibility = "visible";
|
||||
} else {
|
||||
dropdownValues.style.visibility = "hidden";
|
||||
}
|
||||
};
|
||||
|
||||
// Event listener per i pulsanti di rimozione esistenti
|
||||
document.querySelectorAll(".remove-field").forEach(button => {
|
||||
button.addEventListener("click", function() {
|
||||
console.log("Existing remove button clicked");
|
||||
const container = document.getElementById("clientSpecificFields");
|
||||
container.removeChild(button.closest(".client-field-row"));
|
||||
updateFieldIndices();
|
||||
});
|
||||
});
|
||||
|
||||
// Funzione per aggiornare gli indici dei campi
|
||||
function updateFieldIndices() {
|
||||
console.log("Updating field indices");
|
||||
const rows = container.getElementsByClassName("client-field-row");
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const inputs = rows[i].querySelectorAll("input, select");
|
||||
inputs.forEach(input => {
|
||||
const name = input.name.replace(/\[\d+\]/, `[${i}]`);
|
||||
input.name = name;
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Errore nel caricamento dei dati: " + error.message,
|
||||
icon: "error",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
}
|
||||
}
|
||||
loadData();
|
||||
|
||||
// Routine dettagli
|
||||
const routines = <?php echo json_encode($routines); ?>;
|
||||
|
||||
function updateRoutineDetails() {
|
||||
const selectedId = routineSelect.value;
|
||||
routineDetails.style.display = selectedId ? 'block' : 'none';
|
||||
if (selectedId) {
|
||||
const routine = routines.find(r => r.idroutine == selectedId);
|
||||
if (routine) {
|
||||
routineName.textContent = routine.name || 'N/A';
|
||||
routineDescription.textContent = routine.description || 'N/A';
|
||||
routineAction1.textContent = routine.action1 || 'N/A';
|
||||
routineAction2.textContent = routine.action2 || 'N/A';
|
||||
routineAction3.textContent = routine.action3 || 'N/A';
|
||||
} else {
|
||||
routineName.textContent = 'N/A';
|
||||
routineDescription.textContent = 'N/A';
|
||||
routineAction1.textContent = 'N/A';
|
||||
routineAction2.textContent = 'N/A';
|
||||
routineAction3.textContent = 'N/A';
|
||||
}
|
||||
} else {
|
||||
routineName.textContent = '';
|
||||
routineDescription.textContent = '';
|
||||
routineAction1.textContent = '';
|
||||
routineAction2.textContent = '';
|
||||
routineAction3.textContent = '';
|
||||
}
|
||||
}
|
||||
routineSelect.addEventListener('change', updateRoutineDetails);
|
||||
updateRoutineDetails(); // Inizializza dettagli se una routine è preselezionata
|
||||
|
||||
// Submit del form
|
||||
form.addEventListener("submit", function(e) {
|
||||
e.preventDefault();
|
||||
console.log("Form submitted");
|
||||
|
||||
let formData = new FormData(this);
|
||||
|
||||
// Aggiungi il nome del cliente selezionato a FormData
|
||||
const clientSelect = document.getElementById("clientSelect");
|
||||
const clientId = clientSelect.value;
|
||||
const selectedClientOption = clientSelect.options[clientSelect.selectedIndex];
|
||||
|
||||
// Validazione: assicurati che un cliente sia selezionato
|
||||
if (!clientId) {
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
@@ -582,22 +359,18 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Estrai il nome del cliente in modo più robusto
|
||||
let clientName = "";
|
||||
if (selectedClientOption) {
|
||||
const optionText = selectedClientOption.text.trim();
|
||||
const nameMatch = optionText.match(/^(.+?)(?:\s*\(ID:\s*\d+\))?$/);
|
||||
clientName = nameMatch ? nameMatch[1].trim() : optionText;
|
||||
}
|
||||
|
||||
formData.append("client_name", clientName);
|
||||
|
||||
// Aggiungi l'ID e il nome dello schema selezionato a FormData
|
||||
const schemaSelect = document.getElementById("schemaSelect");
|
||||
const schemaId = schemaSelect.value;
|
||||
const selectedSchemaOption = schemaSelect.options[schemaSelect.selectedIndex];
|
||||
|
||||
// Validazione: assicurati che uno schema sia selezionato
|
||||
if (!schemaId) {
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
@@ -608,63 +381,18 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Estrai il nome dello schema in modo più robusto
|
||||
let schemaName = "";
|
||||
if (selectedSchemaOption) {
|
||||
const optionText = selectedSchemaOption.text.trim();
|
||||
const nameMatch = optionText.match(/^(.+?)(?:\s*\(ID:\s*\d+\))?$/);
|
||||
schemaName = nameMatch ? nameMatch[1].trim() : optionText;
|
||||
}
|
||||
|
||||
formData.append("idschema", schemaId);
|
||||
formData.append("schemamaname", schemaName);
|
||||
formData.append("schemaname", schemaName);
|
||||
|
||||
// Log per debug
|
||||
console.log("Client ID:", clientId);
|
||||
console.log("Client Name:", clientName);
|
||||
console.log("Schema ID:", schemaId);
|
||||
console.log("Schema Name:", schemaName);
|
||||
|
||||
// Genera il JSON per client_specific_fields
|
||||
let finalSpecificFields = {};
|
||||
|
||||
// Raccolta dei dati direttamente dal DOM
|
||||
const fieldRows = container.getElementsByClassName("client-field-row");
|
||||
for (let i = 0; i < fieldRows.length; i++) {
|
||||
const row = fieldRows[i];
|
||||
const inputs = row.querySelectorAll("input, select");
|
||||
let fieldData = {};
|
||||
|
||||
inputs.forEach(input => {
|
||||
const nameMatch = input.name.match(/specific_fields\[\d+\]\[(.*?)\]/);
|
||||
if (nameMatch) {
|
||||
const fieldName = nameMatch[1];
|
||||
fieldData[fieldName] = input.value.trim();
|
||||
}
|
||||
});
|
||||
|
||||
if (fieldData.name) {
|
||||
finalSpecificFields[fieldData.name] = {
|
||||
type: fieldData.type || "text",
|
||||
possible_values: (fieldData.possible_values && fieldData.type === "dropdown") ? fieldData.possible_values.split(",").map(v => v.trim()) : [],
|
||||
is_required: fieldData.required === "1",
|
||||
export_column_name: fieldData.export_column_name || "",
|
||||
default_value: fieldData.default_value || ""
|
||||
};
|
||||
console.log(`Field ${fieldData.name}:`, finalSpecificFields[fieldData.name]);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Generated JSON for client_specific_fields:", JSON.stringify(finalSpecificFields));
|
||||
|
||||
// Aggiungi il JSON al FormData
|
||||
formData.append("client_specific_fields", JSON.stringify(finalSpecificFields));
|
||||
|
||||
// Debug del FormData
|
||||
console.log("FormData contents:");
|
||||
for (let pair of formData.entries()) {
|
||||
console.log(pair[0] + ': ' + pair[1]);
|
||||
}
|
||||
// Aggiungi idroutine
|
||||
const routineId = routineSelect.value;
|
||||
formData.append("idroutine", routineId);
|
||||
|
||||
fetch("process_edit_template_xls.php", {
|
||||
method: "POST",
|
||||
@@ -672,7 +400,6 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("Fetch response:", data);
|
||||
if (data.success) {
|
||||
Swal.fire({
|
||||
title: "Successo!",
|
||||
@@ -692,7 +419,6 @@ if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Errore Fetch:", error);
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Si è verificato un errore imprevisto.",
|
||||
|
||||
@@ -5,3 +5,10 @@
|
||||
2025-07-04 10:42:49 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-07-04 10:44:13 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-07-04 10:48:07 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-08-19 16:29:25 - Autenticazione fallita: HTTP 400, Errore cURL: , Risposta: {"title":"Bad Request","status":400,"detail":"Cannot persist the object. It was modified or deleted (purged) by another application.","instance":"POST /api/authentication/authenticate","errorCode":"96bfc1252b"}
|
||||
2025-08-26 16:47:19 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:48:15 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:48:44 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:49:24 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-08-26 16:50:23 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
2025-09-08 08:39:17 - Risposta non JSON valida: <?xml version="1.0" encoding="utf-8"?><edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"><edmx:DataServices><Schema Namespace="DevExpress.ExpressApp.SystemModule" xmlns="http://docs.oasis-open.org/odata/ns/edm"><EntityType Name="DashboardViewItemDescriptor"><Key><PropertyRef Name="ViewId" /></Key><Property Name="ViewId" Type="Edm.String" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem" BaseType="DevExpress.ExpressApp.NonPersistentLiteObject" Abstract="true"><Property Name="Visibility" Type="DevExpress.ExpressApp.Editors.ViewItemVisibility" Nullable="false" /></EntityType><EntityType Name="DashboardOrganizationItem_1OfIModelDashboardViewItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem" Abstract="true" /><EntityType Name="ViewDashboardOrganizationItem" BaseType="DevExpress.ExpressApp.SystemModule.DashboardOrganizationItem_1OfIModelDashboardViewItem"><Property Name="ObjectType" Type="System.Type" /><Proper
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
console.log("export_to_lims.js loaded");
|
||||
|
||||
// Debug: verifica che i pulsanti siano trovati
|
||||
const exportButtons = document.querySelectorAll(".export-lims-btn");
|
||||
console.log(`Found ${exportButtons.length} export-lims-btn buttons`);
|
||||
|
||||
if (exportButtons.length === 0) {
|
||||
console.warn("No .export-lims-btn buttons found in the DOM");
|
||||
return;
|
||||
}
|
||||
|
||||
exportButtons.forEach((btn) => {
|
||||
btn.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
const rowIndex = btn.dataset.row;
|
||||
const iddatadb = btn.dataset.iddatadb;
|
||||
console.log(
|
||||
`Export to LIMS clicked for row ${rowIndex}, iddatadb: ${iddatadb}`,
|
||||
);
|
||||
|
||||
// Mostra il modale di conferma
|
||||
const confirmModalElement =
|
||||
document.getElementById("exportConfirmModal");
|
||||
if (!confirmModalElement) {
|
||||
console.error("exportConfirmModal not found in the DOM");
|
||||
alert("Errore: Modale di conferma non trovato");
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmModal = new bootstrap.Modal(confirmModalElement, {
|
||||
keyboard: false,
|
||||
});
|
||||
document.getElementById("exportIddatadb").textContent = iddatadb;
|
||||
confirmModal.show();
|
||||
|
||||
// Gestisci il click su "Conferma"
|
||||
const confirmBtn = document.getElementById("exportConfirmBtn");
|
||||
if (!confirmBtn) {
|
||||
console.error("exportConfirmBtn not found in the DOM");
|
||||
confirmModal.hide();
|
||||
alert("Errore: Pulsante di conferma non trovato");
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmHandler = async () => {
|
||||
console.log(`Confirmed export for iddatadb: ${iddatadb}`);
|
||||
confirmModal.hide();
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("iddatadb", iddatadb);
|
||||
|
||||
try {
|
||||
const response = await fetch("export_to_lims.php", {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
});
|
||||
if (!response.ok)
|
||||
throw new Error(
|
||||
`HTTP error! status: ${response.status}`,
|
||||
);
|
||||
const data = await response.json();
|
||||
|
||||
console.log("Export response:", data);
|
||||
|
||||
// Mostra il modale di risposta
|
||||
const responseModalElement = document.getElementById(
|
||||
"exportResponseModal",
|
||||
);
|
||||
if (!responseModalElement) {
|
||||
console.error(
|
||||
"exportResponseModal not found in the DOM",
|
||||
);
|
||||
alert("Errore: Modale di risposta non trovato");
|
||||
return;
|
||||
}
|
||||
|
||||
const responseModal = new bootstrap.Modal(
|
||||
responseModalElement,
|
||||
{
|
||||
keyboard: false,
|
||||
},
|
||||
);
|
||||
const responseMessage = document.getElementById(
|
||||
"exportResponseMessage",
|
||||
);
|
||||
if (data.success) {
|
||||
responseMessage.innerHTML = `${data.message.replace(/\n/g, "<br>")}<br>ID CommessaWeb: ${data.idcommessaweb}`;
|
||||
document.getElementById(
|
||||
"exportResponseModalLabel",
|
||||
).textContent = "Esportazione Completata";
|
||||
responseModal.show();
|
||||
|
||||
// Aggiorna la UI per riflettere lo stato 'To LIMS'
|
||||
const statusCell = btn
|
||||
.closest(".grid-row")
|
||||
.querySelector(
|
||||
'.grid-cell[data-col="status"] .status-badge',
|
||||
);
|
||||
if (statusCell) {
|
||||
statusCell.classList.remove("status-i", "status-P");
|
||||
statusCell.classList.add("status-l");
|
||||
statusCell.textContent = "To LIMS";
|
||||
}
|
||||
|
||||
// Gestisci la chiusura del modale di risposta
|
||||
responseModalElement.addEventListener(
|
||||
"hidden.bs.modal",
|
||||
() => {
|
||||
console.log(
|
||||
"exportResponseModal closed, cleaning up",
|
||||
);
|
||||
// Rimuovi tutti i backdrop residui
|
||||
document
|
||||
.querySelectorAll(".modal-backdrop")
|
||||
.forEach((backdrop) => {
|
||||
console.log(
|
||||
"Removing backdrop:",
|
||||
backdrop,
|
||||
);
|
||||
backdrop.remove();
|
||||
});
|
||||
// Ripristina il body
|
||||
document.body.classList.remove("modal-open");
|
||||
document.body.style.paddingRight = "";
|
||||
// Nascondi l'overlay
|
||||
const overlay = document.querySelector(
|
||||
".overlay.toggle-icon",
|
||||
);
|
||||
if (overlay) {
|
||||
overlay.style.display = "none";
|
||||
}
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
} else {
|
||||
responseMessage.textContent = `Errore durante la generazione dei payload: ${data.message}`;
|
||||
document.getElementById(
|
||||
"exportResponseModalLabel",
|
||||
).textContent = "Errore Esportazione";
|
||||
responseModal.show();
|
||||
|
||||
// Gestisci la chiusura del modale di risposta anche in caso di errore
|
||||
responseModalElement.addEventListener(
|
||||
"hidden.bs.modal",
|
||||
() => {
|
||||
console.log(
|
||||
"exportResponseModal closed, cleaning up",
|
||||
);
|
||||
// Rimuovi tutti i backdrop residui
|
||||
document
|
||||
.querySelectorAll(".modal-backdrop")
|
||||
.forEach((backdrop) => {
|
||||
console.log(
|
||||
"Removing backdrop:",
|
||||
backdrop,
|
||||
);
|
||||
backdrop.remove();
|
||||
});
|
||||
// Ripristina il body
|
||||
document.body.classList.remove("modal-open");
|
||||
document.body.style.paddingRight = "";
|
||||
// Nascondi l'overlay
|
||||
const overlay = document.querySelector(
|
||||
".overlay.toggle-icon",
|
||||
);
|
||||
if (overlay) {
|
||||
overlay.style.display = "none";
|
||||
}
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Export error:", error);
|
||||
const responseModalElement = document.getElementById(
|
||||
"exportResponseModal",
|
||||
);
|
||||
if (!responseModalElement) {
|
||||
console.error(
|
||||
"exportResponseModal not found in the DOM",
|
||||
);
|
||||
alert("Errore: Modale di risposta non trovato");
|
||||
return;
|
||||
}
|
||||
const responseModal = new bootstrap.Modal(
|
||||
responseModalElement,
|
||||
{
|
||||
keyboard: false,
|
||||
},
|
||||
);
|
||||
document.getElementById(
|
||||
"exportResponseMessage",
|
||||
).textContent =
|
||||
`Errore durante la generazione dei payload: ${error.message}`;
|
||||
document.getElementById(
|
||||
"exportResponseModalLabel",
|
||||
).textContent = "Errore Esportazione";
|
||||
responseModal.show();
|
||||
|
||||
// Gestisci la chiusura del modale di risposta in caso di errore
|
||||
responseModalElement.addEventListener(
|
||||
"hidden.bs.modal",
|
||||
() => {
|
||||
console.log(
|
||||
"exportResponseModal closed, cleaning up",
|
||||
);
|
||||
// Rimuovi tutti i backdrop residui
|
||||
document
|
||||
.querySelectorAll(".modal-backdrop")
|
||||
.forEach((backdrop) => {
|
||||
console.log("Removing backdrop:", backdrop);
|
||||
backdrop.remove();
|
||||
});
|
||||
// Ripristina il body
|
||||
document.body.classList.remove("modal-open");
|
||||
document.body.style.paddingRight = "";
|
||||
// Nascondi l'overlay
|
||||
const overlay = document.querySelector(
|
||||
".overlay.toggle-icon",
|
||||
);
|
||||
if (overlay) {
|
||||
overlay.style.display = "none";
|
||||
}
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
}
|
||||
|
||||
// Rimuovi il listener dopo l'esecuzione
|
||||
confirmBtn.removeEventListener("click", confirmHandler);
|
||||
};
|
||||
|
||||
// Rimuovi eventuali listener precedenti
|
||||
confirmBtn.removeEventListener("click", confirmHandler);
|
||||
confirmBtn.addEventListener("click", confirmHandler);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
require_once "class/VisualLimsApiClient.class.php";
|
||||
include('include/headscript.php');
|
||||
|
||||
$dbHandler = DBHandlerSelect::getInstance();
|
||||
$pdo = $dbHandler->getConnection();
|
||||
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// 🔹 Configura directory log (creala se non esiste)
|
||||
$logDir = __DIR__ . '/logs/api/';
|
||||
if (!is_dir($logDir)) {
|
||||
mkdir($logDir, 0755, true);
|
||||
}
|
||||
|
||||
// 🔹 Base URL API
|
||||
$apiBaseUrl = 'https://93.43.5.102/limsapi/api/odata/';
|
||||
|
||||
// 🔹 Funzione per validare e convertire date
|
||||
function validateDate($value)
|
||||
{
|
||||
// Prova a validare come data (accetta formati comuni)
|
||||
$date = DateTime::createFromFormat('Y-m-d', $value) ?: DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||
if ($date) {
|
||||
return $date->format('Y-m-d\TH:i:sP'); // Formato ISO 8601
|
||||
}
|
||||
return null; // Imposta null se non è una data valida
|
||||
}
|
||||
|
||||
try {
|
||||
$iddatadb = $_POST['iddatadb'] ?? null;
|
||||
if (!$iddatadb) {
|
||||
throw new Exception("Missing iddatadb");
|
||||
}
|
||||
|
||||
// 🔹 STEP 1+2: Fetch Cliente ID from datadb and Schema ID from excel_templates
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT d.idclient AS clienteId, et.idschema AS schemaId
|
||||
FROM datadb as d
|
||||
INNER JOIN excel_templates as et ON d.templateid = et.id
|
||||
WHERE d.iddatadb = :iddatadb
|
||||
LIMIT 1
|
||||
");
|
||||
$stmt->execute(['iddatadb' => $iddatadb]);
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$result) {
|
||||
throw new Exception("No Cliente/Schema found for iddatadb {$iddatadb}");
|
||||
}
|
||||
|
||||
$clienteId = (int) $result['clienteId'];
|
||||
$schemaId = (int) $result['schemaId'];
|
||||
|
||||
// 🔹 STEP 3: Fetch Parts (including idmatrice)
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT part_number, part_description, material, color, mix, idmatrice
|
||||
FROM identification_parts
|
||||
WHERE iddatadb = :iddatadb
|
||||
");
|
||||
$stmt->execute(['iddatadb' => $iddatadb]);
|
||||
$parts = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 🔹 STEP 4: Fetch Field Values with Labels
|
||||
$stmt = $pdo->prepare("
|
||||
SELECT
|
||||
idd.field_value,
|
||||
m.field_label,
|
||||
m.schema_id,
|
||||
m.field_id
|
||||
FROM
|
||||
import_data_details as idd
|
||||
JOIN template_mapping m ON idd.mapping_id = m.id
|
||||
WHERE idd.id = :iddatadb
|
||||
");
|
||||
$stmt->execute(['iddatadb' => $iddatadb]);
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$fieldValues = [];
|
||||
$valueMap = [];
|
||||
foreach ($rows as $row) {
|
||||
$fieldValues[] = [
|
||||
"IdCommesseCustomFields" => (int) $row['field_id'],
|
||||
"Valore" => $row['field_value'],
|
||||
"FieldLabel" => $row['field_label']
|
||||
];
|
||||
$valueMap[(int) $row['field_id']] = $row['field_value'];
|
||||
}
|
||||
|
||||
// Logga i fieldValues in error_log
|
||||
$logFieldValues = "FieldValues dal DB (iddatadb={$iddatadb}):\n" . json_encode($fieldValues, JSON_PRETTY_PRINT);
|
||||
error_log($logFieldValues);
|
||||
|
||||
// 🔹 Initialize API client
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// 🔹 STEP 5: Create CommessaWeb (NOT WebOrder)
|
||||
$commessaWebPayload = [
|
||||
"Cliente" => $clienteId,
|
||||
"SchemaCustomField" => $schemaId,
|
||||
"Richiedente" => "Test Web Import",
|
||||
"Descrizione" => "TEST CommessaWeb",
|
||||
];
|
||||
|
||||
// Costruisci log curl-like per STEP 5
|
||||
$jsonPayload = json_encode($commessaWebPayload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
$logContentStep5 = "curl --location --request POST '{$apiBaseUrl}CommessaWeb' \\\n" .
|
||||
"--header 'Content-Type: application/json' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••' \\\n" .
|
||||
"--data '{$jsonPayload}'";
|
||||
|
||||
$commessaWeb = $api->post("CommessaWeb", $commessaWebPayload);
|
||||
|
||||
$logContentStep5 .= "\n\nRESPONSE:\n" . json_encode($commessaWeb, JSON_PRETTY_PRINT);
|
||||
|
||||
// Salva log
|
||||
$logFileStep5 = $logDir . "commessa_create_step5_" . $iddatadb . "_" . time() . ".txt";
|
||||
file_put_contents($logFileStep5, $logContentStep5);
|
||||
|
||||
$commessaId = $commessaWeb["IdCommessa"];
|
||||
$commessaWebCode = substr($commessaWeb["CodiceCommessa"] ?? "TEST CommessaWeb", 0, 30); // Limite a 30 caratteri
|
||||
|
||||
// 🔹 STEP 6: Create Campioni (Samples) for each part
|
||||
$campioni = [];
|
||||
$logContentStep6 = "";
|
||||
|
||||
foreach ($parts as $index => $part) {
|
||||
$matriceId = (int) ($part["idmatrice"] ?? 0);
|
||||
|
||||
if ($matriceId <= 0) {
|
||||
throw new Exception("Invalid or missing idmatrice for part: " . ($part["part_number"] ?? "Unknown"));
|
||||
}
|
||||
|
||||
$campionePayload = [
|
||||
"Commessa" => $commessaId,
|
||||
"Matrice" => $matriceId,
|
||||
"SottoMatrice" => null,
|
||||
"SchemaCustomField" => $schemaId,
|
||||
"NoteWeb" => $part["part_description"] ?? ""
|
||||
];
|
||||
|
||||
// Costruisci curl-like per questo campione
|
||||
$jsonPayload = json_encode($campionePayload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
$logContentStep6 .= "CAMPIONE #{$index}\n" .
|
||||
"curl --location --request POST '{$apiBaseUrl}Campione' \\\n" .
|
||||
"--header 'Content-Type: application/json' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••' \\\n" .
|
||||
"--data '{$jsonPayload}'\n\n";
|
||||
|
||||
$campione = $api->post("Campione", $campionePayload);
|
||||
|
||||
$logContentStep6 .= "RESPONSE:\n" . json_encode($campione, JSON_PRETTY_PRINT) . "\n\n---\n";
|
||||
|
||||
$campione["PartNumber"] = $part["part_number"] ?? "";
|
||||
$campione["Material"] = $part["material"] ?? "";
|
||||
$campione["Color"] = $part["color"] ?? "";
|
||||
$campione["Mix"] = $part["mix"] ?? "";
|
||||
|
||||
$campioni[] = $campione;
|
||||
}
|
||||
|
||||
// Salva log per STEP 6
|
||||
$logFileStep6 = $logDir . "commessa_{$commessaId}_campioni_step6_" . time() . ".txt";
|
||||
file_put_contents($logFileStep6, $logContentStep6);
|
||||
|
||||
// 🔹 STEP 7: Update Custom Fields for CommessaWeb
|
||||
if (!empty($fieldValues)) {
|
||||
// GET con espansione per CustomField
|
||||
$expand = "CommesseCustomFields(\$expand=CustomField)";
|
||||
$commessaWithFields = $api->get("CommessaWeb(" . $commessaId . ")?\$expand=" . $expand);
|
||||
|
||||
// Logga il GET
|
||||
$logContentGet = "curl --location --request GET '{$apiBaseUrl}CommessaWeb({$commessaId})?\$expand=CommesseCustomFields(\$expand=CustomField)' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••'\n\n" .
|
||||
"RESPONSE:\n" . json_encode($commessaWithFields, JSON_PRETTY_PRINT);
|
||||
$logFileGet = $logDir . "commessa_{$commessaId}_get_step7_" . time() . ".txt";
|
||||
file_put_contents($logFileGet, $logContentGet);
|
||||
|
||||
// Prepara payload PATCH
|
||||
$commessaCustomFields = [];
|
||||
foreach ($commessaWithFields["CommesseCustomFields"] as $customField) {
|
||||
$definitionId = (int) ($customField["CustomField"]["IdCustomField"] ?? 0);
|
||||
$fieldId = (int) $customField["IdCommesseCustomFields"];
|
||||
$currentValue = $customField["Valore"] ?? '';
|
||||
$fieldType = $customField["CustomField"]["Tipo"] ?? '';
|
||||
$newValue = isset($valueMap[$definitionId]) ? $valueMap[$definitionId] : $currentValue;
|
||||
|
||||
// Valida se il campo è di tipo Data
|
||||
if ($fieldType === 'Data' && $newValue !== $currentValue) {
|
||||
$newValue = validateDate($newValue);
|
||||
}
|
||||
|
||||
$commessaCustomFields[] = [
|
||||
"IdCommesseCustomFields" => $fieldId,
|
||||
"Valore" => $newValue
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($commessaCustomFields)) {
|
||||
$updatePayload = ["CommesseCustomFields" => $commessaCustomFields];
|
||||
|
||||
// Logga payload e response
|
||||
$jsonPayload = json_encode($updatePayload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
$logContentStep7 = "curl --location --request PATCH '{$apiBaseUrl}CommessaWeb({$commessaId})' \\\n" .
|
||||
"--header 'Content-Type: application/json' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••' \\\n" .
|
||||
"--data '{$jsonPayload}'";
|
||||
|
||||
$patchResponse = $api->patch("CommessaWeb({$commessaId})", $updatePayload);
|
||||
|
||||
$logContentStep7 .= "\n\nRESPONSE:\n" . json_encode($patchResponse, JSON_PRETTY_PRINT);
|
||||
$logFileStep7 = $logDir . "commessa_{$commessaId}_update_step7_" . time() . ".txt";
|
||||
file_put_contents($logFileStep7, $logContentStep7);
|
||||
}
|
||||
}
|
||||
|
||||
// 🔹 STEP 8: Update datadb with idcommessaweb, commessaweb, and status
|
||||
$stmt = $pdo->prepare("
|
||||
UPDATE datadb
|
||||
SET idcommessaweb = :idcommessaweb, commessaweb = :commessaweb, status = 'l'
|
||||
WHERE iddatadb = :iddatadb
|
||||
");
|
||||
$stmt->execute([
|
||||
'idcommessaweb' => $commessaId,
|
||||
'commessaweb' => $commessaWebCode,
|
||||
'iddatadb' => $iddatadb
|
||||
]);
|
||||
|
||||
// 🔹 STEP 9: Send CommessaWeb to laboratory (commentato come richiesto)
|
||||
/*
|
||||
$sendResult = $api->post("CommessaWeb({$commessaId})/InviaCommessa", []);
|
||||
|
||||
// Logga il POST
|
||||
$logContentStep9 = "curl --location --request POST '{$apiBaseUrl}CommessaWeb({$commessaId})/InviaCommessa' \\\n" .
|
||||
"--header 'Content-Type: application/json' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••' \\\n" .
|
||||
"--data '{}'\n\n" .
|
||||
"RESPONSE:\n" . json_encode($sendResult, JSON_PRETTY_PRINT);
|
||||
$logFileStep9 = $logDir . "commessa_{$commessaId}_send_step9_" . time() . ".txt";
|
||||
file_put_contents($logFileStep9, $logContentStep9);
|
||||
*/
|
||||
|
||||
// 🔹 STEP 10: GET di controllo post-PATCH
|
||||
$expand = "CommesseCustomFields(\$expand=CustomField)";
|
||||
$commessaAfterPatch = $api->get("CommessaWeb(" . $commessaId . ")?\$expand=" . $expand);
|
||||
|
||||
// Logga il GET di controllo
|
||||
$logContentStep10 = "curl --location --request GET '{$apiBaseUrl}CommessaWeb({$commessaId})?\$expand=CommesseCustomFields(\$expand=CustomField)' \\\n" .
|
||||
"--header 'Authorization: Bearer ••••••'\n\n" .
|
||||
"RESPONSE:\n" . json_encode($commessaAfterPatch, JSON_PRETTY_PRINT);
|
||||
$logFileStep10 = $logDir . "commessa_{$commessaId}_get_step10_" . time() . ".txt";
|
||||
file_put_contents($logFileStep10, $logContentStep10);
|
||||
|
||||
// 🔹 STEP 11: Prepare final response
|
||||
$finalCommessa = [
|
||||
"Cliente" => $clienteId,
|
||||
"SchemaCustomField" => $schemaId,
|
||||
"Richiedente" => $commessaWeb["Richiedente"] ?? "Web Import",
|
||||
"Descrizione" => $commessaWeb["Descrizione"] ?? "",
|
||||
"CommesseCustomFields" => $commessaAfterPatch["CommesseCustomFields"] ?? [],
|
||||
"Campioni" => $campioni,
|
||||
"Inviata" => 0 // Non inviato, come richiesto
|
||||
];
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"commessaWeb" => $finalCommessa,
|
||||
"commessaWebApiResponse" => $commessaWeb, // Incluso per debug
|
||||
"totalCampioni" => count($campioni),
|
||||
"totalCustomFields" => count($commessaAfterPatch["CommesseCustomFields"] ?? []),
|
||||
"message" => "Export successful",
|
||||
"logFiles" => [
|
||||
"step5_create" => $logFileStep5,
|
||||
"step6_campioni" => $logFileStep6,
|
||||
"step7_patch" => $logFileStep7,
|
||||
"step10_get" => $logFileStep10
|
||||
]
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
error_log("LIMS Export Error: " . $e->getMessage() . "\nTrace: " . $e->getTraceAsString());
|
||||
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Export failed: " . $e->getMessage(),
|
||||
"logFiles" => [
|
||||
"step5_create" => $logFileStep5 ?? null,
|
||||
"step6_campioni" => $logFileStep6 ?? null,
|
||||
"step7_patch" => $logFileStep7 ?? null,
|
||||
"step10_get" => $logFileStep10 ?? null
|
||||
]
|
||||
]);
|
||||
}
|
||||
@@ -1,24 +1,74 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php'; // Torna al livello di public per trovare vendor/
|
||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
require_once __DIR__ . '/class/VisualLimsApiClient.class.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// Disabilita la visualizzazione degli errori PHP per evitare output HTML
|
||||
// Disable PHP error display
|
||||
ini_set('display_errors', '0');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
$data = $api->get("Cliente"); // Recupera i clienti
|
||||
|
||||
// Salva la risposta in un file per debug
|
||||
file_put_contents(__DIR__ . '/clienti_response.json', json_encode($data));
|
||||
// Parametri OData
|
||||
$params = [
|
||||
'$select' => 'IdCliente,Nominativo,CodiceNazioneFatturazione',
|
||||
'$orderby' => 'Nominativo asc'
|
||||
];
|
||||
|
||||
// Costruisce query string con encoding corretto
|
||||
$queryString = http_build_query($params);
|
||||
|
||||
// Componi endpoint finale
|
||||
$endpoint = "Cliente?$queryString";
|
||||
|
||||
// Funzione per eseguire la chiamata con retry
|
||||
function makeApiRequest($api, $endpoint, $maxRetries = 3)
|
||||
{
|
||||
for ($retry = 0; $retry < $maxRetries; $retry++) {
|
||||
try {
|
||||
// Tenta la chiamata API
|
||||
$data = $api->get($endpoint);
|
||||
// Salva risposta per debug
|
||||
file_put_contents(__DIR__ . '/clienti_response.json', json_encode($data, JSON_PRETTY_PRINT));
|
||||
return $data;
|
||||
} catch (Exception $e) {
|
||||
$errorMessage = $e->getMessage();
|
||||
// Controlla se l'errore è legato all'autenticazione (HTTP 400 con messaggio specifico)
|
||||
if (strpos($errorMessage, 'HTTP 400') !== false && strpos($errorMessage, 'Cannot persist the object') !== false) {
|
||||
// Forza il refresh del token
|
||||
try {
|
||||
// Assumi che VisualLimsApiClient abbia un metodo per il refresh del token
|
||||
$api->refreshToken(); // Da implementare in VisualLimsApiClient se non esiste
|
||||
error_log("Tentativo $retry: Refresh token eseguito per endpoint $endpoint");
|
||||
} catch (Exception $refreshEx) {
|
||||
error_log("Errore durante il refresh del token: " . $refreshEx->getMessage());
|
||||
throw new Exception("Impossibile eseguire il refresh del token: " . $refreshEx->getMessage());
|
||||
}
|
||||
// Ritarda leggermente prima del retry
|
||||
usleep(500000); // 500ms
|
||||
continue;
|
||||
}
|
||||
// Altri errori non gestiti dal retry
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
throw new Exception("Massimo numero di tentativi raggiunto per $endpoint");
|
||||
}
|
||||
|
||||
// Esegui la chiamata con retry
|
||||
$data = makeApiRequest($api, $endpoint);
|
||||
|
||||
echo json_encode($data);
|
||||
} catch (Exception $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$errorResponse = [
|
||||
'error' => $e->getMessage(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
];
|
||||
error_log("Errore in get_clienti.php: " . json_encode($errorResponse));
|
||||
echo json_encode($errorResponse);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', '0');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// ID della CommessaWeb specifica (cambialo di volta in volta)
|
||||
$id = 529435; // TODO: Cambia questo valore con l'ID desiderato
|
||||
|
||||
// Endpoint per recuperare la CommessaWeb specifica con espansione dello schema custom
|
||||
$endpoint = "CommessaWeb({$id})";
|
||||
|
||||
// Opzioni per l'espansione: includi OrderCustomFields per ottenere i campi custom dello schema assegnato all'ordine
|
||||
$options = ['$expand' => 'OrderCustomFields'];
|
||||
|
||||
// Debug: salva URL usato
|
||||
$base_url = 'https://93.43.5.102/limsapi/api/odata/';
|
||||
$query = http_build_query($options);
|
||||
$full_url = $base_url . $endpoint . ($query ? '?' . $query : '');
|
||||
file_put_contents(__DIR__ . '/last_url.txt', $full_url . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Chiamata API
|
||||
$data = $api->get($endpoint, $options);
|
||||
|
||||
// Salva il JSON in locale
|
||||
file_put_contents(__DIR__ . '/commessaweb_schema_response.json', json_encode($data, JSON_PRETTY_PRINT));
|
||||
|
||||
echo json_encode($data);
|
||||
} catch (Exception $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
http_response_code(500);
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php'; // Torna al livello di public
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
@@ -9,20 +9,30 @@ error_reporting(E_ALL);
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// ID del campo custom passato da GET oppure default
|
||||
$customFieldId = isset($_GET['field_id']) && is_numeric($_GET['field_id']) ? intval($_GET['field_id']) : 156;
|
||||
// მივიღოთ მრავლობითი field_ids
|
||||
$fieldIds = [];
|
||||
if (isset($_GET['field_ids'])) {
|
||||
$fieldIds = array_filter(array_map('intval', explode(',', $_GET['field_ids'])));
|
||||
}
|
||||
|
||||
// Endpoint con $expand per ottenere i valori
|
||||
$endpoint = "CustomField($customFieldId)?\$expand=CustomFieldsValues";
|
||||
// თუ არ გადმოგვცეს -> ერთი default
|
||||
if (empty($fieldIds)) {
|
||||
$fieldIds = [156];
|
||||
}
|
||||
|
||||
// Recupera i dati dal server
|
||||
$data = $api->get($endpoint);
|
||||
$results = [];
|
||||
|
||||
// Salva la risposta in un file per debug
|
||||
file_put_contents(__DIR__ . '/customfield_values_response.json', json_encode($data));
|
||||
foreach ($fieldIds as $customFieldId) {
|
||||
$endpoint = "CustomField($customFieldId)?\$expand=CustomFieldsValues";
|
||||
$data = $api->get($endpoint);
|
||||
|
||||
// Output JSON al client
|
||||
echo json_encode($data);
|
||||
$results[$customFieldId] = $data['CustomFieldsValues'] ?? [];
|
||||
}
|
||||
|
||||
// Debug ფაილი
|
||||
file_put_contents(__DIR__ . '/customfield_values_response.json', json_encode($results));
|
||||
|
||||
echo json_encode($results);
|
||||
} catch (Exception $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php'; // Risale a root/vendor/
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
// Set JSON header
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// Debug: Log the path where we expect the .env file
|
||||
$envPath = dirname(__DIR__, 2);
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Expected .env path: ' . $envPath . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Carica il file .env dalla root del progetto
|
||||
try {
|
||||
$dotenv = Dotenv::createImmutable($envPath);
|
||||
$dotenv->load();
|
||||
} catch (Exception $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore caricamento .env: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore caricamento configurazione: ' . $e->getMessage()]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Recupera le variabili d'ambiente
|
||||
$dbHost = $_ENV['DB_HOST'];
|
||||
$dbName = $_ENV['DB_DATABASE'];
|
||||
$dbUser = $_ENV['DB_USERNAME'];
|
||||
$dbPass = $_ENV['DB_PASSWORD'];
|
||||
$dbPrefix = $_ENV['DB_PREFIX'];
|
||||
|
||||
// Debug: Log database connection details (excluding password)
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . " - DB Connection: host=$dbHost, dbname=$dbName, user=$dbUser, prefix=$dbPrefix" . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Connessione al database MySQL
|
||||
try {
|
||||
$pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (PDOException $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore connessione DB: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore connessione al database: ' . $e->getMessage()]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
// Query per recuperare i valori distinti di MacroMatrice, escludendo quelli che iniziano con '*' e ordinandoli
|
||||
$query = "SELECT DISTINCT MacroMatrice FROM {$dbPrefix}matrici WHERE MacroMatrice IS NOT NULL AND MacroMatrice NOT LIKE '*%' ORDER BY MacroMatrice ASC";
|
||||
$stmt = $pdo->prepare($query);
|
||||
$stmt->execute();
|
||||
$macroMatrici = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
// Debug: Log del numero di MacroMatrice recuperate
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Retrieved ' . count($macroMatrici) . ' MacroMatrice from database' . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Restituisci risposta JSON
|
||||
echo json_encode(['success' => true, 'value' => $macroMatrici]);
|
||||
} catch (PDOException $e) {
|
||||
// Log errore e restituisci risposta di errore
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore nel recupero delle MacroMatrice: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nel recupero delle MacroMatrice: ' . $e->getMessage()]);
|
||||
exit(1);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', '0');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
|
||||
// Endpoint per recuperare le Matrici
|
||||
$endpoint = 'Matrice';
|
||||
|
||||
// (Opzionale) aggiungi parametri, ad esempio $top per limitare i risultati
|
||||
$options = []; // oppure ad esempio: ['$top' => 100]
|
||||
|
||||
// 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__ . '/matrici_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()]);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php'; // Risale a root/vendor/
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
// Set JSON header
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// Debug: Log the path where we expect the .env file
|
||||
$envPath = dirname(__DIR__, 2);
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Expected .env path: ' . $envPath . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Carica il file .env dalla root del progetto
|
||||
try {
|
||||
$dotenv = Dotenv::createImmutable($envPath);
|
||||
$dotenv->load();
|
||||
} catch (Exception $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore caricamento .env: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore caricamento configurazione: ' . $e->getMessage()]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Recupera le variabili d'ambiente
|
||||
$dbHost = $_ENV['DB_HOST'];
|
||||
$dbName = $_ENV['DB_DATABASE'];
|
||||
$dbUser = $_ENV['DB_USERNAME'];
|
||||
$dbPass = $_ENV['DB_PASSWORD'];
|
||||
$dbPrefix = $_ENV['DB_PREFIX'];
|
||||
|
||||
// Debug: Log database connection details (excluding password)
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . " - DB Connection: host=$dbHost, dbname=$dbName, user=$dbUser, prefix=$dbPrefix" . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Connessione al database MySQL
|
||||
try {
|
||||
$pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (PDOException $e) {
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore connessione DB: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore connessione al database: ' . $e->getMessage()]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
// Query per recuperare le matrici, includendo MacroMatrice, escludendo quelle che iniziano con '*' e ordinandole
|
||||
$query = "SELECT IdMatrice, NomeMatrice, MacroMatrice FROM {$dbPrefix}matrici WHERE NomeMatrice NOT LIKE '*%' ORDER BY NomeMatrice ASC";
|
||||
$stmt = $pdo->prepare($query);
|
||||
$stmt->execute();
|
||||
$matrici = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Debug: Log del numero di matrici recuperate
|
||||
file_put_contents(__DIR__ . '/debug_log.txt', date('Y-m-d H:i:s') . ' - Retrieved ' . count($matrici) . ' matrices from database' . PHP_EOL, FILE_APPEND);
|
||||
|
||||
// Restituisci risposta JSON
|
||||
echo json_encode(['success' => true, 'value' => $matrici]);
|
||||
} catch (PDOException $e) {
|
||||
// Log errore e restituisci risposta di errore
|
||||
file_put_contents(__DIR__ . '/error_log.txt', date('Y-m-d H:i:s') . ' - Errore nel recupero delle matrici: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
echo json_encode(['success' => false, 'message' => 'Errore nel recupero delle matrici: ' . $e->getMessage()]);
|
||||
exit(1);
|
||||
}
|
||||
@@ -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>';
|
||||
}
|
||||
@@ -9,7 +9,7 @@ error_reporting(E_ALL);
|
||||
|
||||
try {
|
||||
$api = VisualLimsApiClient::getInstance();
|
||||
$rapporto_id = 515081;
|
||||
$rapporto_id = 533329;
|
||||
|
||||
// Costruzione manuale dell'endpoint con espansione annidata
|
||||
$endpoint = "Rapporto($rapporto_id)?\$expand=CampioniDatiRapporto(\$expand=AnalisiDatiRapporto,CustomFieldsDatiRapporto)";
|
||||
|
||||
@@ -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,209 @@ 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>";
|
||||
}
|
||||
// Status (subito dopo main_field)
|
||||
$fixedColumnsReduced = ['status'];
|
||||
foreach ($fixedColumnsReduced as $col) {
|
||||
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 Import Reference Code, filename_import
|
||||
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 status (subito dopo main_field)
|
||||
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++;
|
||||
}
|
||||
// Header per campi automatici (escluso main_field)
|
||||
foreach ($allMappings as $mapping) {
|
||||
if (!$mapping['is_manual']) {
|
||||
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']) {
|
||||
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 Import Reference Code, filename_import
|
||||
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>
|
||||
<?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>
|
||||
<?php endif; ?>
|
||||
<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>
|
||||
</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) {
|
||||
$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++;
|
||||
}
|
||||
// Status (subito dopo main_field)
|
||||
$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 === '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') {
|
||||
if ($col === 'status') {
|
||||
$badgeClass = $value === 'i' ? 'status-i' : ($value === 'P' ? 'status-P' : 'status-l');
|
||||
$badgeText = $value === 'i' ? 'Imported' : ($value === 'P' ? 'Progress' : 'LIMS');
|
||||
// Aggiungi il numero di commessaweb se lo status è 'l'
|
||||
if ($value === 'l') {
|
||||
$commessaWeb = isset($row['commessaweb']) ? htmlspecialchars($row['commessaweb']) : '';
|
||||
$badgeText .= " ($commessaWeb)";
|
||||
}
|
||||
echo "<span class='status-badge $badgeClass'>" . htmlspecialchars($badgeText) . "</span>";
|
||||
echo "<input type='hidden' name='rows[$index][$col]' value='" . htmlspecialchars($value ?? 'i') . "'>";
|
||||
}
|
||||
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 +837,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 +852,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 +867,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 +882,18 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
$manualIndex++;
|
||||
}
|
||||
}
|
||||
// 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 +929,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 +953,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 +988,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 +1032,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 +1071,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 +1092,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 +1106,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 +1120,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 +1242,80 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
||||
async function populateDropdowns() {
|
||||
if (<?= json_encode($is_readonly) ?>) return;
|
||||
const dropdowns = document.querySelectorAll('.dropdown-select');
|
||||
if (dropdowns.length === 0) return;
|
||||
const uniqueFieldIds = [...new Set(Array.from(dropdowns).map(d => d.getAttribute('data-field-id')))].filter(fieldId => fieldId);
|
||||
for (const fieldId of uniqueFieldIds) {
|
||||
if (!dropdownData[fieldId]) {
|
||||
try {
|
||||
const response = await fetch(`get_customfield_values.php?field_id=${fieldId}`);
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
console.error('Errore per field_id', fieldId, ':', data.error);
|
||||
continue;
|
||||
}
|
||||
dropdownData[fieldId] = data.CustomFieldsValues || [];
|
||||
} catch (error) {
|
||||
console.error('Errore nel fetch per field_id', fieldId, ':', error);
|
||||
}
|
||||
}
|
||||
console.log('Dropdown trovati:', dropdowns.length);
|
||||
if (dropdowns.length === 0) {
|
||||
console.warn('Nessun dropdown trovato con classe .dropdown-select');
|
||||
return;
|
||||
}
|
||||
dropdowns.forEach(dropdown => {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
if (!fieldId || !dropdownData[fieldId]) {
|
||||
dropdown.innerHTML = '<option value="">Errore nel caricamento</option>';
|
||||
|
||||
const uniqueFieldIds = [...new Set(Array.from(dropdowns).map(d => d.getAttribute('data-field-id')))].filter(fieldId => fieldId);
|
||||
console.log('Field IDs unici:', uniqueFieldIds);
|
||||
const missingFieldIds = uniqueFieldIds.filter(fieldId => !dropdownData[fieldId]);
|
||||
|
||||
if (missingFieldIds.length > 0) {
|
||||
try {
|
||||
const response = await fetch(`get_customfield_values.php?field_ids=${missingFieldIds.join(',')}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Errore HTTP: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
console.log('Risposta da get_customfield_values.php:', data);
|
||||
|
||||
if (data.error) {
|
||||
console.error('Errore dal server:', data.error);
|
||||
dropdowns.forEach(dropdown => {
|
||||
dropdown.innerHTML = '<option value="">Errore server</option>';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
for (const fieldId of Object.keys(data)) {
|
||||
dropdownData[fieldId] = data[fieldId] || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Errore nel fetch dei valori dei dropdown:', error);
|
||||
dropdowns.forEach(dropdown => {
|
||||
dropdown.innerHTML = '<option value="">Errore caricamento</option>';
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dropdowns.forEach(dropdown => {
|
||||
const fieldId = dropdown.getAttribute('data-field-id');
|
||||
const mappingId = dropdown.getAttribute('data-mapping-id');
|
||||
const selectedValue = dropdown.getAttribute('data-selected-value') || '';
|
||||
const currentValue = dropdown.value || '';
|
||||
console.log(`Popolamento dropdown field_id=${fieldId}, mapping_id=${mappingId}, valore corrente=${currentValue}, valore selezionato=${selectedValue}`);
|
||||
|
||||
if (!fieldId || !dropdownData[fieldId]) {
|
||||
dropdown.innerHTML = '<option value="">Nessun dato</option>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Preserva il valore corrente o usa quello salvato
|
||||
dropdown.innerHTML = '<option value="">Seleziona...</option>';
|
||||
dropdownData[fieldId].forEach(value => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value.IdCustomFieldsValue;
|
||||
option.textContent = value.Valore;
|
||||
if (dropdown.value === option.value) option.selected = true;
|
||||
// Dai priorità a data-selected-value per il caricamento iniziale
|
||||
if (selectedValue === String(value.IdCustomFieldsValue)) {
|
||||
option.selected = true;
|
||||
} else if (currentValue === String(value.IdCustomFieldsValue)) {
|
||||
option.selected = true;
|
||||
}
|
||||
dropdown.appendChild(option);
|
||||
});
|
||||
|
||||
// Verifica se il valore selezionato esiste tra le opzioni
|
||||
if ((selectedValue || currentValue) && dropdown.value !== (selectedValue || currentValue)) {
|
||||
dropdown.value = '';
|
||||
console.warn(`Valore ${selectedValue || currentValue} non trovato per fieldId ${fieldId}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
populateDropdowns();
|
||||
saveButtons.forEach(btn => {
|
||||
btn.addEventListener('click', function() {
|
||||
if (!this.hasAttribute('disabled')) {
|
||||
setTimeout(populateDropdowns, 100);
|
||||
}
|
||||
});
|
||||
});
|
||||
<?php endif; ?>
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
<?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 = array_map('intval', $_POST['selected_rows']);
|
||||
$columns = json_decode($_POST['columns'], true);
|
||||
$rows = json_decode($_POST['rows'], true);
|
||||
$excelrows = json_decode($_POST['excelrows'], true);
|
||||
$newFilename = htmlspecialchars($_POST['filename']);
|
||||
|
||||
$_SESSION['template_id'] = $template_id;
|
||||
$_SESSION['selected_rows'] = $selected_rows;
|
||||
$_SESSION['columns'] = $columns;
|
||||
$_SESSION['rows'] = $rows;
|
||||
$_SESSION['excelrows'] = $excelrows;
|
||||
$_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));
|
||||
error_log("Excelrows: " . json_encode($excelrows));
|
||||
|
||||
$user_id = $iduserlogin ?? 1;
|
||||
|
||||
$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
|
||||
$insertedIds = [];
|
||||
foreach ($selected_rows as $rowIndex) {
|
||||
$row = $rows[$rowIndex] ?? null;
|
||||
$excelrow = $excelrows[$rowIndex] ?? null;
|
||||
|
||||
if ($row === null || $excelrow === null) {
|
||||
error_log("Errore: riga o excelrow mancante per rowIndex $rowIndex");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Recupera l'idclient di default dal template
|
||||
$template_stmt = $pdo->prepare("SELECT idclient FROM excel_templates WHERE id = ?");
|
||||
$template_stmt->execute([$template_id]);
|
||||
$template = $template_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$default_idclient = $template['idclient'] ?? null;
|
||||
|
||||
$values = [
|
||||
$template_id,
|
||||
$importReferenceCode,
|
||||
$newFilename,
|
||||
'i',
|
||||
$user_id,
|
||||
null,
|
||||
date('Y-m-d'),
|
||||
$excelrow,
|
||||
$default_idclient // Aggiungi idclient
|
||||
];
|
||||
$sql = "INSERT INTO datadb (templateid, importreferencecode, filename_import, status, user_id, limscode, importdate, excelrow, idclient) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute($values);
|
||||
|
||||
$iddatadb = $pdo->lastInsertId();
|
||||
$insertedIds[] = $iddatadb;
|
||||
|
||||
// Inserisci tutti i campi in import_data_details
|
||||
foreach ($allMappings as $mapping) {
|
||||
$fieldValue = null;
|
||||
if (!$mapping['is_manual']) {
|
||||
$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 {
|
||||
$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) ?>'>
|
||||
<input type="hidden" name="excelrows" value='<?= json_encode($excelrows) ?>'>
|
||||
</form>
|
||||
<script>
|
||||
document.getElementById('redirectForm').submit();
|
||||
</script>
|
||||
<?php
|
||||
exit;
|
||||
?>
|
||||
@@ -21,6 +21,11 @@ if (!$template) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verifica i mapping
|
||||
$stmt = $pdo->prepare("SELECT id FROM template_mapping WHERE template_id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$hasMappings = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// Debug del template
|
||||
error_log("Loaded template: " . print_r($template, true));
|
||||
?>
|
||||
@@ -33,6 +38,7 @@ error_log("Loaded template: " . print_r($template, true));
|
||||
<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 href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
@@ -140,43 +146,55 @@ error_log("Loaded template: " . print_r($template, true));
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<!-- Form per caricare il file -->
|
||||
<?php if (!$hasMappings): ?>
|
||||
<div class="alert alert-warning" role="alert">
|
||||
Nessun mapping trovato per questo template. Configura i mapping prima di procedere.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<form id="uploadForm" enctype="multipart/form-data" class="mb-4">
|
||||
<div class="mb-3">
|
||||
<label for="excel_file" class="form-label">Upload XLS File</label>
|
||||
<input type="file" class="form-control" id="excel_file" name="excel_file" accept=".xls,.xlsx" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Upload</button>
|
||||
<button type="submit" class="btn btn-primary" <?= !$hasMappings ? 'disabled' : '' ?>>Upload</button>
|
||||
<div class="loader" id="loader"></div>
|
||||
</form>
|
||||
|
||||
<!-- Contenitore per messaggi di errore -->
|
||||
<div id="errorContainer" class="alert alert-danger mt-3" style="display: none;"></div>
|
||||
|
||||
<!-- Contenitore per la tabella -->
|
||||
<div id="tableContainer"></div>
|
||||
|
||||
<div class="modal fade" id="routineConfirmModal" tabindex="-1" aria-labelledby="routineConfirmModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="routineConfirmModalLabel">Conferma Applicazione Routine</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><strong>Routine:</strong> <span id="routineName"></span></p>
|
||||
<p><strong>Descrizione:</strong> <span id="routineDescription"></span></p>
|
||||
<p>Vuoi applicare questa routine al file caricato?</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="cancelRoutineBtn">Annulla</button>
|
||||
<button type="button" class="btn btn-primary" id="confirmRoutineBtn">Applica</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end page wrapper -->
|
||||
<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>
|
||||
<!--end wrapper-->
|
||||
|
||||
<!-- search modal -->
|
||||
<?php //include('include/searchmodal.php');
|
||||
?>
|
||||
<!-- end search modal -->
|
||||
|
||||
<!--start switcher-->
|
||||
<?php //include('include/themeswitcher.php');
|
||||
?>
|
||||
<!--end switcher-->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.min.js"></script>
|
||||
<?php include('jsinclude.php'); ?>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
@@ -184,6 +202,12 @@ error_log("Loaded template: " . print_r($template, true));
|
||||
const loader = document.getElementById('loader');
|
||||
const errorContainer = document.getElementById('errorContainer');
|
||||
const tableContainer = document.getElementById('tableContainer');
|
||||
const routineModal = new bootstrap.Modal(document.getElementById('routineConfirmModal'));
|
||||
const confirmRoutineBtn = document.getElementById('confirmRoutineBtn');
|
||||
const cancelRoutineBtn = document.getElementById('cancelRoutineBtn');
|
||||
let routineData = null;
|
||||
let excelData = null;
|
||||
let responseData = null;
|
||||
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
@@ -202,131 +226,186 @@ error_log("Loaded template: " . print_r($template, true));
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
console.log('Stato risposta:', response.status);
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Risposta JSON:', data);
|
||||
loader.style.display = 'none';
|
||||
if (data.error) {
|
||||
errorContainer.textContent = data.error;
|
||||
errorContainer.style.display = 'block';
|
||||
} else if (data.apply_routine) {
|
||||
console.log('Routine rilevata:', data.routine_data);
|
||||
routineData = data.routine_data;
|
||||
excelData = data.excel_data;
|
||||
responseData = data;
|
||||
document.getElementById('routineName').textContent = routineData.name || 'Sconosciuta';
|
||||
document.getElementById('routineDescription').textContent = routineData.instruction || 'Nessuna descrizione';
|
||||
routineModal.show();
|
||||
} else {
|
||||
let html = `
|
||||
<form id="selectRowsForm" action="import_edit2.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)}'>
|
||||
<input type="hidden" name="filename" value="${data.filename}">
|
||||
<div class="search-container">
|
||||
<input type="text" id="searchInput" class="form-control" placeholder="Cerca nelle righe...">
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="selectAll"> Seleziona</th>
|
||||
${data.columns.map(col => `<th>${col || 'Colonna senza nome'}<div class="resize-handle"></div></th>`).join('')}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${data.rows.map((row, index) => `
|
||||
<tr>
|
||||
<td><input type="checkbox" class="row-checkbox" name="selected_rows[]" value="${index}"></td>
|
||||
${row.map(cell => `<td>${cell}</td>`).join('')}
|
||||
</tr>
|
||||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-3" id="proceedButton" disabled>Prosegui</button>
|
||||
</form>
|
||||
`;
|
||||
tableContainer.innerHTML = html;
|
||||
|
||||
// Inizializza le variabili dopo aver inserito la tabella
|
||||
const proceedButton = document.getElementById('proceedButton');
|
||||
const selectAllCheckbox = document.getElementById('selectAll');
|
||||
const checkboxes = document.querySelectorAll('.row-checkbox');
|
||||
|
||||
// Funzione per aggiornare lo stato del pulsante Prosegui
|
||||
function updateProceedButton() {
|
||||
proceedButton.disabled = !Array.from(checkboxes).some(cb => cb.checked);
|
||||
}
|
||||
|
||||
// Event listener per il checkbox "Seleziona tutto"
|
||||
selectAllCheckbox.addEventListener('change', function() {
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = this.checked;
|
||||
});
|
||||
updateProceedButton();
|
||||
});
|
||||
|
||||
// Event listener per i checkbox delle righe
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function() {
|
||||
console.log('Checkbox changed, checked: ', this.checked); // Debug
|
||||
// Aggiorna lo stato del checkbox "Seleziona tutto"
|
||||
selectAllCheckbox.checked = Array.from(checkboxes).every(cb => cb.checked);
|
||||
updateProceedButton();
|
||||
});
|
||||
});
|
||||
|
||||
// Aggiungi logica per il ridimensionamento delle colonne
|
||||
const thElements = document.querySelectorAll('.table th');
|
||||
thElements.forEach((th, index) => {
|
||||
if (index === 0) return;
|
||||
const resizeHandle = th.querySelector('.resize-handle');
|
||||
if (resizeHandle) {
|
||||
resizeHandle.addEventListener('mousedown', (e) => {
|
||||
e.preventDefault();
|
||||
const startX = e.clientX;
|
||||
const startWidth = th.offsetWidth;
|
||||
|
||||
const onMouseMove = (e) => {
|
||||
const newWidth = Math.max(50, startWidth + (e.clientX - startX));
|
||||
th.style.width = `${newWidth}px`;
|
||||
th.style.minWidth = `${newWidth}px`;
|
||||
th.style.maxWidth = `${newWidth}px`;
|
||||
|
||||
const cells = document.querySelectorAll(`.table td:nth-child(${index + 1})`);
|
||||
cells.forEach(cell => {
|
||||
cell.style.width = `${newWidth}px`;
|
||||
cell.style.minWidth = `${newWidth}px`;
|
||||
cell.style.maxWidth = `${newWidth}px`;
|
||||
});
|
||||
};
|
||||
|
||||
const onMouseUp = () => {
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
document.removeEventListener('mouseup', onMouseUp);
|
||||
};
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Aggiungi event listener per la ricerca
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
const rows = document.querySelectorAll('.table tbody tr');
|
||||
|
||||
searchInput.addEventListener('input', function() {
|
||||
const searchTerm = this.value.toLowerCase();
|
||||
rows.forEach(row => {
|
||||
const text = Array.from(row.cells).slice(1).map(cell => cell.textContent.toLowerCase()).join(' ');
|
||||
row.style.display = text.includes(searchTerm) ? '' : 'none';
|
||||
});
|
||||
});
|
||||
|
||||
// Abilita il pulsante se ci sono checkbox selezionate all'inizio
|
||||
updateProceedButton();
|
||||
console.log('Nessuna routine, procedo con tabella');
|
||||
showTable(data);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('Errore fetch:', error);
|
||||
loader.style.display = 'none';
|
||||
errorContainer.textContent = 'Errore durante il caricamento del file: ' + error.message;
|
||||
errorContainer.style.display = 'block';
|
||||
});
|
||||
});
|
||||
|
||||
confirmRoutineBtn.addEventListener('click', function() {
|
||||
console.log('Conferma routine:', routineData);
|
||||
routineModal.hide();
|
||||
|
||||
fetch('apply_routine.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
template_id: <?= $id ?>,
|
||||
filename: routineData.filename,
|
||||
headerrow: routineData.headerrow,
|
||||
excel_data: excelData,
|
||||
routine_data: routineData
|
||||
})
|
||||
})
|
||||
.then(response => {
|
||||
console.log('Stato apply_routine:', response.status);
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Risposta apply_routine:', data);
|
||||
if (data.error) {
|
||||
errorContainer.textContent = data.error;
|
||||
errorContainer.style.display = 'block';
|
||||
} else {
|
||||
showTable(data);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('Errore apply_routine:', error);
|
||||
errorContainer.textContent = 'Errore durante l\'applicazione della routine: ' + error.message;
|
||||
errorContainer.style.display = 'block';
|
||||
});
|
||||
});
|
||||
|
||||
cancelRoutineBtn.addEventListener('click', function() {
|
||||
console.log('Routine annullata, procedo con tabella');
|
||||
routineModal.hide();
|
||||
showTable(responseData);
|
||||
});
|
||||
|
||||
function showTable(data) {
|
||||
console.log('Mostro tabella con dati:', data);
|
||||
let html = `
|
||||
<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)}'>
|
||||
<input type="hidden" name="excelrows" value='${JSON.stringify(data.excel_data.map(row => row.excelrow))}'>
|
||||
<input type="hidden" name="filename" value="${data.filename}">
|
||||
<div class="search-container">
|
||||
<input type="text" id="searchInput" class="form-control" placeholder="Cerca nelle righe...">
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="selectAll"> Seleziona</th>
|
||||
${data.columns.map(col => `<th>${col || 'Colonna senza nome'}<div class="resize-handle"></div></th>`).join('')}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${data.excel_data.map((row, index) => `
|
||||
<tr>
|
||||
<td><input type="checkbox" class="row-checkbox" name="selected_rows[]" value="${index}" data-excelrow="${row.excelrow}"></td>
|
||||
${row.data.map(cell => `<td>${cell}</td>`).join('')}
|
||||
</tr>
|
||||
`).join('')}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-3" id="proceedButton" disabled>Prosegui</button>
|
||||
</form>
|
||||
`;
|
||||
tableContainer.innerHTML = html;
|
||||
|
||||
const proceedButton = document.getElementById('proceedButton');
|
||||
const selectAllCheckbox = document.getElementById('selectAll');
|
||||
const checkboxes = document.querySelectorAll('.row-checkbox');
|
||||
|
||||
function updateProceedButton() {
|
||||
proceedButton.disabled = !Array.from(checkboxes).some(cb => cb.checked);
|
||||
}
|
||||
|
||||
selectAllCheckbox.addEventListener('change', function() {
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.checked = this.checked;
|
||||
});
|
||||
updateProceedButton();
|
||||
});
|
||||
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function() {
|
||||
console.log('Checkbox changed, checked:', this.checked, 'excelrow:', this.dataset.excelrow);
|
||||
selectAllCheckbox.checked = Array.from(checkboxes).every(cb => cb.checked);
|
||||
updateProceedButton();
|
||||
});
|
||||
});
|
||||
|
||||
const thElements = document.querySelectorAll('.table th');
|
||||
thElements.forEach((th, index) => {
|
||||
if (index === 0) return;
|
||||
const resizeHandle = th.querySelector('.resize-handle');
|
||||
if (resizeHandle) {
|
||||
resizeHandle.addEventListener('mousedown', (e) => {
|
||||
e.preventDefault();
|
||||
const startX = e.clientX;
|
||||
const startWidth = th.offsetWidth;
|
||||
|
||||
const onMouseMove = (e) => {
|
||||
const newWidth = Math.max(50, startWidth + (e.clientX - startX));
|
||||
th.style.width = `${newWidth}px`;
|
||||
th.style.minWidth = `${newWidth}px`;
|
||||
th.style.maxWidth = `${newWidth}px`;
|
||||
|
||||
const cells = document.querySelectorAll(`.table td:nth-child(${index + 1})`);
|
||||
cells.forEach(cell => {
|
||||
cell.style.width = `${newWidth}px`;
|
||||
cell.style.minWidth = `${newWidth}px`;
|
||||
cell.style.maxWidth = `${newWidth}px`;
|
||||
});
|
||||
};
|
||||
|
||||
const onMouseUp = () => {
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
document.removeEventListener('mouseup', onMouseUp);
|
||||
};
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
const rows = document.querySelectorAll('.table tbody tr');
|
||||
|
||||
searchInput.addEventListener('input', function() {
|
||||
const searchTerm = this.value.toLowerCase();
|
||||
rows.forEach(row => {
|
||||
const text = Array.from(row.cells).slice(1).map(cell => cell.textContent.toLowerCase()).join(' ');
|
||||
row.style.display = text.includes(searchTerm) ? '' : 'none';
|
||||
});
|
||||
});
|
||||
|
||||
updateProceedButton();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/../class/db-functions.php');
|
||||
|
||||
$db = DBHandlerSelect::getInstance()->getConnection();
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
|
||||
// Inizializza la sessione
|
||||
if (session_status() == PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Imposta variabili di sessione di default per evitare errori
|
||||
$_SESSION['iduserlogin'] = '1'; // Nessun utente loggato
|
||||
$_SESSION['nameuser'] = 'Ospite';
|
||||
$_SESSION['surnameuser'] = '';
|
||||
$_SESSION['emailuser'] = '';
|
||||
$_SESSION['photouser'] = '';
|
||||
$photouser = $_SESSION['photouser'];
|
||||
$photousername = '';
|
||||
$iduserlogin = $_SESSION['iduserlogin'];
|
||||
// Include file di lingua, se necessario
|
||||
require_once(__DIR__ . '/../../languages/en/general.php');
|
||||
@@ -41,7 +41,21 @@
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>-->
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" class="has-arrow">
|
||||
<div class="parent-icon"><i class="bx bx-category"></i>
|
||||
</div>
|
||||
<div class="menu-title">Other Functions</div>
|
||||
</a>
|
||||
<ul>
|
||||
<li> <a href="quotations.php"><i class='bx bx-radio-circle'></i><?php echo $quotationstitle; ?></a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
<?php include('include/headscript.php'); ?>
|
||||
<?php include('include/headscript.php');
|
||||
|
||||
// Recupera tutte le routine dal database
|
||||
$db = DBHandlerSelect::getInstance();
|
||||
$pdo = $db->getConnection();
|
||||
$stmt = $pdo->prepare("SELECT * FROM routine");
|
||||
$stmt->execute();
|
||||
$routines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
?>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!--favicon-->
|
||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
||||
<?php include('cssinclude.php'); ?>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<title>Insert XLS Template <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--wrapper-->
|
||||
<div class="wrapper">
|
||||
<!--sidebar wrapper -->
|
||||
<?php include('include/navbar.php'); ?>
|
||||
<!--end sidebar wrapper -->
|
||||
<!--start header -->
|
||||
<?php include('include/topbar.php'); ?>
|
||||
<!--end header -->
|
||||
<!--start page wrapper -->
|
||||
<div class="page-wrapper">
|
||||
<div class="page-content">
|
||||
<div class="card mb-4">
|
||||
@@ -35,7 +37,7 @@
|
||||
<ul class="mb-0">
|
||||
<li>Template Name</li>
|
||||
<li>Row Header and Column Header: where the title of the excel starts</li>
|
||||
<li>Scheme and client</li>
|
||||
<li>Schema and client</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -73,7 +75,6 @@
|
||||
|
||||
<input type="hidden" name="target_table" value="datadb">
|
||||
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Button Size</label>
|
||||
<select name="button_size" class="form-control">
|
||||
@@ -97,7 +98,7 @@
|
||||
<label class="form-label">Button Label</label>
|
||||
<input type="text" name="button_label" class="form-control" value="Click Me">
|
||||
</div>
|
||||
<!-- Aggiungi il campo per selezionare il cliente -->
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Select Client *</label>
|
||||
<select name="client_id" id="clientSelect" class="form-control" required>
|
||||
@@ -105,68 +106,33 @@
|
||||
</select>
|
||||
<span id="clientLoadingStatus" class="text-muted" style="margin-left: 10px; display: none;">Recupero clienti in corso...</span>
|
||||
</div>
|
||||
<!-- Aggiungi il campo per selezionare lo schema -->
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Select Schema *</label>
|
||||
<select name="schema_id" id="schemaSelect" class="form-control" required>
|
||||
<option value="">Select a schema...</option>
|
||||
</select>
|
||||
<span id="schemaLoadingStatus" class="text-muted" style="margin-left: 10px; display: none;">Loading schemas...</span>
|
||||
<span id="schemaLoadingStatus" class="text-muted" style="margin-left: 10px; display: none;">Caricamento schemi in corso...</span>
|
||||
</div>
|
||||
|
||||
<!-- new section for specific client field -->
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Client-Specific Fields</label>
|
||||
|
||||
<!-- Intestazioni -->
|
||||
<div class="row fw-bold text-secondary mb-1">
|
||||
<div class="col-md-3">Field Name</div>
|
||||
<div class="col-md-2">Type</div>
|
||||
<div class="col-md-2 dropdown-values">Possible Values</div>
|
||||
<div class="col-md-1">Required</div>
|
||||
<div class="col-md-2">Export Column Name</div>
|
||||
<div class="col-md-1">Default Value</div>
|
||||
<div class="col-md-1">Actions</div>
|
||||
<label class="form-label">Select Routine</label>
|
||||
<select name="idroutine" id="routineSelect" class="form-control">
|
||||
<option value="">Select a routine...</option>
|
||||
<?php foreach ($routines as $routine): ?>
|
||||
<option value="<?php echo $routine['idroutine']; ?>">
|
||||
<?php echo htmlspecialchars($routine['name']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div id="routineDetails" class="mt-2" style="display: none;">
|
||||
<h6>Routine Details</h6>
|
||||
<p><strong>Name:</strong> <span id="routineName"></span></p>
|
||||
<p><strong>Description:</strong> <span id="routineDescription"></span></p>
|
||||
<p><strong>Action 1:</strong> <span id="routineAction1"></span></p>
|
||||
<p><strong>Action 2:</strong> <span id="routineAction2"></span></p>
|
||||
<p><strong>Action 3:</strong> <span id="routineAction3"></span></p>
|
||||
</div>
|
||||
|
||||
<div id="clientSpecificFields">
|
||||
<!-- Contenitore per i campi dinamici -->
|
||||
<div class="client-field-row mb-2">
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="specific_fields[0][name]" class="form-control" placeholder="Field Name (e.g., SKU)">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select name="specific_fields[0][type]" class="form-control" onchange="toggleDropdownValues(this)">
|
||||
<option value="text">Text</option>
|
||||
<option value="dropdown">Dropdown</option>
|
||||
<option value="date">Date</option>
|
||||
<option value="boolean">Yes/No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2 dropdown-values" style="visibility: hidden;">
|
||||
<input type="text" name="specific_fields[0][possible_values]" class="form-control" placeholder="Values (e.g., Red, Blue, Green)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<select name="specific_fields[0][required]" class="form-control">
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="specific_fields[0][export_column_name]" class="form-control" placeholder="Export Column Name (e.g., MONCLER_SKU)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<input type="text" name="specific_fields[0][default_value]" class="form-control" placeholder="Default Value (optional)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-danger remove-field">-</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary mt-2" id="addField">Add Field</button>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
@@ -178,125 +144,72 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--end page wrapper -->
|
||||
<!--start overlay-->
|
||||
<div class="overlay toggle-icon"></div>
|
||||
<!--end overlay-->
|
||||
<!--Start Back To Top Button-->
|
||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
||||
<!--End Back To Top Button-->
|
||||
<?php include('include/footer.php'); ?>
|
||||
</div>
|
||||
<!--end wrapper-->
|
||||
|
||||
<!-- search modal -->
|
||||
<?php //include('include/searchmodal.php');
|
||||
?>
|
||||
<!-- end search modal -->
|
||||
|
||||
<!--start switcher-->
|
||||
<?php //include('include/themeswitcher.php');
|
||||
?>
|
||||
<!--end switcher-->
|
||||
|
||||
<!-- Includi Select2 JS -->
|
||||
|
||||
<?php include('jsinclude.php'); ?>
|
||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||
<script>
|
||||
// Debug iniziale
|
||||
console.log("JavaScript is loaded and running!");
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
console.log("DOM is loaded");
|
||||
if (typeof jQuery === 'undefined') {
|
||||
alert("Errore: jQuery non è caricato. Contatta l'amministratore.");
|
||||
return;
|
||||
}
|
||||
|
||||
const form = document.getElementById("insertTemplateForm");
|
||||
const addFieldButton = document.getElementById("addField");
|
||||
const container = document.getElementById("clientSpecificFields");
|
||||
const clientLoadingStatus = document.getElementById("clientLoadingStatus");
|
||||
const schemaLoadingStatus = document.getElementById("schemaLoadingStatus");
|
||||
const routineSelect = document.getElementById("routineSelect");
|
||||
const routineDetails = document.getElementById("routineDetails");
|
||||
const routineName = document.getElementById("routineName");
|
||||
const routineDescription = document.getElementById("routineDescription");
|
||||
const routineAction1 = document.getElementById("routineAction1");
|
||||
const routineAction2 = document.getElementById("routineAction2");
|
||||
const routineAction3 = document.getElementById("routineAction3");
|
||||
|
||||
if (!form || !addFieldButton || !container || !clientLoadingStatus || !schemaLoadingStatus) {
|
||||
console.error("One or more DOM elements not found:", {
|
||||
form,
|
||||
addFieldButton,
|
||||
container,
|
||||
clientLoadingStatus,
|
||||
schemaLoadingStatus
|
||||
});
|
||||
if (!form || !clientLoadingStatus || !schemaLoadingStatus || !routineSelect || !routineDetails) {
|
||||
alert("Errore: Uno o più elementi della pagina non sono stati trovati. Contatta l'amministratore.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("All DOM elements found");
|
||||
|
||||
// Controllo che jQuery sia caricato
|
||||
if (typeof jQuery === 'undefined') {
|
||||
console.error("jQuery non è caricato!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Inizializza Select2 sulla tendina dei clienti
|
||||
$('#clientSelect').select2({
|
||||
placeholder: "Search for a client...",
|
||||
allowClear: true
|
||||
}).on('select2:open', function() {
|
||||
console.log("Select2 initialized successfully for clientSelect");
|
||||
}).on('select2:select', function(e) {
|
||||
console.log("Client selected:", e.params.data.id, e.params.data.text);
|
||||
});
|
||||
|
||||
// Inizializza Select2 sulla tendina degli schemi
|
||||
$('#schemaSelect').select2({
|
||||
placeholder: "Search for a schema...",
|
||||
allowClear: true
|
||||
}).on('select2:open', function() {
|
||||
console.log("Select2 initialized successfully for schemaSelect");
|
||||
});
|
||||
|
||||
// Funzione per caricare i clienti
|
||||
$('#routineSelect').select2({
|
||||
placeholder: "Select a routine...",
|
||||
allowClear: true
|
||||
});
|
||||
|
||||
async function loadClients() {
|
||||
try {
|
||||
clientLoadingStatus.style.display = 'inline';
|
||||
clientLoadingStatus.textContent = 'Recupero clienti in corso...';
|
||||
|
||||
const response = await fetch("get_clienti.php", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
console.log("Risposta raw (clienti):", text);
|
||||
const data = JSON.parse(text);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || `Errore HTTP: ${response.status}, Dettagli: ${JSON.stringify(data)}`);
|
||||
}
|
||||
|
||||
if (data.value && Array.isArray(data.value)) {
|
||||
const select = document.getElementById("clientSelect");
|
||||
select.innerHTML = '<option value="">Select a client...</option>';
|
||||
data.value.forEach(client => {
|
||||
const nome = client.Nominativo || "Nome non disponibile";
|
||||
const id = client.IdCliente || "ID non disponibile";
|
||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
||||
select.add(option);
|
||||
});
|
||||
console.log("Clienti caricati con successo.");
|
||||
clientLoadingStatus.textContent = "Clienti caricati.";
|
||||
} else {
|
||||
console.error("Nessun cliente trovato o formato dati non valido.", data);
|
||||
clientLoadingStatus.textContent = "Nessun cliente trovato.";
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Nessun cliente trovato o formato dati non valido.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
}
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.error || `Errore HTTP: ${response.status}`);
|
||||
const select = document.getElementById("clientSelect");
|
||||
select.innerHTML = '<option value="">Select a client...</option>';
|
||||
data.value.forEach(client => {
|
||||
const nome = client.Nominativo || "Nome non disponibile";
|
||||
const id = client.IdCliente || "ID non disponibile";
|
||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
||||
select.add(option);
|
||||
});
|
||||
$(select).trigger('change');
|
||||
clientLoadingStatus.textContent = "Clienti caricati.";
|
||||
} catch (error) {
|
||||
console.error("Errore nel caricamento dei clienti:", error);
|
||||
clientLoadingStatus.textContent = "Errore nel caricamento.";
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
@@ -305,175 +218,110 @@
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => {
|
||||
clientLoadingStatus.style.display = 'none';
|
||||
}, 2000);
|
||||
setTimeout(() => clientLoadingStatus.style.display = 'none', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Funzione per caricare gli schemi con ritentativi
|
||||
async function loadSchemas() {
|
||||
const maxRetries = 3;
|
||||
let attempt = 0;
|
||||
|
||||
while (attempt < maxRetries) {
|
||||
try {
|
||||
schemaLoadingStatus.style.display = 'inline';
|
||||
schemaLoadingStatus.textContent = 'Caricamento schemi in corso...';
|
||||
|
||||
const response = await fetch("get_schemi.php", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
const text = await response.text();
|
||||
console.log("Risposta raw (schemi):", text);
|
||||
const data = JSON.parse(text);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.error || `Errore HTTP: ${response.status}, Dettagli: ${JSON.stringify(data)}`);
|
||||
try {
|
||||
schemaLoadingStatus.style.display = 'inline';
|
||||
schemaLoadingStatus.textContent = 'Caricamento schemi in corso...';
|
||||
const response = await fetch("get_schemi.php", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
const select = document.getElementById("schemaSelect");
|
||||
select.innerHTML = '<option value="">Select a schema...</option>';
|
||||
data.value.forEach(schema => { // Nota: usa data.value per coerenza con il JSON restituito
|
||||
const option = new Option(`${schema.Nome} (ID: ${schema.IdSchemaCustomFields})`, schema.IdSchemaCustomFields);
|
||||
select.add(option);
|
||||
});
|
||||
|
||||
schemaLoadingStatus.textContent = "Schemi caricati.";
|
||||
break; // Esci dal ciclo se la chiamata ha successo
|
||||
} catch (error) {
|
||||
attempt++;
|
||||
console.error(`Tentativo ${attempt} fallito per schemi:`, error);
|
||||
if (attempt === maxRetries) {
|
||||
console.error("Errore finale nel caricamento degli schemi:", error);
|
||||
schemaLoadingStatus.textContent = "Errore nel caricamento.";
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Impossibile caricare gli schemi: " + error.message,
|
||||
icon: "error",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
} else {
|
||||
// Ritardo prima di riprovare
|
||||
await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
|
||||
}
|
||||
} finally {
|
||||
if (attempt === maxRetries || schemaLoadingStatus.textContent === "Schemi caricati.") {
|
||||
setTimeout(() => {
|
||||
schemaLoadingStatus.style.display = 'none';
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
if (!response.ok) throw new Error(data.error || `Errore HTTP: ${response.status}`);
|
||||
const select = document.getElementById("schemaSelect");
|
||||
select.innerHTML = '<option value="">Select a schema...</option>';
|
||||
data.value.forEach(schema => {
|
||||
const nome = schema.Nome || "Nome non disponibile";
|
||||
const id = schema.IdSchemaCustomFields || "ID non disponibile";
|
||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
||||
select.add(option);
|
||||
});
|
||||
$(select).trigger('change');
|
||||
schemaLoadingStatus.textContent = "Schemi caricati.";
|
||||
} catch (error) {
|
||||
schemaLoadingStatus.textContent = "Errore nel caricamento.";
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Impossibile caricare gli schemi: " + error.message,
|
||||
icon: "error",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
} finally {
|
||||
setTimeout(() => schemaLoadingStatus.style.display = 'none', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Funzione combinata per caricare i dati in sequenza
|
||||
async function loadData() {
|
||||
try {
|
||||
await loadClients(); // Carica prima i clienti
|
||||
await loadSchemas(); // Poi carica gli schemi
|
||||
await loadClients();
|
||||
await loadSchemas();
|
||||
} catch (error) {
|
||||
console.error("Errore nel caricamento dei dati:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Avvia il caricamento dei dati
|
||||
loadData();
|
||||
|
||||
// Gestione dinamica dei campi specifici
|
||||
addFieldButton.addEventListener("click", function() {
|
||||
console.log("Add Field button clicked");
|
||||
const fieldCount = container.getElementsByClassName("client-field-row").length;
|
||||
const newField = document.createElement("div");
|
||||
newField.className = "client-field-row mb-2";
|
||||
newField.innerHTML = `
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="specific_fields[${fieldCount}][name]" class="form-control" placeholder="Field Name (e.g., SKU)">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select name="specific_fields[${fieldCount}][type]" class="form-control" onchange="toggleDropdownValues(this)">
|
||||
<option value="text">Text</option>
|
||||
<option value="dropdown">Dropdown</option>
|
||||
<option value="date">Date</option>
|
||||
<option value="boolean">Yes/No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2 dropdown-values" style="visibility: hidden;">
|
||||
<input type="text" name="specific_fields[${fieldCount}][possible_values]" class="form-control" placeholder="Values (e.g., Red, Blue, Green)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<select name="specific_fields[${fieldCount}][required]" class="form-control">
|
||||
<option value="1">Yes</option>
|
||||
<option value="0">No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<input type="text" name="specific_fields[${fieldCount}][export_column_name]" class="form-control" placeholder="Export Column Name (e.g., MONCLER_SKU)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<input type="text" name="specific_fields[${fieldCount}][default_value]" class="form-control" placeholder="Default Value (optional)">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-danger remove-field">-</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(newField);
|
||||
|
||||
newField.querySelector(".remove-field").addEventListener("click", function() {
|
||||
console.log("Remove Field button clicked");
|
||||
container.removeChild(newField);
|
||||
updateFieldIndices();
|
||||
});
|
||||
});
|
||||
|
||||
window.toggleDropdownValues = function(selectElement) {
|
||||
console.log("Toggling dropdown values for:", selectElement.value);
|
||||
const row = selectElement.closest(".row");
|
||||
const dropdownValues = row.querySelector(".dropdown-values");
|
||||
if (selectElement.value === "dropdown") {
|
||||
dropdownValues.style.visibility = "visible";
|
||||
} else {
|
||||
dropdownValues.style.visibility = "hidden";
|
||||
}
|
||||
};
|
||||
|
||||
document.querySelectorAll(".remove-field").forEach(button => {
|
||||
button.addEventListener("click", function() {
|
||||
console.log("Existing remove button clicked");
|
||||
const container = document.getElementById("clientSpecificFields");
|
||||
container.removeChild(button.closest(".client-field-row"));
|
||||
updateFieldIndices();
|
||||
});
|
||||
});
|
||||
|
||||
function updateFieldIndices() {
|
||||
console.log("Updating field indices");
|
||||
const rows = container.getElementsByClassName("client-field-row");
|
||||
for (let i = 0; i < rows.length; i++) {
|
||||
const inputs = rows[i].querySelectorAll("input, select");
|
||||
inputs.forEach(input => {
|
||||
const name = input.name.replace(/\[\d+\]/, `[${i}]`);
|
||||
input.name = name;
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Errore nel caricamento dei dati: " + error.message,
|
||||
icon: "error",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
}
|
||||
}
|
||||
loadData();
|
||||
|
||||
const routines = <?php echo json_encode($routines); ?>;
|
||||
|
||||
function updateRoutineDetails() {
|
||||
const selectedId = routineSelect.value;
|
||||
routineDetails.style.display = selectedId ? 'block' : 'none';
|
||||
if (selectedId) {
|
||||
const routine = routines.find(r => r.idroutine == selectedId);
|
||||
if (routine) {
|
||||
routineName.textContent = routine.name || 'N/A';
|
||||
routineDescription.textContent = routine.description || 'N/A';
|
||||
routineAction1.textContent = routine.action1 || 'N/A';
|
||||
routineAction2.textContent = routine.action2 || 'N/A';
|
||||
routineAction3.textContent = routine.action3 || 'N/A';
|
||||
} else {
|
||||
routineName.textContent = 'N/A';
|
||||
routineDescription.textContent = 'N/A';
|
||||
routineAction1.textContent = 'N/A';
|
||||
routineAction2.textContent = 'N/A';
|
||||
routineAction3.textContent = 'N/A';
|
||||
}
|
||||
} else {
|
||||
routineName.textContent = '';
|
||||
routineDescription.textContent = '';
|
||||
routineAction1.textContent = '';
|
||||
routineAction2.textContent = '';
|
||||
routineAction3.textContent = '';
|
||||
}
|
||||
}
|
||||
routineSelect.addEventListener('change', updateRoutineDetails);
|
||||
updateRoutineDetails();
|
||||
|
||||
form.addEventListener("submit", function(e) {
|
||||
e.preventDefault();
|
||||
console.log("Form submitted");
|
||||
|
||||
let formData = new FormData(this);
|
||||
|
||||
// Aggiungi il nome del cliente selezionato a FormData
|
||||
const clientSelect = document.getElementById("clientSelect");
|
||||
const clientId = clientSelect.value;
|
||||
const selectedClientOption = clientSelect.options[clientSelect.selectedIndex];
|
||||
|
||||
if (!clientId) {
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Per favore seleziona un cliente.",
|
||||
icon: "error",
|
||||
confirmButtonText: "OK"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let clientName = "";
|
||||
if (selectedClientOption) {
|
||||
const optionText = selectedClientOption.text.trim();
|
||||
@@ -482,18 +330,11 @@
|
||||
}
|
||||
formData.append("client_name", clientName);
|
||||
|
||||
// Aggiungi l'ID e il nome dello schema selezionato a FormData
|
||||
const schemaSelect = document.getElementById("schemaSelect");
|
||||
const schemaId = schemaSelect.value;
|
||||
const selectedSchemaOption = schemaSelect.options[schemaSelect.selectedIndex];
|
||||
let schemaName = "";
|
||||
if (selectedSchemaOption && schemaId) {
|
||||
const optionText = selectedSchemaOption.text.trim();
|
||||
const nameMatch = optionText.match(/^(.+?)(?:\s*\(ID:\s*\d+\))?$/);
|
||||
schemaName = nameMatch ? nameMatch[1].trim() : optionText;
|
||||
formData.append("idschema", schemaId);
|
||||
formData.append("schemamaname", schemaName);
|
||||
} else {
|
||||
|
||||
if (!schemaId) {
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Per favore seleziona uno schema.",
|
||||
@@ -503,48 +344,17 @@
|
||||
return;
|
||||
}
|
||||
|
||||
// Log per debug
|
||||
console.log("Client ID:", clientId);
|
||||
console.log("Client Name:", clientName);
|
||||
console.log("Schema ID:", schemaId);
|
||||
console.log("Schema Name:", schemaName);
|
||||
|
||||
// Genera il JSON per client_specific_fields
|
||||
let finalSpecificFields = {};
|
||||
const fieldRows = container.getElementsByClassName("client-field-row");
|
||||
for (let i = 0; i < fieldRows.length; i++) {
|
||||
const row = fieldRows[i];
|
||||
const inputs = row.querySelectorAll("input, select");
|
||||
let fieldData = {};
|
||||
|
||||
inputs.forEach(input => {
|
||||
const nameMatch = input.name.match(/specific_fields\[\d+\]\[(.*?)\]/);
|
||||
if (nameMatch) {
|
||||
const fieldName = nameMatch[1];
|
||||
fieldData[fieldName] = input.value.trim();
|
||||
}
|
||||
});
|
||||
|
||||
if (fieldData.name) {
|
||||
finalSpecificFields[fieldData.name] = {
|
||||
type: fieldData.type || "text",
|
||||
possible_values: (fieldData.possible_values && fieldData.type === "dropdown") ? fieldData.possible_values.split(",").map(v => v.trim()) : [],
|
||||
is_required: fieldData.required === "1",
|
||||
export_column_name: fieldData.export_column_name || "",
|
||||
default_value: fieldData.default_value || ""
|
||||
};
|
||||
console.log(`Field ${fieldData.name}:`, finalSpecificFields[fieldData.name]);
|
||||
}
|
||||
let schemaName = "";
|
||||
if (selectedSchemaOption) {
|
||||
const optionText = selectedSchemaOption.text.trim();
|
||||
const nameMatch = optionText.match(/^(.+?)(?:\s*\(ID:\s*\d+\))?$/);
|
||||
schemaName = nameMatch ? nameMatch[1].trim() : optionText;
|
||||
}
|
||||
formData.append("idschema", schemaId);
|
||||
formData.append("schemaname", schemaName);
|
||||
|
||||
console.log("Generated JSON for client_specific_fields:", JSON.stringify(finalSpecificFields));
|
||||
formData.append("client_specific_fields", JSON.stringify(finalSpecificFields));
|
||||
|
||||
// Debug del FormData
|
||||
console.log("FormData contents:");
|
||||
for (let pair of formData.entries()) {
|
||||
console.log(pair[0] + ': ' + pair[1]);
|
||||
}
|
||||
const routineId = routineSelect.value;
|
||||
formData.append("idroutine", routineId);
|
||||
|
||||
fetch("process_insert_template_xls.php", {
|
||||
method: "POST",
|
||||
@@ -552,7 +362,6 @@
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log("Fetch response:", data);
|
||||
if (data.success) {
|
||||
Swal.fire({
|
||||
title: "Successo!",
|
||||
@@ -572,7 +381,6 @@
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Errore Fetch:", error);
|
||||
Swal.fire({
|
||||
title: "Errore!",
|
||||
text: "Si è verificato un errore imprevisto.",
|
||||
|
||||
@@ -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
|
||||