From 838bc96d1b7af3c553aa27d454291c14f195d643 Mon Sep 17 00:00:00 2001 From: Kenso Grimm Date: Wed, 7 Oct 2026 15:09:57 +0000 Subject: [PATCH] =?UTF-8?q?Buchungskalender:=20UI-Durchlauf=20=E2=80=93=20?= =?UTF-8?q?Text=20=E2=80=9Enull=E2=80=9C=20in=20der=20Summe,=20Knopf-=20un?= =?UTF-8?q?d=20Feldgestaltung=20im=20Portal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- public/buchungen-posten.js | 2 +- public/buchungen.css | 12 ++++++++++++ test/buchungenUi.test.js | 19 ++++++++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/public/buchungen-posten.js b/public/buchungen-posten.js index ab37508..1b73570 100644 --- a/public/buchungen-posten.js +++ b/public/buchungen-posten.js @@ -62,7 +62,7 @@ export function baueEditor(start, steuerart, { aenderung } = {}) { summenEl.replaceChildren( ...(klein ? [] : [h('p', null, `Netto ${euroMitVorzeichen(s.nettoCent)}`), ...s.ust.map((u) => h('p', null, `${u.satz} % USt ${euroMitVorzeichen(u.steuerCent)}`))]), h('p', { class: 'bk-gesamt' }, h('strong', null, `Gesamt ${euroMitVorzeichen(s.bruttoCent)}`)), - klein ? h('p', { class: 'sh-hinweis' }, 'Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.') : null) + ...(klein ? [h('p', { class: 'sh-hinweis' }, 'Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.')] : [])) } const geaendert = () => { zeichneSumme() diff --git a/public/buchungen.css b/public/buchungen.css index a366100..e7506f2 100644 --- a/public/buchungen.css +++ b/public/buchungen.css @@ -63,3 +63,15 @@ } .bk-rechnung .sh-pille { margin: 0; } @media (max-width: 720px) { .bk-rechnung { grid-template-columns: 1fr auto; } } + +/* Knoepfe „kb-btn“ (Hauptaktion) wie kb-btn-primary; Eingaben ausserhalb von .sh-feld (Posten-Editor, Staffeln, Filter) wie die Felder der Formulare */ +#view-buchungen .kb-btn { display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 999px; padding: 10px 20px; font: inherit; font-weight: 600; cursor: pointer; background: var(--kb-purple); color: #fff; min-height: 40px; } +#view-buchungen .kb-btn:hover { background: var(--kb-purple-hover); } +#view-buchungen .kb-btn:disabled { opacity: 0.5; cursor: default; } +#view-buchungen .bk-posten input:not([type=checkbox]), #view-buchungen .bk-posten select, #view-buchungen .bk-staffel input, #view-buchungen .bk-filter select, +#view-buchungen .bk-vorschaufelder input, #view-buchungen .bk-importform input { + box-sizing: border-box; min-width: 0; padding: 9px 10px; border-radius: 10px; font: inherit; font-size: 15px; border: 1px solid var(--kb-border-strong); background: rgba(255, 255, 255, 0.05); color: inherit; +} +#view-buchungen .bk-posten select option, #view-buchungen .bk-filter select option { color: #111; } +#view-buchungen .bk-posten input, #view-buchungen .bk-posten select { width: 100%; } +#view-buchungen input[readonly] { box-sizing: border-box; width: 100%; padding: 9px 10px; border-radius: 10px; font: inherit; font-size: 14px; border: 1px solid var(--kb-border-strong); background: rgba(255, 255, 255, 0.05); color: inherit; } diff --git a/test/buchungenUi.test.js b/test/buchungenUi.test.js index b10e029..d574cf5 100644 --- a/test/buchungenUi.test.js +++ b/test/buchungenUi.test.js @@ -5,7 +5,7 @@ import { installFakeDom } from './support/fakeDom.js' import { h, request } from '../public/shop-dom.js' import { REITER } from '../public/buchungen.js' import { render, zeitraumText, naechteText } from '../public/buchungen-tab-anfragen.js' -import { summeLive } from '../public/buchungen-posten.js' +import { summeLive, baueEditor } from '../public/buchungen-posten.js' // Task 12: Gerüst und Reiter „Anfragen“ gegen eine Anfrage-Attrappe nach docs/funktionen/unterkunft-api.md. @@ -826,3 +826,20 @@ test('CSS: ein ausgeblendetes .sh-box (hidden) bleibt unsichtbar (Hinweis zur Zu const css = readFileSync(new URL('../public/shop.css', import.meta.url), 'utf8') assert.match(css, /\.sh-box\[hidden\]\s*\{\s*display:\s*none/) }) + +test('Preis-Editor: Stornobedingungen mit [Platzhalter] werden nicht gespeichert (Mustertext unveraendert nicht speicherbar)', mit(ukServer({ 'PUT /api/unterkunft/unterkuenfte/u1/preise': () => ({ body: {} }) }), async (fx) => { + const panel = await preisEditor(fx) + await fx.klick(aktion(fx, panel, 'storno-muster')) + assert.equal(await versuche(fx, panel), 0) + assert.equal(fehlerText(fx, panel, 'stornobedingungen'), 'Bitte ersetze die Platzhalter in eckigen Klammern durch deine Werte.') + await fx.setze(fx.finde(panel, '#bk-p-storno'), 'Bis 30 Tage vor Anreise kostenfrei, danach 50 Prozent.') + assert.equal(await versuche(fx, panel), 1) +})) + +test('Posten-Editor: die Summenanzeige enthaelt bei Regelbesteuerung kein Text-"null"', () => { + const fx = installFakeDom({ antworten: [] }) + try { + const e = baueEditor([{ text: 'Übernachtung', menge: 1, einzelCent: 10000, ustProzent: 7 }], 'regel') + assert.doesNotMatch(fx.text(e.el), /null/) + } finally { fx.restore() } +})