*/ public function graceMilestones(): array { return array_values(array_map( 'strval', (array) config('transfer.owner_grace_email_milestones', ['grace_entered', '7', '3', '1']), )); } public function notifyGraceEntered(Transfer $transfer): bool { return $this->notifyOwner($transfer, 'grace_entered'); } public function processGraceReminders(): int { $sent = 0; Transfer::query() ->where('status', Transfer::STATUS_GRACE) ->whereNotNull('grace_ends_at') ->where('grace_ends_at', '>', now()) ->with('user') ->chunkById(100, function ($transfers) use (&$sent) { foreach ($transfers as $transfer) { foreach ($this->dueGraceDayMilestones($transfer) as $milestone) { if ($this->notifyOwner($transfer, $milestone)) { $sent++; } } } }); return $sent; } /** @return list */ private function dueGraceDayMilestones(Transfer $transfer): array { if (! $transfer->grace_ends_at instanceof CarbonInterface) { return []; } $daysRemaining = (int) now()->startOfDay()->diffInDays( $transfer->grace_ends_at->copy()->startOfDay(), false, ); $due = []; foreach (['7', '3', '1'] as $milestone) { if ($daysRemaining === (int) $milestone && in_array($milestone, $this->graceMilestones(), true)) { $due[] = $milestone; } } return $due; } private function notifyOwner(Transfer $transfer, string $milestone): bool { if (! in_array($milestone, $this->graceMilestones(), true)) { return false; } if ($transfer->ownerMilestoneSent($milestone)) { return false; } $user = $transfer->user; if ($user === null) { return false; } $user->notify(new TransferOwnerGraceNotification( $transfer->loadMissing(['files', 'qrCode']), $milestone, )); $transfer->markOwnerMilestoneSent($milestone); return true; } }