diff --git a/public/userarea/class/VisualLimsApiClient.class.php b/public/userarea/class/VisualLimsApiClient.class.php index e9b4a80..f1df702 100644 --- a/public/userarea/class/VisualLimsApiClient.class.php +++ b/public/userarea/class/VisualLimsApiClient.class.php @@ -120,4 +120,76 @@ class VisualLimsApiClient return $data; } + + public function post($endpoint, $payload) + { + $token = $this->getToken(); + $url = "{$this->baseUrl}/api/odata/{$endpoint}"; + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + "Authorization: Bearer {$token}", + "Content-Type: application/json", + "Accept: application/json" + ]); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + + $response = curl_exec($ch); + $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $curl_error = curl_error($ch); + curl_close($ch); + + if ($response === false) { + throw new Exception("Errore nella richiesta POST: {$curl_error}"); + } + + if ($http_code < 200 || $http_code >= 300) { + throw new Exception("POST fallito: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000)); + } + + return json_decode($response, true); + } + + public function patch($endpoint, $payload) + { + $token = $this->getToken(); + $url = "{$this->baseUrl}/api/odata/{$endpoint}"; + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + "Authorization: Bearer {$token}", + "Content-Type: application/json", + "Accept: application/json" + ]); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + + $response = curl_exec($ch); + $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $curl_error = curl_error($ch); + curl_close($ch); + + if ($response === false) { + throw new Exception("Errore nella richiesta PATCH: {$curl_error}"); + } + + if ($http_code < 200 || $http_code >= 300) { + throw new Exception("PATCH fallito: HTTP {$http_code}, Risposta: " . substr($response, 0, 1000)); + } + + return json_decode($response, true); + } + + public function getBaseUrl() + { + return $this->baseUrl; + } + } diff --git a/public/userarea/export_to_lims.php b/public/userarea/export_to_lims.php index 02ebcd0..392c32f 100644 --- a/public/userarea/export_to_lims.php +++ b/public/userarea/export_to_lims.php @@ -1,243 +1,172 @@ getConnection(); -use Dotenv\Dotenv; - -// Carica il file .env -$dotenv = Dotenv::createImmutable(dirname(__DIR__, 3)); // Torna al livello di public -$dotenv->load(); - -// Leggi la variabile SIMULATE_EXPORT_LIMS -$simulate = filter_var($_ENV['SIMULATE_EXPORT_LIMS'] ?? true, FILTER_VALIDATE_BOOLEAN); - -header('Content-Type: application/json'); +header("Content-Type: application/json"); try { - // Verifica che la richiesta sia POST e contenga iddatadb - if ($_SERVER['REQUEST_METHOD'] !== 'POST' || !isset($_POST['iddatadb'])) { - throw new Exception('Richiesta non valida: iddatadb mancante'); + $iddatadb = $_POST['iddatadb'] ?? null; + if (!$iddatadb) { + throw new Exception("Missing iddatadb"); } - $iddatadb = (int)$_POST['iddatadb']; - - // Crea la cartella logsapi se non esiste - $logDir = __DIR__ . '/logsapi'; - if (!is_dir($logDir)) { - mkdir($logDir, 0755, true); - } - - // Ottieni connessione al database - $db = DBHandlerSelect::getInstance(); - $pdo = $db->getConnection(); - - // Step 1: Creazione payload per CommessaWeb - $queryCommessa = " - SELECT - d.iddatadb, - e.idclient AS Cliente, - e.idschema AS SchemaCustomField - FROM datadb d - LEFT JOIN excel_templates e ON d.templateid = e.id + // ๐Ÿ”น STEP 1+2: Fetch Cliente ID + Schema ID + $stmt = $pdo->prepare(" + SELECT et.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); - $stmtCommessa = $pdo->prepare($queryCommessa); - $stmtCommessa->execute(['iddatadb' => $iddatadb]); - $recordCommessa = $stmtCommessa->fetch(PDO::FETCH_ASSOC); - - if (!$recordCommessa) { - throw new Exception("Nessun record trovato per iddatadb: {$iddatadb}"); + if (!$result) { + throw new Exception("No Cliente/Schema found for iddatadb {$iddatadb}"); } - // Validazione payload - if (empty($recordCommessa['Cliente']) || empty($recordCommessa['SchemaCustomField'])) { - throw new Exception("Dati mancanti per CommessaWeb: Cliente o SchemaCustomField non validi"); - } + $clienteId = (int) $result['clienteId']; + $schemaId = (int) $result['schemaId']; - // Payload per creazione CommessaWeb - $payloadCommessa = [ - 'Cliente' => (int)$recordCommessa['Cliente'], - 'SchemaCustomField' => (int)$recordCommessa['SchemaCustomField'], - 'Richiedente' => null, - 'Descrizione' => 'example' - ]; - - // Step 2: Creazione payload per campi custom (CommesseCustomFields) - $queryCustomFields = " - SELECT - tm.field_id AS IdCommesseCustomFields, - idd.field_value AS Valore - FROM import_data_details idd - JOIN template_mapping tm ON idd.mapping_id = tm.id - WHERE idd.id = :iddatadb - "; - - $stmtCustomFields = $pdo->prepare($queryCustomFields); - $stmtCustomFields->execute(['iddatadb' => $iddatadb]); - $customFields = $stmtCustomFields->fetchAll(PDO::FETCH_ASSOC); - - // Costruisci l'array CommesseCustomFields - $commesseCustomFields = []; - foreach ($customFields as $field) { - $commesseCustomFields[] = [ - 'IdCommesseCustomFields' => (int)$field['IdCommesseCustomFields'], - 'Valore' => $field['Valore'] ?? '' - ]; - } - - // Payload per aggiornamento campi custom - $payloadCustomFields = [ - 'CommesseCustomFields' => $commesseCustomFields - ]; - - // Step 3: Creazione payload per Campioni (da identification_parts) - $queryCampioni = " - SELECT - part_number, - idmatrice AS Matrice, - part_description AS NoteWeb + // ๐Ÿ”น 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); - $stmtCampioni = $pdo->prepare($queryCampioni); - $stmtCampioni->execute(['iddatadb' => $iddatadb]); - $campioni = $stmtCampioni->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); - $payloadsCampioni = []; - foreach ($campioni as $campione) { - if (empty($campione['Matrice'])) { - throw new Exception("Matrice non valida per campione: {$campione['part_number']}"); - } - $payloadCampione = [ - 'Commessa' => null, // Sarร  impostato dopo - 'Matrice' => (int)$campione['Matrice'], - 'SottoMatrice' => null, - 'SchemaCustomField' => 1, - 'NoteWeb' => $campione['NoteWeb'] ?? '' + $fieldValues = []; + foreach ($rows as $row) { + $fieldValues[] = [ + "IdCommesseCustomFields" => (int) $row['field_id'], + "Valore" => $row['field_value'] ]; - $payloadsCampioni[] = $payloadCampione; } - // Step 4: Creazione payload per InviaCommessa - $payloadInviaCommessa = []; + // ๐Ÿ”น Initialize API client + $api = VisualLimsApiClient::getInstance(); - // Variabile per idcommessaweb - $idcommessaweb = null; - $commessaweb = ''; + // ๐Ÿ”น STEP 5: Create CommessaWeb (NOT WebOrder) + $commessaWebPayload = [ + "Cliente" => $clienteId, + "SchemaCustomField" => $schemaId, + "Richiedente" => "Test Web Import", + "Descrizione" => "TEST CommessaWeb", + ]; + $commessaWeb = $api->post("CommessaWeb", $commessaWebPayload); - if ($simulate) { - // Flusso simulato - $idcommessaweb = 10176; // Fittizio per il test + $commessaId = $commessaWeb["IdCommessa"]; + // Estraiamo il numero della commessa usando CodiceCommessa + $commessaWebCode = substr($commessaWeb["CodiceCommessa"] ?? "TEST CommessaWeb", 0, 30); // Limite a 30 caratteri - // Salva idcommessaweb in datadb - $updateStmt = $pdo->prepare("UPDATE datadb SET idcommessaweb = :idcommessaweb WHERE iddatadb = :iddatadb"); - $updateStmt->execute(['idcommessaweb' => $idcommessaweb, 'iddatadb' => $iddatadb]); + // ๐Ÿ”น STEP 6: Create Campioni (Samples) for each part + $campioni = []; + foreach ($parts as $index => $part) { + $matriceId = (int) ($part["idmatrice"] ?? 0); - // Salva i payload in file JSON - $outputFileCommessa = $logDir . "/commessaweb_create_{$iddatadb}.json"; - file_put_contents($outputFileCommessa, json_encode($payloadCommessa, JSON_PRETTY_PRINT)); - - $outputFileCustomFields = $logDir . "/commessaweb_customfields_{$iddatadb}.json"; - file_put_contents($outputFileCustomFields, json_encode($payloadCustomFields, JSON_PRETTY_PRINT)); - - foreach ($payloadsCampioni as $index => $payloadCampione) { - $payloadCampione['Commessa'] = $idcommessaweb; - $outputFileCampione = $logDir . "/campione_{$iddatadb}_{$campioni[$index]['part_number']}.json"; - file_put_contents($outputFileCampione, json_encode($payloadCampione, JSON_PRETTY_PRINT)); + if ($matriceId <= 0) { + throw new Exception("Invalid or missing idmatrice for part: " . ($part["part_number"] ?? "Unknown")); } - $outputFileInviaCommessa = $logDir . "/commessaweb_invia_{$iddatadb}.json"; - file_put_contents($outputFileInviaCommessa, json_encode($payloadInviaCommessa, JSON_PRETTY_PRINT)); + $campionePayload = [ + "Commessa" => $commessaId, + "Matrice" => $matriceId, + "SottoMatrice" => null, + "SchemaCustomField" => $schemaId, + "NoteWeb" => $part["part_description"] ?? "" + ]; - // Aggiorna lo status a 'l' (To LIMS) - $updateStmt = $pdo->prepare("UPDATE datadb SET status = 'l' WHERE iddatadb = :iddatadb"); - $updateStmt->execute(['iddatadb' => $iddatadb]); + $campione = $api->post("Campione", $campionePayload); - // Risposta di successo (simulazione) - echo json_encode([ - 'success' => true, - 'mode' => 'simulated', - 'message' => "Payload generati e salvati in {$outputFileCommessa}, {$outputFileCustomFields}, file campioni e {$outputFileInviaCommessa}", - 'idcommessaweb' => $idcommessaweb, - 'commessaweb' => $commessaweb, - 'payload_commessa' => $payloadCommessa, - 'payload_customfields' => $payloadCustomFields, - 'payload_campioni' => $payloadsCampioni, - 'payload_invia_commessa' => $payloadInviaCommessa - ]); - } else { - // Flusso reale - $apiClient = VisualLimsApiClient::getInstance(); + $campione["PartNumber"] = $part["part_number"] ?? ""; + $campione["Material"] = $part["material"] ?? ""; + $campione["Color"] = $part["color"] ?? ""; + $campione["Mix"] = $part["mix"] ?? ""; - // Step 1: Crea CommessaWeb - $response = $apiClient->post('/api/odata/CommessaWeb', $payloadCommessa); - if (!isset($response['success']) || !isset($response['CommessaId'])) { - throw new Exception('Errore nella creazione della CommessaWeb: ' . json_encode($response)); - } - $idcommessaweb = (int)$response['CommessaId']; - - // Salva idcommessaweb in datadb - $updateStmt = $pdo->prepare("UPDATE datadb SET idcommessaweb = :idcommessaweb WHERE iddatadb = :iddatadb"); - $updateStmt->execute(['idcommessaweb' => $idcommessaweb, 'iddatadb' => $iddatadb]); - - // Logga il successo della creazione CommessaWeb - file_put_contents($logDir . '/export_lims_success.log', date('Y-m-d H:i:s') . " - CommessaWeb creata: idcommessaweb {$idcommessaweb} per iddatadb {$iddatadb}\n", FILE_APPEND); - - // Step 2: Aggiorna CommesseCustomFields - $apiClient->patch("/api/odata/CommessaWeb({$idcommessaweb})", $payloadCustomFields); - - // Step 3: Crea Campioni - foreach ($payloadsCampioni as $index => $payloadCampione) { - $payloadCampione['Commessa'] = $idcommessaweb; - $apiClient->post('/api/odata/Campione', $payloadCampione); - $payloadsCampioni[$index] = $payloadCampione; // Aggiorna il payload con Commessa - } - - // Step 4: Invia Commessa - $apiClient->post("/api/odata/CommessaWeb({$idcommessaweb})/InviaCommessa", $payloadInviaCommessa); - - // Step 5: Recupera il numero commessaweb (opzionale) - $commessaData = $apiClient->get("/api/odata/CommessaWeb({$idcommessaweb})"); - $commessaweb = $commessaData['Numero'] ?? ''; - if ($commessaweb) { - $updateStmt = $pdo->prepare("UPDATE datadb SET commessaweb = :commessaweb WHERE iddatadb = :iddatadb"); - $updateStmt->execute(['commessaweb' => $commessaweb, 'iddatadb' => $iddatadb]); - } - - // Aggiorna lo status a 'l' (To LIMS) - $updateStmt = $pdo->prepare("UPDATE datadb SET status = 'l' WHERE iddatadb = :iddatadb"); - $updateStmt->execute(['iddatadb' => $iddatadb]); - - // Risposta di successo (flusso reale) - echo json_encode([ - 'success' => true, - 'mode' => 'real', - 'message' => "Dati inviati al LIMS con successo", - 'idcommessaweb' => $idcommessaweb, - 'commessaweb' => $commessaweb, - 'payload_commessa' => $payloadCommessa, - 'payload_customfields' => $payloadCustomFields, - 'payload_campioni' => $payloadsCampioni, - 'payload_invia_commessa' => $payloadInviaCommessa - ]); + $campioni[] = $campione; } -} catch (Exception $e) { - // Log dell'errore - file_put_contents($logDir . '/export_lims_error.log', date('Y-m-d H:i:s') . ' - Flusso ' . ($simulate ? 'simulato' : 'reale') . ' fallito: ' . $e->getMessage() . PHP_EOL, FILE_APPEND); - http_response_code(500); + + // ๐Ÿ”น STEP 7: Update Custom Fields for CommessaWeb + if (!empty($fieldValues)) { + $commessaWithFields = $api->get("CommessaWeb(" . $commessaId . ")?\$expand=CommesseCustomFields"); + $commessaCustomFields = []; + foreach ($commessaWithFields["CommesseCustomFields"] as $customField) { + foreach ($fieldValues as $fieldValue) { + if ($customField["IdCommesseCustomFields"] == $fieldValue["IdCommesseCustomFields"]) { + $commessaCustomFields[] = [ + "IdCommesseCustomFields" => $customField["IdCommesseCustomFields"], + "Valore" => $fieldValue["Valore"] + ]; + break; + } + } + } + + if (!empty($commessaCustomFields)) { + $updatePayload = ["CommesseCustomFields" => $commessaCustomFields]; + $api->patch("CommessaWeb({$commessaId})", $updatePayload); + } + } + + // ๐Ÿ”น 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 + $sendResult = $api->post("CommessaWeb({$commessaId})/InviaCommessa", []); + + // ๐Ÿ”น STEP 10: Prepare final response + $finalCommessa = [ + "Cliente" => $clienteId, + "SchemaCustomField" => $schemaId, + "Richiedente" => $commessaWeb["Richiedente"] ?? "Web Import", + "Descrizione" => $commessaWeb["Descrizione"] ?? "", + "CommesseCustomFields" => $fieldValues, + "Campioni" => $campioni, + "Inviata" => 1 + ]; + echo json_encode([ - 'success' => false, - 'mode' => $simulate ? 'simulated' : 'real', - 'message' => 'Errore: ' . $e->getMessage() + "success" => true, + "commessaWeb" => $finalCommessa, + "commessaWebApiResponse" => $commessaWeb, // Incluso per debug + "totalCampioni" => count($campioni), + "totalCustomFields" => count($fieldValues), + "message" => "Export successful" + ]); +} catch (Exception $e) { + error_log("LIMS Export Error: " . $e->getMessage() . "\nTrace: " . $e->getTraceAsString()); + + echo json_encode([ + "success" => false, + "message" => "Export failed: " . $e->getMessage() ]); } diff --git a/public/userarea/import_edit2.php b/public/userarea/import_edit2.php index 9ff0fea..5fa19b3 100644 --- a/public/userarea/import_edit2.php +++ b/public/userarea/import_edit2.php @@ -569,7 +569,11 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { $row): ?>
- + + hasRole('Admin'))) : ?> + + + @@ -720,6 +724,33 @@ foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {