OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

_contract_form.js.php

5 KB
(function () {
    'use strict';

    var amountEl  = document.getElementById('cost_amount');
    var netEl     = document.getElementById('cost_amount_net');
    var intvlEl   = document.getElementById('cost_interval');
    var taxEl     = document.getElementById('tax_rate');
    var firstPayEl = document.getElementById('first_payment_date');

    var previewCard = document.getElementById('costPreviewCard');
    var mGross      = document.getElementById('prev-monthly-gross');
    var mNet        = document.getElementById('prev-monthly-net');
    var yGross      = document.getElementById('prev-yearly-gross');
    var yNet        = document.getElementById('prev-yearly-net');
    var dueBox      = document.getElementById('prev-next-payment');
    var dueText     = document.getElementById('prev-next-payment-text');

    if (!amountEl) return;

    function fmt(v) {
        return v.toLocaleString('de-DE', {minimumFractionDigits: 2, maximumFractionDigits: 2}) + '\u202f\u20AC';
    }

    function nextPayDate(firstDate, interval) {
        if (!firstDate) return null;
        var today = new Date(); today.setHours(0, 0, 0, 0);
        var d = new Date(firstDate);
        if (isNaN(d.getTime())) return null;
        if (d >= today) return d;
        var step = interval === 'quarterly' ? 3 : interval === 'yearly' ? 12 : 1;
        while (d < today) { d.setMonth(d.getMonth() + step); }
        return d;
    }

    function update() {
        var raw = amountEl.value;
        var amount = parseFloat(raw);

        if (!raw || isNaN(amount) || amount <= 0) {
            previewCard.style.display = 'none';
            return;
        }
        previewCard.style.display = '';

        var intvl = intvlEl.value;
        var taxRaw = parseFloat(taxEl.value);
        var hasTax = taxEl.value !== '' && !isNaN(taxRaw) && taxRaw > 0;

        var isOneTime = intvl === 'one_time';
        var monthly = isOneTime ? 0
                    : intvl === 'monthly' ? amount
                    : intvl === 'quarterly' ? amount / 3
                    : amount / 12;
        var yearly = isOneTime ? 0 : monthly * 12;

        if (isOneTime) {
            mGross.textContent = <?= json_encode($this->t('(einmalig)'), JSON_UNESCAPED_UNICODE) ?>;
            yGross.textContent = <?= json_encode($this->t('(einmalig)'), JSON_UNESCAPED_UNICODE) ?>;
            mNet.textContent = hasTax ? fmt(amount / (1 + taxRaw / 100)) + <?= json_encode(' ' . $this->t('netto'), JSON_UNESCAPED_UNICODE) ?> : <?= json_encode($this->t('(keine MwSt)'), JSON_UNESCAPED_UNICODE) ?>;
            yNet.textContent = '–';
            if (firstPayEl.value) {
                dueBox.style.display = 'flex';
                dueText.textContent = new Date(firstPayEl.value).toLocaleDateString('de-DE', {day: '2-digit', month: '2-digit', year: 'numeric'});
            } else {
                dueBox.style.display = 'none';
            }
            return;
        }

        mGross.textContent = fmt(monthly);
        yGross.textContent = fmt(yearly);

        if (hasTax) {
            var factor = 1 + taxRaw / 100;
            mNet.textContent = fmt(monthly / factor);
            yNet.textContent = fmt(yearly / factor);
        } else {
            mNet.textContent = <?= json_encode($this->t('(keine MwSt)'), JSON_UNESCAPED_UNICODE) ?>;
            yNet.textContent = <?= json_encode($this->t('(keine MwSt)'), JSON_UNESCAPED_UNICODE) ?>;
        }

        var next = nextPayDate(firstPayEl.value, intvl);
        if (next) {
            dueBox.style.display = 'flex';
            dueText.textContent = next.toLocaleDateString('de-DE', {day: '2-digit', month: '2-digit', year: 'numeric'});
        } else {
            dueBox.style.display = 'none';
        }
    }

    // Brutto und Netto über den MwSt-Satz synchron halten: Eingabe in einem
    // Feld berechnet das andere; ohne MwSt-Satz gilt Netto = Brutto.
    // Gespeichert wird weiterhin nur der Brutto-Betrag.
    function taxFactor() {
        var rate = parseFloat(taxEl.value);
        return isNaN(rate) || rate < 0 ? 1 : 1 + rate / 100;
    }
    function syncFromNet() {
        if (!netEl) return;
        var nv = parseFloat(netEl.value);
        amountEl.value = isNaN(nv) ? '' : (nv * taxFactor()).toFixed(2);
    }
    function syncFromGross() {
        if (!netEl) return;
        var gv = parseFloat(amountEl.value);
        netEl.value = isNaN(gv) ? '' : (gv / taxFactor()).toFixed(2);
    }
    if (netEl) {
        netEl.addEventListener('input', function () { syncFromNet(); update(); });
        amountEl.addEventListener('input', syncFromGross);
        taxEl.addEventListener('input', function () {
            // Beim Wechsel des Steuersatzes gewinnt das zuletzt „führende" Feld:
            // Brutto, wenn befüllt, sonst Netto.
            if (amountEl.value !== '') { syncFromGross(); } else { syncFromNet(); }
        });
    }

    [amountEl, intvlEl, taxEl, firstPayEl].forEach(function (el) {
        el.addEventListener('input', update);
        el.addEventListener('change', update);
    });
    update();
}());