/* Das Wertpapiergeschäft zu einer Kontobuchung. * * Zwei Dialoge wie im FinanzManager: vorne Vorgang, Papier, Stück und Kurs, * dahinter die Nebenkosten. Die Kostenfelder gehören zum vorderen Formular und * stehen nur räumlich im zweiten Dialog – verbunden über das form-Attribut. * * Gerechnet wird hier nur zur Anzeige: Der Buchungsbetrag steht fest, und was * nach den Kosten übrig bleibt, ist der Einstandspreis. Der Server rechnet * dieselbe Zeile noch einmal, denn was der Browser anzeigt, ist kein Beleg. * * Dieselbe Datei bedient die Seite /buchungen/{id}/wertpapier: Dort gibt es * keine Dialoge, aber dieselben Felder und dieselbe Rechnung. */ (function () { 'use strict'; const formular = document.getElementById('wertpapierformular'); if (!formular || !window.FmBetrag) { return; } const dialog = document.getElementById('wertpapierdialog'); const kostendialog = document.getElementById('kostendialog'); const vorgang = document.getElementById('wp_vorgang'); const einstand = document.getElementById('wp_einstand'); const kostensumme = document.getElementById('wp_kostensumme'); const knopfsumme = document.getElementById('wp_kostenknopfsumme'); // Auf der Seite steht der Betrag am Formular, im Kontoblatt bringt ihn erst // die angeklickte Zeile mit. let betrag = Number(formular.dataset.betrag || '0'); function kostenfelder() { return Array.from(document.querySelectorAll('.kostenbetrag')); } function summeKosten() { let summe = 0; kostenfelder().forEach(function (feld) { summe += window.FmBetrag.zahl(feld.value); }); return Math.round(summe * 100) / 100; } function rechne() { const kosten = summeKosten(); const rest = Math.round((Math.abs(betrag) - kosten) * 100) / 100; if (kostensumme) { kostensumme.textContent = window.FmBetrag.formatiere(kosten); } if (knopfsumme) { knopfsumme.textContent = window.FmBetrag.formatiere(kosten); } if (einstand) { einstand.textContent = window.FmBetrag.formatiere(rest); // Bleibt nichts übrig, ist etwas falsch – der Server weist es ab. einstand.classList.toggle('negativ', rest <= 0); } } /* Ein Abfluss vom Konto kann nur ein Kauf sein, ein Zufluss ein Verkauf oder * eine Dividende. Was nicht passt, steht gar nicht erst zur Wahl. */ function vorgaengeStellen() { if (!vorgang) { return; } const erlaubt = betrag < 0 ? ['kauf'] : ['verkauf', 'dividende']; Array.from(vorgang.options).forEach(function (option) { const passt = erlaubt.indexOf(option.value) !== -1; option.hidden = !passt; option.disabled = !passt; }); if (erlaubt.indexOf(vorgang.value) === -1) { vorgang.value = erlaubt[0]; } } document.addEventListener('input', function (ereignis) { if (ereignis.target instanceof Element && ereignis.target.classList.contains('kostenbetrag')) { rechne(); } }); if (kostendialog) { document.getElementById('wp_kostenknopf').addEventListener('click', function () { kostendialog.showModal(); }); document.getElementById('wp_kostenfertig').addEventListener('click', function () { kostendialog.close(); rechne(); }); } if (dialog) { document.getElementById('wp_abbrechen').addEventListener('click', function () { dialog.close(); }); } vorgaengeStellen(); rechne(); if (!dialog) { return; } /* ── Der Dialog des Kontoblatts ──────────────────────────────────────── */ const papierliste = document.getElementById('wp_wertpapier'); /* Das Papier zur ISIN oder WKN aus dem Verwendungszweck. Ohne Treffer bleibt * die Auswahl auf „neues Wertpapier anlegen“, und die gelesenen Kennungen * stehen als Vorgabe in den Feldern darunter. */ function papierWaehlen(isin, wkn) { papierliste.value = ''; if (isin === '' && wkn === '') { return; } Array.from(papierliste.options).forEach(function (option) { if (papierliste.value !== '') { return; } if ((isin !== '' && option.dataset.isin === isin) || (wkn !== '' && option.dataset.wkn === wkn)) { papierliste.value = option.value; } }); } function leeren() { kostenfelder().forEach(function (feld) { feld.value = ''; }); ['wp_name', 'wp_stueck', 'wp_kurs', 'wp_notiz', 'wp_valuta'].forEach(function (id) { document.getElementById(id).value = ''; }); } window.FmWertpapier = { /* @param feld die angeklickte Zuordnungszelle mit ihren data-Werten * @param depotId das gewählte Depot * @param depotName sein Name, für die Kopfzeile des Dialogs * @param ziel wohin das Formular geht */ oeffnen: function (feld, depotId, depotName, ziel) { formular.action = ziel; betrag = Number(feld.dataset.betrag || '0'); const isin = (feld.dataset.isin || '').toUpperCase(); const wkn = (feld.dataset.wkn || '').toUpperCase(); // Der Dialog gilt für alle Zeilen der Seite – die Angaben der // vorigen dürfen nicht stehen bleiben. leeren(); document.getElementById('wp_depot').value = depotId; document.getElementById('wp_depotname').textContent = depotName; document.getElementById('wp_bezeichnung').textContent = feld.dataset.bezeichnung || ''; document.getElementById('wp_verwendungszweck').textContent = feld.dataset.zweck || ''; document.getElementById('wp_buchungsbetrag').textContent = window.FmBetrag.formatiere(betrag); document.getElementById('wp_datum').value = feld.dataset.datum || ''; document.getElementById('wp_isin').value = isin; document.getElementById('wp_wkn').value = wkn; // Die Klasse der Buchung steht schon in ihrer Zeile – sie ist die // Vorgabe für das Geschäft. const zeile = feld.closest('tr'); const klassenfeld = zeile && zeile.querySelector('a.klassenfeld'); const klasse = klassenfeld ? (klassenfeld.dataset.klasse || '') : ''; document.getElementById('wp_klasse').value = klasse === '0' ? '' : klasse; papierWaehlen(isin, wkn); vorgaengeStellen(); rechne(); dialog.showModal(); } }; })();