Abo Einmalprodukte und Bestätigung abschließen

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin 2026-06-05 15:28:08 +00:00
parent 2bdc9ada3c
commit 2269ce031f
57 changed files with 3647 additions and 371 deletions

View file

@ -21,6 +21,12 @@ class AboHelper
*/
public const MIN_DAYS_UNTIL_FIRST_ABO_EXECUTION = 10;
/**
* Standard-Zeitfenster (Kalendertage) vor der Ausführung, in dem einmalige
* Produkte aus dem normalen Sortiment hinzugefügt werden dürfen.
*/
public const DEFAULT_ONETIME_WINDOW_DAYS = 4;
public static $txaction_filter_text = [
'paid' => 'paymend_paid',
'appointed' => 'paymend_open',
@ -168,6 +174,41 @@ class AboHelper
return $nextDate->gt($date) ? $nextDate : $nextDate->addMonth(1);
}
/**
* Konfiguriertes Zeitfenster (Kalendertage) für einmalige Produkte vor der Ausführung.
*/
public static function getOneTimeWindowDays(): int
{
$days = (int) \App\Models\Setting::getContentBySlug('abo-onetime-window-days');
return $days > 0 ? $days : self::DEFAULT_ONETIME_WINDOW_DAYS;
}
/**
* Prüft, ob für dieses Abo aktuell einmalig Produkte aus dem normalen
* Bestellsortiment hinzugefügt werden dürfen (Zeitfenster vor der Ausführung).
*
* Nur die zeitliche Bedingung wird geprüft. Aufrufer sollten zusätzlich den
* Abo-Zustand (active/status) berücksichtigen, falls relevant.
*/
public static function isOneTimeWindowOpen(UserAbo $userAbo): bool
{
if (! $userAbo->next_date) {
return false;
}
$today = Carbon::today();
$nextDate = Carbon::parse($userAbo->next_date)->startOfDay();
if ($nextDate->lt($today)) {
return false;
}
$daysUntilExecution = $today->diffInDays($nextDate);
return $daysUntilExecution <= self::getOneTimeWindowDays();
}
public static function getFirstAboDate($date, $abo_interval)
{
$reference = Carbon::parse($date)->startOfDay();