Abo (A3): Status und Grund eines Abos sichtbar machen
Neue Spalten user_abos.status_reason / paused_until und
user_abo_orders.error_message. Der Grund wird zentral am Model gepflegt
(saving-Event): Zahlungsfehler, Kuendigung/Deaktivierung mit Akteur aus dem
Formular-Kanal, Loeschen beim Zurueckkehren in den Lauf; die Pause setzt
paused_until und paused_by_*. Cron- und Retry-Zahlung schreiben den Fehlertext
des Anbieters an die Abo-Bestellung.
AboStatusExplainer uebersetzt das in einen Satz ("Pausiert bis ... vom Kunden
am ...", "Zahlung am ... fehlgeschlagen - Grund: ...", "Gekuendigt am ... vom
Berater"), Partial _status_explain in Abo-Detail (CRM, Portal, Admin),
Abo-Uebersicht, Kundenabo-Liste, Team-Kundenabos und Admin-Datatable; dort
neuer Filter "Zustand" (pausiert / Zahlung fehlgeschlagen). Backfill-Kommando
abo:backfill-status-reasons fuer Bestandsdaten, Fallback ueber das
Statusprotokoll und die Pausenfelder.
Sprachdateien de/en/es/fr, Tests in AboStatusExplainTest, Plan-Status.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
e8057f9f7b
commit
d6efe56cd4
22 changed files with 977 additions and 15 deletions
|
|
@ -5,6 +5,7 @@ namespace App\Services;
|
|||
use App\Cron\UserMakeOrder;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboOrder;
|
||||
use App\Services\Abo\AboStatusExplainer;
|
||||
use App\Services\Incentive\IncentiveTracker;
|
||||
use App\Services\Payment\PaymentProviderManager;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -86,7 +87,7 @@ class AboRetryPaymentService
|
|||
}
|
||||
|
||||
$this->logPaymentError($userAbo, $shoppingOrder, $response);
|
||||
$this->markAboError($userAbo, $shoppingOrder);
|
||||
$this->markAboError($userAbo, $shoppingOrder, AboStatusExplainer::paymentErrorMessage($response));
|
||||
$paymentAttemptRecorded = true;
|
||||
$this->sendPaymentErrorMail($userOrder, $shoppingOrder, $response);
|
||||
|
||||
|
|
@ -107,7 +108,7 @@ class AboRetryPaymentService
|
|||
]);
|
||||
|
||||
if ($shoppingOrder && ! $paymentAttemptRecorded) {
|
||||
$this->markAboError($userAbo, $shoppingOrder);
|
||||
$this->markAboError($userAbo, $shoppingOrder, mb_substr('Exception: '.$e->getMessage(), 0, 255));
|
||||
}
|
||||
|
||||
return [
|
||||
|
|
@ -170,9 +171,9 @@ class AboRetryPaymentService
|
|||
AboOneTimeService::purgeAfterExecution($userAbo);
|
||||
}
|
||||
|
||||
private function markAboError(UserAbo $userAbo, mixed $shoppingOrder): void
|
||||
private function markAboError(UserAbo $userAbo, mixed $shoppingOrder, ?string $errorMessage = null): void
|
||||
{
|
||||
DB::transaction(function () use ($userAbo, $shoppingOrder): void {
|
||||
DB::transaction(function () use ($userAbo, $shoppingOrder, $errorMessage): void {
|
||||
$userAbo->update([
|
||||
'status' => 3,
|
||||
'last_date' => now(),
|
||||
|
|
@ -182,6 +183,7 @@ class AboRetryPaymentService
|
|||
'user_abo_id' => $userAbo->id,
|
||||
'shopping_order_id' => $shoppingOrder->id,
|
||||
'status' => 3,
|
||||
'error_message' => $errorMessage,
|
||||
'paid' => false,
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue