Punching, Dedupe and CutOff Features Done
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
(() => {
|
||||
"use strict";
|
||||
|
||||
const form = document.getElementById("dedupeWorkspace");
|
||||
const portfolio = document.getElementById("portfolioId");
|
||||
const table = document.getElementById("dedupeCaseTable");
|
||||
if (!form || !portfolio || !table) return;
|
||||
|
||||
portfolio.addEventListener("change", () => form.requestSubmit());
|
||||
|
||||
const openCase = (row) => {
|
||||
const caseId = row?.dataset.caseId;
|
||||
if (!caseId) return;
|
||||
const contextPath = document.body.dataset.contextPath || "";
|
||||
const url = `${contextPath}/ver/dedupefound?uuid=${encodeURIComponent(caseId)}`;
|
||||
const dialog = window.MatrixFrameDialog;
|
||||
if (!dialog?.open) {
|
||||
window.location.assign(url);
|
||||
return;
|
||||
}
|
||||
dialog.open(url, "Dedupe Details").then((result) => {
|
||||
if (Number(result) === 1) row.remove();
|
||||
});
|
||||
};
|
||||
|
||||
table.addEventListener("click", (event) =>
|
||||
openCase(event.target.closest("tr[data-case-id]")));
|
||||
table.addEventListener("keydown", (event) => {
|
||||
if (event.key === "Enter" || event.key === " ") {
|
||||
event.preventDefault();
|
||||
openCase(event.target.closest("tr[data-case-id]"));
|
||||
}
|
||||
});
|
||||
})();
|
||||
101
cygnus-onprem-app/build/WebContent/js/edp/dedupe/dedupe-match.js
Normal file
101
cygnus-onprem-app/build/WebContent/js/edp/dedupe/dedupe-match.js
Normal file
@@ -0,0 +1,101 @@
|
||||
(() => {
|
||||
"use strict";
|
||||
|
||||
const form = document.getElementById("dedupeDetails");
|
||||
if (!form) return;
|
||||
|
||||
const state = { EAR: { rows: [], index: 0 }, NEG: { rows: [], index: 0 } };
|
||||
const value = (id, next) => {
|
||||
const element = document.getElementById(id);
|
||||
if (element && next !== undefined) element.value = next || "";
|
||||
return element?.value || "";
|
||||
};
|
||||
const notify = (type, message, code, referenceId) =>
|
||||
window.CygnusNotifications?.show({ type, message, code, referenceId });
|
||||
|
||||
function address(record) {
|
||||
return record?.residenceAddress || record?.officeAddress || "";
|
||||
}
|
||||
|
||||
function render(type) {
|
||||
const group = state[type];
|
||||
const prefix = type === "EAR" ? "ear" : "neg";
|
||||
const record = group.rows[group.index];
|
||||
document.getElementById(type === "EAR" ? "efound" : "nfound").textContent =
|
||||
group.rows.length ? `(${group.index + 1} / ${group.rows.length} Match Found)` : "(No Match Found)";
|
||||
document.getElementById(type === "EAR" ? "efoundon" : "nfoundon").textContent =
|
||||
record ? `Match Found On: ${record.foundOn || ""}` : "No Match Found";
|
||||
value(`${prefix}name`, record?.customerName);
|
||||
value(`${prefix}dob`, record?.dob);
|
||||
value(`${prefix}address`, record ? address(record) : "");
|
||||
value(`${prefix}rphone`, record?.residencePhone);
|
||||
value(`${prefix}ophone`, record?.officePhone);
|
||||
value(`${prefix}mobile`, record?.mobile);
|
||||
}
|
||||
|
||||
async function load() {
|
||||
const uuid = value("uuid");
|
||||
try {
|
||||
const response = await fetch(`${form.dataset.recordsUrl}?uuid=${encodeURIComponent(uuid)}`, {
|
||||
credentials: "same-origin", headers: { Accept: "application/json" }
|
||||
});
|
||||
const payload = await response.json();
|
||||
if (!response.ok || !payload.success) throw payload.message || {};
|
||||
state.EAR.rows = payload.data.filter((row) => row.dedupeType === "EAR");
|
||||
state.NEG.rows = payload.data.filter((row) => row.dedupeType === "NEG");
|
||||
render("EAR");
|
||||
render("NEG");
|
||||
} catch (error) {
|
||||
notify("danger", error.message || "Matching records could not be loaded.", error.code, error.referenceId);
|
||||
}
|
||||
}
|
||||
|
||||
window.findRecord = (operation, section) => {
|
||||
const group = state[section === 1 ? "EAR" : "NEG"];
|
||||
if (!group.rows.length) return;
|
||||
if (operation === 1) group.index = 0;
|
||||
if (operation === 2) group.index = Math.max(0, group.index - 1);
|
||||
if (operation === 3) group.index = Math.min(group.rows.length - 1, group.index + 1);
|
||||
if (operation === 4) group.index = group.rows.length - 1;
|
||||
render(section === 1 ? "EAR" : "NEG");
|
||||
};
|
||||
|
||||
window.addRemarks = (section, elementId) => {
|
||||
const group = state[section === 1 ? "EAR" : "NEG"];
|
||||
const record = group.rows[group.index];
|
||||
if (!record) return notify("warning", "No match found.", "DDP-4001");
|
||||
const current = value(elementId).trim();
|
||||
value(elementId, `${current}${current ? "\n\n" : ""}${record.remarks || ""}`);
|
||||
};
|
||||
|
||||
window.editRemarks = (elementId, section) => {
|
||||
const group = state[section === 1 ? "EAR" : "NEG"];
|
||||
const remarks = group.rows[group.index]?.remarks;
|
||||
if (remarks && window.confirm("Remove the selected match remarks?")) {
|
||||
value(elementId, value(elementId).replace(remarks, "").trim());
|
||||
}
|
||||
};
|
||||
|
||||
form.addEventListener("submit", async (event) => {
|
||||
event.preventDefault();
|
||||
const body = {
|
||||
uuid: value("uuid"), sessuuid: value("sessuuid"),
|
||||
earremarks: value("earremarks"), negremarks: value("negremarks")
|
||||
};
|
||||
try {
|
||||
const response = await fetch(form.action, {
|
||||
method: "POST", credentials: "same-origin",
|
||||
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
const payload = await response.json();
|
||||
if (!response.ok || !payload.success) throw payload.message || {};
|
||||
notify("success", payload.message.message, payload.message.code);
|
||||
window.setTimeout(() => window.MatrixDialog?.close(1), 300);
|
||||
} catch (error) {
|
||||
notify("danger", error.message || "Dedupe details could not be saved.", error.code, error.referenceId);
|
||||
}
|
||||
});
|
||||
|
||||
load();
|
||||
})();
|
||||
127
cygnus-onprem-app/build/WebContent/js/edp/dedupe/dedupe-run.js
Normal file
127
cygnus-onprem-app/build/WebContent/js/edp/dedupe/dedupe-run.js
Normal file
@@ -0,0 +1,127 @@
|
||||
(function (window, document) {
|
||||
"use strict";
|
||||
|
||||
const endpoint = "/matrix/ver/checkdedupe";
|
||||
const operations = [
|
||||
{ id: 1, field: "earlier", label: "Earlier" },
|
||||
{ id: 2, field: "negative", label: "Negative" }
|
||||
];
|
||||
|
||||
function expandList(id) {
|
||||
const child = document.getElementById(`${id}child`);
|
||||
if (child) child.style.display = child.style.display === "none" ? "table-row" : "none";
|
||||
}
|
||||
|
||||
function notify(type, code, message) {
|
||||
window.CygnusNotifications?.show({ type, code, message, duration: 5000 });
|
||||
}
|
||||
|
||||
function createProgress(label) {
|
||||
const group = document.createElement("div");
|
||||
group.className = "mb-3";
|
||||
group.innerHTML = `<div class="d-flex justify-content-between mb-1"><strong>${label}</strong><span>Waiting</span></div>
|
||||
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100">
|
||||
<div class="progress-bar" style="width:0%"></div>
|
||||
</div>`;
|
||||
return group;
|
||||
}
|
||||
|
||||
function createDialog() {
|
||||
document.getElementById("dedupe-run-modal")?.remove();
|
||||
const root = document.createElement("div");
|
||||
root.id = "dedupe-run-modal";
|
||||
root.className = "modal fade";
|
||||
root.tabIndex = -1;
|
||||
root.innerHTML = `<div class="modal-dialog modal-dialog-centered"><div class="modal-content">
|
||||
<div class="modal-header"><h5 class="modal-title">Checking Earlier and Negative</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div>
|
||||
<div class="modal-body"></div><div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="button" class="btn btn-primary js-start">Start</button></div></div></div>`;
|
||||
const body = root.querySelector(".modal-body");
|
||||
operations.forEach(operation => body.append(createProgress(operation.label)));
|
||||
document.body.append(root);
|
||||
return root;
|
||||
}
|
||||
|
||||
function updateProgress(container, processed, total, counters) {
|
||||
const percent = total === 0 ? 100 : Math.round((processed / total) * 100);
|
||||
container.querySelector(".progress-bar").style.width = `${percent}%`;
|
||||
container.querySelector("span").textContent =
|
||||
`${processed}/${total} | Success ${counters.success} | Failed ${counters.failed} | Skipped ${counters.skipped}`;
|
||||
}
|
||||
|
||||
async function check(row, operation) {
|
||||
const response = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRF-TOKEN": document.getElementById("dedupe-csrf-token")?.value || ""
|
||||
},
|
||||
body: JSON.stringify({
|
||||
documentCaseId: row.dataset.documentCaseId,
|
||||
operation: operation.id
|
||||
})
|
||||
});
|
||||
const payload = await response.json().catch(() => null);
|
||||
if (!response.ok || !payload?.success) {
|
||||
throw new Error(payload?.message?.message || "Dedupe check failed");
|
||||
}
|
||||
}
|
||||
|
||||
async function runOperation(rows, operation, progress) {
|
||||
const counters = { success: 0, failed: 0, skipped: 0 };
|
||||
for (let index = 0; index < rows.length; index += 1) {
|
||||
const row = rows[index];
|
||||
const statusCell = row.querySelector(`td[id$="${operation.field === "earlier" ? "ear" : "neg"}"]`);
|
||||
if (row.dataset[operation.field] !== "Y") {
|
||||
counters.skipped += 1;
|
||||
} else {
|
||||
try {
|
||||
await check(row, operation);
|
||||
counters.success += 1;
|
||||
row.dataset[operation.field] = "D";
|
||||
if (statusCell) {
|
||||
statusCell.textContent = "D";
|
||||
statusCell.classList.add("table-success");
|
||||
}
|
||||
} catch (error) {
|
||||
counters.failed += 1;
|
||||
if (statusCell) {
|
||||
statusCell.textContent = "F";
|
||||
statusCell.title = error.message;
|
||||
statusCell.classList.add("table-danger");
|
||||
}
|
||||
}
|
||||
}
|
||||
updateProgress(progress, index + 1, rows.length, counters);
|
||||
}
|
||||
return counters;
|
||||
}
|
||||
|
||||
async function run(tableId, modalRoot) {
|
||||
const rows = Array.from(document.querySelectorAll(`#${CSS.escape(tableId)} tbody tr[data-document-case-id]`));
|
||||
if (rows.length === 0) {
|
||||
notify("info", "DDP-2002", "The selected list has no records to process.");
|
||||
return;
|
||||
}
|
||||
const start = modalRoot.querySelector(".js-start");
|
||||
start.disabled = true;
|
||||
const progress = modalRoot.querySelectorAll(".modal-body > div");
|
||||
for (let index = 0; index < operations.length; index += 1) {
|
||||
await runOperation(rows, operations[index], progress[index]);
|
||||
}
|
||||
start.disabled = false;
|
||||
notify("success", "DDP-2001", "Earlier and negative dedupe checks completed.");
|
||||
}
|
||||
|
||||
document.addEventListener("click", event => {
|
||||
const runButton = event.target.closest(".js-run-dedupe");
|
||||
if (!runButton) return;
|
||||
const modalRoot = createDialog();
|
||||
modalRoot.querySelector(".js-start").addEventListener("click", () => run(runButton.dataset.table, modalRoot));
|
||||
window.bootstrap.Modal.getOrCreateInstance(modalRoot).show();
|
||||
});
|
||||
|
||||
window.ExpandList = expandList;
|
||||
}(window, document));
|
||||
@@ -0,0 +1,42 @@
|
||||
(() => {
|
||||
"use strict";
|
||||
const form = document.getElementById("senddedupe");
|
||||
const table = document.getElementById("casetobesend");
|
||||
const portfolio = document.getElementById("portlist");
|
||||
const generate = document.getElementById("btngenreport");
|
||||
if (!form || !table || !portfolio) return;
|
||||
|
||||
const checks = () => [...table.querySelectorAll('tbody input[type="checkbox"]')];
|
||||
const sync = () => {
|
||||
const selected = checks().filter((item) => item.checked);
|
||||
document.getElementById("hfdelstat").value = selected.map((item) => item.value).join(",");
|
||||
document.getElementById("selall").checked = selected.length > 0 && selected.length === checks().length;
|
||||
};
|
||||
|
||||
portfolio.addEventListener("change", () => {
|
||||
form.action = form.dataset.listUrl;
|
||||
form.requestSubmit();
|
||||
});
|
||||
document.getElementById("selall")?.addEventListener("change", (event) => {
|
||||
checks().forEach((item) => { item.checked = event.target.checked; });
|
||||
sync();
|
||||
});
|
||||
table.addEventListener("change", sync);
|
||||
table.addEventListener("click", (event) => {
|
||||
const row = event.target.closest("tr[data-case-id]");
|
||||
if (row && event.target.type !== "checkbox") row.querySelector('input[type="checkbox"]')?.click();
|
||||
});
|
||||
generate?.addEventListener("click", () => {
|
||||
sync();
|
||||
if (!document.getElementById("hfdelstat").value) {
|
||||
window.CygnusNotifications?.show({
|
||||
type: "warning", code: "DDP-4002", message: "Select at least one application."
|
||||
});
|
||||
return;
|
||||
}
|
||||
form.action = form.dataset.generateUrl;
|
||||
form.requestSubmit();
|
||||
});
|
||||
if (!checks().length) generate?.setAttribute("hidden", "hidden");
|
||||
sync();
|
||||
})();
|
||||
Reference in New Issue
Block a user