Block 5 — MAN-Abrechnung F06 (E6): Ein explizites Legacy-Vertragsende (grandfathered_until) deckelt jetzt Auswahl und Sperr-Nachprüfung: Beginnt die nächste Periode nach dem Vertragsende, gibt es keine Rechnung mehr. Neuer täglicher Befehl billing:expire-grandfathering (04:15, vor dem Rechnungslauf) setzt abgelaufene Posten auf gekündigt und schickt je Kunde eine Mail (GrandfatheringExpired). Auf der Dev-Kopie trägt kein Posten ein Vertragsende; der Fehler war latent. F16: Nicht abrechenbare Vereinbarungen bekommen einen Sperrvermerk (billing_hold_reason/-at), sichtbar auf der Admin-Zahlungsseite, und stehen im Rechnungslauf hinten an. Der Lauf arbeitet den fälligen Bestand in Seiten ab; --limit deckelt die erstellten Rechnungen (500), nicht die betrachteten Fälle. Vorher blockierten 50 unvollständige Fälle die 51. dauerhaft, und der Durchsatz war auf 50 am Tag begrenzt. Block 6 — Entwicklung F24: Lint-Workflow prüft mit pint --test statt zu formatieren; keine Schreibrechte mehr. F27: composer run dev startet beide Vite-Server (npm run dev:all). F28: docs/README.md als historischer Stand markiert, toter Link auf das Hub-Flux-Archiv korrigiert, aktueller Einstieg dev/README.md. F26: Login-Modal übernimmt den Fokus, hält Tab im Dialog und gibt den Fokus beim Schließen an den Auslöser zurück – ohne neue Abhängigkeit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
48 lines
1.3 KiB
PHP
48 lines
1.3 KiB
PHP
<?php
|
|
|
|
namespace App\Mail;
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Bus\Queueable;
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
use Illuminate\Mail\Mailable;
|
|
use Illuminate\Mail\Mailables\Content;
|
|
use Illuminate\Mail\Mailables\Envelope;
|
|
use Illuminate\Queue\SerializesModels;
|
|
use Illuminate\Support\Carbon;
|
|
|
|
/**
|
|
* Information an den Kunden, dass sein Bestandsschutz zum vertraglich
|
|
* vereinbarten Ende ausgelaufen ist (Audit F06) — keine Mahnung, keine
|
|
* Stornierung, nur der Hinweis, wie es weitergeht.
|
|
*
|
|
* Transaktionsmail: bewusst ohne Opt-out.
|
|
*/
|
|
class GrandfatheringExpired extends Mailable implements ShouldQueue
|
|
{
|
|
use Queueable, SerializesModels;
|
|
|
|
public string $bookingUrl;
|
|
|
|
public function __construct(
|
|
public readonly User $user,
|
|
public readonly ?Carbon $endedOn,
|
|
) {
|
|
$this->bookingUrl = route('me.bookings.index');
|
|
}
|
|
|
|
public function envelope(): Envelope
|
|
{
|
|
$bcc = (string) config('legal.contact_email');
|
|
|
|
return new Envelope(
|
|
subject: 'Ihr Bestandsschutz auf pressekonto ist zum Vertragsende ausgelaufen',
|
|
bcc: $bcc !== '' ? [$bcc] : [],
|
|
);
|
|
}
|
|
|
|
public function content(): Content
|
|
{
|
|
return new Content(view: 'emails.billing.grandfathering-expired');
|
|
}
|
|
}
|