add stats, and add history import details
This commit is contained in:
parent
01fffcb0ac
commit
4f0ad202c9
25
public/userarea/importify/add_compound.php
Normal file
25
public/userarea/importify/add_compound.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
include('../include/headscript.php');
|
||||
include("../class/company.php");
|
||||
$conn = new mysqli($servername, $username, $password, $database);
|
||||
|
||||
$analysisId = $_POST['analysis_id'] ?? null;
|
||||
$compoundId = $_POST['compound_id'] ?? null;
|
||||
|
||||
if ($analysisId && $compoundId) {
|
||||
$sql = "INSERT INTO analysis_compounds (idanalysisvocabulary, idcompoundsvocabulary) VALUES (?, ?)";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("ii", $analysisId, $compoundId);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Error adding compound association.']);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Invalid input data.']);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
@ -28,6 +28,8 @@
|
||||
<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>
|
||||
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.1.0-beta.1/css/select2.min.css" rel="stylesheet" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.1.0-beta.1/js/select2.min.js"></script>
|
||||
|
||||
<style>
|
||||
.width-100 {
|
||||
@ -230,7 +232,8 @@
|
||||
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>';
|
||||
return '<button class="btn btn-sm btn-primary show-synonyms" data-id="' + row.idanalysisvocabulary + '">Show Synonyms</button>' +
|
||||
' <button class="btn btn-sm btn-danger show-compounds" data-id="' + row.idanalysisvocabulary + '">Show Compounds</button>';
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -393,6 +396,233 @@
|
||||
Swal.fire('Error', 'Please enter a synonym.', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
// Show compounds and allow editing of compounds
|
||||
// Show compounds and allow editing of compounds
|
||||
$('#analysisTable').on('click', '.show-compounds', 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_compounds.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: analysisId
|
||||
},
|
||||
success: function(response) {
|
||||
var compounds = JSON.parse(response);
|
||||
var childTable = '<table class="table table-custom"><tr><th>Compound Name</th><th>CAS</th><th>Actions</th></tr>';
|
||||
|
||||
if (compounds.length > 0) {
|
||||
$.each(compounds, function(index, compound) {
|
||||
childTable += '<tr>' +
|
||||
'<td>' + compound.namecompoundsvocabulary + '</td>' +
|
||||
'<td>' + compound.cascompoundvocabulary + '</td>' +
|
||||
'<td><button class="btn btn-danger delete-compound" data-id="' + compound.idcompoundsvocabulary + '" data-analysis-id="' + analysisId + '">Delete</button></td></tr>';
|
||||
});
|
||||
} else {
|
||||
|
||||
childTable += '<tr><td colspan="3">No compounds found</td></tr>';
|
||||
}
|
||||
|
||||
// Add row for adding a new compound
|
||||
childTable += '<tr><td>New</td>' +
|
||||
'<td><select class="form-control new-compound-select" data-id="' + analysisId + '"></select></td>' +
|
||||
'<td><button class="btn btn-success add-compound" data-id="' + analysisId + '">Add</button></td></tr>';
|
||||
|
||||
childTable += '</table>';
|
||||
|
||||
row.child(childTable).show();
|
||||
tr.addClass('shown');
|
||||
|
||||
// Load compound options into the select dropdown with Select2
|
||||
$.ajax({
|
||||
url: 'get_compounds_list.php',
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
var compoundsList = JSON.parse(data);
|
||||
var select = tr.next().find('.new-compound-select');
|
||||
|
||||
// Aggiungi un'opzione iniziale per indicare di selezionare un composto
|
||||
select.append('<option value="" disabled selected>Select a compound...</option>');
|
||||
|
||||
// Popola il select con le opzioni
|
||||
$.each(compoundsList, function(index, compound) {
|
||||
var option = new Option(compound.text, compound.id, false, false);
|
||||
select.append(option);
|
||||
});
|
||||
|
||||
// Inizializza Select2 dopo aver popolato il select
|
||||
select.select2({
|
||||
placeholder: "Select a compound...",
|
||||
width: 'resolve',
|
||||
allowClear: true
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire('Error', 'Error loading compounds list.', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire('Error', 'Server communication error.', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$('#analysisTable').on('click', '.add-compound', function() {
|
||||
var analysisId = $(this).data('id');
|
||||
var compoundId = $(this).closest('tr').find('.new-compound-select').val();
|
||||
var tr = $(this).closest('tr').prev(); // Trova la riga principale dell'analisi
|
||||
var row = table.row(tr);
|
||||
|
||||
if (compoundId) {
|
||||
$.ajax({
|
||||
url: 'add_compound.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
analysis_id: analysisId,
|
||||
compound_id: compoundId
|
||||
},
|
||||
success: function(response) {
|
||||
var jsonResponse = JSON.parse(response);
|
||||
if (jsonResponse.success) {
|
||||
Swal.fire('Success', 'New compound has been added successfully!', 'success');
|
||||
|
||||
// Ricarica solo la lista dei composti nel child table senza chiudere
|
||||
reloadChildCompounds(analysisId, row);
|
||||
} else {
|
||||
Swal.fire('Error', jsonResponse.error || 'There was a problem adding the compound.', 'error');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire('Error', 'Server communication error.', 'error');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire('Error', 'Please select a compound.', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
// Funzione per ricaricare il child table dei composti
|
||||
function reloadChildCompounds(analysisId, row) {
|
||||
$.ajax({
|
||||
url: 'get_compounds.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
id: analysisId
|
||||
},
|
||||
success: function(response) {
|
||||
var compounds = JSON.parse(response);
|
||||
var childTable = '<table class="table table-custom"><tr><th>Compound Name</th><th>CAS</th><th>Actions</th></tr>';
|
||||
|
||||
if (compounds.length > 0) {
|
||||
$.each(compounds, function(index, compound) {
|
||||
childTable += '<tr>' +
|
||||
'<td>' + compound.namecompoundsvocabulary + '</td>' +
|
||||
'<td>' + compound.cascompoundvocabulary + '</td>' +
|
||||
'<td><button class="btn btn-danger delete-compound" data-id="' + compound.idcompoundsvocabulary + '" data-analysis-id="' + analysisId + '">Delete</button></td></tr>';
|
||||
});
|
||||
} else {
|
||||
childTable += '<tr><td colspan="3">No compounds found</td></tr>';
|
||||
}
|
||||
|
||||
// Aggiungi una riga per aggiungere un nuovo composto
|
||||
childTable += '<tr><td>New</td>' +
|
||||
'<td><select class="form-control new-compound-select" data-id="' + analysisId + '"></select></td>' +
|
||||
'<td><button class="btn btn-success add-compound" data-id="' + analysisId + '">Add</button></td></tr>';
|
||||
|
||||
childTable += '</table>';
|
||||
|
||||
// Ricarica il contenuto del child row con il nuovo contenuto
|
||||
row.child(childTable).show();
|
||||
|
||||
// Carica le opzioni dei composti nella tendina con Select2
|
||||
$.ajax({
|
||||
url: 'get_compounds_list.php',
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
var compoundsList = JSON.parse(data);
|
||||
var select = row.child().find('.new-compound-select');
|
||||
|
||||
// Aggiungi un'opzione iniziale per indicare di selezionare un composto
|
||||
select.append('<option value="" disabled selected>Select a compound...</option>');
|
||||
|
||||
// Popola il select con le opzioni
|
||||
$.each(compoundsList, function(index, compound) {
|
||||
var option = new Option(compound.text, compound.id, false, false);
|
||||
select.append(option);
|
||||
});
|
||||
|
||||
// Inizializza Select2 dopo aver popolato il select
|
||||
select.select2({
|
||||
placeholder: "Select a compound...",
|
||||
width: 'resolve',
|
||||
allowClear: true
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire('Error', 'Error loading compounds list.', 'error');
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire('Error', 'Server communication error.', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Handle delete compound
|
||||
$('#analysisTable').on('click', '.delete-compound', function() {
|
||||
var compoundId = $(this).data('id');
|
||||
var analysisId = $(this).data('analysis-id');
|
||||
|
||||
Swal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: 'This will delete the compound.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Yes, delete it!',
|
||||
cancelButtonText: 'Close Window'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$.ajax({
|
||||
url: 'delete_compound.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
analysis_id: analysisId, // Invia l'ID dell'analisi
|
||||
compound_id: compoundId // Invia l'ID del composto
|
||||
},
|
||||
success: function(response) {
|
||||
var jsonResponse = JSON.parse(response);
|
||||
if (jsonResponse.success) {
|
||||
Swal.fire('Deleted!', 'The compound has been deleted.', 'success');
|
||||
table.ajax.reload(); // Reload DataTables
|
||||
} else {
|
||||
Swal.fire('Error', jsonResponse.error || 'There was a problem deleting the compound.', 'error');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire('Error', 'Server communication error.', 'error');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<!-- plugin JS -->
|
||||
|
||||
27
public/userarea/importify/delete_compound.php
Normal file
27
public/userarea/importify/delete_compound.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
include('../include/headscript.php');
|
||||
include("../class/company.php");
|
||||
$conn = new mysqli($servername, $username, $password, $database);
|
||||
|
||||
// Recupera sia l'ID dell'analisi che l'ID del composto dalla richiesta POST
|
||||
$analysisId = $_POST['analysis_id'] ?? null;
|
||||
$compoundId = $_POST['compound_id'] ?? null;
|
||||
|
||||
if ($analysisId && $compoundId) {
|
||||
// Elimina l'associazione specifica tra l'analisi e il composto
|
||||
$sql = "DELETE FROM analysis_compounds WHERE idanalysisvocabulary = ? AND idcompoundsvocabulary = ?";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("ii", $analysisId, $compoundId);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Error deleting compound association.']);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'error' => 'Invalid analysis or compound ID.']);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
@ -1,10 +1,51 @@
|
||||
<?php
|
||||
include('../include/headscript.php');
|
||||
include("../class/company.php");
|
||||
|
||||
// Abilita il reporting degli errori per il debug
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$conn = new mysqli($servername, $username, $password, $database);
|
||||
|
||||
$columns = ['idanalysisvocabulary', 'nameanalysisvoc', 'kindanalysisvoc', 'analysiscode'];
|
||||
|
||||
// Recupera i parametri di DataTables
|
||||
$draw = isset($_POST['draw']) ? intval($_POST['draw']) : 0;
|
||||
$start = isset($_POST['start']) ? intval($_POST['start']) : 0;
|
||||
$length = isset($_POST['length']) ? intval($_POST['length']) : 10;
|
||||
$searchValue = isset($_POST['search']['value']) ? $_POST['search']['value'] : '';
|
||||
|
||||
// Costruisci la query di base per recuperare tutti i dati
|
||||
$sql = "SELECT * FROM analysisvocabulary WHERE preferred = 'Y'";
|
||||
|
||||
// Applica il filtro di ricerca, se presente
|
||||
if (!empty($searchValue)) {
|
||||
$searchValueEscaped = $conn->real_escape_string($searchValue);
|
||||
$sql .= " AND (nameanalysisvoc LIKE '%$searchValueEscaped%'
|
||||
OR kindanalysisvoc LIKE '%$searchValueEscaped%'
|
||||
OR analysiscode LIKE '%$searchValueEscaped%')";
|
||||
}
|
||||
|
||||
// Esegui la query per ottenere il conteggio dei record filtrati
|
||||
$filteredRecordsQuery = "SELECT COUNT(*) as total FROM analysisvocabulary WHERE preferred = 'Y'";
|
||||
if (!empty($searchValue)) {
|
||||
$filteredRecordsQuery .= " AND (nameanalysisvoc LIKE '%$searchValueEscaped%'
|
||||
OR kindanalysisvoc LIKE '%$searchValueEscaped%'
|
||||
OR analysiscode LIKE '%$searchValueEscaped%')";
|
||||
}
|
||||
$filteredRecordsResult = $conn->query($filteredRecordsQuery);
|
||||
$totalFilteredRecords = $filteredRecordsResult->fetch_assoc()['total'];
|
||||
|
||||
// Esegui la query per ottenere il conteggio totale dei record senza filtro
|
||||
$totalRecordsQuery = "SELECT COUNT(*) as total FROM analysisvocabulary WHERE preferred = 'Y'";
|
||||
$totalRecordsResult = $conn->query($totalRecordsQuery);
|
||||
$totalRecords = $totalRecordsResult->fetch_assoc()['total'];
|
||||
|
||||
// Aggiungi la limitazione per la paginazione
|
||||
$sql .= " LIMIT $start, $length";
|
||||
|
||||
// Esegui la query principale per recuperare i dati
|
||||
$result = $conn->query($sql);
|
||||
$data = [];
|
||||
|
||||
@ -17,4 +58,16 @@ while ($row = $result->fetch_assoc()) {
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode(['data' => $data]);
|
||||
// Prepara la risposta per DataTables
|
||||
$response = [
|
||||
"draw" => $draw,
|
||||
"recordsTotal" => $totalRecords,
|
||||
"recordsFiltered" => $totalFilteredRecords,
|
||||
"data" => $data
|
||||
];
|
||||
|
||||
// Imposta il tipo di contenuto e restituisci la risposta JSON
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($response);
|
||||
|
||||
$conn->close();
|
||||
|
||||
34
public/userarea/importify/get_compounds.php
Normal file
34
public/userarea/importify/get_compounds.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
include('../include/headscript.php');
|
||||
include("../class/company.php");
|
||||
$conn = new mysqli($servername, $username, $password, $database);
|
||||
|
||||
// Recupera l'ID dell'analisi dalla richiesta
|
||||
$analysisId = $_POST['id'] ?? null;
|
||||
|
||||
if ($analysisId) {
|
||||
$sql = "SELECT c.idcompoundsvocabulary, c.namecompoundsvocabulary, c.cascompoundvocabulary
|
||||
FROM analysis_compounds ac
|
||||
INNER JOIN compundsvocabulary c ON ac.idcompoundsvocabulary = c.idcompoundsvocabulary
|
||||
WHERE ac.idanalysisvocabulary = ?";
|
||||
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bind_param("i", $analysisId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$data = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$data[] = [
|
||||
'idcompoundsvocabulary' => $row['idcompoundsvocabulary'],
|
||||
'namecompoundsvocabulary' => $row['namecompoundsvocabulary'],
|
||||
'cascompoundvocabulary' => $row['cascompoundvocabulary'],
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($data);
|
||||
} else {
|
||||
echo json_encode(['error' => 'Invalid analysis ID']);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
18
public/userarea/importify/get_compounds_list.php
Normal file
18
public/userarea/importify/get_compounds_list.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
include('../include/headscript.php');
|
||||
include("../class/company.php");
|
||||
$conn = new mysqli($servername, $username, $password, $database);
|
||||
|
||||
$sql = "SELECT idcompoundsvocabulary, namecompoundsvocabulary, cascompoundvocabulary FROM compundsvocabulary WHERE preferred='Y'";
|
||||
$result = $conn->query($sql);
|
||||
|
||||
$data = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$data[] = [
|
||||
'id' => $row['idcompoundsvocabulary'],
|
||||
'text' => $row['namecompoundsvocabulary'] . ' (' . $row['cascompoundvocabulary'] . ')'
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($data);
|
||||
$conn->close();
|
||||
@ -36,8 +36,10 @@ function post_async($url, array $params)
|
||||
|
||||
if (isset($_FILES['f_csv'])) {
|
||||
$file = $_FILES['f_csv']['tmp_name'];
|
||||
$filename = $_FILES['f_csv']['name'];
|
||||
$template_id = $_POST['template_id'];
|
||||
$idLabs = $_POST['lab_id']; // get lab id
|
||||
$iduserlogin = $_SESSION['iduserlogin'];
|
||||
|
||||
//get template associate data
|
||||
$arr_associate_data = new WA_MySQLi_RS("rsl", $repnew, 0);
|
||||
@ -145,6 +147,7 @@ if (isset($_FILES['f_csv'])) {
|
||||
$InsertQuery->bindColumn("importcode", "s", "" . $importcode, "WA_DEFAULT");
|
||||
$InsertQuery->bindColumn("f_status", "i", "0", "WA_DEFAULT");
|
||||
$InsertQuery->bindColumn("idtemplate", "i", $template_id, "WA_DEFAULT");
|
||||
$InsertQuery->bindColumn("importfilename", "s", $filename, "WA_DEFAULT"); // Nome del file
|
||||
$InsertQuery->saveInSession("");
|
||||
$InsertQuery->execute();
|
||||
|
||||
|
||||
37
public/userarea/include/class/rating_definitions.php
Normal file
37
public/userarea/include/class/rating_definitions.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
// Definizioni di rating centralizzate
|
||||
|
||||
// Array di denominazioni per "Pass"
|
||||
define("RATING_PASS", [
|
||||
'PASS',
|
||||
'P',
|
||||
'Complies',
|
||||
'Comply',
|
||||
'pass',
|
||||
'Pass',
|
||||
'comply',
|
||||
'complies'
|
||||
]);
|
||||
|
||||
// Array di denominazioni per "Fail"
|
||||
define("RATING_FAIL", [
|
||||
'FAIL',
|
||||
'F',
|
||||
'Doesn\'t Comply',
|
||||
'fail',
|
||||
'Fail',
|
||||
'f',
|
||||
'doesn\'t comply'
|
||||
]);
|
||||
|
||||
// Array di denominazioni per "Data" o "Other"
|
||||
define("RATING_OTHER", [
|
||||
'DATA',
|
||||
'D',
|
||||
'Data',
|
||||
'data',
|
||||
'other',
|
||||
'misc',
|
||||
'//',
|
||||
'N/A'
|
||||
]);
|
||||
@ -94,5 +94,6 @@ include(BASE_PATH . '/public/languages/en/dash.php');
|
||||
include(BASE_PATH . "/public/userarea/include/generalsettings.php");
|
||||
|
||||
include(BASE_PATH . "/public/userarea/include/class/company.php");
|
||||
//include(BASE_PATH . "/public/userarea/include/class/rating_definitions.php");
|
||||
|
||||
?>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<?php include('../../Connections/repnew.php'); ?>
|
||||
<?php include('../../Connections/repnew.php');
|
||||
include('../include/class/rating_definitions.php'); ?>
|
||||
<?php
|
||||
$conn = new mysqli($servername, $username, $password, $database);
|
||||
// error_reporting(1);
|
||||
@ -238,6 +239,63 @@ while ($row = $topFailingAnalysisResult->fetch_assoc()) {
|
||||
$topFailingAnalysis[] = ['name' => $analysisName, 'failCount' => $row['failCount']];
|
||||
}
|
||||
|
||||
// Query per il grafico a barre orizzontali con raggruppamento basato su products_season
|
||||
// Gestione del raggruppamento dinamico dal POST
|
||||
$groupingField = isset($_POST['groupingField']) ? $_POST['groupingField'] : 'products_season';
|
||||
$passConditions = implode("', '", array_map('addslashes', RATING_PASS));
|
||||
$failConditions = implode("', '", array_map('addslashes', RATING_FAIL));
|
||||
$otherConditions = implode("', '", array_map('addslashes', RATING_OTHER));
|
||||
|
||||
// Query per il grafico a barre orizzontali con sezioni multicolore
|
||||
$horizontalBarQuery = "
|
||||
SELECT
|
||||
p.$groupingField AS groupingValue,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) IN ('$passConditions') THEN 1 ELSE 0 END) AS passCount,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) IN ('$failConditions') THEN 1 ELSE 0 END) AS failCount,
|
||||
SUM(CASE WHEN UPPER(r.reportsRating) NOT IN ('$passConditions', '$failConditions') THEN 1 ELSE 0 END) AS otherCount
|
||||
FROM reports r
|
||||
LEFT JOIN products p ON r.idproducts = p.idproducts
|
||||
$filters
|
||||
GROUP BY p.$groupingField
|
||||
";
|
||||
|
||||
|
||||
$horizontalBarResult = $conn->query($horizontalBarQuery);
|
||||
$horizontalBarData = [];
|
||||
while ($row = $horizontalBarResult->fetch_assoc()) {
|
||||
$horizontalBarData[] = [
|
||||
'groupingValue' => $row['groupingValue'],
|
||||
'passCount' => $row['passCount'],
|
||||
'failCount' => $row['failCount'],
|
||||
'otherCount' => $row['otherCount']
|
||||
];
|
||||
}
|
||||
|
||||
// Query per ottenere il conteggio di Pass, Fail e altri dalle analisi
|
||||
$horizontalBarAnalysisQuery = "
|
||||
SELECT
|
||||
p.$groupingField AS groupingValue,
|
||||
SUM(CASE WHEN UPPER(ap.test_Rating) IN ('PASS', 'P', 'COMPLIES') THEN 1 ELSE 0 END) AS passCount,
|
||||
SUM(CASE WHEN UPPER(ap.test_Rating) IN ('FAIL', 'F', 'DOESN\'T COMPLY') THEN 1 ELSE 0 END) AS failCount,
|
||||
SUM(CASE WHEN UPPER(ap.test_Rating) NOT IN ('PASS', 'P', 'COMPLIES', 'FAIL', 'F', 'DOESN\'T COMPLY') THEN 1 ELSE 0 END) AS otherCount
|
||||
FROM analysis_project ap
|
||||
LEFT JOIN reports r ON ap.idreports = r.idreports
|
||||
LEFT JOIN products p ON r.idproducts = p.idproducts
|
||||
$filters
|
||||
GROUP BY p.$groupingField
|
||||
";
|
||||
|
||||
$horizontalBarAnalysisResult = $conn->query($horizontalBarAnalysisQuery);
|
||||
$horizontalBarAnalysisData = [];
|
||||
while ($row = $horizontalBarAnalysisResult->fetch_assoc()) {
|
||||
$horizontalBarAnalysisData[] = [
|
||||
'groupingValue' => $row['groupingValue'],
|
||||
'passCount' => (int)$row['passCount'],
|
||||
'failCount' => (int)$row['failCount'],
|
||||
'otherCount' => (int)$row['otherCount']
|
||||
];
|
||||
}
|
||||
|
||||
// Statistic for worst suppliers based on % of failed reports
|
||||
$worstSuppliersQuery = "
|
||||
SELECT p.namesupplier AS supplier, COUNT(r.idreports) AS totalReports,
|
||||
@ -451,7 +509,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
'tesType' => $tesType,
|
||||
'numberLabs' => $numberLabs,
|
||||
'failedAnalytes' => $failedAnalytes,
|
||||
'analysisDistribution' => $analysisDistribution // Distribuzione delle analisi per il grafico a torta
|
||||
'analysisDistribution' => $analysisDistribution, // Distribuzione delle analisi per il grafico a torta
|
||||
'horizontalBarData' => $horizontalBarData, // Dati per il grafico a barre orizzontali
|
||||
'horizontalBarAnalysisData' => $horizontalBarAnalysisData // Nuovi dati per le analisi
|
||||
]);
|
||||
exit; // Ferma l'esecuzione del resto dello script dopo aver risposto all'AJAX
|
||||
}
|
||||
|
||||
@ -607,6 +607,37 @@ include('parsedatachart.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row chart-box" id="chart7" data-id="7">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title" id="dynamicChartTitle">Rating Distribution by Group</h5>
|
||||
|
||||
<!-- Inserisci il dropdown direttamente all'interno della card -->
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<label for="groupingField">Group by:</label>
|
||||
<select id="groupingField" class="form-control">
|
||||
<option value="products_season">Product Season</option>
|
||||
<option value="agerange">Age Range</option>
|
||||
<option value="namesupplier">Name Supplier</option>
|
||||
<!-- Aggiungi altri campi se necessario -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Area per il grafico -->
|
||||
<br>
|
||||
<h6 class="mt-4">Report Rating Distribution</h6> <!-- Titolo per il primo grafico -->
|
||||
<div id="horizontalBarChart"></div>
|
||||
|
||||
<h6 class="mt-4">Analysis Rating Distribution</h6> <!-- Titolo per il secondo grafico -->
|
||||
<div id="horizontalBarAnalysisChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
@ -707,6 +738,13 @@ include('parsedatachart.php');
|
||||
var reportsLabName = $('#reportsLabName').val();
|
||||
var reportsTestType = $('#reportsTestType').val();
|
||||
var reportsNumberLab = $('#reportsNumberLab').val();
|
||||
var groupingField = $('#groupingField').val();
|
||||
|
||||
// Aggiorna il titolo dinamicamente in base alla selezione del dropdown
|
||||
var groupingText = $('#groupingField option:selected').text(); // Ottieni il testo dell'opzione selezionata
|
||||
$('#dynamicChartTitle').text(`Rating Distribution by Group: ${groupingText}`); // Aggiorna il titolo
|
||||
|
||||
|
||||
|
||||
$.ajax({
|
||||
url: 'parsedatachart.php',
|
||||
@ -720,7 +758,8 @@ include('parsedatachart.php');
|
||||
ageRange: ageRange,
|
||||
reportsLabName: reportsLabName,
|
||||
reportsTestType: reportsTestType,
|
||||
reportsNumberLab: reportsNumberLab
|
||||
reportsNumberLab: reportsNumberLab,
|
||||
groupingField: groupingField
|
||||
},
|
||||
success: function(response) {
|
||||
if (!response) {
|
||||
@ -867,6 +906,102 @@ include('parsedatachart.php');
|
||||
var chart = new ApexCharts(document.querySelector("#worsttenanalysis"), options);
|
||||
chart.render();
|
||||
|
||||
// Genera il nuovo grafico a barre orizzontali
|
||||
$('#horizontalBarChart').html('');
|
||||
var horizontalBarData = data.horizontalBarData;
|
||||
var categories = horizontalBarData.map(item => item.groupingValue);
|
||||
var passData = horizontalBarData.map(item => item.passCount);
|
||||
var failData = horizontalBarData.map(item => item.failCount);
|
||||
var otherData = horizontalBarData.map(item => item.otherCount);
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'Pass',
|
||||
data: passData
|
||||
},
|
||||
{
|
||||
name: 'Fail',
|
||||
data: failData
|
||||
},
|
||||
{
|
||||
name: 'Others',
|
||||
data: otherData
|
||||
}
|
||||
],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400,
|
||||
stacked: true,
|
||||
horizontal: true
|
||||
},
|
||||
xaxis: {
|
||||
categories: categories
|
||||
},
|
||||
colors: ['#28A745', '#FF4D4D', '#FFA500'],
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
position: 'top'
|
||||
},
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(document.querySelector("#horizontalBarChart"), options);
|
||||
chart.render();
|
||||
|
||||
// Dati per il grafico delle analisi
|
||||
var horizontalBarAnalysisData = data.horizontalBarAnalysisData;
|
||||
var categoriesAnalysis = horizontalBarAnalysisData.map(item => item.groupingValue);
|
||||
var passDataAnalysis = horizontalBarAnalysisData.map(item => item.passCount);
|
||||
var failDataAnalysis = horizontalBarAnalysisData.map(item => item.failCount);
|
||||
var otherDataAnalysis = horizontalBarAnalysisData.map(item => item.otherCount);
|
||||
|
||||
// Crea o aggiorna il grafico delle analisi
|
||||
$('#horizontalBarAnalysisChart').html('');
|
||||
var optionsAnalysis = {
|
||||
series: [{
|
||||
name: 'Pass',
|
||||
data: passDataAnalysis
|
||||
},
|
||||
{
|
||||
name: 'Fail',
|
||||
data: failDataAnalysis
|
||||
},
|
||||
{
|
||||
name: 'Others',
|
||||
data: otherDataAnalysis
|
||||
}
|
||||
],
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 400,
|
||||
stacked: true,
|
||||
horizontal: true
|
||||
},
|
||||
xaxis: {
|
||||
categories: categoriesAnalysis
|
||||
},
|
||||
colors: ['#28A745', '#FF4D4D', '#FFA500'],
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
position: 'top'
|
||||
},
|
||||
};
|
||||
var chartAnalysis = new ApexCharts(document.querySelector("#horizontalBarAnalysisChart"), optionsAnalysis);
|
||||
chartAnalysis.render();
|
||||
|
||||
// remove bar chart and create a new one
|
||||
$('#worstSuppliersChart').html('');
|
||||
|
||||
@ -1144,8 +1279,8 @@ include('parsedatachart.php');
|
||||
|
||||
|
||||
|
||||
// Eventi per applicare i filtri
|
||||
$('#startDate, #endDate, #supplierFilter, #productsRefnumber, #productsSeason, #ageRange, #reportsLabName, #reportsTestType, #reportsNumberLab').on('change', function() {
|
||||
// Eventi per applicare i filtri e il cambio di raggruppamento
|
||||
$('#startDate, #endDate, #supplierFilter, #productsRefnumber, #productsSeason, #ageRange, #reportsLabName, #reportsTestType, #reportsNumberLab, #groupingField').on('change', function() {
|
||||
updateData();
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user