Abo: Mindestlaufzeit nur fuer Vertraege ab Bedingungen Version 3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9b563482ff
commit
2bd166adf3
2 files changed
+15
-3
No files matched your search
@@ -16,6 +16,7 @@ import {
|
|||||||
createBillingPortalUrl,
|
createBillingPortalUrl,
|
||||||
getCurrentSubscription,
|
getCurrentSubscription,
|
||||||
grantCreditForInvoice,
|
grantCreditForInvoice,
|
||||||
|
minTermMonthsFor,
|
||||||
isStripeConfigured,
|
isStripeConfigured,
|
||||||
syncSubscription,
|
syncSubscription,
|
||||||
} from '../services/stripeBilling.js'
|
} from '../services/stripeBilling.js'
|
||||||
@@ -46,7 +47,8 @@ function addMonthsIso(iso, months) {
|
|||||||
|
|
||||||
function minTermEndOf(sub) {
|
function minTermEndOf(sub) {
|
||||||
const start = sub?.trialEnd || sub?.startedAt
|
const start = sub?.trialEnd || sub?.startedAt
|
||||||
return start ? addMonthsIso(start, config.abo.minTermMonths) : null
|
const months = minTermMonthsFor(sub?.termsVersion)
|
||||||
|
return start && months ? addMonthsIso(start, months) : null
|
||||||
}
|
}
|
||||||
|
|
||||||
function publicSubscription(sub) {
|
function publicSubscription(sub) {
|
||||||
@@ -179,8 +181,12 @@ async function sendContractConfirmation(subDoc) {
|
|||||||
' Preis: 50,00 € pro Monat (gemäß § 19 UStG ohne Umsatzsteuer)',
|
' Preis: 50,00 € pro Monat (gemäß § 19 UStG ohne Umsatzsteuer)',
|
||||||
` Vertragsschluss: ${fmtDate(subDoc.startedAt)}`,
|
` Vertragsschluss: ${fmtDate(subDoc.startedAt)}`,
|
||||||
` Leistungsbeginn: ${lateStart ? fmtDate(subDoc.trialEnd) : fmtDate(subDoc.startedAt)}`,
|
` Leistungsbeginn: ${lateStart ? fmtDate(subDoc.trialEnd) : fmtDate(subDoc.startedAt)}`,
|
||||||
|
...(minTermEndOf(subDoc)
|
||||||
|
? [
|
||||||
` Laufzeit: Mindestlaufzeit 12 Monate bis ${fmtDate(minTermEndOf(subDoc))}; Kündigung zu diesem Termin bis einen Monat vorher,`,
|
` Laufzeit: Mindestlaufzeit 12 Monate bis ${fmtDate(minTermEndOf(subDoc))}; Kündigung zu diesem Termin bis einen Monat vorher,`,
|
||||||
' danach läuft das Abo unbefristet und ist jederzeit zum Ende des Abrechnungsmonats kündbar',
|
' danach läuft das Abo unbefristet und ist jederzeit zum Ende des Abrechnungsmonats kündbar',
|
||||||
|
]
|
||||||
|
: [' Laufzeit: unbestimmt, jederzeit zum Ende des Abrechnungsmonats kündbar']),
|
||||||
' Enthalten: Betrieb und Pflege Ihrer Website bzw. Web-Anwendung, 1 Domain, 1 E-Mail-Postfach,',
|
' Enthalten: Betrieb und Pflege Ihrer Website bzw. Web-Anwendung, 1 Domain, 1 E-Mail-Postfach,',
|
||||||
' 1 Stunde Arbeitszeit je bezahltem Monat (12 Monate nutzbar)',
|
' 1 Stunde Arbeitszeit je bezahltem Monat (12 Monate nutzbar)',
|
||||||
'',
|
'',
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ function addMonths(date, months) {
|
|||||||
* - Wunschtermin: fruehestens zum berechneten Zeitpunkt, sonst zum Ende des Abrechnungsmonats,
|
* - Wunschtermin: fruehestens zum berechneten Zeitpunkt, sonst zum Ende des Abrechnungsmonats,
|
||||||
* in dem der Wunschtermin liegt
|
* in dem der Wunschtermin liegt
|
||||||
*/
|
*/
|
||||||
export function computeCancellationDate({ serviceStart, receivedAt = new Date(), requestedDate = null, kind = 'ordentlich' }) {
|
export function computeCancellationDate({ serviceStart, receivedAt = new Date(), requestedDate = null, kind = 'ordentlich', minTermMonths = config.abo.minTermMonths }) {
|
||||||
const start = new Date(serviceStart)
|
const start = new Date(serviceStart)
|
||||||
const boundary = (k) => addMonths(start, k)
|
const boundary = (k) => addMonths(start, k)
|
||||||
const firstBoundaryFrom = (minK, notBefore) => {
|
const firstBoundaryFrom = (minK, notBefore) => {
|
||||||
@@ -208,7 +208,7 @@ export function computeCancellationDate({ serviceStart, receivedAt = new Date(),
|
|||||||
while (boundary(k) < notBefore) k += 1
|
while (boundary(k) < notBefore) k += 1
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
const minTermK = config.abo.minTermMonths
|
const minTermK = minTermMonths
|
||||||
let k
|
let k
|
||||||
if (kind === 'geschaeftsaufgabe') {
|
if (kind === 'geschaeftsaufgabe') {
|
||||||
k = firstBoundaryFrom(1, addMonths(receivedAt, 1))
|
k = firstBoundaryFrom(1, addMonths(receivedAt, 1))
|
||||||
@@ -220,6 +220,11 @@ export function computeCancellationDate({ serviceStart, receivedAt = new Date(),
|
|||||||
return { effectiveAt: boundary(k), minTermEnd: boundary(minTermK), serviceStart: start }
|
return { effectiveAt: boundary(k), minTermEnd: boundary(minTermK), serviceStart: start }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Es gilt die Mindestlaufzeit der Bedingungen, denen der Kunde zugestimmt hat (erst ab Version 3). */
|
||||||
|
export function minTermMonthsFor(termsVersion) {
|
||||||
|
return ['2026-09-25', '2026-09-25-v2'].includes(termsVersion) ? 0 : config.abo.minTermMonths
|
||||||
|
}
|
||||||
|
|
||||||
export function serviceStartOf(sub) {
|
export function serviceStartOf(sub) {
|
||||||
return new Date(((sub.trial_end || sub.start_date) || 0) * 1000)
|
return new Date(((sub.trial_end || sub.start_date) || 0) * 1000)
|
||||||
}
|
}
|
||||||
@@ -425,6 +430,7 @@ export async function cancelSubscriptionAt(subscriptionId, requestedDate = null,
|
|||||||
receivedAt,
|
receivedAt,
|
||||||
requestedDate,
|
requestedDate,
|
||||||
kind,
|
kind,
|
||||||
|
minTermMonths: minTermMonthsFor(sub.metadata?.termsVersion),
|
||||||
})
|
})
|
||||||
const periodEnd = periodEndOf(sub)
|
const periodEnd = periodEndOf(sub)
|
||||||
const effectiveUnix = Math.floor(effectiveAt.getTime() / 1000)
|
const effectiveUnix = Math.floor(effectiveAt.getTime() / 1000)
|
||||||
|
|||||||
Reference in new issue
Block a user