feat: Warnfenster und Planungs-Hinweis bei möglicher Doppelzählung (A12-T4)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
/* 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; }
|
||||
})();
|
||||
@@ -226,3 +226,13 @@ label:has(input:disabled), label:has(select:disabled) {
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Doppelzählung Kredit/Fixposten (Ausbaustufe 12). */
|
||||
.warn-hint {
|
||||
display: block;
|
||||
font-size: 0.8em;
|
||||
color: #b45309;
|
||||
}
|
||||
#doppelzaehlung-dialog {
|
||||
max-width: 32rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user