Files
2026-09-29 07:35:16 +02:00

90 lines
3.4 KiB
JavaScript

/* Warnfenster bei möglicher Doppelzählung Kredit ↔ Fixposten (Ausbaustufe 12).
*
* Die API antwortet mit 409 und detail.code "doppelzaehlung_kredit", wenn ein
* Posten vermutlich einer Kreditrate entspricht. handle() fängt genau diesen
* Fall im globalen htmx:responseError-Handler ab (alle anderen Fehler laufen
* weiter über den alert) und zeigt den <dialog>. „Trotzdem speichern" markiert
* das auslösende Formular (data-doppelzaehlung-bestaetigt="1") und sendet es
* erneut; die json-form-Extension ergänzt dann doppelzaehlung_bestaetigt=true.
* Nach jedem Request wird die Markierung entfernt, damit ein späteres
* Speichern die Warnung nicht stillschweigend umgeht.
*/
(function () {
'use strict';
var CODE = 'doppelzaehlung_kredit';
var ATTR = 'data-doppelzaehlung-bestaetigt';
var fmt = new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
function parseDetail(xhr) {
if (!xhr || xhr.status !== 409) { return null; }
var body;
try { body = JSON.parse(xhr.responseText); } catch (e) { return null; }
var d = body && body.detail;
return d && d.code === CODE ? d : null;
}
function eur(s) { return fmt.format(parseFloat(s)) + ' €'; }
function konfliktText(k) {
return 'Posten „' + k.posten + '“ (' + eur(k.posten_betrag) + ') ↔ Kredit „'
+ k.kredit + '“ (Rate ' + eur(k.kredit_rate) + ')';
}
function handle(evt) {
var d = parseDetail(evt && evt.detail && evt.detail.xhr);
var elt = evt && evt.detail && evt.detail.elt;
var form = elt && elt.closest ? elt.closest('form') : null;
if (!d || !form) { return false; }
var doc = form.ownerDocument;
var dlg = doc.getElementById('doppelzaehlung-dialog');
if (!dlg) { return false; }
dlg.querySelector('.dz-meldung').textContent = d.meldung;
var list = dlg.querySelector('.dz-konflikte');
list.textContent = '';
(d.konflikte || []).forEach(function (k) {
var li = doc.createElement('li');
li.textContent = konfliktText(k);
list.appendChild(li);
});
dlg.fbForm = form;
dlg.showModal();
return true;
}
function abbrechen(dlg) {
dlg.fbForm = null;
dlg.close();
}
function bestaetigen(dlg) {
var form = dlg.fbForm;
dlg.fbForm = null;
dlg.close();
if (!form) { return; }
form.setAttribute(ATTR, '1');
form.ownerDocument.defaultView.htmx.trigger(form, 'submit');
}
function init(doc) {
var dlg = doc.getElementById('doppelzaehlung-dialog');
if (!dlg) { return; }
doc.getElementById('dz-abbrechen').addEventListener('click', function () { abbrechen(dlg); });
doc.getElementById('dz-bestaetigen').addEventListener('click', function () { bestaetigen(dlg); });
doc.body.addEventListener('htmx:afterRequest', function (e) {
var elt = e.detail && e.detail.elt;
var form = elt && elt.closest ? elt.closest('form') : null;
if (form && form.getAttribute(ATTR) === '1') {
// Erst nach dem Request mit Flag entfernen: der 409-Request selbst
// hat die Markierung nie gesetzt.
form.removeAttribute(ATTR);
}
});
}
var api = { parseDetail: parseDetail, konfliktText: konfliktText, handle: handle,
abbrechen: abbrechen, bestaetigen: bestaetigen, init: init };
if (typeof module !== 'undefined' && module.exports) { module.exports = api; }
if (typeof window !== 'undefined') { window.FBDoppel = api; }
})();