synonim pages and new dump

This commit is contained in:
Claudio 2024-10-10 12:16:59 +02:00
parent c3ddf47a7e
commit 59243c754b
22 changed files with 2373 additions and 62534 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,20 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
if (isset($_POST['refid'], $_POST['name'])) {
$refid = $_POST['refid'];
$name = $_POST['name'];
$preferred = 'N';
$stmt = $conn->prepare("INSERT INTO compundsvocabulary (namecompoundsvocabulary, refid, preferred) VALUES (?, ?, ?)");
$stmt->bind_param('sis', $name, $refid, $preferred);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -0,0 +1,20 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
if (isset($_POST['refid'], $_POST['name'])) {
$refid = $_POST['refid'];
$name = $_POST['name'];
$preferred = 'N';
$stmt = $conn->prepare("INSERT INTO analysisvocabulary (nameanalysisvoc, refid, preferred) VALUES (?, ?, ?)");
$stmt->bind_param('sis', $name, $refid, $preferred);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -0,0 +1,421 @@
<?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">
<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="../assets/js/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.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;
}
.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;
}
</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>
<br><br>
<div class="table-responsive">
<table id="analysisTable" class="table table-striped table-custom">
<thead>
<tr>
<th>ID</th>
<th>Analysis Name</th>
<th>Kind</th>
<th>Code</th>
<th>Actions</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<input id="f_csv" type="file" name="f_csv" style="display: none" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/csv">
</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() {
var table = $('#analysisTable').DataTable({
processing: true,
serverSide: true,
ajax: {
url: 'get_analysis_data.php',
type: 'POST'
},
columns: [{
data: 'idanalysisvocabulary'
},
{
data: 'nameanalysisvoc',
render: function(data, type, row) {
return '<span class="editable-field" data-id="' + row.idanalysisvocabulary + '" data-field="nameanalysisvoc">' + data + '</span>';
}
},
{
data: 'kindanalysisvoc',
render: function(data, type, row) {
return '<span class="editable-field" data-id="' + row.idanalysisvocabulary + '" data-field="kindanalysisvoc">' + data + '</span>';
}
},
{
data: 'analysiscode',
render: function(data, type, row) {
return '<span class="editable-field" data-id="' + row.idanalysisvocabulary + '" data-field="analysiscode">' + data + '</span>';
}
},
{
data: null,
className: 'dt-center',
render: function(data, type, row) {
return '<button class="btn btn-sm btn-primary show-synonyms" data-id="' + row.idanalysisvocabulary + '">Show Synonyms</button>';
}
}
]
});
// Double-click to transform field into input or select
$('#analysisTable').on('dblclick', '.editable-field', function() {
var span = $(this);
var currentValue = span.text();
var field = span.data('field');
var id = span.data('id');
if (field === 'kindanalysisvoc') {
var select = '<select class="form-control edit-field" data-id="' + id + '" data-field="' + field + '">' +
'<option value="CH"' + (currentValue === 'CH' ? ' selected' : '') + '>CH</option>' +
'<option value="MB"' + (currentValue === 'MB' ? ' selected' : '') + '>MB</option>' +
'<option value="PM"' + (currentValue === 'PM' ? ' selected' : '') + '>PM</option>' +
'</select>';
span.replaceWith(select);
} else {
var input = '<input type="text" class="form-control edit-field" value="' + currentValue + '" data-id="' + id + '" data-field="' + field + '">';
span.replaceWith(input);
}
});
// Handle update on blur
$('#analysisTable').on('blur', '.edit-field', function() {
var input = $(this);
var id = input.data('id');
var field = input.data('field');
var value = input.val();
$.ajax({
url: 'update_analysis.php',
type: 'POST',
data: {
id: id,
field: field,
value: value
},
success: function(response) {
var jsonResponse = JSON.parse(response);
if (jsonResponse.success) {
var newText = $('<span class="editable-field" data-id="' + id + '" data-field="' + field + '">' + value + '</span>');
input.replaceWith(newText);
Swal.fire('Success', 'The analysis has been updated successfully!', 'success');
} else {
Swal.fire('Error', jsonResponse.error || 'There was a problem updating the analysis.', 'error');
}
},
error: function() {
Swal.fire('Error', 'Server communication error.', 'error');
}
});
});
// Show synonyms and allow editing of synonyms
$('#analysisTable').on('click', '.show-synonyms', function() {
var tr = $(this).closest('tr');
var row = table.row(tr);
var analysisId = $(this).data('id');
if (row.child.isShown()) {
row.child.hide();
tr.removeClass('shown');
} else {
$.ajax({
url: 'get_synonymsvoc.php',
type: 'POST',
data: {
id: analysisId
},
success: function(response) {
var synonyms = JSON.parse(response);
var childTable = '<table class="table table-custom"><tr><th>ID</th><th>Synonym</th><th>Actions</th></tr>';
$.each(synonyms, function(index, synonym) {
childTable += '<tr><td>' + synonym.idanalysisvocabulary + '</td>' +
'<td><span class="editable-synonym-field" data-id="' + synonym.idanalysisvocabulary + '" data-field="nameanalysisvoc">' + synonym.nameanalysisvoc + '</span></td>' +
'<td><button class="btn btn-danger delete-synonym" data-id="' + synonym.idanalysisvocabulary + '">Delete</button></td></tr>';
});
// Add row for adding a new synonym
childTable += '<tr><td>New</td>' +
'<td><input type="text" class="form-control new-synonym-input" placeholder="Enter synonym" data-id="' + analysisId + '"></td>' +
'<td><button class="btn btn-success add-synonym" data-id="' + analysisId + '">Add</button></td></tr>';
childTable += '</table>';
row.child(childTable).show();
tr.addClass('shown');
}
});
}
});
// Handle delete synonym
$('#analysisTable').on('click', '.delete-synonym', function() {
var id = $(this).data('id');
Swal.fire({
title: 'Are you sure?',
text: 'This will delete the synonym.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'Close Window'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: 'delete_synonymvoc.php',
type: 'POST',
data: {
id: id
},
success: function(response) {
var jsonResponse = JSON.parse(response);
if (jsonResponse.success) {
Swal.fire('Deleted!', 'The synonym has been deleted.', 'success');
table.ajax.reload(); // Reload DataTables
} else {
Swal.fire('Error', jsonResponse.error || 'There was a problem deleting the synonym.', 'error');
}
},
error: function() {
Swal.fire('Error', 'Server communication error.', 'error');
}
});
}
});
});
// Handle add new synonym
$('#analysisTable').on('click', '.add-synonym', function() {
var analysisId = $(this).data('id');
var newSynonym = $(this).closest('tr').find('.new-synonym-input').val();
if (newSynonym) {
$.ajax({
url: 'add_synonymvoc.php',
type: 'POST',
data: {
refid: analysisId,
name: newSynonym
},
success: function(response) {
var jsonResponse = JSON.parse(response);
if (jsonResponse.success) {
Swal.fire('Success', 'New synonym has been added successfully!', 'success');
table.ajax.reload(); // Reload DataTables to show the new synonym
} else {
Swal.fire('Error', jsonResponse.error || 'There was a problem adding the synonym.', 'error');
}
},
error: function() {
Swal.fire('Error', 'Server communication error.', 'error');
}
});
} else {
Swal.fire('Error', 'Please enter a synonym.', 'error');
}
});
});
</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>

View File

@ -0,0 +1,404 @@
<?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">
<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="../assets/js/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.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;
}
.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;
}
</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-xl-12">
<div class="card">
<div class="card-body">
<h5 class="header-title pb-3 mt-0">Compounds Management</h5>
<div class="table-responsive">
<table id="compoundsTable" class="table table-striped table-custom">
<thead>
<tr>
<th>ID</th>
<th>Compound Name</th>
<th>CAS</th>
<th>Actions</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</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>
<br><br>
<div class="table-responsive">
</div><!--end table-responsive-->
<input id="f_csv" type="file" name="f_csv" style="display: none" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel, text/csv">
</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() {
var compoundsTable = $('#compoundsTable').DataTable({
processing: true,
serverSide: true,
pageLength: 100,
ajax: {
url: 'get_compounds_data.php',
type: 'POST'
},
columns: [{
data: 'idcompoundsvocabulary'
},
{
data: 'namecompoundsvocabulary',
render: function(data, type, row) {
return '<span class="editable-compound-field" data-id="' + row.idcompoundsvocabulary + '" data-field="namecompoundsvocabulary">' + data + '</span>';
}
},
{
data: 'cascompoundvocabulary',
render: function(data, type, row) {
return '<span class="editable-compound-field" data-id="' + row.idcompoundsvocabulary + '" data-field="cascompoundvocabulary">' + data + '</span>';
}
},
{
data: null,
className: 'dt-center',
render: function(data, type, row) {
return '<button class="btn btn-sm btn-primary show-compound-synonyms" data-id="' + row.idcompoundsvocabulary + '">Show Synonyms</button>';
}
}
]
});
// Double-click to transform field into input
$('#compoundsTable').on('dblclick', '.editable-compound-field', function() {
var span = $(this);
var currentValue = span.text();
var field = span.data('field');
var id = span.data('id');
var input = '<input type="text" class="form-control edit-compound-field" value="' + currentValue + '" data-id="' + id + '" data-field="' + field + '">';
span.replaceWith(input);
});
// Handle update on blur
$('#compoundsTable').on('blur', '.edit-compound-field', function() {
var input = $(this);
var id = input.data('id');
var field = input.data('field');
var value = input.val();
$.ajax({
url: 'update_compounds.php',
type: 'POST',
data: {
id: id,
field: field,
value: value
},
success: function(response) {
var jsonResponse = JSON.parse(response);
if (jsonResponse.success) {
var newText = $('<span class="editable-compound-field" data-id="' + id + '" data-field="' + field + '">' + value + '</span>');
input.replaceWith(newText);
Swal.fire('Success', 'The compound has been updated successfully!', 'success');
} else {
Swal.fire('Error', jsonResponse.error || 'There was a problem updating the compound.', 'error');
}
},
error: function() {
Swal.fire('Error', 'Server communication error.', 'error');
}
});
});
// Show compound synonyms and allow editing or adding new ones
$('#compoundsTable').on('click', '.show-compound-synonyms', function() {
var tr = $(this).closest('tr');
var row = compoundsTable.row(tr);
var compoundId = $(this).data('id');
if (row.child.isShown()) {
row.child.hide();
tr.removeClass('shown');
} else {
$.ajax({
url: 'get_compound_synonyms.php',
type: 'POST',
data: {
id: compoundId
},
success: function(response) {
var synonyms = JSON.parse(response);
var childTable = '<table class="table table-custom"><tr><th>ID</th><th>Synonym</th><th>Actions</th></tr>';
$.each(synonyms, function(index, synonym) {
childTable += '<tr><td>' + synonym.idcompoundsvocabulary + '</td>' +
'<td><span class="editable-compound-synonym-field" data-id="' + synonym.idcompoundsvocabulary + '" data-field="namecompoundsvocabulary">' + synonym.namecompoundsvocabulary + '</span></td>' +
'<td><button class="btn btn-danger delete-compound-synonym" data-id="' + synonym.idcompoundsvocabulary + '">Delete</button></td></tr>';
});
// Add row for adding a new synonym
childTable += '<tr><td>New</td>' +
'<td><input type="text" class="form-control new-compound-synonym-input" placeholder="Enter synonym" data-id="' + compoundId + '"></td>' +
'<td><button class="btn btn-success add-compound-synonym" data-id="' + compoundId + '">Add</button></td></tr>';
childTable += '</table>';
row.child(childTable).show();
tr.addClass('shown');
}
});
}
});
// Handle delete synonym
$('#compoundsTable').on('click', '.delete-compound-synonym', function() {
var id = $(this).data('id');
Swal.fire({
title: 'Are you sure?',
text: 'This will delete the compound synonym.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, delete it!',
cancelButtonText: 'Close window'
}).then((result) => {
if (result.isConfirmed) {
$.ajax({
url: 'delete_compound_synonym.php',
type: 'POST',
data: {
id: id
},
success: function(response) {
var jsonResponse = JSON.parse(response);
if (jsonResponse.success) {
Swal.fire('Deleted!', 'The compound synonym has been deleted.', 'success');
compoundsTable.ajax.reload();
} else {
Swal.fire('Error', jsonResponse.error || 'There was a problem deleting the compound synonym.', 'error');
}
},
error: function() {
Swal.fire('Error', 'Server communication error.', 'error');
}
});
}
});
});
// Handle add new synonym
$('#compoundsTable').on('click', '.add-compound-synonym', function() {
var compoundId = $(this).data('id');
var newSynonym = $(this).closest('tr').find('.new-compound-synonym-input').val();
if (newSynonym) {
$.ajax({
url: 'add_compound_synonym.php',
type: 'POST',
data: {
refid: compoundId,
name: newSynonym
},
success: function(response) {
var jsonResponse = JSON.parse(response);
if (jsonResponse.success) {
Swal.fire('Success', 'New synonym has been added successfully!', 'success');
compoundsTable.ajax.reload();
} else {
Swal.fire('Error', jsonResponse.error || 'There was a problem adding the synonym.', 'error');
}
},
error: function() {
Swal.fire('Error', 'Server communication error.', 'error');
}
});
} else {
Swal.fire('Error', 'Please enter a synonym.', 'error');
}
});
});
</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>

View File

@ -0,0 +1,17 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
if (isset($_POST['id'])) {
$id = $_POST['id'];
$stmt = $conn->prepare("DELETE FROM compundsvocabulary WHERE idcompoundsvocabulary = ?");
$stmt->bind_param('i', $id);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -0,0 +1,17 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
if (isset($_POST['id'])) {
$id = $_POST['id'];
$stmt = $conn->prepare("DELETE FROM analysisvocabulary WHERE idanalysisvocabulary = ?");
$stmt->bind_param('i', $id);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -0,0 +1,20 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
$columns = ['idanalysisvocabulary', 'nameanalysisvoc', 'kindanalysisvoc', 'analysiscode'];
$sql = "SELECT * FROM analysisvocabulary WHERE preferred = 'Y'";
$result = $conn->query($sql);
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = [
'idanalysisvocabulary' => $row['idanalysisvocabulary'],
'nameanalysisvoc' => $row['nameanalysisvoc'],
'kindanalysisvoc' => $row['kindanalysisvoc'],
'analysiscode' => $row['analysiscode']
];
}
echo json_encode(['data' => $data]);

View File

@ -0,0 +1,22 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
if (isset($_POST['id'])) {
$refid = $_POST['id'];
// Recupera i sinonimi per il composto specifico
$stmt = $conn->prepare("SELECT * FROM compundsvocabulary WHERE refid = ? AND preferred = 'N'");
$stmt->bind_param('i', $refid);
$stmt->execute();
$result = $stmt->get_result();
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row;
}
echo json_encode($data);
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -0,0 +1,45 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
// Ottieni i parametri per la paginazione da DataTables
$start = $_POST['start'];
$length = $_POST['length'];
$search = $_POST['search']['value'];
// Costruisci la query base
$query = "SELECT * FROM compundsvocabulary WHERE preferred = 'Y'";
// Aggiungi la logica di ricerca se necessario
if (!empty($search)) {
$query .= " AND (namecompoundsvocabulary LIKE ? OR cascompoundvocabulary LIKE ?)";
$searchParam = '%' . $search . '%';
$stmt = $conn->prepare($query . " LIMIT ?, ?");
$stmt->bind_param('ssii', $searchParam, $searchParam, $start, $length);
} else {
$stmt = $conn->prepare($query . " LIMIT ?, ?");
$stmt->bind_param('ii', $start, $length);
}
$stmt->execute();
$result = $stmt->get_result();
// Recupera i dati e formattali per DataTables
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row;
}
// Ottieni il numero totale di record per il paginatore di DataTables
$totalQuery = "SELECT COUNT(*) as total FROM compundsvocabulary WHERE preferred = 'Y'";
$totalResult = $conn->query($totalQuery);
$totalData = $totalResult->fetch_assoc();
$response = [
"draw" => intval($_POST['draw']),
"recordsTotal" => intval($totalData['total']),
"recordsFiltered" => intval($totalData['total']),
"data" => $data
];
echo json_encode($response);

View File

@ -0,0 +1,20 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
$id = $_POST['id'];
$sql = "SELECT * FROM analysisvocabulary WHERE preferred = 'N' AND refid = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
$synonyms = [];
while ($row = $result->fetch_assoc()) {
$synonyms[] = [
'idanalysisvocabulary' => $row['idanalysisvocabulary'],
'nameanalysisvoc' => $row['nameanalysisvoc']
];
}
echo json_encode($synonyms);

View File

@ -0,0 +1,21 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
if (isset($_POST['id'], $_POST['field'], $_POST['value'])) {
$id = $_POST['id'];
$field = $_POST['field'];
$value = $_POST['value'];
// Assicurati di proteggere da SQL injection usando prepared statements
$stmt = $conn->prepare("UPDATE analysisvocabulary SET $field = ? WHERE idanalysisvocabulary = ?");
$stmt->bind_param('si', $value, $id);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -0,0 +1,21 @@
<?php
include('../include/headscript.php');
include("../class/company.php");
$conn = new mysqli($servername, $username, $password, $database);
if (isset($_POST['id'], $_POST['field'], $_POST['value'])) {
$id = $_POST['id'];
$field = $_POST['field'];
$value = $_POST['value'];
// Proteggi da SQL injection utilizzando prepared statements
$stmt = $conn->prepare("UPDATE compundsvocabulary SET $field = ? WHERE idcompoundsvocabulary = ?");
$stmt->bind_param('si', $value, $id);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
} else {
echo json_encode(['success' => false, 'error' => 'Invalid input']);
}

View File

@ -81,6 +81,8 @@
<li><a href="<?php echo USERAREA_PATH; ?>importify/importifydashboard.php">Importify Dashboard</a></li>
<li><a href="<?php echo USERAREA_PATH; ?>importify/insert-importifytemplate.php">New Import Templates</a></li>
<li><a href="<?php echo USERAREA_PATH; ?>importify/history_importify.php">Import History</a></li>
<li><a href="<?php echo USERAREA_PATH; ?>importify/analysis-vocabulary.php">Analysis Synonims</a></li>
<li><a href="<?php echo USERAREA_PATH; ?>importify/compounds-vocabulary.php">Compounds Synonims</a></li>
</ul>
</li>
<?php } ?>

View File

@ -216,7 +216,7 @@ while ($row = mysqli_fetch_array($resultworstsupplier)) {
$testnameworstsupplier[] = $row['namesupplier'];
}
echo "ciaopappa";
?>
<?php
// fecth region area
@ -245,4 +245,41 @@ while ($row = mysqli_fetch_array($resultworstregion)) {
}
?>
?>
<?php
// fecth analytes with most fails
$failedAnalytesQuery = "
SELECT c.namecompoundsvocabulary AS AnalyteName, COUNT(*) AS FailCount
FROM result_project rp
LEFT JOIN compundsvocabulary c ON rp.result_AnalytsName = c.idcompoundsvocabulary
WHERE LOWER(rp.result_AnalytsRating) IN ('f', 'fail', 'doesn\'t comply')
GROUP BY c.namecompoundsvocabulary
ORDER BY FailCount DESC
LIMIT 10;
";
$resultFailedAnalytes = mysqli_query($repnew, $failedAnalytesQuery) or die("Error in Selecting " . mysqli_error($repnew));
// Verifica se ci sono risultati
if (mysqli_num_rows($resultFailedAnalytes) > 0) {
echo "La query ha restituito dei risultati.";
} else {
echo "La query non ha restituito risultati.";
}
$failedAnalytes = array();
while ($row = mysqli_fetch_assoc($resultFailedAnalytes)) {
echo "Analita: " . $row['AnalyteName'] . ", Fail Count: " . $row['FailCount'] . "<br>";
$failedAnalytes[] = [
'AnalyteName' => $row['AnalyteName'],
'FailCount' => $row['FailCount']
];
}
// Salva i dati per essere utilizzati nel JSON di risposta
$data['failedAnalytes'] = $failedAnalytes;
echo "<pre>";
print_r($data['failedAnalytes']);
echo "</pre>";
?>

View File

@ -374,12 +374,25 @@ $result = $conn->query($query);
html += '<tbody>';
$.each(reports, function(index, report) {
// Definisci la classe di stile per il rating del report
var ratingClass = '';
var ratingValue = report.reportsRating.toLowerCase(); // Converte il valore in minuscolo
if (ratingValue === 'fail') {
ratingClass = 'bg-danger text-white';
} else if (ratingValue === 'pass') {
ratingClass = 'bg-success text-white';
} else if (ratingValue === '//' || ratingValue === 'n/a') {
ratingClass = 'bg-warning text-dark';
}
html += '<tr>';
html += '<td>' + report.reportsNumberLab + '</td>';
html += '<td>' + report.reportDateIn + '</td>';
html += '<td>' + report.reportsRating + '</td>';
html += '<td class="' + ratingClass + '">' + report.reportsRating + '</td>'; // Applica la classe alla cella
html += '<td colspan="2"></td>'; // Righe vuote per mantenere l'allineamento
html += '<td><button class="btn btn-primary btn-sm report-details" data-reportid="' + report.idreports + '">Details</button></td>';
html += '</tr>';
// Se ci sono analisi associate, aggiungi le righe per ciascuna analisi
if (report.analysis.length > 0) {
@ -405,9 +418,9 @@ $result = $conn->query($query);
} else {
html += '<tr><td colspan="5">No analysis available for this report.</td></tr>';
}
html += '</tr>';
});
html += '</tbody></table>';
return html;
}

View File

@ -0,0 +1,61 @@
<?php
include('../include/headscript.php');
if (isset($_POST['user']) && isset($_POST['table'])) {
$userId = $_POST['user'];
$page = 'reports';
$conn = new mysqli($servername, $username, $password, $database);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Query per cercare le impostazioni salvate
$query = "SELECT * FROM user_table_settings WHERE iduser = ? AND page = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("is", $userId, $page);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
// Se esistono, restituisci le impostazioni esistenti
$row = $result->fetch_assoc();
$settings = [
'columns' => json_decode($row['column_visibility'], true),
'ColReorder' => json_decode($row['column_order'], true),
'time' => time()
];
echo json_encode($settings);
} else {
// Se non esistono, inserisci un record di default
$defaultColumnVisibility = json_encode([true, true, true, true, true, true]); // Adatta le colonne al numero di colonne della tua tabella
$defaultColumnOrder = json_encode([0, 1, 2, 3, 4, 5]); // Ordine predefinito delle colonne
$insertQuery = "INSERT INTO user_table_settings (iduser, page, column_visibility, column_order, created_at, updated_at) VALUES (?, ?, ?, ?, NOW(), NOW())";
$insertStmt = $conn->prepare($insertQuery);
$insertStmt->bind_param("isss", $userId, $page, $defaultColumnVisibility, $defaultColumnOrder);
if ($insertStmt->execute()) {
// Restituisci le impostazioni predefinite appena create
$settings = [
'columns' => json_decode($defaultColumnVisibility, true),
'ColReorder' => json_decode($defaultColumnOrder, true),
'time' => time()
];
echo json_encode($settings);
} else {
// Gestisci eventuali errori nell'inserimento
echo json_encode(['error' => 'Failed to insert default settings']);
}
$insertStmt->close();
}
$stmt->close();
$conn->close();
} else {
echo json_encode(['error' => 'Invalid request']);
}

View File

@ -3,6 +3,18 @@
$conn = new mysqli($servername, $username, $password, $database);
$page = 'reports'; // Nome della pagina specifica per salvare/ripristinare le impostazioni
$conn = new mysqli($servername, $username, $password, $database);
// Recupera le impostazioni delle colonne e dell'ordinamento dal database
$query = "SELECT column_visibility, column_order FROM user_table_settings WHERE iduser = ? AND page = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("is", $iduserlogin, $page);
$stmt->execute();
$stmt->bind_result($column_visibility, $column_order);
$stmt->fetch();
$stmt->close();
// Query per ottenere tutti i report e i prodotti associati
$query = "
SELECT r.*, p.products_refnumber, p.products_description
@ -20,14 +32,26 @@ $result = $conn->query($query);
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimal-ui">
<title>Reports</title>
<!-- Includi prima jQuery -->
<!-- Includi prima jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- Includi DataTables CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
<!-- DataTables CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.min.css">
<!-- DataTables Buttons CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.3.1/css/buttons.dataTables.min.css">
<!-- ColReorder CSS -->
<link rel="stylesheet" href="https://cdn.datatables.net/colreorder/1.5.6/css/colReorder.dataTables.min.css">
<!-- DataTables JS -->
<script src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.min.js"></script>
<!-- DataTables Buttons JS -->
<script src="https://cdn.datatables.net/buttons/2.3.1/js/dataTables.buttons.min.js"></script>
<!-- Buttons ColVis JS -->
<script src="https://cdn.datatables.net/buttons/2.3.1/js/buttons.colVis.min.js"></script>
<!-- ColReorder JS -->
<script src="https://cdn.datatables.net/colreorder/1.5.6/js/dataTables.colReorder.min.js"></script>
<!-- Includi DataTables JS -->
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
<!-- Altri riferimenti al CSS e JS -->
<link href="../assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
@ -87,7 +111,7 @@ $result = $conn->query($query);
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table id="reportsTable" class="table table-striped table-hover">
<table id="reportsTable" class="table table-striped table-hover" data-user="<?php echo $iduserlogin; ?>" data-table="reports">
<thead>
<tr>
<th>Report Number</th>
@ -115,6 +139,7 @@ $result = $conn->query($query);
</tbody>
</table>
</div>
</div>
</div>
</div>
@ -129,56 +154,133 @@ $result = $conn->query($query);
<script>
$(document).ready(function() {
// Inizializza DataTables con filtri per le colonne
var table = $('#reportsTable').DataTable({
responsive: true,
"pageLength": 50,
"order": [
[0, 'asc']
], // Ordina per numero di report
initComplete: function() {
// Aggiungi i filtri per ogni colonna
this.api().columns().every(function() {
var column = this;
var input = $('<input class="form-control form-control-sm" type="text" placeholder="Search"/>')
.appendTo($(column.header()))
.on('keyup change clear', function() {
if (column.search() !== this.value) {
column.search(this.value).draw();
}
});
});
var hasUserInteracted = false;
// Recupera le impostazioni salvate dal server prima di inizializzare DataTables
var columnSettings = {};
var userId = $('#reportsTable').data('user');
var tableName = $('#reportsTable').data('table');
// Recupera le impostazioni salvate
$.ajax({
url: 'get_user_table_settings_reports.php',
method: 'POST',
data: {
user: userId,
table: tableName
},
async: false,
success: function(response) {
columnSettings = JSON.parse(response);
console.log("Impostazioni recuperate:", columnSettings);
},
error: function(xhr, status, error) {
console.error('Errore nel caricamento delle impostazioni:', xhr.responseText);
}
});
// Gestione del click su "Analysis" per visualizzare la tabella delle analisi
// Inizializza DataTables con ColReorder, filtri e ColVis
var table = $('#reportsTable').DataTable({
responsive: true,
pageLength: 50,
order: [
[0, 'asc']
],
colReorder: {
order: columnSettings && columnSettings.ColReorder ? columnSettings.ColReorder : null
},
dom: 'Bfrtip', // Integra i bottoni
buttons: [{
extend: 'colvis',
text: 'Select Columns',
collectionLayout: 'fixed four-column',
postfixButtons: ['colvisRestore'],
columns: ':not(:last-child)' // Escludi l'ultima colonna (Actions)
}],
initComplete: function() {
// Applica le impostazioni di visibilità delle colonne, se presenti
if (columnSettings && columnSettings.columns) {
console.log("Applico visibilità colonne:", columnSettings.columns);
this.api().columns().every(function(index) {
var column = this;
column.visible(columnSettings.columns[index].visible, false);
});
}
this.api().columns.adjust().draw(false);
// Aggiungi i filtri per ogni colonna (eccetto la colonna delle azioni)
this.api().columns().every(function() {
var column = this;
if (column.index() !== 5) { // Escludi la colonna "Action"
$('<input class="form-control form-control-sm" type="text" placeholder="Search"/>')
.appendTo($(column.header()))
.on('keyup change clear', function() {
if (column.search() !== this.value) {
column.search(this.value).draw();
}
});
}
});
},
stateSave: true,
stateSaveCallback: function(settings, data) {
if (hasUserInteracted) {
$.ajax({
url: 'save_user_table_settings_reports.php',
method: 'POST',
data: {
user: userId,
table: tableName,
settings: JSON.stringify(data)
},
success: function(response) {
console.log('Impostazioni salvate:', response);
},
error: function(xhr, status, error) {
console.error('Errore nel salvataggio delle impostazioni:', xhr.responseText);
}
});
}
}
});
// Imposta il flag `hasUserInteracted` quando l'utente modifica qualcosa (colonne o riordina)
table.on('column-reorder', function() {
hasUserInteracted = true;
console.log("Colonne riordinate");
});
table.on('column-visibility', function() {
hasUserInteracted = true;
console.log("Visibilità colonna cambiata");
});
// Gestione del click su "Analysis" per visualizzare la tabella child con le analisi
$('#reportsTable').on('click', '.show-analysis', function() {
var tr = $(this).closest('tr');
var reportId = tr.data('reportid');
var row = $('#reportsTable').DataTable().row(tr);
var button = $(this);
console.log('Loading analysis for reportId:', reportId); // Debug
button.prop('disabled', true);
button.html('<i class="fa fa-spinner fa-spin"></i> Loading...');
// Se la riga child è già visibile, non facciamo nulla
if (row.child.isShown()) {
button.prop('disabled', false);
row.child.hide();
tr.removeClass('shown');
button.html('Analysis');
button.prop('disabled', false);
return;
}
// Carica le analisi tramite AJAX
$.ajax({
url: 'get_analysis_by_report.php', // Nuovo script PHP per ottenere le analisi del report
url: 'get_analysis_by_report.php',
type: 'POST',
data: {
reportId: reportId
},
success: function(data) {
console.log('Analysis data loaded:', data); // Debug
row.child(formatAnalysis(data)).show();
tr.addClass('shown');
},
@ -194,22 +296,20 @@ $result = $conn->query($query);
});
});
// Funzione per formattare le analisi
function formatAnalysis(data) {
var parsedData = JSON.parse(data);
var html = '<table class="table table-bordered child-table">';
html += '<thead><tr><th>Analysis Name</th><th>Final Rating</th></tr></thead>';
html += '<tbody>';
// Per ogni analisi, aggiungi la riga corrispondente
$.each(parsedData, function(index, analysis) {
var ratingClass = ''; // Classe CSS per la colorazione della cella
var ratingClass = '';
if (analysis.finalRating === 'FAIL') {
ratingClass = 'bg-danger text-white'; // Colore rosso per i fallimenti
ratingClass = 'bg-danger text-white';
} else if (analysis.finalRating === 'PASS') {
ratingClass = 'bg-success text-white'; // Colore verde per i successi
ratingClass = 'bg-success text-white';
} else if (analysis.finalRating === '//' || analysis.finalRating === 'N/A') {
ratingClass = 'bg-warning text-dark'; // Colore giallo per risultati ambigui
ratingClass = 'bg-warning text-dark';
}
html += '<tr>';
@ -221,10 +321,12 @@ $result = $conn->query($query);
html += '</tbody></table>';
return html;
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,53 @@
<?php
// Connessione al database
include('../include/headscript.php');
$tableName = 'reports'; // Nome tabella per reports.php
// Verifica che i parametri necessari siano stati inviati
if (isset($_POST['user']) && isset($_POST['table']) && isset($_POST['settings'])) {
$userId = $_POST['user'];
$page = $tableName;
$settings = json_decode($_POST['settings'], true);
$columnVisibility = json_encode(array_column($settings['columns'], 'visible'));
$columnOrder = json_encode($settings['ColReorder']);
$conn = new mysqli($servername, $username, $password, $database);
// Verifica della connessione
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Query per verificare se il record esiste già
$query = "SELECT * FROM user_table_settings WHERE iduser = ? AND page = ?";
$stmt = $conn->prepare($query);
$stmt->bind_param("is", $userId, $page);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
// Aggiorna le impostazioni esistenti
$updateQuery = "UPDATE user_table_settings SET column_visibility = ?, column_order = ?, updated_at = NOW() WHERE iduser = ? AND page = ?";
$updateStmt = $conn->prepare($updateQuery);
$updateStmt->bind_param("ssis", $columnVisibility, $columnOrder, $userId, $page);
$updateStmt->execute();
$updateStmt->close();
echo json_encode(['status' => 'Settings updated']);
} else {
// Inserisci nuove impostazioni
$insertQuery = "INSERT INTO user_table_settings (iduser, page, column_visibility, column_order, created_at, updated_at) VALUES (?, ?, ?, ?, NOW(), NOW())";
$insertStmt = $conn->prepare($insertQuery);
$insertStmt->bind_param("isss", $userId, $page, $columnVisibility, $columnOrder);
$insertStmt->execute();
$insertStmt->close();
echo json_encode(['status' => 'Settings saved']);
}
$stmt->close();
$conn->close();
} else {
// Se i parametri non sono validi, restituisci errore
http_response_code(400);
echo json_encode(['error' => 'Invalid request']);
}

View File

@ -5,89 +5,89 @@ $conn = new mysqli($servername, $username, $password, $database);
// ini_set('display_errors', 1);
// Ottieni i filtri dal POST
$startDate = isset($_POST['startDate']) ? $_POST['startDate'] : '';
$endDate = isset($_POST['endDate']) ? $_POST['endDate'] : '';
$endDate = isset($_POST['endDate']) ? $_POST['endDate'] : '';
// suppliers can be multiple
if(isset($_POST['supplier']) && !empty($_POST['supplier'])){
if (isset($_POST['supplier']) && !empty($_POST['supplier'])) {
$suppliers = implode(',', $_POST['supplier']);
$supplierArr = explode(',', $suppliers);
$supplierFilter = '';
foreach($supplierArr as $supplier){
$supplierFilter .= "'".$supplier."',";
foreach ($supplierArr as $supplier) {
$supplierFilter .= "'" . $supplier . "',";
}
$supplierFilter = substr($supplierFilter,0,-1);
} else{
$supplierFilter = substr($supplierFilter, 0, -1);
} else {
$supplierFilter = "";
}
if(isset($_POST["productsRefnumber"]) && !empty($_POST["productsRefnumber"])){
if (isset($_POST["productsRefnumber"]) && !empty($_POST["productsRefnumber"])) {
$refNumbers = implode(',', $_POST['productsRefnumber']);
$refNumbersArr = explode(',', $refNumbers);
$refNumberFilter = '';
foreach($refNumbersArr as $refNumber){
$refNumberFilter .= "'".$refNumber."',";
foreach ($refNumbersArr as $refNumber) {
$refNumberFilter .= "'" . $refNumber . "',";
}
$refNumberFilter = substr($refNumberFilter,0,-1);
}else{
$refNumberFilter = substr($refNumberFilter, 0, -1);
} else {
$refNumberFilter = "";
}
if(isset($_POST["productsSeason"]) && !empty($_POST["productsSeason"])){
if (isset($_POST["productsSeason"]) && !empty($_POST["productsSeason"])) {
$productsSeasons = implode(',', $_POST['productsSeason']);
$productsSeasonsArr = explode(',', $productsSeasons);
$productsSeasonFilter = '';
foreach($productsSeasonsArr as $productsSeason){
$productsSeasonFilter .= "'".$productsSeason."',";
foreach ($productsSeasonsArr as $productsSeason) {
$productsSeasonFilter .= "'" . $productsSeason . "',";
}
$productsSeasonFilter = substr($productsSeasonFilter,0,-1);
}else{
$productsSeasonFilter = substr($productsSeasonFilter, 0, -1);
} else {
$productsSeasonFilter = "";
}
if(isset($_POST["ageRange"]) && !empty($_POST["ageRange"])){
if (isset($_POST["ageRange"]) && !empty($_POST["ageRange"])) {
$ageRanges = implode(',', $_POST['ageRange']);
$ageRangesArr = explode(',', $ageRanges);
$ageRangeFilter = '';
foreach($ageRangesArr as $ageRange){
$ageRangeFilter .= "'".$ageRange."',";
foreach ($ageRangesArr as $ageRange) {
$ageRangeFilter .= "'" . $ageRange . "',";
}
$ageRangeFilter = substr($ageRangeFilter,0,-1);
}else{
$ageRangeFilter = substr($ageRangeFilter, 0, -1);
} else {
$ageRangeFilter = "";
}
if(isset($_POST["reportsLabName"]) && !empty($_POST["reportsLabName"])){
if (isset($_POST["reportsLabName"]) && !empty($_POST["reportsLabName"])) {
$labNames = implode(',', $_POST['reportsLabName']);
$labNamesArr = explode(',', $labNames);
$labNameFilter = '';
foreach($labNamesArr as $labName){
$labNameFilter .= "'".$labName."',";
foreach ($labNamesArr as $labName) {
$labNameFilter .= "'" . $labName . "',";
}
$labNameFilter = substr($labNameFilter,0,-1);
}else{
$labNameFilter = substr($labNameFilter, 0, -1);
} else {
$labNameFilter = "";
}
if(isset($_POST["reportsTestType"]) && !empty($_POST["reportsTestType"])){
if (isset($_POST["reportsTestType"]) && !empty($_POST["reportsTestType"])) {
$tesTypes = implode(',', $_POST['reportsTestType']);
$tesTypesArr = explode(',', $tesTypes);
$tesTypeFilter = '';
foreach($tesTypesArr as $tesType){
$tesTypeFilter .= "'".$tesType."',";
foreach ($tesTypesArr as $tesType) {
$tesTypeFilter .= "'" . $tesType . "',";
}
$tesTypeFilter = substr($tesTypeFilter,0,-1);
}else{
$tesTypeFilter = substr($tesTypeFilter, 0, -1);
} else {
$tesTypeFilter = "";
}
if(isset($_POST["reportsNumberLab"]) && !empty($_POST["reportsNumberLab"])){
if (isset($_POST["reportsNumberLab"]) && !empty($_POST["reportsNumberLab"])) {
$numberLabs = implode(',', $_POST['reportsNumberLab']);
$numberLabsArr = explode(',', $numberLabs);
$numberLabFilter = '';
foreach($numberLabsArr as $numberLab){
$numberLabFilter .= "'".$numberLab."',";
foreach ($numberLabsArr as $numberLab) {
$numberLabFilter .= "'" . $numberLab . "',";
}
$numberLabFilter = substr($numberLabFilter,0,-1);
}else{
$numberLabFilter = substr($numberLabFilter, 0, -1);
} else {
$numberLabFilter = "";
}
@ -132,7 +132,7 @@ if (!empty($supplierFilter)) {
}
if (!empty($refNumberFilter)) {
$totalProductsQuery .= " AND p.products_refnumber IN ($refNumberFilter)";
}
}
if (!empty($productsSeasonFilter)) {
$totalProductsQuery .= " AND p.products_season IN ($productsSeasonFilter)";
}
@ -256,19 +256,19 @@ while ($row = $worstSuppliersResult->fetch_assoc()) {
];
}
$suPfilters='';
$suPfilters = '';
// Statistic for products by suppliers
if(!empty($supplierFilter)){
if (!empty($supplierFilter)) {
$suPfilters .= " AND p.namesupplier IN ($supplierFilter)";
}
if(!empty($refNumberFilter)){
if (!empty($refNumberFilter)) {
$suPfilters .= " AND p.products_refnumber IN ($refNumberFilter)";
}
if(!empty($productsSeasonFilter)){
if (!empty($productsSeasonFilter)) {
$suPfilters .= " AND p.products_season IN ($productsSeasonFilter)";
}
if(!empty($ageRangeFilter)){
if (!empty($ageRangeFilter)) {
$suPfilters .= " AND p.agerange IN ($ageRangeFilter)";
}
$productBySupplierQuery = "
@ -276,7 +276,7 @@ $productBySupplierQuery = "
FROM products p
WHERE p.namesupplier IS NOT NULL $suPfilters
GROUP BY p.namesupplier
ORDER BY totalProducts DESC";
ORDER BY totalProducts DESC";
$productBySupplierResult = $conn->query($productBySupplierQuery);
$productBySupplier = [];
@ -299,7 +299,7 @@ while ($row = $refNumbersResult->fetch_assoc()) {
$refNumbers[] = [
'refNumber' => $row['refNumber']
];
}
}
// productsSeason
$productsSeasonQuery = "
SELECT p.products_season AS season
@ -312,7 +312,7 @@ $productsSeasons = [];
while ($row = $productsSeasonResult->fetch_assoc()) {
$productsSeasons[] = [
"season" => $row['season']
];
];
}
// ageRanges
@ -328,7 +328,7 @@ $ageRange = [];
while ($row = $ageRangeResult->fetch_assoc()) {
$ageRange[] = [
"ageRange" => $row['ageRange']
];
];
}
// labNames
@ -343,7 +343,7 @@ $labName = [];
while ($row = $labNameResult->fetch_assoc()) {
$labName[] = [
"LabName" => $row['LabName']
];
];
}
// tesTypes
@ -358,7 +358,7 @@ $tesType = [];
while ($row = $tesTypeResult->fetch_assoc()) {
$tesType[] = [
"tesType" => $row['tesType']
];
];
}
// numberLabs
@ -373,8 +373,8 @@ $numberLabs = [];
while ($row = $numberLabsResult->fetch_assoc()) {
$numberLabs[] = [
"reportNumber" => $row['reportNumber']
];
}
];
}
// New Query: Distribution of analyses (for pie chart)
@ -398,6 +398,29 @@ while ($row = $analysisDistributionResult->fetch_assoc()) {
];
}
// fecth analytes with most fails
$failedAnalytesQuery = "
SELECT c.namecompoundsvocabulary AS AnalyteName, COUNT(*) AS FailCount
FROM result_project rp
LEFT JOIN compundsvocabulary c ON rp.result_AnalytsName = c.idcompoundsvocabulary
WHERE LOWER(rp.result_AnalytsRating) IN ('f', 'fail', 'doesn\'t comply')
GROUP BY c.namecompoundsvocabulary
ORDER BY FailCount DESC
LIMIT 10;
";
$resultFailedAnalytes = mysqli_query($repnew, $failedAnalytesQuery) or die("Error in Selecting " . mysqli_error($repnew));
// Verifica se ci sono risultati
$failedAnalytes = array();
while ($row = mysqli_fetch_assoc($resultFailedAnalytes)) {
$failedAnalytes[] = [
'AnalyteName' => $row['AnalyteName'],
'FailCount' => $row['FailCount']
];
}
// Ora controlliamo se è una richiesta AJAX
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Rispondi ai dati aggiornati tramite AJAX
@ -421,7 +444,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
'labName' => $labName,
'tesType' => $tesType,
'numberLabs' => $numberLabs,
'failedAnalytes' => $failedAnalytes,
'analysisDistribution' => $analysisDistribution // Distribuzione delle analisi per il grafico a torta
]);
exit; // Ferma l'esecuzione del resto dello script dopo aver risposto all'AJAX
}
?>

View File

@ -32,21 +32,21 @@ include('parsedatachart.php');
<style>
#activeFilters{
#activeFilters {
display: flex;
font-size: 16px;
flex-direction: row;
background: 0;
}
}
.badge{
.badge {
display: flex;
flex-direction: row;
align-items: center;
gap: 5px;
}
.width-100 {
width: 100%;
}
@ -201,7 +201,7 @@ include('parsedatachart.php');
}
.filters-applied {
display: inline-block;
display: inline-block;
color: white;
border-radius: 5px;
padding: 5px 10px;
@ -210,15 +210,15 @@ include('parsedatachart.php');
}
.chart-container {
width: 100%;
width: 100%;
margin: 20px;
}
.chart-box {
.chart-box {
display: flex;
justify-content: center;
align-items: center;
align-items: center;
}
</style>
</head>
@ -235,7 +235,6 @@ include('parsedatachart.php');
<!-- sidebar filter style -->
<style>
.filter-sidebar {
position: fixed;
top: 0;
@ -243,29 +242,33 @@ include('parsedatachart.php');
width: 300px;
height: 100%;
background: #f8f9fa;
box-shadow: -2px 0 5px rgba(0,0,0,0.1);
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
padding: 20px;
display: none;
z-index: 999;
}
.active-filters {
margin-bottom: 20px;
}
body {
transition: margin-right 0.3s; /* Smooth transition */
transition: margin-right 0.3s;
/* Smooth transition */
}
#main-content{
transition: margin-right 0.3s; /* Smooth transition */
#main-content {
transition: margin-right 0.3s;
/* Smooth transition */
}
.collapsed {
margin-right: 300px; /* Hide the sidebar */
margin-right: 300px;
/* Hide the sidebar */
}
</style>
@ -284,7 +287,7 @@ include('parsedatachart.php');
<div class="page-content-wrapper " id="main-content">
<div class="container-fluid" >
<div class="container-fluid">
<div class="row">
<div class="col-sm-12">
@ -304,9 +307,9 @@ include('parsedatachart.php');
<button id="toggleFilters" class="btn btn-primary">Toggle Filters</button>
<!-- Right Sidebar -->
<div class="filter-sidebar" id="filterSidebar">
<?php
<div class="filter-sidebar" id="filterSidebar">
<?php
// 'refNumbers' => $refNumbers,
// 'productsSeasons' => $productsSeasons,
// 'ageRange' => $ageRange,
@ -316,17 +319,17 @@ include('parsedatachart.php');
?>
<div class="form-group">
<label for="productsRefnumber">Product Ref Number</label>
<label for="productsRefnumber">Product Ref Number</label>
<select id="productsRefnumber" class="form-control select2" multiple>
<?php foreach ($refNumbers as $refNumber): ?>
<option value="<?php echo $refNumber['refNumber']; ?>"><?php echo $refNumber['refNumber']; ?></option>
<?php endforeach; ?>
</select>
<option value="<?php echo $refNumber['refNumber']; ?>"><?php echo $refNumber['refNumber']; ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="form-group">
<label for="productsSeason">Product Season</label>
<label for="productsSeason">Product Season</label>
<select id="productsSeason" class="form-control select2" multiple>
<?php foreach ($productsSeasons as $productSeason): ?>
<option value="<?php echo $productSeason['season']; ?>"><?php echo $productSeason['season']; ?></option>
@ -335,7 +338,7 @@ include('parsedatachart.php');
</div>
<div class="form-group">
<label for="ageRange">Age Range</label>
<label for="ageRange">Age Range</label>
<select id="ageRange" class="form-control select2" multiple>
<?php foreach ($ageRange as $age): ?>
<option value="<?php echo $age['ageRange']; ?>"><?php echo $age['ageRange']; ?></option>
@ -344,7 +347,7 @@ include('parsedatachart.php');
</div>
<div class="form-group">
<label for="reportsLabName">Lab Name</label>
<label for="reportsLabName">Lab Name</label>
<select id="reportsLabName" class="form-control select2" multiple>
<?php foreach ($labName as $lab): ?>
<option value="<?php echo $lab['labName']; ?>"><?php echo $lab['labName']; ?></option>
@ -353,7 +356,7 @@ include('parsedatachart.php');
</div>
<div class="form-group">
<label for="reportsTestType">Tes Type</label>
<label for="reportsTestType">Tes Type</label>
<select id="reportsTestType" class="form-control select2" multiple>
<?php foreach ($tesType as $test): ?>
<option value="<?php echo $test['tesType']; ?>"><?php echo $test['tesType']; ?></option>
@ -362,7 +365,7 @@ include('parsedatachart.php');
</div>
<div class="form-group">
<label for="reportsNumberLab">Report Number</label>
<label for="reportsNumberLab">Report Number</label>
<select id="reportsNumberLab" class="form-control select2" multiple>
<?php foreach ($numberLabs as $number): ?>
<option value="<?php echo $number['reportNumber']; ?>"><?php echo $number['reportNumber']; ?></option>
@ -373,67 +376,67 @@ include('parsedatachart.php');
<!-- Scripts -->
<script>
$(document).ready(function() {
$('.select2').select2({
placeholder: "Select options",
allowClear: true
});
$('#toggleFilters').on('click', function() {
$('#filterSidebar').toggle();
$('#main-content').toggleClass('collapsed');
});
$('.select2').on('change', function() {
updateActiveFilters();
});
$('#startDate, #endDate').on('change', function() {
updateActiveFilters();
});
function updateActiveFilters() {
let activeFilters = [];
$('.select2').each(function() {
const selectedValues = $(this).val();
if (selectedValues) {
// activeFilters with values
// activeFilters.push(`${$(this).prev('label').text()}: ${selectedValues.join(', ')}`);
// activefilters without values
activeFilters.push($(this).prev('label').text());
}
$(document).ready(function() {
$('.select2').select2({
placeholder: "Select options",
allowClear: true
});
$('#startDate, #endDate').each(function(){
const selectedValue = $(this).val();
if(selectedValue){
activeFilters.push($(this).prev('label').text());
}
})
$('#activeFilters').html(activeFilters.map(f => `<span class="badge badge-info mr-1">${f} <button class="close" onclick="removeFilter('${f}')">&times;</button></span>`).join(''));
$('#toggleFilters').on('click', function() {
$('#filterSidebar').toggle();
$('#main-content').toggleClass('collapsed');
});
$('.select2').on('change', function() {
updateActiveFilters();
});
$('#startDate, #endDate').on('change', function() {
updateActiveFilters();
});
function updateActiveFilters() {
let activeFilters = [];
$('.select2').each(function() {
const selectedValues = $(this).val();
if (selectedValues) {
// activeFilters with values
// activeFilters.push(`${$(this).prev('label').text()}: ${selectedValues.join(', ')}`);
// activefilters without values
activeFilters.push($(this).prev('label').text());
}
});
$('#startDate, #endDate').each(function() {
const selectedValue = $(this).val();
if (selectedValue) {
activeFilters.push($(this).prev('label').text());
}
})
$('#activeFilters').html(activeFilters.map(f => `<span class="badge badge-info mr-1">${f} <button class="close" onclick="removeFilter('${f}')">&times;</button></span>`).join(''));
}
});
function removeFilter(filter) {
const label = filter.split(':')[0];
const select = $('label').filter(function() {
return $(this).text().trim() === label;
}).next('select');
const dateInput = $('label').filter(function() {
return $(this).text().trim() === label;
}).next('input')
// Clear the select2 field
if (select.length) {
select.val(null).trigger('change');
}
// Clear the date field
if (dateInput.length) {
dateInput.val(null).trigger('change');
}
}
});
function removeFilter(filter) {
const label = filter.split(':')[0];
const select = $('label').filter(function() {
return $(this).text().trim() === label;
}).next('select');
const dateInput = $('label').filter(function(){
return $(this).text().trim() === label;
}).next('input')
// Clear the select2 field
if (select.length) {
select.val(null).trigger('change');
}
// Clear the date field
if(dateInput.length){
dateInput.val(null).trigger('change');
}
}
</script>
@ -455,7 +458,7 @@ include('parsedatachart.php');
</div>
<div class="col-md-4">
<label for="supplierFilter">Supplier</label>
<select id="supplierFilter" class="form-control select2" multiple>
<select id="supplierFilter" class="form-control select2" multiple>
<?php foreach ($productBySupplier as $supplier): ?>
<option value="<?php echo $supplier['supplier']; ?>"><?php echo $supplier['supplier']; ?></option>
<?php endforeach; ?>
@ -593,6 +596,17 @@ include('parsedatachart.php');
</div>
</div>
<div class="row chart-box" id="chart6" data-id="6">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">Analytes with Most Failures</h5>
<div id="analytesFailChart"></div> <!-- Lo spazio per il grafico -->
</div>
</div>
</div>
</div>
</div>
@ -615,7 +629,7 @@ include('parsedatachart.php');
const chartContainer = document.getElementById('charts');
const sortable = new Sortable(chartContainer, {
animation: 150,
onEnd: function () {
onEnd: function() {
saveChartOrder(); // Save chart order after dragging
}
});
@ -630,7 +644,7 @@ include('parsedatachart.php');
url: 'chartorder.php',
method: 'POST',
data: {
method:'save',
method: 'save',
order: order
},
success: function(response) {
@ -660,7 +674,7 @@ include('parsedatachart.php');
url: 'chartorder.php',
method: 'POST',
data: {
method:'load'
method: 'load'
},
success: function(response) {
console.log(response);
@ -713,9 +727,9 @@ include('parsedatachart.php');
alert('No data found.');
data = {};
return;
}else{
} else {
var data = JSON.parse(response);
}
}
// Aggiorna le cards con i nuovi dati
$('#totalProducts').text(data.totalProducts);
@ -855,7 +869,7 @@ include('parsedatachart.php');
// remove bar chart and create a new one
$('#worstSuppliersChart').html('');
// Data for the bar chart of worst suppliers
var supplierNames = data.worstSuppliers.map(function(item) {
return item.supplier;
@ -925,7 +939,7 @@ include('parsedatachart.php');
// remove bar chart and create a new one
$('#productBySupplierChart').html('');
// Prepara i dati per il grafico
var supplierNames = data.productBySupplier.map(function(item) {
return item.supplier;
@ -982,19 +996,20 @@ include('parsedatachart.php');
chart.render();
// remove bar chart and create a new one
$('#analysisDistributionChart').html('');
$('#analysisDistributionChart').html(''); // Resetta il contenuto del div
var analysisNames = data.analysisDistribution.map(function(item) {
return item.analysisName;
});
var totalTests = data.analysisDistribution.map(function(item) {
return parseInt(item.totalTests, 10);
});
// Define the horizontal bar chart for analysis distribution
var analysisBarChartOptions = {
series: [{
name: 'Total Tests',
data: totalTests // Initially empty, will be filled via AJAX
data: totalTests
}],
chart: {
type: 'bar',
@ -1024,7 +1039,7 @@ include('parsedatachart.php');
yaxis: {
labels: {
show: true,
maxWidth: 700, // Increased max width for labels
maxWidth: 700,
style: {
fontSize: '12px',
colors: ['#000']
@ -1051,15 +1066,73 @@ include('parsedatachart.php');
},
grid: {
padding: {
left: 10 // Increased left padding for more label space
left: 10
}
}
};
};
// Create the initial chart
var analysisBarChart = new ApexCharts(document.querySelector("#analysisDistributionChart"), analysisBarChartOptions);
analysisBarChart.render();
// remove bar chart and create a new one
$('#analytesFailChart').html('');
console.log("Dati degli analiti ricevuti:", data.failedAnalytes);
var analyteNames = data.failedAnalytes.map(function(item) {
return item.AnalyteName;
});
var failCounts = data.failedAnalytes.map(function(item) {
return parseInt(item.FailCount, 10);
});
var options = {
series: [{
data: failCounts
}],
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) {
return analyteNames[opt.dataPointIndex]; // Mostra il nome dell'analita 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: 'Analytes'
}
},
colors: ['#ffa515'], // Rosso per i Fail
title: {
text: 'Top 10 Analytes with the Most Failures',
align: 'center'
}
};
console.log(data.failedAnalytes);
var chart = new ApexCharts(document.querySelector("#analytesFailChart"), options);
chart.render();
},
error: function() {
alert('Error retrieving data.');
@ -1067,6 +1140,10 @@ include('parsedatachart.php');
});
}
// Eventi per applicare i filtri
$('#startDate, #endDate, #supplierFilter, #productsRefnumber, #productsSeason, #ageRange, #reportsLabName, #reportsTestType, #reportsNumberLab').on('change', function() {
updateData();
@ -1103,7 +1180,6 @@ include('parsedatachart.php');
document.getElementById('failedTestsPercent').innerText = "(<?php echo number_format($failedTestsPercent, 2); ?>%)";
</script>
<script>
// for multiple select
$(document).ready(function() {
$('.select2').select2({
@ -1111,8 +1187,8 @@ include('parsedatachart.php');
allowClear: true,
width: '100%'
});
});
</script>
});
</script>
<!-- plugin JS -->
<script src="../assets/js/popper.min.js"></script>