diff --git a/public/userarea/products/get_user_table_settings.php b/public/userarea/products/get_user_table_settings.php index a13a82f..7cf5bd3 100644 --- a/public/userarea/products/get_user_table_settings.php +++ b/public/userarea/products/get_user_table_settings.php @@ -1,12 +1,12 @@ prepare($query); - $stmt->bind_param("is", $userId, $tablen); + $stmt->bind_param("is", $userId, $page); $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows > 0) { // Restituisci i dati esistenti $row = $result->fetch_assoc(); - echo json_encode([ - 'column_visibility' => $row['column_visibility'], - 'column_order' => $row['column_order'] - ]); + + // Costruisci l'output JSON nel formato che DataTables si aspetta + $settings = [ + 'columns' => array_map(function ($visible) { + return ['visible' => $visible]; + }, json_decode($row['column_visibility'], true)), // Converti la visibilità in array associativo + 'ColReorder' => json_decode($row['column_order'], true), // Decodifica l'ordine delle colonne + 'time' => time() // Aggiungi un timestamp per evitare che i dati vengano memorizzati in cache + ]; + + echo json_encode($settings); } else { - // Crea un record di default se non esiste - $defaultVisibility = json_encode([/* Impostazioni di visibilità predefinite */]); - $defaultOrder = json_encode([/* Ordine delle colonne predefinito */]); - - $insertQuery = "INSERT INTO user_table_settings (iduser, page, column_visibility, column_order, created_at) VALUES (?, ?, ?, ?, NOW())"; - $insertStmt = $conn->prepare($insertQuery); - $insertStmt->bind_param("isss", $userId, $tablen, $defaultVisibility, $defaultOrder); - $insertStmt->execute(); - - // Restituisci le impostazioni predefinite - echo json_encode([ - 'column_visibility' => $defaultVisibility, - 'column_order' => $defaultOrder - ]); + // Se non ci sono dati, invia un errore (o imposta valori predefiniti) + http_response_code(404); + echo json_encode(['error' => 'No settings found']); } + + $stmt->close(); + $conn->close(); +} else { + // Se i parametri non sono validi, restituisci errore + http_response_code(400); + echo json_encode(['error' => 'Invalid request']); } diff --git a/public/userarea/products/products.php b/public/userarea/products/products.php index 69b70e8..e32e0d4 100644 --- a/public/userarea/products/products.php +++ b/public/userarea/products/products.php @@ -216,6 +216,30 @@ $result = $conn->query($query); - - - - - - \ No newline at end of file diff --git a/public/userarea/products/save_user_table_settings.php b/public/userarea/products/save_user_table_settings.php new file mode 100644 index 0000000..15ab99d --- /dev/null +++ b/public/userarea/products/save_user_table_settings.php @@ -0,0 +1,62 @@ +prepare("SELECT column_visibility, column_order FROM user_table_settings WHERE iduser = ? AND page = ?"); + $stmt->bind_param("is", $iduser, $table); + $stmt->execute(); + $result = $stmt->get_result(); + + if ($result->num_rows > 0) { + $row = $result->fetch_assoc(); + $existing_visibility = $row['column_visibility']; + $existing_order = $row['column_order']; + + // Aggiorna solo se c'è una differenza rispetto alle impostazioni già salvate + if ($existing_visibility != $column_visibility || $existing_order != $column_order) { + $stmt = $conn->prepare("UPDATE user_table_settings SET column_visibility = ?, column_order = ?, updated_at = NOW() WHERE iduser = ? AND page = ?"); + $stmt->bind_param("ssis", $column_visibility, $column_order, $iduser, $table); + if ($stmt->execute()) { + echo json_encode(['success' => true, 'message' => 'Settings updated']); + } else { + echo json_encode(['error' => 'Failed to update settings']); + } + } else { + echo json_encode(['success' => true, 'message' => 'No changes to save']); + } + } else { + // Inserisci nuove impostazioni solo se non esistono già + $stmt = $conn->prepare("INSERT INTO user_table_settings (iduser, page, column_visibility, column_order, created_at) VALUES (?, ?, ?, ?, NOW())"); + $stmt->bind_param("isss", $iduser, $table, $column_visibility, $column_order); + if ($stmt->execute()) { + echo json_encode(['success' => true, 'message' => 'Settings saved']); + } else { + echo json_encode(['error' => 'Failed to save settings']); + } + } + } else { + echo json_encode(['error' => 'Invalid JSON format']); + } +} else { + // Se non ci sono dati sufficienti, invia un errore + http_response_code(400); + echo json_encode(['error' => 'Invalid request']); +} + +$conn->close(); diff --git a/public/userarea/statkpi/parsedatachart-details.php b/public/userarea/statkpi/parsedatachart-details.php new file mode 100644 index 0000000..9d8a7b2 --- /dev/null +++ b/public/userarea/statkpi/parsedatachart-details.php @@ -0,0 +1,427 @@ + +query($totalProductsQuery); +$totalProducts = $totalProductsResult->fetch_assoc()['totalProducts']; + +// Statistic 2: Total number of reports +$totalReportsQuery = " + SELECT COUNT(DISTINCT r.idreports) AS totalReports + FROM reports r + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters +"; +$totalReportsResult = $conn->query($totalReportsQuery); +$totalReports = $totalReportsResult->fetch_assoc()['totalReports']; + +// Statistic 3: Number of 'fail' reports and percentage compared to total +$failedReportsQuery = " + SELECT COUNT(DISTINCT r.idreports) AS failedReports + FROM reports r + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters AND UPPER(r.reportsRating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') +"; +$failedReportsResult = $conn->query($failedReportsQuery); +$failedReports = $failedReportsResult->fetch_assoc()['failedReports']; +$failedReportsPercent = ($totalReports > 0) ? ($failedReports / $totalReports) * 100 : 0; + +// Statistic 4: Total number of tests performed (distinct tests) +$totalTestsQuery = " + SELECT COUNT(DISTINCT rp.idreports, rp.idPart, rp.result_TestName) AS totalTests + FROM result_project rp + LEFT JOIN reports r ON rp.idreports = r.idreports + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters +"; +$totalTestsResult = $conn->query($totalTestsQuery); +$totalTests = $totalTestsResult->fetch_assoc()['totalTests']; + +// Statistic 5: Number of 'fail' tests and percentage (case-insensitive for rating fail) +$failedTestsQuery = " + SELECT COUNT(DISTINCT rp.idreports, rp.idPart, rp.result_TestName) AS failedTests + FROM result_project rp + LEFT JOIN reports r ON rp.idreports = r.idreports + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters AND UPPER(rp.result_Rating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') +"; +$failedTestsResult = $conn->query($failedTestsQuery); +$failedTests = $failedTestsResult->fetch_assoc()['failedTests']; +$failedTestsPercent = ($totalTests > 0) ? ($failedTests / $totalTests) * 100 : 0; + +// Pie Chart Data for Reports (Fail, Pass, Others) +$failReportsPieQuery = " + SELECT COUNT(*) AS failReports + FROM reports r + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters AND UPPER(r.reportsRating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') +"; +$failReportsPieResult = $conn->query($failReportsPieQuery); +$failReportsPie = $failReportsPieResult->fetch_assoc()['failReports']; + +$passReportsPieQuery = " + SELECT COUNT(*) AS passReports + FROM reports r + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters AND UPPER(r.reportsRating) IN ('PASS', 'P', 'COMPLIES') +"; +$passReportsPieResult = $conn->query($passReportsPieQuery); +$passReportsPie = $passReportsPieResult->fetch_assoc()['passReports']; + +$otherReportsPieQuery = " + SELECT COUNT(*) AS otherReports + FROM reports r + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters AND UPPER(r.reportsRating) NOT IN ('FAIL', 'F', 'DOESN\'T COMPLY', 'PASS', 'P', 'COMPLIES') +"; +$otherReportsPieResult = $conn->query($otherReportsPieQuery); +$otherReportsPie = $otherReportsPieResult->fetch_assoc()['otherReports']; + +// Query to get the top 10 analyses with the most 'Fail' results +$topFailingAnalysisQuery = " + SELECT a.nameanalysisvoc AS analysisName, COUNT(DISTINCT rp.idreports, rp.idPart, rp.result_TestName) AS failCount + FROM result_project rp + LEFT JOIN reports r ON rp.idreports = r.idreports + LEFT JOIN products p ON r.idproducts = p.idproducts + LEFT JOIN analysisvocabulary a ON rp.result_TestName = a.idanalysisvocabulary + $filters AND UPPER(rp.result_Rating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') + GROUP BY rp.result_TestName + ORDER BY failCount DESC + LIMIT 10 +"; +$topFailingAnalysisResult = $conn->query($topFailingAnalysisQuery); +$topFailingAnalysis = []; +while ($row = $topFailingAnalysisResult->fetch_assoc()) { + $analysisName = (strlen($row['analysisName']) > 80) ? substr($row['analysisName'], 0, 80) . '...' : $row['analysisName']; + $topFailingAnalysis[] = ['name' => $analysisName, 'failCount' => $row['failCount']]; +} + +// Statistic for worst suppliers based on % of failed reports +$worstSuppliersQuery = " + SELECT p.namesupplier AS supplier, COUNT(r.idreports) AS totalReports, + SUM(CASE WHEN UPPER(r.reportsRating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') THEN 1 ELSE 0 END) AS failedReports, + (SUM(CASE WHEN UPPER(r.reportsRating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') THEN 1 ELSE 0 END) / COUNT(r.idreports)) * 100 AS failPercentage + FROM reports r + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters + GROUP BY p.namesupplier + ORDER BY failPercentage DESC + LIMIT 10 +"; +$worstSuppliersResult = $conn->query($worstSuppliersQuery); +$worstSuppliers = []; +while ($row = $worstSuppliersResult->fetch_assoc()) { + $worstSuppliers[] = [ + 'supplier' => $row['supplier'], + 'failPercentage' => round($row['failPercentage'], 2), + 'totalReports' => $row['totalReports'], + 'failedReports' => $row['failedReports'] + ]; +} + +$suPfilters = ''; +// Statistic for products by suppliers + +if (!empty($supplierFilter)) { + $suPfilters .= " AND p.namesupplier IN ($supplierFilter)"; +} +if (!empty($refNumberFilter)) { + $suPfilters .= " AND p.products_refnumber IN ($refNumberFilter)"; +} +if (!empty($productsSeasonFilter)) { + $suPfilters .= " AND p.products_season IN ($productsSeasonFilter)"; +} +if (!empty($ageRangeFilter)) { + $suPfilters .= " AND p.agerange IN ($ageRangeFilter)"; +} +$productBySupplierQuery = " + SELECT p.namesupplier AS supplier, COUNT(p.idproducts) AS totalProducts + FROM products p + WHERE p.namesupplier IS NOT NULL $suPfilters + GROUP BY p.namesupplier + ORDER BY totalProducts DESC"; + +$productBySupplierResult = $conn->query($productBySupplierQuery); +$productBySupplier = []; +while ($row = $productBySupplierResult->fetch_assoc()) { + $productBySupplier[] = [ + 'supplier' => $row['supplier'], + 'totalProducts' => $row['totalProducts'] + ]; +} +// refNumbers +$refNumbersQuery = " + SELECT p.products_refnumber AS refNumber + FROM products p + WHERE p.products_refnumber IS NOT NULL + GROUP BY p.products_refnumber +"; +$refNumbersResult = $conn->query($refNumbersQuery); +$refNumbers = []; +while ($row = $refNumbersResult->fetch_assoc()) { + $refNumbers[] = [ + 'refNumber' => $row['refNumber'] + ]; +} +// productsSeason +$productsSeasonQuery = " + SELECT p.products_season AS season + FROM products p + WHERE p.products_season IS NOT NULL + GROUP BY p.products_season +"; +$productsSeasonResult = $conn->query($productsSeasonQuery); +$productsSeasons = []; +while ($row = $productsSeasonResult->fetch_assoc()) { + $productsSeasons[] = [ + "season" => $row['season'] + ]; +} + +// ageRanges +$ageRangeQuery = " + SELECT p.agerange AS ageRange + FROM products p + WHERE p.agerange IS NOT NULL + GROUP BY p.agerange +"; + +$ageRangeResult = $conn->query($ageRangeQuery); +$ageRange = []; +while ($row = $ageRangeResult->fetch_assoc()) { + $ageRange[] = [ + "ageRange" => $row['ageRange'] + ]; +} + +// labNames +$labNameQuery = " + SELECT r.reports_LabName AS LabName + FROM reports r + WHERE r.reports_LabName IS NOT NULL + GROUP BY r.reports_LabName +"; +$labNameResult = $conn->query($labNameQuery); +$labName = []; +while ($row = $labNameResult->fetch_assoc()) { + $labName[] = [ + "LabName" => $row['LabName'] + ]; +} + +// tesTypes +$tesTypeQuery = " + SELECT r.reports_testype AS tesType + FROM reports r + WHERE r.reports_testype IS NOT NULL + GROUP BY r.reports_testype +"; +$tesTypeResult = $conn->query($tesTypeQuery); +$tesType = []; +while ($row = $tesTypeResult->fetch_assoc()) { + $tesType[] = [ + "tesType" => $row['tesType'] + ]; +} + +// numberLabs +$numberLabsQuery = " + SELECT r.reportsNumberLab as reportNumber + FROM reports r + WHERE r.reportsNumberLab IS NOT NULL + GROUP BY r.reportsNumberLab +"; +$numberLabsResult = $conn->query($numberLabsQuery); +$numberLabs = []; +while ($row = $numberLabsResult->fetch_assoc()) { + $numberLabs[] = [ + "reportNumber" => $row['reportNumber'] + ]; +} + + +// New Query: Distribution of analyses (for pie chart) +$analysisDistributionQuery = " + SELECT a.nameanalysisvoc AS analysisName, COUNT(DISTINCT rp.idreports, rp.idPart, rp.result_TestName) AS totalTests + FROM result_project rp + LEFT JOIN analysisvocabulary a ON rp.result_TestName = a.idanalysisvocabulary + LEFT JOIN reports r ON rp.idreports = r.idreports + LEFT JOIN products p ON r.idproducts = p.idproducts + $filters + GROUP BY rp.result_TestName + ORDER BY totalTests DESC +"; + +$analysisDistributionResult = $conn->query($analysisDistributionQuery); +$analysisDistribution = []; +while ($row = $analysisDistributionResult->fetch_assoc()) { + $analysisDistribution[] = [ + 'analysisName' => $row['analysisName'], + 'totalTests' => $row['totalTests'] + ]; +} + +// Ora controlliamo se è una richiesta AJAX +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + // Rispondi ai dati aggiornati tramite AJAX + echo json_encode([ + 'totalProducts' => $totalProducts, + 'totalReports' => $totalReports, + 'failedReports' => $failedReports, + 'failedReportsPercent' => $failedReportsPercent, + 'totalTests' => $totalTests, + 'failedTests' => $failedTests, + 'failedTestsPercent' => $failedTestsPercent, + 'failReportsPie' => $failReportsPie, + 'passReportsPie' => $passReportsPie, + 'otherReportsPie' => $otherReportsPie, + 'topFailingAnalysis' => $topFailingAnalysis, + 'worstSuppliers' => $worstSuppliers, + 'productBySupplier' => $productBySupplier, + 'refNumbers' => $refNumbers, + 'productsSeasons' => $productsSeasons, + 'ageRange' => $ageRange, + 'labName' => $labName, + 'tesType' => $tesType, + 'numberLabs' => $numberLabs, + 'analysisDistribution' => $analysisDistribution // Distribuzione delle analisi per il grafico a torta + ]); + exit; // Ferma l'esecuzione del resto dello script dopo aver risposto all'AJAX +} diff --git a/public/userarea/statkpi/statkpi-details.php b/public/userarea/statkpi/statkpi-details.php new file mode 100644 index 0000000..3071d42 --- /dev/null +++ b/public/userarea/statkpi/statkpi-details.php @@ -0,0 +1,1127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + + + + + + + +
+ + + + + +
+ +
+ + + +
+ +
+ +
+
+
+
+ +
+

Importify

+
+
+
+ + + + + +
+ $refNumbers, + // 'productsSeasons' => $productsSeasons, + // 'ageRange' => $ageRange, + // 'labName' => $labName, + // 'tesType' => $tesType, + // 'numberLabs' => $numberLabs, + + ?> +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ + + + + +
+
+
+
+
Importify:
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+
Active Filters:
+
+ +
+ + +
+
+
+
+
+ + +
+ +
+
+
+
+ + + +
+
+
+
+
Products
+

0

+
+
+
+
+
+
+
Reports
+

0

+
+
+
+
+
+
+
Failed Reports
+
+

0

+ (0%) +
+
+
+
+
+
+
+
Total Tests
+

0

+
+
+
+
+
+
+
Failed Tests
+
+

0

+ (0%) +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
Reports Overview
+
+
+
+
+
+
+
+
Worst Analysis
+
+
+
+
+
+ + +
+
+
+
+
Analyts with the Most Failures
+
+
+
+
+
+ + + + + + + +
+
+ +
+ +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file