mirror of
https://github.com/snipe/snipe-it.git
synced 2025-03-05 20:52:15 -08:00
Merge pull request #16232 from Godmartinz/adds-expiring-notifications
Expiration notifcation switched to use Mailable
This commit is contained in:
commit
ff1157a95e
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Mail\ExpiringAssetsMail;
|
||||||
|
use App\Mail\ExpiringLicenseMail;
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\License;
|
use App\Models\License;
|
||||||
use App\Models\Recipients\AlertRecipient;
|
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Notifications\ExpiringAssetsNotification;
|
|
||||||
use App\Notifications\ExpiringLicenseNotification;
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
class SendExpirationAlerts extends Command
|
class SendExpirationAlerts extends Command
|
||||||
{
|
{
|
||||||
|
@ -47,22 +47,22 @@ class SendExpirationAlerts extends Command
|
||||||
if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) {
|
if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) {
|
||||||
|
|
||||||
// Send a rollup to the admin, if settings dictate
|
// Send a rollup to the admin, if settings dictate
|
||||||
$recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) {
|
$recipients = collect(explode(',', $settings->alert_email))
|
||||||
return new AlertRecipient($item);
|
->map(fn($item) => trim($item)) // Trim each email
|
||||||
});
|
->all();
|
||||||
|
|
||||||
// Expiring Assets
|
// Expiring Assets
|
||||||
$assets = Asset::getExpiringWarrantee($threshold);
|
$assets = Asset::getExpiringWarrantee($threshold);
|
||||||
|
|
||||||
if ($assets->count() > 0) {
|
if ($assets->count() > 0) {
|
||||||
$this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold]));
|
$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
|
// Expiring licenses
|
||||||
$licenses = License::getExpiringLicenses($threshold);
|
$licenses = License::getExpiringLicenses($threshold);
|
||||||
if ($licenses->count() > 0) {
|
if ($licenses->count() > 0) {
|
||||||
$this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $threshold]));
|
$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 {
|
} else {
|
||||||
if ($settings->alert_email == '') {
|
if ($settings->alert_email == '') {
|
||||||
|
|
62
app/Mail/ExpiringAssetsMail.php
Normal file
62
app/Mail/ExpiringAssetsMail.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Address;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ExpiringAssetsMail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*/
|
||||||
|
public function __construct($params, $threshold)
|
||||||
|
{
|
||||||
|
$this->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<int, \Illuminate\Mail\Mailables\Attachment>
|
||||||
|
*/
|
||||||
|
public function attachments(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
62
app/Mail/ExpiringLicenseMail.php
Normal file
62
app/Mail/ExpiringLicenseMail.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Address;
|
||||||
|
use Illuminate\Mail\Mailables\Content;
|
||||||
|
use Illuminate\Mail\Mailables\Envelope;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ExpiringLicenseMail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*/
|
||||||
|
public function __construct($params, $threshold)
|
||||||
|
{
|
||||||
|
$this->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<int, \Illuminate\Mail\Mailables\Attachment>
|
||||||
|
*/
|
||||||
|
public function attachments(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature\Notifications\Email;
|
||||||
|
|
||||||
|
use App\Mail\ExpiringAssetsMail;
|
||||||
|
use App\Mail\ExpiringLicenseMail;
|
||||||
|
use App\Models\Asset;
|
||||||
|
use App\Models\License;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
|
||||||
|
class ExpiringAlertsNotificationTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testExpiringAssetsEmailNotification()
|
||||||
|
{
|
||||||
|
$this->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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,12 +21,23 @@ class Settings
|
||||||
|
|
||||||
public function enableAlertEmail(string $email = 'notifications@afcrichmond.com'): 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
|
public function disableAlertEmail(): Settings
|
||||||
{
|
{
|
||||||
return $this->update(['alert_email' => null]);
|
return $this->update([
|
||||||
|
'alert_email' => null,
|
||||||
|
'alerts_enabled' => 0,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function enableMultipleFullCompanySupport(): Settings
|
public function enableMultipleFullCompanySupport(): Settings
|
||||||
|
|
Loading…
Reference in a new issue