Deploy Ladill Woo Manager / deploy (push) Successful in 2m11s
New order, store connected, Pro expiry, and past-due alerts use the Ladill notification layout with woo branding; expiry reminders dedupe per threshold like hosting. Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
2.6 KiB
PHP
83 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Woo;
|
|
|
|
use App\Models\Woo\ProSubscription;
|
|
|
|
/** Sends one-time Woo Manager Pro/Business expiry reminders. */
|
|
class WooProExpiryAlertService
|
|
{
|
|
public function __construct(private readonly WooNotificationService $notifications) {}
|
|
|
|
/** @return list<int> */
|
|
public function milestones(): array
|
|
{
|
|
return array_values(array_map(
|
|
'intval',
|
|
(array) config('notifications.pro_expiry_milestones', [7, 3, 1])
|
|
));
|
|
}
|
|
|
|
public function checkAll(): int
|
|
{
|
|
$sent = 0;
|
|
|
|
ProSubscription::query()
|
|
->whereIn('status', [ProSubscription::STATUS_ACTIVE, ProSubscription::STATUS_CANCELED])
|
|
->whereNotNull('current_period_end')
|
|
->where('current_period_end', '>', now())
|
|
->with('user')
|
|
->each(function (ProSubscription $subscription) use (&$sent): void {
|
|
if ($this->checkSubscription($subscription)) {
|
|
$sent++;
|
|
}
|
|
});
|
|
|
|
return $sent;
|
|
}
|
|
|
|
public function checkSubscription(ProSubscription $subscription): bool
|
|
{
|
|
if (! $subscription->current_period_end || ! $subscription->user || $subscription->current_period_end->isPast()) {
|
|
return false;
|
|
}
|
|
|
|
if ($subscription->auto_renew && $subscription->status === ProSubscription::STATUS_ACTIVE) {
|
|
return false;
|
|
}
|
|
|
|
$daysRemaining = $this->daysUntilExpiry($subscription);
|
|
if (! in_array($daysRemaining, $this->milestones(), true)) {
|
|
return false;
|
|
}
|
|
|
|
$metadata = is_array($subscription->metadata) ? $subscription->metadata : [];
|
|
$sent = array_map('intval', (array) ($metadata['expiry_alerts_sent'] ?? []));
|
|
if (in_array($daysRemaining, $sent, true)) {
|
|
return false;
|
|
}
|
|
|
|
$this->notifications->proExpiring($subscription, $daysRemaining);
|
|
|
|
$metadata['expiry_alerts_sent'] = array_values(array_unique([...$sent, $daysRemaining]));
|
|
$subscription->update(['metadata' => $metadata]);
|
|
|
|
return true;
|
|
}
|
|
|
|
public function resetAlerts(ProSubscription $subscription): void
|
|
{
|
|
$metadata = is_array($subscription->metadata) ? $subscription->metadata : [];
|
|
unset($metadata['expiry_alerts_sent']);
|
|
$subscription->update(['metadata' => $metadata]);
|
|
}
|
|
|
|
private function daysUntilExpiry(ProSubscription $subscription): int
|
|
{
|
|
return (int) now()->startOfDay()->diffInDays(
|
|
$subscription->current_period_end->copy()->startOfDay(),
|
|
false
|
|
);
|
|
}
|
|
}
|