Skip to content

Commit f0813e0

Browse files
authored
Merge pull request #15681 from Godmartinz/seperating_notification_n_mail
Separated Notifications and Emails: Check ins and Check outs
2 parents 05875eb + 58ff641 commit f0813e0

32 files changed

+793
-397
lines changed

app/Http/Controllers/Account/AcceptanceController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,4 +338,5 @@ public function store(Request $request, $id) : RedirectResponse
338338
return redirect()->to('account/accept')->with('success', $return_msg);
339339

340340
}
341+
341342
}

app/Listeners/CheckoutableListener.php

Lines changed: 84 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@
33
namespace App\Listeners;
44

55
use App\Events\CheckoutableCheckedOut;
6+
use App\Mail\CheckinAccessoryMail;
7+
use App\Mail\CheckinLicenseMail;
8+
use App\Mail\CheckoutAccessoryMail;
9+
use App\Mail\CheckoutAssetMail;
10+
use App\Mail\CheckinAssetMail;
11+
use App\Mail\CheckoutConsumableMail;
12+
use App\Mail\CheckoutLicenseMail;
613
use App\Models\Accessory;
714
use App\Models\Asset;
815
use App\Models\CheckoutAcceptance;
916
use App\Models\Component;
1017
use App\Models\Consumable;
1118
use App\Models\LicenseSeat;
12-
use App\Models\Recipients\AdminRecipient;
1319
use App\Models\Setting;
1420
use App\Models\User;
1521
use App\Notifications\CheckinAccessoryNotification;
@@ -20,6 +26,7 @@
2026
use App\Notifications\CheckoutConsumableNotification;
2127
use App\Notifications\CheckoutLicenseSeatNotification;
2228
use GuzzleHttp\Exception\ClientException;
29+
use Illuminate\Support\Facades\Mail;
2330
use Illuminate\Support\Facades\Notification;
2431
use Exception;
2532
use Illuminate\Support\Facades\Log;
@@ -43,33 +50,42 @@ public function onCheckedOut($event)
4350
/**
4451
* Make a checkout acceptance and attach it in the notification
4552
*/
53+
$settings = Setting::getSettings();
4654
$acceptance = $this->getCheckoutAcceptance($event);
47-
$notifiables = $this->getNotifiables($event);
55+
$adminCcEmailsArray = [];
4856

57+
if($settings->admin_cc_email !== '') {
58+
$adminCcEmail = $settings->admin_cc_email;
59+
$adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail));
60+
}
61+
$ccEmails = array_filter($adminCcEmailsArray);
62+
$notifiable = $event->checkedOutTo;
63+
$mailable = $this->getCheckoutMailType($event, $acceptance);
4964
// Send email notifications
5065
try {
51-
foreach ($notifiables as $notifiable) {
52-
if ($notifiable instanceof User && $notifiable->email != '') {
53-
if (! $event->checkedOutTo->locale){
54-
Notification::locale(Setting::getSettings()->locale)->send($notifiable, $this->getCheckoutNotification($event, $acceptance));
55-
}
56-
else {
57-
Notification::send($notifiable, $this->getCheckoutNotification($event, $acceptance));
58-
}
66+
if (!$event->checkedOutTo->locale){
67+
$mailable->locale($event->checkedOutTo->locale);
5968
}
69+
70+
/**
71+
* Send an email if any of the following conditions are met:
72+
* 1. The asset requires acceptance
73+
* 2. The item has a EULA
74+
* 3. The item should send an email at check-in/check-out
75+
*/
76+
if ($notifiable instanceof User && $notifiable->email != '') {
77+
if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() ||
78+
(method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) {
79+
Mail::to($notifiable)->cc($ccEmails)->send($mailable);
80+
Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default'));
6081
}
82+
}
6183

62-
// Send Webhook notification
63-
if ($this->shouldSendWebhookNotification()) {
64-
// Slack doesn't include the URL in its messaging format, so this is needed to hit the endpoint
65-
if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general') {
66-
Notification::route('slack', Setting::getSettings()->webhook_endpoint)
67-
->notify($this->getCheckoutNotification($event, $acceptance));
68-
} else {
84+
// Send Webhook notification
85+
if ($this->shouldSendWebhookNotification()) {
6986
Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint)
7087
->notify($this->getCheckoutNotification($event, $acceptance));
7188
}
72-
}
7389
} catch (ClientException $e) {
7490
Log::debug("Exception caught during checkout notification: " . $e->getMessage());
7591
} catch (Exception $e) {
@@ -103,32 +119,41 @@ public function onCheckedIn($event)
103119
}
104120
}
105121
}
122+
$settings = Setting::getSettings();
123+
$adminCcEmailsArray = [];
124+
125+
if($settings->admin_cc_email !== '') {
126+
$adminCcEmail = $settings->admin_cc_email;
127+
$adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail));
128+
}
129+
$ccEmails = array_filter($adminCcEmailsArray);
130+
$notifiable = $event->checkedOutTo;
131+
$mailable = $this->getCheckinMailType($event);
106132

107-
$notifiables = $this->getNotifiables($event);
108133
// Send email notifications
109134
try {
110-
foreach ($notifiables as $notifiable) {
111-
if ($notifiable instanceof User && $notifiable->email != '') {
112-
if (! $event->checkedOutTo->locale){
113-
Notification::locale(Setting::getSettings()->locale)->send($notifiable, $this->getCheckoutNotification($event, $acceptance));
114-
}
115-
else {
116-
Notification::send($notifiable, $this->getCheckinNotification($event));
117-
}
135+
if (!$event->checkedOutTo->locale){
136+
$mailable->locale($event->checkedOutTo->locale);
137+
}
138+
/**
139+
* Send an email if any of the following conditions are met:
140+
* 1. The asset requires acceptance
141+
* 2. The item has a EULA
142+
* 3. The item should send an email at check-in/check-out
143+
*/
144+
145+
if ($notifiable instanceof User && $notifiable->email != '') {
146+
if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() ||
147+
(method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) {
148+
Mail::to($notifiable)->cc($ccEmails)->send($mailable);
149+
Log::info('Sending email, Locale: ' . $event->checkedOutTo->locale);
118150
}
119151
}
120152
// Send Webhook notification
121153
if ($this->shouldSendWebhookNotification()) {
122-
// Slack doesn't include the URL in its messaging format, so this is needed to hit the endpoint
123-
if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general') {
124-
Notification::route('slack', Setting::getSettings()->webhook_endpoint)
125-
->notify($this->getCheckinNotification($event));
126-
} else {
127154
Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint)
128155
->notify($this->getCheckinNotification($event));
129156
}
130-
}
131-
132157
} catch (ClientException $e) {
133158
Log::warning("Exception caught during checkout notification: " . $e->getMessage());
134159
} catch (Exception $e) {
@@ -159,33 +184,6 @@ private function getCheckoutAcceptance($event)
159184
return $acceptance;
160185
}
161186

162-
/**
163-
* Gets the entities to be notified of the passed event
164-
*
165-
* @param Event $event
166-
* @return Collection
167-
*/
168-
private function getNotifiables($event)
169-
{
170-
$notifiables = collect();
171-
172-
/**
173-
* Notify who checked out the item as long as the model can route notifications
174-
*/
175-
if (method_exists($event->checkedOutTo, 'routeNotificationFor')) {
176-
$notifiables->push($event->checkedOutTo);
177-
}
178-
179-
/**
180-
* Notify Admin users if the settings is activated
181-
*/
182-
if ((Setting::getSettings()) && (Setting::getSettings()->admin_cc_email != '')) {
183-
$notifiables->push(new AdminRecipient());
184-
}
185-
186-
return $notifiables;
187-
}
188-
189187
/**
190188
* Get the appropriate notification for the event
191189
*
@@ -234,7 +232,7 @@ private function getCheckoutNotification($event, $acceptance = null)
234232
break;
235233
case Consumable::class:
236234
$notificationClass = CheckoutConsumableNotification::class;
237-
break;
235+
break;
238236
case LicenseSeat::class:
239237
$notificationClass = CheckoutLicenseSeatNotification::class;
240238
break;
@@ -243,6 +241,30 @@ private function getCheckoutNotification($event, $acceptance = null)
243241

244242
return new $notificationClass($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $acceptance, $event->note);
245243
}
244+
private function getCheckoutMailType($event, $acceptance){
245+
$lookup = [
246+
Accessory::class => CheckoutAccessoryMail::class,
247+
Asset::class => CheckoutAssetMail::class,
248+
LicenseSeat::class => CheckoutLicenseMail::class,
249+
Consumable::class => CheckoutConsumableMail::class,
250+
];
251+
$mailable= $lookup[get_class($event->checkoutable)];
252+
253+
return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $event->note, $acceptance);
254+
255+
}
256+
private function getCheckinMailType($event){
257+
$lookup = [
258+
Accessory::class => CheckinAccessoryMail::class,
259+
Asset::class => CheckinAssetMail::class,
260+
LicenseSeat::class => CheckinLicenseMail::class,
261+
];
262+
263+
$mailable= $lookup[get_class($event->checkoutable)];
264+
265+
return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note);
266+
267+
}
246268

247269
/**
248270
* Register the listeners for the subscriber.

app/Mail/CheckinAccessoryMail.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace App\Mail;
4+
5+
use App\Models\Accessory;
6+
use App\Models\Setting;
7+
use App\Models\User;
8+
use Illuminate\Bus\Queueable;
9+
use Illuminate\Contracts\Queue\ShouldQueue;
10+
use Illuminate\Mail\Mailable;
11+
use Illuminate\Mail\Mailables\Address;
12+
use Illuminate\Mail\Mailables\Content;
13+
use Illuminate\Mail\Mailables\Envelope;
14+
use Illuminate\Queue\SerializesModels;
15+
16+
class CheckinAccessoryMail extends Mailable
17+
{
18+
use Queueable, SerializesModels;
19+
20+
/**
21+
* Create a new message instance.
22+
*/
23+
public function __construct(Accessory $accessory, $checkedOutTo, User $checkedInby, $note)
24+
{
25+
$this->item = $accessory;
26+
$this->target = $checkedOutTo;
27+
$this->admin = $checkedInby;
28+
$this->note = $note;
29+
$this->settings = Setting::getSettings();
30+
}
31+
32+
/**
33+
* Get the message envelope.
34+
*/
35+
public function envelope(): Envelope
36+
{
37+
$from = new Address(env('MAIL_FROM_ADDR','[email protected]'));
38+
39+
return new Envelope(
40+
from: $from,
41+
subject: trans('mail.Accessory_Checkin_Notification'),
42+
);
43+
}
44+
45+
/**
46+
* Get the message content definition.
47+
*/
48+
public function content(): Content
49+
{
50+
return new Content(
51+
markdown: 'mail.markdown.checkin-accessory',
52+
with: [
53+
'item' => $this->item,
54+
'admin' => $this->admin,
55+
'note' => $this->note,
56+
'target' => $this->target,
57+
]
58+
);
59+
}
60+
61+
/**
62+
* Get the attachments for the message.
63+
*
64+
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
65+
*/
66+
public function attachments(): array
67+
{
68+
return [];
69+
}
70+
}

app/Mail/CheckinAssetMail.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace App\Mail;
4+
5+
use App\Helpers\Helper;
6+
use App\Models\Asset;
7+
use App\Models\Setting;
8+
use App\Models\User;
9+
use Illuminate\Bus\Queueable;
10+
use Illuminate\Contracts\Queue\ShouldQueue;
11+
use Illuminate\Mail\Mailable;
12+
use Illuminate\Mail\Mailables\Address;
13+
use Illuminate\Mail\Mailables\Content;
14+
use Illuminate\Mail\Mailables\Envelope;
15+
use Illuminate\Notifications\Messages\MailMessage;
16+
use Illuminate\Queue\SerializesModels;
17+
18+
class CheckinAssetMail extends Mailable
19+
{
20+
use Queueable, SerializesModels;
21+
22+
/**
23+
* Create a new message instance.
24+
*/
25+
public function __construct(Asset $asset, $checkedOutTo, User $checkedInBy, $note)
26+
{
27+
$this->target = $checkedOutTo;
28+
$this->item = $asset;
29+
$this->admin = $checkedInBy;
30+
$this->note = $note;
31+
32+
$this->settings = Setting::getSettings();
33+
$this->expected_checkin = '';
34+
35+
if ($this->item->expected_checkin) {
36+
$this->expected_checkin = Helper::getFormattedDateObject($this->item->expected_checkin, 'date',
37+
false);
38+
}
39+
}
40+
41+
/**
42+
* Get the message envelope.
43+
*/
44+
public function envelope(): Envelope
45+
{
46+
$from = new Address(env('MAIL_FROM_ADDR','[email protected]'));
47+
48+
return new Envelope(
49+
from: $from,
50+
subject: trans('mail.Asset_Checkin_Notification'),
51+
);
52+
}
53+
54+
/**
55+
* Get the mail representation of the notification.
56+
*
57+
* @param mixed $notifiable
58+
* @return Content
59+
*/
60+
public function content(): Content
61+
{
62+
$this->item->load('assetstatus');
63+
$fields = [];
64+
65+
// Check if the item has custom fields associated with it
66+
if (($this->item->model) && ($this->item->model->fieldset)) {
67+
$fields = $this->item->model->fieldset->fields;
68+
}
69+
70+
return new Content(
71+
markdown: 'mail.markdown.checkin-asset',
72+
with: [
73+
'item' => $this->item,
74+
'status' => $this->item->assetstatus?->name,
75+
'admin' => $this->admin,
76+
'note' => $this->note,
77+
'target' => $this->target,
78+
'fields' => $fields,
79+
'expected_checkin' => $this->expected_checkin,
80+
],
81+
);
82+
}
83+
84+
/**
85+
* Get the attachments for the message.
86+
*
87+
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
88+
*/
89+
public function attachments(): array
90+
{
91+
return [];
92+
}
93+
}

0 commit comments

Comments
 (0)