Skip to content

Commit 9b5ead3

Browse files
authored
Merge pull request #18985 from grokability/#18959-slack-notification-location
Fixed #18959 - refresh data on checkout notification
2 parents bd8e944 + 158e66f commit 9b5ead3

3 files changed

Lines changed: 68 additions & 11 deletions

File tree

app/Listeners/CheckoutableListener.php

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use Exception;
3535
use GuzzleHttp\Exception\ClientException;
3636
use Illuminate\Database\Eloquent\Model;
37+
use Illuminate\Notifications\Notification as BaseNotification;
3738
use Illuminate\Support\Facades\Context;
3839
use Illuminate\Support\Facades\Log;
3940
use Illuminate\Support\Facades\Mail;
@@ -126,12 +127,12 @@ public function onCheckedOut($event)
126127
if ($shouldSendWebhookNotification) {
127128
try {
128129
if ($this->newMicrosoftTeamsWebhookEnabled()) {
129-
$message = $this->getCheckoutNotification($event)->toMicrosoftTeams();
130+
$message = $this->getCheckoutNotification($event, $acceptance, true)->toMicrosoftTeams();
130131
$notification = new TeamsNotification(Setting::getSettings()->webhook_endpoint);
131132
$notification->success()->sendMessage($message[0], $message[1]); // Send the message to Microsoft Teams
132133
} else {
133134
Notification::route($this->webhookSelected(), Setting::getSettings()->webhook_endpoint)
134-
->notify($this->getCheckoutNotification($event, $acceptance));
135+
->notify($this->getCheckoutNotification($event, $acceptance, true));
135136
}
136137
} catch (ClientException $e) {
137138
$status = $e->getResponse()->getStatusCode();
@@ -233,12 +234,12 @@ public function onCheckedIn($event)
233234
// Send Webhook notification
234235
try {
235236
if ($this->newMicrosoftTeamsWebhookEnabled()) {
236-
$message = $this->getCheckinNotification($event)->toMicrosoftTeams();
237+
$message = $this->getCheckinNotification($event, true)->toMicrosoftTeams();
237238
$notification = new TeamsNotification(Setting::getSettings()->webhook_endpoint);
238239
$notification->success()->sendMessage($message[0], $message[1]); // Send the message to Microsoft Teams
239240
} else {
240241
Notification::route($this->webhookSelected(), Setting::getSettings()->webhook_endpoint)
241-
->notify($this->getCheckinNotification($event));
242+
->notify($this->getCheckinNotification($event, true));
242243
}
243244
} catch (ClientException $e) {
244245
$status = $e->getResponse()->getStatusCode();
@@ -312,12 +313,12 @@ private function getCheckoutAcceptance($event)
312313
* @param CheckoutableCheckedIn $event
313314
* @return Notification
314315
*/
315-
private function getCheckinNotification($event)
316+
private function getCheckinNotification($event, bool $refreshCheckoutable = false): BaseNotification
316317
{
317-
318318
$notificationClass = null;
319+
$checkoutable = $this->getCheckoutableForNotification($event->checkoutable, $refreshCheckoutable);
319320

320-
switch (get_class($event->checkoutable)) {
321+
switch (get_class($checkoutable)) {
321322
case Accessory::class:
322323
$notificationClass = CheckinAccessoryNotification::class;
323324
break;
@@ -334,7 +335,7 @@ private function getCheckinNotification($event)
334335

335336
Log::debug('Notification class: '.$notificationClass);
336337

337-
return new $notificationClass($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note);
338+
return new $notificationClass($checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note);
338339
}
339340

340341
/**
@@ -344,11 +345,12 @@ private function getCheckinNotification($event)
344345
* @param CheckoutAcceptance|null $acceptance
345346
* @return Notification
346347
*/
347-
private function getCheckoutNotification($event, $acceptance = null)
348+
private function getCheckoutNotification($event, $acceptance = null, bool $refreshCheckoutable = false): BaseNotification
348349
{
349350
$notificationClass = null;
351+
$checkoutable = $this->getCheckoutableForNotification($event->checkoutable, $refreshCheckoutable);
350352

351-
switch (get_class($event->checkoutable)) {
353+
switch (get_class($checkoutable)) {
352354
case Accessory::class:
353355
$notificationClass = CheckoutAccessoryNotification::class;
354356
break;
@@ -366,7 +368,16 @@ private function getCheckoutNotification($event, $acceptance = null)
366368
break;
367369
}
368370

369-
return new $notificationClass($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $acceptance, $event->note);
371+
return new $notificationClass($checkoutable, $event->checkedOutTo, $event->checkedOutBy, $acceptance, $event->note);
372+
}
373+
374+
private function getCheckoutableForNotification(Model $checkoutable, bool $shouldRefresh): Model
375+
{
376+
if (! $shouldRefresh) {
377+
return $checkoutable;
378+
}
379+
380+
return $checkoutable->fresh() ?? $checkoutable;
370381
}
371382

372383
private function getCheckoutMailType($event, $acceptance)

tests/Feature/Notifications/Webhooks/SlackNotificationsUponCheckinTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use App\Notifications\CheckinComponentNotification;
1717
use App\Notifications\CheckinLicenseSeatNotification;
1818
use Illuminate\Database\Eloquent\Model;
19+
use Illuminate\Notifications\AnonymousNotifiable;
1920
use Illuminate\Support\Facades\Notification;
2021
use PHPUnit\Framework\Attributes\DataProvider;
2122
use PHPUnit\Framework\Attributes\Group;
@@ -145,6 +146,28 @@ public function test_slack_notification_is_still_sent_when_category_email_is_not
145146
$this->assertSlackNotificationSent(CheckinAssetNotification::class);
146147
}
147148

149+
public function test_asset_checkin_slack_notification_uses_updated_asset_location()
150+
{
151+
$this->settings->enableSlackWebhook();
152+
153+
$previousLocation = Location::factory()->create(['name' => 'Region B']);
154+
$newLocation = Location::factory()->create(['name' => 'Office A']);
155+
$target = User::factory()->create(['location_id' => $previousLocation->id]);
156+
$asset = Asset::factory()->create(['location_id' => $previousLocation->id]);
157+
158+
// Simulate post-checkin state while keeping a stale in-memory relation loaded.
159+
$asset->location_id = $newLocation->id;
160+
$asset->save();
161+
162+
$this->fireCheckInEvent($asset, $target);
163+
164+
Notification::assertSentTo(
165+
new AnonymousNotifiable,
166+
CheckinAssetNotification::class,
167+
fn (CheckinAssetNotification $notification): bool => $notification->item->location?->is($newLocation)
168+
);
169+
}
170+
148171
#[DataProvider('licenseCheckInTargets')]
149172
public function test_license_checkin_sends_slack_notification_when_setting_enabled($checkoutTarget)
150173
{

tests/Feature/Notifications/Webhooks/SlackNotificationsUponCheckoutTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use App\Notifications\CheckoutConsumableNotification;
1919
use App\Notifications\CheckoutLicenseSeatNotification;
2020
use Illuminate\Database\Eloquent\Model;
21+
use Illuminate\Notifications\AnonymousNotifiable;
2122
use Illuminate\Support\Facades\Mail;
2223
use Illuminate\Support\Facades\Notification;
2324
use PHPUnit\Framework\Attributes\DataProvider;
@@ -159,6 +160,28 @@ public function test_slack_notification_is_still_sent_when_category_email_is_not
159160
$this->assertSlackNotificationSent(CheckoutAssetNotification::class);
160161
}
161162

163+
public function test_asset_checkout_slack_notification_uses_updated_asset_location()
164+
{
165+
$this->settings->enableSlackWebhook();
166+
167+
$previousLocation = Location::factory()->create(['name' => 'Office A']);
168+
$newLocation = Location::factory()->create(['name' => 'Region B']);
169+
$target = User::factory()->create(['location_id' => $newLocation->id, 'email' => null]);
170+
$asset = Asset::factory()->create(['location_id' => $previousLocation->id]);
171+
172+
// Simulate post-checkout state while keeping a stale in-memory relation loaded.
173+
$asset->location_id = $newLocation->id;
174+
$asset->save();
175+
176+
$this->fireCheckOutEvent($asset, $target);
177+
178+
Notification::assertSentTo(
179+
new AnonymousNotifiable,
180+
CheckoutAssetNotification::class,
181+
fn (CheckoutAssetNotification $notification): bool => $notification->item->location?->is($newLocation)
182+
);
183+
}
184+
162185
public function test_consumable_checkout_sends_slack_notification_when_setting_enabled()
163186
{
164187
$this->settings->enableSlackWebhook();

0 commit comments

Comments
 (0)