mirror of
https://github.com/kbenestad/invoice.git
synced 2026-06-18 08:04:32 +00:00
Use translation keys for all FX row labels; append currency dynamically
All four FX sub-row labels now come from config translations instead of hardcoded English strings. Labels with a currency suffix (per-item, total-foreign) have the currency code appended by updateFxLabels() so they read e.g. "Price per item in USD" / "Line total in USD" and update when the foreign currency dropdown changes. Language switching also re-applies all four labels via the existing updateFxLabels() call in relabel(). Translation key values updated: - currency-code → "Foreign currency code" - exchange-rate → "Exchange rate" (dropped the redundant convention note) - per-item → "Price per item in" (currency appended at runtime) - total-foreign → "Line total in" (currency appended at runtime) PDF note updated to match: "Price per item in USD: 100.00 (35 THB per USD)" https://claude.ai/code/session_0151QtsUhzXmgzEhSvXG2SDt
This commit is contained in:
parent
77cf865ddc
commit
0f26de9222
2 changed files with 30 additions and 24 deletions
|
|
@ -408,25 +408,25 @@ translations:
|
||||||
fr: Devise étrangère
|
fr: Devise étrangère
|
||||||
"no": Utenlandsk valuta
|
"no": Utenlandsk valuta
|
||||||
currency-code:
|
currency-code:
|
||||||
en: Currency code
|
en: Foreign currency code
|
||||||
de: Währungscode
|
de: Fremdwährungscode
|
||||||
fr: Code devise
|
fr: Code devise étrangère
|
||||||
"no": Valutakode
|
"no": Utenlandsk valutakode
|
||||||
exchange-rate:
|
exchange-rate:
|
||||||
en: "Exchange rate (1 foreign = X local)"
|
en: Exchange rate
|
||||||
de: "Wechselkurs (1 Fremd = X Inland)"
|
de: Wechselkurs
|
||||||
fr: "Taux de change (1 étranger = X local)"
|
fr: Taux de change
|
||||||
"no": "Valutakurs (1 utenlandsk = X lokal)"
|
"no": Valutakurs
|
||||||
per-item:
|
per-item:
|
||||||
en: Price per item (foreign currency)
|
en: Price per item in
|
||||||
de: Preis je Einheit (Fremdwährung)
|
de: Preis je Einheit in
|
||||||
fr: Prix par unité (devise étrangère)
|
fr: Prix par unité en
|
||||||
"no": Pris per enhet (utenlandsk valuta)
|
"no": Pris per enhet i
|
||||||
total-foreign:
|
total-foreign:
|
||||||
en: Line total in foreign currency
|
en: Line total in
|
||||||
de: Zeilenbetrag (Fremdwährung)
|
de: Zeilenbetrag in
|
||||||
fr: Total ligne en devise étrangère
|
fr: Total ligne en
|
||||||
"no": Linjebeløp i utenlandsk valuta
|
"no": Linjebeløp i
|
||||||
add-line:
|
add-line:
|
||||||
en: "+ Add new line"
|
en: "+ Add new line"
|
||||||
de: "+ Neue Zeile hinzufügen"
|
de: "+ Neue Zeile hinzufügen"
|
||||||
|
|
|
||||||
|
|
@ -931,11 +931,11 @@ function toggleFx(i) {
|
||||||
<td colspan="6">
|
<td colspan="6">
|
||||||
<div class="fx-grid">
|
<div class="fx-grid">
|
||||||
<div>
|
<div>
|
||||||
<div class="fx-label">${t("currency-code")}</div>
|
<div class="fx-label" id="fcur-lbl-${i}">${t("currency-code")}</div>
|
||||||
<select id="fcur-${i}" onchange="updateFxLabels(${i});calcLine(${i});saveLines()">${currOpts(defaultFcy)}</select>
|
<select id="fcur-${i}" onchange="updateFxLabels(${i});calcLine(${i});saveLines()">${currOpts(defaultFcy)}</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="fx-label">Exchange rate</div>
|
<div class="fx-label" id="frate-lbl-${i}">${t("exchange-rate")}</div>
|
||||||
<div style="display:flex;align-items:center;gap:4px;flex-wrap:wrap">
|
<div style="display:flex;align-items:center;gap:4px;flex-wrap:wrap">
|
||||||
<input type="number" id="frate-${i}" value="" min="0" step="any" style="width:80px" oninput="calcFxFromPer(${i})">
|
<input type="number" id="frate-${i}" value="" min="0" step="any" style="width:80px" oninput="calcFxFromPer(${i})">
|
||||||
<select id="rcur-${i}" style="width:auto" onchange="updateFxLabels(${i});calcFxFromPer(${i});saveLines()">
|
<select id="rcur-${i}" style="width:auto" onchange="updateFxLabels(${i});calcFxFromPer(${i});saveLines()">
|
||||||
|
|
@ -947,11 +947,11 @@ function toggleFx(i) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="fx-label" id="fper-lbl-${i}">Price per item in ${h(defaultFcy)}</div>
|
<div class="fx-label" id="fper-lbl-${i}">${t("per-item")} ${h(defaultFcy)}</div>
|
||||||
<input type="number" id="fper-${i}" value="" min="0" step="any" oninput="calcFxFromPer(${i})">
|
<input type="number" id="fper-${i}" value="" min="0" step="any" oninput="calcFxFromPer(${i})">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fx-note">${t("total-foreign")}: <strong id="fltot-${i}">0.00</strong></div>
|
<div class="fx-note"><span id="ftot-lbl-${i}">${t("total-foreign")} ${h(defaultFcy)}</span>: <strong id="fltot-${i}">0.00</strong></div>
|
||||||
</td>`;
|
</td>`;
|
||||||
lr?.insertAdjacentElement("afterend", fxTr);
|
lr?.insertAdjacentElement("afterend", fxTr);
|
||||||
calcLine(i);
|
calcLine(i);
|
||||||
|
|
@ -1406,7 +1406,7 @@ function buildPDF() {
|
||||||
let fxH = 0;
|
let fxH = 0;
|
||||||
if (row.fxNote) {
|
if (row.fxNote) {
|
||||||
const fxOther = row.fxNote.rcur === iCur ? row.fxNote.cur : iCur;
|
const fxOther = row.fxNote.rcur === iCur ? row.fxNote.cur : iCur;
|
||||||
const fxStr = `${td("per-item")}: ${row.fxNote.cur} ${fmt(row.fxNote.per)} `
|
const fxStr = `${td("per-item")} ${row.fxNote.cur}: ${fmt(row.fxNote.per)} `
|
||||||
+ `(${(+row.fxNote.rate).toFixed(5)} ${row.fxNote.rcur} per ${fxOther})`;
|
+ `(${(+row.fxNote.rate).toFixed(5)} ${row.fxNote.rcur} per ${fxOther})`;
|
||||||
const fxLines = sp(fxStr, CD + CP - 4);
|
const fxLines = sp(fxStr, CD + CP - 4);
|
||||||
fxH = fxLines.length * 3.5 + 1;
|
fxH = fxLines.length * 3.5 + 1;
|
||||||
|
|
@ -1440,7 +1440,7 @@ function buildPDF() {
|
||||||
|
|
||||||
if (row.fxNote) {
|
if (row.fxNote) {
|
||||||
const fxOther = row.fxNote.rcur === iCur ? row.fxNote.cur : iCur;
|
const fxOther = row.fxNote.rcur === iCur ? row.fxNote.cur : iCur;
|
||||||
const fxStr = `${td("per-item")}: ${row.fxNote.cur} ${fmt(row.fxNote.per)} `
|
const fxStr = `${td("per-item")} ${row.fxNote.cur}: ${fmt(row.fxNote.per)} `
|
||||||
+ `(${(+row.fxNote.rate).toFixed(5)} ${row.fxNote.rcur} per ${fxOther})`;
|
+ `(${(+row.fxNote.rate).toFixed(5)} ${row.fxNote.rcur} per ${fxOther})`;
|
||||||
fn(7); tc(107,114,128);
|
fn(7); tc(107,114,128);
|
||||||
const fxLines = sp(fxStr, CD + CP - 4);
|
const fxLines = sp(fxStr, CD + CP - 4);
|
||||||
|
|
@ -1491,14 +1491,20 @@ function updateFxLabels(i) {
|
||||||
const lcy = document.getElementById("icur")?.value || "";
|
const lcy = document.getElementById("icur")?.value || "";
|
||||||
const rcurEl = document.getElementById(`rcur-${i}`);
|
const rcurEl = document.getElementById(`rcur-${i}`);
|
||||||
const rotherEl = document.getElementById(`rother-${i}`);
|
const rotherEl = document.getElementById(`rother-${i}`);
|
||||||
const pl = document.getElementById(`fper-lbl-${i}`);
|
|
||||||
if (rcurEl) {
|
if (rcurEl) {
|
||||||
const prev = rcurEl.value;
|
const prev = rcurEl.value;
|
||||||
rcurEl.innerHTML = `<option value="${h(lcy)}">${h(lcy)}</option><option value="${h(fcy)}">${h(fcy)}</option>`;
|
rcurEl.innerHTML = `<option value="${h(lcy)}">${h(lcy)}</option><option value="${h(fcy)}">${h(fcy)}</option>`;
|
||||||
rcurEl.value = (prev === lcy || prev === fcy) ? prev : lcy;
|
rcurEl.value = (prev === lcy || prev === fcy) ? prev : lcy;
|
||||||
}
|
}
|
||||||
if (rotherEl) rotherEl.textContent = rcurEl?.value === lcy ? fcy : lcy;
|
if (rotherEl) rotherEl.textContent = rcurEl?.value === lcy ? fcy : lcy;
|
||||||
if (pl) pl.textContent = `Price per item in ${fcy}`;
|
const cl = document.getElementById(`fcur-lbl-${i}`);
|
||||||
|
if (cl) cl.textContent = t("currency-code");
|
||||||
|
const rl = document.getElementById(`frate-lbl-${i}`);
|
||||||
|
if (rl) rl.textContent = t("exchange-rate");
|
||||||
|
const pl = document.getElementById(`fper-lbl-${i}`);
|
||||||
|
if (pl) pl.textContent = t("per-item") + " " + fcy;
|
||||||
|
const tl = document.getElementById(`ftot-lbl-${i}`);
|
||||||
|
if (tl) tl.textContent = t("total-foreign") + " " + fcy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Save / load invoice lines ──────────────────────────────────────────────────
|
// ── Save / load invoice lines ──────────────────────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue