/* Buchungsmaske: Restbetrag der Splitzeilen mitrechnen und direkte Zuordnung * und Splitbuchung gegeneinander sperren. * * Nur Komfort – die Maske kommt fertig vom Server. Ohne JavaScript bleibt alles * bedienbar: Die Splitsumme prüft ohnehin das Model. * * Eine Buchung ist entweder direkt zugeordnet (Kategorie / Gegenkonto, Klasse) * oder eine Splitbuchung. Sobald in einer Splitzeile etwas steht, sind die * beiden Felder oben gesperrt; steht oben eine Kategorie oder Klasse, sind es * die Splitzeilen. Gesperrte Felder schickt der Browser nicht mit – was dort * noch stehen mag, geht also nicht in die Buchung ein. Der Knopf * „Splitbuchungen löschen“ leert alle Splitzeilen und gibt oben wieder frei. * * Kategorie und Gegenkonto stehen in einem Feld, deshalb gibt es hier nichts * mehr ein- und auszublenden; die Art bestimmt nur noch die Richtung. */ (function () { 'use strict'; const art = document.getElementById('art'); const maske = document.querySelector('.buchungsmaske'); if (!art || !maske || !window.FmBetrag) { return; } const summenfeld = document.getElementById('splitsumme'); const betragsfeld = document.getElementById('betrag'); function rechneSumme() { if (!summenfeld) { 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 = window.FmBetrag.zahl(betragsfeld ? betragsfeld.value : '0'); if (art.value !== 'einnahme') { ziel = -ziel; } const stand = window.FmBetrag.splitsumme( Array.from(maske.querySelectorAll('.splitbetrag')), ziel ); summenfeld.textContent = stand.text; summenfeld.classList.toggle('negativ', stand.belegt && stand.rest !== 0); } const direktfelder = ['zuordnung', 'klasse_id'] .map(function (id) { return document.getElementById(id); }) .filter(Boolean); const splitkasten = document.getElementById('splitzeilen'); const leerenknopf = document.getElementById('splitsleeren'); function splitfelder() { return splitkasten ? Array.from(splitkasten.querySelectorAll('input, select')) : []; } function belegt(felder) { return felder.some(function (feld) { return feld.value.trim() !== ''; }); } function sperrenAktualisieren() { const splits = splitfelder(); const splitBelegt = belegt(splits); // Stehen beim Öffnen beide Seiten voll (ältere Daten), gilt wie im // Model die Splitbuchung. const direktBelegt = !splitBelegt && belegt(direktfelder); direktfelder.forEach(function (feld) { feld.disabled = splitBelegt; }); splits.forEach(function (feld) { feld.disabled = direktBelegt; }); if (leerenknopf) { leerenknopf.hidden = !splitBelegt; } } function splitsLeeren() { splitfelder().forEach(function (feld) { feld.value = ''; }); sperrenAktualisieren(); rechneSumme(); } art.addEventListener('change', rechneSumme); maske.addEventListener('input', function (ereignis) { if (ereignis.target.classList.contains('splitbetrag') || ereignis.target.id === 'betrag') { rechneSumme(); } sperrenAktualisieren(); }); maske.addEventListener('change', sperrenAktualisieren); if (leerenknopf) { leerenknopf.addEventListener('click', splitsLeeren); } sperrenAktualisieren(); rechneSumme(); })();