Wartungs-Abo v2: Rechtsrunde umgesetzt
- Bestellseite: Pflichtangaben direkt ueber dem Button, Zahlungsarten, Wahl des Leistungsbeginns (sofort / nach Widerrufsfrist via 15 Tage Stripe-Probezeit), keine Vorauswahl - Zustimmungsnachweis: Zeitpunkt, Version, Wahl, IP, Browser in Stripe- Metadaten und Appwrite (neue Attribute, Setup-Skript ergaenzt) - Checkout: Karte + SEPA (Fallback nur Karte), korrigierter Hinweistext - Vertragsbestaetigung mit PDF der Vertragsunterlagen statt HTML - Kuendigen/Widerrufen: Formular direkt (keine Zwischenseite), Wunsch- termin, Druck/PDF der Bestaetigung, Vorbefuellung bei Login - Widerrufsbutton im Abo waehrend der Frist, 'beginnt am'-Status - Pilotbetrieb per ABO_PILOT_EMAILS - Vertragsbedingungen v2, Datenschutzerklaerung, Kalkulator ohne MwSt und mit 100/80 EUR Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0214725c0
commit
4ab154bfa2
18 files changed
+354
-163
No files matched your search
@@ -8,7 +8,8 @@
|
||||
localStorage des Browsers. */
|
||||
|
||||
/* --------------------------------------------------------------- Katalog --- */
|
||||
const MWST = 19
|
||||
// Kleinunternehmer (§ 19 UStG): alle Preise sind Endpreise, keine Umsatzsteuer
|
||||
const USt_HINWEIS = 'Gemäß § 19 UStG wird keine Umsatzsteuer berechnet (Kleinunternehmerregelung).'
|
||||
|
||||
const CATS = [
|
||||
{
|
||||
@@ -118,7 +119,8 @@ const CATS = [
|
||||
},
|
||||
]
|
||||
|
||||
const STAFFEL = [{ max: 5, r: 150 }, { max: 15, r: 130 }, { max: 40, r: 115 }, { max: 1e9, r: 100 }]
|
||||
// Stundensatz: 100 € für kleine Aufträge, ab 10 Stunden (größeres Projekt) 80 €
|
||||
const STAFFEL = [{ max: 9.99, r: 100 }, { max: 1e9, r: 80 }]
|
||||
|
||||
const PEOPLE = {
|
||||
justin: {
|
||||
@@ -285,7 +287,7 @@ function totals() {
|
||||
}
|
||||
|
||||
return {
|
||||
sel, hrsNum, rateNum, netNum, grossNum: netNum * (1 + MWST / 100),
|
||||
sel, hrsNum, rateNum, netNum,
|
||||
mSum, askServer, monthlyItems, hasMonthly: monthlyItems.length > 0,
|
||||
payTitle, payText, flagTitle, flagText, tone,
|
||||
monthly: eur(mSum) + (askServer ? ' +' : ''),
|
||||
@@ -389,7 +391,7 @@ function summaryText() {
|
||||
lines.push('')
|
||||
lines.push(`Summe: ${fmt(t.hrsNum)} Stunden`)
|
||||
lines.push(`Stundensatz: ${eur(t.rateNum)}`)
|
||||
lines.push(`Projektpreis: ${eur(t.netNum)} netto (${eur(t.grossNum)} brutto inkl. ${MWST} % MwSt.)`)
|
||||
lines.push(`Projektpreis: ${eur(t.netNum)} (Endpreis, ohne Umsatzsteuer)`)
|
||||
lines.push('', 'ZAHLUNG', `${t.payTitle} — ${t.payText}`)
|
||||
|
||||
if (t.hasMonthly) {
|
||||
@@ -414,7 +416,7 @@ function summaryText() {
|
||||
if (state.portalEmail) lines.push(`E-Mail: ${state.portalEmail}`)
|
||||
if (state.portalPass) lines.push(`Passwort: ${state.portalPass}`)
|
||||
}
|
||||
lines.push('', 'Alle Preise netto zzgl. gesetzlicher Umsatzsteuer.')
|
||||
lines.push('', `Alle Preise sind Endpreise. ${USt_HINWEIS}`)
|
||||
return lines.join('\n')
|
||||
}
|
||||
|
||||
@@ -425,7 +427,7 @@ function renderNumbers(t) {
|
||||
el('hdr-monthly').textContent = t.hasMonthly ? t.monthly : '–'
|
||||
|
||||
el('hero-net').textContent = eur(t.netNum)
|
||||
el('hero-sub').textContent = `netto · ${eur(t.grossNum)} brutto inkl. ${MWST} % MwSt.`
|
||||
el('hero-sub').textContent = 'Endpreis · gemäß § 19 UStG ohne Umsatzsteuer'
|
||||
el('hero-hrs').textContent = `${fmt(t.hrsNum)} Std`
|
||||
el('hero-rate').textContent = `Stundensatz ${eur(t.rateNum)}/Std`
|
||||
el('hero-monthly').textContent = t.hasMonthly ? t.monthly : '–'
|
||||
|
||||
Reference in new issue
Block a user