Update 18-09-2024 adding NAS
This commit is contained in:
@@ -0,0 +1,610 @@
|
||||
<?php include('../include/headscript.php'); ?>
|
||||
<?php include("../class/company.php");
|
||||
include('parsedatachart.php');
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
|
||||
<?php include('../include/seo.php'); ?>
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<link rel="shortcut icon" href="../assets/images/favicon.ico">
|
||||
|
||||
<link href="../assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="../assets/css/icons.css" rel="stylesheet" type="text/css">
|
||||
<link href="../assets/css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/boxicons@2.0.7/css/boxicons.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.css">
|
||||
<script src="../assets/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="../assets/plugins/select2/select2.min.css">
|
||||
<script src="../assets/plugins/select2/select2.min.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||
|
||||
<style>
|
||||
.width-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.flex_center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mg_none {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.table-custom tr {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
#ajax_preloader {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: transparent;
|
||||
z-index: 9999999;
|
||||
}
|
||||
|
||||
.table-custom td,
|
||||
.table-custom th {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.table-custom .btn {
|
||||
padding: 2px 15px;
|
||||
line-height: 1.7;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* Questo allinea verticalmente gli elementi nella riga */
|
||||
gap: 10px;
|
||||
/* Questo crea una piccola distanza tra gli elementi nella riga */
|
||||
}
|
||||
|
||||
.table-custom .form-control,
|
||||
.table-custom .form-select {
|
||||
height: 25px;
|
||||
/* Puoi modificare questo valore per adattarlo al tuo design */
|
||||
padding: 2px 6px;
|
||||
/* riduce la dimensione del padding */
|
||||
font-size: 14px;
|
||||
/* riduce la dimensione del font */
|
||||
}
|
||||
|
||||
.table-custom .form-control-sm.analysis-input {
|
||||
height: 25px;
|
||||
/* Questo modifica la dimensione degli input con classe 'form-control-sm' e 'analysis-input' */
|
||||
padding: 2px 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.padding_none {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.select2-container--open {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.card h5 {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.card {
|
||||
min-height: 150px;
|
||||
/* Imposta un'altezza minima per le card */
|
||||
}
|
||||
|
||||
.percentage {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.bg-light {
|
||||
background-color: #f8f9fa !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border: 2px solid #007bff !important;
|
||||
}
|
||||
|
||||
.border-info {
|
||||
border: 2px solid #17a2b8 !important;
|
||||
}
|
||||
|
||||
.border-danger {
|
||||
border: 2px solid #dc3545 !important;
|
||||
}
|
||||
|
||||
.border-success {
|
||||
border: 2px solid #28a745 !important;
|
||||
}
|
||||
|
||||
.border-warning {
|
||||
border: 2px solid #ffc107 !important;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.col-md-2 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.col-md-2 {
|
||||
flex: 0 0 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
<body class="fixed-left">
|
||||
|
||||
<!-- Loader -->
|
||||
<div id="preloader">
|
||||
<div id="status">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Begin page -->
|
||||
<div id="wrapper">
|
||||
|
||||
<?php include('../include/navigationbar.php'); ?>
|
||||
|
||||
<!-- Start right Content here -->
|
||||
|
||||
<div class="content-page">
|
||||
<!-- Start content -->
|
||||
<div class="content">
|
||||
|
||||
<?php include('../include/topbar.php'); ?>
|
||||
|
||||
<div class="page-content-wrapper ">
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="page-title-box">
|
||||
<div class="btn-group float-right">
|
||||
<ol class="breadcrumb hide-phone p-0 m-0">
|
||||
<li class="breadcrumb-item"><a href="#">Reportify</a></li>
|
||||
<li class="breadcrumb-item active">Importify</li>
|
||||
</ol>
|
||||
</div>
|
||||
<h4 class="page-title">Importify</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end page title end breadcrumb -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="header-title pb-3 mt-0">Importify: <?php echo $dashboard; ?></h5>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
|
||||
<!-- cards -->
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-primary">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Products</h5>
|
||||
<h2 id="totalProducts">0</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-info">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Reports</h5>
|
||||
<h2 id="totalReports">0</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-danger">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Failed Reports</h5>
|
||||
<div class="d-flex justify-content-center align-items-baseline">
|
||||
<h2 id="failedReports">0</h2>
|
||||
<span class="percentage text-danger" id="failedReportsPercent" style="margin-left: 10px;">(0%)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-success">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Total Tests</h5>
|
||||
<h2 id="totalTests">0</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-warning">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Failed Tests</h5>
|
||||
<div class="d-flex justify-content-center align-items-baseline">
|
||||
<h2 id="failedTests">0</h2>
|
||||
<span class="percentage text-danger" id="failedTestsPercent" style="margin-left: 10px;">(0%)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4"> <!-- Colonna per il primo grafico (Pie Chart) -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Reports Overview</h5>
|
||||
<div id="reportPieChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8"> <!-- Colonna per il secondo grafico -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Worst Analysis</h5>
|
||||
<div id="worsttenanalysis"></div> <!-- Questo è lo spazio per il secondo grafico -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Worst Suppliers by Failed Report Percentage</h5>
|
||||
<div id="worstSuppliersChart"></div> <!-- Il grafico verrà inserito qui -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Number of Products by Supplier</h5>
|
||||
<div id="productBySupplierChart"></div> <!-- Lo spazio per il grafico -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div><!-- container -->
|
||||
|
||||
</div> <!-- Page content Wrapper -->
|
||||
|
||||
</div> <!-- content -->
|
||||
|
||||
<?php include('../include/footer.php'); ?>
|
||||
|
||||
</div>
|
||||
<!-- End Right content here -->
|
||||
|
||||
</div>
|
||||
<!-- END wrapper -->
|
||||
|
||||
<script>
|
||||
document.getElementById('totalProducts').innerText = <?php echo $totalProducts; ?>;
|
||||
document.getElementById('totalReports').innerText = <?php echo $totalReports; ?>;
|
||||
document.getElementById('failedReports').innerText = <?php echo $failedReports; ?>;
|
||||
document.getElementById('failedReportsPercent').innerText = "(<?php echo number_format($failedReportsPercent, 2); ?>%)";
|
||||
document.getElementById('totalTests').innerText = <?php echo $totalTests; ?>;
|
||||
document.getElementById('failedTests').innerText = <?php echo $failedTests; ?>;
|
||||
document.getElementById('failedTestsPercent').innerText = "(<?php echo number_format($failedTestsPercent, 2); ?>%)";
|
||||
</script>
|
||||
<script>
|
||||
// Data for pie chart (Reports: Fail, Pass, Others)
|
||||
var options = {
|
||||
series: [<?php echo $failReportsPie; ?>, <?php echo $passReportsPie; ?>, <?php echo $otherReportsPie; ?>],
|
||||
chart: {
|
||||
width: '100%', // Mantieni la larghezza al 100% all'interno della colonna Bootstrap
|
||||
type: 'pie',
|
||||
},
|
||||
labels: ['Fail', 'Pass', 'Others'],
|
||||
colors: ['#FF4D4D', '#28A745', '#FFA500'], // Red for Fail, Green for Pass, Orange for Others
|
||||
responsive: [{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
chart: {
|
||||
width: 250 // Riduci la larghezza sui dispositivi mobili
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
}
|
||||
}
|
||||
}],
|
||||
legend: {
|
||||
position: 'bottom', // Posiziona la legenda sotto il grafico
|
||||
offsetY: 0,
|
||||
height: 50, // Altezza della legenda
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#reportPieChart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
<script>
|
||||
// Data for the bar chart
|
||||
var analysisNames = <?php echo json_encode(array_column($topFailingAnalysis, 'name')); ?>;
|
||||
var failCounts = <?php echo json_encode(array_column($topFailingAnalysis, 'failCount')); ?>;
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
data: failCounts
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 350
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
dataLabels: {
|
||||
position: 'center' // Posiziona i nomi delle analisi al centro delle barre
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'], // Colore del testo all'interno delle barre (bianco)
|
||||
fontSize: '12px'
|
||||
},
|
||||
formatter: function(val, opt) {
|
||||
return analysisNames[opt.dataPointIndex]; // Mostra il nome dell'analisi dentro la barra
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: failCounts, // Visualizza solo i numeri sull'asse X
|
||||
title: {
|
||||
text: 'Number of Failures'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false // Nascondiamo le etichette dell'asse Y
|
||||
},
|
||||
title: {
|
||||
text: 'Analysis'
|
||||
}
|
||||
},
|
||||
colors: ['#FF4D4D'], // Rosso per i Fail
|
||||
responsive: [{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
chart: {
|
||||
height: 300
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
show: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}],
|
||||
title: {
|
||||
text: 'Top 10 Analyses with the Most Failures',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#worsttenanalysis"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Data for the bar chart of worst suppliers
|
||||
var supplierNames = <?php echo json_encode(array_column($worstSuppliers, 'supplier')); ?>;
|
||||
var failPercentages = <?php echo json_encode(array_column($worstSuppliers, 'failPercentage')); ?>;
|
||||
var totalReportsForSupplier = <?php echo json_encode(array_column($worstSuppliers, 'totalReports')); ?>;
|
||||
var failedReportsForSupplier = <?php echo json_encode(array_column($worstSuppliers, 'failedReports')); ?>;
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
data: failPercentages
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
dataLabels: {
|
||||
position: 'center' // Etichette al centro delle barre
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'], // Colore del testo all'interno delle barre
|
||||
fontSize: '12px'
|
||||
},
|
||||
formatter: function(val, opt) {
|
||||
// Aggiungi nome del fornitore, percentuale, numero di fail e numero totale di report
|
||||
var totalReports = totalReportsForSupplier[opt.dataPointIndex]; // Numero totale di report
|
||||
var failedReports = failedReportsForSupplier[opt.dataPointIndex]; // Numero di report falliti
|
||||
return supplierNames[opt.dataPointIndex] + ' (' + val.toFixed(2) + '%) (Fail: ' + failedReports + ' - Total: ' + totalReports + ')';
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: supplierNames, // Visualizza i nomi dei fornitori
|
||||
title: {
|
||||
text: 'Failure Percentage (%)'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false // Nascondiamo le etichette dell'asse Y
|
||||
},
|
||||
title: {
|
||||
text: 'Suppliers'
|
||||
}
|
||||
},
|
||||
colors: ['#3368FF'], // Colore blu chiaro per le barre
|
||||
title: {
|
||||
text: 'Top 10 Suppliers with the Highest Failed Reports Percentage',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#worstSuppliersChart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Prepara i dati per il grafico
|
||||
var supplierNames = <?php echo json_encode(array_column($productBySupplier, 'supplier')); ?>;
|
||||
var totalProducts = <?php echo json_encode(array_column($productBySupplier, 'totalProducts')); ?>;
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'Total Products',
|
||||
data: totalProducts
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false, // Imposta il grafico a barre verticali
|
||||
columnWidth: '50%',
|
||||
dataLabels: {
|
||||
position: 'top', // Etichette nella parte superiore delle barre
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
offsetY: -20,
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
colors: ['#000']
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: supplierNames,
|
||||
title: {
|
||||
text: 'Suppliers'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
title: {
|
||||
text: 'Number of Products'
|
||||
}
|
||||
},
|
||||
colors: ['#3368FF'],
|
||||
title: {
|
||||
text: 'Number of Products by Supplier',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#productBySupplierChart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- plugin JS -->
|
||||
<script src="../assets/js/popper.min.js"></script>
|
||||
<script src="../assets/js/bootstrap.min.js"></script>
|
||||
<script src="../assets/js/modernizr.min.js"></script>
|
||||
<script src="../assets/js/detect.js"></script>
|
||||
<script src="../assets/js/fastclick.js"></script>
|
||||
<script src="../assets/js/jquery.slimscroll.js"></script>
|
||||
<script src="../assets/js/jquery.blockUI.js"></script>
|
||||
<script src="../assets/js/waves.js"></script>
|
||||
<script src="../assets/js/jquery.nicescroll.js"></script>
|
||||
<script src="../assets/js/jquery.scrollTo.min.js"></script>
|
||||
<script src="../assets/js/common_helper.js"></script>
|
||||
|
||||
<script src="../assets/plugins/chart.js/chart.min.js"></script>
|
||||
<script src="../assets/pages/dashboard.js"></script>
|
||||
|
||||
<!-- App js -->
|
||||
<script src="../assets/js/app.js"></script>
|
||||
<script src="../assets/plugins/alertify/js/alertify.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php include('../include/headscript.php'); ?>
|
||||
<?php include("../class/company.php");
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
|
||||
<?php include('../include/seo.php'); ?>
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<link rel="shortcut icon" href="../assets/images/favicon.ico">
|
||||
|
||||
<link href="../assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="../assets/css/icons.css" rel="stylesheet" type="text/css">
|
||||
<link href="../assets/css/style.css" rel="stylesheet" type="text/css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/boxicons@2.0.7/css/boxicons.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.css">
|
||||
<style>
|
||||
.table-custom tr {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.table-custom td,
|
||||
.table-custom th {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.table-custom .btn {
|
||||
padding: 2px 15px;
|
||||
line-height: 1.7;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* Questo allinea verticalmente gli elementi nella riga */
|
||||
gap: 10px;
|
||||
/* Questo crea una piccola distanza tra gli elementi nella riga */
|
||||
}
|
||||
|
||||
.table-custom .form-control,
|
||||
.table-custom .form-select {
|
||||
height: 25px;
|
||||
/* Puoi modificare questo valore per adattarlo al tuo design */
|
||||
padding: 2px 6px;
|
||||
/* riduce la dimensione del padding */
|
||||
font-size: 14px;
|
||||
/* riduce la dimensione del font */
|
||||
}
|
||||
|
||||
.table-custom .form-control-sm.analysis-input {
|
||||
height: 25px;
|
||||
/* Questo modifica la dimensione degli input con classe 'form-control-sm' e 'analysis-input' */
|
||||
padding: 2px 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
||||
<body class="fixed-left">
|
||||
|
||||
<!-- Loader -->
|
||||
<div id="preloader">
|
||||
<div id="status">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Begin page -->
|
||||
<div id="wrapper">
|
||||
|
||||
<?php include('../include/navigationbar.php'); ?>
|
||||
|
||||
<!-- Start right Content here -->
|
||||
|
||||
<div class="content-page">
|
||||
<!-- Start content -->
|
||||
<div class="content">
|
||||
|
||||
<?php include('../include/topbar.php'); ?>
|
||||
|
||||
<div class="page-content-wrapper ">
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="page-title-box">
|
||||
<div class="btn-group float-right">
|
||||
<ol class="breadcrumb hide-phone p-0 m-0">
|
||||
<li class="breadcrumb-item"><a href="#">Reportify</a></li>
|
||||
<li class="breadcrumb-item active">StatKPI</li>
|
||||
</ol>
|
||||
</div>
|
||||
<h4 class="page-title">StatKPI</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end page title end breadcrumb -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="header-title pb-3 mt-0">Products</h5>
|
||||
<a class="btn btn-primary" href="insert-importifytemplate.php" role="button">Products</a>
|
||||
<a class="btn btn-danger" href="../index.php" role="button">Dahboard</a>
|
||||
|
||||
<br><br>
|
||||
<div class="col-sm-12 mb-3">
|
||||
<input type="text" class="form-control" id="searchInput" placeholder="Search by Component or CAS">
|
||||
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm sm-0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th><strong>Ref. Number</strong></th>
|
||||
<th><strong>Description</strong></th>
|
||||
<th><strong>Ref. Number</strong></th>
|
||||
<th><strong>Description</strong></th>
|
||||
<th><strong>Test Out</strong></th>
|
||||
<th><strong>Rating</strong></th>
|
||||
<th><strong>Action</strong></th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $productslist = new WA_MySQLi_RS("rsl", $repnew, 0);
|
||||
$productslist->setQuery("SELECT * FROM products");
|
||||
$productslist->execute();
|
||||
|
||||
$wa_startindex = 0;
|
||||
while (!$productslist->atEnd()) {
|
||||
$wa_startindex = $productslist->Index;
|
||||
?> <tr>
|
||||
<td><?php echo ($productslist->getColumnVal("products_refnumber")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("products_description")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("products_refnumber")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("products_description")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("reportsDateOut")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("reportsRating")); ?></td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td>
|
||||
<a class="btn btn-success" href="material-rsl.php?id=<?php echo ($productslist->getColumnVal("idimporttemplates")); ?>" role="button" data-toggle="tooltip" title="Go"><i class="fas fa-angle-double-right font-size-16 align-middle"></i></a>
|
||||
<a class="btn btn-primary" href="material-rsl.php?id=<?php echo ($productslist->getColumnVal("idimporttemplates")); ?>" role="button" data-toggle="tooltip" title="Expand"><i class="fas fa-angle-double-down font-size-16 align-middle"></i></a>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<?php $productslist->moveNext();
|
||||
}
|
||||
$productslist->moveFirst(); //return RS to first record
|
||||
unset($wa_startindex);
|
||||
unset($wa_repeatcount);
|
||||
|
||||
?></tbody>
|
||||
</table>
|
||||
</div><!--end table-responsive-->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
|
||||
</div><!-- container -->
|
||||
|
||||
</div> <!-- Page content Wrapper -->
|
||||
|
||||
</div> <!-- content -->
|
||||
|
||||
<?php include('../include/footer.php'); ?>
|
||||
|
||||
</div>
|
||||
<!-- End Right content here -->
|
||||
|
||||
</div>
|
||||
<!-- END wrapper -->
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- plugin JS -->
|
||||
<script src="../assets/js/jquery.min.js"></script>
|
||||
<script src="../assets/js/popper.min.js"></script>
|
||||
<script src="../assets/js/bootstrap.min.js"></script>
|
||||
<script src="../assets/js/modernizr.min.js"></script>
|
||||
<script src="../assets/js/detect.js"></script>
|
||||
<script src="../assets/js/fastclick.js"></script>
|
||||
<script src="../assets/js/jquery.slimscroll.js"></script>
|
||||
<script src="../assets/js/jquery.blockUI.js"></script>
|
||||
<script src="../assets/js/waves.js"></script>
|
||||
<script src="../assets/js/jquery.nicescroll.js"></script>
|
||||
<script src="../assets/js/jquery.scrollTo.min.js"></script>
|
||||
|
||||
<script src="../assets/plugins/chart.js/chart.min.js"></script>
|
||||
<script src="../assets/pages/dashboard.js"></script>
|
||||
|
||||
<!-- App js -->
|
||||
<script src="../assets/js/app.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php include('../../Connections/repnew.php'); ?>
|
||||
<?php
|
||||
$conn = new mysqli($servername, $username, $password, $database);
|
||||
|
||||
// Ottieni i filtri dal POST
|
||||
$startDate = isset($_POST['startDate']) ? $_POST['startDate'] : '';
|
||||
$endDate = isset($_POST['endDate']) ? $_POST['endDate'] : '';
|
||||
$supplierFilter = isset($_POST['supplier']) ? $_POST['supplier'] : '';
|
||||
|
||||
// Creazione della condizione dei filtri di data e supplier
|
||||
$filters = "WHERE 1=1";
|
||||
if (!empty($startDate) && !empty($endDate)) {
|
||||
$filters .= " AND r.reportsDateOut BETWEEN '$startDate' AND '$endDate'";
|
||||
}
|
||||
if (!empty($supplierFilter)) {
|
||||
$filters .= " AND p.namesupplier = '$supplierFilter'";
|
||||
}
|
||||
|
||||
// Statistic 1: Total number of products (filtered by supplier if necessary)
|
||||
$totalProductsQuery = "SELECT COUNT(DISTINCT p.idproducts) AS totalProducts FROM products p";
|
||||
if (!empty($supplierFilter)) {
|
||||
$totalProductsQuery .= " WHERE p.namesupplier = '$supplierFilter'";
|
||||
}
|
||||
$totalProductsResult = $conn->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']
|
||||
];
|
||||
}
|
||||
|
||||
// Statistic for products by suppliers
|
||||
$productBySupplierQuery = "
|
||||
SELECT p.namesupplier AS supplier, COUNT(p.idproducts) AS totalProducts
|
||||
FROM products p
|
||||
WHERE p.namesupplier IS NOT NULL
|
||||
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']
|
||||
];
|
||||
}
|
||||
|
||||
// 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
|
||||
]);
|
||||
exit; // Ferma l'esecuzione del resto dello script dopo aver risposto all'AJAX
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php include('../include/headscript.php'); ?>
|
||||
<?php include("../class/company.php");
|
||||
include('parsedatachart.php');
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
@@ -20,12 +21,49 @@
|
||||
<link href="https://cdn.jsdelivr.net/npm/boxicons@2.0.7/css/boxicons.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sweetalert2@10/dist/sweetalert2.min.css">
|
||||
<script src="../assets/js/jquery.min.js"></script>
|
||||
<link rel="stylesheet" href="../assets/plugins/select2/select2.min.css">
|
||||
<script src="../assets/plugins/select2/select2.min.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/4.2.6/gridstack.min.css" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/4.2.6/gridstack-h5.min.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.width-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.flex_center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.mg_none {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.table-custom tr {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
#ajax_preloader {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: transparent;
|
||||
z-index: 9999999;
|
||||
}
|
||||
|
||||
.table-custom td,
|
||||
.table-custom th {
|
||||
padding: 4px 8px;
|
||||
@@ -61,7 +99,103 @@
|
||||
padding: 2px 6px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.padding_none {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.select2-container--open {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
|
||||
transition: transform 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.card h5 {
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.card {
|
||||
min-height: 150px;
|
||||
/* Imposta un'altezza minima per le card */
|
||||
}
|
||||
|
||||
.percentage {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.bg-light {
|
||||
background-color: #f8f9fa !important;
|
||||
}
|
||||
|
||||
.border-primary {
|
||||
border: 2px solid #007bff !important;
|
||||
}
|
||||
|
||||
.border-info {
|
||||
border: 2px solid #17a2b8 !important;
|
||||
}
|
||||
|
||||
.border-danger {
|
||||
border: 2px solid #dc3545 !important;
|
||||
}
|
||||
|
||||
.border-success {
|
||||
border: 2px solid #28a745 !important;
|
||||
}
|
||||
|
||||
.border-warning {
|
||||
border: 2px solid #ffc107 !important;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.col-md-2 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.col-md-2 {
|
||||
flex: 0 0 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.filters-applied {
|
||||
display: inline-block;
|
||||
background-color: #3368ff;
|
||||
color: white;
|
||||
border-radius: 5px;
|
||||
padding: 5px 10px;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
@@ -74,6 +208,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Begin page -->
|
||||
<div id="wrapper">
|
||||
|
||||
@@ -97,91 +233,162 @@
|
||||
<div class="btn-group float-right">
|
||||
<ol class="breadcrumb hide-phone p-0 m-0">
|
||||
<li class="breadcrumb-item"><a href="#">Reportify</a></li>
|
||||
<li class="breadcrumb-item active">StatKPI</li>
|
||||
<li class="breadcrumb-item active">Importify</li>
|
||||
</ol>
|
||||
</div>
|
||||
<h4 class="page-title">StatKPI</h4>
|
||||
<h4 class="page-title">Importify</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end page title end breadcrumb -->
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="header-title pb-3 mt-0">Products</h5>
|
||||
<a class="btn btn-primary" href="insert-importifytemplate.php" role="button">Products</a>
|
||||
<a class="btn btn-danger" href="../index.php" role="button">Dahboard</a>
|
||||
|
||||
<br><br>
|
||||
<div class="col-sm-12 mb-3">
|
||||
<input type="text" class="form-control" id="searchInput" placeholder="Search by Component or CAS">
|
||||
<h5 class="header-title pb-3 mt-0">Importify: <?php echo $dashboard; ?></h5>
|
||||
|
||||
<!-- Filter Section -->
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<label for="startDate">Start Date</label>
|
||||
<input type="date" id="startDate" class="form-control" placeholder="Start Date">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="endDate">End Date</label>
|
||||
<input type="date" id="endDate" class="form-control" placeholder="End Date">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label for="supplierFilter">Supplier</label>
|
||||
<select id="supplierFilter" class="form-control select2">
|
||||
<option value="">All Suppliers</option>
|
||||
<?php foreach ($productBySupplier as $supplier): ?>
|
||||
<option value="<?php echo $supplier['supplier']; ?>"><?php echo $supplier['supplier']; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<!-- Active Filters Display -->
|
||||
<div id="activeFilters" class="mt-3" style="display: none;">
|
||||
<h6>Active Filters:</h6>
|
||||
<div id="filterDisplay" class="filters-applied badge badge-info p-2" style="font-size: 16px;"></div>
|
||||
<button id="clearFilters" class="btn btn-sm btn-warning ml-3">Clear Filters</button>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-sm sm-0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th><strong>Ref. Number</strong></th>
|
||||
<th><strong>Description</strong></th>
|
||||
<th><strong>Ref. Number</strong></th>
|
||||
<th><strong>Description</strong></th>
|
||||
<th><strong>Test Out</strong></th>
|
||||
<th><strong>Rating</strong></th>
|
||||
<th><strong>Action</strong></th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $productslist = new WA_MySQLi_RS("rsl", $repnew, 0);
|
||||
$productslist->setQuery("SELECT * FROM products");
|
||||
$productslist->execute();
|
||||
|
||||
$wa_startindex = 0;
|
||||
while (!$productslist->atEnd()) {
|
||||
$wa_startindex = $productslist->Index;
|
||||
?> <tr>
|
||||
<td><?php echo ($productslist->getColumnVal("products_refnumber")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("products_description")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("products_refnumber")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("products_description")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("reportsDateOut")); ?></td>
|
||||
<td><?php echo ($productslist->getColumnVal("reportsRating")); ?></td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td>
|
||||
<a class="btn btn-success" href="material-rsl.php?id=<?php echo ($productslist->getColumnVal("idimporttemplates")); ?>" role="button" data-toggle="tooltip" title="Go"><i class="fas fa-angle-double-right font-size-16 align-middle"></i></a>
|
||||
<a class="btn btn-primary" href="material-rsl.php?id=<?php echo ($productslist->getColumnVal("idimporttemplates")); ?>" role="button" data-toggle="tooltip" title="Expand"><i class="fas fa-angle-double-down font-size-16 align-middle"></i></a>
|
||||
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<?php $productslist->moveNext();
|
||||
}
|
||||
$productslist->moveFirst(); //return RS to first record
|
||||
unset($wa_startindex);
|
||||
unset($wa_repeatcount);
|
||||
|
||||
?></tbody>
|
||||
</table>
|
||||
</div><!--end table-responsive-->
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
|
||||
<!-- cards -->
|
||||
<div class="row justify-content-between">
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-primary">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Products</h5>
|
||||
<h2 id="totalProducts">0</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-info">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Reports</h5>
|
||||
<h2 id="totalReports">0</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-danger">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Failed Reports</h5>
|
||||
<div class="d-flex justify-content-center align-items-baseline">
|
||||
<h2 id="failedReports">0</h2>
|
||||
<span class="percentage text-danger" id="failedReportsPercent" style="margin-left: 10px;">(0%)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-success">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Total Tests</h5>
|
||||
<h2 id="totalTests">0</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2 col-sm-6">
|
||||
<div class="card text-center bg-light border-warning">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Failed Tests</h5>
|
||||
<div class="d-flex justify-content-center align-items-baseline">
|
||||
<h2 id="failedTests">0</h2>
|
||||
<span class="percentage text-danger" id="failedTestsPercent" style="margin-left: 10px;">(0%)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4"> <!-- Colonna per il primo grafico (Pie Chart) -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Reports Overview</h5>
|
||||
<div id="reportPieChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8"> <!-- Colonna per il secondo grafico -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Worst Analysis</h5>
|
||||
<div id="worsttenanalysis"></div> <!-- Questo è lo spazio per il secondo grafico -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Worst Suppliers by Failed Report Percentage</h5>
|
||||
<div id="worstSuppliersChart"></div> <!-- Il grafico verrà inserito qui -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Number of Products by Supplier</h5>
|
||||
<div id="productBySupplierChart"></div> <!-- Lo spazio per il grafico -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div><!-- container -->
|
||||
|
||||
@@ -198,12 +405,304 @@
|
||||
<!-- END wrapper -->
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
// Inizializza Select2 per il filtro supplier
|
||||
$('#supplierFilter').select2({
|
||||
placeholder: 'Select a supplier',
|
||||
allowClear: true
|
||||
});
|
||||
|
||||
// Funzione per aggiornare i dati con AJAX
|
||||
function updateData() {
|
||||
var startDate = $('#startDate').val();
|
||||
var endDate = $('#endDate').val();
|
||||
var supplier = $('#supplierFilter').val();
|
||||
|
||||
$.ajax({
|
||||
url: 'parsedatachart.php',
|
||||
method: 'POST',
|
||||
data: {
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
supplier: supplier
|
||||
},
|
||||
success: function(response) {
|
||||
// Assicurati di fare il parsing della risposta JSON
|
||||
var data = JSON.parse(response);
|
||||
|
||||
// Aggiorna le cards con i nuovi dati
|
||||
$('#totalProducts').text(data.totalProducts);
|
||||
$('#totalReports').text(data.totalReports);
|
||||
$('#failedReports').text(data.failedReports);
|
||||
$('#failedReportsPercent').text('(' + data.failedReportsPercent.toFixed(2) + '%)');
|
||||
$('#totalTests').text(data.totalTests);
|
||||
$('#failedTests').text(data.failedTests);
|
||||
$('#failedTestsPercent').text('(' + data.failedTestsPercent.toFixed(2) + '%)');
|
||||
|
||||
// Aggiorna il grafico dei report (Pie Chart)
|
||||
chart.updateSeries([data.failReportsPie, data.passReportsPie, data.otherReportsPie]);
|
||||
|
||||
// Mostra i filtri attivi
|
||||
var filterText = '';
|
||||
if (startDate && endDate) {
|
||||
filterText += 'Date: ' + startDate + ' to ' + endDate + ' ';
|
||||
}
|
||||
if (supplier) {
|
||||
filterText += 'Supplier: ' + $('#supplierFilter option:selected').text();
|
||||
}
|
||||
$('#filterDisplay').text(filterText);
|
||||
$('#activeFilters').show();
|
||||
},
|
||||
error: function() {
|
||||
alert('Error retrieving data.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Eventi per applicare i filtri
|
||||
$('#startDate, #endDate, #supplierFilter').on('change', function() {
|
||||
updateData();
|
||||
});
|
||||
|
||||
// Clear filters
|
||||
$('#clearFilters').on('click', function() {
|
||||
$('#startDate').val('');
|
||||
$('#endDate').val('');
|
||||
$('#supplierFilter').val('').trigger('change');
|
||||
updateData();
|
||||
$('#activeFilters').hide();
|
||||
});
|
||||
|
||||
// Chiamata iniziale per caricare i dati alla prima visualizzazione della pagina
|
||||
updateData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
document.getElementById('totalProducts').innerText = <?php echo $totalProducts; ?>;
|
||||
document.getElementById('totalReports').innerText = <?php echo $totalReports; ?>;
|
||||
document.getElementById('failedReports').innerText = <?php echo $failedReports; ?>;
|
||||
document.getElementById('failedReportsPercent').innerText = "(<?php echo number_format($failedReportsPercent, 2); ?>%)";
|
||||
document.getElementById('totalTests').innerText = <?php echo $totalTests; ?>;
|
||||
document.getElementById('failedTests').innerText = <?php echo $failedTests; ?>;
|
||||
document.getElementById('failedTestsPercent').innerText = "(<?php echo number_format($failedTestsPercent, 2); ?>%)";
|
||||
</script>
|
||||
<script>
|
||||
// Data for pie chart (Reports: Fail, Pass, Others)
|
||||
var options = {
|
||||
series: [<?php echo $failReportsPie; ?>, <?php echo $passReportsPie; ?>, <?php echo $otherReportsPie; ?>],
|
||||
chart: {
|
||||
width: '100%', // Mantieni la larghezza al 100% all'interno della colonna Bootstrap
|
||||
type: 'pie',
|
||||
},
|
||||
labels: ['Fail', 'Pass', 'Others'],
|
||||
colors: ['#FF4D4D', '#28A745', '#FFA500'], // Red for Fail, Green for Pass, Orange for Others
|
||||
responsive: [{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
chart: {
|
||||
width: 250 // Riduci la larghezza sui dispositivi mobili
|
||||
},
|
||||
legend: {
|
||||
position: 'bottom'
|
||||
}
|
||||
}
|
||||
}],
|
||||
legend: {
|
||||
position: 'bottom', // Posiziona la legenda sotto il grafico
|
||||
offsetY: 0,
|
||||
height: 50, // Altezza della legenda
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#reportPieChart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
<script>
|
||||
// Data for the bar chart
|
||||
var analysisNames = <?php echo json_encode(array_column($topFailingAnalysis, 'name')); ?>;
|
||||
var failCounts = <?php echo json_encode(array_column($topFailingAnalysis, 'failCount')); ?>;
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
data: failCounts
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 350
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
dataLabels: {
|
||||
position: 'center' // Posiziona i nomi delle analisi al centro delle barre
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'], // Colore del testo all'interno delle barre (bianco)
|
||||
fontSize: '12px'
|
||||
},
|
||||
formatter: function(val, opt) {
|
||||
return analysisNames[opt.dataPointIndex]; // Mostra il nome dell'analisi dentro la barra
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: failCounts, // Visualizza solo i numeri sull'asse X
|
||||
title: {
|
||||
text: 'Number of Failures'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false // Nascondiamo le etichette dell'asse Y
|
||||
},
|
||||
title: {
|
||||
text: 'Analysis'
|
||||
}
|
||||
},
|
||||
colors: ['#FF4D4D'], // Rosso per i Fail
|
||||
responsive: [{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
chart: {
|
||||
height: 300
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
show: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}],
|
||||
title: {
|
||||
text: 'Top 10 Analyses with the Most Failures',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#worsttenanalysis"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Data for the bar chart of worst suppliers
|
||||
var supplierNames = <?php echo json_encode(array_column($worstSuppliers, 'supplier')); ?>;
|
||||
var failPercentages = <?php echo json_encode(array_column($worstSuppliers, 'failPercentage')); ?>;
|
||||
var totalReportsForSupplier = <?php echo json_encode(array_column($worstSuppliers, 'totalReports')); ?>;
|
||||
var failedReportsForSupplier = <?php echo json_encode(array_column($worstSuppliers, 'failedReports')); ?>;
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
data: failPercentages
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
dataLabels: {
|
||||
position: 'center' // Etichette al centro delle barre
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'], // Colore del testo all'interno delle barre
|
||||
fontSize: '12px'
|
||||
},
|
||||
formatter: function(val, opt) {
|
||||
// Aggiungi nome del fornitore, percentuale, numero di fail e numero totale di report
|
||||
var totalReports = totalReportsForSupplier[opt.dataPointIndex]; // Numero totale di report
|
||||
var failedReports = failedReportsForSupplier[opt.dataPointIndex]; // Numero di report falliti
|
||||
return supplierNames[opt.dataPointIndex] + ' (' + val.toFixed(2) + '%) (Fail: ' + failedReports + ' - Total: ' + totalReports + ')';
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: supplierNames, // Visualizza i nomi dei fornitori
|
||||
title: {
|
||||
text: 'Failure Percentage (%)'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false // Nascondiamo le etichette dell'asse Y
|
||||
},
|
||||
title: {
|
||||
text: 'Suppliers'
|
||||
}
|
||||
},
|
||||
colors: ['#3368FF'], // Colore blu chiaro per le barre
|
||||
title: {
|
||||
text: 'Top 10 Suppliers with the Highest Failed Reports Percentage',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#worstSuppliersChart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Prepara i dati per il grafico
|
||||
var supplierNames = <?php echo json_encode(array_column($productBySupplier, 'supplier')); ?>;
|
||||
var totalProducts = <?php echo json_encode(array_column($productBySupplier, 'totalProducts')); ?>;
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'Total Products',
|
||||
data: totalProducts
|
||||
}],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false, // Imposta il grafico a barre verticali
|
||||
columnWidth: '50%',
|
||||
dataLabels: {
|
||||
position: 'top', // Etichette nella parte superiore delle barre
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
offsetY: -20,
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
colors: ['#000']
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: supplierNames,
|
||||
title: {
|
||||
text: 'Suppliers'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
title: {
|
||||
text: 'Number of Products'
|
||||
}
|
||||
},
|
||||
colors: ['#3368FF'],
|
||||
title: {
|
||||
text: 'Number of Products by Supplier',
|
||||
align: 'center'
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#productBySupplierChart"), options);
|
||||
chart.render();
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- plugin JS -->
|
||||
<script src="../assets/js/jquery.min.js"></script>
|
||||
<script src="../assets/js/popper.min.js"></script>
|
||||
<script src="../assets/js/bootstrap.min.js"></script>
|
||||
<script src="../assets/js/modernizr.min.js"></script>
|
||||
@@ -214,12 +713,14 @@
|
||||
<script src="../assets/js/waves.js"></script>
|
||||
<script src="../assets/js/jquery.nicescroll.js"></script>
|
||||
<script src="../assets/js/jquery.scrollTo.min.js"></script>
|
||||
<script src="../assets/js/common_helper.js"></script>
|
||||
|
||||
<script src="../assets/plugins/chart.js/chart.min.js"></script>
|
||||
<script src="../assets/pages/dashboard.js"></script>
|
||||
|
||||
<!-- App js -->
|
||||
<script src="../assets/js/app.js"></script>
|
||||
<script src="../assets/plugins/alertify/js/alertify.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user