Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
b29d032
adds checkoutAssetMail class, and content method
Godmartinz Oct 15, 2024
f8476f7
finished the construct and mail call in the listner
Godmartinz Oct 15, 2024
9f06a0e
handle some edge cases, null values clean up variable names
Godmartinz Oct 15, 2024
3ab2521
email comes through, no picture and html markup appear though.
Godmartinz Oct 16, 2024
9e1b86f
sends checkout notification via webhook
Godmartinz Oct 16, 2024
16cffe9
simplified checkout webhook call
Godmartinz Oct 16, 2024
9710436
adds Mailables for asset checkin and out
Godmartinz Oct 16, 2024
dcdf600
adds Checkin and Checkout mailables and listner logic
Godmartinz Oct 16, 2024
c39df34
forgot to add accessory mail to project
Godmartinz Oct 16, 2024
f1d83a3
forgot to add asset checkout markdown to projet
Godmartinz Oct 16, 2024
2584d60
adds Licenses seat checkout Mailable
Godmartinz Oct 16, 2024
4becdca
removes toMail from license notificaqtion
Godmartinz Oct 16, 2024
02ff646
adds checkin license mailable
Godmartinz Oct 16, 2024
02bda3c
adds Checkout Consumable mailable and slackwebhook channel to notifs
Godmartinz Oct 16, 2024
a7754c1
fixed asset checkout markdown, and notifiable variable
Godmartinz Oct 16, 2024
ed60340
removed test route
Godmartinz Oct 16, 2024
9a79483
removed namespaces from routing
Godmartinz Oct 16, 2024
285d689
added a coulple test adjustments and moved mail send logic to listener
Godmartinz Oct 17, 2024
65735a3
removed symfony/mailgun-mailer symfony/http-client
Godmartinz Oct 17, 2024
ceb3f5c
added mail-gun and http-client to 8.1
Godmartinz Oct 17, 2024
a690cc3
removing my composer stuff again..for the last time
Godmartinz Oct 17, 2024
496b44e
merged composer lock from dev
Godmartinz Oct 17, 2024
123cdeb
add email check to listener
Godmartinz Oct 17, 2024
dceb8e3
attempt to fix tests
Godmartinz Oct 17, 2024
cdd4fef
attempt to fix tests p2
Godmartinz Oct 17, 2024
83e8186
fix assertSent to AssertNotSent on some test
Godmartinz Oct 17, 2024
b98058c
fix tests pt 3
Godmartinz Oct 17, 2024
7ae76e7
remove viewdata array from 3 tests
Godmartinz Oct 17, 2024
ff113ef
typo fix
Godmartinz Oct 17, 2024
1e31592
messing with the tests
Godmartinz Oct 22, 2024
ead27ac
fixed accessory tests and notifiable target
Godmartinz Oct 22, 2024
1e9922a
fix moar tests
Godmartinz Oct 22, 2024
1b5f441
corrected cc email behavior
Godmartinz Oct 23, 2024
6c34a5c
conditionally check cc emails, initiate variables
Godmartinz Oct 23, 2024
257d25b
removed import notification from test, feature is not present in project
Godmartinz Oct 23, 2024
c681946
added component markdown changes
Godmartinz Oct 23, 2024
fd74c35
remove old notify by mail from consumable notification
Godmartinz Oct 23, 2024
f29a383
Merge branch 'develop' into seperating_notification_n_mail
Godmartinz Oct 23, 2024
62d06b4
set fallback from email address to service.snipe-it.io
Godmartinz Oct 23, 2024
2cc2b2b
apply array_filter to cc emails to prevent errors
Godmartinz Oct 23, 2024
ab3b9c4
remove unnecessary code from checkinasset notification
Godmartinz Oct 23, 2024
a80c09c
Merge branch 'develop' into seperating_notification_n_mail
Godmartinz Oct 24, 2024
15073a0
last test to fix
Godmartinz Oct 24, 2024
6329f5b
removed unused variable from test
Godmartinz Oct 24, 2024
57107c4
fixed last test, definetly the last test
Godmartinz Oct 24, 2024
5636549
remove unnecessary fields in accessory checkout mail
Godmartinz Oct 24, 2024
ce68f55
remove alert emails from cc
Godmartinz Oct 24, 2024
58ff641
removed unused variables
Godmartinz Oct 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/Http/Controllers/Account/AcceptanceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,5 @@ public function store(Request $request, $id) : RedirectResponse
return redirect()->to('account/accept')->with('success', $return_msg);

}

}
146 changes: 84 additions & 62 deletions app/Listeners/CheckoutableListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
namespace App\Listeners;

use App\Events\CheckoutableCheckedOut;
use App\Mail\CheckinAccessoryMail;
use App\Mail\CheckinLicenseMail;
use App\Mail\CheckoutAccessoryMail;
use App\Mail\CheckoutAssetMail;
use App\Mail\CheckinAssetMail;
use App\Mail\CheckoutConsumableMail;
use App\Mail\CheckoutLicenseMail;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use App\Models\Component;
use App\Models\Consumable;
use App\Models\LicenseSeat;
use App\Models\Recipients\AdminRecipient;
use App\Models\Setting;
use App\Models\User;
use App\Notifications\CheckinAccessoryNotification;
Expand All @@ -20,6 +26,7 @@
use App\Notifications\CheckoutConsumableNotification;
use App\Notifications\CheckoutLicenseSeatNotification;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use Exception;
use Illuminate\Support\Facades\Log;
Expand All @@ -43,33 +50,42 @@ public function onCheckedOut($event)
/**
* Make a checkout acceptance and attach it in the notification
*/
$settings = Setting::getSettings();
$acceptance = $this->getCheckoutAcceptance($event);
$notifiables = $this->getNotifiables($event);
$adminCcEmailsArray = [];

if($settings->admin_cc_email !== '') {
$adminCcEmail = $settings->admin_cc_email;
$adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail));
}
$ccEmails = array_filter($adminCcEmailsArray);
$notifiable = $event->checkedOutTo;
$mailable = $this->getCheckoutMailType($event, $acceptance);
// Send email notifications
try {
foreach ($notifiables as $notifiable) {
if ($notifiable instanceof User && $notifiable->email != '') {
if (! $event->checkedOutTo->locale){
Notification::locale(Setting::getSettings()->locale)->send($notifiable, $this->getCheckoutNotification($event, $acceptance));
}
else {
Notification::send($notifiable, $this->getCheckoutNotification($event, $acceptance));
}
if (!$event->checkedOutTo->locale){
$mailable->locale($event->checkedOutTo->locale);
}

/**
* Send an email if any of the following conditions are met:
* 1. The asset requires acceptance
* 2. The item has a EULA
* 3. The item should send an email at check-in/check-out
*/
if ($notifiable instanceof User && $notifiable->email != '') {
if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() ||
(method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) {
Mail::to($notifiable)->cc($ccEmails)->send($mailable);
Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default'));
}
}

// Send Webhook notification
if ($this->shouldSendWebhookNotification()) {
// Slack doesn't include the URL in its messaging format, so this is needed to hit the endpoint
if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general') {
Notification::route('slack', Setting::getSettings()->webhook_endpoint)
->notify($this->getCheckoutNotification($event, $acceptance));
} else {
// Send Webhook notification
if ($this->shouldSendWebhookNotification()) {
Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint)
->notify($this->getCheckoutNotification($event, $acceptance));
}
}
} catch (ClientException $e) {
Log::debug("Exception caught during checkout notification: " . $e->getMessage());
} catch (Exception $e) {
Expand Down Expand Up @@ -103,32 +119,41 @@ public function onCheckedIn($event)
}
}
}
$settings = Setting::getSettings();
$adminCcEmailsArray = [];

if($settings->admin_cc_email !== '') {
$adminCcEmail = $settings->admin_cc_email;
$adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail));
}
$ccEmails = array_filter($adminCcEmailsArray);
$notifiable = $event->checkedOutTo;
$mailable = $this->getCheckinMailType($event);

$notifiables = $this->getNotifiables($event);
// Send email notifications
try {
foreach ($notifiables as $notifiable) {
if ($notifiable instanceof User && $notifiable->email != '') {
if (! $event->checkedOutTo->locale){
Notification::locale(Setting::getSettings()->locale)->send($notifiable, $this->getCheckoutNotification($event, $acceptance));
}
else {
Notification::send($notifiable, $this->getCheckinNotification($event));
}
if (!$event->checkedOutTo->locale){
$mailable->locale($event->checkedOutTo->locale);
}
/**
* Send an email if any of the following conditions are met:
* 1. The asset requires acceptance
* 2. The item has a EULA
* 3. The item should send an email at check-in/check-out
*/

if ($notifiable instanceof User && $notifiable->email != '') {
if ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() ||
(method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) {
Mail::to($notifiable)->cc($ccEmails)->send($mailable);
Log::info('Sending email, Locale: ' . $event->checkedOutTo->locale);
}
}
// Send Webhook notification
if ($this->shouldSendWebhookNotification()) {
// Slack doesn't include the URL in its messaging format, so this is needed to hit the endpoint
if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general') {
Notification::route('slack', Setting::getSettings()->webhook_endpoint)
->notify($this->getCheckinNotification($event));
} else {
Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint)
->notify($this->getCheckinNotification($event));
}
}

} catch (ClientException $e) {
Log::warning("Exception caught during checkout notification: " . $e->getMessage());
} catch (Exception $e) {
Expand Down Expand Up @@ -159,33 +184,6 @@ private function getCheckoutAcceptance($event)
return $acceptance;
}

/**
* Gets the entities to be notified of the passed event
*
* @param Event $event
* @return Collection
*/
private function getNotifiables($event)
{
$notifiables = collect();

/**
* Notify who checked out the item as long as the model can route notifications
*/
if (method_exists($event->checkedOutTo, 'routeNotificationFor')) {
$notifiables->push($event->checkedOutTo);
}

/**
* Notify Admin users if the settings is activated
*/
if ((Setting::getSettings()) && (Setting::getSettings()->admin_cc_email != '')) {
$notifiables->push(new AdminRecipient());
}

return $notifiables;
}

/**
* Get the appropriate notification for the event
*
Expand Down Expand Up @@ -234,7 +232,7 @@ private function getCheckoutNotification($event, $acceptance = null)
break;
case Consumable::class:
$notificationClass = CheckoutConsumableNotification::class;
break;
break;
case LicenseSeat::class:
$notificationClass = CheckoutLicenseSeatNotification::class;
break;
Expand All @@ -243,6 +241,30 @@ private function getCheckoutNotification($event, $acceptance = null)

return new $notificationClass($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $acceptance, $event->note);
}
private function getCheckoutMailType($event, $acceptance){
$lookup = [
Accessory::class => CheckoutAccessoryMail::class,
Asset::class => CheckoutAssetMail::class,
LicenseSeat::class => CheckoutLicenseMail::class,
Consumable::class => CheckoutConsumableMail::class,
];
$mailable= $lookup[get_class($event->checkoutable)];

return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $event->note, $acceptance);

}
private function getCheckinMailType($event){
$lookup = [
Accessory::class => CheckinAccessoryMail::class,
Asset::class => CheckinAssetMail::class,
LicenseSeat::class => CheckinLicenseMail::class,
];

$mailable= $lookup[get_class($event->checkoutable)];

return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note);

}

/**
* Register the listeners for the subscriber.
Expand Down
70 changes: 70 additions & 0 deletions app/Mail/CheckinAccessoryMail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

namespace App\Mail;

use App\Models\Accessory;
use App\Models\Setting;
use App\Models\User;
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 CheckinAccessoryMail extends Mailable
{
use Queueable, SerializesModels;

/**
* Create a new message instance.
*/
public function __construct(Accessory $accessory, $checkedOutTo, User $checkedInby, $note)
{
$this->item = $accessory;
$this->target = $checkedOutTo;
$this->admin = $checkedInby;
$this->note = $note;
$this->settings = Setting::getSettings();
}

/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
$from = new Address(env('MAIL_FROM_ADDR','[email protected]'));

return new Envelope(
from: $from,
subject: trans('mail.Accessory_Checkin_Notification'),
);
}

/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
markdown: 'mail.markdown.checkin-accessory',
with: [
'item' => $this->item,
'admin' => $this->admin,
'note' => $this->note,
'target' => $this->target,
]
);
}

/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
93 changes: 93 additions & 0 deletions app/Mail/CheckinAssetMail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Mail;

use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Setting;
use App\Models\User;
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\Notifications\Messages\MailMessage;
use Illuminate\Queue\SerializesModels;

class CheckinAssetMail extends Mailable
{
use Queueable, SerializesModels;

/**
* Create a new message instance.
*/
public function __construct(Asset $asset, $checkedOutTo, User $checkedInBy, $note)
{
$this->target = $checkedOutTo;
$this->item = $asset;
$this->admin = $checkedInBy;
$this->note = $note;

$this->settings = Setting::getSettings();
$this->expected_checkin = '';

if ($this->item->expected_checkin) {
$this->expected_checkin = Helper::getFormattedDateObject($this->item->expected_checkin, 'date',
false);
}
}

/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
$from = new Address(env('MAIL_FROM_ADDR','[email protected]'));

return new Envelope(
from: $from,
subject: trans('mail.Asset_Checkin_Notification'),
);
}

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return Content
*/
public function content(): Content
{
$this->item->load('assetstatus');
$fields = [];

// Check if the item has custom fields associated with it
if (($this->item->model) && ($this->item->model->fieldset)) {
$fields = $this->item->model->fieldset->fields;
}

return new Content(
markdown: 'mail.markdown.checkin-asset',
with: [
'item' => $this->item,
'status' => $this->item->assetstatus?->name,
'admin' => $this->admin,
'note' => $this->note,
'target' => $this->target,
'fields' => $fields,
'expected_checkin' => $this->expected_checkin,
],
);
}

/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}
Loading
Loading