Support multi-page PDFs for more than 3 selected checks
- pdfService: batch checks into groups of 3, add doc.addPage() between groups - pdf route: remove 1-3 limit, accept any number of check IDs - Frontend: remove 3-check selection cap; any number of checks can be selected
This commit is contained in:
+1
-15
@@ -70,7 +70,6 @@ function renderTable() {
|
||||
|
||||
tbody.innerHTML = checks.map(renderRow).join('');
|
||||
updateSortIndicators();
|
||||
updateCheckboxStates();
|
||||
|
||||
// Attach row-level event listeners
|
||||
tbody.querySelectorAll('input[type="checkbox"]').forEach(cb => {
|
||||
@@ -157,14 +156,6 @@ function updateSortIndicators() {
|
||||
});
|
||||
}
|
||||
|
||||
function updateCheckboxStates() {
|
||||
document.querySelectorAll('#checks-tbody input[type="checkbox"]').forEach(cb => {
|
||||
const id = parseInt(cb.dataset.id, 10);
|
||||
if (!state.selected.has(id)) {
|
||||
cb.disabled = state.selected.size >= 3;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function refreshPdfButton() {
|
||||
const n = state.selected.size;
|
||||
@@ -178,16 +169,11 @@ function refreshPdfButton() {
|
||||
function onCheckboxChange(cb) {
|
||||
const id = parseInt(cb.dataset.id, 10);
|
||||
if (cb.checked) {
|
||||
if (state.selected.size >= 3) {
|
||||
cb.checked = false;
|
||||
return;
|
||||
}
|
||||
state.selected.add(id);
|
||||
} else {
|
||||
state.selected.delete(id);
|
||||
}
|
||||
refreshPdfButton();
|
||||
updateCheckboxStates();
|
||||
}
|
||||
|
||||
// ── Slide-in panel ───────────────────────────────────────────────────────────
|
||||
@@ -298,7 +284,7 @@ async function deleteCheck(id) {
|
||||
|
||||
async function generatePdf() {
|
||||
const ids = [...state.selected];
|
||||
if (ids.length === 0 || ids.length > 3) return;
|
||||
if (ids.length === 0) return;
|
||||
|
||||
const btn = document.getElementById('btn-generate-pdf');
|
||||
btn.disabled = true;
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@ const { generateCheckPdf } = require('../services/pdfService');
|
||||
router.post('/', async (req, res) => {
|
||||
const { checkIds } = req.body;
|
||||
|
||||
if (!Array.isArray(checkIds) || checkIds.length === 0 || checkIds.length > 3) {
|
||||
return res.status(400).json({ error: 'checkIds must be an array of 1–3 IDs' });
|
||||
if (!Array.isArray(checkIds) || checkIds.length === 0) {
|
||||
return res.status(400).json({ error: 'checkIds must be a non-empty array' });
|
||||
}
|
||||
|
||||
// Fetch account
|
||||
|
||||
@@ -88,7 +88,7 @@ function formatMicrLine(routingNo, accountNo, checkNo) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Main export: generates a PDF buffer for 1–3 checks.
|
||||
* Main export: generates a multi-page PDF buffer for any number of checks (3 per page).
|
||||
*
|
||||
* @param {Object} account - Account row from database
|
||||
* @param {Array} checks - Array of 1–3 check rows from database
|
||||
@@ -128,14 +128,17 @@ function generateCheckPdf(account, checks, fields) {
|
||||
const hasUsableLogo = !!(logoField && account.logo_data);
|
||||
const COMPANY_FIELDS = new Set(['Company Name', 'Company Name2', 'Company Name3', 'Company Name4']);
|
||||
|
||||
// We always render 3 slots; empty slots get a blank placeholder
|
||||
for (let slot = 0; slot < 3; slot++) {
|
||||
const check = checks[slot] || null;
|
||||
const slotOriginY = slot * SLOT_HEIGHT_IN;
|
||||
const offX = (account.offset_right - account.offset_left);
|
||||
const offY = (account.offset_down - account.offset_up);
|
||||
|
||||
// Offset adjustments from account calibration
|
||||
const offX = (account.offset_right - account.offset_left);
|
||||
const offY = (account.offset_down - account.offset_up);
|
||||
// Render checks in pages of 3; add a new page for each additional group
|
||||
const pages = Math.ceil(checks.length / 3);
|
||||
for (let page = 0; page < pages; page++) {
|
||||
if (page > 0) doc.addPage();
|
||||
|
||||
for (let slot = 0; slot < 3; slot++) {
|
||||
const check = checks[page * 3 + slot] || null;
|
||||
const slotOriginY = slot * SLOT_HEIGHT_IN;
|
||||
|
||||
// Helper: convert inches (relative to slot) to PDF points (absolute page)
|
||||
const pt = (xIn, yIn) => ({
|
||||
@@ -220,7 +223,8 @@ function generateCheckPdf(account, checks, fields) {
|
||||
.text(micrLine, micrPos.x, micrPos.y, { lineBreak: false });
|
||||
}
|
||||
|
||||
}
|
||||
} // end slot loop
|
||||
} // end page loop
|
||||
|
||||
doc.end();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user