/* Buchungsmaske: Felder je nach Art ein- und ausblenden, Restbetrag der * Splitzeilen mitrechnen. * * Nur Komfort – die Maske kommt fertig vom Server. Ohne JavaScript bleibt alles * bedienbar: dann sind sämtliche Felder sichtbar, und die Splitsumme prüft * ohnehin das Model. */ (function () { 'use strict'; const art = document.getElementById('art'); const maske = document.querySelector('.buchungsmaske'); if (!art || !maske) { return; } const kategorie = maske.querySelector('.nur-kategorie'); const umbuchung = maske.querySelector('.nur-umbuchung'); const gegenkonto = document.getElementById('gegenkonto_id'); const summenfeld = document.getElementById('splitsumme'); const betragsfeld = document.getElementById('betrag'); function zeigePassendeFelder() { const istUmbuchung = art.value.indexOf('umbuchung') === 0; if (kategorie) { kategorie.hidden = istUmbuchung; } if (umbuchung) { umbuchung.hidden = !istUmbuchung; } if (gegenkonto) { gegenkonto.required = istUmbuchung; } } /* Beträge stehen im deutschen Format im Feld. Dieselbe Regel wie * KontenController::zahl(): ohne Komma entscheidet die Stellenzahl, ob der * Punkt Tausender- oder Dezimaltrenner ist. */ function zahl(text) { const bereinigt = String(text).replace(/[\s€]/g, ''); if (bereinigt === '') { return 0; } if (bereinigt.indexOf(',') !== -1) { return parseFloat(bereinigt.replace(/\./g, '').replace(',', '.')) || 0; } const punkte = (bereinigt.match(/\./g) || []).length; const letzter = bereinigt.split('.').pop(); if (punkte > 1 || (punkte === 1 && letzter.length === 3)) { return parseFloat(bereinigt.replace(/\./g, '')) || 0; } return parseFloat(bereinigt) || 0; } function formatiere(wert) { return wert.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); } function rechneSumme() { if (!summenfeld) { return; } let summe = 0; let belegt = false; maske.querySelectorAll('.splitbetrag').forEach(function (feld) { if (feld.value.trim() === '') { return; } belegt = true; summe += zahl(feld.value); }); if (!belegt) { summenfeld.textContent = '0,00'; summenfeld.classList.remove('negativ'); return; } // Der Buchungsbetrag wird positiv eingegeben; das Vorzeichen ergibt // sich aus der Art. Für den Vergleich zählt der Betrag mit Richtung. let ziel = zahl(betragsfeld ? betragsfeld.value : '0'); if (art.value === 'ausgabe' || art.value === 'umbuchung_ab') { ziel = -ziel; } const rest = Math.round((ziel - summe) * 100) / 100; summenfeld.textContent = formatiere(summe) + (rest === 0 ? '' : ' (Rest ' + formatiere(rest) + ')'); summenfeld.classList.toggle('negativ', rest !== 0); } art.addEventListener('change', function () { zeigePassendeFelder(); rechneSumme(); }); maske.addEventListener('input', function (ereignis) { if (ereignis.target.classList.contains('splitbetrag') || ereignis.target.id === 'betrag') { rechneSumme(); } }); zeigePassendeFelder(); rechneSumme(); })();