Abo: Doppelbestellung verhindern, Payment-Link loeschen & Pending-Status

Verhindert das Anlegen eines zweiten Abos (eigenes oder Kundenabo) wenn
bereits eines initiiert ist bzw. ein offener Abo-Payment-Link existiert
(redirectIfAboAlreadyInitiated). Payment-Links koennen jetzt geloescht
werden, abgesichert ueber canDeleteInstance + Shop-Zugehoerigkeit, mit
Erfolgs-/Fehler-Flash. Kundenabo-Uebersicht zeigt den Pending-Initial-
Payment-Status (wartend / in Bearbeitung / fehlgeschlagen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kevin 2026-06-25 13:37:30 +00:00
parent 42ef4dd1c6
commit 2b2847add1
7 changed files with 386 additions and 23 deletions

View file

@ -4,6 +4,8 @@ namespace App\Services;
use App\Models\ShoppingInstance;
use App\Models\ShoppingUser;
use App\Models\UserAbo;
use App\User;
use Yard;
class OrderPaymentService
@ -21,6 +23,52 @@ class OrderPaymentService
}*/
}
public static function isAboCustomerPaymentLink(ShoppingInstance $shoppingInstance): bool
{
return (int) $shoppingInstance->payment === 6
&& ($shoppingInstance->shopping_data['is_for'] ?? null) === 'abo-ot-customer'
&& (bool) ($shoppingInstance->shopping_data['is_abo'] ?? false);
}
public static function canDeleteInstance(ShoppingInstance $shoppingInstance): bool
{
return in_array((int) $shoppingInstance->status, [0, 1, 5, 6], true);
}
public static function isPaymentProcessing(ShoppingInstance $shoppingInstance): bool
{
return in_array((int) $shoppingInstance->status, [2, 3, 4], true);
}
public static function isPaymentFailed(ShoppingInstance $shoppingInstance): bool
{
return in_array((int) $shoppingInstance->status, [5, 6], true);
}
public static function hasUserAboForPaymentLink(ShoppingInstance $shoppingInstance, User $user): bool
{
$shoppingUserId = (int) ($shoppingInstance->shopping_user_id ?: ($shoppingInstance->shopping_data['shopping_user_id'] ?? 0));
$email = trim((string) ($shoppingInstance->shopping_data['billing_email'] ?? ''));
if ($shoppingUserId <= 0 && $email === '') {
return false;
}
return UserAbo::where('member_id', $user->id)
->where('is_for', 'ot')
->where('status', '>=', 1)
->where(function ($query) use ($shoppingUserId, $email) {
if ($shoppingUserId > 0) {
$query->orWhere('shopping_user_id', $shoppingUserId);
}
if ($email !== '') {
$query->orWhereRaw('LOWER(email) = ?', [mb_strtolower($email)]);
}
})
->exists();
}
public static function updateInstanceStatus($identifier, $status, $lower = true)
{
if (! ShoppingInstance::where('identifier', $identifier)->exists()) {