Files
fotospiel-app/app/Console/Commands/CheckEventPackages.php

183 lines
7.6 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Events\Packages\EventPackageGalleryExpired;
use App\Events\Packages\EventPackageGalleryExpiring;
use App\Models\EventPackage;
use App\Services\Monitoring\PackageLimitMetrics;
use Illuminate\Console\Command;
class CheckEventPackages extends Command
{
protected $signature = 'package:check-status';
protected $description = 'Check event packages for upcoming gallery expiry and emit notifications.';
public function handle(): int
{
$warningDays = collect(config('package-limits.gallery_warning_days', []))
->filter(fn ($day) => is_numeric($day) && $day > 0)
->map(fn ($day) => (int) $day)
->unique()
->sortDesc() // handle larger days first
->values();
$eventPackageExpiryDays = collect(config('package-limits.package_expiry_days', []))
->filter(fn ($day) => is_numeric($day) && $day > 0)
->map(fn ($day) => (int) $day)
->unique()
->sortDesc()
->values();
$creditThresholds = collect(config('package-limits.credit_thresholds', []))
->filter(fn ($value) => is_numeric($value) && $value >= 0)
->map(fn ($value) => (int) $value)
->unique()
->sortDesc()
->values();
$maxCreditThreshold = $creditThresholds->max();
$now = now();
if ($maxCreditThreshold !== null) {
\App\Models\Tenant::query()
->select(['id', 'event_credits_balance', 'credit_warning_sent_at', 'credit_warning_threshold', 'contact_email'])
->chunkById(100, function ($tenants) use ($creditThresholds, $maxCreditThreshold, $now) {
foreach ($tenants as $tenant) {
$balance = (int) ($tenant->event_credits_balance ?? 0);
if ($balance > $maxCreditThreshold && $tenant->credit_warning_sent_at) {
$tenant->forceFill([
'credit_warning_sent_at' => null,
'credit_warning_threshold' => null,
])->save();
PackageLimitMetrics::recordCreditRecovery($balance);
continue;
}
foreach ($creditThresholds as $threshold) {
if (
$balance <= $threshold
&& (
$tenant->credit_warning_sent_at === null
|| $threshold < ($tenant->credit_warning_threshold ?? PHP_INT_MAX)
)
) {
event(new \App\Events\Packages\TenantCreditsLow($tenant, $balance, $threshold));
PackageLimitMetrics::recordCreditWarning($threshold, $balance);
$tenant->forceFill([
'credit_warning_sent_at' => $now,
'credit_warning_threshold' => $threshold,
])->save();
break;
}
}
}
});
}
EventPackage::query()
->whereNotNull('gallery_expires_at')
->chunkById(100, function ($packages) use ($warningDays, $now) {
foreach ($packages as $package) {
$expiresAt = $package->gallery_expires_at;
if (! $expiresAt) {
continue;
}
$daysDiff = $now->diffInDays($expiresAt, false);
if ($warningDays->isNotEmpty() && $package->gallery_warning_sent_at) {
$maxWarningDay = $warningDays->max();
if ($maxWarningDay !== null && $daysDiff > $maxWarningDay) {
$package->forceFill([
'gallery_warning_sent_at' => null,
])->save();
}
}
if ($daysDiff < 0) {
if (! $package->gallery_expired_notified_at) {
event(new EventPackageGalleryExpired($package));
PackageLimitMetrics::recordGalleryExpired();
$package->forceFill([
'gallery_expired_notified_at' => $now,
])->save();
}
continue;
}
if ($warningDays->isEmpty()) {
continue;
}
if ($package->gallery_warning_sent_at) {
continue;
}
foreach ($warningDays as $day) {
if ($daysDiff <= $day && $daysDiff >= 0) {
event(new EventPackageGalleryExpiring($package, $day));
PackageLimitMetrics::recordGalleryWarning($day);
$package->forceFill([
'gallery_warning_sent_at' => $now,
])->save();
break;
}
}
}
});
\App\Models\TenantPackage::query()
->with(['tenant', 'package'])
->whereNotNull('expires_at')
->chunkById(100, function ($tenantPackages) use ($eventPackageExpiryDays, $now) {
foreach ($tenantPackages as $tenantPackage) {
$expiresAt = $tenantPackage->expires_at;
if (! $expiresAt) {
continue;
}
$daysDiff = $now->diffInDays($expiresAt, false);
if ($daysDiff < 0) {
if (! $tenantPackage->expired_notified_at) {
event(new \App\Events\Packages\TenantPackageExpired($tenantPackage));
PackageLimitMetrics::recordTenantPackageExpired();
$tenantPackage->forceFill(['expired_notified_at' => $now])->save();
}
continue;
}
if ($eventPackageExpiryDays->isNotEmpty() && $tenantPackage->expiry_warning_sent_at) {
$maxTenantWarning = $eventPackageExpiryDays->max();
if ($maxTenantWarning !== null && $daysDiff > $maxTenantWarning) {
$tenantPackage->forceFill(['expiry_warning_sent_at' => null])->save();
} else {
continue;
}
} elseif ($tenantPackage->expiry_warning_sent_at) {
$tenantPackage->forceFill(['expiry_warning_sent_at' => null])->save();
}
foreach ($eventPackageExpiryDays as $day) {
if ($daysDiff <= $day && $daysDiff >= 0) {
event(new \App\Events\Packages\TenantPackageExpiring($tenantPackage, $day));
PackageLimitMetrics::recordTenantPackageWarning($day);
$tenantPackage->forceFill(['expiry_warning_sent_at' => $now])->save();
break;
}
}
}
});
return self::SUCCESS;
}
}