CluPilotCloud/app/Actions/OpenDunningCase.php

49 lines
1.6 KiB
PHP

<?php
namespace App\Actions;
use App\Models\DunningCase;
use App\Models\Subscription;
use App\Services\Billing\DunningSchedule;
use Illuminate\Support\Carbon;
/**
* Der Fall, der entsteht, wenn eine Abbuchung zum ersten Mal scheitert.
*
* Hängt an ApplyStripeBillingEvent::invoicePaymentFailed(), das bis hierher
* `past_due` setzte und schwieg. Der Kunde erfuhr davon erst, wenn seine Cloud
* stand.
*
* JE RECHNUNG GENAU EINMAL. Stripe versucht dieselbe Rechnung mehrfach, und
* jeder Versuch ist ein eigenes Ereignis — ohne diese Bedingung entstünden drei
* Fälle für eine Schuld, mit drei Mahnläufen und dreifachen Gebühren. Die
* Eindeutigkeit steht zusätzlich als Index in der Tabelle, damit zwei
* gleichzeitig eintreffende Ereignisse sie nicht umgehen können.
*
* Eröffnet wird auf Stufe 0 — dem HINWEIS. Keine Mahnung, keine Gebühr: eine
* abgelaufene Karte ist keine Zahlungsverweigerung.
*/
class OpenDunningCase
{
public function __invoke(Subscription $subscription, string $invoiceId): ?DunningCase
{
if ($invoiceId === '') {
return null;
}
$now = Carbon::now();
return DunningCase::query()->firstOrCreate(
['stripe_invoice_id' => $invoiceId],
[
'subscription_id' => $subscription->id,
'level' => 0,
'opened_at' => $now,
// Die erste Mahnung, nicht der Hinweis: der geht sofort hinaus.
'next_step_at' => $now->copy()->addDays(DunningSchedule::dayOfLevel(1)),
'fee_invoice_ids' => [],
],
);
}
}