Skip to content

Commit 931ab10

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents 7556046 + f68df1f commit 931ab10

File tree

521 files changed

+3560
-1991
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

521 files changed

+3560
-1991
lines changed

.github/workflows/tests-mysql.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,7 @@ jobs:
7777
DB_PORT: ${{ job.services.mysql.ports[3306] }}
7878
DB_USERNAME: root
7979
run: php artisan test
80+
81+
- name: Test failure
82+
if: ${{ failure() }}
83+
run: docker exec "$PROJECT_NAME-php-fpm" cat storage/logs/laravel.log

.github/workflows/tests-postgres.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,7 @@ jobs:
7575
DB_USERNAME: snipeit
7676
DB_PASSWORD: password
7777
run: php artisan test
78+
79+
- name: Test failure
80+
if: ${{ failure() }}
81+
run: docker exec "$PROJECT_NAME-php-fpm" cat storage/logs/laravel.log

.github/workflows/tests-sqlite.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ jobs:
5959
env:
6060
DB_CONNECTION: sqlite_testing
6161
run: php artisan test
62+
63+
- name: Test failure
64+
if: ${{ failure() }}
65+
run: docker exec "$PROJECT_NAME-php-fpm" cat storage/logs/laravel.log

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/Http/Controllers/Api/ReportsController.php

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,6 @@ public function index(Request $request) : JsonResponse | array
4444
});
4545
}
4646

47-
if ($request->filled('action_type')) {
48-
$actionlogs = $actionlogs->where('action_type', '=', $request->input('action_type'))->orderBy('created_at', 'desc');
49-
}
50-
51-
if ($request->filled('created_by')) {
52-
$actionlogs = $actionlogs->where('created_by', '=', $request->input('created_by'));
53-
}
54-
55-
if ($request->filled('action_source')) {
56-
$actionlogs = $actionlogs->where('action_source', '=', $request->input('action_source'))->orderBy('created_at', 'desc');
57-
}
58-
59-
if ($request->filled('remote_ip')) {
60-
$actionlogs = $actionlogs->where('remote_ip', '=', $request->input('remote_ip'))->orderBy('created_at', 'desc');
61-
}
6247

6348
if ($request->filled('uploads')) {
6449
$actionlogs = $actionlogs->whereNotNull('filename')->orderBy('created_at', 'desc');
@@ -74,6 +59,8 @@ public function index(Request $request) : JsonResponse | array
7459
'note',
7560
'remote_ip',
7661
'user_agent',
62+
'target_type',
63+
'item_type',
7764
'action_source',
7865
'action_date',
7966
];

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+
}

0 commit comments

Comments
 (0)