Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9ec5419a86 | |||
| c05091e020 | |||
| 0b470f290e | |||
| e74870c8d3 | |||
| 9001eff317 | |||
| 650676037a | |||
| 2fc34c3cf4 | |||
| 955a7ed9e9 | |||
| e6a805f1f7 | |||
| fe84d446e7 | |||
| 2ddf575191 | |||
| d73a8bb8d3 | |||
| fa2f293835 | |||
| fc35adc7f9 | |||
| ac942dcdc8 | |||
| 5728afa788 | |||
| 1946648b1b | |||
| a1bcab3188 | |||
| 2bbeb11726 | |||
| dd5edab2f3 | |||
| 1fadc22178 | |||
| d3ee9a3790 | |||
| c387b71cae | |||
| b2cfec77df | |||
| 73b9a3d890 | |||
| 0550ffe923 | |||
| d2e5cc8b2b | |||
| d7b6a58407 | |||
| 174fa73c2c | |||
| 0bd41b8eb0 | |||
| 248ae63875 | |||
| d39e997beb | |||
| 1b23885659 | |||
| ad16d84b2e | |||
| 8cf74608b8 | |||
| 2642906a9b | |||
| d2f2a9089e | |||
| 53b990ff40 | |||
| f477f393ba | |||
| bc806f37f4 | |||
| f043b43791 | |||
| 245750f057 | |||
| 22e5b90fe4 | |||
| 31f22b4d92 | |||
| 340ebdcbce | |||
| 1edf7b7239 | |||
| 51cca3448a | |||
| 8732f21af8 | |||
| 3043522465 | |||
| 49435b8e44 | |||
| e876cb9775 | |||
| 7f78a61808 | |||
| 50c808e605 | |||
| 978b38c669 | |||
| 4683c4f40c | |||
| d9cbaf8df1 | |||
| 9649751ad8 | |||
| 824ae278d1 | |||
| 37909e8175 | |||
| 86782d26b2 | |||
| 329b3ffdeb | |||
| 9447f3cf00 | |||
| 5b7a8b57d5 | |||
| 7a2cac27cd | |||
| f9737fdf73 | |||
| 77e5820dcc | |||
| dd9d109dee | |||
| a1c9d9f789 | |||
| 4c63f16a54 | |||
| 6f3b933a71 | |||
| 779821a08b | |||
| 8edccbdfef | |||
| eeb1d0d5de | |||
| 711d3d5f73 | |||
| 85c8ddc985 | |||
| edcedb8f91 | |||
| a4b1fb9b1f | |||
| 92ec026afe |
@@ -31,6 +31,8 @@ MAIL_USERNAME=null
|
|||||||
MAIL_PASSWORD=null
|
MAIL_PASSWORD=null
|
||||||
MAIL_ENCRYPTION=null
|
MAIL_ENCRYPTION=null
|
||||||
|
|
||||||
|
MANAGER_USER_ID=
|
||||||
|
|
||||||
PUSHER_APP_ID=
|
PUSHER_APP_ID=
|
||||||
PUSHER_APP_KEY=
|
PUSHER_APP_KEY=
|
||||||
PUSHER_APP_SECRET=
|
PUSHER_APP_SECRET=
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ auth.json
|
|||||||
# File XLSX temporanei importati
|
# File XLSX temporanei importati
|
||||||
/public/userarea/imported_trf/*.xlsx
|
/public/userarea/imported_trf/*.xlsx
|
||||||
/public/userarea/xlstemplates/*.xlsx
|
/public/userarea/xlstemplates/*.xlsx
|
||||||
|
/public/userarea/photos/matrici/allegati/
|
||||||
|
/public/userarea/photos/matrici/allegati/*
|
||||||
|
|
||||||
# Ignora cartelle di foto generate
|
# Ignora cartelle di foto generate
|
||||||
/public/photostrf/
|
/public/photostrf/
|
||||||
@@ -64,3 +66,6 @@ public/userarea/logsapi/commessaweb_customfields_763.json
|
|||||||
public/userarea/logsapi/commessaweb_invia_762.json
|
public/userarea/logsapi/commessaweb_invia_762.json
|
||||||
public/userarea/logsapi/commessaweb_invia_763.json
|
public/userarea/logsapi/commessaweb_invia_763.json
|
||||||
public/userarea/logsapi/last_auth_url.txt
|
public/userarea/logsapi/last_auth_url.txt
|
||||||
|
|
||||||
|
# User uploaded files
|
||||||
|
/public/userarea/files/
|
||||||
@@ -108,9 +108,17 @@ class LoginController extends Controller
|
|||||||
|
|
||||||
// Reindirizza in base al ruolo
|
// Reindirizza in base al ruolo
|
||||||
if ($user->hasRole('Admin')) {
|
if ($user->hasRole('Admin')) {
|
||||||
return redirect()->to('userarea/import_dashboard.php');
|
return redirect()->to('userarea/production_dashboard.php');
|
||||||
} elseif ($user->hasRole('User')) {
|
} elseif ($user->hasRole('User')) {
|
||||||
return redirect()->to('userarea/import_dashboard.php');
|
return redirect()->to('userarea/production_dashboard.php');
|
||||||
|
} elseif ($user->hasRole('HR')) {
|
||||||
|
return redirect()->to('userarea/production_dashboard.php');
|
||||||
|
} elseif ($user->hasRole('SuperUser')) {
|
||||||
|
return redirect()->to('userarea/production_dashboard.php');
|
||||||
|
} elseif ($user->hasRole('Management')) {
|
||||||
|
return redirect()->to('userarea/production_dashboard.php');
|
||||||
|
} elseif ($user->hasRole('Quality')) {
|
||||||
|
return redirect()->to('userarea/production_dashboard.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Se il ruolo non è specificato, reindirizza alla home predefinita
|
// Se il ruolo non è specificato, reindirizza alla home predefinita
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
"phpmailer/phpmailer": "^6.9",
|
"phpmailer/phpmailer": "^6.9",
|
||||||
"phpoffice/phpspreadsheet": "^4.1",
|
"phpoffice/phpspreadsheet": "^4.1",
|
||||||
"proengsoft/laravel-jsvalidation": "^4.0.0",
|
"proengsoft/laravel-jsvalidation": "^4.0.0",
|
||||||
|
"robmorgan/phinx": "^0.16.11",
|
||||||
"socialiteproviders/microsoft": "^4.7",
|
"socialiteproviders/microsoft": "^4.7",
|
||||||
"spatie/laravel-query-builder": "^5.0",
|
"spatie/laravel-query-builder": "^5.0",
|
||||||
"vanguardapp/activity-log": "^6.0",
|
"vanguardapp/activity-log": "^6.0",
|
||||||
|
|||||||
Generated
+646
-2
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "9c4f1e3bc3ee2180211c055e70635aef",
|
"content-hash": "076e7721d08cfea8b06ce75dd8c6c576",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "akaunting/laravel-setting",
|
"name": "akaunting/laravel-setting",
|
||||||
@@ -251,6 +251,330 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-11-29T23:19:16+00:00"
|
"time": "2023-11-29T23:19:16+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "cakephp/chronos",
|
||||||
|
"version": "3.5.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cakephp/chronos.git",
|
||||||
|
"reference": "e6e777b534244911566face8a5dbdbd7f7bda5a6"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cakephp/chronos/zipball/e6e777b534244911566face8a5dbdbd7f7bda5a6",
|
||||||
|
"reference": "e6e777b534244911566face8a5dbdbd7f7bda5a6",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.1",
|
||||||
|
"psr/clock": "^1.0"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/clock-implementation": "1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"cakephp/cakephp-codesniffer": "^5.0",
|
||||||
|
"phpunit/phpunit": "^10.5.58 || ^11.5.3 || ^12.1.3"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Cake\\Chronos\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Brian Nesbitt",
|
||||||
|
"email": "brian@nesbot.com",
|
||||||
|
"homepage": "http://nesbot.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "The CakePHP Team",
|
||||||
|
"homepage": "https://cakephp.org"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A simple API extension for DateTime.",
|
||||||
|
"homepage": "https://cakephp.org",
|
||||||
|
"keywords": [
|
||||||
|
"date",
|
||||||
|
"datetime",
|
||||||
|
"time"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/cakephp/chronos/issues",
|
||||||
|
"source": "https://github.com/cakephp/chronos"
|
||||||
|
},
|
||||||
|
"time": "2026-04-10T02:50:39+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cakephp/core",
|
||||||
|
"version": "5.3.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cakephp/core.git",
|
||||||
|
"reference": "eb012517900ed288f580aa3487e9a09f28ea85f9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cakephp/core/zipball/eb012517900ed288f580aa3487e9a09f28ea85f9",
|
||||||
|
"reference": "eb012517900ed288f580aa3487e9a09f28ea85f9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"cakephp/utility": "^5.3.0",
|
||||||
|
"league/container": "^5.1",
|
||||||
|
"php": ">=8.2",
|
||||||
|
"psr/container": "^1.1 || ^2.0"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/container-implementation": "^2.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"cakephp/cache": "To use Configure::store() and restore().",
|
||||||
|
"cakephp/event": "To use PluginApplicationInterface or plugin applications.",
|
||||||
|
"league/container": "To use Container and ServiceProvider classes"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-5.next": "5.4.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"functions.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Cake\\Core\\": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "CakePHP Community",
|
||||||
|
"homepage": "https://github.com/cakephp/core/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "CakePHP Framework Core classes",
|
||||||
|
"homepage": "https://cakephp.org",
|
||||||
|
"keywords": [
|
||||||
|
"cakephp",
|
||||||
|
"core",
|
||||||
|
"framework"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||||
|
"irc": "irc://irc.freenode.org/cakephp",
|
||||||
|
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||||
|
"source": "https://github.com/cakephp/core"
|
||||||
|
},
|
||||||
|
"time": "2026-03-31T06:25:23+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cakephp/database",
|
||||||
|
"version": "5.3.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cakephp/database.git",
|
||||||
|
"reference": "cf94dcb57c54a1a308fd866b038cd6995910e36e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cakephp/database/zipball/cf94dcb57c54a1a308fd866b038cd6995910e36e",
|
||||||
|
"reference": "cf94dcb57c54a1a308fd866b038cd6995910e36e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"cakephp/chronos": "^3.3",
|
||||||
|
"cakephp/core": "^5.3.0",
|
||||||
|
"cakephp/datasource": "^5.3.0",
|
||||||
|
"php": ">=8.2",
|
||||||
|
"psr/log": "^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"cakephp/i18n": "^5.3.0",
|
||||||
|
"cakephp/log": "^5.3.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"cakephp/i18n": "If you are using locale-aware datetime formats.",
|
||||||
|
"cakephp/log": "If you want to use query logging without providing a logger yourself."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-5.next": "5.4.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Cake\\Database\\": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "CakePHP Community",
|
||||||
|
"homepage": "https://github.com/cakephp/database/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Flexible and powerful Database abstraction library with a familiar PDO-like API",
|
||||||
|
"homepage": "https://cakephp.org",
|
||||||
|
"keywords": [
|
||||||
|
"abstraction",
|
||||||
|
"cakephp",
|
||||||
|
"database",
|
||||||
|
"database abstraction",
|
||||||
|
"pdo"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||||
|
"irc": "irc://irc.freenode.org/cakephp",
|
||||||
|
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||||
|
"source": "https://github.com/cakephp/database"
|
||||||
|
},
|
||||||
|
"time": "2026-03-31T06:25:23+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cakephp/datasource",
|
||||||
|
"version": "5.3.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cakephp/datasource.git",
|
||||||
|
"reference": "512464eb27b19316b515ec338089b83822c9ab5a"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cakephp/datasource/zipball/512464eb27b19316b515ec338089b83822c9ab5a",
|
||||||
|
"reference": "512464eb27b19316b515ec338089b83822c9ab5a",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"cakephp/core": "^5.3.0",
|
||||||
|
"php": ">=8.2",
|
||||||
|
"psr/simple-cache": "^2.0 || ^3.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"cakephp/cache": "^5.3.0",
|
||||||
|
"cakephp/collection": "^5.3.0",
|
||||||
|
"cakephp/utility": "^5.3.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"cakephp/cache": "If you decide to use Query caching.",
|
||||||
|
"cakephp/collection": "If you decide to use ResultSetInterface.",
|
||||||
|
"cakephp/utility": "If you decide to use EntityTrait."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-5.next": "5.4.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Cake\\Datasource\\": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "CakePHP Community",
|
||||||
|
"homepage": "https://github.com/cakephp/datasource/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provides connection managing and traits for Entities and Queries that can be reused for different datastores",
|
||||||
|
"homepage": "https://cakephp.org",
|
||||||
|
"keywords": [
|
||||||
|
"cakephp",
|
||||||
|
"connection management",
|
||||||
|
"datasource",
|
||||||
|
"entity",
|
||||||
|
"query"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||||
|
"irc": "irc://irc.freenode.org/cakephp",
|
||||||
|
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||||
|
"source": "https://github.com/cakephp/datasource"
|
||||||
|
},
|
||||||
|
"time": "2026-04-04T08:08:42+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "cakephp/utility",
|
||||||
|
"version": "5.3.5",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cakephp/utility.git",
|
||||||
|
"reference": "4ac9826fe5faa1505ec5aa3c171d6b58b6ab4e99"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cakephp/utility/zipball/4ac9826fe5faa1505ec5aa3c171d6b58b6ab4e99",
|
||||||
|
"reference": "4ac9826fe5faa1505ec5aa3c171d6b58b6ab4e99",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"cakephp/core": "^5.3.0",
|
||||||
|
"php": ">=8.2"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-intl": "To use Text::transliterate() or Text::slug()",
|
||||||
|
"lib-ICU": "To use Text::transliterate() or Text::slug()"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-5.next": "5.4.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"files": [
|
||||||
|
"bootstrap.php"
|
||||||
|
],
|
||||||
|
"psr-4": {
|
||||||
|
"Cake\\Utility\\": "."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "CakePHP Community",
|
||||||
|
"homepage": "https://github.com/cakephp/utility/graphs/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "CakePHP Utility classes such as Inflector, String, Hash, and Security",
|
||||||
|
"homepage": "https://cakephp.org",
|
||||||
|
"keywords": [
|
||||||
|
"cakephp",
|
||||||
|
"hash",
|
||||||
|
"inflector",
|
||||||
|
"security",
|
||||||
|
"string",
|
||||||
|
"utility"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"forum": "https://stackoverflow.com/tags/cakephp",
|
||||||
|
"irc": "irc://irc.freenode.org/cakephp",
|
||||||
|
"issues": "https://github.com/cakephp/cakephp/issues",
|
||||||
|
"source": "https://github.com/cakephp/utility"
|
||||||
|
},
|
||||||
|
"time": "2026-03-09T09:38:36+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "carbonphp/carbon-doctrine-types",
|
"name": "carbonphp/carbon-doctrine-types",
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
@@ -2627,6 +2951,90 @@
|
|||||||
],
|
],
|
||||||
"time": "2022-12-11T20:36:23+00:00"
|
"time": "2022-12-11T20:36:23+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "league/container",
|
||||||
|
"version": "5.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/thephpleague/container.git",
|
||||||
|
"reference": "58accbc032f0090a9bd08326f93062c5a658b2c5"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/thephpleague/container/zipball/58accbc032f0090a9bd08326f93062c5a658b2c5",
|
||||||
|
"reference": "58accbc032f0090a9bd08326f93062c5a658b2c5",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.1",
|
||||||
|
"psr/container": "^2.0.2",
|
||||||
|
"psr/event-dispatcher": "^1.0"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/container-implementation": "^1.0"
|
||||||
|
},
|
||||||
|
"replace": {
|
||||||
|
"orno/di": "~2.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"nette/php-generator": "^4.1",
|
||||||
|
"nikic/php-parser": "^5.0",
|
||||||
|
"phpstan/phpstan": "^2.1.11",
|
||||||
|
"phpunit/phpunit": "^10.5.45|^11.5.15|^12.0",
|
||||||
|
"roave/security-advisories": "dev-latest",
|
||||||
|
"scrutinizer/ocular": "^1.9",
|
||||||
|
"squizlabs/php_codesniffer": "^3.9"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-1.x": "1.x-dev",
|
||||||
|
"dev-2.x": "2.x-dev",
|
||||||
|
"dev-3.x": "3.x-dev",
|
||||||
|
"dev-4.x": "4.x-dev",
|
||||||
|
"dev-5.x": "5.x-dev",
|
||||||
|
"dev-master": "5.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"League\\Container\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Phil Bennett",
|
||||||
|
"email": "mail@philbennett.co.uk",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A fast and intuitive dependency injection container.",
|
||||||
|
"homepage": "https://github.com/thephpleague/container",
|
||||||
|
"keywords": [
|
||||||
|
"container",
|
||||||
|
"dependency",
|
||||||
|
"di",
|
||||||
|
"injection",
|
||||||
|
"league",
|
||||||
|
"provider",
|
||||||
|
"service"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/thephpleague/container/issues",
|
||||||
|
"source": "https://github.com/thephpleague/container/tree/5.2.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/philipobenito",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-03-19T18:52:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "league/flysystem",
|
"name": "league/flysystem",
|
||||||
"version": "3.28.0",
|
"version": "3.28.0",
|
||||||
@@ -4980,6 +5388,93 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-04-27T21:32:50+00:00"
|
"time": "2024-04-27T21:32:50+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "robmorgan/phinx",
|
||||||
|
"version": "0.16.11",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/cakephp/phinx.git",
|
||||||
|
"reference": "a03014fea316ba021fc0776982e5bed2d10228d4"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/cakephp/phinx/zipball/a03014fea316ba021fc0776982e5bed2d10228d4",
|
||||||
|
"reference": "a03014fea316ba021fc0776982e5bed2d10228d4",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"cakephp/database": "^5.0.2",
|
||||||
|
"composer-runtime-api": "^2.0",
|
||||||
|
"php-64bit": ">=8.1",
|
||||||
|
"psr/container": "^1.1|^2.0",
|
||||||
|
"symfony/config": "^4.0|^5.0|^6.0|^7.0|^8.0",
|
||||||
|
"symfony/console": "^6.0|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"cakephp/cakephp-codesniffer": "^5.0",
|
||||||
|
"cakephp/i18n": "^5.0",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-pdo": "*",
|
||||||
|
"phpunit/phpunit": "^10.5",
|
||||||
|
"symfony/yaml": "^4.0|^5.0|^6.0|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-json": "Install if using JSON configuration format",
|
||||||
|
"ext-pdo": "PDO extension is needed",
|
||||||
|
"symfony/yaml": "Install if using YAML configuration format"
|
||||||
|
},
|
||||||
|
"bin": [
|
||||||
|
"bin/phinx"
|
||||||
|
],
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Phinx\\": "src/Phinx/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Rob Morgan",
|
||||||
|
"email": "robbym@gmail.com",
|
||||||
|
"homepage": "https://robmorgan.id.au",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Woody Gilk",
|
||||||
|
"email": "woody.gilk@gmail.com",
|
||||||
|
"homepage": "https://shadowhand.me",
|
||||||
|
"role": "Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Richard Quadling",
|
||||||
|
"email": "rquadling@gmail.com",
|
||||||
|
"role": "Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CakePHP Community",
|
||||||
|
"homepage": "https://github.com/cakephp/phinx/graphs/contributors",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Phinx makes it ridiculously easy to manage the database migrations for your PHP app.",
|
||||||
|
"homepage": "https://phinx.org",
|
||||||
|
"keywords": [
|
||||||
|
"database",
|
||||||
|
"database migrations",
|
||||||
|
"db",
|
||||||
|
"migrations",
|
||||||
|
"phinx"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/cakephp/phinx/issues",
|
||||||
|
"source": "https://github.com/cakephp/phinx/tree/0.16.11"
|
||||||
|
},
|
||||||
|
"time": "2026-03-15T00:04:32+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "socialiteproviders/manager",
|
"name": "socialiteproviders/manager",
|
||||||
"version": "v4.8.1",
|
"version": "v4.8.1",
|
||||||
@@ -5312,6 +5807,85 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-05-31T14:57:53+00:00"
|
"time": "2024-05-31T14:57:53+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/config",
|
||||||
|
"version": "v7.4.10",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/config.git",
|
||||||
|
"reference": "d91b6c7cd2a8c9a9c2b8d26c8f5ed48edf99ef57"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/config/zipball/d91b6c7cd2a8c9a9c2b8d26c8f5ed48edf99ef57",
|
||||||
|
"reference": "d91b6c7cd2a8c9a9c2b8d26c8f5ed48edf99ef57",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2",
|
||||||
|
"symfony/deprecation-contracts": "^2.5|^3",
|
||||||
|
"symfony/filesystem": "^7.1|^8.0",
|
||||||
|
"symfony/polyfill-ctype": "~1.8"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/finder": "<6.4",
|
||||||
|
"symfony/service-contracts": "<2.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/event-dispatcher": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/finder": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/messenger": "^6.4|^7.0|^8.0",
|
||||||
|
"symfony/service-contracts": "^2.5|^3",
|
||||||
|
"symfony/yaml": "^6.4|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Config\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/config/tree/v7.4.10"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-05-03T14:20:49+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/console",
|
"name": "symfony/console",
|
||||||
"version": "v7.1.3",
|
"version": "v7.1.3",
|
||||||
@@ -5768,6 +6342,76 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-04-18T09:32:20+00:00"
|
"time": "2024-04-18T09:32:20+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/filesystem",
|
||||||
|
"version": "v7.4.11",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/filesystem.git",
|
||||||
|
"reference": "d721ea61b4a5fba8c5b6e7c1feda19efea144b50"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/filesystem/zipball/d721ea61b4a5fba8c5b6e7c1feda19efea144b50",
|
||||||
|
"reference": "d721ea61b4a5fba8c5b6e7c1feda19efea144b50",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.2",
|
||||||
|
"symfony/polyfill-ctype": "~1.8",
|
||||||
|
"symfony/polyfill-mbstring": "~1.8"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/process": "^6.4|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\Component\\Filesystem\\": ""
|
||||||
|
},
|
||||||
|
"exclude-from-classmap": [
|
||||||
|
"/Tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Provides basic utilities for the filesystem",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/filesystem/tree/v7.4.11"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/nicolas-grekas",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-05-11T16:38:44+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/finder",
|
"name": "symfony/finder",
|
||||||
"version": "v7.1.3",
|
"version": "v7.1.3",
|
||||||
@@ -11355,6 +11999,6 @@
|
|||||||
"php": "^8.2.0",
|
"php": "^8.2.0",
|
||||||
"ext-json": "*"
|
"ext-json": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class BaselineExistingDatabase extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
// Baseline migration.
|
||||||
|
// Existing database structure starts being tracked from this point.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class CreatePhinxTestTable extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Change Method.
|
||||||
|
*
|
||||||
|
* Write your reversible migrations using this method.
|
||||||
|
*
|
||||||
|
* More information on writing migrations is available here:
|
||||||
|
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
|
||||||
|
*
|
||||||
|
* Remember to call "create()" or "update()" and NOT "save()" when working
|
||||||
|
* with the Table class.
|
||||||
|
*/
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$table = $this->table('phinx_test_table');
|
||||||
|
|
||||||
|
$table
|
||||||
|
->addColumn('name', 'string', [
|
||||||
|
'limit' => 100,
|
||||||
|
'null' => false,
|
||||||
|
])
|
||||||
|
->addColumn('created_at', 'timestamp', [
|
||||||
|
'default' => 'CURRENT_TIMESTAMP',
|
||||||
|
'null' => false,
|
||||||
|
])
|
||||||
|
->create();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class AddFunctionsToScadDeadlines extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$this->table('scad_functions', [
|
||||||
|
'id' => false,
|
||||||
|
'primary_key' => ['id'],
|
||||||
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
|
'encoding' => 'utf8mb4',
|
||||||
|
])
|
||||||
|
->addColumn('id', 'integer', [
|
||||||
|
'identity' => true,
|
||||||
|
'signed' => false,
|
||||||
|
])
|
||||||
|
->addColumn('name', 'string', [
|
||||||
|
'limit' => 255,
|
||||||
|
'null' => false,
|
||||||
|
])
|
||||||
|
->addColumn('description', 'text', [
|
||||||
|
'null' => true,
|
||||||
|
])
|
||||||
|
->addColumn('status', 'string', [
|
||||||
|
'limit' => 20,
|
||||||
|
'null' => false,
|
||||||
|
'default' => 'active',
|
||||||
|
])
|
||||||
|
->addColumn('created_at', 'timestamp', [
|
||||||
|
'null' => false,
|
||||||
|
'default' => 'CURRENT_TIMESTAMP',
|
||||||
|
])
|
||||||
|
->addColumn('updated_at', 'timestamp', [
|
||||||
|
'null' => false,
|
||||||
|
'default' => 'CURRENT_TIMESTAMP',
|
||||||
|
'update' => 'CURRENT_TIMESTAMP',
|
||||||
|
])
|
||||||
|
->addIndex(['name'], [
|
||||||
|
'unique' => true,
|
||||||
|
'name' => 'uniq_scad_functions_name',
|
||||||
|
])
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$this->table('scad_deadlines')
|
||||||
|
->addColumn('function_id', 'integer', [
|
||||||
|
'signed' => false,
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'subject_id',
|
||||||
|
])
|
||||||
|
->addIndex(['function_id'], [
|
||||||
|
'name' => 'idx_scad_deadlines_function_id',
|
||||||
|
])
|
||||||
|
->addForeignKey('function_id', 'scad_functions', 'id', [
|
||||||
|
'delete' => 'SET_NULL',
|
||||||
|
'update' => 'CASCADE',
|
||||||
|
'constraint' => 'fk_scad_deadlines_function',
|
||||||
|
])
|
||||||
|
->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
if (file_exists(__DIR__ . '/.env')) {
|
||||||
|
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
|
||||||
|
$dotenv->safeLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'paths' => [
|
||||||
|
'migrations' => __DIR__ . '/db/migrations',
|
||||||
|
'seeds' => __DIR__ . '/db/seeds',
|
||||||
|
],
|
||||||
|
|
||||||
|
'environments' => [
|
||||||
|
'default_migration_table' => 'phinxlog',
|
||||||
|
'default_environment' => 'development',
|
||||||
|
|
||||||
|
'development' => [
|
||||||
|
'adapter' => $_ENV['DB_CONNECTION'] ?? 'mysql',
|
||||||
|
'host' => $_ENV['DB_HOST'] ?? 'localhost',
|
||||||
|
'name' => $_ENV['DB_DATABASE'] ?? '',
|
||||||
|
'user' => $_ENV['DB_USERNAME'] ?? '',
|
||||||
|
'pass' => $_ENV['DB_PASSWORD'] ?? '',
|
||||||
|
'port' => $_ENV['DB_PORT'] ?? 3306,
|
||||||
|
'charset' => 'utf8mb4',
|
||||||
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'version_order' => 'creation',
|
||||||
|
];
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 456 KiB |
@@ -0,0 +1,254 @@
|
|||||||
|
<?php
|
||||||
|
ob_start();
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/../../../extra/auth.php');
|
||||||
|
require_once(__DIR__ . '/../class/db-functions.php');
|
||||||
|
|
||||||
|
while (ob_get_level()) {
|
||||||
|
ob_end_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
if (!class_exists('Auth')) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Classe Auth non disponibile'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Auth::check()) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Sessione non valida o utente non autenticato'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
|
function formatDateIT($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00') return '';
|
||||||
|
return date("d/m/Y", strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDateTimeIT($d)
|
||||||
|
{
|
||||||
|
if (!$d || $d === '0000-00-00 00:00:00') return '';
|
||||||
|
return date("d/m/Y H:i", strtotime($d));
|
||||||
|
}
|
||||||
|
|
||||||
|
function worksheetNumberLabel($n)
|
||||||
|
{
|
||||||
|
$n = (int)$n;
|
||||||
|
return $n > 0 ? 'FL' . $n : '—';
|
||||||
|
}
|
||||||
|
|
||||||
|
function revisionLabel($rev)
|
||||||
|
{
|
||||||
|
$rev = trim((string)$rev);
|
||||||
|
return $rev !== '' ? $rev : '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$action = $_POST['action'] ?? '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($action === 'get_matrice_worksheets') {
|
||||||
|
$idmatrice = isset($_POST['idmatrice']) ? (int)$_POST['idmatrice'] : 0;
|
||||||
|
if ($idmatrice <= 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'ID matrice non valido'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
ws.id,
|
||||||
|
ws.idmatrice,
|
||||||
|
ws.worksheet_number,
|
||||||
|
ws.revision_code,
|
||||||
|
ws.worksheet_status,
|
||||||
|
ws.worksheet_date,
|
||||||
|
ws.customer_name,
|
||||||
|
ws.profile_type_code,
|
||||||
|
ws.marking,
|
||||||
|
ws.approved_by,
|
||||||
|
ws.created_at,
|
||||||
|
ws.updated_at,
|
||||||
|
(
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM work_sheet_mescole wsm
|
||||||
|
WHERE wsm.worksheet_id = ws.id
|
||||||
|
) AS mix_count
|
||||||
|
FROM work_sheets ws
|
||||||
|
WHERE ws.idmatrice = ?
|
||||||
|
ORDER BY
|
||||||
|
ws.worksheet_number DESC,
|
||||||
|
CASE
|
||||||
|
WHEN ws.revision_code IS NULL OR ws.revision_code = '' THEN 0
|
||||||
|
WHEN ws.revision_code REGEXP '^R[0-9]+$' THEN CAST(SUBSTRING(ws.revision_code, 2) AS UNSIGNED)
|
||||||
|
ELSE 0
|
||||||
|
END DESC,
|
||||||
|
ws.id DESC
|
||||||
|
");
|
||||||
|
$stmt->execute([$idmatrice]);
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$data = [];
|
||||||
|
foreach ($rows as $r) {
|
||||||
|
$data[] = [
|
||||||
|
'id' => (int)$r['id'],
|
||||||
|
'idmatrice' => (int)$r['idmatrice'],
|
||||||
|
'worksheet_number' => (int)($r['worksheet_number'] ?? 0),
|
||||||
|
'worksheet_number_label' => worksheetNumberLabel($r['worksheet_number'] ?? 0),
|
||||||
|
'revision_code' => $r['revision_code'] ?? '',
|
||||||
|
'revision_label' => revisionLabel($r['revision_code'] ?? ''),
|
||||||
|
'worksheet_status' => $r['worksheet_status'] ?? 'active',
|
||||||
|
'worksheet_status_label' => (($r['worksheet_status'] ?? 'active') === 'inactive') ? 'Inattivo' : 'Attivo',
|
||||||
|
'worksheet_date' => $r['worksheet_date'],
|
||||||
|
'worksheet_date_it' => formatDateIT($r['worksheet_date']),
|
||||||
|
'customer_name' => $r['customer_name'] ?? '',
|
||||||
|
'profile_type_code' => $r['profile_type_code'] ?? '',
|
||||||
|
'marking' => $r['marking'] ?? '',
|
||||||
|
'approved_by' => $r['approved_by'] ?? '',
|
||||||
|
'created_at' => $r['created_at'] ?? '',
|
||||||
|
'created_at_it' => formatDateTimeIT($r['created_at'] ?? ''),
|
||||||
|
'updated_at' => $r['updated_at'] ?? '',
|
||||||
|
'updated_at_it' => formatDateTimeIT($r['updated_at'] ?? ''),
|
||||||
|
'mix_count' => (int)($r['mix_count'] ?? 0)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'worksheets' => $data
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'get_worksheet_detail') {
|
||||||
|
$worksheetId = isset($_POST['worksheet_id']) ? (int)$_POST['worksheet_id'] : 0;
|
||||||
|
if ($worksheetId <= 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'ID foglio non valido'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
ws.*,
|
||||||
|
m.nome AS matrice_nome,
|
||||||
|
m.cliente AS matrice_cliente
|
||||||
|
FROM work_sheets ws
|
||||||
|
LEFT JOIN matrice m ON m.id = ws.idmatrice
|
||||||
|
WHERE ws.id = ?
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
$stmt->execute([$worksheetId]);
|
||||||
|
$ws = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$ws) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Foglio di lavoro non trovato'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmtMix = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
wsm.*,
|
||||||
|
me.nome AS mescola_nome,
|
||||||
|
me.nomeuscita AS mescola_uscita
|
||||||
|
FROM work_sheet_mescole wsm
|
||||||
|
LEFT JOIN mescole me ON me.id = wsm.idmescola
|
||||||
|
WHERE wsm.worksheet_id = ?
|
||||||
|
ORDER BY wsm.mix_position ASC, wsm.id ASC
|
||||||
|
");
|
||||||
|
$stmtMix->execute([$worksheetId]);
|
||||||
|
$mixRows = $stmtMix->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'worksheet' => [
|
||||||
|
'id' => (int)$ws['id'],
|
||||||
|
'worksheet_number' => (int)($ws['worksheet_number'] ?? 0),
|
||||||
|
'worksheet_number_label' => worksheetNumberLabel($ws['worksheet_number'] ?? 0),
|
||||||
|
'revision_code' => $ws['revision_code'] ?? '',
|
||||||
|
'revision_label' => revisionLabel($ws['revision_code'] ?? ''),
|
||||||
|
'worksheet_status' => $ws['worksheet_status'] ?? 'active',
|
||||||
|
'worksheet_status_label' => (($ws['worksheet_status'] ?? 'active') === 'inactive') ? 'Inattivo' : 'Attivo',
|
||||||
|
'idmatrice' => (int)$ws['idmatrice'],
|
||||||
|
'matrice_nome' => $ws['matrice_nome'] ?? '',
|
||||||
|
'matrice_cliente' => $ws['matrice_cliente'] ?? '',
|
||||||
|
'worksheet_date' => $ws['worksheet_date'] ?? '',
|
||||||
|
'worksheet_date_it' => formatDateIT($ws['worksheet_date'] ?? ''),
|
||||||
|
'customer_name' => $ws['customer_name'] ?? '',
|
||||||
|
'profile_type_code' => $ws['profile_type_code'] ?? '',
|
||||||
|
'marking' => $ws['marking'] ?? '',
|
||||||
|
'prod_control_measure_settings' => $ws['prod_control_measure_settings'] ?? '',
|
||||||
|
'control_frequency_cut' => $ws['control_frequency_cut'] ?? '',
|
||||||
|
'control_frequency_drawing' => $ws['control_frequency_drawing'] ?? '',
|
||||||
|
'control_frequency_jig' => $ws['control_frequency_jig'] ?? '',
|
||||||
|
'control_mode_jig' => $ws['control_mode_jig'] ?? '',
|
||||||
|
'requested_package_code' => $ws['requested_package_code'] ?? '',
|
||||||
|
'meters_per_package' => $ws['meters_per_package'] ?? '',
|
||||||
|
'meters_per_package_tolerance' => $ws['meters_per_package_tolerance'] ?? '',
|
||||||
|
'meters_per_package_notes' => $ws['meters_per_package_notes'] ?? '',
|
||||||
|
'box_type' => $ws['box_type'] ?? '',
|
||||||
|
'packages_or_pieces_per_box' => $ws['packages_or_pieces_per_box'] ?? '',
|
||||||
|
'meters_per_box' => $ws['meters_per_box'] ?? '',
|
||||||
|
'pallet_type' => $ws['pallet_type'] ?? '',
|
||||||
|
'boxes_or_packages_per_pallet' => $ws['boxes_or_packages_per_pallet'] ?? '',
|
||||||
|
'speed_expected_kg_h' => $ws['speed_expected_kg_h'] ?? '',
|
||||||
|
'speed_actual_kg_h' => $ws['speed_actual_kg_h'] ?? '',
|
||||||
|
'speed_expected_m_h' => $ws['speed_expected_m_h'] ?? '',
|
||||||
|
'speed_actual_m_h' => $ws['speed_actual_m_h'] ?? '',
|
||||||
|
'approved_by' => $ws['approved_by'] ?? '',
|
||||||
|
'notes' => $ws['notes'] ?? '',
|
||||||
|
'created_at' => $ws['created_at'] ?? '',
|
||||||
|
'created_at_it' => formatDateTimeIT($ws['created_at'] ?? ''),
|
||||||
|
'updated_at' => $ws['updated_at'] ?? '',
|
||||||
|
'updated_at_it' => formatDateTimeIT($ws['updated_at'] ?? '')
|
||||||
|
],
|
||||||
|
'mix_rows' => array_map(function ($r) {
|
||||||
|
return [
|
||||||
|
'id' => (int)$r['id'],
|
||||||
|
'mix_position' => (int)$r['mix_position'],
|
||||||
|
'mescola_nome' => $r['mescola_nome'] ?? '',
|
||||||
|
'mescola_uscita' => $r['mescola_uscita'] ?? '',
|
||||||
|
'mix_weight_g_m' => $r['mix_weight_g_m'] ?? '',
|
||||||
|
'required_density' => $r['required_density'] ?? '',
|
||||||
|
'required_hardness_shore_a' => $r['required_hardness_shore_a'] ?? '',
|
||||||
|
'lubrication_type' => $r['lubrication_type'] ?? '',
|
||||||
|
'lubrication_notes' => $r['lubrication_notes'] ?? ''
|
||||||
|
];
|
||||||
|
}, $mixRows)
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Azione AJAX sconosciuta'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
<?php
|
||||||
|
require_once(__DIR__ . "/class/db-functions.php");
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$STATUS_PROGRAMMATO = 6;
|
||||||
|
$STATUS_DA_PROGRAMMARE = 1;
|
||||||
|
|
||||||
|
$jsonFile = __DIR__ . "/data/production_priority.json";
|
||||||
|
|
||||||
|
/* -------------------------------
|
||||||
|
JSON HELPERS
|
||||||
|
---------------------------------*/
|
||||||
|
function loadPriority()
|
||||||
|
{
|
||||||
|
global $jsonFile;
|
||||||
|
if (!file_exists($jsonFile)) return [];
|
||||||
|
return json_decode(file_get_contents($jsonFile), true) ?: [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function savePriority($arr)
|
||||||
|
{
|
||||||
|
global $jsonFile;
|
||||||
|
file_put_contents($jsonFile, json_encode($arr, JSON_PRETTY_PRINT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------
|
||||||
|
LOAD: PROGRAMMATI
|
||||||
|
---------------------------------*/
|
||||||
|
if ($_GET['mode'] === 'planned') {
|
||||||
|
|
||||||
|
$priority = loadPriority();
|
||||||
|
$map = [];
|
||||||
|
foreach ($priority as $p) $map[$p['id']] = $p['priority'];
|
||||||
|
|
||||||
|
$sql = "SELECT p.*, m.nome AS matrice, ms.nome AS mescola,
|
||||||
|
l.name AS linea, c.nome AS cliente
|
||||||
|
FROM productiondata p
|
||||||
|
LEFT JOIN matrice m ON p.idmatrice = m.id
|
||||||
|
LEFT JOIN mescole ms ON p.idmescola = ms.id
|
||||||
|
LEFT JOIN production_lines l ON p.id_linea = l.id
|
||||||
|
LEFT JOIN clients c ON p.id_cliente = c.id
|
||||||
|
WHERE p.id_status = :s";
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute(['s' => $STATUS_PROGRAMMATO]);
|
||||||
|
$rows = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// Ordina per priority
|
||||||
|
usort($rows, function ($a, $b) use ($map) {
|
||||||
|
return ($map[$a['id']] ?? 9999) <=> ($map[$b['id']] ?? 9999);
|
||||||
|
});
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
foreach ($rows as $r):
|
||||||
|
$prio = $map[$r['id']] ?? '-';
|
||||||
|
?>
|
||||||
|
<tr data-id="<?= $r['id'] ?>">
|
||||||
|
<td><strong><?= $prio ?></strong></td>
|
||||||
|
<td><?= date('d/m/Y', strtotime($r['Data'])) ?></td>
|
||||||
|
<td><?= $r['matrice'] ?></td>
|
||||||
|
<td><?= $r['mescola'] ?></td>
|
||||||
|
<td><?= $r['linea'] ?></td>
|
||||||
|
<td><?= $r['cliente'] ?? '-' ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
|
||||||
|
echo json_encode(['html' => ob_get_clean()]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------
|
||||||
|
LOAD: DA PROGRAMMARE
|
||||||
|
---------------------------------*/
|
||||||
|
if ($_GET['mode'] === 'to_plan') {
|
||||||
|
|
||||||
|
$sql = "SELECT p.*, m.nome AS matrice, ms.nome AS mescola,
|
||||||
|
l.name AS linea, c.nome AS cliente
|
||||||
|
FROM productiondata p
|
||||||
|
LEFT JOIN matrice m ON p.idmatrice = m.id
|
||||||
|
LEFT JOIN mescole ms ON p.idmescola = ms.id
|
||||||
|
LEFT JOIN production_lines l ON p.id_linea = l.id
|
||||||
|
LEFT JOIN clients c ON p.id_cliente = c.id
|
||||||
|
WHERE p.id_status = :s
|
||||||
|
ORDER BY p.Data ASC";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute(['s' => $STATUS_DA_PROGRAMMARE]);
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
foreach ($stmt as $r): ?>
|
||||||
|
<tr data-id="<?= $r['id'] ?>">
|
||||||
|
<td><?= date('d/m/Y', strtotime($r['Data'])) ?></td>
|
||||||
|
<td><?= $r['matrice'] ?></td>
|
||||||
|
<td><?= $r['mescola'] ?></td>
|
||||||
|
<td><?= $r['linea'] ?></td>
|
||||||
|
<td><?= $r['cliente'] ?? '-' ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach;
|
||||||
|
|
||||||
|
echo json_encode(['html' => ob_get_clean()]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------
|
||||||
|
UPDATE STATUS + PRIORITY
|
||||||
|
---------------------------------*/
|
||||||
|
if ($_POST['mode'] === 'save') {
|
||||||
|
|
||||||
|
$planned = json_decode($_POST['planned'], true);
|
||||||
|
$toPlan = json_decode($_POST['toPlan'], true);
|
||||||
|
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
// Aggiorna programmati
|
||||||
|
foreach ($planned as $i => $row) {
|
||||||
|
$id = $row['id'];
|
||||||
|
$stmt = $pdo->prepare("UPDATE productiondata SET id_status = :s WHERE id = :id");
|
||||||
|
$stmt->execute(['s' => $STATUS_PROGRAMMATO, 'id' => $id]);
|
||||||
|
$priorityArr[] = ['id' => $id, 'priority' => $i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggiorna da programmare
|
||||||
|
foreach ($toPlan as $row) {
|
||||||
|
$id = $row['id'];
|
||||||
|
$stmt = $pdo->prepare("UPDATE productiondata SET id_status = :s WHERE id = :id");
|
||||||
|
$stmt->execute(['s' => $STATUS_DA_PROGRAMMARE, 'id' => $id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
savePriority($priorityArr);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
require_once("include/headscript.php");
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$programmati = json_decode($_POST["programmati"] ?? '[]', true);
|
||||||
|
$daProgrammare = json_decode($_POST["daProgrammare"] ?? '[]', true);
|
||||||
|
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
foreach ($programmati as $p) {
|
||||||
|
if (empty($p['id'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$stmt = $pdo->prepare(
|
||||||
|
"UPDATE productiondata SET id_status=6, priority=? WHERE id=?"
|
||||||
|
);
|
||||||
|
$stmt->execute([(int)$p["priority"], (int)$p["id"]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($daProgrammare as $p) {
|
||||||
|
if (empty($p['id'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$stmt = $pdo->prepare(
|
||||||
|
"UPDATE productiondata SET id_status=1, priority=? WHERE id=?"
|
||||||
|
);
|
||||||
|
$stmt->execute([(int)$p["priority"], (int)$p["id"]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
echo json_encode(["success" => true]);
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +0,0 @@
|
|||||||
<?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;
|
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 19 KiB |
@@ -37,6 +37,16 @@ $(function () {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
}),
|
}),
|
||||||
|
// NEW: se la pagina parte già con .wrapper.toggled, abilita subito l'hover
|
||||||
|
$(".wrapper").hasClass("toggled") &&
|
||||||
|
$(".sidebar-wrapper").hover(
|
||||||
|
function () {
|
||||||
|
$(".wrapper").addClass("sidebar-hovered");
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$(".wrapper").removeClass("sidebar-hovered");
|
||||||
|
},
|
||||||
|
),
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$(window).on("scroll", function () {
|
$(window).on("scroll", function () {
|
||||||
$(this).scrollTop() > 300
|
$(this).scrollTop() > 300
|
||||||
|
|||||||
@@ -0,0 +1,362 @@
|
|||||||
|
(function () {
|
||||||
|
function escapeHtml(str) {
|
||||||
|
return String(str || "")
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function valueOrDash(v) {
|
||||||
|
return v === null || v === undefined || String(v).trim() === ""
|
||||||
|
? "—"
|
||||||
|
: escapeHtml(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderReadonlyField(label, value) {
|
||||||
|
return `
|
||||||
|
<div class="readonly-label">${escapeHtml(label)}</div>
|
||||||
|
<div class="readonly-value">${valueOrDash(value)}</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.loadMatriceWorksheets = function (idmatrice, matriceNome, endpoint) {
|
||||||
|
endpoint = endpoint || "ajax/worksheet-linked-data.php";
|
||||||
|
|
||||||
|
$("#wl_idmatrice").val(idmatrice);
|
||||||
|
$("#wl_matrice_name").html(
|
||||||
|
`<span class="worksheet-chip"><i class="fa-solid fa-layer-group"></i>${escapeHtml(matriceNome || "")}</span>`,
|
||||||
|
);
|
||||||
|
$("#worksheetsListContainer").html(
|
||||||
|
'<div class="text-muted">Caricamento fogli di lavoro...</div>',
|
||||||
|
);
|
||||||
|
|
||||||
|
fetch(endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||||
|
body:
|
||||||
|
"action=get_matrice_worksheets&idmatrice=" +
|
||||||
|
encodeURIComponent(idmatrice),
|
||||||
|
})
|
||||||
|
.then(async (r) => {
|
||||||
|
const text = await r.text();
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Risposta non JSON worksheets:", text);
|
||||||
|
throw new Error("Risposta non JSON, vedi console");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (!data.success) {
|
||||||
|
$("#worksheetsListContainer").html(
|
||||||
|
'<div class="text-danger">Errore nel caricamento dei fogli</div>',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = data.worksheets || [];
|
||||||
|
|
||||||
|
if (!rows.length) {
|
||||||
|
$("#worksheetsListContainer").html(
|
||||||
|
'<div class="text-muted">Nessun foglio di lavoro collegato a questo profilo</div>',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let html = `
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped align-middle worksheet-list-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width:110px;">Foglio</th>
|
||||||
|
<th style="width:100px;">Rev.</th>
|
||||||
|
<th style="width:110px;">Stato</th>
|
||||||
|
<th style="width:140px;">Data foglio</th>
|
||||||
|
<th>Cliente</th>
|
||||||
|
<th>Codice profilo</th>
|
||||||
|
<th style="width:110px;">Mescole</th>
|
||||||
|
<th style="width:230px;">Azioni</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
`;
|
||||||
|
|
||||||
|
rows.forEach((r) => {
|
||||||
|
const statusBadge =
|
||||||
|
r.worksheet_status === "inactive"
|
||||||
|
? `<span class="worksheet-badge-status-inactive">Inattivo</span>`
|
||||||
|
: `<span class="worksheet-badge-status-active">Attivo</span>`;
|
||||||
|
|
||||||
|
html += `
|
||||||
|
<tr>
|
||||||
|
<td><span class="worksheet-badge-fl">${escapeHtml(r.worksheet_number_label || "—")}</span></td>
|
||||||
|
<td><span class="worksheet-badge-rev">${escapeHtml(r.revision_label || "0")}</span></td>
|
||||||
|
<td>${statusBadge}</td>
|
||||||
|
<td>${escapeHtml(r.worksheet_date_it || "—")}</td>
|
||||||
|
<td title="${escapeHtml(r.customer_name || "")}">${escapeHtml(r.customer_name || "—")}</td>
|
||||||
|
<td>${escapeHtml(r.profile_type_code || "—")}</td>
|
||||||
|
<td>${escapeHtml(String(r.mix_count || 0))}</td>
|
||||||
|
<td class="text-nowrap">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-view-worksheet open-worksheet-detail"
|
||||||
|
data-id="${r.id}"
|
||||||
|
data-endpoint="${escapeHtml(endpoint)}">
|
||||||
|
<i class="fa-solid fa-eye me-1"></i>Apri dettaglio
|
||||||
|
</button>
|
||||||
|
<a class="worksheet-open-link ms-1"
|
||||||
|
href="manage-worksheet.php?id=${r.id}"
|
||||||
|
target="_blank">
|
||||||
|
<i class="fa-solid fa-arrow-up-right-from-square"></i>Apri pagina
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
html += `
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
$("#worksheetsListContainer").html(html);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
$("#worksheetsListContainer").html(
|
||||||
|
'<div class="text-danger">Errore nel caricamento dei fogli</div>',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
window.loadWorksheetDetail = function (worksheetId, endpoint) {
|
||||||
|
endpoint = endpoint || "ajax/worksheet-linked-data.php";
|
||||||
|
|
||||||
|
$("#worksheetDetailContainer").html(
|
||||||
|
'<div class="text-muted">Caricamento dettaglio foglio...</div>',
|
||||||
|
);
|
||||||
|
|
||||||
|
fetch(endpoint, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||||
|
body:
|
||||||
|
"action=get_worksheet_detail&worksheet_id=" +
|
||||||
|
encodeURIComponent(worksheetId),
|
||||||
|
})
|
||||||
|
.then(async (r) => {
|
||||||
|
const text = await r.text();
|
||||||
|
try {
|
||||||
|
return JSON.parse(text);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Risposta non JSON worksheet detail:", text);
|
||||||
|
throw new Error("Risposta non JSON, vedi console");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (!data.success) {
|
||||||
|
console.error("Errore worksheets:", data);
|
||||||
|
|
||||||
|
$("#worksheetsListContainer").html(
|
||||||
|
'<div class="text-danger">Errore nel caricamento dei fogli: ' +
|
||||||
|
escapeHtml(
|
||||||
|
data.message || "nessun dettaglio restituito",
|
||||||
|
) +
|
||||||
|
"</div>",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ws = data.worksheet || {};
|
||||||
|
const mixRows = data.mix_rows || [];
|
||||||
|
|
||||||
|
let mixHtml = `<div class="text-muted">Nessuna mescola associata</div>`;
|
||||||
|
|
||||||
|
if (mixRows.length) {
|
||||||
|
mixHtml = `
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped align-middle mix-readonly-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width:80px;">Pos</th>
|
||||||
|
<th>Mescola</th>
|
||||||
|
<th style="width:120px;">Peso g/m</th>
|
||||||
|
<th style="width:140px;">Densità</th>
|
||||||
|
<th style="width:150px;">Durezza</th>
|
||||||
|
<th style="width:130px;">Lubr.</th>
|
||||||
|
<th>Note lubr.</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
`;
|
||||||
|
|
||||||
|
mixRows.forEach((r) => {
|
||||||
|
const nomeMescola = r.mescola_uscita
|
||||||
|
? `${escapeHtml(r.mescola_nome || "—")} <div class="small text-muted">${escapeHtml(r.mescola_uscita)}</div>`
|
||||||
|
: escapeHtml(r.mescola_nome || "—");
|
||||||
|
|
||||||
|
mixHtml += `
|
||||||
|
<tr>
|
||||||
|
<td>${escapeHtml(String(r.mix_position || ""))}</td>
|
||||||
|
<td>${nomeMescola}</td>
|
||||||
|
<td>${valueOrDash(r.mix_weight_g_m)}</td>
|
||||||
|
<td>${valueOrDash(r.required_density)}</td>
|
||||||
|
<td>${valueOrDash(r.required_hardness_shore_a)}</td>
|
||||||
|
<td>${valueOrDash(r.lubrication_type)}</td>
|
||||||
|
<td>${valueOrDash(r.lubrication_notes)}</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
mixHtml += `
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const html = `
|
||||||
|
<div class="worksheet-title-box mb-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-start gap-3 flex-wrap">
|
||||||
|
<div>
|
||||||
|
<h4 class="mb-1">${escapeHtml(ws.worksheet_number_label || "—")} / Rev. ${escapeHtml(ws.revision_label || "0")}</h4>
|
||||||
|
<small>
|
||||||
|
Stato: ${escapeHtml(ws.worksheet_status_label || "Attivo")}
|
||||||
|
${ws.matrice_nome ? " • Profilo: " + escapeHtml(ws.matrice_nome) : ""}
|
||||||
|
${ws.matrice_cliente ? " • Cliente matrice: " + escapeHtml(ws.matrice_cliente) : ""}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a href="manage-worksheet.php?id=${escapeHtml(String(ws.id || ""))}"
|
||||||
|
target="_blank"
|
||||||
|
class="worksheet-open-link">
|
||||||
|
<i class="fa-solid fa-arrow-up-right-from-square"></i>
|
||||||
|
Apri foglio completo
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="readonly-card">
|
||||||
|
<div class="readonly-card-header">Dati principali</div>
|
||||||
|
<div class="readonly-card-body">
|
||||||
|
<div class="readonly-grid">
|
||||||
|
${renderReadonlyField("Foglio", ws.worksheet_number_label)}
|
||||||
|
${renderReadonlyField("Revisione", ws.revision_label)}
|
||||||
|
${renderReadonlyField("Stato", ws.worksheet_status_label)}
|
||||||
|
${renderReadonlyField("Data foglio", ws.worksheet_date_it)}
|
||||||
|
${renderReadonlyField("Cliente override", ws.customer_name)}
|
||||||
|
${renderReadonlyField("Codice profilo", ws.profile_type_code)}
|
||||||
|
${renderReadonlyField("Marchiatura", ws.marking)}
|
||||||
|
${renderReadonlyField("Approvato da", ws.approved_by)}
|
||||||
|
${renderReadonlyField("Creato il", ws.created_at_it)}
|
||||||
|
${renderReadonlyField("Ultimo aggiornamento", ws.updated_at_it)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="readonly-card">
|
||||||
|
<div class="readonly-card-header">Controlli produzione</div>
|
||||||
|
<div class="readonly-card-body">
|
||||||
|
<div class="readonly-grid">
|
||||||
|
${renderReadonlyField("Taglio", ws.control_frequency_cut)}
|
||||||
|
${renderReadonlyField("Disegno", ws.control_frequency_drawing)}
|
||||||
|
${renderReadonlyField("Dima", ws.control_frequency_jig)}
|
||||||
|
${renderReadonlyField("Modalità dima", ws.control_mode_jig)}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="readonly-label mb-2">Impostazione misure controllo produzione</div>
|
||||||
|
<div class="readonly-value" style="white-space:pre-wrap;">${valueOrDash(ws.prod_control_measure_settings)}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="readonly-card">
|
||||||
|
<div class="readonly-card-header">Packaging / Confezionamento</div>
|
||||||
|
<div class="readonly-card-body">
|
||||||
|
<div class="readonly-grid">
|
||||||
|
${renderReadonlyField("Codice confezione", ws.requested_package_code)}
|
||||||
|
${renderReadonlyField("Metri per confezione", ws.meters_per_package)}
|
||||||
|
${renderReadonlyField("Tolleranza metri/conf.", ws.meters_per_package_tolerance)}
|
||||||
|
${renderReadonlyField("Scatola tipo", ws.box_type)}
|
||||||
|
${renderReadonlyField("Conf./pezzi per scatola", ws.packages_or_pieces_per_box)}
|
||||||
|
${renderReadonlyField("Metri per scatola", ws.meters_per_box)}
|
||||||
|
${renderReadonlyField("Bancale tipo", ws.pallet_type)}
|
||||||
|
${renderReadonlyField("Scatole/conf. per bancale", ws.boxes_or_packages_per_pallet)}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="readonly-label mb-2">Note metri / confezione</div>
|
||||||
|
<div class="readonly-value" style="white-space:pre-wrap;">${valueOrDash(ws.meters_per_package_notes)}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="readonly-card">
|
||||||
|
<div class="readonly-card-header">Velocità e note</div>
|
||||||
|
<div class="readonly-card-body">
|
||||||
|
<div class="readonly-grid">
|
||||||
|
${renderReadonlyField("Vel. prevista kg/h", ws.speed_expected_kg_h)}
|
||||||
|
${renderReadonlyField("Vel. effettiva kg/h", ws.speed_actual_kg_h)}
|
||||||
|
${renderReadonlyField("Vel. prevista m/h", ws.speed_expected_m_h)}
|
||||||
|
${renderReadonlyField("Vel. effettiva m/h", ws.speed_actual_m_h)}
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="readonly-label mb-2">Note</div>
|
||||||
|
<div class="readonly-value" style="white-space:pre-wrap;">${valueOrDash(ws.notes)}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="readonly-card">
|
||||||
|
<div class="readonly-card-header">Mescole associate al foglio</div>
|
||||||
|
<div class="readonly-card-body">
|
||||||
|
${mixHtml}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
$("#worksheetDetailContainer").html(html);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error("Catch loadMatriceWorksheets:", err);
|
||||||
|
|
||||||
|
$("#worksheetsListContainer").html(
|
||||||
|
'<div class="text-danger">Errore nel caricamento dei fogli: ' +
|
||||||
|
escapeHtml(err.message || "errore JavaScript/fetch") +
|
||||||
|
"</div>",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).on("click", ".worksheets, .show-worksheets", function () {
|
||||||
|
const idmatrice = $(this).data("id");
|
||||||
|
const nome = $(this).data("nome") || "";
|
||||||
|
const endpoint =
|
||||||
|
$(this).data("endpoint") || "ajax/worksheet-linked-data.php";
|
||||||
|
|
||||||
|
loadMatriceWorksheets(idmatrice, nome, endpoint);
|
||||||
|
new bootstrap.Modal(
|
||||||
|
document.getElementById("worksheetsListModal"),
|
||||||
|
).show();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on("click", ".open-worksheet-detail", function () {
|
||||||
|
const worksheetId = $(this).data("id");
|
||||||
|
const endpoint =
|
||||||
|
$(this).data("endpoint") || "ajax/worksheet-linked-data.php";
|
||||||
|
|
||||||
|
loadWorksheetDetail(worksheetId, endpoint);
|
||||||
|
new bootstrap.Modal(
|
||||||
|
document.getElementById("worksheetDetailModal"),
|
||||||
|
).show();
|
||||||
|
});
|
||||||
|
})();
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
@@ -1,58 +0,0 @@
|
|||||||
<?php
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
// URL dell'API e credenziali
|
|
||||||
$api_url = 'https://93.43.5.102/limsapi/api/authentication/authenticate';
|
|
||||||
$credentials = [
|
|
||||||
'Username' => 'WebApiUser',
|
|
||||||
'Password' => 'webapiuser01'
|
|
||||||
];
|
|
||||||
|
|
||||||
// Inizializza cURL
|
|
||||||
$ch = curl_init($api_url);
|
|
||||||
|
|
||||||
// Configura le opzioni di cURL
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($credentials));
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
||||||
'Content-Type: application/json',
|
|
||||||
'Accept: application/json'
|
|
||||||
]);
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Solo per test
|
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Solo per test
|
|
||||||
curl_setopt($ch, CURLOPT_VERBOSE, true);
|
|
||||||
$log = fopen('curl_auth_debug.log', 'w');
|
|
||||||
curl_setopt($ch, CURLOPT_STDERR, $log);
|
|
||||||
|
|
||||||
// Esegui la richiesta
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
$curl_error = curl_error($ch);
|
|
||||||
fclose($log);
|
|
||||||
|
|
||||||
// Verifica errori
|
|
||||||
if ($response === false || $http_code != 200) {
|
|
||||||
http_response_code($http_code ? $http_code : 500);
|
|
||||||
echo json_encode([
|
|
||||||
'error' => 'Errore nella richiesta API',
|
|
||||||
'http_code' => $http_code,
|
|
||||||
'curl_error' => $curl_error,
|
|
||||||
'response' => substr($response, 0, 1000)
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$decoded = json_decode($response);
|
|
||||||
if (json_last_error() === JSON_ERROR_NONE) {
|
|
||||||
http_response_code($http_code);
|
|
||||||
echo $response;
|
|
||||||
} else {
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode([
|
|
||||||
'error' => 'Risposta non JSON valida',
|
|
||||||
'http_code' => $http_code,
|
|
||||||
'response' => substr($response, 0, 1000)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_close($ch);
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
<?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'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
// Recupero foto esistenti
|
||||||
|
$photosSlots = [];
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT param_position, filename
|
||||||
|
FROM production_photos
|
||||||
|
WHERE production_id = ?
|
||||||
|
AND photo_type = 'parametri_macchina'
|
||||||
|
");
|
||||||
|
$stmt->execute([$r['id']]);
|
||||||
|
|
||||||
|
foreach ($stmt->fetchAll() as $p) {
|
||||||
|
$photosSlots[(int)$p['param_position']] = $p['filename'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slot dinamici per la linea
|
||||||
|
$slots = $r['param_slots'] ?? [];
|
||||||
|
|
||||||
|
if (empty($slots)) {
|
||||||
|
echo "<div style='color:#999; padding:8px;'>Nessun parametro configurato per questa linea.</div>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="param-grid" style="grid-template-columns: repeat(<?= count($slots) ?>, 1fr);">
|
||||||
|
<?php foreach ($slots as $slot): ?>
|
||||||
|
<?php
|
||||||
|
$pos = (int)$slot['position'];
|
||||||
|
$label = htmlspecialchars($slot['short_label']);
|
||||||
|
$img = $photosSlots[$pos] ?? null;
|
||||||
|
?>
|
||||||
|
<div class="param-slot" data-slot="<?= $pos ?>" data-production="<?= $r['id'] ?>">
|
||||||
|
<div class="thumb">
|
||||||
|
<?php if ($img): ?>
|
||||||
|
<img src="photos/<?= htmlspecialchars($img) ?>" class="thumb-img">
|
||||||
|
<?php else: ?>
|
||||||
|
<img src="assets/placeholder-photo.png" class="thumb-img">
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<div class="param-label"><?= $label ?></div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="photo-actions" style="margin-top:12px; display:flex; gap:12px; width:100%; align-items:center;">
|
||||||
|
|
||||||
|
<!-- Lotto mescola -->
|
||||||
|
<button class="photo-btn"
|
||||||
|
data-type="lotto_mescola"
|
||||||
|
data-production="<?= $r['id'] ?>"
|
||||||
|
title="Foto Lotti Mescola">
|
||||||
|
<i class="bi bi-box-seam" style="font-size:1.8rem; color:#334155;"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Problemi -->
|
||||||
|
<button class="photo-btn"
|
||||||
|
data-type="problema"
|
||||||
|
data-production="<?= $r['id'] ?>"
|
||||||
|
title="Foto Problemi">
|
||||||
|
<i class="bi bi-exclamation-triangle" style="font-size:1.8rem; color:#b91c1c;"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- 🔥 SPAZIO PER PORTARE A DESTRA -->
|
||||||
|
<div style="flex-grow:1;"></div>
|
||||||
|
|
||||||
|
<!-- 🔵 ICONA QUALITÀ -->
|
||||||
|
<button class="photo-btn qc-btn"
|
||||||
|
data-production="<?= $r['id'] ?>"
|
||||||
|
title="Controlli Qualità">
|
||||||
|
<i class="bi bi-droplet-half"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
<div id="photoModal" class="custom-modal">
|
||||||
|
<div class="modal-content final-wide" style="max-width:800px; position:relative;">
|
||||||
|
|
||||||
|
<!-- X per chiudere -->
|
||||||
|
<button id="photoModalCloseX"
|
||||||
|
style="position:absolute; top:10px; right:15px; font-size:1.7rem; background:none; border:none; cursor:pointer;">
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<h3 id="photoModalTitle">Carica Foto</h3>
|
||||||
|
<p id="photoModalSubtitle"></p>
|
||||||
|
|
||||||
|
<div id="photoMessageSuccess"
|
||||||
|
style="display:none; margin-bottom:10px; padding:8px 12px; border-radius:8px; background:#dcfce7; color:#166534; font-weight:500; text-align:left;">
|
||||||
|
✅ Foto caricata correttamente.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="photoMessageError"
|
||||||
|
style="display:none; margin-bottom:10px; padding:8px 12px; border-radius:8px; background:#fee2e2; color:#b91c1c; font-weight:500; text-align:left;">
|
||||||
|
⚠️ Errore durante il caricamento.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="photoForm" enctype="multipart/form-data">
|
||||||
|
<input type="hidden" name="production_id" id="photoProductionId">
|
||||||
|
<input type="hidden" name="photo_type" id="photoType">
|
||||||
|
<input type="hidden" name="param_position" id="photoParamPosition">
|
||||||
|
|
||||||
|
<!-- ✅ input file DENTRO al form -->
|
||||||
|
<input type="file" name="photo" id="photoInput"
|
||||||
|
accept="image/*;capture=camera"
|
||||||
|
style="display:none;">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label><strong>Carica o scatta una foto:</strong></label>
|
||||||
|
<button type="button" class="modal-btn" id="choosePhotoBtn">Scegli foto</button>
|
||||||
|
<span id="selectedPhotoName" style="margin-left:8px; font-size:0.85rem; color:#64748b;"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 🔥 loader -->
|
||||||
|
<div id="photoLoading"
|
||||||
|
style="display:none; margin-top:10px; font-size:0.9rem; color:#64748b;">
|
||||||
|
⏳ Caricamento in corso...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="singlePhotoInfo"
|
||||||
|
style="display:none; margin-top:10px; font-size:0.9rem; color:#b91c1c; text-align:left;">
|
||||||
|
Per questo parametro è già presente una foto.
|
||||||
|
Se vuoi sostituirla, chiedi all'amministratore di cancellare quella esistente.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal-buttons" style="margin-top:1.5rem;">
|
||||||
|
<button type="button" id="photoCancel" class="modal-btn modal-cancel">Annulla</button>
|
||||||
|
<button type="submit" class="modal-btn modal-confirm">Carica</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<hr style="margin:1.5rem 0;">
|
||||||
|
|
||||||
|
<h4 style="font-size:1rem; margin-bottom:0.7rem;">Foto già registrate per questa tipologia</h4>
|
||||||
|
|
||||||
|
<div id="photoGallery" class="photo-gallery"
|
||||||
|
style="display:flex; flex-wrap:wrap; gap:10px; max-height:220px; overflow-y:auto; padding:4px 0;">
|
||||||
|
<!-- thumbnails caricati via JS -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Questo file può essere vuoto o contenere logica PHP aggiuntiva se necessario
|
|
||||||
?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="it">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Autenticazione VisualLims</title>
|
|
||||||
<!-- Includi Select2 CSS -->
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
max-width: 600px;
|
|
||||||
margin: 20px auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#authButton {
|
|
||||||
padding: 10px 20px;
|
|
||||||
background-color: #007bff;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#authButton:hover {
|
|
||||||
background-color: #0056b3;
|
|
||||||
}
|
|
||||||
|
|
||||||
#result {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
#schemiResult {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select2-container {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Autenticazione VisualLims</h1>
|
|
||||||
<button id="authButton">Autentica</button>
|
|
||||||
<div id="result"></div>
|
|
||||||
|
|
||||||
<!-- Tendina per i clienti -->
|
|
||||||
<h3>Seleziona un cliente:</h3>
|
|
||||||
<select id="clientiSelect" style="width: 100%;">
|
|
||||||
<option value="">Seleziona un cliente...</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<!-- Area per mostrare gli schemi -->
|
|
||||||
<div id="schemiResult"></div>
|
|
||||||
|
|
||||||
<!-- Includi jQuery (necessario per Select2) -->
|
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
||||||
<!-- Includi Select2 JS -->
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Inizializza Select2 sulla tendina
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#clientiSelect').select2({
|
|
||||||
placeholder: "Cerca un cliente...",
|
|
||||||
allowClear: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Carica i clienti al caricamento della pagina
|
|
||||||
loadClienti();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Autenticazione
|
|
||||||
document.getElementById('authButton').addEventListener('click', async () => {
|
|
||||||
const resultDiv = document.getElementById('result');
|
|
||||||
resultDiv.textContent = 'Autenticazione in corso...';
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch('auth_proxy.php', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Errore HTTP! Stato: ${response.status}, Dettagli: ${data.error || 'Nessun dettaglio disponibile'}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof data === 'string' && data.length > 0) {
|
|
||||||
resultDiv.textContent = `Token: ${data}`;
|
|
||||||
} else if (data && data.token) {
|
|
||||||
resultDiv.textContent = `Token: ${data.token}`;
|
|
||||||
} else {
|
|
||||||
resultDiv.textContent = `Autenticazione fallita: Nessun token ricevuto. Dettagli: ${JSON.stringify(data)}`;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
resultDiv.textContent = `Errore: ${error.message}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Funzione per caricare i clienti nella tendina
|
|
||||||
async function loadClienti() {
|
|
||||||
const resultDiv = document.getElementById('result');
|
|
||||||
resultDiv.textContent = 'Caricamento clienti...';
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch('get_clienti.php', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({})
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
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('clientiSelect');
|
|
||||||
data.value.forEach(c => {
|
|
||||||
const nome = c.Nominativo || 'Nome non disponibile';
|
|
||||||
const id = c.IdCliente || 'ID non disponibile';
|
|
||||||
const option = new Option(`${nome.trim()} (ID: ${id})`, id);
|
|
||||||
select.add(option);
|
|
||||||
});
|
|
||||||
resultDiv.textContent = 'Clienti caricati con successo.';
|
|
||||||
} else {
|
|
||||||
resultDiv.textContent = 'Nessun cliente trovato o formato dati non valido.';
|
|
||||||
console.log('Risposta API:', data);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
resultDiv.textContent = 'Errore: ' + err.message;
|
|
||||||
console.error('Dettagli errore:', err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evento per gestire la selezione di un cliente e recuperare gli schemi
|
|
||||||
$('#clientiSelect').on('select2:select', async function(e) {
|
|
||||||
const clienteId = e.target.value; // Oppure: $(this).val()
|
|
||||||
const schemiDiv = document.getElementById('schemiResult'); // Correzione del nome variabile
|
|
||||||
|
|
||||||
// Log per debug
|
|
||||||
console.log('Cliente selezionato:', clienteId);
|
|
||||||
|
|
||||||
if (!clienteId) {
|
|
||||||
schemiDiv.textContent = '';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
schemiDiv.textContent = 'Caricamento schemi...';
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch('get_schemi.php', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
clienteId
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(data.error || `Errore HTTP: ${response.status}, Dettagli: ${JSON.stringify(data)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.SchemiAbilitati && Array.isArray(data.SchemiAbilitati)) {
|
|
||||||
let html = '<h3>Schemi Abilitati:</h3><ul>';
|
|
||||||
data.SchemiAbilitati.forEach(s => {
|
|
||||||
const nomeSchema = s.NomeSchema || s.Descrizione || 'Schema non specificato';
|
|
||||||
html += `<li>${nomeSchema}</li>`;
|
|
||||||
});
|
|
||||||
html += '</ul>';
|
|
||||||
schemiDiv.innerHTML = html;
|
|
||||||
} else {
|
|
||||||
schemiDiv.textContent = 'Nessuno schema trovato per questo cliente.';
|
|
||||||
console.log('Risposta Schemi:', data);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
schemiDiv.textContent = 'Errore: ' + err.message;
|
|
||||||
console.error('Dettagli errore:', err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Gestisci la deselezione (opzionale)
|
|
||||||
$('#clientiSelect').on('select2:unselect', function(e) {
|
|
||||||
const schemiDiv = document.getElementById('schemiResult'); // Correzione del nome variabile
|
|
||||||
schemiDiv.textContent = '';
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -13,10 +13,145 @@
|
|||||||
<link href="assets/css/app.css" rel="stylesheet">
|
<link href="assets/css/app.css" rel="stylesheet">
|
||||||
<link href="assets/css/icons.css" rel="stylesheet">
|
<link href="assets/css/icons.css" rel="stylesheet">
|
||||||
<!-- Theme Style CSS -->
|
<!-- Theme Style CSS -->
|
||||||
<link rel="stylesheet" href="assets/css/dark-theme.css" />
|
<!-- <link rel="stylesheet" href="assets/css/dark-theme.css" />
|
||||||
<link rel="stylesheet" href="assets/css/semi-dark.css" />
|
<link rel="stylesheet" href="assets/css/semi-dark.css" />
|
||||||
<link rel="stylesheet" href="assets/css/header-colors.css" />
|
<link rel="stylesheet" href="assets/css/header-colors.css" /> -->
|
||||||
<!-- Font awesome -->
|
<!-- Font awesome -->
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
|
||||||
<!-- SweetAlert2 -->
|
<!-- SweetAlert2 -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
<!-- Override temporaneo per tema chiaro pastello -->
|
||||||
|
<style>
|
||||||
|
/* ======= HEADER (barra superiore) ======= */
|
||||||
|
.top-header {
|
||||||
|
background-color: #a4c4fdff !important;
|
||||||
|
/* azzurro pastello */
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-header .nav-link,
|
||||||
|
.top-header .navbar-brand,
|
||||||
|
.top-header .navbar-nav .nav-item a,
|
||||||
|
.top-header .dropdown-item {
|
||||||
|
color: #1a2a3b !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-header .nav-link:hover,
|
||||||
|
.top-header .navbar-nav .nav-item a:hover,
|
||||||
|
.top-header .dropdown-item:hover {
|
||||||
|
color: #0b5ed7 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======= SIDEBAR (menu laterale) ======= */
|
||||||
|
.sidebar-wrapper {
|
||||||
|
background-color: #dfebffff !important;
|
||||||
|
/* grigio chiaro con tono bluastro */
|
||||||
|
color: #2b3e50 !important;
|
||||||
|
box-shadow: inset -2px 0 5px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper .metismenu a {
|
||||||
|
color: #2b3e50 !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
border-radius: 6px !important;
|
||||||
|
padding: 10px 14px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-wrapper .metismenu a:hover,
|
||||||
|
.sidebar-wrapper .metismenu .mm-active>a {
|
||||||
|
background-color: #d6e4ff !important;
|
||||||
|
/* azzurro più deciso al passaggio */
|
||||||
|
color: #0d6efd !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======= CORPO PAGINA ======= */
|
||||||
|
body {
|
||||||
|
background-color: #f8fafc !important;
|
||||||
|
color: #2b3e50 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card,
|
||||||
|
.form-container,
|
||||||
|
.table-container {
|
||||||
|
background-color: #ffffff !important;
|
||||||
|
border: 1px solid #e2e8f0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pulsanti principali coerenti */
|
||||||
|
.btn-primary,
|
||||||
|
.btn-submit {
|
||||||
|
background-color: #0d6efd !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover,
|
||||||
|
.btn-submit:hover {
|
||||||
|
background-color: #0b5ed7 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navbar icone (se presenti) */
|
||||||
|
.top-header i {
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* ======= TOPBAR (barra superiore, con menu e profilo utente) ======= */
|
||||||
|
.topbar {
|
||||||
|
background-color: #a4c4fdff !important;
|
||||||
|
/* azzurro pastello */
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar .nav-link,
|
||||||
|
.topbar .navbar-nav .nav-item a,
|
||||||
|
.topbar .navbar-brand,
|
||||||
|
.topbar .dropdown-item {
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
font-weight: 500 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar .nav-link:hover,
|
||||||
|
.topbar .navbar-nav .nav-item a:hover,
|
||||||
|
.topbar .dropdown-item:hover {
|
||||||
|
color: #0d6efd !important;
|
||||||
|
background-color: rgba(255, 255, 255, 0.3) !important;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar .user-box .user-info p {
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar .dropdown-menu {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======= SIDEBAR HEADER (logo + titolo) ======= */
|
||||||
|
.sidebar-header {
|
||||||
|
background-color: #a4c4fdff !important;
|
||||||
|
/* leggermente più scuro per separare dal resto */
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
border-bottom: 1px solid #a8c5f9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-header .logo-text {
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-header .toggle-icon i {
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======= ICONCINE GENERICHE ======= */
|
||||||
|
.bx,
|
||||||
|
.fa {
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
require_once(__DIR__ . '/class/db-functions.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (int)$_GET['id'];
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM production_lines WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
|
||||||
|
if ($stmt->rowCount() > 0) {
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} else {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Linea non trovata o già eliminata.']);
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
include('../class/db-functions.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isset($_GET['id'])) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID non fornito.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = intval($_GET['id']);
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// Cancella eventuali associazioni
|
||||||
|
$pdo->prepare("DELETE FROM matrice_lines WHERE idmatrice = ?")->execute([$id]);
|
||||||
|
$pdo->prepare("DELETE FROM matrice_mescole WHERE idmatrice = ?")->execute([$id]);
|
||||||
|
|
||||||
|
// Cancella la matrice
|
||||||
|
$pdo->prepare("DELETE FROM matrice WHERE id = ?")->execute([$id]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'message' => 'Matrice eliminata con successo.']);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'success' => false,
|
||||||
|
'message' => ''
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
throw new Exception('Metodo non consentito');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($_POST['id']) || !is_numeric($_POST['id'])) {
|
||||||
|
throw new Exception('ID allegato non valido');
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (int)$_POST['id'];
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("SELECT id, file_path FROM matrice_attachments WHERE id = :id LIMIT 1");
|
||||||
|
$stmt->execute([':id' => $id]);
|
||||||
|
$attachment = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$attachment) {
|
||||||
|
throw new Exception('Allegato non trovato');
|
||||||
|
}
|
||||||
|
|
||||||
|
$filePathRelative = ltrim((string)$attachment['file_path'], '/\\');
|
||||||
|
$filePathAbsolute = __DIR__ . '/' . $filePathRelative;
|
||||||
|
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
$deleteStmt = $pdo->prepare("DELETE FROM matrice_attachments WHERE id = :id");
|
||||||
|
$deleteStmt->execute([':id' => $id]);
|
||||||
|
|
||||||
|
if ($deleteStmt->rowCount() <= 0) {
|
||||||
|
throw new Exception('Impossibile eliminare il record allegato');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($filePathRelative) && file_exists($filePathAbsolute) && is_file($filePathAbsolute)) {
|
||||||
|
@unlink($filePathAbsolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
$response['success'] = true;
|
||||||
|
$response['message'] = 'Allegato eliminato correttamente';
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
if (isset($pdo) && $pdo instanceof PDO && $pdo->inTransaction()) {
|
||||||
|
$pdo->rollBack();
|
||||||
|
}
|
||||||
|
$response['message'] = $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($response, JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$id = isset($_POST['id']) ? (int)$_POST['id'] : 0;
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid id']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM mescole_supplier_lots WHERE id = ?");
|
||||||
|
$ok = $stmt->execute([$id]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => (bool)$ok]);
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$id = isset($_POST['id']) ? (int)$_POST['id'] : 0;
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid id']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM packaging_stock_lots WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid parameter id.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// Check existence
|
||||||
|
$stmt = $pdo->prepare("SELECT id FROM production_line_params WHERE id = :id");
|
||||||
|
$stmt->execute([':id' => $id]);
|
||||||
|
|
||||||
|
if (!$stmt->fetchColumn()) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Parameter not found.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
$del = $pdo->prepare("DELETE FROM production_line_params WHERE id = :id");
|
||||||
|
$del->execute([':id' => $id]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Parameter deleted successfully.'
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Server error: ' . $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<?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()]);
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<?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,35 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/class/db-functions.php';
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$id = (int)($_GET['id'] ?? 0);
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Verifica se è usata in production_pauses
|
||||||
|
$check = $pdo->prepare("SELECT COUNT(*) FROM production_pauses WHERE reason_id = :id");
|
||||||
|
$check->execute([':id' => $id]);
|
||||||
|
$used = $check->fetchColumn();
|
||||||
|
|
||||||
|
if ($used > 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Impossibile eliminare: la causa è utilizzata in una o più pause.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elimina
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM pause_reasons WHERE id = :id");
|
||||||
|
$stmt->execute([':id' => $id]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
// delete_photo.php
|
|
||||||
include('include/headscript.php');
|
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['photo_id'])) {
|
|
||||||
echo json_encode(['success' => false, 'message' => 'Richiesta non valida']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$photoId = intval($_POST['photo_id']);
|
|
||||||
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
|
||||||
$pdo = $db->getConnection();
|
|
||||||
|
|
||||||
// Recupera il percorso del file
|
|
||||||
$stmt = $pdo->prepare("SELECT file_path FROM datadb_photos WHERE id = ?");
|
|
||||||
$stmt->execute([$photoId]);
|
|
||||||
$photo = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
if (!$photo) {
|
|
||||||
echo json_encode(['success' => false, 'message' => 'Foto non trovata']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elimina il file dal server
|
|
||||||
$filePath = '../photostrf/' . $photo['file_path'];
|
|
||||||
if (file_exists($filePath)) {
|
|
||||||
unlink($filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elimina il record dal database
|
|
||||||
$stmt = $pdo->prepare("DELETE FROM datadb_photos WHERE id = ?");
|
|
||||||
$stmt->execute([$photoId]);
|
|
||||||
|
|
||||||
echo json_encode(['success' => true, 'message' => 'Foto eliminata con successo']);
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
if (empty($_POST['id'])) {
|
||||||
|
echo json_encode(['success' => false, 'msg' => 'ID mancante']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM productiondata WHERE id = :id");
|
||||||
|
$stmt->execute(['id' => $_POST['id']]);
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'msg' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Enable errors for debugging
|
|
||||||
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__ . '/delete_record_debug.log');
|
|
||||||
|
|
||||||
// Log iniziale
|
|
||||||
error_log("Inizio cancellazione record alle " . date('Y-m-d H:i:s'));
|
|
||||||
|
|
||||||
// Includi il file di configurazione del database
|
|
||||||
include('include/headscript.php');
|
|
||||||
|
|
||||||
// Ricevi l'ID dalla richiesta POST
|
|
||||||
$input = json_decode(file_get_contents('php://input'), true);
|
|
||||||
$iddatadb = isset($input['id']) ? intval($input['id']) : 0;
|
|
||||||
|
|
||||||
if ($iddatadb <= 0) {
|
|
||||||
http_response_code(400);
|
|
||||||
echo json_encode(['success' => false, 'message' => 'ID non valido']);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connessione al database
|
|
||||||
try {
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
|
||||||
$pdo = $db->getConnection();
|
|
||||||
} catch (Exception $e) {
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode(['success' => false, 'message' => 'Errore di connessione al database: ' . $e->getMessage()]);
|
|
||||||
error_log("Errore di connessione al database: " . $e->getMessage());
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inizia una transazione
|
|
||||||
$pdo->beginTransaction();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Elimina i dettagli associati dal tavolo import_data_details
|
|
||||||
$stmt = $pdo->prepare("DELETE FROM import_data_details WHERE id = ?");
|
|
||||||
$stmt->execute([$iddatadb]);
|
|
||||||
|
|
||||||
// Elimina il record principale dal tavolo datadb
|
|
||||||
$stmt = $pdo->prepare("DELETE FROM datadb WHERE iddatadb = ?");
|
|
||||||
$stmt->execute([$iddatadb]);
|
|
||||||
|
|
||||||
// Verifica se il record è stato eliminato
|
|
||||||
if ($stmt->rowCount() > 0) {
|
|
||||||
$pdo->commit();
|
|
||||||
echo json_encode(['success' => true, 'message' => 'Record eliminato con successo']);
|
|
||||||
error_log("Record con iddatadb=$iddatadb eliminato con successo");
|
|
||||||
} else {
|
|
||||||
$pdo->rollBack();
|
|
||||||
http_response_code(404);
|
|
||||||
echo json_encode(['success' => false, 'message' => 'Record non trovato']);
|
|
||||||
error_log("Record con iddatadb=$iddatadb non trovato");
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$pdo->rollBack();
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode(['success' => false, 'message' => 'Errore durante la cancellazione: ' . $e->getMessage()]);
|
|
||||||
error_log("Errore durante la cancellazione del record con iddatadb=$iddatadb: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$id = intval($_GET['id'] ?? 0);
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID non valido']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica se status è usato in produzione
|
||||||
|
$check = $pdo->prepare("SELECT COUNT(*) FROM productiondata WHERE id_status = :id");
|
||||||
|
$check->execute([':id' => $id]);
|
||||||
|
$count = $check->fetchColumn();
|
||||||
|
|
||||||
|
if ($count > 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => "Impossibile eliminare: lo status è utilizzato in $count record di produzione."
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eliminazione
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM production_status WHERE id = :id");
|
||||||
|
$stmt->execute([':id' => $id]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Abilita la gestione degli errori
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
// Includi la connessione al database
|
|
||||||
require_once 'class/db-functions.php';
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Controlla se è stato passato un ID valido
|
|
||||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|
||||||
throw new Exception('Invalid ID');
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = intval($_GET['id']); // Sanifica l'ID
|
|
||||||
|
|
||||||
// Connessione al database
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
|
||||||
$pdo = $db->getConnection();
|
|
||||||
|
|
||||||
if (!$pdo) {
|
|
||||||
throw new Exception('Database connection failed');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifica se l'ID esiste
|
|
||||||
$stmtCheck = $pdo->prepare("SELECT id FROM excel_templates WHERE id = ?");
|
|
||||||
$stmtCheck->execute([$id]);
|
|
||||||
if ($stmtCheck->rowCount() === 0) {
|
|
||||||
throw new Exception('Template not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Esegui l'eliminazione
|
|
||||||
$stmt = $pdo->prepare("DELETE FROM excel_templates WHERE id = ?");
|
|
||||||
$stmt->execute([$id]);
|
|
||||||
|
|
||||||
if ($stmt->rowCount() > 0) {
|
|
||||||
$message = "Template deleted successfully!";
|
|
||||||
$status = "success";
|
|
||||||
} else {
|
|
||||||
throw new Exception('Failed to delete template');
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
$message = $e->getMessage();
|
|
||||||
$status = "error";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reindirizza con un messaggio
|
|
||||||
header("Location: templates_dashboard.php?status=$status&message=" . urlencode($message));
|
|
||||||
exit;
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
require_once 'include/headscript.php';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$id = (int)($_POST['id'] ?? 0);
|
||||||
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
$tool_type = trim($_POST['tool_type'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$is_active = isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1;
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid ID.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($name === '') {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Name is required.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "UPDATE production_tools
|
||||||
|
SET name = :name,
|
||||||
|
tool_type = :tool_type,
|
||||||
|
description = :description,
|
||||||
|
is_active = :is_active
|
||||||
|
WHERE id = :id";
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([
|
||||||
|
'name' => $name,
|
||||||
|
'tool_type' => $tool_type ?: null,
|
||||||
|
'description' => $description ?: null,
|
||||||
|
'is_active' => $is_active,
|
||||||
|
'id' => $id
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,799 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
/* ==========================================
|
||||||
|
AJAX HANDLERS
|
||||||
|
========================================== */
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] == '1') {
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$action = $_POST['action'] ?? '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($action === 'add') {
|
||||||
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
$code = trim($_POST['code'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$color = trim($_POST['color'] ?? '#6c757d');
|
||||||
|
$sort_order = isset($_POST['sort_order']) && $_POST['sort_order'] !== '' ? (int)$_POST['sort_order'] : 999;
|
||||||
|
$is_active = isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1;
|
||||||
|
|
||||||
|
if ($name === '') {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Department name is required.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($code === '') {
|
||||||
|
$code = strtoupper(str_replace(' ', '_', $name));
|
||||||
|
$code = preg_replace('/[^A-Z0-9_]/', '', $code);
|
||||||
|
} else {
|
||||||
|
$code = strtoupper($code);
|
||||||
|
$code = preg_replace('/[^A-Z0-9_]/', '', $code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('/^#[0-9A-Fa-f]{6}$/', $color)) {
|
||||||
|
$color = '#6c757d';
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_active = $is_active === 1 ? 1 : 0;
|
||||||
|
|
||||||
|
$check = $pdo->prepare("
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM departments
|
||||||
|
WHERE name = :name OR code = :code
|
||||||
|
");
|
||||||
|
$check->execute([
|
||||||
|
'name' => $name,
|
||||||
|
'code' => $code
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ((int)$check->fetchColumn() > 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'A department with the same name or code already exists.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "INSERT INTO departments
|
||||||
|
(name, code, description, color, sort_order, is_active, created_at, updated_at)
|
||||||
|
VALUES
|
||||||
|
(:name, :code, :description, :color, :sort_order, :is_active, NOW(), NOW())";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([
|
||||||
|
'name' => $name,
|
||||||
|
'code' => $code !== '' ? $code : null,
|
||||||
|
'description' => $description !== '' ? $description : null,
|
||||||
|
'color' => $color,
|
||||||
|
'sort_order' => $sort_order,
|
||||||
|
'is_active' => $is_active
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'edit') {
|
||||||
|
$id = (int)($_POST['id'] ?? 0);
|
||||||
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
$code = trim($_POST['code'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$color = trim($_POST['color'] ?? '#6c757d');
|
||||||
|
$sort_order = isset($_POST['sort_order']) && $_POST['sort_order'] !== '' ? (int)$_POST['sort_order'] : 999;
|
||||||
|
$is_active = isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1;
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Invalid department ID.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($name === '') {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Department name is required.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($code === '') {
|
||||||
|
$code = strtoupper(str_replace(' ', '_', $name));
|
||||||
|
$code = preg_replace('/[^A-Z0-9_]/', '', $code);
|
||||||
|
} else {
|
||||||
|
$code = strtoupper($code);
|
||||||
|
$code = preg_replace('/[^A-Z0-9_]/', '', $code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preg_match('/^#[0-9A-Fa-f]{6}$/', $color)) {
|
||||||
|
$color = '#6c757d';
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_active = $is_active === 1 ? 1 : 0;
|
||||||
|
|
||||||
|
$check = $pdo->prepare("
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM departments
|
||||||
|
WHERE (name = :name OR code = :code)
|
||||||
|
AND id <> :id
|
||||||
|
");
|
||||||
|
$check->execute([
|
||||||
|
'name' => $name,
|
||||||
|
'code' => $code,
|
||||||
|
'id' => $id
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ((int)$check->fetchColumn() > 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Another department with the same name or code already exists.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "UPDATE departments
|
||||||
|
SET name = :name,
|
||||||
|
code = :code,
|
||||||
|
description = :description,
|
||||||
|
color = :color,
|
||||||
|
sort_order = :sort_order,
|
||||||
|
is_active = :is_active,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = :id";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([
|
||||||
|
'name' => $name,
|
||||||
|
'code' => $code !== '' ? $code : null,
|
||||||
|
'description' => $description !== '' ? $description : null,
|
||||||
|
'color' => $color,
|
||||||
|
'sort_order' => $sort_order,
|
||||||
|
'is_active' => $is_active,
|
||||||
|
'id' => $id
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($action === 'delete') {
|
||||||
|
$id = (int)($_POST['id'] ?? 0);
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Invalid department ID.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Future-proof check:
|
||||||
|
* If later you add employees.department_id, this prevents deleting
|
||||||
|
* a department already used by employees.
|
||||||
|
*/
|
||||||
|
$columnCheck = $pdo->prepare("
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'employees'
|
||||||
|
AND COLUMN_NAME = 'department_id'
|
||||||
|
");
|
||||||
|
$columnCheck->execute();
|
||||||
|
$hasDepartmentId = (int)$columnCheck->fetchColumn() > 0;
|
||||||
|
|
||||||
|
if ($hasDepartmentId) {
|
||||||
|
$usageCheck = $pdo->prepare("
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM employees
|
||||||
|
WHERE department_id = :id
|
||||||
|
");
|
||||||
|
$usageCheck->execute(['id' => $id]);
|
||||||
|
|
||||||
|
if ((int)$usageCheck->fetchColumn() > 0) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'This department is linked to one or more employees and cannot be deleted.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("DELETE FROM departments WHERE id = :id");
|
||||||
|
$stmt->execute(['id' => $id]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Unknown action.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================
|
||||||
|
PAGE DATA
|
||||||
|
========================================== */
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
SELECT *
|
||||||
|
FROM departments
|
||||||
|
ORDER BY sort_order ASC, name ASC
|
||||||
|
";
|
||||||
|
$stmtDepartments = $pdo->query($sql);
|
||||||
|
$departments = $stmtDepartments->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="it">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||||||
|
<?php include('cssinclude.php'); ?>
|
||||||
|
<title>Gestione Departments - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
||||||
|
|
||||||
|
<!-- jQuery and Bootstrap -->
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
|
||||||
|
<!-- DataTables -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css">
|
||||||
|
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
|
||||||
|
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
background: #f8fafc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-dashboard {
|
||||||
|
background-color: #cfe3ff !important;
|
||||||
|
color: #1f2d3d !important;
|
||||||
|
border: 1px solid #bcd4f4 !important;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 10px 18px;
|
||||||
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-dashboard:hover {
|
||||||
|
background-color: #b9d3ff !important;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-add {
|
||||||
|
background-color: #0d6efd;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-add:hover {
|
||||||
|
background-color: #0b5ed7;
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table thead {
|
||||||
|
background-color: #cfe3ff;
|
||||||
|
color: #1f2d3d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabellaDepartments thead th {
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-status {
|
||||||
|
padding: 0.25rem 0.6rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-status.active {
|
||||||
|
background-color: #d1fae5;
|
||||||
|
color: #065f46;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-status.inactive {
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.department-color-dot {
|
||||||
|
display: inline-block;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.department-code {
|
||||||
|
font-family: Consolas, Monaco, monospace;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
background: #f1f5f9;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #334155;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-cell {
|
||||||
|
max-width: 320px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="wrapper toggled">
|
||||||
|
<?php include('include/navbar.php'); ?>
|
||||||
|
<?php include('include/topbar.php'); ?>
|
||||||
|
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="card p-3">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="mb-0">Gestione Departments</h5>
|
||||||
|
<button type="button" class="btn back-dashboard" onclick="location.href='production_dashboard.php'">
|
||||||
|
↩️ Torna alla Dashboard
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||||
|
<h6 class="fw-semibold mb-0">Elenco Reparti / Departments</h6>
|
||||||
|
|
||||||
|
<button class="btn btn-add" data-bs-toggle="modal" data-bs-target="#addDepartmentModal">
|
||||||
|
➕ Aggiungi Department
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table id="tabellaDepartments" class="table table-striped align-middle text-center" style="width:100%;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Color</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Code</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Order</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Created</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<?php if (!empty($departments)): ?>
|
||||||
|
<?php foreach ($departments as $row): ?>
|
||||||
|
<?php
|
||||||
|
$id = (int)$row['id'];
|
||||||
|
$name = $row['name'] ?? '';
|
||||||
|
$code = $row['code'] ?? '';
|
||||||
|
$description = $row['description'] ?? '';
|
||||||
|
$color = $row['color'] ?? '#6c757d';
|
||||||
|
$sortOrder = (int)($row['sort_order'] ?? 999);
|
||||||
|
$isActive = (int)($row['is_active'] ?? 1);
|
||||||
|
|
||||||
|
$statusClass = $isActive === 1 ? 'active' : 'inactive';
|
||||||
|
$statusLabel = $isActive === 1 ? 'Active' : 'Inactive';
|
||||||
|
|
||||||
|
$createdAt = !empty($row['created_at'])
|
||||||
|
? date('d/m/Y H:i', strtotime($row['created_at']))
|
||||||
|
: '-';
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?= $id ?></td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<span class="department-color-dot" style="background-color: <?= htmlspecialchars($color, ENT_QUOTES) ?>;"></span>
|
||||||
|
<?= htmlspecialchars($color) ?>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="fw-semibold">
|
||||||
|
<?= htmlspecialchars($name) ?>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<?php if ($code !== ''): ?>
|
||||||
|
<span class="department-code"><?= htmlspecialchars($code) ?></span>
|
||||||
|
<?php else: ?>
|
||||||
|
-
|
||||||
|
<?php endif; ?>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="description-cell" title="<?= htmlspecialchars($description, ENT_QUOTES) ?>">
|
||||||
|
<?= $description !== '' ? htmlspecialchars($description) : '-' ?>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td><?= $sortOrder ?></td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<span class="badge-status <?= $statusClass ?>">
|
||||||
|
<?= htmlspecialchars($statusLabel) ?>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td><?= $createdAt ?></td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-outline-secondary edit-department"
|
||||||
|
data-id="<?= $id ?>"
|
||||||
|
data-name="<?= htmlspecialchars($name, ENT_QUOTES) ?>"
|
||||||
|
data-code="<?= htmlspecialchars($code, ENT_QUOTES) ?>"
|
||||||
|
data-description="<?= htmlspecialchars($description, ENT_QUOTES) ?>"
|
||||||
|
data-color="<?= htmlspecialchars($color, ENT_QUOTES) ?>"
|
||||||
|
data-sort_order="<?= $sortOrder ?>"
|
||||||
|
data-is_active="<?= $isActive ?>">
|
||||||
|
✏️ Modifica
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-outline-danger delete-department"
|
||||||
|
data-id="<?= $id ?>"
|
||||||
|
data-name="<?= htmlspecialchars($name, ENT_QUOTES) ?>">
|
||||||
|
🗑️ Cancella
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include('include/footer.php'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ADD DEPARTMENT MODAL -->
|
||||||
|
<div class="modal fade" id="addDepartmentModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header" style="background-color:#cfe3ff;">
|
||||||
|
<h5 class="modal-title">Aggiungi Department</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="addDepartmentForm">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Name</label>
|
||||||
|
<input type="text" class="form-control" id="addName" name="name" placeholder="e.g. Produzione" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Code</label>
|
||||||
|
<input type="text" class="form-control" id="addCode" name="code" placeholder="Optional, e.g. PRODUZIONE">
|
||||||
|
<small class="text-muted">If empty, it will be generated automatically from the name.</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Description</label>
|
||||||
|
<textarea class="form-control" id="addDescription" name="description" rows="3" placeholder="Optional notes"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label fw-semibold">Color</label>
|
||||||
|
<input type="color" class="form-control form-control-color" id="addColor" name="color" value="#6c757d">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label fw-semibold">Sort Order</label>
|
||||||
|
<input type="number" class="form-control" id="addSortOrder" name="sort_order" value="999" min="0">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Status</label>
|
||||||
|
<select class="form-select" id="addIsActive" name="is_active">
|
||||||
|
<option value="1" selected>Active</option>
|
||||||
|
<option value="0">Inactive</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit" class="btn btn-add">💾 Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- EDIT DEPARTMENT MODAL -->
|
||||||
|
<div class="modal fade" id="editDepartmentModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header" style="background-color:#cfe3ff;">
|
||||||
|
<h5 class="modal-title">Modifica Department</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="editDepartmentForm">
|
||||||
|
<input type="hidden" id="editDepartmentId">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Name</label>
|
||||||
|
<input type="text" class="form-control" id="editName" name="name" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Code</label>
|
||||||
|
<input type="text" class="form-control" id="editCode" name="code">
|
||||||
|
<small class="text-muted">If empty, it will be generated automatically from the name.</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Description</label>
|
||||||
|
<textarea class="form-control" id="editDescription" name="description" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label fw-semibold">Color</label>
|
||||||
|
<input type="color" class="form-control form-control-color" id="editColor" name="color" value="#6c757d">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label class="form-label fw-semibold">Sort Order</label>
|
||||||
|
<input type="number" class="form-control" id="editSortOrder" name="sort_order" value="999" min="0">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label fw-semibold">Status</label>
|
||||||
|
<select class="form-select" id="editIsActive" name="is_active">
|
||||||
|
<option value="1">Active</option>
|
||||||
|
<option value="0">Inactive</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<button type="submit" class="btn btn-add">💾 Save Changes</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include('jsinclude.php'); ?>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#tabellaDepartments').DataTable({
|
||||||
|
order: [
|
||||||
|
[5, 'asc'],
|
||||||
|
[2, 'asc']
|
||||||
|
],
|
||||||
|
pageLength: 25,
|
||||||
|
language: {
|
||||||
|
url: 'https://cdn.datatables.net/plug-ins/1.13.6/i18n/it-IT.json',
|
||||||
|
emptyTable: 'Nessun department presente'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------- ADD DEPARTMENT -------- */
|
||||||
|
$("#addDepartmentForm").on("submit", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const payload = new URLSearchParams();
|
||||||
|
payload.append('ajax', '1');
|
||||||
|
payload.append('action', 'add');
|
||||||
|
payload.append('name', $("#addName").val().trim());
|
||||||
|
payload.append('code', $("#addCode").val().trim());
|
||||||
|
payload.append('description', $("#addDescription").val().trim());
|
||||||
|
payload.append('color', $("#addColor").val());
|
||||||
|
payload.append('sort_order', $("#addSortOrder").val());
|
||||||
|
payload.append('is_active', $("#addIsActive").val());
|
||||||
|
|
||||||
|
fetch("", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: payload.toString()
|
||||||
|
})
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Saved!",
|
||||||
|
confirmButtonColor: "#3085d6"
|
||||||
|
}).then(() => location.reload());
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Error",
|
||||||
|
text: data.message || "Unable to save department."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Error",
|
||||||
|
text: "Communication error."
|
||||||
|
});
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------- OPEN EDIT MODAL -------- */
|
||||||
|
$(document).on("click", ".edit-department", function() {
|
||||||
|
const btn = $(this);
|
||||||
|
|
||||||
|
$("#editDepartmentId").val(btn.data("id"));
|
||||||
|
$("#editName").val(btn.data("name"));
|
||||||
|
$("#editCode").val(btn.data("code"));
|
||||||
|
$("#editDescription").val(btn.data("description"));
|
||||||
|
$("#editColor").val(btn.data("color") || '#6c757d');
|
||||||
|
$("#editSortOrder").val(btn.data("sort_order"));
|
||||||
|
$("#editIsActive").val(String(btn.data("is_active")));
|
||||||
|
|
||||||
|
$("#editDepartmentModal").modal("show");
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------- SAVE EDIT -------- */
|
||||||
|
$("#editDepartmentForm").on("submit", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const payload = new URLSearchParams();
|
||||||
|
payload.append('ajax', '1');
|
||||||
|
payload.append('action', 'edit');
|
||||||
|
payload.append('id', $("#editDepartmentId").val());
|
||||||
|
payload.append('name', $("#editName").val().trim());
|
||||||
|
payload.append('code', $("#editCode").val().trim());
|
||||||
|
payload.append('description', $("#editDescription").val().trim());
|
||||||
|
payload.append('color', $("#editColor").val());
|
||||||
|
payload.append('sort_order', $("#editSortOrder").val());
|
||||||
|
payload.append('is_active', $("#editIsActive").val());
|
||||||
|
|
||||||
|
fetch("", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: payload.toString()
|
||||||
|
})
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Updated!",
|
||||||
|
confirmButtonColor: "#3085d6"
|
||||||
|
}).then(() => location.reload());
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Error",
|
||||||
|
text: data.message || "Unable to update department."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Error",
|
||||||
|
text: "Communication error."
|
||||||
|
});
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -------- DELETE DEPARTMENT -------- */
|
||||||
|
$(document).on("click", ".delete-department", function() {
|
||||||
|
const id = $(this).data("id");
|
||||||
|
const name = $(this).data("name");
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
title: "Confermi la cancellazione?",
|
||||||
|
text: name ? ("Department: " + name) : "This department will be deleted.",
|
||||||
|
icon: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#d33",
|
||||||
|
cancelButtonColor: "#6c757d",
|
||||||
|
confirmButtonText: "Sì, cancella",
|
||||||
|
cancelButtonText: "Annulla"
|
||||||
|
}).then((result) => {
|
||||||
|
if (!result.isConfirmed) return;
|
||||||
|
|
||||||
|
const payload = new URLSearchParams();
|
||||||
|
payload.append('ajax', '1');
|
||||||
|
payload.append('action', 'delete');
|
||||||
|
payload.append('id', id);
|
||||||
|
|
||||||
|
fetch("", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: payload.toString()
|
||||||
|
})
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Deleted!",
|
||||||
|
confirmButtonColor: "#3085d6"
|
||||||
|
}).then(() => location.reload());
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Error",
|
||||||
|
text: data.message || "Unable to delete department."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "error",
|
||||||
|
title: "Error",
|
||||||
|
text: "Communication error."
|
||||||
|
});
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
<?php include('include/headscript.php'); ?>
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="it">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
||||||
|
<?php include('cssinclude.php'); ?>
|
||||||
|
<title>Modifica Linea di Produzione</title>
|
||||||
|
|
||||||
|
<!-- jQuery + Bootstrap -->
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #f8fafc;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-save {
|
||||||
|
background-color: #0d6efd;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-save:hover {
|
||||||
|
background-color: #0b5ed7;
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-dashboard {
|
||||||
|
background-color: #cfe3ff;
|
||||||
|
color: #1f2d3d;
|
||||||
|
border: 1px solid #bcd4f4;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 10px 18px;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-dashboard:hover {
|
||||||
|
background-color: #b9d3ff;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<?php include('include/navbar.php'); ?>
|
||||||
|
<?php include('include/topbar.php'); ?>
|
||||||
|
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<div class="page-content">
|
||||||
|
<div class="card p-4 mx-auto" style="max-width: 600px;">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="mb-0 text-center w-100">Modifica Linea</h5>
|
||||||
|
<button type="button" class="btn back-dashboard position-absolute end-0 me-3" onclick="location.href='linee.php'">
|
||||||
|
↩️ Torna all'elenco
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<?php
|
||||||
|
require_once(__DIR__ . '/class/db-functions.php');
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||||
|
echo "<div class='alert alert-danger'>ID non valido.</div>";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (int)$_GET['id'];
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM production_lines WHERE id = ?");
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$line = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$line) {
|
||||||
|
echo "<div class='alert alert-warning'>Linea non trovata.</div>";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<form id="editLineaForm">
|
||||||
|
<input type="hidden" name="id" value="<?= htmlspecialchars($line['id']) ?>">
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="lineNumber" class="form-label fw-semibold">Numero Linea</label>
|
||||||
|
<input type="number" id="lineNumber" name="lineNumber" class="form-control" value="<?= htmlspecialchars($line['line_number']) ?>" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="lineName" class="form-label fw-semibold">Nome Linea</label>
|
||||||
|
<input type="text" id="lineName" name="lineName" class="form-control" value="<?= htmlspecialchars($line['name']) ?>" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="model" class="form-label fw-semibold">Modello</label>
|
||||||
|
<input type="text" id="model" name="model" class="form-control" value="<?= htmlspecialchars($line['model']) ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="brand" class="form-label fw-semibold">Marca</label>
|
||||||
|
<input type="text" id="brand" name="brand" class="form-control" value="<?= htmlspecialchars($line['brand']) ?>">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="color" class="form-label fw-semibold">Colore Linea</label>
|
||||||
|
<input type="color" id="color" name="color" class="form-control form-control-color"
|
||||||
|
value="<?= htmlspecialchars($line['color'] ?? '#dc2626') ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="status" class="form-label fw-semibold">Stato</label>
|
||||||
|
<select id="status" name="status" class="form-select">
|
||||||
|
<option value="active" <?= $line['status'] === 'active' ? 'selected' : '' ?>>Attiva</option>
|
||||||
|
<option value="inactive" <?= $line['status'] === 'inactive' ? 'selected' : '' ?>>Inattiva</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-center mt-4">
|
||||||
|
<button type="submit" class="btn btn-save">💾 Salva Modifiche</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include('include/footer.php'); ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById("editLineaForm").addEventListener("submit", e => {
|
||||||
|
e.preventDefault();
|
||||||
|
const formData = new FormData(e.target);
|
||||||
|
|
||||||
|
fetch("update_linea.php", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: "success",
|
||||||
|
title: "Aggiornata!",
|
||||||
|
text: "La linea è stata modificata correttamente.",
|
||||||
|
confirmButtonColor: "#3085d6"
|
||||||
|
}).then(() => location.href = "linee.php");
|
||||||
|
} else {
|
||||||
|
Swal.fire("Errore", data.message || "Errore durante l'aggiornamento.", "error");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => Swal.fire("Errore", "Impossibile contattare il server.", "error"));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/class/db-functions.php';
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$id = (int)($_POST['id'] ?? 0);
|
||||||
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$is_problem = isset($_POST['is_problem']) ? (int)$_POST['is_problem'] : 0;
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID non valido.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if ($name === '') {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Il nome è obbligatorio.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE pause_reasons
|
||||||
|
SET name = :name,
|
||||||
|
description = :description,
|
||||||
|
is_problem = :is_problem
|
||||||
|
WHERE id = :id
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
':name' => $name,
|
||||||
|
':description' => $description !== '' ? $description : null,
|
||||||
|
':is_problem' => $is_problem,
|
||||||
|
':id' => $id
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// Validazione
|
||||||
|
$id = intval($_POST['id'] ?? 0);
|
||||||
|
$nome = trim($_POST['nome'] ?? '');
|
||||||
|
$ordinamento = intval($_POST['ordinamento'] ?? 0);
|
||||||
|
$badge = $_POST['badge_color'] ?? '#6c757d';
|
||||||
|
$line = $_POST['line_color'] ?? '#e9ecef';
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID non valido']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($nome === '') {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Il nome è obbligatorio']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE production_status
|
||||||
|
SET nome = :nome,
|
||||||
|
ordinamento = :ordinamento,
|
||||||
|
badge_color = :badge,
|
||||||
|
line_color = :line
|
||||||
|
WHERE id = :id
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
':nome' => $nome,
|
||||||
|
':ordinamento' => $ordinamento,
|
||||||
|
':badge' => $badge,
|
||||||
|
':line' => $line,
|
||||||
|
':id' => $id
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -1,434 +0,0 @@
|
|||||||
<?php include('include/headscript.php');
|
|
||||||
|
|
||||||
// Controlla se è stato passato un ID valido
|
|
||||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|
||||||
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Invalid ID"));
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = intval($_GET['id']); // Sanifica l'ID
|
|
||||||
|
|
||||||
// Recupera il template dal database
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
|
||||||
$pdo = $db->getConnection();
|
|
||||||
$stmt = $pdo->prepare("SELECT * FROM excel_templates WHERE id = ?");
|
|
||||||
$stmt->execute([$id]);
|
|
||||||
$template = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
if (!$template) {
|
|
||||||
header("Location: template_dashboard.php?status=error&message=" . urlencode("Template not found"));
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
|
|
||||||
<?php include('cssinclude.php'); ?>
|
|
||||||
<!-- 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>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="wrapper">
|
|
||||||
<?php include('include/navbar.php'); ?>
|
|
||||||
<?php include('include/topbar.php'); ?>
|
|
||||||
<div class="page-wrapper">
|
|
||||||
<div class="page-content">
|
|
||||||
<div class="card mb-4">
|
|
||||||
<div class="card-header">
|
|
||||||
<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>
|
|
||||||
<p class="mb-2">Mandatory Fields</p>
|
|
||||||
<ul class="mb-0">
|
|
||||||
<li>Template Name</li>
|
|
||||||
<li>Row Header and Column Header: where the title of the excel starts</li>
|
|
||||||
<li>Schema</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card radius-10">
|
|
||||||
<div class="card-header">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div>
|
|
||||||
<h6 class="mb-0">Edit Template: <?php echo htmlspecialchars($template['name']); ?></h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div class="col-12">
|
|
||||||
<form id="editTemplateForm" method="POST">
|
|
||||||
<input type="hidden" name="id" value="<?php echo $template['id']; ?>">
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label"><?= htmlspecialchars($templatename, ENT_QUOTES, 'UTF-8'); ?> *</label>
|
|
||||||
<input type="text" name="name" class="form-control" value="<?php echo htmlspecialchars($template['name']); ?>" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label"><?= htmlspecialchars($rowheader, ENT_QUOTES, 'UTF-8'); ?> *</label>
|
|
||||||
<input type="number" name="header_row" class="form-control" value="<?php echo $template['header_row']; ?>" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label"><?= htmlspecialchars($columnheader, ENT_QUOTES, 'UTF-8'); ?>*</label>
|
|
||||||
<input type="text" name="start_column" class="form-control" value="<?php echo htmlspecialchars($template['start_column']); ?>" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label class="form-label"><?= htmlspecialchars($desctemplate, ENT_QUOTES, 'UTF-8'); ?></label>
|
|
||||||
<textarea name="description" class="form-control"><?php echo htmlspecialchars($template['description']); ?></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
</select>
|
|
||||||
<span id="clientLoadingStatus" class="text-muted" style="margin-left: 10px; display: none;">Recupero clienti in corso...</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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;">Caricamento schemi in corso...</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overlay toggle-icon"></div>
|
|
||||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
|
||||||
<?php include('include/footer.php'); ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<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 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 || !clientLoadingStatus || !schemaLoadingStatus || !routineSelect || !routineDetails) {
|
|
||||||
alert("Errore: Uno o più elementi della pagina non sono stati trovati. Contatta l'amministratore.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inizializza Select2
|
|
||||||
$('#clientSelect').select2({
|
|
||||||
placeholder: "Search for a client...",
|
|
||||||
allowClear: true
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#schemaSelect').select2({
|
|
||||||
placeholder: "Search for a schema...",
|
|
||||||
allowClear: true
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#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 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) {
|
|
||||||
clientLoadingStatus.textContent = "Errore nel caricamento.";
|
|
||||||
Swal.fire({
|
|
||||||
title: "Errore!",
|
|
||||||
text: "Impossibile caricare i clienti: " + error.message,
|
|
||||||
icon: "error",
|
|
||||||
confirmButtonText: "OK"
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
setTimeout(() => clientLoadingStatus.style.display = 'none', 2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 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);
|
|
||||||
if (parseInt(id) === parseInt(<?php echo json_encode($template['idschema'] ?? 0); ?>)) {
|
|
||||||
option.selected = true;
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Carica i dati
|
|
||||||
async function loadData() {
|
|
||||||
try {
|
|
||||||
await loadClients();
|
|
||||||
await loadSchemas();
|
|
||||||
} catch (error) {
|
|
||||||
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();
|
|
||||||
|
|
||||||
let formData = new FormData(this);
|
|
||||||
|
|
||||||
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();
|
|
||||||
const nameMatch = optionText.match(/^(.+?)(?:\s*\(ID:\s*\d+\))?$/);
|
|
||||||
clientName = nameMatch ? nameMatch[1].trim() : optionText;
|
|
||||||
}
|
|
||||||
formData.append("client_name", clientName);
|
|
||||||
|
|
||||||
const schemaSelect = document.getElementById("schemaSelect");
|
|
||||||
const schemaId = schemaSelect.value;
|
|
||||||
const selectedSchemaOption = schemaSelect.options[schemaSelect.selectedIndex];
|
|
||||||
|
|
||||||
if (!schemaId) {
|
|
||||||
Swal.fire({
|
|
||||||
title: "Errore!",
|
|
||||||
text: "Per favore seleziona uno schema.",
|
|
||||||
icon: "error",
|
|
||||||
confirmButtonText: "OK"
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Aggiungi idroutine
|
|
||||||
const routineId = routineSelect.value;
|
|
||||||
formData.append("idroutine", routineId);
|
|
||||||
|
|
||||||
fetch("process_edit_template_xls.php", {
|
|
||||||
method: "POST",
|
|
||||||
body: formData
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
Swal.fire({
|
|
||||||
title: "Successo!",
|
|
||||||
text: "Template aggiornato con successo!",
|
|
||||||
icon: "success",
|
|
||||||
confirmButtonText: "OK"
|
|
||||||
}).then(() => {
|
|
||||||
window.location.href = "templates_dashboard.php";
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Swal.fire({
|
|
||||||
title: "Errore!",
|
|
||||||
text: data.message,
|
|
||||||
icon: "error",
|
|
||||||
confirmButtonText: "OK"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
Swal.fire({
|
|
||||||
title: "Errore!",
|
|
||||||
text: "Si è verificato un errore imprevisto.",
|
|
||||||
icon: "error",
|
|
||||||
confirmButtonText: "OK"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
require_once 'include/headscript.php';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$id = (int)($_POST['id'] ?? 0);
|
||||||
|
$name = trim($_POST['name'] ?? '');
|
||||||
|
$registrationNumber = trim($_POST['registration_number'] ?? '');
|
||||||
|
$serialNumber = trim($_POST['serial_number'] ?? '');
|
||||||
|
$toolType = trim($_POST['tool_type'] ?? '');
|
||||||
|
$manufacturer = trim($_POST['manufacturer'] ?? '');
|
||||||
|
$description = trim($_POST['description'] ?? '');
|
||||||
|
$isActive = isset($_POST['is_active']) ? (int)$_POST['is_active'] : 1;
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid ID.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($name === '') {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Name is required.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "UPDATE production_tools
|
||||||
|
SET name = :name,
|
||||||
|
registration_number = :registration_number,
|
||||||
|
serial_number = :serial_number,
|
||||||
|
tool_type = :tool_type,
|
||||||
|
manufacturer = :manufacturer,
|
||||||
|
description = :description,
|
||||||
|
is_active = :is_active
|
||||||
|
WHERE id = :id";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([
|
||||||
|
'name' => $name,
|
||||||
|
'registration_number' => $registrationNumber ?: null,
|
||||||
|
'serial_number' => $serialNumber ?: null,
|
||||||
|
'tool_type' => $toolType ?: null,
|
||||||
|
'manufacturer' => $manufacturer ?: null,
|
||||||
|
'description' => $description ?: null,
|
||||||
|
'is_active' => $isActive,
|
||||||
|
'id' => $id
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,14 +0,0 @@
|
|||||||
2025-06-10 12:21:44 - Errore nel recupero dati: HTTP 404, Risposta:
|
|
||||||
2025-06-16 11:15:30 - Errore nel recupero dati: HTTP 404, Risposta: {"title":"Not Found","status":404,"detail":"Not Found","instance":"GET /api/odata/Rapporto(2523026)","errorCode":"d25cbd678"}
|
|
||||||
2025-06-16 11:34:59 - Autenticazione fallita: HTTP 0, Errore cURL: Failed to connect to 93.43.5.102 port 443 after 21033 ms: Couldn't connect to server, Risposta:
|
|
||||||
2025-06-16 11:42:03 - Errore nella richiesta: Recv failure: Connection was reset
|
|
||||||
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
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?php
|
|
||||||
ini_set('log_errors', 1);
|
|
||||||
ini_set('error_log', __DIR__ . '/import_debug.log');
|
|
||||||
|
|
||||||
|
|
||||||
error_log("TEST: errore manuale");
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,291 +0,0 @@
|
|||||||
<?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,150 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Abilita il debug degli errori (solo per sviluppo)
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
ini_set('display_startup_errors', 1);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
// Assicurati che non ci sia output prima del JSON
|
|
||||||
ob_start();
|
|
||||||
|
|
||||||
// Imposta l'header per JSON
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
// Configura la tua chiave API di TrackingMore
|
|
||||||
$apiKey = 'u4ssgynn-xuyy-9act-ca29-2glsv2qlzh0w'; // La tua chiave API reale
|
|
||||||
|
|
||||||
// Funzione per inviare una risposta JSON e terminare l'esecuzione
|
|
||||||
function sendResponse($data)
|
|
||||||
{
|
|
||||||
ob_end_clean();
|
|
||||||
echo json_encode($data);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifica che il numero di tracking e il corriere siano stati inviati
|
|
||||||
if (!isset($_POST['tracking_number']) || empty($_POST['tracking_number']) || !isset($_POST['courier_code']) || empty($_POST['courier_code'])) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Numero di tracking o corriere non fornito']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$trackingNumber = $_POST['tracking_number'];
|
|
||||||
$courierCode = $_POST['courier_code'];
|
|
||||||
|
|
||||||
// Lista dei corrieri validi per validazione
|
|
||||||
$validCarriers = ['tnt-it', 'dhl', 'gls', 'sda', 'ups'];
|
|
||||||
if (!in_array($courierCode, $validCarriers)) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Corriere non valido']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Imposta il nome del corriere in base al codice
|
|
||||||
$carrierNames = [
|
|
||||||
'tnt-it' => 'TNT Italy',
|
|
||||||
'dhl' => 'DHL',
|
|
||||||
'gls' => 'GLS',
|
|
||||||
'sda' => 'SDA',
|
|
||||||
'ups' => 'UPS'
|
|
||||||
];
|
|
||||||
$courierName = $carrierNames[$courierCode];
|
|
||||||
|
|
||||||
// Funzione per fare una richiesta cURL a TrackingMore
|
|
||||||
function makeRequest($url, $data, $apiKey, $method = 'POST')
|
|
||||||
{
|
|
||||||
$ch = curl_init($url);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
||||||
'Tracking-Api-Key: ' . $apiKey,
|
|
||||||
'Content-Type: application/json'
|
|
||||||
]);
|
|
||||||
if ($method === 'POST') {
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
$jsonData = json_encode($data, JSON_PRETTY_PRINT);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
|
|
||||||
file_put_contents('debug.log', "Encoded JSON Data: $jsonData\n", FILE_APPEND);
|
|
||||||
}
|
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
$error = curl_error($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
file_put_contents('debug.log', "Request URL: $url\nRequest Data: " . json_encode($data) . "\nResponse: $response\nHTTP Code: $httpCode\nError: $error\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if ($response === false) {
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'code' => $httpCode,
|
|
||||||
'message' => 'Errore nella richiesta API: ' . $error
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$decodedResponse = json_decode($response, true);
|
|
||||||
if ($decodedResponse === null) {
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'code' => $httpCode,
|
|
||||||
'message' => 'Risposta API non valida (non è JSON)'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$decodedResponse['success'] = isset($decodedResponse['meta']['code']) && ($decodedResponse['meta']['code'] === 200 || $decodedResponse['meta']['code'] === 201);
|
|
||||||
$decodedResponse['http_code'] = $httpCode;
|
|
||||||
return $decodedResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1: Prova a creare il tracking
|
|
||||||
$createUrl = 'https://api.trackingmore.com/v4/trackings/create';
|
|
||||||
$createData = [
|
|
||||||
'tracking_number' => $trackingNumber,
|
|
||||||
'courier_code' => $courierCode
|
|
||||||
];
|
|
||||||
$createResponse = makeRequest($createUrl, $createData, $apiKey);
|
|
||||||
file_put_contents('debug.log', "Create Response: " . json_encode($createResponse) . "\n", FILE_APPEND);
|
|
||||||
|
|
||||||
$trackingInfo = null;
|
|
||||||
if ($createResponse['success']) {
|
|
||||||
// Creazione riuscita, usa i dati restituiti
|
|
||||||
$trackingInfo = $createResponse['data'];
|
|
||||||
} else {
|
|
||||||
// Controlla se l'errore è "Tracking No. already exists" (4101)
|
|
||||||
if (isset($createResponse['meta']['code']) && $createResponse['meta']['code'] === 4101) {
|
|
||||||
// Il tracking esiste già, usa /trackings (GET) con tracking_number e courier_code
|
|
||||||
$getUrl = 'https://api.trackingmore.com/v4/get?tracking_numbers=' . urlencode($trackingNumber);
|
|
||||||
$getResponse = makeRequest($getUrl, [], $apiKey, 'GET');
|
|
||||||
file_put_contents('debug.log', "Get Response: " . json_encode($getResponse) . "\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if ($getResponse['success'] && !empty($getResponse['data']['items']) && !empty($getResponse['data']['items'][0])) {
|
|
||||||
$trackingInfo = $getResponse['data']['items'][0];
|
|
||||||
} else {
|
|
||||||
$errorMessage = isset($getResponse['meta']['message']) ? $getResponse['meta']['message'] : 'Errore sconosciuto';
|
|
||||||
sendResponse(['success' => false, 'message' => 'Errore nel recupero del tracking esistente: ' . $errorMessage]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Altro errore nella creazione
|
|
||||||
$errorMessage = isset($createResponse['meta']['message']) ? $createResponse['meta']['message'] : 'Errore sconosciuto';
|
|
||||||
sendResponse(['success' => false, 'message' => 'Errore nella creazione del tracking: ' . $errorMessage]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$trackingInfo) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Nessuna informazione di tracking trovata']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Estrai la data di consegna e il firmatario
|
|
||||||
$deliveryDate = 'Non disponibile';
|
|
||||||
$signedBy = 'Non disponibile';
|
|
||||||
if (isset($trackingInfo['origin_info']['trackinfo']) && is_array($trackingInfo['origin_info']['trackinfo'])) {
|
|
||||||
foreach ($trackingInfo['origin_info']['trackinfo'] as $checkpoint) {
|
|
||||||
if (isset($checkpoint['checkpoint_delivery_status']) && $checkpoint['checkpoint_delivery_status'] === 'delivered') {
|
|
||||||
$deliveryDate = $checkpoint['checkpoint_date'] ?? 'Non disponibile';
|
|
||||||
$signedBy = $trackingInfo['signed_by'] ?? 'Non disponibile';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restituisci i dati al frontend
|
|
||||||
sendResponse([
|
|
||||||
'success' => true,
|
|
||||||
'deliveryDate' => $deliveryDate,
|
|
||||||
'signedBy' => $signedBy,
|
|
||||||
'carrierName' => $courierName
|
|
||||||
]);
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Abilita il debug degli errori (solo per sviluppo)
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
ini_set('display_startup_errors', 1);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
// Assicurati che non ci sia output prima del JSON
|
|
||||||
ob_start();
|
|
||||||
|
|
||||||
// Imposta l'header per JSON
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
// Configura la tua chiave API di 17Track
|
|
||||||
$apiKey = '489F6B6DADDE09A5B6CB1C42B5363A3F'; // Sostituisci con la tua chiave API reale
|
|
||||||
|
|
||||||
// Funzione per inviare una risposta JSON e terminare l'esecuzione
|
|
||||||
function sendResponse($data)
|
|
||||||
{
|
|
||||||
ob_end_clean();
|
|
||||||
echo json_encode($data);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifica che il numero di tracking sia stato inviato
|
|
||||||
if (!isset($_POST['tracking_number']) || empty($_POST['tracking_number'])) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Numero di tracking non fornito']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$trackingNumber = $_POST['tracking_number'];
|
|
||||||
|
|
||||||
// Funzione per fare una richiesta cURL a 17Track
|
|
||||||
function makeRequest($url, $data, $apiKey, $method = 'POST')
|
|
||||||
{
|
|
||||||
$ch = curl_init($url);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
||||||
'17token: ' . $apiKey,
|
|
||||||
'Content-Type: application/json'
|
|
||||||
]);
|
|
||||||
if ($method === 'POST') {
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
|
||||||
}
|
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
$error = curl_error($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
file_put_contents('debug.log', "Request URL: $url\nRequest Data: " . json_encode($data) . "\nResponse: $response\nHTTP Code: $httpCode\nError: $error\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if ($response === false || $httpCode !== 200) {
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'code' => $httpCode,
|
|
||||||
'message' => 'Errore nella richiesta API: HTTP ' . $httpCode . ' - ' . $error
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$decodedResponse = json_decode($response, true);
|
|
||||||
if ($decodedResponse === null) {
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'code' => $httpCode,
|
|
||||||
'message' => 'Risposta API non valida (non è JSON)'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $decodedResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1: Prova con auto-detection
|
|
||||||
$trackUrl = 'https://api.17track.net/track/v2/register';
|
|
||||||
$trackData = [
|
|
||||||
[
|
|
||||||
'number' => $trackingNumber,
|
|
||||||
'carrier' => null,
|
|
||||||
'auto_detection' => true
|
|
||||||
]
|
|
||||||
];
|
|
||||||
$registerResponse = makeRequest($trackUrl, $trackData, $apiKey);
|
|
||||||
|
|
||||||
file_put_contents('debug.log', "Register Response (Auto-detect): " . json_encode($registerResponse) . "\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if (!isset($registerResponse['data']['accepted']) || empty($registerResponse['data']['accepted'])) {
|
|
||||||
$errorMessage = $registerResponse['data']['rejected'][0]['error']['message'] ?? 'Errore sconosciuto';
|
|
||||||
sendResponse(['success' => false, 'message' => 'Errore nella registrazione del tracking: ' . $errorMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2: Recupera i dettagli con riprova
|
|
||||||
$getUrl = 'https://api.17track.net/track/v2/gettrackinfo';
|
|
||||||
$getData = [['number' => $trackingNumber]];
|
|
||||||
$maxAttempts = 3;
|
|
||||||
$delaySeconds = 5;
|
|
||||||
|
|
||||||
for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
|
|
||||||
$trackResponse = makeRequest($getUrl, $getData, $apiKey);
|
|
||||||
file_put_contents('debug.log', "Track Response (Attempt $attempt): " . json_encode($trackResponse) . "\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if (isset($trackResponse['data']['accepted']) && !empty($trackResponse['data']['accepted'])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($attempt < $maxAttempts) {
|
|
||||||
sleep($delaySeconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Se auto-detection ha successo, procedi
|
|
||||||
if (isset($trackResponse['data']['accepted']) && !empty($trackResponse['data']['accepted'])) {
|
|
||||||
$trackingInfo = $trackResponse['data']['accepted'][0]['track'] ?? null;
|
|
||||||
if (!$trackingInfo) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Nessuna informazione di tracking trovata']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$deliveryDate = 'Non disponibile';
|
|
||||||
$signedBy = 'Non disponibile';
|
|
||||||
$carrierName = $trackingInfo['carrier']['name'] ?? 'Sconosciuto';
|
|
||||||
|
|
||||||
if (isset($trackingInfo['z0']['e']) && $trackingInfo['z0']['e'] == 40) {
|
|
||||||
$deliveryDate = $trackingInfo['z0']['z'] ?? 'Non disponibile';
|
|
||||||
$signedBy = $trackingInfo['z0']['d'] ?? 'Non disponibile';
|
|
||||||
}
|
|
||||||
|
|
||||||
sendResponse([
|
|
||||||
'success' => true,
|
|
||||||
'deliveryDate' => $deliveryDate,
|
|
||||||
'signedBy' => $signedBy,
|
|
||||||
'carrierName' => $carrierName
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: Se auto-detection fallisce, prova una lista di corrieri comuni
|
|
||||||
$commonCarriers = [
|
|
||||||
['code' => 100003, 'name' => 'TNT'], // TNT
|
|
||||||
['code' => 100001, 'name' => 'DHL'], // DHL Express
|
|
||||||
['code' => 100065, 'name' => 'DHL eCommerce'], // DHL eCommerce
|
|
||||||
['code' => 100002, 'name' => 'UPS'] // UPS
|
|
||||||
];
|
|
||||||
|
|
||||||
$possibleCarriers = [];
|
|
||||||
foreach ($commonCarriers as $carrier) {
|
|
||||||
$trackData = [
|
|
||||||
[
|
|
||||||
'number' => $trackingNumber,
|
|
||||||
'carrier' => $carrier['code'],
|
|
||||||
'auto_detection' => false
|
|
||||||
]
|
|
||||||
];
|
|
||||||
$registerResponse = makeRequest($trackUrl, $trackData, $apiKey);
|
|
||||||
|
|
||||||
if (isset($registerResponse['data']['accepted']) && !empty($registerResponse['data']['accepted'])) {
|
|
||||||
$possibleCarriers[] = $carrier['name'];
|
|
||||||
}
|
|
||||||
sleep(1); // Piccolo ritardo per evitare limiti di rate
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($possibleCarriers)) {
|
|
||||||
sendResponse([
|
|
||||||
'success' => false,
|
|
||||||
'message' => 'Auto-detection fallita. Seleziona un corriere tra quelli possibili.',
|
|
||||||
'possibleCarriers' => $possibleCarriers
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Nessun corriere identificato per questo numero di tracking']);
|
|
||||||
}
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
<?php
|
|
||||||
// Abilita il debug degli errori (solo per sviluppo)
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
ini_set('display_startup_errors', 1);
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
// Assicurati che non ci sia output prima del JSON
|
|
||||||
ob_start();
|
|
||||||
|
|
||||||
// Imposta l'header per JSON
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
// Configura la tua chiave API di TrackingMore
|
|
||||||
$apiKey = 'u4ssgynn-xuyy-9act-ca29-2glsv2qlzh0w'; // La tua chiave API reale
|
|
||||||
|
|
||||||
// Funzione per inviare una risposta JSON e terminare l'esecuzione
|
|
||||||
function sendResponse($data)
|
|
||||||
{
|
|
||||||
ob_end_clean();
|
|
||||||
echo json_encode($data);
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifica che il numero di tracking sia stato inviato
|
|
||||||
if (!isset($_POST['tracking_number']) || empty($_POST['tracking_number'])) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Numero di tracking non fornito']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$trackingNumber = $_POST['tracking_number'];
|
|
||||||
|
|
||||||
// Funzione per fare una richiesta cURL a TrackingMore
|
|
||||||
function makeRequest($url, $data, $apiKey, $method = 'POST')
|
|
||||||
{
|
|
||||||
$ch = curl_init($url);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
||||||
'Tracking-Api-Key: ' . $apiKey,
|
|
||||||
'Content-Type: application/json'
|
|
||||||
]);
|
|
||||||
if ($method === 'POST') {
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
|
||||||
}
|
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
$error = curl_error($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
file_put_contents('debug.log', "Request URL: $url\nRequest Data: " . json_encode($data) . "\nResponse: $response\nHTTP Code: $httpCode\nError: $error\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if ($response === false || ($httpCode !== 200 && $httpCode !== 201)) {
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'code' => $httpCode,
|
|
||||||
'message' => 'Errore nella richiesta API: HTTP ' . $httpCode . ' - ' . $error
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$decodedResponse = json_decode($response, true);
|
|
||||||
if ($decodedResponse === null) {
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'code' => $httpCode,
|
|
||||||
'message' => 'Risposta API non valida (non è JSON)'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$decodedResponse['success'] = isset($decodedResponse['meta']['code']) && ($decodedResponse['meta']['code'] === 200 || $decodedResponse['meta']['code'] === 201);
|
|
||||||
return $decodedResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1: Identifica il corriere
|
|
||||||
$detectUrl = 'https://api.trackingmore.com/v4/couriers/detect';
|
|
||||||
$detectData = ['tracking_number' => $trackingNumber];
|
|
||||||
$detectResponse = makeRequest($detectUrl, $detectData, $apiKey);
|
|
||||||
file_put_contents('debug.log', "Detect Response: " . json_encode($detectResponse) . "\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if (!$detectResponse['success']) {
|
|
||||||
$errorMessage = isset($detectResponse['meta']['message']) ? $detectResponse['meta']['message'] : 'Errore sconosciuto';
|
|
||||||
sendResponse(['success' => false, 'message' => 'Errore nella rilevazione del corriere: ' . $errorMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$couriers = $detectResponse['data'] ?? [];
|
|
||||||
if (empty($couriers)) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Corriere non identificato per il numero di tracking']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prendi il primo corriere per ora
|
|
||||||
$courierCode = $couriers[0]['courier_code'] ?? null;
|
|
||||||
$courierName = $couriers[0]['courier_name'] ?? 'Sconosciuto';
|
|
||||||
if (!$courierCode) {
|
|
||||||
sendResponse(['success' => false, 'message' => 'Corriere non identificato']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2: Crea un tracking
|
|
||||||
$createUrl = 'https://api.trackingmore.com/v4/trackings/create';
|
|
||||||
$createData = [
|
|
||||||
'tracking_number' => $trackingNumber,
|
|
||||||
'courier_code' => $courierCode
|
|
||||||
];
|
|
||||||
$createResponse = makeRequest($createUrl, $createData, $apiKey);
|
|
||||||
file_put_contents('debug.log', "Create Response: " . json_encode($createResponse) . "\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if (!$createResponse['success']) {
|
|
||||||
$errorMessage = isset($createResponse['meta']['message']) ? $createResponse['meta']['message'] : 'Errore sconosciuto';
|
|
||||||
sendResponse(['success' => false, 'message' => 'Errore nella creazione del tracking: ' . $errorMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: Recupera i dettagli del tracking con riprova
|
|
||||||
$getUrl = 'https://api.trackingmore.com/v4/trackings/get?tracking_number=' . urlencode($trackingNumber);
|
|
||||||
$maxAttempts = 3;
|
|
||||||
$delaySeconds = 5;
|
|
||||||
|
|
||||||
for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
|
|
||||||
$trackResponse = makeRequest($getUrl, [], $apiKey, 'GET');
|
|
||||||
file_put_contents('debug.log', "Track Response (Attempt $attempt): " . json_encode($trackResponse) . "\n", FILE_APPEND);
|
|
||||||
|
|
||||||
if ($trackResponse['success'] && !empty($trackResponse['data'])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($attempt < $maxAttempts) {
|
|
||||||
sleep($delaySeconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$trackResponse['success']) {
|
|
||||||
$errorMessage = isset($trackResponse['meta']['message']) ? $trackResponse['meta']['message'] : 'Errore sconosciuto';
|
|
||||||
sendResponse(['success' => false, 'message' => 'Errore nel recupero delle informazioni: ' . $errorMessage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$trackingInfo = $trackResponse['data'] ?? null;
|
|
||||||
if (!$trackingInfo) {
|
|
||||||
// Se ci sono più corrieri rilevati, restituisci una lista per la tendina
|
|
||||||
if (count($couriers) > 1) {
|
|
||||||
$possibleCarriers = array_map(function ($courier) {
|
|
||||||
return ['code' => $courier['courier_code'], 'name' => $courier['courier_name']];
|
|
||||||
}, $couriers);
|
|
||||||
sendResponse([
|
|
||||||
'success' => false,
|
|
||||||
'message' => 'Dati non trovati. Seleziona un corriere tra quelli rilevati.',
|
|
||||||
'possibleCarriers' => $possibleCarriers
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
sendResponse(['success' => false, 'message' => 'Nessuna informazione di tracking trovata']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Estrai la data di consegna e il firmatario
|
|
||||||
$deliveryDate = 'Non disponibile';
|
|
||||||
$signedBy = 'Non disponibile';
|
|
||||||
foreach ($trackingInfo['trackinfo'] as $checkpoint) {
|
|
||||||
if ($checkpoint['status'] === 'delivered') {
|
|
||||||
$deliveryDate = $checkpoint['Date'];
|
|
||||||
$signedBy = $checkpoint['signed_by'] ?? 'Non disponibile';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restituisci i dati al frontend
|
|
||||||
sendResponse([
|
|
||||||
'success' => true,
|
|
||||||
'deliveryDate' => $deliveryDate,
|
|
||||||
'signedBy' => $signedBy,
|
|
||||||
'carrierName' => $courierName
|
|
||||||
]);
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
<?php
|
|
||||||
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
|
||||||
require_once __DIR__ . '/class/VisualLimsApiClient.class.php';
|
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
// Disable PHP error display
|
|
||||||
ini_set('display_errors', '0');
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$api = VisualLimsApiClient::getInstance();
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
$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);
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
<?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,41 +0,0 @@
|
|||||||
<?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();
|
|
||||||
|
|
||||||
// მივიღოთ მრავლობითი field_ids
|
|
||||||
$fieldIds = [];
|
|
||||||
if (isset($_GET['field_ids'])) {
|
|
||||||
$fieldIds = array_filter(array_map('intval', explode(',', $_GET['field_ids'])));
|
|
||||||
}
|
|
||||||
|
|
||||||
// თუ არ გადმოგვცეს -> ერთი default
|
|
||||||
if (empty($fieldIds)) {
|
|
||||||
$fieldIds = [156];
|
|
||||||
}
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
|
|
||||||
foreach ($fieldIds as $customFieldId) {
|
|
||||||
$endpoint = "CustomField($customFieldId)?\$expand=CustomFieldsValues";
|
|
||||||
$data = $api->get($endpoint);
|
|
||||||
|
|
||||||
$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([
|
|
||||||
'error' => $e->getMessage()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
include('../class/db-functions.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isset($_GET['id'])) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID matrice non fornito.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$idMatrice = intval($_GET['id']);
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// Tutte le linee
|
||||||
|
$stmt = $pdo->query("SELECT id, name, brand FROM production_lines ORDER BY name ASC");
|
||||||
|
$tutte = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// Linee già associate
|
||||||
|
$stmt = $pdo->prepare("SELECT idlinea FROM matrice_lines WHERE idmatrice = ?");
|
||||||
|
$stmt->execute([$idMatrice]);
|
||||||
|
$associate = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'tutte' => $tutte, 'associate' => $associate]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
require_once(__DIR__ . '/class/db-functions.php');
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isset($_GET['id'])) {
|
||||||
|
throw new Exception("Parametro ID mancante.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$idMescola = (int) $_GET['id'];
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// Recupera TUTTE le linee
|
||||||
|
$stmt = $pdo->query("SELECT id, name, brand FROM production_lines ORDER BY line_number ASC");
|
||||||
|
$tutte_linee = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// Recupera linee associate a questa mescola
|
||||||
|
$stmt = $pdo->prepare("SELECT idlinea FROM mescole_lines WHERE idmescola = ?");
|
||||||
|
$stmt->execute([$idMescola]);
|
||||||
|
$associate = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
// Conversione in stringhe (per compatibilità con JS)
|
||||||
|
$associate = array_map('strval', $associate);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
"success" => true,
|
||||||
|
"tutte_linee" => $tutte_linee,
|
||||||
|
"associate" => $associate
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
"success" => false,
|
||||||
|
"message" => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<?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);
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<?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,65 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'success' => false,
|
||||||
|
'attachments' => [],
|
||||||
|
'message' => ''
|
||||||
|
];
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||||
|
throw new Exception('ID matrice non valido');
|
||||||
|
}
|
||||||
|
|
||||||
|
$idmatrice = (int)$_GET['id'];
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
id,
|
||||||
|
matrice_id,
|
||||||
|
file_name,
|
||||||
|
file_path,
|
||||||
|
file_type,
|
||||||
|
description,
|
||||||
|
sort_order,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
FROM matrice_attachments
|
||||||
|
WHERE matrice_id = :matrice_id
|
||||||
|
ORDER BY sort_order ASC, id DESC";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([':matrice_id' => $idmatrice]);
|
||||||
|
|
||||||
|
$attachments = [];
|
||||||
|
|
||||||
|
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
$relativePath = ltrim((string)$row['file_path'], '/\\');
|
||||||
|
|
||||||
|
$attachments[] = [
|
||||||
|
'id' => (int)$row['id'],
|
||||||
|
'matrice_id' => (int)$row['matrice_id'],
|
||||||
|
'file_name' => $row['file_name'],
|
||||||
|
'file_path' => $relativePath,
|
||||||
|
'file_url' => $relativePath,
|
||||||
|
'file_type' => $row['file_type'],
|
||||||
|
'description' => $row['description'] ?? '',
|
||||||
|
'sort_order' => (int)($row['sort_order'] ?? 0),
|
||||||
|
'created_at' => !empty($row['created_at']) ? date('d/m/Y H:i', strtotime($row['created_at'])) : '',
|
||||||
|
'updated_at' => !empty($row['updated_at']) ? date('d/m/Y H:i', strtotime($row['updated_at'])) : ''
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$response['success'] = true;
|
||||||
|
$response['attachments'] = $attachments;
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
$response['message'] = $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($response, JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$idmatrice = (int)($_GET['id'] ?? 0);
|
||||||
|
if ($idmatrice <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid id']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// tutte le linee (attive + inattive se vuoi: qui prendo tutte)
|
||||||
|
$stmt = $pdo->query("
|
||||||
|
SELECT id, line_number, name
|
||||||
|
FROM production_lines
|
||||||
|
ORDER BY line_number ASC
|
||||||
|
");
|
||||||
|
$lines = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// linee già associate
|
||||||
|
$stmt = $pdo->prepare("SELECT idlinea FROM matrici_lines WHERE idmatrice = ?");
|
||||||
|
$stmt->execute([$idmatrice]);
|
||||||
|
$selected_ids = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'lines' => $lines,
|
||||||
|
'selected_ids' => $selected_ids
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Server error']);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$idmatrice = (int)($_GET['id'] ?? 0);
|
||||||
|
if ($idmatrice <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid id']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// tutte le mescole
|
||||||
|
$stmt = $pdo->query("
|
||||||
|
SELECT id, nome, nomeuscita
|
||||||
|
FROM mescole
|
||||||
|
ORDER BY nome ASC
|
||||||
|
");
|
||||||
|
$mescole = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// mescole già associate
|
||||||
|
$stmt = $pdo->prepare("SELECT idmescola FROM matrici_mescole WHERE idmatrice = ?");
|
||||||
|
$stmt->execute([$idmatrice]);
|
||||||
|
$selected_ids = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'mescole' => $mescole,
|
||||||
|
'selected_ids' => $selected_ids
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Server error']);
|
||||||
|
}
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<?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,31 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid id']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
msl.id,
|
||||||
|
msl.idsupplier AS idsupplier,
|
||||||
|
s.supplier_name,
|
||||||
|
msl.supplier_mix_name,
|
||||||
|
msl.lot_code,
|
||||||
|
msl.expiry_date,
|
||||||
|
msl.qty
|
||||||
|
FROM mescole_supplier_lots msl
|
||||||
|
INNER JOIN suppliers s ON s.idsupplier = msl.idsupplier
|
||||||
|
WHERE msl.idmescola = ?
|
||||||
|
ORDER BY msl.id DESC";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'rows' => $rows]);
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
// Evita che warning PHP rovinino il json
|
||||||
|
error_reporting(0);
|
||||||
|
ini_set('display_errors', 0);
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/../class/db-functions.php');
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isset($_GET['id'])) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'ID matrice non fornito.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$idMatrice = intval($_GET['id']);
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
// tutte le mescole
|
||||||
|
$stmt = $pdo->query("SELECT id, nome FROM mescole ORDER BY nome ASC");
|
||||||
|
$tutte = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// mescole associate
|
||||||
|
$stmt = $pdo->prepare("SELECT idmescola FROM matrice_mescole WHERE idmatrice = ?");
|
||||||
|
$stmt->execute([$idMatrice]);
|
||||||
|
$associate = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'tutte' => $tutte,
|
||||||
|
'associate' => $associate
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<?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>';
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid id']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$sql = "SELECT
|
||||||
|
psl.id,
|
||||||
|
psl.idsupplier,
|
||||||
|
s.supplier_name,
|
||||||
|
psl.lot_code,
|
||||||
|
psl.expiry_date,
|
||||||
|
psl.qty
|
||||||
|
FROM packaging_stock_lots psl
|
||||||
|
INNER JOIN suppliers s ON s.idsupplier = psl.idsupplier
|
||||||
|
WHERE psl.idpackaging_item = ?
|
||||||
|
ORDER BY psl.id DESC";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'rows' => $rows]);
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
ini_set('display_errors', 1);
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
include('include/headscript.php');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Invalid parameter id.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT id, line_id, position, short_label, label, icon
|
||||||
|
FROM production_line_params
|
||||||
|
WHERE id = :id
|
||||||
|
");
|
||||||
|
$stmt->execute([':id' => $id]);
|
||||||
|
$param = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$param) {
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Parameter not found.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'param' => $param
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Server error: ' . $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
require_once __DIR__ . '/class/db-functions.php';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$production_id = isset($_GET['production_id']) ? (int)$_GET['production_id'] : 0;
|
||||||
|
$photo_type = $_GET['photo_type'] ?? '';
|
||||||
|
$slot = isset($_GET['param_position']) ? (int)$_GET['param_position'] : null;
|
||||||
|
|
||||||
|
if ($production_id <= 0 || $photo_type === '') {
|
||||||
|
throw new Exception("Parametri non validi");
|
||||||
|
}
|
||||||
|
|
||||||
|
// QUERY BASE
|
||||||
|
$sql = "
|
||||||
|
SELECT id, filename, photo_type, created_at, elaborato
|
||||||
|
FROM production_photos
|
||||||
|
WHERE production_id = :prod
|
||||||
|
AND photo_type = :ptype
|
||||||
|
";
|
||||||
|
|
||||||
|
// SE È PARAMETRO MACCHINA → FILTRO PER POSIZIONE
|
||||||
|
if ($photo_type === 'parametri_macchina') {
|
||||||
|
$sql .= " AND param_position = :slot";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= " ORDER BY created_at DESC, id DESC";
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare($sql);
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
':prod' => $production_id,
|
||||||
|
':ptype' => $photo_type
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($photo_type === 'parametri_macchina') {
|
||||||
|
$params[':slot'] = $slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt->execute($params);
|
||||||
|
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'photos' => $photos
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<?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();
|
|
||||||
$rapporto_id = 533329;
|
|
||||||
|
|
||||||
// Costruzione manuale dell'endpoint con espansione annidata
|
|
||||||
$endpoint = "Rapporto($rapporto_id)?\$expand=CampioniDatiRapporto(\$expand=AnalisiDatiRapporto,CustomFieldsDatiRapporto)";
|
|
||||||
|
|
||||||
// Non passiamo options, già incluso nell'endpoint
|
|
||||||
$data = $api->get($endpoint);
|
|
||||||
|
|
||||||
file_put_contents(__DIR__ . '/rapporto_expanded.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
|
||||||
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,30 +0,0 @@
|
|||||||
<?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 dello schema passato via GET o default 45
|
|
||||||
$schemaId = isset($_GET['id']) && is_numeric($_GET['id']) ? intval($_GET['id']) : 42;
|
|
||||||
|
|
||||||
// IMPORTANTE: $expand va dentro la stringa endpoint per entità singola
|
|
||||||
$endpoint = "SchemaCustomField($schemaId)?\$expand=SchemiCustomFieldsDettagli(\$expand=CustomField)";
|
|
||||||
|
|
||||||
// Nessun parametro aggiuntivo
|
|
||||||
$data = $api->get($endpoint);
|
|
||||||
|
|
||||||
// Salva la risposta per debug
|
|
||||||
file_put_contents(__DIR__ . '/schema_dettagli_response.json', json_encode($data));
|
|
||||||
|
|
||||||
echo json_encode($data);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode([
|
|
||||||
'error' => $e->getMessage()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<?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();
|
|
||||||
|
|
||||||
// Nessun filtro o espansione: solo la lista degli schemi
|
|
||||||
$endpoint = 'SchemaCustomField';
|
|
||||||
|
|
||||||
// (Opzionale) aggiungi $top se vuoi 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__ . '/schemi_base_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,26 +0,0 @@
|
|||||||
```php
|
|
||||||
<?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';
|
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
|
|
||||||
// Disabilita la visualizzazione degli errori PHP per evitare output HTML
|
|
||||||
ini_set('display_errors', '0');
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$api = VisualLimsApiClient::getInstance();
|
|
||||||
$data = $api->get("SchemaCustomField"); // Recupera la lista degli schemi custom fields
|
|
||||||
|
|
||||||
// Salva la risposta in un file per debug
|
|
||||||
file_put_contents(__DIR__ . '/schemi_custom_fields_response.json', json_encode($data));
|
|
||||||
|
|
||||||
echo json_encode($data);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
http_response_code(500);
|
|
||||||
echo json_encode([
|
|
||||||
'error' => $e->getMessage()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
include('include/headscript.php');
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->query("SELECT idsupplier, supplier_name FROM suppliers ORDER BY supplier_name ASC");
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
echo json_encode(['success' => true, 'rows' => $rows]);
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,153 +0,0 @@
|
|||||||
<?php include('include/headscript.php'); ?>
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
|
||||||
<?php include('cssinclude.php'); ?>
|
|
||||||
<title>Template Buttons - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Layout flessibile per gestire dimensioni diverse */
|
|
||||||
#templateButtons {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
justify-content: flex-start;
|
|
||||||
/* Allinea a sinistra */
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Definizione delle dimensioni */
|
|
||||||
/* Definizione delle dimensioni */
|
|
||||||
.btn-small {
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
min-width: 100px;
|
|
||||||
min-height: 30px;
|
|
||||||
display: flex;
|
|
||||||
/* Aggiunto */
|
|
||||||
justify-content: center;
|
|
||||||
/* Aggiunto */
|
|
||||||
align-items: center;
|
|
||||||
/* Aggiunto */
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-medium {
|
|
||||||
font-size: 16px;
|
|
||||||
padding: 10px 20px;
|
|
||||||
min-width: 130px;
|
|
||||||
min-height: 45px;
|
|
||||||
display: flex;
|
|
||||||
/* Aggiunto */
|
|
||||||
justify-content: center;
|
|
||||||
/* Aggiunto */
|
|
||||||
align-items: center;
|
|
||||||
/* Aggiunto */
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-large {
|
|
||||||
font-size: 20px;
|
|
||||||
padding: 14px 28px;
|
|
||||||
min-width: 180px;
|
|
||||||
min-height: 60px;
|
|
||||||
display: flex;
|
|
||||||
/* Aggiunto */
|
|
||||||
justify-content: center;
|
|
||||||
/* Aggiunto */
|
|
||||||
align-items: center;
|
|
||||||
/* Aggiunto */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stile della barra di ricerca */
|
|
||||||
#searchInput {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
font-size: 16px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="wrapper">
|
|
||||||
<?php include('include/navbar.php'); ?>
|
|
||||||
<?php include('include/topbar.php'); ?>
|
|
||||||
|
|
||||||
<div class="page-wrapper">
|
|
||||||
<div class="page-content">
|
|
||||||
<?php include('top_stat_widget.php'); ?>
|
|
||||||
|
|
||||||
<div class="card radius-10">
|
|
||||||
<div class="card-header">
|
|
||||||
<h6 class="mb-0">Active Templates</h6>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<!-- Barra di ricerca -->
|
|
||||||
<input type="text" id="searchInput" placeholder="Search template...">
|
|
||||||
<div id="templateButtons"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="overlay toggle-icon"></div>
|
|
||||||
<a href="javaScript:;" class="back-to-top"><i class='bx bxs-up-arrow-alt'></i></a>
|
|
||||||
<?php include('include/footer.php'); ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<?php include('jsinclude.php'); ?>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
fetch("load_active_templates.php")
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (!data.success) {
|
|
||||||
console.error("Error loading templates:", data.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let templateButtons = document.getElementById("templateButtons");
|
|
||||||
templateButtons.innerHTML = '';
|
|
||||||
|
|
||||||
data.data.forEach(template => {
|
|
||||||
let sizeClass = "btn-medium"; // Default
|
|
||||||
if (template.button_size === "small") sizeClass = "btn-small";
|
|
||||||
if (template.button_size === "large") sizeClass = "btn-large";
|
|
||||||
|
|
||||||
let btn = document.createElement("a");
|
|
||||||
btn.href = `import_xls2.php?id=${template.id}`;
|
|
||||||
btn.className = `btn ${sizeClass}`;
|
|
||||||
btn.style.backgroundColor = template.button_bg_color;
|
|
||||||
btn.style.color = template.button_text_color;
|
|
||||||
btn.textContent = template.button_label;
|
|
||||||
btn.setAttribute("data-label", template.button_label.toLowerCase()); // Attributo per ricerca
|
|
||||||
|
|
||||||
templateButtons.appendChild(btn);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(error => console.error("Fetch error:", error));
|
|
||||||
|
|
||||||
// Funzione per la ricerca live
|
|
||||||
document.getElementById("searchInput").addEventListener("input", function() {
|
|
||||||
let searchValue = this.value.toLowerCase();
|
|
||||||
document.querySelectorAll("#templateButtons a").forEach(btn => {
|
|
||||||
let label = btn.getAttribute("data-label");
|
|
||||||
if (label.includes(searchValue)) {
|
|
||||||
btn.style.display = "inline-block";
|
|
||||||
} else {
|
|
||||||
btn.style.display = "none";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,173 +0,0 @@
|
|||||||
<?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;
|
|
||||||
?>
|
|
||||||
@@ -1,305 +0,0 @@
|
|||||||
<?php
|
|
||||||
include('include/headscript.php');
|
|
||||||
|
|
||||||
// Controlla se è stato passato un ID valido
|
|
||||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|
||||||
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Invalid ID"));
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = intval($_GET['id']); // Sanifica l'ID
|
|
||||||
|
|
||||||
// Recupera il template dal database
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
|
||||||
$pdo = $db->getConnection();
|
|
||||||
$stmt = $pdo->prepare("SELECT * FROM excel_templates WHERE id = ?");
|
|
||||||
$stmt->execute([$id]);
|
|
||||||
$template = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
if (!$template) {
|
|
||||||
header("Location: template_dashboard.php?status=error&message=" . urlencode("Template not found"));
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug del template
|
|
||||||
error_log("Loaded template: " . print_r($template, true));
|
|
||||||
?>
|
|
||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
|
||||||
<?php include('cssinclude.php'); ?>
|
|
||||||
<style>
|
|
||||||
.table-container {
|
|
||||||
overflow-x: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th,
|
|
||||||
.table td {
|
|
||||||
padding: 10px;
|
|
||||||
text-align: left;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
min-width: 100px;
|
|
||||||
max-width: 200px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th:first-child,
|
|
||||||
.table td:first-child {
|
|
||||||
min-width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
position: relative;
|
|
||||||
cursor: col-resize;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th .resize-handle {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 5px;
|
|
||||||
height: 100%;
|
|
||||||
cursor: col-resize;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th .resize-handle:hover {
|
|
||||||
background: #007bff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-container {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-container input {
|
|
||||||
width: 300px;
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #ced4da;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader {
|
|
||||||
display: none;
|
|
||||||
border: 4px solid #f3f3f3;
|
|
||||||
border-top: 4px solid #3498db;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
margin: 10px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<title><?= htmlspecialchars($template['name']) ?> - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="wrapper">
|
|
||||||
<?php include('include/navbar.php'); ?>
|
|
||||||
<?php include('include/topbar.php'); ?>
|
|
||||||
<div class="page-wrapper">
|
|
||||||
<div class="page-content">
|
|
||||||
<?php include('top_stat_widget.php'); ?>
|
|
||||||
|
|
||||||
<div class="card radius-10">
|
|
||||||
<div class="card-header">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div>
|
|
||||||
<h6 class="mb-0"><?= htmlspecialchars($template['name']) ?></h6>
|
|
||||||
<small>Template ID: <?= $id ?>, Start Row: <?= $template['header_row'] ?>, Start Column: <?= $template['start_column'] ?></small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<!-- Form per caricare il file -->
|
|
||||||
<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>
|
|
||||||
<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>
|
|
||||||
</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-->
|
|
||||||
<?php include('jsinclude.php'); ?>
|
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
const form = document.getElementById('uploadForm');
|
|
||||||
const loader = document.getElementById('loader');
|
|
||||||
const errorContainer = document.getElementById('errorContainer');
|
|
||||||
const tableContainer = document.getElementById('tableContainer');
|
|
||||||
|
|
||||||
form.addEventListener('submit', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
loader.style.display = 'block';
|
|
||||||
errorContainer.style.display = 'none';
|
|
||||||
tableContainer.innerHTML = '';
|
|
||||||
|
|
||||||
const formData = new FormData(this);
|
|
||||||
formData.append('template_id', <?= $id ?>);
|
|
||||||
formData.append('header_row', <?= $template['header_row'] ?>);
|
|
||||||
formData.append('start_column', <?= $template['start_column'] ?>);
|
|
||||||
|
|
||||||
fetch('process_import_xls.php', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
loader.style.display = 'none';
|
|
||||||
if (data.error) {
|
|
||||||
errorContainer.textContent = data.error;
|
|
||||||
errorContainer.style.display = 'block';
|
|
||||||
} else {
|
|
||||||
let html = `
|
|
||||||
<form id="selectRowsForm" action="import_edit.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>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;
|
|
||||||
|
|
||||||
// Aggiungi logica per il ridimensionamento delle colonne
|
|
||||||
const thElements = document.querySelectorAll('.table th');
|
|
||||||
thElements.forEach((th, index) => {
|
|
||||||
if (index === 0) return; // Escludi la colonna "Seleziona" dal ridimensionamento
|
|
||||||
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');
|
|
||||||
const checkboxes = document.querySelectorAll('.row-checkbox');
|
|
||||||
const proceedButton = document.getElementById('proceedButton');
|
|
||||||
|
|
||||||
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';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Aggiungi event listener per i checkbox
|
|
||||||
checkboxes.forEach(checkbox => {
|
|
||||||
checkbox.addEventListener('change', function() {
|
|
||||||
proceedButton.disabled = !Array.from(checkboxes).some(cb => cb.checked);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
loader.style.display = 'none';
|
|
||||||
errorContainer.textContent = 'Errore durante il caricamento del file: ' + error.message;
|
|
||||||
errorContainer.style.display = 'block';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,413 +0,0 @@
|
|||||||
<?php
|
|
||||||
include('include/headscript.php');
|
|
||||||
|
|
||||||
// Controlla se è stato passato un ID valido
|
|
||||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
|
||||||
header("Location: xlstemplates_grid.php?status=error&message=" . urlencode("Invalid ID"));
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = intval($_GET['id']); // Sanifica l'ID
|
|
||||||
|
|
||||||
// Recupera il template dal database
|
|
||||||
$db = DBHandlerSelect::getInstance();
|
|
||||||
$pdo = $db->getConnection();
|
|
||||||
$stmt = $pdo->prepare("SELECT * FROM excel_templates WHERE id = ?");
|
|
||||||
$stmt->execute([$id]);
|
|
||||||
$template = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
if (!$template) {
|
|
||||||
header("Location: template_dashboard.php?status=error&message=" . urlencode("Template not found"));
|
|
||||||
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));
|
|
||||||
?>
|
|
||||||
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
|
|
||||||
<?php include('cssinclude.php'); ?>
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
.table-container {
|
|
||||||
overflow-x: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th,
|
|
||||||
.table td {
|
|
||||||
padding: 10px;
|
|
||||||
text-align: left;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
min-width: 100px;
|
|
||||||
max-width: 200px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th:first-child,
|
|
||||||
.table td:first-child {
|
|
||||||
min-width: 50px;
|
|
||||||
max-width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th {
|
|
||||||
background-color: #f8f9fa;
|
|
||||||
position: relative;
|
|
||||||
cursor: col-resize;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th .resize-handle {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 5px;
|
|
||||||
height: 100%;
|
|
||||||
cursor: col-resize;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th .resize-handle:hover {
|
|
||||||
background: #007bff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-container {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-container input {
|
|
||||||
width: 300px;
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #ced4da;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader {
|
|
||||||
display: none;
|
|
||||||
border: 4px solid #f3f3f3;
|
|
||||||
border-top: 4px solid #3498db;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
margin: 10px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<title><?= htmlspecialchars($template['name']) ?> - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="wrapper">
|
|
||||||
<?php include('include/navbar.php'); ?>
|
|
||||||
<?php include('include/topbar.php'); ?>
|
|
||||||
<div class="page-wrapper">
|
|
||||||
<div class="page-content">
|
|
||||||
<?php include('top_stat_widget.php'); ?>
|
|
||||||
<div class="mb-3 text">
|
|
||||||
<a href="historical_trf.php?id=<?= $id ?>&status=i" class="btn btn-warning me-2">Imported (i)</a>
|
|
||||||
<a href="historical_trf.php?id=<?= $id ?>&status=P" class="btn btn-primary me-2">In Progress (P)</a>
|
|
||||||
<a href="historical_trf.php?id=<?= $id ?>&status=l" class="btn btn-success">To LIMS (l)</a>
|
|
||||||
</div>
|
|
||||||
<div class="card radius-10">
|
|
||||||
<div class="card-header">
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div>
|
|
||||||
<h6 class="mb-0"><?= htmlspecialchars($template['name']) ?></h6>
|
|
||||||
<small>Template ID: <?= $id ?>, Start Row: <?= $template['header_row'] ?>, Start Column: <?= $template['start_column'] ?></small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<?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" <?= !$hasMappings ? 'disabled' : '' ?>>Upload</button>
|
|
||||||
<div class="loader" id="loader"></div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="errorContainer" class="alert alert-danger mt-3" style="display: none;"></div>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<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() {
|
|
||||||
const form = document.getElementById('uploadForm');
|
|
||||||
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();
|
|
||||||
loader.style.display = 'block';
|
|
||||||
errorContainer.style.display = 'none';
|
|
||||||
tableContainer.innerHTML = '';
|
|
||||||
|
|
||||||
const formData = new FormData(this);
|
|
||||||
const templateId = <?= $id ?>;
|
|
||||||
console.log('Template ID passed to formData:', templateId);
|
|
||||||
formData.append('template_id', templateId);
|
|
||||||
formData.append('header_row', <?= $template['header_row'] ?>);
|
|
||||||
formData.append('start_column', <?= $template['start_column'] ?>);
|
|
||||||
|
|
||||||
fetch('process_import_xls2.php', {
|
|
||||||
method: 'POST',
|
|
||||||
body: formData
|
|
||||||
})
|
|
||||||
.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 {
|
|
||||||
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>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user