Deploy Ladill Transfer / deploy (push) Successful in 44s
Recipients can be emailed the download link immediately and at optional reminders (7/3/1 days before unavailable, or when grace period starts). Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
2.9 KiB
PHP
100 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Transfer;
|
|
|
|
use App\Models\Transfer;
|
|
use App\Notifications\TransferRecipientNotification;
|
|
use Carbon\CarbonInterface;
|
|
use Illuminate\Support\Facades\Notification;
|
|
|
|
/** Sends milestone emails to transfer recipients (share link + reminders). */
|
|
class TransferRecipientMailService
|
|
{
|
|
/** @return list<string> */
|
|
public function allowedMilestones(): array
|
|
{
|
|
return array_keys((array) config('transfer.recipient_email_milestones', []));
|
|
}
|
|
|
|
/** @return array<string, string> */
|
|
public function milestoneOptions(): array
|
|
{
|
|
return (array) config('transfer.recipient_email_milestones', []);
|
|
}
|
|
|
|
/** @param list<string> $milestones */
|
|
public function normalizeMilestones(array $milestones): array
|
|
{
|
|
$allowed = $this->allowedMilestones();
|
|
|
|
return array_values(array_unique(array_filter(
|
|
$milestones,
|
|
static fn ($milestone) => in_array((string) $milestone, $allowed, true),
|
|
)));
|
|
}
|
|
|
|
public function notifyRecipient(Transfer $transfer, string $milestone): bool
|
|
{
|
|
$email = trim((string) $transfer->recipient_email);
|
|
if ($email === '' || ! $transfer->wantsRecipientMilestone($milestone)) {
|
|
return false;
|
|
}
|
|
|
|
if ($transfer->recipientMilestoneSent($milestone)) {
|
|
return false;
|
|
}
|
|
|
|
Notification::route('mail', $email)->notify(
|
|
new TransferRecipientNotification($transfer->loadMissing(['files', 'qrCode', 'user']), $milestone),
|
|
);
|
|
|
|
$transfer->markRecipientMilestoneSent($milestone);
|
|
|
|
return true;
|
|
}
|
|
|
|
public function processDueMilestones(): int
|
|
{
|
|
$sent = 0;
|
|
|
|
Transfer::query()
|
|
->accessible()
|
|
->whereNotNull('recipient_email')
|
|
->whereNotNull('recipient_email_milestones')
|
|
->with(['files', 'qrCode', 'user'])
|
|
->chunkById(100, function ($transfers) use (&$sent) {
|
|
foreach ($transfers as $transfer) {
|
|
foreach ($this->dueDayMilestones($transfer) as $milestone) {
|
|
if ($this->notifyRecipient($transfer, $milestone)) {
|
|
$sent++;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return $sent;
|
|
}
|
|
|
|
/** @return list<string> */
|
|
private function dueDayMilestones(Transfer $transfer): array
|
|
{
|
|
if (! $transfer->paid_until instanceof CarbonInterface || $transfer->paid_until->isPast()) {
|
|
return [];
|
|
}
|
|
|
|
$daysRemaining = (int) now()->startOfDay()->diffInDays(
|
|
$transfer->paid_until->copy()->startOfDay(),
|
|
false,
|
|
);
|
|
|
|
$due = [];
|
|
foreach (['7', '3', '1'] as $milestone) {
|
|
if ($daysRemaining === (int) $milestone && $transfer->wantsRecipientMilestone($milestone)) {
|
|
$due[] = $milestone;
|
|
}
|
|
}
|
|
|
|
return $due;
|
|
}
|
|
}
|