diff --git a/app/Console/Commands/SendExpirationAlerts.php b/app/Console/Commands/SendExpirationAlerts.php index 025ba2ce23..1220e0cd9d 100644 --- a/app/Console/Commands/SendExpirationAlerts.php +++ b/app/Console/Commands/SendExpirationAlerts.php @@ -2,13 +2,13 @@ namespace App\Console\Commands; +use App\Mail\ExpiringAssetsMail; +use App\Mail\ExpiringLicenseMail; use App\Models\Asset; use App\Models\License; -use App\Models\Recipients\AlertRecipient; use App\Models\Setting; -use App\Notifications\ExpiringAssetsNotification; -use App\Notifications\ExpiringLicenseNotification; use Illuminate\Console\Command; +use Illuminate\Support\Facades\Mail; class SendExpirationAlerts extends Command { @@ -47,22 +47,22 @@ class SendExpirationAlerts extends Command if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) { // Send a rollup to the admin, if settings dictate - $recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) { - return new AlertRecipient($item); - }); - + $recipients = collect(explode(',', $settings->alert_email)) + ->map(fn($item) => trim($item)) // Trim each email + ->all(); // Expiring Assets $assets = Asset::getExpiringWarrantee($threshold); + if ($assets->count() > 0) { $this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold])); - \Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold)); + Mail::to($recipients)->send(new ExpiringAssetsMail($assets, $threshold)); } // Expiring licenses $licenses = License::getExpiringLicenses($threshold); if ($licenses->count() > 0) { $this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $threshold])); - \Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold)); + Mail::to($recipients)->send(new ExpiringLicenseMail($licenses, $threshold)); } } else { if ($settings->alert_email == '') { diff --git a/app/Mail/ExpiringAssetsMail.php b/app/Mail/ExpiringAssetsMail.php new file mode 100644 index 0000000000..13d322f060 --- /dev/null +++ b/app/Mail/ExpiringAssetsMail.php @@ -0,0 +1,62 @@ +assets = $params; + $this->threshold = $threshold; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(config('mail.from.address'), config('mail.from.name')); + + return new Envelope( + from: $from, + subject: trans('mail.Expiring_Assets_Report'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + markdown: 'notifications.markdown.report-expiring-assets', + with: [ + 'assets' => $this->assets, + 'threshold' => $this->threshold, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/ExpiringLicenseMail.php b/app/Mail/ExpiringLicenseMail.php new file mode 100644 index 0000000000..77d94df637 --- /dev/null +++ b/app/Mail/ExpiringLicenseMail.php @@ -0,0 +1,62 @@ +licenses = $params; + $this->threshold = $threshold; + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = new Address(config('mail.from.address'), config('mail.from.name')); + + return new Envelope( + from: $from, + subject: trans('mail.Expiring_Licenses_Report'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + markdown: 'notifications.markdown.report-expiring-licenses', + with: [ + 'licenses' => $this->licenses, + 'threshold' => $this->threshold, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/tests/Feature/Notifications/Email/ExpiringAlertsNotificationTest.php b/tests/Feature/Notifications/Email/ExpiringAlertsNotificationTest.php new file mode 100644 index 0000000000..220f6543c8 --- /dev/null +++ b/tests/Feature/Notifications/Email/ExpiringAlertsNotificationTest.php @@ -0,0 +1,91 @@ +markIncompleteIfSqlite(); + Mail::fake(); + + $this->settings->enableAlertEmail('admin@example.com'); + $this->settings->setAlertInterval(30); + + $alert_email = Setting::first()->alert_email; + + $expiringAsset = Asset::factory()->create([ + 'purchase_date' => now()->subMonths(11)->format('Y-m-d'), + 'warranty_months' => 12, + 'archived' => 0, + 'deleted_at' => null, + ]); + + $expiredAsset = Asset::factory()->create([ + 'purchase_date' => now()->subMonths(13)->format('Y-m-d'), + 'warranty_months' => 12, + 'archived' => 0, + 'deleted_at' => null, + ]); + $notExpiringAsset = Asset::factory()->create([ + 'purchase_date' => now()->subMonths(10)->format('Y-m-d'), + 'warranty_months' => 12, + 'archived' => 0, + 'deleted_at' => null, + ]); + + $this->artisan('snipeit:expiring-alerts')->assertExitCode(0); + + Mail::assertSent(ExpiringAssetsMail::class, function($mail) use ($alert_email, $expiringAsset) { + return $mail->hasTo($alert_email) && $mail->assets->contains($expiringAsset); + }); + + Mail::assertNotSent(ExpiringAssetsMail::class, function($mail) use ($expiredAsset, $notExpiringAsset) { + return $mail->assets->contains($expiredAsset) || $mail->assets->contains($notExpiringAsset); + }); + } + + public function testExpiringLicensesEmailNotification() + { + $this->markIncompleteIfSqlite(); + Mail::fake(); + $this->settings->enableAlertEmail('admin@example.com'); + $this->settings->setAlertInterval(60); + + $alert_email = Setting::first()->alert_email; + + $expiringLicense = License::factory()->create([ + 'expiration_date' => now()->addDays(30)->format('Y-m-d'), + 'deleted_at' => null, + ]); + + $expiredLicense = License::factory()->create([ + 'expiration_date' => now()->subDays(10)->format('Y-m-d'), + 'deleted_at' => null, + ]); + $notExpiringLicense = License::factory()->create([ + 'expiration_date' => now()->addMonths(3)->format('Y-m-d'), + 'deleted_at' => null, + ]); + + $this->artisan('snipeit:expiring-alerts')->assertExitCode(0); + + Mail::assertSent(ExpiringLicenseMail::class, function($mail) use ($alert_email, $expiringLicense) { + return $mail->hasTo($alert_email) && $mail->licenses->contains($expiringLicense); + }); + + Mail::assertNotSent(ExpiringLicenseMail::class, function($mail) use ($expiredLicense, $notExpiringLicense) { + return $mail->licenses->contains($expiredLicense) || $mail->licenses->contains($notExpiringLicense); + }); + } +} \ No newline at end of file diff --git a/tests/Support/Settings.php b/tests/Support/Settings.php index e171c0ab95..09d40974c1 100644 --- a/tests/Support/Settings.php +++ b/tests/Support/Settings.php @@ -21,12 +21,23 @@ class Settings public function enableAlertEmail(string $email = 'notifications@afcrichmond.com'): Settings { - return $this->update(['alert_email' => $email]); + return $this->update([ + 'alert_email' => $email, + 'alerts_enabled' => 1, + ]); + } + public function setAlertInterval(int $days): Settings + { + return $this->update([ + 'alert_threshold' => $days, + ]); } - public function disableAlertEmail(): Settings { - return $this->update(['alert_email' => null]); + return $this->update([ + 'alert_email' => null, + 'alerts_enabled' => 0, + ]); } public function enableMultipleFullCompanySupport(): Settings