fix(invoices): Leistungsdatum editor lost or mis-formatted the service date
Playwright Tests / test (push) Canceled after 0s

- serializeObject: an empty optional date field was run through parseDt,
  became null and invalidated the whole form, so leaving "bis" empty made
  dlgform call success with only loginaccount and wiped the stored period.
  Empty optional date fields are now sent as ''.
- dlgform: an invalid form no longer calls success with partial data; it
  stops the spinner and keeps the dialog open.
- eProvisionPeriod: the date inputs return yyyy-MM-dd, which was saved
  verbatim; it is now stored as German dd.MM.yyyy as documented (PDF,
  eRechnung mapping). ISO values saved by the old editor are accepted when
  reopening, so their fields are prefilled instead of empty.
- Add a Playwright regression test (e2e_tests/invoice-provisionperiod.cjs)
  driving the real form builder, serializer and dialog submit handler.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Stefan
2026-10-06 18:04:03 +02:00
co-authored by Claude Opus 5.5
parent e2faf52cd2
commit 4145ab699c
12 changed files with 117 additions and 15 deletions
+5 -2
View File
@@ -1696,12 +1696,14 @@ $inv.eAddress = function (ev) {
German dd.MM.yyyy string ("18.06.2026" or "01.06.2026 - 30.06.2026") that the PDF shows and the
backend maps to the eRechnung service date/period. */
$inv.provToIso = function (dmy) {
if (/^\d{4}-\d{2}-\d{2}$/.test(dmy || '')) { return dmy; }
let m = ('' + (dmy || '')).match(/(\d{1,2})\.(\d{1,2})\.(\d{4})/);
return m ? (m[3] + '-' + ('0' + m[2]).slice(-2) + '-' + ('0' + m[1]).slice(-2)) : '';
};
$inv.eProvisionPeriod = function (ev) {
let cur = ('' + (ev.data && ev.data.t ? ev.data.t.text() : '')).trim();
let dates = cur.match(/\d{1,2}\.\d{1,2}\.\d{4}/g) || [];
// Accept ISO values saved by older editor versions as well as German dates.
let dates = cur.match(/\d{1,2}\.\d{1,2}\.\d{4}|\d{4}-\d{2}-\d{2}/g) || [];
let flds = [
{ name: 'von', label: 'Leistungsdatum', type: 'date', value: $inv.provToIso(dates[0] || '') },
{ name: 'bis', label: 'Leistungszeitraum – bis (optional)', type: 'date', value: $inv.provToIso(dates[1] || '') }
@@ -1715,7 +1717,8 @@ $inv.eProvisionPeriod = function (ev) {
title: 'Leistungsdatum / -zeitraum',
addcontent: hint,
success: function (res) {
let v = ('' + (res.von || '')).trim(), b = ('' + (res.bis || '')).trim();
let germanDate = (iso) => iso ? fdt(iso + 'T00:00:00', 'dd.MM.yyyy') : '';
let v = germanDate(res.von), b = germanDate(res.bis);
let txt = v === '' ? '' : ((b === '' || b === v) ? v : (v + ' - ' + b));
if (ev.data && ev.data.t) { ev.data.t.rwText(txt); }
if (typeof (ev.data || {}).change === 'function') { ev.data.change(txt); }