Buchungskalender: Stornobedingungen je Unterkunft, Zustimmung und Bestellstatus
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
efeb99e214
commit
05006f1480
5 files changed
+123
-29
No files matched your search
@@ -1,18 +1,17 @@
|
||||
/* Buchungskalender, Reiter „Einstellungen“: Firmendaten, Steuernummer/USt-IdNr., Rechnungspraefix, Auftrag zur Rechnungsstellung,
|
||||
Bankverbindung, Akzentfarbe, Stornobedingungen (Mustertext), Stripe-Konto und Online-Zahlung.
|
||||
Bankverbindung, Akzentfarbe, Stripe-Konto und Online-Zahlung.
|
||||
API (docs/funktionen/unterkunft-api.md, ?projectId=): GET /einstellungen => { einstellungen:{ firma, inhaber, strasse, plz, ort, email, telefon,
|
||||
steuernummer, ustId, iban, bic, bank, rechnungsPraefix, akzentfarbe, onlineZahlung, rechnungAuftrag, stornobedingungen },
|
||||
steuernummer, ustId, iban, bic, bank, rechnungsPraefix, akzentfarbe, onlineZahlung, rechnungAuftrag },
|
||||
stripe:{ status:'keins'|'onboarding'|'aktiv', vorhandenesShopKonto:boolean }, rechnungenVorhanden:boolean };
|
||||
PUT /einstellungen mit denselben Feldern (ohne Wrapper; rechnungAuftrag:true setzt rechnungAuftragAt auf dem Server);
|
||||
PUT /einstellungen mit denselben Feldern (ohne Wrapper; rechnungAuftrag:true setzt rechnungAuftragAt, false widerruft);
|
||||
POST /stripe/verbinden => { url } (Onboarding bei Stripe), POST /stripe/vorhandenes-konto und /stripe/aktualisieren => { stripe }.
|
||||
Geprueft wird auf dem Server; Feldfehler stehen am Feld. Text nur ueber textContent (h). render(panel, ctx) wie shop-tab-*.js. */
|
||||
|
||||
import { abschnitt, allgemeinerFehler, feld, h, hakenFeld, setzeFehler } from './shop-dom.js'
|
||||
import { abschnitt, allgemeinerFehler, feld, frage, h, hakenFeld, setzeFehler } from './shop-dom.js'
|
||||
import { enc, zeichen, zeigeApiFehler } from './buchungen-uk-hilfe.js'
|
||||
|
||||
export const STORNO_MUSTER = 'Stornierung bis 14 Tage vor Anreise: kostenlos. Stornierung 13 bis 3 Tage vor Anreise: 50 % des Gesamtpreises. Stornierung ab 2 Tage vor Anreise oder Nichtanreise: 90 % des Gesamtpreises. Die Stornierung bedarf der Textform (z. B. E-Mail). Maßgeblich ist der Eingang bei uns.'
|
||||
export const STORNO_HINWEIS = 'Vorlage – bitte an deine Bedingungen anpassen, keine Rechtsberatung.'
|
||||
export const AUFTRAG_TEXT = 'Ich beauftrage WEBklar, in meinem Namen und auf meine Rechnung Rechnungen an meine Gäste auszustellen (§ 14 Abs. 2 Satz 4 UStG).'
|
||||
export const AUFTRAG_WIDERRUF = 'Ohne diese Zustimmung können keine Buchungen bestätigt werden. Zustimmung wirklich zurückziehen?'
|
||||
export const AUFTRAG_FEHLT = 'Ohne diesen Auftrag kannst du Buchungen nicht bestätigen, weil wir keine Rechnungen für dich ausstellen dürfen.'
|
||||
const STRIPE_FEHLER = 'Stripe hat keine gültige Adresse geliefert. Bitte versuch es gleich noch einmal.'
|
||||
const PFLICHT = { firma: 'Bitte gib den Namen deiner Firma oder Unterkunft an.', inhaber: 'Bitte gib den Namen des Inhabers an.', strasse: 'Bitte gib Straße und Hausnummer an.', plz: 'Bitte gib die Postleitzahl an.', ort: 'Bitte gib den Ort an.', email: 'Bitte gib eine E-Mail-Adresse an.' }
|
||||
@@ -44,23 +43,31 @@ export async function render(panel, ctx = {}) {
|
||||
const praefix = textfeld({ maxlength: 8, placeholder: 'RE' }); praefix.value = zeichen(e.rechnungsPraefix) || 'RE'
|
||||
if (rechnungenVorhanden) { praefix.disabled = true; praefix.setAttribute('aria-disabled', 'true') }
|
||||
const auftrag = h('input', { type: 'checkbox' }); auftrag.checked = e.rechnungAuftrag === true
|
||||
const iban = textfeld({ maxlength: 40 }); iban.value = zeichen(e.iban)
|
||||
const iban = textfeld({ maxlength: 34 }); iban.value = zeichen(e.iban)
|
||||
const bic = textfeld({ maxlength: 11 }); bic.value = zeichen(e.bic)
|
||||
const bank = textfeld({ maxlength: 80 }); bank.value = zeichen(e.bank)
|
||||
const akzent = h('input', { type: 'color' }); akzent.value = /^#[0-9a-fA-F]{6}$/.test(zeichen(e.akzentfarbe)) ? e.akzentfarbe : '#111111'
|
||||
const storno = h('textarea', { rows: 6, maxlength: 5000 }); storno.value = zeichen(e.stornobedingungen)
|
||||
const online = h('input', { type: 'checkbox' }); online.checked = e.onlineZahlung === true && stripe.status === 'aktiv'
|
||||
|
||||
const auftragHinweis = h('div', { class: 'sh-box sh-box-warn', role: 'note', 'data-hinweis': 'auftrag' }, AUFTRAG_FEHLT)
|
||||
const zeigeAuftrag = () => { auftragHinweis.hidden = auftrag.checked }
|
||||
auftrag.addEventListener('change', zeigeAuftrag)
|
||||
// Widerruf einer gespeicherten Zustimmung nur nach Rueckfrage in der Seite
|
||||
const widerrufPlatz = h('div', { 'data-widerruf-platz': '' })
|
||||
auftrag.addEventListener('change', () => {
|
||||
if (!auftrag.checked && e.rechnungAuftrag === true && !widerrufPlatz.firstChild) {
|
||||
auftrag.checked = true
|
||||
const zu = () => { widerrufPlatz.replaceChildren(); auftrag.focus() }
|
||||
const box = frage('Zustimmung zurückziehen', h('p', null, AUFTRAG_WIDERRUF),
|
||||
h('div', { class: 'sh-aktionen' },
|
||||
h('button', { type: 'button', class: 'kb-btn-primary', 'data-aktion': 'widerruf-ja', onclick: () => { auftrag.checked = false; zeigeAuftrag(); zu() } }, 'Ja, zurückziehen'),
|
||||
h('button', { type: 'button', class: 'kb-btn-outline', 'data-aktion': 'widerruf-nein', onclick: zu }, 'Abbrechen')))
|
||||
widerrufPlatz.replaceChildren(box)
|
||||
box.focus()
|
||||
}
|
||||
zeigeAuftrag()
|
||||
})
|
||||
zeigeAuftrag()
|
||||
|
||||
const musterKnopf = h('button', {
|
||||
type: 'button', class: 'kb-btn-outline', 'data-aktion': 'storno-muster',
|
||||
onclick: () => { storno.value = STORNO_MUSTER },
|
||||
}, 'Mustertext übernehmen')
|
||||
|
||||
/* ------------------------------------------------------------------ Stripe --- */
|
||||
let beschaeftigt = false
|
||||
async function stripeAktion(pfad, { weiter = false } = {}) {
|
||||
@@ -116,15 +123,13 @@ export async function render(panel, ctx = {}) {
|
||||
? 'Der Präfix ist gesperrt, weil es schon Rechnungen gibt. Die Nummern bleiben so lückenlos.'
|
||||
: '2 bis 8 Zeichen (A–Z, 0–9). Die Nummern lauten dann zum Beispiel RE-2026-0001. Du kannst den Präfix nur vor der ersten Rechnung ändern.'),
|
||||
hakenFeld('rechnungAuftrag', auftrag, AUFTRAG_TEXT),
|
||||
auftragHinweis),
|
||||
auftragHinweis,
|
||||
widerrufPlatz),
|
||||
abschnitt('Bankverbindung (freiwillig)', 'Erscheint als Hinweis, wenn Gäste vor Ort oder per Überweisung zahlen.',
|
||||
feld('iban', 'IBAN', iban),
|
||||
feld('bic', 'BIC', bic),
|
||||
feld('bank', 'Name der Bank', bank)),
|
||||
abschnitt('Darstellung', null, feld('akzentfarbe', 'Akzentfarbe', akzent, 'Diese Farbe bekommen Knöpfe auf deiner Buchungsseite.')),
|
||||
abschnitt('Stornobedingungen', 'Sie stehen auf der Buchungsseite und gelten für neue Freigaben.',
|
||||
feld('stornobedingungen', 'Stornobedingungen', storno, STORNO_HINWEIS),
|
||||
h('div', { class: 'sh-aktionen' }, musterKnopf)),
|
||||
status === 'aktiv'
|
||||
? abschnitt('Online-Zahlung', null, hakenFeld('onlineZahlung', online, 'Online-Zahlung anbieten', 'Gäste können bei der Buchung per Stripe bezahlen.'))
|
||||
: null,
|
||||
@@ -149,7 +154,7 @@ export async function render(panel, ctx = {}) {
|
||||
email: email.value.trim(), telefon: telefon.value.trim(), steuernummer: steuernummer.value.trim(), ustId: ustId.value.trim(),
|
||||
iban: iban.value.trim(), bic: bic.value.trim(), bank: bank.value.trim(),
|
||||
rechnungsPraefix: rechnungenVorhanden ? zeichen(e.rechnungsPraefix) || 'RE' : p,
|
||||
rechnungAuftrag: auftrag.checked, akzentfarbe: akzent.value, stornobedingungen: storno.value.trim(),
|
||||
rechnungAuftrag: auftrag.checked, akzentfarbe: akzent.value,
|
||||
onlineZahlung: status === 'aktiv' && online.checked,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user