mirror of
https://github.com/kbenestad/invoice.git
synced 2026-06-18 08:04:32 +00:00
Swap Invoice details / Payment positions; bank fields only for Other
- New layout: Sender | Invoice details (top row), Charge to | Payment (bottom row) - Bank account fields (#bank-section) are hidden by default and only revealed when "Other" is selected for charge-to; hidden again for predefined recipients - gatherData() only collects bank fields when bank-section is visible - Preview and PDF panels updated to match the new quadrant order https://claude.ai/code/session_015iyCBgoTXNNqaErR287U1u
This commit is contained in:
parent
275d3a3b71
commit
a63fcc8a42
1 changed files with 108 additions and 101 deletions
201
app/index.html
201
app/index.html
|
|
@ -507,27 +507,23 @@ function buildForm() {
|
|||
<input id="se" type="email" data-ls="se" autocomplete="email"></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title" id="lbl-pay-sec">${t("payment")}</div>
|
||||
<div class="pay-terms-row">
|
||||
<label id="lbl-pterm">${t("payment-terms")}:</label>
|
||||
<input id="pterm" type="number" min="0" value="7" oninput="calcPayBy()" data-ls="pterm">
|
||||
<span id="lbl-days">${t("payment-days")}</span>
|
||||
<div class="card-title" id="sec-invdet">${t("invoice-details-section")}</div>
|
||||
<div class="fg"><label id="lbl-idate" for="idate">${t("invoice-date")}</label>
|
||||
<input id="idate" type="date" value="${dateDef}"></div>
|
||||
<div class="fg"><label id="lbl-icur" for="icur">${t("invoice-currency")}</label>
|
||||
<select id="icur" data-ls="icur">${curOpts}</select></div>
|
||||
<div class="fg"><label id="lbl-pcode" for="pcode">${t("project-code")}</label>
|
||||
<select id="pcode">
|
||||
<option value="">${t("select")}</option>
|
||||
${pcOpts}
|
||||
<option value="__other__">${t("other")}</option>
|
||||
</select></div>
|
||||
<div class="fg" id="pcode-other-wrap" style="display:none">
|
||||
<label id="lbl-pcode-other" for="pcode-other">${t("project-code")} (${t("other")})</label>
|
||||
<input id="pcode-other" type="text">
|
||||
</div>
|
||||
<div class="pay-by-row">
|
||||
<label id="lbl-paybyl">${t("pay-by")}:</label>
|
||||
<span id="paybydisp"></span>
|
||||
</div>
|
||||
<div class="fg"><label id="lbl-pacct">${t("account-holder")}</label>
|
||||
<input id="pacct" type="text" data-ls="pacct"></div>
|
||||
<div class="fg"><label id="lbl-piban">${t("account-no")}</label>
|
||||
<input id="piban" type="text" data-ls="piban"></div>
|
||||
<div class="fg"><label id="lbl-pbic">${t("bank-bic")}</label>
|
||||
<input id="pbic" type="text" data-ls="pbic"></div>
|
||||
<div class="fg"><label id="lbl-pbadr">${t("bank-address")}</label>
|
||||
<input id="pbadr1" type="text" data-ls="pbadr1">
|
||||
<input id="pbadr2" type="text" style="margin-top:6px" data-ls="pbadr2"></div>
|
||||
<div class="fg"><label id="lbl-pref">${t("payment-ref")}</label>
|
||||
<input id="pref" type="text" data-ls="pref"></div>
|
||||
<div class="fg"><label id="lbl-ino" for="ino">${t("invoice-no")}</label>
|
||||
<input id="ino" type="text" data-ls="ino"></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title" style="display:flex;align-items:center;gap:8px;flex-wrap:wrap">
|
||||
|
|
@ -562,23 +558,29 @@ function buildForm() {
|
|||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title" id="sec-invdet">${t("invoice-details-section")}</div>
|
||||
<div class="fg"><label id="lbl-idate" for="idate">${t("invoice-date")}</label>
|
||||
<input id="idate" type="date" value="${dateDef}"></div>
|
||||
<div class="fg"><label id="lbl-icur" for="icur">${t("invoice-currency")}</label>
|
||||
<select id="icur" data-ls="icur">${curOpts}</select></div>
|
||||
<div class="fg"><label id="lbl-pcode" for="pcode">${t("project-code")}</label>
|
||||
<select id="pcode">
|
||||
<option value="">${t("select")}</option>
|
||||
${pcOpts}
|
||||
<option value="__other__">${t("other")}</option>
|
||||
</select></div>
|
||||
<div class="fg" id="pcode-other-wrap" style="display:none">
|
||||
<label id="lbl-pcode-other" for="pcode-other">${t("project-code")} (${t("other")})</label>
|
||||
<input id="pcode-other" type="text">
|
||||
<div class="card-title" id="lbl-pay-sec">${t("payment")}</div>
|
||||
<div class="pay-terms-row">
|
||||
<label id="lbl-pterm">${t("payment-terms")}:</label>
|
||||
<input id="pterm" type="number" min="0" value="7" oninput="calcPayBy()" data-ls="pterm">
|
||||
<span id="lbl-days">${t("payment-days")}</span>
|
||||
</div>
|
||||
<div class="pay-by-row">
|
||||
<label id="lbl-paybyl">${t("pay-by")}:</label>
|
||||
<span id="paybydisp"></span>
|
||||
</div>
|
||||
<div id="bank-section" style="display:none">
|
||||
<div class="fg"><label id="lbl-pacct">${t("account-holder")}</label>
|
||||
<input id="pacct" type="text" data-ls="pacct"></div>
|
||||
<div class="fg"><label id="lbl-piban">${t("account-no")}</label>
|
||||
<input id="piban" type="text" data-ls="piban"></div>
|
||||
<div class="fg"><label id="lbl-pbic">${t("bank-bic")}</label>
|
||||
<input id="pbic" type="text" data-ls="pbic"></div>
|
||||
<div class="fg"><label id="lbl-pbadr">${t("bank-address")}</label>
|
||||
<input id="pbadr1" type="text" data-ls="pbadr1">
|
||||
<input id="pbadr2" type="text" style="margin-top:6px" data-ls="pbadr2"></div>
|
||||
<div class="fg"><label id="lbl-pref">${t("payment-ref")}</label>
|
||||
<input id="pref" type="text" data-ls="pref"></div>
|
||||
</div>
|
||||
<div class="fg"><label id="lbl-ino" for="ino">${t("invoice-no")}</label>
|
||||
<input id="ino" type="text" data-ls="ino"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -645,6 +647,9 @@ function fillChargeTo(v) {
|
|||
const f = (id, val) => { const el = document.getElementById(id); if (el) el.value = val ?? ""; };
|
||||
const fields = document.getElementById("ct-fields");
|
||||
|
||||
const bsec = document.getElementById("bank-section");
|
||||
if (bsec) bsec.style.display = v === "__other__" ? "" : "none";
|
||||
|
||||
if (v === "" || v === "__other__") {
|
||||
if (v === "") ["ctn","ca1","ca2","ca3","ca4","cc","cph","cem","cvat","creg"].forEach(id => f(id, ""));
|
||||
fields?.classList.remove("locked");
|
||||
|
|
@ -1043,12 +1048,14 @@ function gatherData(renderLang) {
|
|||
|
||||
const pTerm = parseInt(document.getElementById("pterm")?.value) || 0;
|
||||
const pPayBy = document.getElementById("paybydisp")?.textContent || "";
|
||||
const pAcct = g("pacct");
|
||||
const pIban = g("piban");
|
||||
const pBic = g("pbic");
|
||||
const pBadr1 = g("pbadr1");
|
||||
const pBadr2 = g("pbadr2");
|
||||
const pRef = g("pref");
|
||||
const bsecEl = document.getElementById("bank-section");
|
||||
const bankVis = bsecEl && bsecEl.style.display !== "none";
|
||||
const pAcct = bankVis ? g("pacct") : "";
|
||||
const pIban = bankVis ? g("piban") : "";
|
||||
const pBic = bankVis ? g("pbic") : "";
|
||||
const pBadr1 = bankVis ? g("pbadr1"): "";
|
||||
const pBadr2 = bankVis ? g("pbadr2"): "";
|
||||
const pRef = bankVis ? g("pref") : "";
|
||||
const hasBank = !!(pAcct || pIban || pBic || pBadr1 || pRef);
|
||||
const hidePaymentOut = cfg["hide-payment-info"] === true || cfg["hide-payment-info"] === "yes";
|
||||
|
||||
|
|
@ -1142,16 +1149,14 @@ function buildPreviewHTML() {
|
|||
${sPh ? `<p>${h(td("sender-phone"))}: ${h(sPh)}</p>` : ""}
|
||||
${sEm ? `<p>${h(td("sender-email"))}: ${h(sEm)}</p>` : ""}
|
||||
</div>
|
||||
<div class="d-tr d-pay-hdr">
|
||||
<div class="ph-lbl">${h(td("payment"))}</div>
|
||||
${pTerm > 0 ? `<div class="ph-terms">${h(td("payment-terms"))}: <strong>${pTerm}</strong> ${h(td("payment-days"))}${pPayBy ? ` — ${h(td("pay-by"))}: <strong>${h(pPayBy)}</strong>` : ""}</div>` : ""}
|
||||
${showBank ? `<div class="ph-grid">
|
||||
${pAcct ? `<span class="pl">${h(td("account-holder"))}</span><span class="pv">${h(pAcct)}</span>` : ""}
|
||||
${pIban ? `<span class="pl">${h(td("account-no"))}</span><span class="pv">${h(pIban)}</span>` : ""}
|
||||
${pBic ? `<span class="pl">${h(td("bank-bic"))}</span><span class="pv">${h(pBic)}</span>` : ""}
|
||||
${pBadr1 || pBadr2 ? `<span class="pl">${h(td("bank-address"))}</span><span class="pv">${[pBadr1,pBadr2].filter(Boolean).map(l=>h(l)).join("<br>")}</span>` : ""}
|
||||
</div>
|
||||
${pRef ? `<div class="ph-ref">${h(td("payment-ref"))}: <strong>${h(pRef)}</strong></div>` : ""}` : ""}
|
||||
<div class="d-tr d-inv-meta">
|
||||
<h1>${h(td("invoice"))}</h1>
|
||||
<table class="d-meta">
|
||||
${iNo ? `<tr><td class="ml">${h(td("invoice-no"))}</td><td class="mv">${h(iNo)}</td></tr>` : ""}
|
||||
${iDate ? `<tr><td class="ml">${h(td("invoice-date"))}</td><td class="mv">${h(fmtDate(iDate))}</td></tr>` : ""}
|
||||
${pCode ? `<tr><td class="ml">${h(td("project-code"))}</td><td class="mv">${h(pCode)}</td></tr>` : ""}
|
||||
${iCur ? `<tr><td class="ml">${h(td("invoice-currency"))}</td><td class="mv">${h(iCur)}</td></tr>` : ""}
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-bl d-bill">
|
||||
<div class="bt-lbl">${h(td("charge-to"))}</div>
|
||||
|
|
@ -1165,14 +1170,16 @@ function buildPreviewHTML() {
|
|||
${ctReg ? `<span><strong>${h(td("registration-no"))}:</strong> ${h(ctReg)}</span>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-br d-inv-meta">
|
||||
<h1>${h(td("invoice"))}</h1>
|
||||
<table class="d-meta">
|
||||
${iNo ? `<tr><td class="ml">${h(td("invoice-no"))}</td><td class="mv">${h(iNo)}</td></tr>` : ""}
|
||||
${iDate ? `<tr><td class="ml">${h(td("invoice-date"))}</td><td class="mv">${h(fmtDate(iDate))}</td></tr>` : ""}
|
||||
${pCode ? `<tr><td class="ml">${h(td("project-code"))}</td><td class="mv">${h(pCode)}</td></tr>` : ""}
|
||||
${iCur ? `<tr><td class="ml">${h(td("invoice-currency"))}</td><td class="mv">${h(iCur)}</td></tr>` : ""}
|
||||
</table>
|
||||
<div class="d-br d-pay-hdr">
|
||||
<div class="ph-lbl">${h(td("payment"))}</div>
|
||||
${pTerm > 0 ? `<div class="ph-terms">${h(td("payment-terms"))}: <strong>${pTerm}</strong> ${h(td("payment-days"))}${pPayBy ? ` — ${h(td("pay-by"))}: <strong>${h(pPayBy)}</strong>` : ""}</div>` : ""}
|
||||
${showBank ? `<div class="ph-grid">
|
||||
${pAcct ? `<span class="pl">${h(td("account-holder"))}</span><span class="pv">${h(pAcct)}</span>` : ""}
|
||||
${pIban ? `<span class="pl">${h(td("account-no"))}</span><span class="pv">${h(pIban)}</span>` : ""}
|
||||
${pBic ? `<span class="pl">${h(td("bank-bic"))}</span><span class="pv">${h(pBic)}</span>` : ""}
|
||||
${pBadr1 || pBadr2 ? `<span class="pl">${h(td("bank-address"))}</span><span class="pv">${[pBadr1,pBadr2].filter(Boolean).map(l=>h(l)).join("<br>")}</span>` : ""}
|
||||
</div>
|
||||
${pRef ? `<div class="ph-ref">${h(td("payment-ref"))}: <strong>${h(pRef)}</strong></div>` : ""}` : ""}
|
||||
</div>
|
||||
</div>
|
||||
<table class="d-lines">
|
||||
|
|
@ -1253,34 +1260,19 @@ function buildPDF() {
|
|||
fn(8); tc(107,114,128); tL(parts.join(" "), ML, ly); ly += 5;
|
||||
}
|
||||
|
||||
// ── Row 1 right: Payment ──
|
||||
if (pTerm > 0 || showBank) {
|
||||
fb(7); tc(107,114,128); tL(td("payment").toUpperCase(), XM_L, ry); ry += 5;
|
||||
if (pTerm > 0) {
|
||||
const ts = `${td("payment-terms")}: ${pTerm} ${td("payment-days")}${pPayBy ? ` ${td("pay-by")}: ${pPayBy}` : ""}`;
|
||||
fn(8.5); tc(17,24,39); tL(ts, XM_L, ry); ry += 5;
|
||||
}
|
||||
if (showBank) {
|
||||
const LLBL = 46;
|
||||
const payRows = [
|
||||
pAcct ? [td("account-holder"), pAcct] : null,
|
||||
pIban ? [td("account-no"), pIban] : null,
|
||||
pBic ? [td("bank-bic"), pBic] : null,
|
||||
(pBadr1||pBadr2) ? [td("bank-address"), [pBadr1,pBadr2].filter(Boolean).join(", ")] : null,
|
||||
// ── Row 1 right: INVOICE + meta ──
|
||||
fb(24); tc(30,45,69); tR(td("invoice"), XR, ry); ry += 10;
|
||||
const metaRows = [
|
||||
iNo ? [td("invoice-no"), iNo] : null,
|
||||
iDate ? [td("invoice-date"), fmtDate(iDate)] : null,
|
||||
pCode ? [td("project-code"), pCode] : null,
|
||||
iCur ? [td("invoice-currency"), iCur] : null,
|
||||
].filter(Boolean);
|
||||
payRows.forEach(([lbl, val]) => {
|
||||
fn(8); tc(107,114,128); tL(lbl + ":", XM_L, ry);
|
||||
fn(8.5); tc(17,24,39);
|
||||
const wrapped = sp(val, LW - LLBL - 2);
|
||||
wrapped.forEach((line, i) => tL(line, XM_L + LLBL, ry + i * 4));
|
||||
ry += Math.max(4.5, wrapped.length * 4);
|
||||
metaRows.forEach(([lbl, val]) => {
|
||||
fn(8.5); tc(107,114,128); tR(lbl + ":", XR - 42, ry);
|
||||
fb(8.5); tc(17,24,39); tR(val, XR, ry);
|
||||
ry += 5;
|
||||
});
|
||||
if (pRef) {
|
||||
fn(8); tc(107,114,128); tL(td("payment-ref") + ":", XM_L, ry);
|
||||
fb(8.5); tc(17,24,39); tL(pRef, XM_L + LLBL, ry); ry += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Row 1 divider
|
||||
const row1Y = Math.max(ly, ry) + 4;
|
||||
|
|
@ -1302,19 +1294,34 @@ function buildPDF() {
|
|||
if (ctParts.length) { fn(8); tc(107,114,128); tL(ctParts.join(" "), ML, ly2); ly2 += 5; }
|
||||
}
|
||||
|
||||
// ── Row 2 right: INVOICE + meta ──
|
||||
fb(24); tc(30,45,69); tR(td("invoice"), XR, ry2); ry2 += 10;
|
||||
const metaRows = [
|
||||
iNo ? [td("invoice-no"), iNo] : null,
|
||||
iDate ? [td("invoice-date"), fmtDate(iDate)] : null,
|
||||
pCode ? [td("project-code"), pCode] : null,
|
||||
iCur ? [td("invoice-currency"), iCur] : null,
|
||||
// ── Row 2 right: Payment ──
|
||||
if (pTerm > 0 || showBank) {
|
||||
fb(7); tc(107,114,128); tL(td("payment").toUpperCase(), XM_L, ry2); ry2 += 5;
|
||||
if (pTerm > 0) {
|
||||
const ts = `${td("payment-terms")}: ${pTerm} ${td("payment-days")}${pPayBy ? ` ${td("pay-by")}: ${pPayBy}` : ""}`;
|
||||
fn(8.5); tc(17,24,39); tL(ts, XM_L, ry2); ry2 += 5;
|
||||
}
|
||||
if (showBank) {
|
||||
const LLBL = 46;
|
||||
const payRows = [
|
||||
pAcct ? [td("account-holder"), pAcct] : null,
|
||||
pIban ? [td("account-no"), pIban] : null,
|
||||
pBic ? [td("bank-bic"), pBic] : null,
|
||||
(pBadr1||pBadr2) ? [td("bank-address"), [pBadr1,pBadr2].filter(Boolean).join(", ")] : null,
|
||||
].filter(Boolean);
|
||||
metaRows.forEach(([lbl, val]) => {
|
||||
fn(8.5); tc(107,114,128); tR(lbl + ":", XR - 42, ry2);
|
||||
fb(8.5); tc(17,24,39); tR(val, XR, ry2);
|
||||
ry2 += 5;
|
||||
payRows.forEach(([lbl, val]) => {
|
||||
fn(8); tc(107,114,128); tL(lbl + ":", XM_L, ry2);
|
||||
fn(8.5); tc(17,24,39);
|
||||
const wrapped = sp(val, LW - LLBL - 2);
|
||||
wrapped.forEach((line, i) => tL(line, XM_L + LLBL, ry2 + i * 4));
|
||||
ry2 += Math.max(4.5, wrapped.length * 4);
|
||||
});
|
||||
if (pRef) {
|
||||
fn(8); tc(107,114,128); tL(td("payment-ref") + ":", XM_L, ry2);
|
||||
fb(8.5); tc(17,24,39); tL(pRef, XM_L + LLBL, ry2); ry2 += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
y = Math.max(ly2, ry2) + 5;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue