const PRICE_LOCALE = 'de-DE'; export function getBrutto(netto, kSteuerklasse) { const rate = { 1: 19, 2: 7, 3: 0 }[kSteuerklasse] ?? 19; return netto * (1 + rate / 100); } /** Currency display, e.g. `6,60 €`. */ export function formatPrice(amount) { if (amount == null || !Number.isFinite(Number(amount))) return ''; return new Intl.NumberFormat(PRICE_LOCALE, { style: 'currency', currency: 'EUR', }).format(amount); } /** * Amount without currency symbol (for fields with a separate € adornment). * e.g. `6,60` / `1.234,56` */ export function formatPriceAmount(amount, { minFractionDigits = 2, maxFractionDigits = 2 } = {}) { if (amount == null || !Number.isFinite(Number(amount))) return ''; return new Intl.NumberFormat(PRICE_LOCALE, { minimumFractionDigits: minFractionDigits, maximumFractionDigits: maxFractionDigits, }).format(amount); } /** * Parse de-DE (or plain) price input → number. * Accepts `6,60`, `1.234,56`, and plain `6.60`. */ export function parsePriceInput(value) { if (value === '' || value == null) return null; let normalized = String(value).trim().replace(/\s/g, ''); if (normalized === '') return null; if (normalized.includes(',')) { // de-DE: thousand `.`, decimal `,` normalized = normalized.replace(/\./g, '').replace(',', '.'); } const parsed = Number(normalized); return Number.isFinite(parsed) && parsed >= 0 ? parsed : null; } /** Convert gross (brutto) → net for PUT /prices. Rounded to 4 decimal places. */ export function netFromGross(gross, taxRate) { if (gross == null || taxRate == null) return null; if (!Number.isFinite(gross) || !Number.isFinite(taxRate) || taxRate < 0) return null; const factor = 1 + taxRate / 100; if (factor <= 0) return null; return Math.round((gross / factor) * 10000) / 10000; }