analysis complete
This commit is contained in:
parent
7dfb935e33
commit
39a821357e
@ -1,6 +1,9 @@
|
|||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
let analysisMatriciMap = {};
|
let analysisMatriciMap = {};
|
||||||
|
let analysisLoadedCache = {};
|
||||||
|
let analysisAssignedState = {};
|
||||||
|
let analysisSelectedState = {};
|
||||||
|
|
||||||
function loadAnalysisMatrixNames() {
|
function loadAnalysisMatrixNames() {
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
@ -57,6 +60,475 @@
|
|||||||
analysisMatriciMap[String(matrixId)] || "#" + matrixId;
|
analysisMatriciMap[String(matrixId)] || "#" + matrixId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function readInitialAssignedAnalyses() {
|
||||||
|
const jsonEl = document.getElementById("analysisAssignedInitialData");
|
||||||
|
if (!jsonEl) {
|
||||||
|
analysisAssignedState = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
analysisAssignedState =
|
||||||
|
JSON.parse(jsonEl.textContent || "{}") || {};
|
||||||
|
} catch (e) {
|
||||||
|
analysisAssignedState = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedPartIds() {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return [];
|
||||||
|
|
||||||
|
return Array.from(
|
||||||
|
modal.querySelectorAll(".analysis-part-checkbox:checked"),
|
||||||
|
).map((el) => String(el.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentSelectedAnalysisRecordKeys() {
|
||||||
|
return Object.keys(analysisSelectedState).filter(function (key) {
|
||||||
|
return analysisSelectedState[key] === true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAssignedAnalysesForPart(partId) {
|
||||||
|
const container = document.getElementById(
|
||||||
|
"analysisAssignedListPart" + partId,
|
||||||
|
);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const items = Array.isArray(analysisAssignedState[String(partId)])
|
||||||
|
? analysisAssignedState[String(partId)]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (!items.length) {
|
||||||
|
container.innerHTML = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.innerHTML = items
|
||||||
|
.map(function (item) {
|
||||||
|
const recordKey = item.analysis_recordkey || "";
|
||||||
|
const title = item.analysis_name || "Unnamed analysis";
|
||||||
|
const method = item.analysis_method || "";
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="analysis-assigned-chip" data-recordkey="${escapeHtml(recordKey)}">
|
||||||
|
<div class="analysis-assigned-chip-text">
|
||||||
|
<div class="analysis-assigned-chip-title">${escapeHtml(title)}</div>
|
||||||
|
${method ? `<div class="analysis-assigned-chip-method">${escapeHtml(method)}</div>` : ""}
|
||||||
|
</div>
|
||||||
|
<button type="button"
|
||||||
|
class="analysis-remove-btn"
|
||||||
|
data-part-id="${escapeHtml(partId)}"
|
||||||
|
data-recordkey="${escapeHtml(recordKey)}"
|
||||||
|
title="Remove analysis">×</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAssignedAnalysesForSelectedParts() {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
modal.querySelectorAll(".analysis-part-item").forEach(function (item) {
|
||||||
|
const partId = item.getAttribute("data-part-id");
|
||||||
|
renderAssignedAnalysesForPart(partId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncSelectedAnalysisRows() {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
modal
|
||||||
|
.querySelectorAll(".analysis-analysis-item")
|
||||||
|
.forEach(function (item) {
|
||||||
|
const recordKey = item.getAttribute("data-recordkey") || "";
|
||||||
|
if (recordKey && analysisSelectedState[recordKey]) {
|
||||||
|
item.classList.add("analysis-selected");
|
||||||
|
} else {
|
||||||
|
item.classList.remove("analysis-selected");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildAnalysisPayloadFromRow(rowEl) {
|
||||||
|
return {
|
||||||
|
analysis_recordkey: rowEl.getAttribute("data-recordkey") || "",
|
||||||
|
analysis_name: rowEl.getAttribute("data-analysis-name") || "",
|
||||||
|
analysis_method: rowEl.getAttribute("data-analysis-method") || "",
|
||||||
|
analysis_level: rowEl.getAttribute("data-analysis-level") || "",
|
||||||
|
is_web_selectable: rowEl.getAttribute("data-web") === "1" ? 1 : 0,
|
||||||
|
is_accredited:
|
||||||
|
rowEl.getAttribute("data-accredited") === "1" ? 1 : 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAnalysisToLocalState(partId, payload, iddatadb, idmatrice) {
|
||||||
|
const key = String(partId);
|
||||||
|
if (!Array.isArray(analysisAssignedState[key])) {
|
||||||
|
analysisAssignedState[key] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const exists = analysisAssignedState[key].some(function (item) {
|
||||||
|
return item.analysis_recordkey === payload.analysis_recordkey;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!exists) {
|
||||||
|
analysisAssignedState[key].push({
|
||||||
|
id: null,
|
||||||
|
part_id: parseInt(partId, 10),
|
||||||
|
iddatadb: iddatadb || null,
|
||||||
|
idmatrice: idmatrice || null,
|
||||||
|
analysis_recordkey: payload.analysis_recordkey,
|
||||||
|
analysis_name: payload.analysis_name,
|
||||||
|
analysis_method: payload.analysis_method,
|
||||||
|
analysis_level:
|
||||||
|
payload.analysis_level !== ""
|
||||||
|
? parseInt(payload.analysis_level, 10)
|
||||||
|
: null,
|
||||||
|
is_web_selectable: payload.is_web_selectable,
|
||||||
|
is_accredited: payload.is_accredited,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAnalysisFromLocalState(partId, recordKey) {
|
||||||
|
const key = String(partId);
|
||||||
|
if (!Array.isArray(analysisAssignedState[key])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
analysisAssignedState[key] = analysisAssignedState[key].filter(
|
||||||
|
function (item) {
|
||||||
|
return item.analysis_recordkey !== recordKey;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveAnalysisAssociation(partId, payload, callback) {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
const iddatadb =
|
||||||
|
modal.querySelector("#analysisModalIddatadb")?.value || "";
|
||||||
|
const partItem = modal.querySelector(
|
||||||
|
'.analysis-part-item[data-part-id="' + partId + '"]',
|
||||||
|
);
|
||||||
|
const idmatrice = partItem
|
||||||
|
? partItem.getAttribute("data-matrix-id") || ""
|
||||||
|
: "";
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "save_part_analysis.php",
|
||||||
|
method: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
part_id: partId,
|
||||||
|
iddatadb: iddatadb,
|
||||||
|
idmatrice: idmatrice !== "NO_MATRIX" ? idmatrice : "",
|
||||||
|
analysis_recordkey: payload.analysis_recordkey,
|
||||||
|
analysis_name: payload.analysis_name,
|
||||||
|
analysis_method: payload.analysis_method,
|
||||||
|
analysis_level: payload.analysis_level,
|
||||||
|
is_web_selectable: payload.is_web_selectable,
|
||||||
|
is_accredited: payload.is_accredited,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.done(function () {
|
||||||
|
addAnalysisToLocalState(
|
||||||
|
partId,
|
||||||
|
payload,
|
||||||
|
iddatadb,
|
||||||
|
idmatrice !== "NO_MATRIX" ? idmatrice : null,
|
||||||
|
);
|
||||||
|
renderAssignedAnalysesForPart(partId);
|
||||||
|
if (typeof callback === "function") callback(true);
|
||||||
|
})
|
||||||
|
.fail(function (xhr) {
|
||||||
|
let message = "Error saving analysis association";
|
||||||
|
if (xhr && xhr.responseJSON && xhr.responseJSON.message) {
|
||||||
|
message = xhr.responseJSON.message;
|
||||||
|
}
|
||||||
|
alert(message);
|
||||||
|
if (typeof callback === "function") callback(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteAnalysisAssociation(partId, recordKey, callback) {
|
||||||
|
$.ajax({
|
||||||
|
url: "delete_part_analysis.php",
|
||||||
|
method: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
part_id: partId,
|
||||||
|
analysis_recordkey: recordKey,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.done(function () {
|
||||||
|
removeAnalysisFromLocalState(partId, recordKey);
|
||||||
|
renderAssignedAnalysesForPart(partId);
|
||||||
|
if (typeof callback === "function") callback(true);
|
||||||
|
})
|
||||||
|
.fail(function (xhr) {
|
||||||
|
let message = "Error deleting analysis association";
|
||||||
|
if (xhr && xhr.responseJSON && xhr.responseJSON.message) {
|
||||||
|
message = xhr.responseJSON.message;
|
||||||
|
}
|
||||||
|
alert(message);
|
||||||
|
if (typeof callback === "function") callback(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function setAnalysisLoadingState(isLoading) {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
const loadingEl = modal.querySelector("#analysisLoadingBox");
|
||||||
|
if (!loadingEl) return;
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
loadingEl.classList.remove("d-none");
|
||||||
|
} else {
|
||||||
|
loadingEl.classList.add("d-none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAnalysisError(message) {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
const errorEl = modal.querySelector("#analysisErrorBox");
|
||||||
|
const emptyEl = modal.querySelector("#analysisEmptyBox");
|
||||||
|
const listEl = modal.querySelector("#analysisList");
|
||||||
|
|
||||||
|
if (listEl) listEl.innerHTML = "";
|
||||||
|
if (emptyEl) emptyEl.classList.add("d-none");
|
||||||
|
|
||||||
|
if (errorEl) {
|
||||||
|
errorEl.textContent = message || "Error loading analyses";
|
||||||
|
errorEl.classList.remove("d-none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAnalysisEmpty(message) {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
const errorEl = modal.querySelector("#analysisErrorBox");
|
||||||
|
const emptyEl = modal.querySelector("#analysisEmptyBox");
|
||||||
|
const listEl = modal.querySelector("#analysisList");
|
||||||
|
|
||||||
|
if (listEl) listEl.innerHTML = "";
|
||||||
|
if (errorEl) errorEl.classList.add("d-none");
|
||||||
|
|
||||||
|
if (emptyEl) {
|
||||||
|
emptyEl.textContent =
|
||||||
|
message || "No analyses found for this matrix";
|
||||||
|
emptyEl.classList.remove("d-none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHtml(value) {
|
||||||
|
return String(value ?? "")
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAnalysesList(analyses) {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
const errorEl = modal.querySelector("#analysisErrorBox");
|
||||||
|
const emptyEl = modal.querySelector("#analysisEmptyBox");
|
||||||
|
const listEl = modal.querySelector("#analysisList");
|
||||||
|
|
||||||
|
if (!listEl) return;
|
||||||
|
|
||||||
|
if (errorEl) errorEl.classList.add("d-none");
|
||||||
|
|
||||||
|
if (!Array.isArray(analyses) || analyses.length === 0) {
|
||||||
|
showAnalysisEmpty("No analyses found for this matrix");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emptyEl) emptyEl.classList.add("d-none");
|
||||||
|
|
||||||
|
listEl.innerHTML = analyses
|
||||||
|
.map(function (item) {
|
||||||
|
const recordKey = item.RecordKey || "";
|
||||||
|
const analysisName =
|
||||||
|
item.NomeAnalisiTraduzione ||
|
||||||
|
item.NomeAnalisi ||
|
||||||
|
"Unnamed analysis";
|
||||||
|
const methodName = item.MetodoNome || "";
|
||||||
|
const selectable = item.SelezionabileSuWeb === true;
|
||||||
|
const accredited = item.Accreditato === true;
|
||||||
|
const level = item.Livello ?? "";
|
||||||
|
const searchText = (
|
||||||
|
analysisName +
|
||||||
|
" " +
|
||||||
|
methodName
|
||||||
|
).toLowerCase();
|
||||||
|
|
||||||
|
let badges = "";
|
||||||
|
if (selectable) {
|
||||||
|
badges += '<span class="badge bg-success">Web</span>';
|
||||||
|
} else {
|
||||||
|
badges += '<span class="badge bg-secondary">Not web</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accredited) {
|
||||||
|
badges +=
|
||||||
|
'<span class="badge bg-info text-dark">Accredited</span>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level !== "") {
|
||||||
|
badges +=
|
||||||
|
'<span class="badge bg-light text-dark border">Level ' +
|
||||||
|
escapeHtml(level) +
|
||||||
|
"</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div
|
||||||
|
class="list-group-item analysis-analysis-item"
|
||||||
|
data-recordkey="${escapeHtml(recordKey)}"
|
||||||
|
data-analysis-name="${escapeHtml(analysisName)}"
|
||||||
|
data-analysis-method="${escapeHtml(methodName)}"
|
||||||
|
data-analysis-level="${escapeHtml(level)}"
|
||||||
|
data-web="${selectable ? "1" : "0"}"
|
||||||
|
data-accredited="${accredited ? "1" : "0"}"
|
||||||
|
data-search="${escapeHtml(searchText)}"
|
||||||
|
>
|
||||||
|
<div class="fw-semibold">${escapeHtml(analysisName)}</div>
|
||||||
|
|
||||||
|
${methodName ? `<div class="analysis-analysis-meta mt-1">${escapeHtml(methodName)}</div>` : ""}
|
||||||
|
|
||||||
|
<div class="analysis-analysis-badges mt-2">
|
||||||
|
${badges}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
filterAnalysisList();
|
||||||
|
syncSelectedAnalysisRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterAnalysisList() {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
const webOnlyEl = modal.querySelector("#analysisWebOnly");
|
||||||
|
const searchEl = modal.querySelector("#analysisSearchInput");
|
||||||
|
const items = modal.querySelectorAll(".analysis-analysis-item");
|
||||||
|
const emptyEl = modal.querySelector("#analysisEmptyBox");
|
||||||
|
const errorEl = modal.querySelector("#analysisErrorBox");
|
||||||
|
|
||||||
|
const webOnly = webOnlyEl ? webOnlyEl.checked : false;
|
||||||
|
const searchValue = searchEl ? searchEl.value.trim().toLowerCase() : "";
|
||||||
|
|
||||||
|
let visibleCount = 0;
|
||||||
|
|
||||||
|
items.forEach((item) => {
|
||||||
|
const isWeb = item.getAttribute("data-web") === "1";
|
||||||
|
const searchText = (
|
||||||
|
item.getAttribute("data-search") || ""
|
||||||
|
).toLowerCase();
|
||||||
|
|
||||||
|
let visible = true;
|
||||||
|
|
||||||
|
if (webOnly && !isWeb) {
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visible && searchValue && !searchText.includes(searchValue)) {
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.style.display = visible ? "" : "none";
|
||||||
|
|
||||||
|
if (visible) {
|
||||||
|
visibleCount++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (errorEl) {
|
||||||
|
errorEl.classList.add("d-none");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emptyEl) {
|
||||||
|
if (items.length === 0) {
|
||||||
|
emptyEl.textContent = "No analyses found for this matrix";
|
||||||
|
emptyEl.classList.remove("d-none");
|
||||||
|
} else if (visibleCount === 0) {
|
||||||
|
emptyEl.textContent = "No analyses match the current filters";
|
||||||
|
emptyEl.classList.remove("d-none");
|
||||||
|
} else {
|
||||||
|
emptyEl.classList.add("d-none");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadAnalysesByMatrix(matrixId) {
|
||||||
|
const modal = document.getElementById("analysisModal");
|
||||||
|
if (!modal) return;
|
||||||
|
|
||||||
|
if (!matrixId || matrixId === "NO_MATRIX") {
|
||||||
|
showAnalysisEmpty("No matrix selected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const listEl = modal.querySelector("#analysisList");
|
||||||
|
const errorEl = modal.querySelector("#analysisErrorBox");
|
||||||
|
const emptyEl = modal.querySelector("#analysisEmptyBox");
|
||||||
|
|
||||||
|
if (listEl) listEl.innerHTML = "";
|
||||||
|
if (errorEl) errorEl.classList.add("d-none");
|
||||||
|
if (emptyEl) {
|
||||||
|
emptyEl.textContent = "";
|
||||||
|
emptyEl.classList.add("d-none");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (analysisLoadedCache[String(matrixId)]) {
|
||||||
|
renderAnalysesList(analysisLoadedCache[String(matrixId)]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAnalysisLoadingState(true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "get_analisi_matrice_filter.php",
|
||||||
|
method: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
data: {
|
||||||
|
id_matrice: matrixId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.done(function (response) {
|
||||||
|
const analyses = Array.isArray(response.value)
|
||||||
|
? response.value
|
||||||
|
: [];
|
||||||
|
analysisLoadedCache[String(matrixId)] = analyses;
|
||||||
|
renderAnalysesList(analyses);
|
||||||
|
})
|
||||||
|
.fail(function (xhr) {
|
||||||
|
let message = "Error loading analyses";
|
||||||
|
if (xhr && xhr.responseJSON && xhr.responseJSON.error) {
|
||||||
|
message = xhr.responseJSON.error;
|
||||||
|
}
|
||||||
|
showAnalysisError(message);
|
||||||
|
})
|
||||||
|
.always(function () {
|
||||||
|
setAnalysisLoadingState(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function updateSelectedPartsInfo() {
|
function updateSelectedPartsInfo() {
|
||||||
const modal = document.getElementById("analysisModal");
|
const modal = document.getElementById("analysisModal");
|
||||||
@ -112,8 +584,24 @@
|
|||||||
if (matrixLabelEl) {
|
if (matrixLabelEl) {
|
||||||
matrixLabelEl.textContent = matrixLabel || "-";
|
matrixLabelEl.textContent = matrixLabel || "-";
|
||||||
}
|
}
|
||||||
|
analysisSelectedState = {};
|
||||||
|
|
||||||
|
const selectedPartIds = getSelectedPartIds();
|
||||||
|
selectedPartIds.forEach(function (partId) {
|
||||||
|
const assigned = Array.isArray(
|
||||||
|
analysisAssignedState[String(partId)],
|
||||||
|
)
|
||||||
|
? analysisAssignedState[String(partId)]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
assigned.forEach(function (item) {
|
||||||
|
if (item.analysis_recordkey) {
|
||||||
|
analysisSelectedState[item.analysis_recordkey] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
updateSelectedPartsInfo();
|
updateSelectedPartsInfo();
|
||||||
|
loadAnalysesByMatrix(matrixId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAnalysisSelection() {
|
function clearAnalysisSelection() {
|
||||||
@ -135,6 +623,16 @@
|
|||||||
const matrixLabelEl = modal.querySelector("#analysisCurrentMatrix");
|
const matrixLabelEl = modal.querySelector("#analysisCurrentMatrix");
|
||||||
if (matrixLabelEl) matrixLabelEl.textContent = "-";
|
if (matrixLabelEl) matrixLabelEl.textContent = "-";
|
||||||
|
|
||||||
|
const webOnlyEl = modal.querySelector("#analysisWebOnly");
|
||||||
|
if (webOnlyEl) webOnlyEl.checked = false;
|
||||||
|
|
||||||
|
const searchEl = modal.querySelector("#analysisSearchInput");
|
||||||
|
if (searchEl) searchEl.value = "";
|
||||||
|
|
||||||
|
const listEl = modal.querySelector("#analysisList");
|
||||||
|
if (listEl) listEl.innerHTML = "";
|
||||||
|
|
||||||
|
showAnalysisEmpty("Select a matrix to load analyses");
|
||||||
updateSelectedPartsInfo();
|
updateSelectedPartsInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +640,11 @@
|
|||||||
const modal = document.getElementById("analysisModal");
|
const modal = document.getElementById("analysisModal");
|
||||||
if (!modal) return;
|
if (!modal) return;
|
||||||
|
|
||||||
|
analysisLoadedCache = {};
|
||||||
|
analysisSelectedState = {};
|
||||||
|
readInitialAssignedAnalyses();
|
||||||
|
renderAssignedAnalysesForSelectedParts();
|
||||||
|
|
||||||
modal.querySelectorAll(".analysis-matrix-item").forEach((btn) => {
|
modal.querySelectorAll(".analysis-matrix-item").forEach((btn) => {
|
||||||
btn.addEventListener("click", function () {
|
btn.addEventListener("click", function () {
|
||||||
modal
|
modal
|
||||||
@ -171,6 +674,99 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const webOnlyEl = modal.querySelector("#analysisWebOnly");
|
||||||
|
if (webOnlyEl) {
|
||||||
|
webOnlyEl.addEventListener("change", function () {
|
||||||
|
filterAnalysisList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchEl = modal.querySelector("#analysisSearchInput");
|
||||||
|
if (searchEl) {
|
||||||
|
searchEl.addEventListener("input", function () {
|
||||||
|
filterAnalysisList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
modal.addEventListener("click", function (e) {
|
||||||
|
const removeBtn = e.target.closest(".analysis-remove-btn");
|
||||||
|
if (removeBtn) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const partId = removeBtn.getAttribute("data-part-id");
|
||||||
|
const recordKey = removeBtn.getAttribute("data-recordkey");
|
||||||
|
|
||||||
|
deleteAnalysisAssociation(partId, recordKey, function () {
|
||||||
|
const stillUsed = Object.keys(analysisAssignedState).some(
|
||||||
|
function (pid) {
|
||||||
|
return (
|
||||||
|
Array.isArray(analysisAssignedState[pid]) &&
|
||||||
|
analysisAssignedState[pid].some(
|
||||||
|
function (item) {
|
||||||
|
return (
|
||||||
|
item.analysis_recordkey ===
|
||||||
|
recordKey
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!stillUsed) {
|
||||||
|
delete analysisSelectedState[recordKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
syncSelectedAnalysisRows();
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const row = e.target.closest(".analysis-analysis-item");
|
||||||
|
if (!row) return;
|
||||||
|
|
||||||
|
const selectedPartIds = getSelectedPartIds();
|
||||||
|
if (!selectedPartIds.length) {
|
||||||
|
alert("Select at least one part first");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = buildAnalysisPayloadFromRow(row);
|
||||||
|
if (!payload.analysis_recordkey) {
|
||||||
|
alert("Invalid analysis record key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const recordKey = payload.analysis_recordkey;
|
||||||
|
const alreadySelected = !!analysisSelectedState[recordKey];
|
||||||
|
|
||||||
|
if (alreadySelected) {
|
||||||
|
selectedPartIds.forEach(function (partId) {
|
||||||
|
deleteAnalysisAssociation(partId, recordKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
delete analysisSelectedState[recordKey];
|
||||||
|
syncSelectedAnalysisRows();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pending = selectedPartIds.length;
|
||||||
|
let atLeastOneSaved = false;
|
||||||
|
|
||||||
|
selectedPartIds.forEach(function (partId) {
|
||||||
|
saveAnalysisAssociation(partId, payload, function (ok) {
|
||||||
|
if (ok) atLeastOneSaved = true;
|
||||||
|
|
||||||
|
pending--;
|
||||||
|
if (pending <= 0 && atLeastOneSaved) {
|
||||||
|
analysisSelectedState[recordKey] = true;
|
||||||
|
syncSelectedAnalysisRows();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const firstActiveMatrix = modal.querySelector(
|
const firstActiveMatrix = modal.querySelector(
|
||||||
".analysis-matrix-item.active",
|
".analysis-matrix-item.active",
|
||||||
);
|
);
|
||||||
|
|||||||
3202
public/userarea/cronfiles/debug_log.txt
Normal file
3202
public/userarea/cronfiles/debug_log.txt
Normal file
File diff suppressed because it is too large
Load Diff
1
public/userarea/cronfiles/last_url.txt
Normal file
1
public/userarea/cronfiles/last_url.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://93.43.5.102/limsapi/api/odata/Matrice
|
||||||
25589
public/userarea/cronfiles/matrici_response.json
Normal file
25589
public/userarea/cronfiles/matrici_response.json
Normal file
File diff suppressed because it is too large
Load Diff
1
public/userarea/cronfiles/success_log.txt
Normal file
1
public/userarea/cronfiles/success_log.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
2026-04-03 10:07:01 - Aggiornamento completato: 3198 record inseriti.
|
||||||
48
public/userarea/delete_part_analysis.php
Normal file
48
public/userarea/delete_part_analysis.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once __DIR__ . '/class/db-functions.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$partId = isset($_POST['part_id']) ? (int)$_POST['part_id'] : 0;
|
||||||
|
$analysisRecordkey = trim($_POST['analysis_recordkey'] ?? '');
|
||||||
|
|
||||||
|
if ($partId <= 0 || $analysisRecordkey === '') {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Missing required data']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
DELETE FROM identification_parts_analyses
|
||||||
|
WHERE part_id = :part_id
|
||||||
|
AND analysis_recordkey = :analysis_recordkey
|
||||||
|
");
|
||||||
|
$stmt->execute([
|
||||||
|
':part_id' => $partId,
|
||||||
|
':analysis_recordkey' => $analysisRecordkey,
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Association deleted'
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
60
public/userarea/get_analisi_matrice_filter.php
Normal file
60
public/userarea/get_analisi_matrice_filter.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once dirname(__FILE__) . '/class/VisualLimsApiClient.class.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$idMatrice = isset($_GET['id_matrice']) ? (int)$_GET['id_matrice'] : 0;
|
||||||
|
$debug = isset($_GET['debug']) ? (int)$_GET['debug'] : 0;
|
||||||
|
|
||||||
|
if ($idMatrice <= 0) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => 'Missing or invalid id_matrice']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$api = VisualLimsApiClient::getInstance();
|
||||||
|
|
||||||
|
$filter = rawurlencode("Matrice/IdMatrice eq $idMatrice");
|
||||||
|
$endpoint = "Analisi?\$filter={$filter}";
|
||||||
|
|
||||||
|
$base_url = 'https://93.43.5.102/limsapi/api/odata/';
|
||||||
|
$full_url = $base_url . $endpoint;
|
||||||
|
|
||||||
|
file_put_contents(__DIR__ . '/last_url_analisi.txt', $full_url . PHP_EOL, FILE_APPEND);
|
||||||
|
|
||||||
|
$data = $api->get($endpoint, []);
|
||||||
|
|
||||||
|
file_put_contents(
|
||||||
|
__DIR__ . '/analisi_by_matrice_response.json',
|
||||||
|
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($debug === 1) {
|
||||||
|
echo json_encode([
|
||||||
|
'endpoint' => $endpoint,
|
||||||
|
'full_url' => $full_url,
|
||||||
|
'raw_response' => $data
|
||||||
|
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$analisi = $data['value'] ?? [];
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'value' => $analisi,
|
||||||
|
'count' => is_array($analisi) ? count($analisi) : 0
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
file_put_contents(
|
||||||
|
__DIR__ . '/error_log_analisi.txt',
|
||||||
|
date('Y-m-d H:i:s') . ' - ' . $e->getMessage() . PHP_EOL,
|
||||||
|
FILE_APPEND
|
||||||
|
);
|
||||||
|
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(['error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
@ -48,6 +48,38 @@ $stmt = $pdo->prepare("
|
|||||||
$stmt->execute([$iddatadb]);
|
$stmt->execute([$iddatadb]);
|
||||||
$parts = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$parts = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$partIds = array_column($parts, 'id');
|
||||||
|
$assignedAnalysesByPart = [];
|
||||||
|
|
||||||
|
if (!empty($partIds)) {
|
||||||
|
$placeholders = implode(',', array_fill(0, count($partIds), '?'));
|
||||||
|
|
||||||
|
$stmtAssigned = $pdo->prepare("
|
||||||
|
SELECT
|
||||||
|
ipa.id,
|
||||||
|
ipa.part_id,
|
||||||
|
ipa.analysis_recordkey,
|
||||||
|
ipa.analysis_name,
|
||||||
|
ipa.analysis_method,
|
||||||
|
ipa.analysis_level,
|
||||||
|
ipa.is_web_selectable,
|
||||||
|
ipa.is_accredited
|
||||||
|
FROM identification_parts_analyses ipa
|
||||||
|
WHERE ipa.part_id IN ($placeholders)
|
||||||
|
ORDER BY ipa.analysis_name ASC, ipa.id ASC
|
||||||
|
");
|
||||||
|
$stmtAssigned->execute($partIds);
|
||||||
|
$assignedRows = $stmtAssigned->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
foreach ($assignedRows as $row) {
|
||||||
|
$partId = (int)$row['part_id'];
|
||||||
|
if (!isset($assignedAnalysesByPart[$partId])) {
|
||||||
|
$assignedAnalysesByPart[$partId] = [];
|
||||||
|
}
|
||||||
|
$assignedAnalysesByPart[$partId][] = $row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build matrix groups from parts.
|
* Build matrix groups from parts.
|
||||||
* No join for now: we use idmatrice only.
|
* No join for now: we use idmatrice only.
|
||||||
@ -198,7 +230,9 @@ $matrixGroups = array_values($matrixGroups);
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="analysis-part-assigned-list mt-2" id="analysisAssignedListPart<?= (int)$part['id'] ?>"></div>
|
||||||
</div>
|
</div>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@ -214,34 +248,50 @@ $matrixGroups = array_values($matrixGroups);
|
|||||||
<strong>Analyses</strong>
|
<strong>Analyses</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body analysis-scroll-area" id="analysisRightPanel">
|
<div class="card-body analysis-scroll-area" id="analysisRightPanel">
|
||||||
<div class="alert alert-info mb-3">
|
<div class="mt-1 mb-3">
|
||||||
This area will contain analyses in the next step.
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="border rounded p-3 bg-light">
|
|
||||||
<div class="mb-2"><strong>Current behavior</strong></div>
|
|
||||||
<ul class="mb-0 ps-3">
|
|
||||||
<li>Click a matrix on the left</li>
|
|
||||||
<li>All parts linked to that matrix become selected</li>
|
|
||||||
<li>Analyses panel will be connected later</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3">
|
|
||||||
<div class="small text-muted">Selected matrix:</div>
|
<div class="small text-muted">Selected matrix:</div>
|
||||||
<div id="analysisCurrentMatrix" class="fw-semibold">-</div>
|
<div id="analysisCurrentMatrix" class="fw-semibold">-</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3">
|
<div class="mb-3">
|
||||||
<div class="small text-muted">Selected parts IDs:</div>
|
<div class="small text-muted">Selected parts IDs:</div>
|
||||||
<div id="analysisSelectedPartsIds" class="fw-semibold">-</div>
|
<div id="analysisSelectedPartsIds" class="fw-semibold">-</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex flex-wrap align-items-center gap-2 mb-3">
|
||||||
|
<div class="form-check m-0">
|
||||||
|
<input class="form-check-input" type="checkbox" id="analysisWebOnly">
|
||||||
|
<label class="form-check-label small" for="analysisWebOnly">
|
||||||
|
Web only
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-grow-1" style="min-width: 220px;">
|
||||||
|
<input type="text" class="form-control form-control-sm" id="analysisSearchInput" placeholder="Search analyses or method">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="analysisLoadingBox" class="alert alert-info mb-3 d-none">
|
||||||
|
Loading analyses...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="analysisErrorBox" class="alert alert-danger mb-3 d-none"></div>
|
||||||
|
|
||||||
|
<div id="analysisEmptyBox" class="alert alert-secondary mb-3">
|
||||||
|
Select a matrix to load analyses
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="list-group" id="analysisList"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="hidden" id="analysisModalIddatadb" value="<?= (int)$iddatadb ?>">
|
<input type="hidden" id="analysisModalIddatadb" value="<?= (int)$iddatadb ?>">
|
||||||
|
|
||||||
|
<script type="application/json" id="analysisAssignedInitialData">
|
||||||
|
<?= json_encode($assignedAnalysesByPart, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@ -301,4 +351,75 @@ $matrixGroups = array_values($matrixGroups);
|
|||||||
#analysisSelectedPartsIds {
|
#analysisSelectedPartsIds {
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.analysis-analysis-item {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#analysisList .analysis-analysis-item:nth-child(even) {
|
||||||
|
background-color: #eef4ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-analysis-meta {
|
||||||
|
font-size: 0.84rem;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-analysis-badges .badge {
|
||||||
|
margin-right: 4px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-assigned-chip {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: 1px solid #dbe7f3;
|
||||||
|
background: #f7fbff;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-size: 0.84rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-assigned-chip-text {
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-assigned-chip-title {
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-assigned-chip-method {
|
||||||
|
color: #6c757d;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-remove-btn {
|
||||||
|
border: 0;
|
||||||
|
background: transparent;
|
||||||
|
color: #dc3545;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 0 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-analysis-item.analysis-selected {
|
||||||
|
border-color: #198754 !important;
|
||||||
|
background-color: #eaf7ea !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-part-assigned-list {
|
||||||
|
border-top: 1px dashed #dee2e6;
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
90
public/userarea/save_part_analysis.php
Normal file
90
public/userarea/save_part_analysis.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
require_once __DIR__ . '/class/db-functions.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
ini_set('display_errors', '0');
|
||||||
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$partId = isset($_POST['part_id']) ? (int)$_POST['part_id'] : 0;
|
||||||
|
$iddatadb = isset($_POST['iddatadb']) ? (int)$_POST['iddatadb'] : 0;
|
||||||
|
$idmatrice = isset($_POST['idmatrice']) ? (int)$_POST['idmatrice'] : 0;
|
||||||
|
$analysisRecordkey = trim($_POST['analysis_recordkey'] ?? '');
|
||||||
|
$analysisName = trim($_POST['analysis_name'] ?? '');
|
||||||
|
$analysisMethod = trim($_POST['analysis_method'] ?? '');
|
||||||
|
$analysisLevel = isset($_POST['analysis_level']) && $_POST['analysis_level'] !== '' ? (int)$_POST['analysis_level'] : null;
|
||||||
|
$isWebSelectable = isset($_POST['is_web_selectable']) ? (int)$_POST['is_web_selectable'] : 0;
|
||||||
|
$isAccredited = isset($_POST['is_accredited']) ? (int)$_POST['is_accredited'] : 0;
|
||||||
|
|
||||||
|
if ($partId <= 0 || $analysisRecordkey === '') {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Missing required data']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
INSERT INTO identification_parts_analyses (
|
||||||
|
part_id,
|
||||||
|
iddatadb,
|
||||||
|
idmatrice,
|
||||||
|
analysis_recordkey,
|
||||||
|
analysis_name,
|
||||||
|
analysis_method,
|
||||||
|
analysis_level,
|
||||||
|
is_web_selectable,
|
||||||
|
is_accredited
|
||||||
|
) VALUES (
|
||||||
|
:part_id,
|
||||||
|
:iddatadb,
|
||||||
|
:idmatrice,
|
||||||
|
:analysis_recordkey,
|
||||||
|
:analysis_name,
|
||||||
|
:analysis_method,
|
||||||
|
:analysis_level,
|
||||||
|
:is_web_selectable,
|
||||||
|
:is_accredited
|
||||||
|
)
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
analysis_name = VALUES(analysis_name),
|
||||||
|
analysis_method = VALUES(analysis_method),
|
||||||
|
analysis_level = VALUES(analysis_level),
|
||||||
|
is_web_selectable = VALUES(is_web_selectable),
|
||||||
|
is_accredited = VALUES(is_accredited),
|
||||||
|
iddatadb = VALUES(iddatadb),
|
||||||
|
idmatrice = VALUES(idmatrice),
|
||||||
|
updated_at = CURRENT_TIMESTAMP
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
':part_id' => $partId,
|
||||||
|
':iddatadb' => $iddatadb ?: null,
|
||||||
|
':idmatrice' => $idmatrice ?: null,
|
||||||
|
':analysis_recordkey' => $analysisRecordkey,
|
||||||
|
':analysis_name' => $analysisName ?: null,
|
||||||
|
':analysis_method' => $analysisMethod ?: null,
|
||||||
|
':analysis_level' => $analysisLevel,
|
||||||
|
':is_web_selectable' => $isWebSelectable,
|
||||||
|
':is_accredited' => $isAccredited,
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Association saved'
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user