From b29d032bf0250941a2a968c85c227bbee9449c81 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 15 Oct 2024 11:28:27 -0700 Subject: [PATCH 01/46] adds checkoutAssetMail class, and content method --- .../CheckoutAssetNotification.php | 30 -- composer.json | 2 + composer.lock | 416 ++++++++++-------- 3 files changed, 245 insertions(+), 203 deletions(-) diff --git a/app/Notifications/CheckoutAssetNotification.php b/app/Notifications/CheckoutAssetNotification.php index b14796fb8c..e61d49bf5c 100644 --- a/app/Notifications/CheckoutAssetNotification.php +++ b/app/Notifications/CheckoutAssetNotification.php @@ -191,35 +191,5 @@ public function toGoogleChat() * @param mixed $notifiable * @return \Illuminate\Notifications\Messages\MailMessage */ - public function toMail() - { $this->item->load('assetstatus'); - $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; - $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; - $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; - } - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - $message = (new MailMessage)->markdown('notifications.markdown.checkout-asset', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'status' => $this->item->assetstatus?->name, - 'note' => $this->note, - 'target' => $this->target, - 'fields' => $fields, - 'eula' => $eula, - 'req_accept' => $req_accept, - 'accept_url' => $accept_url, - 'last_checkout' => $this->last_checkout, - 'expected_checkin' => $this->expected_checkin, - ]) - ->subject(trans('mail.Confirm_asset_delivery')); - - return $message; - } } diff --git a/composer.json b/composer.json index 6d89312578..b255f821cd 100644 --- a/composer.json +++ b/composer.json @@ -63,6 +63,8 @@ "rollbar/rollbar-laravel": "^8.0", "spatie/laravel-backup": "^8.8", "spatie/laravel-ignition": "^2.0", + "symfony/http-client": "^7.1", + "symfony/mailgun-mailer": "^7.1", "tecnickcom/tc-lib-barcode": "^1.15", "tecnickcom/tcpdf": "^6.5", "unicodeveloper/laravel-password": "^1.0", diff --git a/composer.lock b/composer.lock index 3f79921b26..c6e469c597 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3819ab4ef72eb77fabe494c0e746b83b", + "content-hash": "0378e36c927d3838ac338c4f58ed30cd", "packages": [ { "name": "alek13/slack", @@ -9081,6 +9081,178 @@ ], "time": "2024-08-13T14:27:37+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-20T13:35:23+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/http-foundation", "version": "v6.4.12", @@ -9352,6 +9524,75 @@ ], "time": "2024-09-08T12:30:05+00:00" }, + { + "name": "symfony/mailgun-mailer", + "version": "v7.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailgun-mailer.git", + "reference": "dac02fe68e9306849703025511c56f10701696a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/dac02fe68e9306849703025511c56f10701696a8", + "reference": "dac02fe68e9306849703025511c56f10701696a8", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/mailer": "^6.4|^7.0" + }, + "conflict": { + "symfony/http-foundation": "<6.4" + }, + "require-dev": { + "symfony/http-client": "^6.4|^7.0", + "symfony/webhook": "^6.4|^7.0" + }, + "type": "symfony-mailer-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\Bridge\\Mailgun\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Mailgun Mailer Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-07-04T11:20:59+00:00" + }, { "name": "symfony/mime", "version": "v6.4.12", @@ -16028,177 +16269,6 @@ ], "time": "2024-09-16T16:01:33+00:00" }, - { - "name": "symfony/http-client", - "version": "v6.4.12", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client.git", - "reference": "fbebfcce21084d3e91ea987ae5bdd8c71ff0fd56" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/fbebfcce21084d3e91ea987ae5bdd8c71ff0fd56", - "reference": "fbebfcce21084d3e91ea987ae5bdd8c71ff0fd56", - "shasum": "" - }, - "require": { - "php": ">=8.1", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "^3.4.1", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.3" - }, - "provide": { - "php-http/async-client-implementation": "*", - "php-http/client-implementation": "*", - "psr/http-client-implementation": "1.0", - "symfony/http-client-implementation": "3.0" - }, - "require-dev": { - "amphp/amp": "^2.5", - "amphp/http-client": "^4.2.1", - "amphp/http-tunnel": "^1.0", - "amphp/socket": "^1.1", - "guzzlehttp/promises": "^1.4|^2.0", - "nyholm/psr7": "^1.0", - "php-http/httplug": "^1.0|^2.0", - "psr/http-client": "^1.0", - "symfony/dependency-injection": "^5.4|^6.0|^7.0", - "symfony/http-kernel": "^5.4|^6.0|^7.0", - "symfony/messenger": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "symfony/stopwatch": "^5.4|^6.0|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", - "homepage": "https://symfony.com", - "keywords": [ - "http" - ], - "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.12" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-20T08:21:33+00:00" - }, - { - "name": "symfony/http-client-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "20414d96f391677bf80078aa55baece78b82647d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", - "reference": "20414d96f391677bf80078aa55baece78b82647d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to HTTP clients", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-04-18T09:32:20+00:00" - }, { "name": "symfony/options-resolver", "version": "v6.4.8", @@ -16658,5 +16728,5 @@ "ext-pdo": "*" }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } From f8476f713396027e7149e7306db2bfcc710d5e5c Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 15 Oct 2024 12:49:52 -0700 Subject: [PATCH 02/46] finished the construct and mail call in the listner --- app/Listeners/CheckoutableListener.php | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index eb6b738094..7dab68f18c 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -3,6 +3,7 @@ namespace App\Listeners; use App\Events\CheckoutableCheckedOut; +use App\Mail\CheckoutAssetMail; use App\Models\Accessory; use App\Models\Asset; use App\Models\CheckoutAcceptance; @@ -20,6 +21,7 @@ use App\Notifications\CheckoutAssetNotification; 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; @@ -44,23 +46,24 @@ class CheckoutableListener * Make a checkout acceptance and attach it in the notification */ $acceptance = $this->getCheckoutAcceptance($event); - $notifiables = $this->getNotifiables($event); + $notifiable = $this->getNotifiables($event); + $mailable = (new CheckoutAssetMail( + $event->checkoutable, + $event->checkedOutTo, + $event->checkedOutBy, + $acceptance, + $event->note + )); // 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); } - } + Mail::to($notifiable)->send($mailable); - // Send Webhook notification - if ($this->shouldSendWebhookNotification()) { + // 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) From 9f06a0e441940606de32279c428b24a8957186fb Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 15 Oct 2024 14:01:28 -0700 Subject: [PATCH 03/46] handle some edge cases, null values clean up variable names --- app/Listeners/CheckoutableListener.php | 42 +++++++++++++----------- app/Models/Recipients/AdminRecipient.php | 6 ++++ 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 7dab68f18c..4d21fd6c10 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -4,6 +4,7 @@ namespace App\Listeners; use App\Events\CheckoutableCheckedOut; use App\Mail\CheckoutAssetMail; +use App\Mail\CheckinAssetMail; use App\Models\Accessory; use App\Models\Asset; use App\Models\CheckoutAcceptance; @@ -14,7 +15,6 @@ use App\Models\Recipients\AdminRecipient; use App\Models\Setting; use App\Models\User; use App\Notifications\CheckinAccessoryNotification; -use App\Notifications\CheckinAssetNotification; use App\Notifications\CheckinLicenseSeatNotification; use App\Notifications\CheckoutAccessoryNotification; use App\Notifications\CheckoutAssetNotification; @@ -46,7 +46,7 @@ class CheckoutableListener * Make a checkout acceptance and attach it in the notification */ $acceptance = $this->getCheckoutAcceptance($event); - $notifiable = $this->getNotifiables($event); + $notifiable = $this->getNotifiable($event); $mailable = (new CheckoutAssetMail( $event->checkoutable, $event->checkedOutTo, @@ -57,11 +57,11 @@ class CheckoutableListener // Send email notifications try { - if (! $event->checkedOutTo->locale){ + if (!$event->checkedOutTo->locale){ $mailable->locale($event->checkedOutTo->locale); } Mail::to($notifiable)->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 @@ -107,19 +107,22 @@ class CheckoutableListener } } - $notifiables = $this->getNotifiables($event); + $notifiable = $this->getNotifiable($event); + $mailable = (new CheckInAssetMail( + $event->checkoutable, + $event->checkedOutTo, + $event->checkedOutBy, + $event->note, + null, + )); + // 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); } + Mail::to($notifiable)->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 @@ -168,25 +171,26 @@ class CheckoutableListener * @param Event $event * @return Collection */ - private function getNotifiables($event) + private function getNotifiable($event) { - $notifiables = collect(); + $notifiable = 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); + $notifiable->push($event->checkedOutTo); } /** * Notify Admin users if the settings is activated */ if ((Setting::getSettings()) && (Setting::getSettings()->admin_cc_email != '')) { - $notifiables->push(new AdminRecipient()); + $adminRecipient= new AdminRecipient; + $notifiable->push($adminRecipient->getEmail()); } - return $notifiables; + return new $notifiable; } /** diff --git a/app/Models/Recipients/AdminRecipient.php b/app/Models/Recipients/AdminRecipient.php index 433bd00209..90e39d4ee5 100644 --- a/app/Models/Recipients/AdminRecipient.php +++ b/app/Models/Recipients/AdminRecipient.php @@ -6,9 +6,15 @@ use App\Models\Setting; class AdminRecipient extends Recipient { + + protected $email; public function __construct() { $settings = Setting::getSettings(); $this->email = trim($settings->admin_cc_email); } + + public function getEmail(){ + return $this->email; + } } From 3ab2521cb0b8f61cb42a7b205a7836d7950046a6 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 12:21:33 -0700 Subject: [PATCH 04/46] email comes through, no picture and html markup appear though. --- .../Account/AcceptanceController.php | 1 + app/Listeners/CheckoutableListener.php | 25 ++-- .../CheckoutAssetNotification.php | 21 --- .../markdown/checkout-asset.blade.php | 130 +++++++++--------- routes/web.php | 22 +++ 5 files changed, 100 insertions(+), 99 deletions(-) diff --git a/app/Http/Controllers/Account/AcceptanceController.php b/app/Http/Controllers/Account/AcceptanceController.php index e29fa7c63b..278d7e2081 100644 --- a/app/Http/Controllers/Account/AcceptanceController.php +++ b/app/Http/Controllers/Account/AcceptanceController.php @@ -338,4 +338,5 @@ class AcceptanceController extends Controller return redirect()->to('account/accept')->with('success', $return_msg); } + } diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 4d21fd6c10..cfadad5ae9 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -51,8 +51,8 @@ class CheckoutableListener $event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, + $event->note, $acceptance, - $event->note )); // Send email notifications @@ -61,18 +61,18 @@ class CheckoutableListener $mailable->locale($event->checkedOutTo->locale); } Mail::to($notifiable)->send($mailable); - \Log::info('Sending email, Locale: ' .($event->checkedOutTo->locale ?? 'default')); + 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 { - Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) - ->notify($this->getCheckoutNotification($event, $acceptance)); - } - } +// 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 { +// 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) { @@ -113,7 +113,6 @@ class CheckoutableListener $event->checkedOutTo, $event->checkedOutBy, $event->note, - null, )); // Send email notifications diff --git a/app/Notifications/CheckoutAssetNotification.php b/app/Notifications/CheckoutAssetNotification.php index e61d49bf5c..4337749f49 100644 --- a/app/Notifications/CheckoutAssetNotification.php +++ b/app/Notifications/CheckoutAssetNotification.php @@ -32,28 +32,7 @@ class CheckoutAssetNotification extends Notification */ public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note) { - $this->item = $asset; - $this->admin = $checkedOutBy; - $this->note = $note; - $this->target = $checkedOutTo; - $this->acceptance = $acceptance; - - $this->settings = Setting::getSettings(); - - $this->last_checkout = ''; - $this->expected_checkin = ''; - - if ($this->item->last_checkout) { - $this->last_checkout = Helper::getFormattedDateObject($this->item->last_checkout, 'date', - false); - } - - if ($this->item->expected_checkin) { - $this->expected_checkin = Helper::getFormattedDateObject($this->item->expected_checkin, 'date', - false); - } } - /** * Get the notification's delivery channels. * diff --git a/resources/views/notifications/markdown/checkout-asset.blade.php b/resources/views/notifications/markdown/checkout-asset.blade.php index 9b5fc26dc2..5b4c811dd7 100644 --- a/resources/views/notifications/markdown/checkout-asset.blade.php +++ b/resources/views/notifications/markdown/checkout-asset.blade.php @@ -1,76 +1,76 @@ @component('mail::message') -# {{ trans('mail.hello') }} {{ $target->present()->fullName() }}, + # {{ trans('mail.hello') }} {{ $target->present()->fullName() }}, -{{ trans('mail.new_item_checked') }} + {{ trans('mail.new_item_checked') }} -@if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl()) -
Asset
-@endif + @if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl()) +
Asset
+ @endif -@component('mail::table') -| | | -| ------------- | ------------- | -@if ((isset($item->name)) && ($item->name!='')) -| **{{ trans('mail.asset_name') }}** | {{ $item->name }} | -@endif -@if (($item->name!=$item->asset_tag)) -| **{{ trans('mail.asset_tag') }}** | {{ $item->asset_tag }} | -@endif -@if (isset($item->manufacturer)) -| **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | -@endif -@if (isset($item->model)) -| **{{ trans('general.asset_model') }}** | {{ $item->model->name }} | -@endif -@if ((isset($item->model->model_number)) && ($item->model->name!=$item->model->model_number)) -| **{{ trans('general.model_no') }}** | {{ $item->model->model_number }} | -@endif -@if (isset($item->serial)) -| **{{ trans('mail.serial') }}** | {{ $item->serial }} | -@endif -@if (isset($last_checkout)) -| **{{ trans('mail.checkout_date') }}** | {{ $last_checkout }} | -@endif -@if (isset($status)) -| **{{ trans('general.status') }}** | {{ $status }} | -@endif -@if ((isset($expected_checkin)) && ($expected_checkin!='')) -| **{{ trans('mail.expecting_checkin_date') }}** | {{ $expected_checkin }} | -@endif -@foreach($fields as $field) -@if (($item->{ $field->db_column_name() }!='') && ($field->show_in_email) && ($field->field_encrypted=='0')) -| **{{ $field->name }}** | {{ $item->{ $field->db_column_name() } }} | -@endif -@endforeach -@if ($admin) -| **{{ trans('general.administrator') }}** | {{ $admin->present()->fullName() }} | -@endif -@if ($note) -| **{{ trans('mail.additional_notes') }}** | {{ $note }} | -@endif -@endcomponent + @component('mail::table') + | | | + | ------------- | ------------- | + @if ((isset($item->name)) && ($item->name!='')) + | **{{ trans('mail.asset_name') }}** | {{ $item->name }} | + @endif + @if (($item->name!=$item->asset_tag)) + | **{{ trans('mail.asset_tag') }}** | {{ $item->asset_tag }} | + @endif + @if (isset($item->manufacturer)) + | **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | + @endif + @if (isset($item->model)) + | **{{ trans('general.asset_model') }}** | {{ $item->model->name }} | + @endif + @if ((isset($item->model->model_number)) && ($item->model->name!=$item->model->model_number)) + | **{{ trans('general.model_no') }}** | {{ $item->model->model_number }} | + @endif + @if (isset($item->serial)) + | **{{ trans('mail.serial') }}** | {{ $item->serial }} | + @endif + @if (isset($last_checkout)) + | **{{ trans('mail.checkout_date') }}** | {{ $last_checkout }} | + @endif + @if (isset($status)) + | **{{ trans('general.status') }}** | {{ $status }} | + @endif + @if ((isset($expected_checkin)) && ($expected_checkin!='')) + | **{{ trans('mail.expecting_checkin_date') }}** | {{ $expected_checkin }} | + @endif + @foreach($fields as $field) + @if (($item->{ $field->db_column_name() }!='') && ($field->show_in_email) && ($field->field_encrypted=='0')) + | **{{ $field->name }}** | {{ $item->{ $field->db_column_name() } }} | + @endif + @endforeach + @if ($admin) + | **{{ trans('general.administrator') }}** | {{ $admin->present()->fullName() }} | + @endif + @if ($note) + | **{{ trans('mail.additional_notes') }}** | {{ $note }} | + @endif + @endcomponent -@if (($req_accept == 1) && ($eula!='')) -{{ trans('mail.read_the_terms_and_click') }} -@elseif (($req_accept == 1) && ($eula=='')) -{{ trans('mail.click_on_the_link_asset') }} -@elseif (($req_accept == 0) && ($eula!='')) -{{ trans('mail.read_the_terms') }} -@endif + @if (($req_accept == 1) && ($eula!='')) + {{ trans('mail.read_the_terms_and_click') }} + @elseif (($req_accept == 1) && ($eula=='')) + {{ trans('mail.click_on_the_link_asset') }} + @elseif (($req_accept == 0) && ($eula!='')) + {{ trans('mail.read_the_terms') }} + @endif -@if ($eula) -@component('mail::panel') -{!! $eula !!} -@endcomponent -@endif + @if ($eula) + @component('mail::panel') + {!! $eula !!} + @endcomponent + @endif -@if ($req_accept == 1) -**[✔ {{ trans('mail.i_have_read') }}]({{ $accept_url }})** -@endif + @if ($req_accept == 1) + **[✔ {{ trans('mail.i_have_read') }}]({{ $accept_url }})** + @endif -{{ trans('mail.best_regards') }} + {{ trans('mail.best_regards') }} -{{ $snipeSettings->site_name }} + {{ $snipeSettings->site_name }} -@endcomponent +@endcomponent \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 60b74476c7..7bed89acf7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -24,6 +24,8 @@ use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Auth\ForgotPasswordController; use App\Http\Controllers\Auth\ResetPasswordController; use App\Livewire\Importer; +use App\Models\Asset; +use App\Models\User; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Auth; @@ -53,6 +55,26 @@ Route::group(['middleware' => 'auth'], function () { /* * Locations */ + Route::get('/test-email', function() { + $item = Asset::find(1); // Load some test data + $admin = User::find(1); + $target = User::find(2); + $acceptance = null; // Simulate acceptance data + $note = 'Test note'; + + $fields = []; + if (($item->model) && ($item->model->fieldset)) { + $fields = $item->model->fieldset->fields; + } + + return new \App\Mail\CheckoutAssetMail( + $item, + $admin, + $target, + $acceptance, + $note); + }); + Route::group(['prefix' => 'locations', 'middleware' => ['auth']], function () { From 9e1b86f586f2942312105b0b37d69ee8ec34ca17 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 12:51:19 -0700 Subject: [PATCH 05/46] sends checkout notification via webhook --- app/Listeners/CheckoutableListener.php | 34 +++++------ .../CheckinAssetNotification.php | 17 +++--- .../CheckoutAssetNotification.php | 61 ++++++++----------- 3 files changed, 51 insertions(+), 61 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index cfadad5ae9..3204bf628b 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -62,17 +62,17 @@ class CheckoutableListener } Mail::to($notifiable)->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 { -// Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) -// ->notify($this->getCheckoutNotification($event, $acceptance)); -// } -// } +// 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 { + 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) { @@ -231,17 +231,17 @@ class CheckoutableListener { $notificationClass = null; - switch (get_class($event->checkoutable)) { - case Accessory::class: + switch (true) { + case $event->checkoutable instanceof Accessory: $notificationClass = CheckoutAccessoryNotification::class; break; - case Asset::class: + case $event->checkoutable instanceof Asset: $notificationClass = CheckoutAssetNotification::class; break; - case Consumable::class: + case $event->checkoutable instanceof Consumable: $notificationClass = CheckoutConsumableNotification::class; - break; - case LicenseSeat::class: + break; + case $event->checkoutable instanceof LicenseSeat: $notificationClass = CheckoutLicenseSeatNotification::class; break; } diff --git a/app/Notifications/CheckinAssetNotification.php b/app/Notifications/CheckinAssetNotification.php index 77cd6d9b5a..85b1c74413 100644 --- a/app/Notifications/CheckinAssetNotification.php +++ b/app/Notifications/CheckinAssetNotification.php @@ -50,7 +50,6 @@ class CheckinAssetNotification extends Notification */ public function via() { - $notifyBy = []; if (Setting::getSettings()->webhook_selected == 'google' && Setting::getSettings()->webhook_endpoint) { $notifyBy[] = GoogleChatChannel::class; @@ -64,14 +63,14 @@ class CheckinAssetNotification extends Notification Log::debug('use webhook'); $notifyBy[] = 'slack'; } - - /** - * Only send checkin notifications to users if the category - * has the corresponding checkbox checked. - */ - if ($this->item->checkin_email() && $this->target instanceof User && $this->target->email != '') { - $notifyBy[] = 'mail'; - } +dd($notifyBy); +// /** +// * Only send checkin notifications to users if the category +// * has the corresponding checkbox checked. +// */ +// if ($this->item->checkin_email() && $this->target instanceof User && $this->target->email != '') { +// $notifyBy[] = 'mail'; +// } return $notifyBy; } diff --git a/app/Notifications/CheckoutAssetNotification.php b/app/Notifications/CheckoutAssetNotification.php index 4337749f49..1ca329ed80 100644 --- a/app/Notifications/CheckoutAssetNotification.php +++ b/app/Notifications/CheckoutAssetNotification.php @@ -8,6 +8,7 @@ use App\Models\Setting; use App\Models\User; use Exception; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -32,6 +33,23 @@ class CheckoutAssetNotification extends Notification */ public function __construct(Asset $asset, $checkedOutTo, User $checkedOutBy, $acceptance, $note) { + $this->settings = Setting::getSettings(); + $this->item = $asset; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->target = $checkedOutTo; + $this->last_checkout = ''; + $this->expected_checkin = ''; + + if ($this->item->last_checkout) { + $this->last_checkout = Helper::getFormattedDateObject($this->item->last_checkout, 'date', + false); + } + + if ($this->item->expected_checkin) { + $this->expected_checkin = Helper::getFormattedDateObject($this->item->expected_checkin, 'date', + false); + } } /** * Get the notification's delivery channels. @@ -41,61 +59,34 @@ class CheckoutAssetNotification extends Notification public function via() { $notifyBy = []; - if (Setting::getSettings()->webhook_selected == 'google' && Setting::getSettings()->webhook_endpoint) { + + if (Setting::getSettings()->webhook_selected === 'google' && Setting::getSettings()->webhook_endpoint) { $notifyBy[] = GoogleChatChannel::class; } - if (Setting::getSettings()->webhook_selected == 'microsoft' && Setting::getSettings()->webhook_endpoint) { + if (Setting::getSettings()->webhook_selected === 'microsoft' && Setting::getSettings()->webhook_endpoint) { $notifyBy[] = MicrosoftTeamsChannel::class; } - if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { + if (Setting::getSettings()->webhook_selected === 'slack' || Setting::getSettings()->webhook_selected === 'general' ) { Log::debug('use webhook'); - $notifyBy[] = 'slack'; - } - - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ($this->item->checkin_email()) { - $notifyBy[1] = 'mail'; - } + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; } - public function toSlack() + public function toSlack() :SlackMessage { $target = $this->target; $admin = $this->admin; $item = $this->item; $note = $this->note; - $botname = ($this->settings->webhook_botname) ? $this->settings->webhook_botname : 'Snipe-Bot'; + $botname = ($this->settings->webhook_botname) ?: 'Snipe-Bot'; $channel = ($this->settings->webhook_channel) ? $this->settings->webhook_channel : ''; $fields = [ @@ -103,7 +94,7 @@ class CheckoutAssetNotification extends Notification 'By' => '<'.$admin->present()->viewUrl().'|'.$admin->present()->fullName().'>', ]; - if (($this->expected_checkin) && ($this->expected_checkin != '')) { + if (($this->expected_checkin) && ($this->expected_checkin !== '')) { $fields['Expected Checkin'] = $this->expected_checkin; } From 16cffe9a9dd0cbce4f38d161a2b4cbebeaffde1c Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 12:53:35 -0700 Subject: [PATCH 06/46] simplified checkout webhook call --- app/Listeners/CheckoutableListener.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 3204bf628b..16032a54f5 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -124,16 +124,9 @@ class CheckoutableListener \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) { From 9710436d54fc23e79bf96b61430f3f0f3345581a Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 13:12:07 -0700 Subject: [PATCH 07/46] adds Mailables for asset checkin and out --- app/Listeners/CheckoutableListener.php | 8 +- app/Mail/CheckinAssetMail.php | 102 ++++++++++++ app/Mail/CheckoutAssetMail.php | 150 ++++++++++++++++++ .../CheckinAssetNotification.php | 32 +--- .../markdown/checkin-asset.blade.php | 0 routes/web.php | 2 +- 6 files changed, 255 insertions(+), 39 deletions(-) create mode 100644 app/Mail/CheckinAssetMail.php create mode 100644 app/Mail/CheckoutAssetMail.php rename resources/views/{notifications => mail}/markdown/checkin-asset.blade.php (100%) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 16032a54f5..44e731b4ba 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -64,15 +64,9 @@ class CheckoutableListener 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 { 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) { @@ -111,7 +105,7 @@ class CheckoutableListener $mailable = (new CheckInAssetMail( $event->checkoutable, $event->checkedOutTo, - $event->checkedOutBy, + $event->checkedInBy, $event->note, )); diff --git a/app/Mail/CheckinAssetMail.php b/app/Mail/CheckinAssetMail.php new file mode 100644 index 0000000000..5795d795c7 --- /dev/null +++ b/app/Mail/CheckinAssetMail.php @@ -0,0 +1,102 @@ +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 = null; + $cc = []; + + if (!empty(Setting::getSettings()->alert_email)) { + $from = new Address(Setting::getSettings()->alert_email); + } + if (!empty(Setting::getSettings()->admin_cc_email)) { + $cc[] = new Address(Setting::getSettings()->admin_cc_email); + } + + return new Envelope( + from: $from ?? new Address('default@example.com', 'Default Sender'), + cc: $cc, + 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 + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Mail/CheckoutAssetMail.php b/app/Mail/CheckoutAssetMail.php new file mode 100644 index 0000000000..214c48ed5c --- /dev/null +++ b/app/Mail/CheckoutAssetMail.php @@ -0,0 +1,150 @@ +item = $asset; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + + $this->settings = Setting::getSettings(); + + $this->last_checkout = ''; + $this->expected_checkin = ''; + + if ($this->item->last_checkout) { + $this->last_checkout = Helper::getFormattedDateObject($this->item->last_checkout, 'date', + false); + } + + 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 = null; + $cc = []; + + if (!empty(Setting::getSettings()->alert_email)) { + $from = new Address(Setting::getSettings()->alert_email); + } + if (!empty(Setting::getSettings()->admin_cc_email)) { + $cc[] = new Address(Setting::getSettings()->admin_cc_email); + } + + return new Envelope( + from: $from ?? new Address('default@example.com', 'Default Sender'), + cc: $cc, + subject: trans('mail.Asset_Checkout_Notification'), + ); + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return Content + */ + public function content(): Content + { + $this->item->load('assetstatus'); + $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; + $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; + $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; + } + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-asset', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'status' => $this->item->assetstatus?->name, + 'note' => $this->note, + 'target' => $this->target, + 'fields' => $fields, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + 'last_checkout' => $this->last_checkout, + 'expected_checkin' => $this->expected_checkin, + ], + ); + } +// public function build() +// { +// $this->item->load('assetstatus'); +// $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; +// $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; +// $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; +// } +// +// $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); +// +// return $this +// ->subject('Asset Checkout Notification') +// ->markdown('notifications.markdown.checkout-asset') +// ->with([ +// 'item' => $this->item, +// 'admin' => $this->admin, +// 'status' => $this->item->assetstatus?->name, +// 'note' => $this->note, +// 'target' => $this->target, +// 'fields' => $fields, +// 'eula' => $eula, +// 'req_accept' => $req_accept, +// 'accept_url' => $accept_url, +// 'last_checkout' => $this->last_checkout, +// 'expected_checkin' => $this->expected_checkin, +// ]); +// } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Notifications/CheckinAssetNotification.php b/app/Notifications/CheckinAssetNotification.php index 85b1c74413..5c38982ab6 100644 --- a/app/Notifications/CheckinAssetNotification.php +++ b/app/Notifications/CheckinAssetNotification.php @@ -63,7 +63,7 @@ class CheckinAssetNotification extends Notification Log::debug('use webhook'); $notifyBy[] = 'slack'; } -dd($notifyBy); + // /** // * Only send checkin notifications to users if the category // * has the corresponding checkbox checked. @@ -141,35 +141,5 @@ dd($notifyBy); ) ) ); - - } - - /** - * Get the mail representation of the notification. - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - $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; - } - - $message = (new MailMessage)->markdown('notifications.markdown.checkin-asset', - [ - 'item' => $this->item, - 'status' => $this->item->assetstatus?->name, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - 'fields' => $fields, - 'expected_checkin' => $this->expected_checkin, - ]) - ->subject(trans('mail.Asset_Checkin_Notification')); - - return $message; } } diff --git a/resources/views/notifications/markdown/checkin-asset.blade.php b/resources/views/mail/markdown/checkin-asset.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkin-asset.blade.php rename to resources/views/mail/markdown/checkin-asset.blade.php diff --git a/routes/web.php b/routes/web.php index 7bed89acf7..548758e382 100644 --- a/routes/web.php +++ b/routes/web.php @@ -67,7 +67,7 @@ Route::group(['middleware' => 'auth'], function () { $fields = $item->model->fieldset->fields; } - return new \App\Mail\CheckoutAssetMail( + return new \App\Mail\CheckinAssetMail( $item, $admin, $target, From dcdf600b785501d960ee6a8f99a46f9a6ba90b9f Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 15:27:34 -0700 Subject: [PATCH 08/46] adds Checkin and Checkout mailables and listner logic --- app/Listeners/CheckoutableListener.php | 43 +++++--- app/Mail/CheckoutAccessoryMail.php | 98 +++++++++++++++++++ .../CheckinAccessoryNotification.php | 62 ++++++------ .../CheckoutAccessoryNotification.php | 58 +---------- .../markdown/checkin-accessory.blade.php | 0 .../markdown/checkout-accessory.blade.php | 0 routes/web.php | 6 +- 7 files changed, 162 insertions(+), 105 deletions(-) create mode 100644 app/Mail/CheckoutAccessoryMail.php rename resources/views/{notifications => mail}/markdown/checkin-accessory.blade.php (100%) rename resources/views/{notifications => mail}/markdown/checkout-accessory.blade.php (100%) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 44e731b4ba..6acedd4d97 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -3,6 +3,8 @@ namespace App\Listeners; use App\Events\CheckoutableCheckedOut; +use App\Mail\CheckinAccessoryMail; +use App\Mail\CheckoutAccessoryMail; use App\Mail\CheckoutAssetMail; use App\Mail\CheckinAssetMail; use App\Models\Accessory; @@ -47,14 +49,7 @@ class CheckoutableListener */ $acceptance = $this->getCheckoutAcceptance($event); $notifiable = $this->getNotifiable($event); - $mailable = (new CheckoutAssetMail( - $event->checkoutable, - $event->checkedOutTo, - $event->checkedOutBy, - $event->note, - $acceptance, - )); - + $mailable = $this->getCheckoutMailType($event, $acceptance); // Send email notifications try { if (!$event->checkedOutTo->locale){ @@ -102,12 +97,7 @@ class CheckoutableListener } $notifiable = $this->getNotifiable($event); - $mailable = (new CheckInAssetMail( - $event->checkoutable, - $event->checkedOutTo, - $event->checkedInBy, - $event->note, - )); + $mailable = $this->getCheckinMailType($event); // Send email notifications try { @@ -233,9 +223,32 @@ class CheckoutableListener break; } - 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, +// Consumable::class => +// LicenseSeat::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, +// Consumable::class => +// LicenseSeat::class => + ]; + $mailable= $lookup[get_class($event->checkoutable)]; + + return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note); + + } /** * Register the listeners for the subscriber. diff --git a/app/Mail/CheckoutAccessoryMail.php b/app/Mail/CheckoutAccessoryMail.php new file mode 100644 index 0000000000..f7f90e8fe2 --- /dev/null +++ b/app/Mail/CheckoutAccessoryMail.php @@ -0,0 +1,98 @@ +item = $accessory; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->checkout_qty = $accessory->checkout_qty; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = null; + $cc = []; + + if (!empty(Setting::getSettings()->alert_email)) { + $from = new Address(Setting::getSettings()->alert_email); + } + if (!empty(Setting::getSettings()->admin_cc_email)) { + $cc[] = new Address(Setting::getSettings()->admin_cc_email); + } + return new Envelope( + from: $from ?? new Address('default@example.com', 'Default Sender'), + cc: $cc, + subject: (trans('mail.Accessory_Checkout_Notification')), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + Log::debug($this->item->getImageUrl()); + $eula = $this->item->getEula(); + $req_accept = $this->item->requireAcceptance(); + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + // Check if the item has custom fields associated with it + if (($this->item->model) && ($this->item->model->fieldset)) { + $fields = $this->item->model->fieldset->fields; + } + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-accessory', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + 'checkout_qty' => $this->checkout_qty, + ], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Notifications/CheckinAccessoryNotification.php b/app/Notifications/CheckinAccessoryNotification.php index 7e033f1870..d36b77a850 100644 --- a/app/Notifications/CheckinAccessoryNotification.php +++ b/app/Notifications/CheckinAccessoryNotification.php @@ -58,18 +58,18 @@ class CheckinAccessoryNotification extends Notification $notifyBy[] = 'slack'; } - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - Log::debug('The target is a user'); - - if ($this->item->checkin_email()) { - $notifyBy[] = 'mail'; - } - } - - Log::debug('checkin_email on this category is '.$this->item->checkin_email()); +// /** +// * Only send notifications to users that have email addresses +// */ +// if ($this->target instanceof User && $this->target->email != '') { +// Log::debug('The target is a user'); +// +// if ($this->item->checkin_email()) { +// $notifyBy[] = 'mail'; +// } +// } +// +// Log::debug('checkin_email on this category is '.$this->item->checkin_email()); return $notifyBy; } @@ -143,23 +143,23 @@ class CheckinAccessoryNotification extends Notification } - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - Log::debug('to email called'); - - return (new MailMessage)->markdown('notifications.markdown.checkin-accessory', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - ]) - ->subject(trans('mail.Accessory_Checkin_Notification')); - } +// /** +// * Get the mail representation of the notification. +// * +// * @param mixed $notifiable +// * @return \Illuminate\Notifications\Messages\MailMessage +// */ +// public function toMail() +// { +// Log::debug('to email called'); +// +// return (new MailMessage)->markdown('notifications.markdown.checkin-accessory', +// [ +// 'item' => $this->item, +// 'admin' => $this->admin, +// 'note' => $this->note, +// 'target' => $this->target, +// ]) +// ->subject(trans('mail.Accessory_Checkin_Notification')); +// } } diff --git a/app/Notifications/CheckoutAccessoryNotification.php b/app/Notifications/CheckoutAccessoryNotification.php index 721ba7f6a4..cbc946ba43 100644 --- a/app/Notifications/CheckoutAccessoryNotification.php +++ b/app/Notifications/CheckoutAccessoryNotification.php @@ -6,6 +6,7 @@ use App\Models\Accessory; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -55,35 +56,7 @@ class CheckoutAccessoryNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; - } - - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ($this->item->checkin_email()) { - $notifyBy[1] = 'mail'; - } + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; @@ -163,31 +136,4 @@ class CheckoutAccessoryNotification extends Notification } - - /** - * Get the mail representation of the notification. - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - Log::debug($this->item->getImageUrl()); - $eula = $this->item->getEula(); - $req_accept = $this->item->requireAcceptance(); - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - return (new MailMessage)->markdown('notifications.markdown.checkout-accessory', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - 'eula' => $eula, - 'req_accept' => $req_accept, - 'accept_url' => $accept_url, - 'checkout_qty' => $this->checkout_qty, - ]) - ->subject(trans('mail.Confirm_accessory_delivery')); - } } diff --git a/resources/views/notifications/markdown/checkin-accessory.blade.php b/resources/views/mail/markdown/checkin-accessory.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkin-accessory.blade.php rename to resources/views/mail/markdown/checkin-accessory.blade.php diff --git a/resources/views/notifications/markdown/checkout-accessory.blade.php b/resources/views/mail/markdown/checkout-accessory.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkout-accessory.blade.php rename to resources/views/mail/markdown/checkout-accessory.blade.php diff --git a/routes/web.php b/routes/web.php index 548758e382..756c6dd451 100644 --- a/routes/web.php +++ b/routes/web.php @@ -24,6 +24,7 @@ use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Auth\ForgotPasswordController; use App\Http\Controllers\Auth\ResetPasswordController; use App\Livewire\Importer; +use App\Models\Accessory; use App\Models\Asset; use App\Models\User; use Illuminate\Support\Facades\Route; @@ -56,7 +57,7 @@ Route::group(['middleware' => 'auth'], function () { * Locations */ Route::get('/test-email', function() { - $item = Asset::find(1); // Load some test data + $item = Accessory::find(1); // Load some test data $admin = User::find(1); $target = User::find(2); $acceptance = null; // Simulate acceptance data @@ -67,11 +68,10 @@ Route::group(['middleware' => 'auth'], function () { $fields = $item->model->fieldset->fields; } - return new \App\Mail\CheckinAssetMail( + return new \App\Mail\CheckinAccessoryMail( $item, $admin, $target, - $acceptance, $note); }); From c39df34bdfabb2acde4ab8aaba01cf5c65582675 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 15:29:50 -0700 Subject: [PATCH 09/46] forgot to add accessory mail to project --- app/Mail/CheckinAccessoryMail.php | 79 +++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 app/Mail/CheckinAccessoryMail.php diff --git a/app/Mail/CheckinAccessoryMail.php b/app/Mail/CheckinAccessoryMail.php new file mode 100644 index 0000000000..0c3ddbba0e --- /dev/null +++ b/app/Mail/CheckinAccessoryMail.php @@ -0,0 +1,79 @@ +item = $accessory; + $this->target = $checkedOutTo; + $this->admin = $checkedInby; + $this->note = $note; + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = null; + $cc = []; + + if (!empty(Setting::getSettings()->alert_email)) { + $from = new Address(Setting::getSettings()->alert_email); + } + if (!empty(Setting::getSettings()->admin_cc_email)) { + $cc[] = new Address(Setting::getSettings()->admin_cc_email); + } + + return new Envelope( + from: $from ?? new Address('default@example.com', 'Default Sender'), + cc: $cc, + 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 + */ + public function attachments(): array + { + return []; + } +} From f1d83a3f281a7d17c2b8ca52ccaf8403cac4d246 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 15:30:53 -0700 Subject: [PATCH 10/46] forgot to add asset checkout markdown to projet --- .../mail/markdown/checkout-asset.blade.php | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 resources/views/mail/markdown/checkout-asset.blade.php diff --git a/resources/views/mail/markdown/checkout-asset.blade.php b/resources/views/mail/markdown/checkout-asset.blade.php new file mode 100644 index 0000000000..5b4c811dd7 --- /dev/null +++ b/resources/views/mail/markdown/checkout-asset.blade.php @@ -0,0 +1,76 @@ +@component('mail::message') + # {{ trans('mail.hello') }} {{ $target->present()->fullName() }}, + + {{ trans('mail.new_item_checked') }} + + @if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl()) +
Asset
+ @endif + + @component('mail::table') + | | | + | ------------- | ------------- | + @if ((isset($item->name)) && ($item->name!='')) + | **{{ trans('mail.asset_name') }}** | {{ $item->name }} | + @endif + @if (($item->name!=$item->asset_tag)) + | **{{ trans('mail.asset_tag') }}** | {{ $item->asset_tag }} | + @endif + @if (isset($item->manufacturer)) + | **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | + @endif + @if (isset($item->model)) + | **{{ trans('general.asset_model') }}** | {{ $item->model->name }} | + @endif + @if ((isset($item->model->model_number)) && ($item->model->name!=$item->model->model_number)) + | **{{ trans('general.model_no') }}** | {{ $item->model->model_number }} | + @endif + @if (isset($item->serial)) + | **{{ trans('mail.serial') }}** | {{ $item->serial }} | + @endif + @if (isset($last_checkout)) + | **{{ trans('mail.checkout_date') }}** | {{ $last_checkout }} | + @endif + @if (isset($status)) + | **{{ trans('general.status') }}** | {{ $status }} | + @endif + @if ((isset($expected_checkin)) && ($expected_checkin!='')) + | **{{ trans('mail.expecting_checkin_date') }}** | {{ $expected_checkin }} | + @endif + @foreach($fields as $field) + @if (($item->{ $field->db_column_name() }!='') && ($field->show_in_email) && ($field->field_encrypted=='0')) + | **{{ $field->name }}** | {{ $item->{ $field->db_column_name() } }} | + @endif + @endforeach + @if ($admin) + | **{{ trans('general.administrator') }}** | {{ $admin->present()->fullName() }} | + @endif + @if ($note) + | **{{ trans('mail.additional_notes') }}** | {{ $note }} | + @endif + @endcomponent + + @if (($req_accept == 1) && ($eula!='')) + {{ trans('mail.read_the_terms_and_click') }} + @elseif (($req_accept == 1) && ($eula=='')) + {{ trans('mail.click_on_the_link_asset') }} + @elseif (($req_accept == 0) && ($eula!='')) + {{ trans('mail.read_the_terms') }} + @endif + + @if ($eula) + @component('mail::panel') + {!! $eula !!} + @endcomponent + @endif + + @if ($req_accept == 1) + **[✔ {{ trans('mail.i_have_read') }}]({{ $accept_url }})** + @endif + + + {{ trans('mail.best_regards') }} + + {{ $snipeSettings->site_name }} + +@endcomponent \ No newline at end of file From 2584d603445bb0a82e722cd8b7a3dbf7f1c1d020 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 15:38:49 -0700 Subject: [PATCH 11/46] adds Licenses seat checkout Mailable --- app/Listeners/CheckoutableListener.php | 3 +- app/Mail/CheckoutLicenseMail.php | 89 +++++++++++++++++++ .../CheckoutLicenseSeatNotification.php | 28 ------ .../markdown/checkout-license.blade.php | 0 routes/web.php | 6 +- 5 files changed, 95 insertions(+), 31 deletions(-) create mode 100644 app/Mail/CheckoutLicenseMail.php rename resources/views/{notifications => mail}/markdown/checkout-license.blade.php (100%) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 6acedd4d97..915ed5753a 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -7,6 +7,7 @@ use App\Mail\CheckinAccessoryMail; use App\Mail\CheckoutAccessoryMail; use App\Mail\CheckoutAssetMail; use App\Mail\CheckinAssetMail; +use App\Mail\CheckoutLicenseMail; use App\Models\Accessory; use App\Models\Asset; use App\Models\CheckoutAcceptance; @@ -229,8 +230,8 @@ class CheckoutableListener $lookup = [ Accessory::class => CheckoutAccessoryMail::class, Asset::class => CheckoutAssetMail::class, + LicenseSeat::class => CheckoutLicenseMail::class, // Consumable::class => -// LicenseSeat::class => ]; $mailable= $lookup[get_class($event->checkoutable)]; diff --git a/app/Mail/CheckoutLicenseMail.php b/app/Mail/CheckoutLicenseMail.php new file mode 100644 index 0000000000..8389f1136f --- /dev/null +++ b/app/Mail/CheckoutLicenseMail.php @@ -0,0 +1,89 @@ +item = $licenseSeat->license; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = null; + $cc = []; + + if (!empty(Setting::getSettings()->alert_email)) { + $from = new Address(Setting::getSettings()->alert_email); + } + if (!empty(Setting::getSettings()->admin_cc_email)) { + $cc[] = new Address(Setting::getSettings()->admin_cc_email); + } + + return new Envelope( + from: $from ?? new Address('default@example.com', 'Default Sender'), + cc: $cc, + subject: trans('mail.Confirm_license_delivery'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; + $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-license', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Notifications/CheckoutLicenseSeatNotification.php b/app/Notifications/CheckoutLicenseSeatNotification.php index 8e0273c66e..16f8c7c1d5 100644 --- a/app/Notifications/CheckoutLicenseSeatNotification.php +++ b/app/Notifications/CheckoutLicenseSeatNotification.php @@ -63,34 +63,6 @@ class CheckoutLicenseSeatNotification extends Notification $notifyBy[] = 'slack'; } - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ($this->item->checkin_email()) { - $notifyBy[1] = 'mail'; - } - } - return $notifyBy; } diff --git a/resources/views/notifications/markdown/checkout-license.blade.php b/resources/views/mail/markdown/checkout-license.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkout-license.blade.php rename to resources/views/mail/markdown/checkout-license.blade.php diff --git a/routes/web.php b/routes/web.php index 756c6dd451..bcbe159b30 100644 --- a/routes/web.php +++ b/routes/web.php @@ -26,6 +26,7 @@ use App\Http\Controllers\Auth\ResetPasswordController; use App\Livewire\Importer; use App\Models\Accessory; use App\Models\Asset; +use App\Models\LicenseSeat; use App\Models\User; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Auth; @@ -57,7 +58,7 @@ Route::group(['middleware' => 'auth'], function () { * Locations */ Route::get('/test-email', function() { - $item = Accessory::find(1); // Load some test data + $item = LicenseSeat::find(1); // Load some test data $admin = User::find(1); $target = User::find(2); $acceptance = null; // Simulate acceptance data @@ -68,10 +69,11 @@ Route::group(['middleware' => 'auth'], function () { $fields = $item->model->fieldset->fields; } - return new \App\Mail\CheckinAccessoryMail( + return new \App\Mail\CheckoutLicenseMail( $item, $admin, $target, + $acceptance, $note); }); From 4becdca8aa792957243e5ca9a3dcf04cfa3ee522 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 15:39:20 -0700 Subject: [PATCH 12/46] removes toMail from license notificaqtion --- .../CheckoutLicenseSeatNotification.php | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/app/Notifications/CheckoutLicenseSeatNotification.php b/app/Notifications/CheckoutLicenseSeatNotification.php index 16f8c7c1d5..85d02abc92 100644 --- a/app/Notifications/CheckoutLicenseSeatNotification.php +++ b/app/Notifications/CheckoutLicenseSeatNotification.php @@ -136,29 +136,4 @@ class CheckoutLicenseSeatNotification extends Notification ); } - - /** - * Get the mail representation of the notification. - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; - $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - return (new MailMessage)->markdown('notifications.markdown.checkout-license', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - 'eula' => $eula, - 'req_accept' => $req_accept, - 'accept_url' => $accept_url, - ]) - ->subject(trans('mail.Confirm_license_delivery')); - } } From 02ff646da4388422d260ed50d8e93ea7bc57dab0 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 15:44:45 -0700 Subject: [PATCH 13/46] adds checkin license mailable --- app/Listeners/CheckoutableListener.php | 3 +- app/Mail/CheckinLicenseMail.php | 79 +++++++++++++++++++ .../CheckinAccessoryNotification.php | 33 -------- .../CheckinLicenseSeatNotification.php | 27 ------- .../markdown/checkin-license.blade.php | 0 5 files changed, 81 insertions(+), 61 deletions(-) create mode 100644 app/Mail/CheckinLicenseMail.php rename resources/views/{notifications => mail}/markdown/checkin-license.blade.php (100%) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 915ed5753a..fe9f7b6d38 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -4,6 +4,7 @@ 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; @@ -242,8 +243,8 @@ class CheckoutableListener $lookup = [ Accessory::class => CheckinAccessoryMail::class, Asset::class => CheckinAssetMail::class, + LicenseSeat::class => CheckinLicenseMail::class, // Consumable::class => -// LicenseSeat::class => ]; $mailable= $lookup[get_class($event->checkoutable)]; diff --git a/app/Mail/CheckinLicenseMail.php b/app/Mail/CheckinLicenseMail.php new file mode 100644 index 0000000000..e567383f80 --- /dev/null +++ b/app/Mail/CheckinLicenseMail.php @@ -0,0 +1,79 @@ +target = $checkedOutTo; + $this->item = $licenseSeat->license; + $this->admin = $checkedInBy; + $this->note = $note; + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = null; + $cc = []; + + if (!empty(Setting::getSettings()->alert_email)) { + $from = new Address(Setting::getSettings()->alert_email); + } + if (!empty(Setting::getSettings()->admin_cc_email)) { + $cc[] = new Address(Setting::getSettings()->admin_cc_email); + } + + return new Envelope( + from: $from ?? new Address('default@example.com', 'Default Sender'), + cc: $cc, + subject: trans('mail.License_Checkin_Notification'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + return new Content( + markdown: 'mail.markdown.checkin-license', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Notifications/CheckinAccessoryNotification.php b/app/Notifications/CheckinAccessoryNotification.php index d36b77a850..777834aae7 100644 --- a/app/Notifications/CheckinAccessoryNotification.php +++ b/app/Notifications/CheckinAccessoryNotification.php @@ -58,19 +58,6 @@ class CheckinAccessoryNotification extends Notification $notifyBy[] = 'slack'; } -// /** -// * Only send notifications to users that have email addresses -// */ -// if ($this->target instanceof User && $this->target->email != '') { -// Log::debug('The target is a user'); -// -// if ($this->item->checkin_email()) { -// $notifyBy[] = 'mail'; -// } -// } -// -// Log::debug('checkin_email on this category is '.$this->item->checkin_email()); - return $notifyBy; } @@ -142,24 +129,4 @@ class CheckinAccessoryNotification extends Notification ); } - -// /** -// * Get the mail representation of the notification. -// * -// * @param mixed $notifiable -// * @return \Illuminate\Notifications\Messages\MailMessage -// */ -// public function toMail() -// { -// Log::debug('to email called'); -// -// return (new MailMessage)->markdown('notifications.markdown.checkin-accessory', -// [ -// 'item' => $this->item, -// 'admin' => $this->admin, -// 'note' => $this->note, -// 'target' => $this->target, -// ]) -// ->subject(trans('mail.Accessory_Checkin_Notification')); -// } } diff --git a/app/Notifications/CheckinLicenseSeatNotification.php b/app/Notifications/CheckinLicenseSeatNotification.php index 289e63a162..114011bd72 100644 --- a/app/Notifications/CheckinLicenseSeatNotification.php +++ b/app/Notifications/CheckinLicenseSeatNotification.php @@ -61,14 +61,6 @@ class CheckinLicenseSeatNotification extends Notification $notifyBy[] = 'slack'; } - /** - * Only send checkin notifications to users if the category - * has the corresponding checkbox checked. - */ - if ($this->item->checkin_email() && $this->target instanceof User && $this->target->email != '') { - $notifyBy[] = 'mail'; - } - return $notifyBy; } @@ -149,23 +141,4 @@ class CheckinLicenseSeatNotification extends Notification ); } - - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - return (new MailMessage)->markdown('notifications.markdown.checkin-license', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - ]) - ->subject(trans('mail.License_Checkin_Notification')); - } } diff --git a/resources/views/notifications/markdown/checkin-license.blade.php b/resources/views/mail/markdown/checkin-license.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkin-license.blade.php rename to resources/views/mail/markdown/checkin-license.blade.php From 02bda3cd9598d77ddd2c68f67f589f82e0af37b3 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 15:53:05 -0700 Subject: [PATCH 14/46] adds Checkout Consumable mailable and slackwebhook channel to notifs --- app/Listeners/CheckoutableListener.php | 16 ++-- app/Mail/CheckoutConsumableMail.php | 91 +++++++++++++++++++ .../CheckinAccessoryNotification.php | 3 +- .../CheckoutConsumableNotification.php | 83 ++++++----------- .../CheckoutLicenseSeatNotification.php | 3 +- .../markdown/checkout-consumable.blade.php | 0 6 files changed, 133 insertions(+), 63 deletions(-) create mode 100644 app/Mail/CheckoutConsumableMail.php rename resources/views/{notifications => mail}/markdown/checkout-consumable.blade.php (100%) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index fe9f7b6d38..4f51ed705f 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -8,6 +8,7 @@ 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; @@ -210,21 +211,22 @@ class CheckoutableListener { $notificationClass = null; - switch (true) { - case $event->checkoutable instanceof Accessory: + switch (get_class($event->checkoutable)) { + case Accessory::class: $notificationClass = CheckoutAccessoryNotification::class; break; - case $event->checkoutable instanceof Asset: + case Asset::class: $notificationClass = CheckoutAssetNotification::class; break; - case $event->checkoutable instanceof Consumable: + case Consumable::class: $notificationClass = CheckoutConsumableNotification::class; break; - case $event->checkoutable instanceof LicenseSeat: + case LicenseSeat::class: $notificationClass = CheckoutLicenseSeatNotification::class; break; } + return new $notificationClass($event->checkoutable, $event->checkedOutTo, $event->checkedOutBy, $acceptance, $event->note); } private function getCheckoutMailType($event, $acceptance){ @@ -232,7 +234,7 @@ class CheckoutableListener Accessory::class => CheckoutAccessoryMail::class, Asset::class => CheckoutAssetMail::class, LicenseSeat::class => CheckoutLicenseMail::class, -// Consumable::class => + Consumable::class => CheckoutConsumableMail::class, ]; $mailable= $lookup[get_class($event->checkoutable)]; @@ -244,8 +246,8 @@ class CheckoutableListener Accessory::class => CheckinAccessoryMail::class, Asset::class => CheckinAssetMail::class, LicenseSeat::class => CheckinLicenseMail::class, -// Consumable::class => ]; + $mailable= $lookup[get_class($event->checkoutable)]; return new $mailable($event->checkoutable, $event->checkedOutTo, $event->checkedInBy, $event->note); diff --git a/app/Mail/CheckoutConsumableMail.php b/app/Mail/CheckoutConsumableMail.php new file mode 100644 index 0000000000..382f789eb9 --- /dev/null +++ b/app/Mail/CheckoutConsumableMail.php @@ -0,0 +1,91 @@ +item = $consumable; + $this->admin = $checkedOutBy; + $this->note = $note; + $this->target = $checkedOutTo; + $this->acceptance = $acceptance; + + $this->settings = Setting::getSettings(); + } + + /** + * Get the message envelope. + */ + public function envelope(): Envelope + { + $from = null; + $cc = []; + + if (!empty(Setting::getSettings()->alert_email)) { + $from = new Address(Setting::getSettings()->alert_email); + } + if (!empty(Setting::getSettings()->admin_cc_email)) { + $cc[] = new Address(Setting::getSettings()->admin_cc_email); + } + + return new Envelope( + from: $from ?? new Address('default@example.com', 'Default Sender'), + cc: $cc, + subject: trans('mail.Confirm_consumable_delivery'), + ); + } + + /** + * Get the message content definition. + */ + public function content(): Content + { + Log::debug($this->item->getImageUrl()); + $eula = $this->item->getEula(); + $req_accept = $this->item->requireAcceptance(); + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return new Content( + markdown: 'mail.markdown.checkout-consumable', + with: [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + ] + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + return []; + } +} diff --git a/app/Notifications/CheckinAccessoryNotification.php b/app/Notifications/CheckinAccessoryNotification.php index 777834aae7..d295515121 100644 --- a/app/Notifications/CheckinAccessoryNotification.php +++ b/app/Notifications/CheckinAccessoryNotification.php @@ -6,6 +6,7 @@ use App\Models\Accessory; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -55,7 +56,7 @@ class CheckinAccessoryNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; diff --git a/app/Notifications/CheckoutConsumableNotification.php b/app/Notifications/CheckoutConsumableNotification.php index 6746795f2c..0a2733689b 100644 --- a/app/Notifications/CheckoutConsumableNotification.php +++ b/app/Notifications/CheckoutConsumableNotification.php @@ -6,6 +6,7 @@ use App\Models\Consumable; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -61,36 +62,36 @@ class CheckoutConsumableNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; + $notifyBy[] = SlackWebhookChannel::class; } - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ((method_exists($this->item, 'checkin_email')) && ($this->item->checkin_email())) { - $notifyBy[1] = 'mail'; - } - } +// /** +// * Only send notifications to users that have email addresses +// */ +// if ($this->target instanceof User && $this->target->email != '') { +// +// /** +// * Send an email if the asset requires acceptance, +// * so the user can accept or decline the asset +// */ +// if ($this->item->requireAcceptance()) { +// $notifyBy[1] = 'mail'; +// } +// +// /** +// * Send an email if the item has a EULA, since the user should always receive it +// */ +// if ($this->item->getEula()) { +// $notifyBy[1] = 'mail'; +// } +// +// /** +// * Send an email if an email should be sent at checkin/checkout +// */ +// if ((method_exists($this->item, 'checkin_email')) && ($this->item->checkin_email())) { +// $notifyBy[1] = 'mail'; +// } +// } return $notifyBy; } @@ -165,30 +166,4 @@ class CheckoutConsumableNotification extends Notification ); } - - /** - * Get the mail representation of the notification. - * - * @return \Illuminate\Notifications\Messages\MailMessage - */ - public function toMail() - { - Log::debug($this->item->getImageUrl()); - $eula = $this->item->getEula(); - $req_accept = $this->item->requireAcceptance(); - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - return (new MailMessage)->markdown('notifications.markdown.checkout-consumable', - [ - 'item' => $this->item, - 'admin' => $this->admin, - 'note' => $this->note, - 'target' => $this->target, - 'eula' => $eula, - 'req_accept' => $req_accept, - 'accept_url' => $accept_url, - ]) - ->subject(trans('mail.Confirm_consumable_delivery')); - } } diff --git a/app/Notifications/CheckoutLicenseSeatNotification.php b/app/Notifications/CheckoutLicenseSeatNotification.php index 85d02abc92..1c26138a6e 100644 --- a/app/Notifications/CheckoutLicenseSeatNotification.php +++ b/app/Notifications/CheckoutLicenseSeatNotification.php @@ -6,6 +6,7 @@ use App\Models\LicenseSeat; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -60,7 +61,7 @@ class CheckoutLicenseSeatNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; diff --git a/resources/views/notifications/markdown/checkout-consumable.blade.php b/resources/views/mail/markdown/checkout-consumable.blade.php similarity index 100% rename from resources/views/notifications/markdown/checkout-consumable.blade.php rename to resources/views/mail/markdown/checkout-consumable.blade.php From a7754c1a7fd6559b5d512fbd520556c9d10b76aa Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 16:46:52 -0700 Subject: [PATCH 15/46] fixed asset checkout markdown, and notifiable variable --- app/Listeners/CheckoutableListener.php | 35 +---- .../mail/markdown/checkout-asset.blade.php | 128 +++++++++--------- 2 files changed, 67 insertions(+), 96 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 4f51ed705f..44987e20d1 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -16,10 +16,9 @@ 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; +use App\Notifications\CheckinAssetNotification; use App\Notifications\CheckinLicenseSeatNotification; use App\Notifications\CheckoutAccessoryNotification; use App\Notifications\CheckoutAssetNotification; @@ -51,7 +50,7 @@ class CheckoutableListener * Make a checkout acceptance and attach it in the notification */ $acceptance = $this->getCheckoutAcceptance($event); - $notifiable = $this->getNotifiable($event); + $notifiable = $event->checkedOutTo; $mailable = $this->getCheckoutMailType($event, $acceptance); // Send email notifications try { @@ -99,7 +98,7 @@ class CheckoutableListener } } - $notifiable = $this->getNotifiable($event); + $notifiable = $event->checkedInBy; $mailable = $this->getCheckinMailType($event); // Send email notifications @@ -144,34 +143,6 @@ class CheckoutableListener return $acceptance; } - /** - * Gets the entities to be notified of the passed event - * - * @param Event $event - * @return Collection - */ - private function getNotifiable($event) - { - $notifiable = collect(); - - /** - * Notify who checked out the item as long as the model can route notifications - */ - if (method_exists($event->checkedOutTo, 'routeNotificationFor')) { - $notifiable->push($event->checkedOutTo); - } - - /** - * Notify Admin users if the settings is activated - */ - if ((Setting::getSettings()) && (Setting::getSettings()->admin_cc_email != '')) { - $adminRecipient= new AdminRecipient; - $notifiable->push($adminRecipient->getEmail()); - } - - return new $notifiable; - } - /** * Get the appropriate notification for the event * diff --git a/resources/views/mail/markdown/checkout-asset.blade.php b/resources/views/mail/markdown/checkout-asset.blade.php index 5b4c811dd7..aae0b21584 100644 --- a/resources/views/mail/markdown/checkout-asset.blade.php +++ b/resources/views/mail/markdown/checkout-asset.blade.php @@ -1,76 +1,76 @@ @component('mail::message') - # {{ trans('mail.hello') }} {{ $target->present()->fullName() }}, +# {{ trans('mail.hello') }} {{ $target->present()->fullName() }}, - {{ trans('mail.new_item_checked') }} +{{ trans('mail.new_item_checked') }} - @if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl()) -
Asset
- @endif +@if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl()) +
Asset
+@endif - @component('mail::table') - | | | - | ------------- | ------------- | - @if ((isset($item->name)) && ($item->name!='')) - | **{{ trans('mail.asset_name') }}** | {{ $item->name }} | - @endif - @if (($item->name!=$item->asset_tag)) - | **{{ trans('mail.asset_tag') }}** | {{ $item->asset_tag }} | - @endif - @if (isset($item->manufacturer)) - | **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | - @endif - @if (isset($item->model)) - | **{{ trans('general.asset_model') }}** | {{ $item->model->name }} | - @endif - @if ((isset($item->model->model_number)) && ($item->model->name!=$item->model->model_number)) - | **{{ trans('general.model_no') }}** | {{ $item->model->model_number }} | - @endif - @if (isset($item->serial)) - | **{{ trans('mail.serial') }}** | {{ $item->serial }} | - @endif - @if (isset($last_checkout)) - | **{{ trans('mail.checkout_date') }}** | {{ $last_checkout }} | - @endif - @if (isset($status)) - | **{{ trans('general.status') }}** | {{ $status }} | - @endif - @if ((isset($expected_checkin)) && ($expected_checkin!='')) - | **{{ trans('mail.expecting_checkin_date') }}** | {{ $expected_checkin }} | - @endif - @foreach($fields as $field) - @if (($item->{ $field->db_column_name() }!='') && ($field->show_in_email) && ($field->field_encrypted=='0')) - | **{{ $field->name }}** | {{ $item->{ $field->db_column_name() } }} | - @endif - @endforeach - @if ($admin) - | **{{ trans('general.administrator') }}** | {{ $admin->present()->fullName() }} | - @endif - @if ($note) - | **{{ trans('mail.additional_notes') }}** | {{ $note }} | - @endif - @endcomponent +@component('mail::table') +| | | +| ------------- | ------------- | +@if ((isset($item->name)) && ($item->name!='')) +| **{{ trans('mail.asset_name') }}** | {{ $item->name }} | +@endif +@if (($item->name!=$item->asset_tag)) +| **{{ trans('mail.asset_tag') }}** | {{ $item->asset_tag }} | +@endif +@if (isset($item->manufacturer)) +| **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | +@endif +@if (isset($item->model)) +| **{{ trans('general.asset_model') }}** | {{ $item->model->name }} | +@endif +@if ((isset($item->model->model_number)) && ($item->model->name!=$item->model->model_number)) +| **{{ trans('general.model_no') }}** | {{ $item->model->model_number }} | +@endif +@if (isset($item->serial)) +| **{{ trans('mail.serial') }}** | {{ $item->serial }} | +@endif +@if (isset($last_checkout)) +| **{{ trans('mail.checkout_date') }}** | {{ $last_checkout }} | +@endif +@if (isset($status)) +| **{{ trans('general.status') }}** | {{ $status }} | +@endif +@if ((isset($expected_checkin)) && ($expected_checkin!='')) +| **{{ trans('mail.expecting_checkin_date') }}** | {{ $expected_checkin }} | +@endif +@foreach($fields as $field) +@if (($item->{ $field->db_column_name() }!='') && ($field->show_in_email) && ($field->field_encrypted=='0')) +| **{{ $field->name }}** | {{ $item->{ $field->db_column_name() } }} | +@endif +@endforeach +@if ($admin) +| **{{ trans('general.administrator') }}** | {{ $admin->present()->fullName() }} | +@endif +@if ($note) +| **{{ trans('mail.additional_notes') }}** | {{ $note }} | +@endif +@endcomponent - @if (($req_accept == 1) && ($eula!='')) - {{ trans('mail.read_the_terms_and_click') }} - @elseif (($req_accept == 1) && ($eula=='')) - {{ trans('mail.click_on_the_link_asset') }} - @elseif (($req_accept == 0) && ($eula!='')) - {{ trans('mail.read_the_terms') }} - @endif +@if (($req_accept == 1) && ($eula!='')) +{{ trans('mail.read_the_terms_and_click') }} +@elseif (($req_accept == 1) && ($eula=='')) +{{ trans('mail.click_on_the_link_asset') }} +@elseif (($req_accept == 0) && ($eula!='')) +{{ trans('mail.read_the_terms') }} +@endif - @if ($eula) - @component('mail::panel') - {!! $eula !!} - @endcomponent - @endif +@if ($eula) +@component('mail::panel') +{!! $eula !!} +@endcomponent +@endif - @if ($req_accept == 1) - **[✔ {{ trans('mail.i_have_read') }}]({{ $accept_url }})** - @endif +@if ($req_accept == 1) +**[✔ {{ trans('mail.i_have_read') }}]({{ $accept_url }})** +@endif - {{ trans('mail.best_regards') }} +{{ trans('mail.best_regards') }} - {{ $snipeSettings->site_name }} +{{ $snipeSettings->site_name }} @endcomponent \ No newline at end of file From ed6034065b34797ba531782a207fe49384e0f465 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 16:47:36 -0700 Subject: [PATCH 16/46] removed test route --- routes/web.php | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/routes/web.php b/routes/web.php index bcbe159b30..dbd1a53808 100644 --- a/routes/web.php +++ b/routes/web.php @@ -57,27 +57,6 @@ Route::group(['middleware' => 'auth'], function () { /* * Locations */ - Route::get('/test-email', function() { - $item = LicenseSeat::find(1); // Load some test data - $admin = User::find(1); - $target = User::find(2); - $acceptance = null; // Simulate acceptance data - $note = 'Test note'; - - $fields = []; - if (($item->model) && ($item->model->fieldset)) { - $fields = $item->model->fieldset->fields; - } - - return new \App\Mail\CheckoutLicenseMail( - $item, - $admin, - $target, - $acceptance, - $note); - }); - - Route::group(['prefix' => 'locations', 'middleware' => ['auth']], function () { Route::post( From 9a794833755ff5fb335ab6cf1e118a0d411b021e Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 16 Oct 2024 16:59:18 -0700 Subject: [PATCH 17/46] removed namespaces from routing --- routes/web.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/routes/web.php b/routes/web.php index dbd1a53808..9d9d4ab21f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -24,10 +24,6 @@ use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Auth\ForgotPasswordController; use App\Http\Controllers\Auth\ResetPasswordController; use App\Livewire\Importer; -use App\Models\Accessory; -use App\Models\Asset; -use App\Models\LicenseSeat; -use App\Models\User; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Auth; From 285d6897cf83d2cac7e791fa50d23ec88f116849 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 12:05:36 -0700 Subject: [PATCH 18/46] added a coulple test adjustments and moved mail send logic to listener --- app/Listeners/CheckoutableListener.php | 13 ++++ .../CheckoutAssetNotification.php | 9 --- .../CheckoutConsumableNotification.php | 54 ++++++------- .../markdown/checkout-asset.blade.php | 76 ------------------- .../Checkouts/Ui/ConsumableCheckoutTest.php | 7 +- .../EmailNotificationsUponCheckinTest.php | 22 +++--- 6 files changed, 57 insertions(+), 124 deletions(-) delete mode 100644 resources/views/notifications/markdown/checkout-asset.blade.php diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 44987e20d1..3e23259fb6 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -57,8 +57,21 @@ class CheckoutableListener 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 ($event->checkoutable->requireAcceptance() || $event->checkoutable->getEula() || + (method_exists($event->checkoutable, 'checkin_email') && $event->checkoutable->checkin_email())) { + Mail::to($notifiable)->send($mailable); Log::info('Sending email, Locale: ' .($event->checkedOutTo->locale ?? 'default')); + } + // Send Webhook notification if ($this->shouldSendWebhookNotification()) { Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) diff --git a/app/Notifications/CheckoutAssetNotification.php b/app/Notifications/CheckoutAssetNotification.php index 1ca329ed80..97706cec94 100644 --- a/app/Notifications/CheckoutAssetNotification.php +++ b/app/Notifications/CheckoutAssetNotification.php @@ -9,7 +9,6 @@ use App\Models\User; use Exception; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Channels\SlackWebhookChannel; -use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; use NotificationChannels\GoogleChat\Card; @@ -154,12 +153,4 @@ public function toGoogleChat() ); } - - /** - * Get the mail representation of the notification. - * - * @param mixed $notifiable - * @return \Illuminate\Notifications\Messages\MailMessage - */ - } diff --git a/app/Notifications/CheckoutConsumableNotification.php b/app/Notifications/CheckoutConsumableNotification.php index 0a2733689b..3f2adc3331 100644 --- a/app/Notifications/CheckoutConsumableNotification.php +++ b/app/Notifications/CheckoutConsumableNotification.php @@ -65,33 +65,33 @@ class CheckoutConsumableNotification extends Notification $notifyBy[] = SlackWebhookChannel::class; } -// /** -// * Only send notifications to users that have email addresses -// */ -// if ($this->target instanceof User && $this->target->email != '') { -// -// /** -// * Send an email if the asset requires acceptance, -// * so the user can accept or decline the asset -// */ -// if ($this->item->requireAcceptance()) { -// $notifyBy[1] = 'mail'; -// } -// -// /** -// * Send an email if the item has a EULA, since the user should always receive it -// */ -// if ($this->item->getEula()) { -// $notifyBy[1] = 'mail'; -// } -// -// /** -// * Send an email if an email should be sent at checkin/checkout -// */ -// if ((method_exists($this->item, 'checkin_email')) && ($this->item->checkin_email())) { -// $notifyBy[1] = 'mail'; -// } -// } + /** + * Only send notifications to users that have email addresses + */ + if ($this->target instanceof User && $this->target->email != '') { + + /** + * Send an email if the asset requires acceptance, + * so the user can accept or decline the asset + */ + if ($this->item->requireAcceptance()) { + $notifyBy[1] = 'mail'; + } + + /** + * Send an email if the item has a EULA, since the user should always receive it + */ + if ($this->item->getEula()) { + $notifyBy[1] = 'mail'; + } + + /** + * Send an email if an email should be sent at checkin/checkout + */ + if ((method_exists($this->item, 'checkin_email')) && ($this->item->checkin_email())) { + $notifyBy[1] = 'mail'; + } + } return $notifyBy; } diff --git a/resources/views/notifications/markdown/checkout-asset.blade.php b/resources/views/notifications/markdown/checkout-asset.blade.php deleted file mode 100644 index 5b4c811dd7..0000000000 --- a/resources/views/notifications/markdown/checkout-asset.blade.php +++ /dev/null @@ -1,76 +0,0 @@ -@component('mail::message') - # {{ trans('mail.hello') }} {{ $target->present()->fullName() }}, - - {{ trans('mail.new_item_checked') }} - - @if (($snipeSettings->show_images_in_email =='1') && $item->getImageUrl()) -
Asset
- @endif - - @component('mail::table') - | | | - | ------------- | ------------- | - @if ((isset($item->name)) && ($item->name!='')) - | **{{ trans('mail.asset_name') }}** | {{ $item->name }} | - @endif - @if (($item->name!=$item->asset_tag)) - | **{{ trans('mail.asset_tag') }}** | {{ $item->asset_tag }} | - @endif - @if (isset($item->manufacturer)) - | **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | - @endif - @if (isset($item->model)) - | **{{ trans('general.asset_model') }}** | {{ $item->model->name }} | - @endif - @if ((isset($item->model->model_number)) && ($item->model->name!=$item->model->model_number)) - | **{{ trans('general.model_no') }}** | {{ $item->model->model_number }} | - @endif - @if (isset($item->serial)) - | **{{ trans('mail.serial') }}** | {{ $item->serial }} | - @endif - @if (isset($last_checkout)) - | **{{ trans('mail.checkout_date') }}** | {{ $last_checkout }} | - @endif - @if (isset($status)) - | **{{ trans('general.status') }}** | {{ $status }} | - @endif - @if ((isset($expected_checkin)) && ($expected_checkin!='')) - | **{{ trans('mail.expecting_checkin_date') }}** | {{ $expected_checkin }} | - @endif - @foreach($fields as $field) - @if (($item->{ $field->db_column_name() }!='') && ($field->show_in_email) && ($field->field_encrypted=='0')) - | **{{ $field->name }}** | {{ $item->{ $field->db_column_name() } }} | - @endif - @endforeach - @if ($admin) - | **{{ trans('general.administrator') }}** | {{ $admin->present()->fullName() }} | - @endif - @if ($note) - | **{{ trans('mail.additional_notes') }}** | {{ $note }} | - @endif - @endcomponent - - @if (($req_accept == 1) && ($eula!='')) - {{ trans('mail.read_the_terms_and_click') }} - @elseif (($req_accept == 1) && ($eula=='')) - {{ trans('mail.click_on_the_link_asset') }} - @elseif (($req_accept == 0) && ($eula!='')) - {{ trans('mail.read_the_terms') }} - @endif - - @if ($eula) - @component('mail::panel') - {!! $eula !!} - @endcomponent - @endif - - @if ($req_accept == 1) - **[✔ {{ trans('mail.i_have_read') }}]({{ $accept_url }})** - @endif - - - {{ trans('mail.best_regards') }} - - {{ $snipeSettings->site_name }} - -@endcomponent \ No newline at end of file diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index 484b7e72cb..46c34aedd7 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -8,6 +8,7 @@ use App\Models\Component; use App\Models\Consumable; use App\Models\User; use App\Notifications\CheckoutConsumableNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -53,7 +54,7 @@ class ConsumableCheckoutTest extends TestCase public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $consumable = Consumable::factory()->create(); $user = User::factory()->create(); @@ -63,7 +64,9 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Notification::assertSentTo($user, CheckoutConsumableNotification::class); + Mail::assertSent(CheckoutConsumableNotification::class, function ($mail) use ($consumable, $user) { + return $mail->hasTo($user) && $mail->consumables->contains($consumable); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php index 449f65c7ab..c7c239b7ab 100644 --- a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php +++ b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php @@ -2,6 +2,8 @@ namespace Tests\Feature\Notifications\Email; +use App\Mail\CheckinAssetMail; +use Illuminate\Support\Facades\Mail; use PHPUnit\Framework\Attributes\Group; use App\Events\CheckoutableCheckedIn; use App\Models\Asset; @@ -22,6 +24,8 @@ class EmailNotificationsUponCheckinTest extends TestCase public function testCheckInEmailSentToUserIfSettingEnabled() { + Mail::fake(); + $user = User::factory()->create(); $asset = Asset::factory()->assignedToUser($user)->create(); @@ -29,16 +33,16 @@ class EmailNotificationsUponCheckinTest extends TestCase $this->fireCheckInEvent($asset, $user); - Notification::assertSentTo( - $user, - function (CheckinAssetNotification $notification, $channels) { - return in_array('mail', $channels); - }, - ); + Mail::assertSent(CheckinAssetMail::class, function($mail) use ($user, $asset) { + return $mail->hasTo($user->email) && $mail->event->checkoutable->id === $asset->id; + }); + } public function testCheckInEmailNotSentToUserIfSettingDisabled() { + Mail::fake(); + $user = User::factory()->create(); $asset = Asset::factory()->assignedToUser($user)->create(); @@ -46,10 +50,8 @@ class EmailNotificationsUponCheckinTest extends TestCase $this->fireCheckInEvent($asset, $user); - Notification::assertNotSentTo( - $user, - function (CheckinAssetNotification $notification, $channels) { - return in_array('mail', $channels); + Mail::assertNotSent(CheckinAssetMail::class, function($mail) use ($user, $asset) { + return $mail->hasTo($user->email) && $mail->event->checkoutable->id === $asset->id; } ); } From 65735a31f178c8bd4e1efabc7190a30e3500f5fd Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 12:18:34 -0700 Subject: [PATCH 19/46] removed symfony/mailgun-mailer symfony/http-client --- composer.json | 2 - composer.lock | 415 +++++++++++++++++++++----------------------------- 2 files changed, 173 insertions(+), 244 deletions(-) diff --git a/composer.json b/composer.json index b255f821cd..6d89312578 100644 --- a/composer.json +++ b/composer.json @@ -63,8 +63,6 @@ "rollbar/rollbar-laravel": "^8.0", "spatie/laravel-backup": "^8.8", "spatie/laravel-ignition": "^2.0", - "symfony/http-client": "^7.1", - "symfony/mailgun-mailer": "^7.1", "tecnickcom/tc-lib-barcode": "^1.15", "tecnickcom/tcpdf": "^6.5", "unicodeveloper/laravel-password": "^1.0", diff --git a/composer.lock b/composer.lock index c6e469c597..9132659142 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0378e36c927d3838ac338c4f58ed30cd", + "content-hash": "3819ab4ef72eb77fabe494c0e746b83b", "packages": [ { "name": "alek13/slack", @@ -9081,178 +9081,6 @@ ], "time": "2024-08-13T14:27:37+00:00" }, - { - "name": "symfony/http-client", - "version": "v7.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client.git", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "^3.4.1", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.4" - }, - "provide": { - "php-http/async-client-implementation": "*", - "php-http/client-implementation": "*", - "psr/http-client-implementation": "1.0", - "symfony/http-client-implementation": "3.0" - }, - "require-dev": { - "amphp/amp": "^2.5", - "amphp/http-client": "^4.2.1", - "amphp/http-tunnel": "^1.0", - "amphp/socket": "^1.1", - "guzzlehttp/promises": "^1.4|^2.0", - "nyholm/psr7": "^1.0", - "php-http/httplug": "^1.0|^2.0", - "psr/http-client": "^1.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", - "homepage": "https://symfony.com", - "keywords": [ - "http" - ], - "support": { - "source": "https://github.com/symfony/http-client/tree/v7.1.5" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-20T13:35:23+00:00" - }, - { - "name": "symfony/http-client-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "20414d96f391677bf80078aa55baece78b82647d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", - "reference": "20414d96f391677bf80078aa55baece78b82647d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to HTTP clients", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-04-18T09:32:20+00:00" - }, { "name": "symfony/http-foundation", "version": "v6.4.12", @@ -9524,75 +9352,6 @@ ], "time": "2024-09-08T12:30:05+00:00" }, - { - "name": "symfony/mailgun-mailer", - "version": "v7.1.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "dac02fe68e9306849703025511c56f10701696a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/dac02fe68e9306849703025511c56f10701696a8", - "reference": "dac02fe68e9306849703025511c56f10701696a8", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/mailer": "^6.4|^7.0" - }, - "conflict": { - "symfony/http-foundation": "<6.4" - }, - "require-dev": { - "symfony/http-client": "^6.4|^7.0", - "symfony/webhook": "^6.4|^7.0" - }, - "type": "symfony-mailer-bridge", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mailer\\Bridge\\Mailgun\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Mailgun Mailer Bridge", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.3" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-07-04T11:20:59+00:00" - }, { "name": "symfony/mime", "version": "v6.4.12", @@ -16269,6 +16028,178 @@ ], "time": "2024-09-16T16:01:33+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-20T13:35:23+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/options-resolver", "version": "v6.4.8", From ceb3f5cea629ed68fa4bfc119fefa2166456499c Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 12:19:50 -0700 Subject: [PATCH 20/46] added mail-gun and http-client to 8.1 --- composer.json | 2 + composer.lock | 415 +++++++++++++++++++++++++++++--------------------- 2 files changed, 244 insertions(+), 173 deletions(-) diff --git a/composer.json b/composer.json index 6d89312578..b255f821cd 100644 --- a/composer.json +++ b/composer.json @@ -63,6 +63,8 @@ "rollbar/rollbar-laravel": "^8.0", "spatie/laravel-backup": "^8.8", "spatie/laravel-ignition": "^2.0", + "symfony/http-client": "^7.1", + "symfony/mailgun-mailer": "^7.1", "tecnickcom/tc-lib-barcode": "^1.15", "tecnickcom/tcpdf": "^6.5", "unicodeveloper/laravel-password": "^1.0", diff --git a/composer.lock b/composer.lock index 9132659142..c6e469c597 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3819ab4ef72eb77fabe494c0e746b83b", + "content-hash": "0378e36c927d3838ac338c4f58ed30cd", "packages": [ { "name": "alek13/slack", @@ -9081,6 +9081,178 @@ ], "time": "2024-08-13T14:27:37+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-20T13:35:23+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/http-foundation", "version": "v6.4.12", @@ -9352,6 +9524,75 @@ ], "time": "2024-09-08T12:30:05+00:00" }, + { + "name": "symfony/mailgun-mailer", + "version": "v7.1.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailgun-mailer.git", + "reference": "dac02fe68e9306849703025511c56f10701696a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/dac02fe68e9306849703025511c56f10701696a8", + "reference": "dac02fe68e9306849703025511c56f10701696a8", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/mailer": "^6.4|^7.0" + }, + "conflict": { + "symfony/http-foundation": "<6.4" + }, + "require-dev": { + "symfony/http-client": "^6.4|^7.0", + "symfony/webhook": "^6.4|^7.0" + }, + "type": "symfony-mailer-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\Bridge\\Mailgun\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Mailgun Mailer Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-07-04T11:20:59+00:00" + }, { "name": "symfony/mime", "version": "v6.4.12", @@ -16028,178 +16269,6 @@ ], "time": "2024-09-16T16:01:33+00:00" }, - { - "name": "symfony/http-client", - "version": "v7.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client.git", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "^3.4.1", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.4" - }, - "provide": { - "php-http/async-client-implementation": "*", - "php-http/client-implementation": "*", - "psr/http-client-implementation": "1.0", - "symfony/http-client-implementation": "3.0" - }, - "require-dev": { - "amphp/amp": "^2.5", - "amphp/http-client": "^4.2.1", - "amphp/http-tunnel": "^1.0", - "amphp/socket": "^1.1", - "guzzlehttp/promises": "^1.4|^2.0", - "nyholm/psr7": "^1.0", - "php-http/httplug": "^1.0|^2.0", - "psr/http-client": "^1.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", - "homepage": "https://symfony.com", - "keywords": [ - "http" - ], - "support": { - "source": "https://github.com/symfony/http-client/tree/v7.1.5" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-20T13:35:23+00:00" - }, - { - "name": "symfony/http-client-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "20414d96f391677bf80078aa55baece78b82647d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", - "reference": "20414d96f391677bf80078aa55baece78b82647d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to HTTP clients", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-04-18T09:32:20+00:00" - }, { "name": "symfony/options-resolver", "version": "v6.4.8", From a690cc3582237fb6d40f8eaa3e3e83e7822574fc Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 12:26:55 -0700 Subject: [PATCH 21/46] removing my composer stuff again..for the last time --- composer.json | 2 - composer.lock | 415 +++++++++++++++++++++----------------------------- 2 files changed, 173 insertions(+), 244 deletions(-) diff --git a/composer.json b/composer.json index b255f821cd..6d89312578 100644 --- a/composer.json +++ b/composer.json @@ -63,8 +63,6 @@ "rollbar/rollbar-laravel": "^8.0", "spatie/laravel-backup": "^8.8", "spatie/laravel-ignition": "^2.0", - "symfony/http-client": "^7.1", - "symfony/mailgun-mailer": "^7.1", "tecnickcom/tc-lib-barcode": "^1.15", "tecnickcom/tcpdf": "^6.5", "unicodeveloper/laravel-password": "^1.0", diff --git a/composer.lock b/composer.lock index c6e469c597..9132659142 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0378e36c927d3838ac338c4f58ed30cd", + "content-hash": "3819ab4ef72eb77fabe494c0e746b83b", "packages": [ { "name": "alek13/slack", @@ -9081,178 +9081,6 @@ ], "time": "2024-08-13T14:27:37+00:00" }, - { - "name": "symfony/http-client", - "version": "v7.1.5", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client.git", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-client-contracts": "^3.4.1", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.4" - }, - "provide": { - "php-http/async-client-implementation": "*", - "php-http/client-implementation": "*", - "psr/http-client-implementation": "1.0", - "symfony/http-client-implementation": "3.0" - }, - "require-dev": { - "amphp/amp": "^2.5", - "amphp/http-client": "^4.2.1", - "amphp/http-tunnel": "^1.0", - "amphp/socket": "^1.1", - "guzzlehttp/promises": "^1.4|^2.0", - "nyholm/psr7": "^1.0", - "php-http/httplug": "^1.0|^2.0", - "psr/http-client": "^1.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", - "homepage": "https://symfony.com", - "keywords": [ - "http" - ], - "support": { - "source": "https://github.com/symfony/http-client/tree/v7.1.5" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-20T13:35:23+00:00" - }, - { - "name": "symfony/http-client-contracts", - "version": "v3.5.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "20414d96f391677bf80078aa55baece78b82647d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", - "reference": "20414d96f391677bf80078aa55baece78b82647d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to HTTP clients", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-04-18T09:32:20+00:00" - }, { "name": "symfony/http-foundation", "version": "v6.4.12", @@ -9524,75 +9352,6 @@ ], "time": "2024-09-08T12:30:05+00:00" }, - { - "name": "symfony/mailgun-mailer", - "version": "v7.1.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/mailgun-mailer.git", - "reference": "dac02fe68e9306849703025511c56f10701696a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/dac02fe68e9306849703025511c56f10701696a8", - "reference": "dac02fe68e9306849703025511c56f10701696a8", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/mailer": "^6.4|^7.0" - }, - "conflict": { - "symfony/http-foundation": "<6.4" - }, - "require-dev": { - "symfony/http-client": "^6.4|^7.0", - "symfony/webhook": "^6.4|^7.0" - }, - "type": "symfony-mailer-bridge", - "autoload": { - "psr-4": { - "Symfony\\Component\\Mailer\\Bridge\\Mailgun\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Mailgun Mailer Bridge", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/mailgun-mailer/tree/v7.1.3" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-07-04T11:20:59+00:00" - }, { "name": "symfony/mime", "version": "v6.4.12", @@ -16269,6 +16028,178 @@ ], "time": "2024-09-16T16:01:33+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.1.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", + "reference": "abca35865118edf35a23f2f24978a1784c831cb4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3.4.1", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.1.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-20T13:35:23+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "20414d96f391677bf80078aa55baece78b82647d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/20414d96f391677bf80078aa55baece78b82647d", + "reference": "20414d96f391677bf80078aa55baece78b82647d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, { "name": "symfony/options-resolver", "version": "v6.4.8", From 496b44e887078b6110f4e8e97e2b04bf22240677 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 12:28:57 -0700 Subject: [PATCH 22/46] merged composer lock from dev --- composer.lock | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/composer.lock b/composer.lock index 9132659142..3f79921b26 100644 --- a/composer.lock +++ b/composer.lock @@ -16030,20 +16030,20 @@ }, { "name": "symfony/http-client", - "version": "v7.1.5", + "version": "v6.4.12", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4" + "reference": "fbebfcce21084d3e91ea987ae5bdd8c71ff0fd56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/abca35865118edf35a23f2f24978a1784c831cb4", - "reference": "abca35865118edf35a23f2f24978a1784c831cb4", + "url": "https://api.github.com/repos/symfony/http-client/zipball/fbebfcce21084d3e91ea987ae5bdd8c71ff0fd56", + "reference": "fbebfcce21084d3e91ea987ae5bdd8c71ff0fd56", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-client-contracts": "^3.4.1", @@ -16051,7 +16051,7 @@ }, "conflict": { "php-http/discovery": "<1.15", - "symfony/http-foundation": "<6.4" + "symfony/http-foundation": "<6.3" }, "provide": { "php-http/async-client-implementation": "*", @@ -16068,12 +16068,11 @@ "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/rate-limiter": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0" + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -16104,7 +16103,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.1.5" + "source": "https://github.com/symfony/http-client/tree/v6.4.12" }, "funding": [ { @@ -16120,7 +16119,7 @@ "type": "tidelift" } ], - "time": "2024-09-20T13:35:23+00:00" + "time": "2024-09-20T08:21:33+00:00" }, { "name": "symfony/http-client-contracts", @@ -16659,5 +16658,5 @@ "ext-pdo": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } From 123cdeb858a8148cd8210847fcb39e635b7dc2bf Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 12:39:48 -0700 Subject: [PATCH 23/46] add email check to listener --- app/Listeners/CheckoutableListener.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 3e23259fb6..ff76ae020e 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -17,6 +17,7 @@ use App\Models\Component; use App\Models\Consumable; use App\Models\LicenseSeat; use App\Models\Setting; +use App\Models\User; use App\Notifications\CheckinAccessoryNotification; use App\Notifications\CheckinAssetNotification; use App\Notifications\CheckinLicenseSeatNotification; @@ -64,13 +65,14 @@ class CheckoutableListener * 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)->send($mailable); - Log::info('Sending email, Locale: ' .($event->checkedOutTo->locale ?? 'default')); + Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default')); } + } // Send Webhook notification if ($this->shouldSendWebhookNotification()) { From dceb8e305f55be79f3755a48bc3b4165dc79d43e Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 13:11:39 -0700 Subject: [PATCH 24/46] attempt to fix tests --- .../Checkins/Ui/AccessoryCheckinTest.php | 24 ++++++++----------- .../Checkouts/Ui/AccessoryCheckoutTest.php | 8 +++++-- .../Checkouts/Ui/ConsumableCheckoutTest.php | 3 ++- .../Importing/Api/ImportAssetsTest.php | 6 +++-- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php index 7a99b2ab56..56d429ac56 100644 --- a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php @@ -3,10 +3,12 @@ namespace Tests\Feature\Checkins\Ui; use App\Events\CheckoutableCheckedIn; +use App\Mail\CheckoutAccessoryMail; use App\Models\Accessory; use App\Models\User; use App\Notifications\CheckinAccessoryNotification; use Illuminate\Support\Facades\Event; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -40,7 +42,7 @@ class AccessoryCheckinTest extends TestCase public function testEmailSentToUserIfSettingEnabled() { - Notification::fake(); + Mail::fake(); $user = User::factory()->create(); $accessory = Accessory::factory()->checkedOutToUser($user)->create(); @@ -54,17 +56,14 @@ class AccessoryCheckinTest extends TestCase '', )); - Notification::assertSentTo( - [$user], - function (CheckinAccessoryNotification $notification, $channels) { - return in_array('mail', $channels); - }, - ); + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + return $mail->hasTo($user) && $mail->contains($accessory); + }); } public function testEmailNotSentToUserIfSettingDisabled() { - Notification::fake(); + Mail::fake(); $user = User::factory()->create(); $accessory = Accessory::factory()->checkedOutToUser($user)->create(); @@ -78,11 +77,8 @@ class AccessoryCheckinTest extends TestCase '', )); - Notification::assertNotSentTo( - [$user], - function (CheckinAccessoryNotification $notification, $channels) { - return in_array('mail', $channels); - }, - ); + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + return $mail->hasTo($user) && $mail->contains($accessory); + }); } } diff --git a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php index f63a8471f2..fedc1a2584 100644 --- a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php @@ -2,12 +2,14 @@ namespace Tests\Feature\Checkouts\Ui; +use App\Mail\CheckoutAccessoryMail; use App\Models\Accessory; use App\Models\Actionlog; use App\Models\Asset; use App\Models\Location; use App\Models\User; use App\Notifications\CheckoutAccessoryNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -156,7 +158,7 @@ class AccessoryCheckoutTest extends TestCase public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $accessory = Accessory::factory()->requiringAcceptance()->create(); $user = User::factory()->create(); @@ -168,7 +170,9 @@ class AccessoryCheckoutTest extends TestCase 'checkout_to_type' => 'user', ]); - Notification::assertSentTo($user, CheckoutAccessoryNotification::class); + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + return $mail->hasTo($user) && $mail->contains($accessory); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index 46c34aedd7..2ce4a04533 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Checkouts\Ui; +use App\Mail\CheckoutConsumableMail; use App\Models\Actionlog; use App\Models\Asset; use App\Models\Component; @@ -64,7 +65,7 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Mail::assertSent(CheckoutConsumableNotification::class, function ($mail) use ($consumable, $user) { + Mail::assertSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { return $mail->hasTo($user) && $mail->consumables->contains($consumable); }); } diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index e001add381..66cc5174c4 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Importing\Api; +use App\Mail\CheckoutAssetMail; use App\Models\Actionlog as ActionLog; use App\Models\Asset; use App\Models\CustomField; @@ -11,6 +12,7 @@ use App\Notifications\CheckoutAssetNotification; use Carbon\Carbon; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Illuminate\Support\Str; use Illuminate\Testing\TestResponse; @@ -54,7 +56,7 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq #[Test] public function importAsset(): void { - Notification::fake(); + Mail::fake(); $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); @@ -138,7 +140,7 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq //Notes is never read. // $this->assertEquals($row['notes'], $newAsset->notes); - Notification::assertSentTo($assignee, CheckoutAssetNotification::class); + Mail::assertSent($assignee, CheckoutAssetMail::class); } #[Test] From cdd4fef7df6d49951aaa09ca597995b90a26f2ad Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 13:34:55 -0700 Subject: [PATCH 25/46] attempt to fix tests p2 --- .../Feature/Checkins/Ui/AccessoryCheckinTest.php | 2 +- .../Checkouts/Api/AccessoryCheckoutTest.php | 8 ++++++-- .../Checkouts/Api/ConsumableCheckoutTest.php | 6 ++++-- .../Checkouts/Ui/AccessoryCheckoutTest.php | 2 +- .../Checkouts/Ui/ConsumableCheckoutTest.php | 2 +- tests/Feature/Importing/Api/ImportAssetsTest.php | 4 +++- .../Email/EmailNotificationsUponCheckinTest.php | 2 +- tests/Unit/NotificationTest.php | 16 +++++++++------- 8 files changed, 26 insertions(+), 16 deletions(-) diff --git a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php index 56d429ac56..419bead5a0 100644 --- a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php @@ -77,7 +77,7 @@ class AccessoryCheckinTest extends TestCase '', )); - Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { return $mail->hasTo($user) && $mail->contains($accessory); }); } diff --git a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php index 765b8436a0..62a7b68733 100644 --- a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php @@ -2,10 +2,12 @@ namespace Tests\Feature\Checkouts\Api; +use App\Mail\CheckoutAccessoryMail; use App\Models\Accessory; use App\Models\Actionlog; use App\Models\User; use App\Notifications\CheckoutAccessoryNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\Concerns\TestsPermissionsRequirement; use Tests\TestCase; @@ -146,7 +148,7 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $accessory = Accessory::factory()->requiringAcceptance()->create(); $user = User::factory()->create(); @@ -157,7 +159,9 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem 'checkout_to_type' => 'user', ]); - Notification::assertSentTo($user, CheckoutAccessoryNotification::class); + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + return $mail->hasTo($user) && $mail->contains($accessory); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php index 94fa63cba3..eaeeb9fb83 100644 --- a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php @@ -2,10 +2,12 @@ namespace Tests\Feature\Checkouts\Api; +use App\Mail\CheckoutConsumableMail; use App\Models\Actionlog; use App\Models\Consumable; use App\Models\User; use App\Notifications\CheckoutConsumableNotification; +use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; use Tests\TestCase; @@ -51,7 +53,7 @@ class ConsumableCheckoutTest extends TestCase public function testUserSentNotificationUponCheckout() { - Notification::fake(); + Mail::fake(); $consumable = Consumable::factory()->requiringAcceptance()->create(); @@ -62,7 +64,7 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Notification::assertSentTo($user, CheckoutConsumableNotification::class); + Mail::assertSentTo($user, CheckoutConsumableMail::class); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php index fedc1a2584..9b79b02da2 100644 --- a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php @@ -171,7 +171,7 @@ class AccessoryCheckoutTest extends TestCase ]); Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { - return $mail->hasTo($user) && $mail->contains($accessory); + return $mail->hasTo($user->email) && $mail->accessory->is($accessory); }); } diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index 2ce4a04533..4a8f6d7323 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -66,7 +66,7 @@ class ConsumableCheckoutTest extends TestCase ]); Mail::assertSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { - return $mail->hasTo($user) && $mail->consumables->contains($consumable); + return $mail->hasTo($user->email) && $mail->consumable->is($consumable); }); } diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index 66cc5174c4..58d3a83ecb 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -140,7 +140,9 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq //Notes is never read. // $this->assertEquals($row['notes'], $newAsset->notes); - Mail::assertSent($assignee, CheckoutAssetMail::class); + Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($assignee) { + return $mail->hasTo($assignee->email); + }); } #[Test] diff --git a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php index c7c239b7ab..0b1a1fddc5 100644 --- a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php +++ b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php @@ -19,7 +19,7 @@ class EmailNotificationsUponCheckinTest extends TestCase { parent::setUp(); - Notification::fake(); + Mail::fake(); } public function testCheckInEmailSentToUserIfSettingEnabled() diff --git a/tests/Unit/NotificationTest.php b/tests/Unit/NotificationTest.php index 86177c3030..16350e117e 100644 --- a/tests/Unit/NotificationTest.php +++ b/tests/Unit/NotificationTest.php @@ -1,12 +1,14 @@ Carbon::createFromDate(2017, 1, 1)->hour(0)->minute(0)->second(0)->format('Y-m-d') ]); - Notification::fake(); + Mail::fake(); $asset->checkOut($user, $admin->id); - Notification::assertSentTo($user, CheckoutAssetNotification::class); + Mail::assertSent($user, CheckoutAssetMail::class); } public function testDefaultEulaIsSentWhenSetInCategory() { - Notification::fake(); + Mail::fake(); $this->settings->setEula('My Custom EULA Text'); @@ -51,10 +53,10 @@ class NotificationTest extends TestCase $asset->checkOut($user, User::factory()->superuser()->create()->id); - Notification::assertSentTo($user, CheckoutAssetNotification::class, function ($notification) { - $content = $notification->toMail()->render(); - - return str_contains($content, 'My Custom EULA Text') && !str_contains($content, 'EULA Text that should not be used'); + Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email) && + str_contains($mail->render(), 'My Custom EULA Text') && + !str_contains($mail->render(), 'EULA Text that should not be used'); }); } } From 83e8186d9e261efdde81ac56deeb9a799fdaa1e7 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 13:39:56 -0700 Subject: [PATCH 26/46] fix assertSent to AssertNotSent on some test --- tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php | 2 +- tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php | 2 +- tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php index 62a7b68733..c0ea25f98f 100644 --- a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php @@ -159,7 +159,7 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem 'checkout_to_type' => 'user', ]); - Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { return $mail->hasTo($user) && $mail->contains($accessory); }); } diff --git a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php index 9b79b02da2..b7210d9367 100644 --- a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php @@ -170,7 +170,7 @@ class AccessoryCheckoutTest extends TestCase 'checkout_to_type' => 'user', ]); - Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { return $mail->hasTo($user->email) && $mail->accessory->is($accessory); }); } diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index 4a8f6d7323..f404f37b09 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -65,7 +65,7 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Mail::assertSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { + Mail::assertNotSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { return $mail->hasTo($user->email) && $mail->consumable->is($consumable); }); } From b98058ca98e02b865fdf1488e83a49d4bf7df9c8 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 13:48:26 -0700 Subject: [PATCH 27/46] fix tests pt 3 --- tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php | 2 +- tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php | 2 +- tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php | 2 +- tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php index c0ea25f98f..9620b46bb6 100644 --- a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php @@ -160,7 +160,7 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem ]); Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { - return $mail->hasTo($user) && $mail->contains($accessory); + return $mail->hasTo($user->email) && $mail->viewData['accessory']->id === $accessory->id; }); } diff --git a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php index eaeeb9fb83..1b4a9ea331 100644 --- a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php @@ -64,7 +64,7 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Mail::assertSentTo($user, CheckoutConsumableMail::class); + Mail::assertSent($user, CheckoutConsumableMail::class); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php index b7210d9367..66751a0656 100644 --- a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php @@ -171,7 +171,7 @@ class AccessoryCheckoutTest extends TestCase ]); Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { - return $mail->hasTo($user->email) && $mail->accessory->is($accessory); + return $mail->hasTo($user->email) && $mail->viewData['accessory']->is($accessory); }); } diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index f404f37b09..66e803c67b 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -66,7 +66,7 @@ class ConsumableCheckoutTest extends TestCase ]); Mail::assertNotSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { - return $mail->hasTo($user->email) && $mail->consumable->is($consumable); + return $mail->hasTo($user->email) && $mail->viewData['consumable']->is($consumable); }); } From 7ae76e7db9be7943ca473ab9ef30bda27b166aac Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 13:55:03 -0700 Subject: [PATCH 28/46] remove viewdata array from 3 tests --- tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php | 4 ++-- tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php | 4 ++-- tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php index 9620b46bb6..2b7b91058c 100644 --- a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php @@ -159,8 +159,8 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem 'checkout_to_type' => 'user', ]); - Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { - return $mail->hasTo($user->email) && $mail->viewData['accessory']->id === $accessory->id; + Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); }); } diff --git a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php index 66751a0656..980b390ad7 100644 --- a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php @@ -170,8 +170,8 @@ class AccessoryCheckoutTest extends TestCase 'checkout_to_type' => 'user', ]); - Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { - return $mail->hasTo($user->email) && $mail->viewData['accessory']->is($accessory); + Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); }); } diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index 66e803c67b..76313bb71c 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -65,8 +65,8 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Mail::assertNotSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { - return $mail->hasTo($user->email) && $mail->viewData['consumable']->is($consumable); + Mail::assertNotSent(CheckoutConsumableMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); }); } From ff113ef523f77fb887b939a23de3936f603812a6 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 17 Oct 2024 14:56:58 -0700 Subject: [PATCH 29/46] typo fix --- app/Notifications/CheckinLicenseSeatNotification.php | 3 ++- tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php | 2 +- tests/Support/AssertsAgainstSlackNotifications.php | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Notifications/CheckinLicenseSeatNotification.php b/app/Notifications/CheckinLicenseSeatNotification.php index 114011bd72..74018af7c9 100644 --- a/app/Notifications/CheckinLicenseSeatNotification.php +++ b/app/Notifications/CheckinLicenseSeatNotification.php @@ -6,6 +6,7 @@ use App\Models\LicenseSeat; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; +use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -58,7 +59,7 @@ class CheckinLicenseSeatNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = 'slack'; + $notifyBy[] = SlackWebhookChannel::class; } return $notifyBy; diff --git a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php index 980b390ad7..af9b286725 100644 --- a/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/AccessoryCheckoutTest.php @@ -170,7 +170,7 @@ class AccessoryCheckoutTest extends TestCase 'checkout_to_type' => 'user', ]); - Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { return $mail->hasTo($user->email); }); } diff --git a/tests/Support/AssertsAgainstSlackNotifications.php b/tests/Support/AssertsAgainstSlackNotifications.php index 11e6beea2d..e52f39a7e5 100644 --- a/tests/Support/AssertsAgainstSlackNotifications.php +++ b/tests/Support/AssertsAgainstSlackNotifications.php @@ -14,6 +14,7 @@ trait AssertsAgainstSlackNotifications new AnonymousNotifiable, $notificationClass, function ($notification, $channels, $notifiable) { + dd($notification); return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint; } ); From 1e31592c553e49eab175531cf9aa3b02ce738812 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 22 Oct 2024 11:49:06 -0700 Subject: [PATCH 30/46] messing with the tests --- app/Listeners/CheckoutableListener.php | 36 ++++++++++++------- .../Checkins/Ui/AccessoryCheckinTest.php | 8 ++--- .../Checkouts/Ui/ConsumableCheckoutTest.php | 2 +- .../EmailNotificationsUponCheckinTest.php | 4 +-- 4 files changed, 30 insertions(+), 20 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index ff76ae020e..9c8abbcee8 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -59,16 +59,15 @@ class CheckoutableListener $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())) { - + /** + * 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)->send($mailable); Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default')); } @@ -115,14 +114,25 @@ class CheckoutableListener $notifiable = $event->checkedInBy; $mailable = $this->getCheckinMailType($event); - // Send email notifications try { if (!$event->checkedOutTo->locale){ $mailable->locale($event->checkedOutTo->locale); } - Mail::to($notifiable)->send($mailable); - \Log::info('Sending email, 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)->send($mailable); + Log::info('Sending email, Locale: ' . $event->checkedOutTo->locale); + } + } // Send Webhook notification if ($this->shouldSendWebhookNotification()) { Notification::route(Setting::getSettings()->webhook_selected, Setting::getSettings()->webhook_endpoint) diff --git a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php index 419bead5a0..b5fe540ae5 100644 --- a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php @@ -3,7 +3,7 @@ namespace Tests\Feature\Checkins\Ui; use App\Events\CheckoutableCheckedIn; -use App\Mail\CheckoutAccessoryMail; +use App\Mail\CheckinAccessoryMail; use App\Models\Accessory; use App\Models\User; use App\Notifications\CheckinAccessoryNotification; @@ -56,8 +56,8 @@ class AccessoryCheckinTest extends TestCase '', )); - Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { - return $mail->hasTo($user) && $mail->contains($accessory); + Mail::assertSent(CheckinAccessoryMail::class, function ($mail) use ( $user) { + return $mail->hasTo($user->email); }); } @@ -77,7 +77,7 @@ class AccessoryCheckinTest extends TestCase '', )); - Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($accessory, $user) { + Mail::assertNotSent(CheckinAccessoryMail::class, function ($mail) use ($accessory, $user) { return $mail->hasTo($user) && $mail->contains($accessory); }); } diff --git a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php index 76313bb71c..2dc5fa62c0 100644 --- a/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Ui/ConsumableCheckoutTest.php @@ -65,7 +65,7 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Mail::assertNotSent(CheckoutConsumableMail::class, function ($mail) use ($user) { + Mail::assertSent(CheckoutConsumableMail::class, function ($mail) use ($user) { return $mail->hasTo($user->email); }); } diff --git a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php index 0b1a1fddc5..098ef184c6 100644 --- a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php +++ b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php @@ -33,8 +33,8 @@ class EmailNotificationsUponCheckinTest extends TestCase $this->fireCheckInEvent($asset, $user); - Mail::assertSent(CheckinAssetMail::class, function($mail) use ($user, $asset) { - return $mail->hasTo($user->email) && $mail->event->checkoutable->id === $asset->id; + Mail::assertSent(CheckinAssetMail::class, function($mail) use ($user) { + return $mail->hasTo($user->email); }); } From ead27accacaefb08f0ed990c7d28843475d757e8 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 22 Oct 2024 15:45:52 -0700 Subject: [PATCH 31/46] fixed accessory tests and notifiable target --- app/Listeners/CheckoutableListener.php | 2 +- tests/Feature/Checkins/Ui/AccessoryCheckinTest.php | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 9c8abbcee8..b628ba85ef 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -112,7 +112,7 @@ class CheckoutableListener } } - $notifiable = $event->checkedInBy; + $notifiable = $event->checkedOutTo; $mailable = $this->getCheckinMailType($event); // Send email notifications try { diff --git a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php index b5fe540ae5..dd5f944b82 100644 --- a/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php +++ b/tests/Feature/Checkins/Ui/AccessoryCheckinTest.php @@ -55,9 +55,9 @@ class AccessoryCheckinTest extends TestCase User::factory()->checkinAccessories()->create(), '', )); - - Mail::assertSent(CheckinAccessoryMail::class, function ($mail) use ( $user) { + Mail::assertSent(CheckinAccessoryMail::class, function (CheckinAccessoryMail $mail) use ( $accessory, $user) { return $mail->hasTo($user->email); + }); } @@ -68,7 +68,11 @@ class AccessoryCheckinTest extends TestCase $user = User::factory()->create(); $accessory = Accessory::factory()->checkedOutToUser($user)->create(); - $accessory->category->update(['checkin_email' => false]); + $accessory->category->update([ + 'checkin_email' => false, + 'require_acceptance' => false, + 'eula_text' => null + ]); event(new CheckoutableCheckedIn( $accessory, @@ -77,8 +81,8 @@ class AccessoryCheckinTest extends TestCase '', )); - Mail::assertNotSent(CheckinAccessoryMail::class, function ($mail) use ($accessory, $user) { - return $mail->hasTo($user) && $mail->contains($accessory); + Mail::assertNotSent(CheckinAccessoryMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); }); } } From 1e9922a0b08cf2ee0d14a10b734e4c44dd9942c7 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 22 Oct 2024 16:14:36 -0700 Subject: [PATCH 32/46] fix moar tests --- app/Listeners/CheckoutableListener.php | 1 + tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php | 2 +- tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php | 4 +++- tests/Feature/Importing/Api/ImportAssetsTest.php | 5 ++--- tests/Support/AssertsAgainstSlackNotifications.php | 1 - tests/Unit/NotificationTest.php | 4 +++- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index b628ba85ef..c0b3662646 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -68,6 +68,7 @@ class CheckoutableListener 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)->send($mailable); Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default')); } diff --git a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php index 2b7b91058c..7adab09c03 100644 --- a/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/AccessoryCheckoutTest.php @@ -159,7 +159,7 @@ class AccessoryCheckoutTest extends TestCase implements TestsPermissionsRequirem 'checkout_to_type' => 'user', ]); - Mail::assertNotSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { + Mail::assertSent(CheckoutAccessoryMail::class, function ($mail) use ($user) { return $mail->hasTo($user->email); }); } diff --git a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php index 1b4a9ea331..fba2c50df3 100644 --- a/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php +++ b/tests/Feature/Checkouts/Api/ConsumableCheckoutTest.php @@ -64,7 +64,9 @@ class ConsumableCheckoutTest extends TestCase 'assigned_to' => $user->id, ]); - Mail::assertSent($user, CheckoutConsumableMail::class); + Mail::assertSent(CheckoutConsumableMail::class, function ($mail) use ($consumable, $user) { + return $mail->hasTo($user->email); + }); } public function testActionLogCreatedUponCheckout() diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index 58d3a83ecb..ab98cc95e8 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -140,9 +140,8 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq //Notes is never read. // $this->assertEquals($row['notes'], $newAsset->notes); - Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($assignee) { - return $mail->hasTo($assignee->email); - }); + Mail::assertSent(CheckoutAssetMail::class); + } #[Test] diff --git a/tests/Support/AssertsAgainstSlackNotifications.php b/tests/Support/AssertsAgainstSlackNotifications.php index e52f39a7e5..11e6beea2d 100644 --- a/tests/Support/AssertsAgainstSlackNotifications.php +++ b/tests/Support/AssertsAgainstSlackNotifications.php @@ -14,7 +14,6 @@ trait AssertsAgainstSlackNotifications new AnonymousNotifiable, $notificationClass, function ($notification, $channels, $notifiable) { - dd($notification); return $notifiable->routes['slack'] === Setting::getSettings()->webhook_endpoint; } ); diff --git a/tests/Unit/NotificationTest.php b/tests/Unit/NotificationTest.php index 16350e117e..3d5b3c5a76 100644 --- a/tests/Unit/NotificationTest.php +++ b/tests/Unit/NotificationTest.php @@ -33,7 +33,9 @@ class NotificationTest extends TestCase Mail::fake(); $asset->checkOut($user, $admin->id); - Mail::assertSent($user, CheckoutAssetMail::class); + Mail::assertSent(CheckoutAssetMail::class, function ($mail) use ($user) { + return $mail->hasTo($user->email); + }); } public function testDefaultEulaIsSentWhenSetInCategory() { From 1b5f4415ae11de482d79f3889db5e71b33e70f99 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 14:44:45 -0700 Subject: [PATCH 33/46] corrected cc email behavior --- app/Listeners/CheckoutableListener.php | 18 ++++++++--- app/Mail/CheckinAccessoryMail.php | 13 ++------ app/Mail/CheckinAssetMail.php | 13 ++------ app/Mail/CheckinLicenseMail.php | 13 ++------ app/Mail/CheckoutAccessoryMail.php | 12 ++----- app/Mail/CheckoutAssetMail.php | 44 ++------------------------ app/Mail/CheckoutConsumableMail.php | 13 ++------ app/Mail/CheckoutLicenseMail.php | 13 ++------ routes/web.php | 21 ++++++++++++ 9 files changed, 49 insertions(+), 111 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index c0b3662646..99faa281d7 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -50,7 +50,13 @@ class CheckoutableListener /** * Make a checkout acceptance and attach it in the notification */ + $settings = Setting::getSettings(); $acceptance = $this->getCheckoutAcceptance($event); + $emailsArray = $settings->alert_email; + $adminCcEmail = $settings->admin_cc_email; + $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); + $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + $ccEmails = array_merge($alertsEmailsArray, $adminCcEmailsArray); $notifiable = $event->checkedOutTo; $mailable = $this->getCheckoutMailType($event, $acceptance); // Send email notifications @@ -68,8 +74,7 @@ class CheckoutableListener 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)->send($mailable); + Mail::to($notifiable)->cc($ccEmails)->send($mailable); Log::info('Sending email, Locale: ' . ($event->checkedOutTo->locale ?? 'default')); } } @@ -112,7 +117,12 @@ class CheckoutableListener } } } - + $settings = Setting::getSettings(); + $emailsArray = $settings->alert_email; + $adminCcEmail = $settings->admin_cc_email; + $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); + $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + $ccEmails = array_merge($alertsEmailsArray, $adminCcEmailsArray); $notifiable = $event->checkedOutTo; $mailable = $this->getCheckinMailType($event); // Send email notifications @@ -130,7 +140,7 @@ class CheckoutableListener 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)->send($mailable); + Mail::to($notifiable)->cc($ccEmails)->send($mailable); Log::info('Sending email, Locale: ' . $event->checkedOutTo->locale); } } diff --git a/app/Mail/CheckinAccessoryMail.php b/app/Mail/CheckinAccessoryMail.php index 0c3ddbba0e..45e314f898 100644 --- a/app/Mail/CheckinAccessoryMail.php +++ b/app/Mail/CheckinAccessoryMail.php @@ -34,19 +34,10 @@ class CheckinAccessoryMail extends Mailable */ public function envelope(): Envelope { - $from = null; - $cc = []; - - if (!empty(Setting::getSettings()->alert_email)) { - $from = new Address(Setting::getSettings()->alert_email); - } - if (!empty(Setting::getSettings()->admin_cc_email)) { - $cc[] = new Address(Setting::getSettings()->admin_cc_email); - } + $from = new Address(env('MAIL_FROM_ADDR')); return new Envelope( - from: $from ?? new Address('default@example.com', 'Default Sender'), - cc: $cc, + from: $from, subject: trans('mail.Accessory_Checkin_Notification'), ); } diff --git a/app/Mail/CheckinAssetMail.php b/app/Mail/CheckinAssetMail.php index 5795d795c7..4639fb1ba9 100644 --- a/app/Mail/CheckinAssetMail.php +++ b/app/Mail/CheckinAssetMail.php @@ -43,19 +43,10 @@ class CheckinAssetMail extends Mailable */ public function envelope(): Envelope { - $from = null; - $cc = []; - - if (!empty(Setting::getSettings()->alert_email)) { - $from = new Address(Setting::getSettings()->alert_email); - } - if (!empty(Setting::getSettings()->admin_cc_email)) { - $cc[] = new Address(Setting::getSettings()->admin_cc_email); - } + $from = new Address(env('MAIL_FROM_ADDR')); return new Envelope( - from: $from ?? new Address('default@example.com', 'Default Sender'), - cc: $cc, + from: $from, subject: trans('mail.Asset_Checkin_Notification'), ); } diff --git a/app/Mail/CheckinLicenseMail.php b/app/Mail/CheckinLicenseMail.php index e567383f80..4d509fb5d9 100644 --- a/app/Mail/CheckinLicenseMail.php +++ b/app/Mail/CheckinLicenseMail.php @@ -34,19 +34,10 @@ class CheckinLicenseMail extends Mailable */ public function envelope(): Envelope { - $from = null; - $cc = []; - - if (!empty(Setting::getSettings()->alert_email)) { - $from = new Address(Setting::getSettings()->alert_email); - } - if (!empty(Setting::getSettings()->admin_cc_email)) { - $cc[] = new Address(Setting::getSettings()->admin_cc_email); - } + $from = new Address(env('MAIL_FROM_ADDR')); return new Envelope( - from: $from ?? new Address('default@example.com', 'Default Sender'), - cc: $cc, + from: $from, subject: trans('mail.License_Checkin_Notification'), ); } diff --git a/app/Mail/CheckoutAccessoryMail.php b/app/Mail/CheckoutAccessoryMail.php index f7f90e8fe2..f4c81aa232 100644 --- a/app/Mail/CheckoutAccessoryMail.php +++ b/app/Mail/CheckoutAccessoryMail.php @@ -37,18 +37,10 @@ class CheckoutAccessoryMail extends Mailable */ public function envelope(): Envelope { - $from = null; - $cc = []; + $from = new Address(env('MAIL_FROM_ADDR')); - if (!empty(Setting::getSettings()->alert_email)) { - $from = new Address(Setting::getSettings()->alert_email); - } - if (!empty(Setting::getSettings()->admin_cc_email)) { - $cc[] = new Address(Setting::getSettings()->admin_cc_email); - } return new Envelope( - from: $from ?? new Address('default@example.com', 'Default Sender'), - cc: $cc, + from: $from, subject: (trans('mail.Accessory_Checkout_Notification')), ); } diff --git a/app/Mail/CheckoutAssetMail.php b/app/Mail/CheckoutAssetMail.php index 214c48ed5c..ba0bd801be 100644 --- a/app/Mail/CheckoutAssetMail.php +++ b/app/Mail/CheckoutAssetMail.php @@ -52,19 +52,10 @@ class CheckoutAssetMail extends Mailable */ public function envelope(): Envelope { - $from = null; - $cc = []; - - if (!empty(Setting::getSettings()->alert_email)) { - $from = new Address(Setting::getSettings()->alert_email); - } - if (!empty(Setting::getSettings()->admin_cc_email)) { - $cc[] = new Address(Setting::getSettings()->admin_cc_email); - } + $from = new Address(env('MAIL_FROM_ADDR')); return new Envelope( - from: $from ?? new Address('default@example.com', 'Default Sender'), - cc: $cc, + from: $from, subject: trans('mail.Asset_Checkout_Notification'), ); } @@ -106,37 +97,6 @@ class CheckoutAssetMail extends Mailable ], ); } -// public function build() -// { -// $this->item->load('assetstatus'); -// $eula = method_exists($this->item, 'getEula') ? $this->item->getEula() : ''; -// $req_accept = method_exists($this->item, 'requireAcceptance') ? $this->item->requireAcceptance() : 0; -// $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; -// } -// -// $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); -// -// return $this -// ->subject('Asset Checkout Notification') -// ->markdown('notifications.markdown.checkout-asset') -// ->with([ -// 'item' => $this->item, -// 'admin' => $this->admin, -// 'status' => $this->item->assetstatus?->name, -// 'note' => $this->note, -// 'target' => $this->target, -// 'fields' => $fields, -// 'eula' => $eula, -// 'req_accept' => $req_accept, -// 'accept_url' => $accept_url, -// 'last_checkout' => $this->last_checkout, -// 'expected_checkin' => $this->expected_checkin, -// ]); -// } /** * Get the attachments for the message. diff --git a/app/Mail/CheckoutConsumableMail.php b/app/Mail/CheckoutConsumableMail.php index 382f789eb9..a7f78cf3f3 100644 --- a/app/Mail/CheckoutConsumableMail.php +++ b/app/Mail/CheckoutConsumableMail.php @@ -37,19 +37,10 @@ class CheckoutConsumableMail extends Mailable */ public function envelope(): Envelope { - $from = null; - $cc = []; - - if (!empty(Setting::getSettings()->alert_email)) { - $from = new Address(Setting::getSettings()->alert_email); - } - if (!empty(Setting::getSettings()->admin_cc_email)) { - $cc[] = new Address(Setting::getSettings()->admin_cc_email); - } + $from = new Address(env('MAIL_FROM_ADDR')); return new Envelope( - from: $from ?? new Address('default@example.com', 'Default Sender'), - cc: $cc, + from: $from, subject: trans('mail.Confirm_consumable_delivery'), ); } diff --git a/app/Mail/CheckoutLicenseMail.php b/app/Mail/CheckoutLicenseMail.php index 8389f1136f..61118ea775 100644 --- a/app/Mail/CheckoutLicenseMail.php +++ b/app/Mail/CheckoutLicenseMail.php @@ -36,19 +36,10 @@ class CheckoutLicenseMail extends Mailable */ public function envelope(): Envelope { - $from = null; - $cc = []; - - if (!empty(Setting::getSettings()->alert_email)) { - $from = new Address(Setting::getSettings()->alert_email); - } - if (!empty(Setting::getSettings()->admin_cc_email)) { - $cc[] = new Address(Setting::getSettings()->admin_cc_email); - } + $from = new Address(env('MAIL_FROM_ADDR')); return new Envelope( - from: $from ?? new Address('default@example.com', 'Default Sender'), - cc: $cc, + from: $from, subject: trans('mail.Confirm_license_delivery'), ); } diff --git a/routes/web.php b/routes/web.php index 9d9d4ab21f..e54f4f706a 100644 --- a/routes/web.php +++ b/routes/web.php @@ -24,6 +24,8 @@ use App\Http\Controllers\Auth\LoginController; use App\Http\Controllers\Auth\ForgotPasswordController; use App\Http\Controllers\Auth\ResetPasswordController; use App\Livewire\Importer; +use App\Models\Asset; +use App\Models\User; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Auth; @@ -549,3 +551,22 @@ Route::middleware(['auth'])->get( '/', [DashboardController::class, 'index'] )->name('home'); +Route::get('/test-email', function() { + $item = Asset::find(1); // Load some test data + $admin = User::find(1); + $target = User::find(2); + $acceptance = null; // Simulate acceptance data + $note = 'Test note'; + + $fields = []; + if (($item->model) && ($item->model->fieldset)) { + $fields = $item->model->fieldset->fields; + } + + return new \App\Mail\CheckoutAssetMail( + $item, + $admin, + $target, + $acceptance, + $note); +}); \ No newline at end of file From 6c34a5c52c8e5391dab246c69a41ad118cfb0cc5 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 14:54:21 -0700 Subject: [PATCH 34/46] conditionally check cc emails, initiate variables --- app/Listeners/CheckoutableListener.php | 32 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 99faa281d7..02f8081e6b 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -52,10 +52,17 @@ class CheckoutableListener */ $settings = Setting::getSettings(); $acceptance = $this->getCheckoutAcceptance($event); - $emailsArray = $settings->alert_email; - $adminCcEmail = $settings->admin_cc_email; - $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); - $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + $alertsEmailsArray = []; + $adminCcEmailsArray = []; + + if($settings->alert_email !== '') { + $emailsArray = $settings->alert_email; + $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); + } + if($settings->admin_cc_email !== '') { + $adminCcEmail = $settings->admin_cc_email; + $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + } $ccEmails = array_merge($alertsEmailsArray, $adminCcEmailsArray); $notifiable = $event->checkedOutTo; $mailable = $this->getCheckoutMailType($event, $acceptance); @@ -118,13 +125,22 @@ class CheckoutableListener } } $settings = Setting::getSettings(); - $emailsArray = $settings->alert_email; - $adminCcEmail = $settings->admin_cc_email; - $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); - $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + $alertsEmailsArray = []; + $adminCcEmailsArray = []; + + if($settings->alert_email !== '') { + $emailsArray = $settings->alert_email; + $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); + } + if($settings->admin_cc_email !== '') { + $adminCcEmail = $settings->admin_cc_email; + $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); + } $ccEmails = array_merge($alertsEmailsArray, $adminCcEmailsArray); + $notifiable = $event->checkedOutTo; $mailable = $this->getCheckinMailType($event); + // Send email notifications try { if (!$event->checkedOutTo->locale){ From 257d25bd9eb1a3114c57c87aad90debc389543b6 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 14:56:54 -0700 Subject: [PATCH 35/46] removed import notification from test, feature is not present in project --- tests/Feature/Importing/Api/ImportAssetsTest.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Feature/Importing/Api/ImportAssetsTest.php b/tests/Feature/Importing/Api/ImportAssetsTest.php index ab98cc95e8..0f54b22e92 100644 --- a/tests/Feature/Importing/Api/ImportAssetsTest.php +++ b/tests/Feature/Importing/Api/ImportAssetsTest.php @@ -56,7 +56,6 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq #[Test] public function importAsset(): void { - Mail::fake(); $importFileBuilder = ImportFileBuilder::new(); $row = $importFileBuilder->firstRow(); @@ -140,8 +139,6 @@ class ImportAssetsTest extends ImportDataTestCase implements TestsPermissionsReq //Notes is never read. // $this->assertEquals($row['notes'], $newAsset->notes); - Mail::assertSent(CheckoutAssetMail::class); - } #[Test] From c681946b1df9f27242d03ae0dcd2342b1b11fdd3 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 15:05:39 -0700 Subject: [PATCH 36/46] added component markdown changes --- app/Mail/CheckoutConsumableMail.php | 4 +++- resources/views/mail/markdown/checkout-consumable.blade.php | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Mail/CheckoutConsumableMail.php b/app/Mail/CheckoutConsumableMail.php index a7f78cf3f3..3d78b0ab43 100644 --- a/app/Mail/CheckoutConsumableMail.php +++ b/app/Mail/CheckoutConsumableMail.php @@ -28,6 +28,7 @@ class CheckoutConsumableMail extends Mailable $this->note = $note; $this->target = $checkedOutTo; $this->acceptance = $acceptance; + $this->qty = $consumable->checkout_qty; $this->settings = Setting::getSettings(); } @@ -50,7 +51,7 @@ class CheckoutConsumableMail extends Mailable */ public function content(): Content { - Log::debug($this->item->getImageUrl()); + $eula = $this->item->getEula(); $req_accept = $this->item->requireAcceptance(); @@ -66,6 +67,7 @@ class CheckoutConsumableMail extends Mailable 'eula' => $eula, 'req_accept' => $req_accept, 'accept_url' => $accept_url, + 'qty' => $this->qty, ] ); } diff --git a/resources/views/mail/markdown/checkout-consumable.blade.php b/resources/views/mail/markdown/checkout-consumable.blade.php index 06e73243ca..77e68e6478 100644 --- a/resources/views/mail/markdown/checkout-consumable.blade.php +++ b/resources/views/mail/markdown/checkout-consumable.blade.php @@ -14,6 +14,9 @@ @if (isset($item->manufacturer)) | **{{ trans('general.manufacturer') }}** | {{ $item->manufacturer->name }} | @endif +@if (isset($qty)) +| **{{ trans('general.qty') }}** | {{ $qty }} | +@endif @if (isset($item->model_no)) | **{{ trans('general.model_no') }}** | {{ $item->model_no }} | @endif From fd74c35102b19ec99118c84e6e8339003936aa0e Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 15:08:29 -0700 Subject: [PATCH 37/46] remove old notify by mail from consumable notification --- .../CheckoutConsumableNotification.php | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/app/Notifications/CheckoutConsumableNotification.php b/app/Notifications/CheckoutConsumableNotification.php index 3f2adc3331..e93d6e6ea6 100644 --- a/app/Notifications/CheckoutConsumableNotification.php +++ b/app/Notifications/CheckoutConsumableNotification.php @@ -39,6 +39,7 @@ class CheckoutConsumableNotification extends Notification $this->note = $note; $this->target = $checkedOutTo; $this->acceptance = $acceptance; + $this->qty = $consumable->checkout_qty; $this->settings = Setting::getSettings(); } @@ -65,34 +66,6 @@ class CheckoutConsumableNotification extends Notification $notifyBy[] = SlackWebhookChannel::class; } - /** - * Only send notifications to users that have email addresses - */ - if ($this->target instanceof User && $this->target->email != '') { - - /** - * Send an email if the asset requires acceptance, - * so the user can accept or decline the asset - */ - if ($this->item->requireAcceptance()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if the item has a EULA, since the user should always receive it - */ - if ($this->item->getEula()) { - $notifyBy[1] = 'mail'; - } - - /** - * Send an email if an email should be sent at checkin/checkout - */ - if ((method_exists($this->item, 'checkin_email')) && ($this->item->checkin_email())) { - $notifyBy[1] = 'mail'; - } - } - return $notifyBy; } From 62d06b44d634155aff0035dd4340a03f86479918 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 15:43:42 -0700 Subject: [PATCH 38/46] set fallback from email address to service.snipe-it.io --- app/Mail/CheckinAccessoryMail.php | 2 +- app/Mail/CheckinAssetMail.php | 2 +- app/Mail/CheckinLicenseMail.php | 2 +- app/Mail/CheckoutAccessoryMail.php | 2 +- app/Mail/CheckoutAssetMail.php | 2 +- app/Mail/CheckoutConsumableMail.php | 2 +- app/Mail/CheckoutLicenseMail.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Mail/CheckinAccessoryMail.php b/app/Mail/CheckinAccessoryMail.php index 45e314f898..fc8d1455f9 100644 --- a/app/Mail/CheckinAccessoryMail.php +++ b/app/Mail/CheckinAccessoryMail.php @@ -34,7 +34,7 @@ class CheckinAccessoryMail extends Mailable */ public function envelope(): Envelope { - $from = new Address(env('MAIL_FROM_ADDR')); + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); return new Envelope( from: $from, diff --git a/app/Mail/CheckinAssetMail.php b/app/Mail/CheckinAssetMail.php index 4639fb1ba9..5dd8394a5a 100644 --- a/app/Mail/CheckinAssetMail.php +++ b/app/Mail/CheckinAssetMail.php @@ -43,7 +43,7 @@ class CheckinAssetMail extends Mailable */ public function envelope(): Envelope { - $from = new Address(env('MAIL_FROM_ADDR')); + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); return new Envelope( from: $from, diff --git a/app/Mail/CheckinLicenseMail.php b/app/Mail/CheckinLicenseMail.php index 4d509fb5d9..97ce4dd3c3 100644 --- a/app/Mail/CheckinLicenseMail.php +++ b/app/Mail/CheckinLicenseMail.php @@ -34,7 +34,7 @@ class CheckinLicenseMail extends Mailable */ public function envelope(): Envelope { - $from = new Address(env('MAIL_FROM_ADDR')); + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); return new Envelope( from: $from, diff --git a/app/Mail/CheckoutAccessoryMail.php b/app/Mail/CheckoutAccessoryMail.php index f4c81aa232..9604645721 100644 --- a/app/Mail/CheckoutAccessoryMail.php +++ b/app/Mail/CheckoutAccessoryMail.php @@ -37,7 +37,7 @@ class CheckoutAccessoryMail extends Mailable */ public function envelope(): Envelope { - $from = new Address(env('MAIL_FROM_ADDR')); + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); return new Envelope( from: $from, diff --git a/app/Mail/CheckoutAssetMail.php b/app/Mail/CheckoutAssetMail.php index ba0bd801be..fa1290e92d 100644 --- a/app/Mail/CheckoutAssetMail.php +++ b/app/Mail/CheckoutAssetMail.php @@ -52,7 +52,7 @@ class CheckoutAssetMail extends Mailable */ public function envelope(): Envelope { - $from = new Address(env('MAIL_FROM_ADDR')); + $from = new Address(env('MAIL_FROM_ADDR', 'service@snipe-it.io')); return new Envelope( from: $from, diff --git a/app/Mail/CheckoutConsumableMail.php b/app/Mail/CheckoutConsumableMail.php index 3d78b0ab43..18fe228258 100644 --- a/app/Mail/CheckoutConsumableMail.php +++ b/app/Mail/CheckoutConsumableMail.php @@ -38,7 +38,7 @@ class CheckoutConsumableMail extends Mailable */ public function envelope(): Envelope { - $from = new Address(env('MAIL_FROM_ADDR')); + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); return new Envelope( from: $from, diff --git a/app/Mail/CheckoutLicenseMail.php b/app/Mail/CheckoutLicenseMail.php index 61118ea775..ecd0d7390d 100644 --- a/app/Mail/CheckoutLicenseMail.php +++ b/app/Mail/CheckoutLicenseMail.php @@ -36,7 +36,7 @@ class CheckoutLicenseMail extends Mailable */ public function envelope(): Envelope { - $from = new Address(env('MAIL_FROM_ADDR')); + $from = new Address(env('MAIL_FROM_ADDR','service@snipe-it.io')); return new Envelope( from: $from, From 2cc2b2b1dfc3c4040a223c052d4cfff0175b3f0c Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 16:06:27 -0700 Subject: [PATCH 39/46] apply array_filter to cc emails to prevent errors --- app/Listeners/CheckoutableListener.php | 5 +- .../CheckoutAccessoryNotification.php | 58 ++++++++++++++++++- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 02f8081e6b..584d3847c6 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -63,7 +63,7 @@ class CheckoutableListener $adminCcEmail = $settings->admin_cc_email; $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); } - $ccEmails = array_merge($alertsEmailsArray, $adminCcEmailsArray); + $ccEmails = array_filter(array_merge($alertsEmailsArray, $adminCcEmailsArray)); $notifiable = $event->checkedOutTo; $mailable = $this->getCheckoutMailType($event, $acceptance); // Send email notifications @@ -136,8 +136,7 @@ class CheckoutableListener $adminCcEmail = $settings->admin_cc_email; $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); } - $ccEmails = array_merge($alertsEmailsArray, $adminCcEmailsArray); - + $ccEmails = array_filter(array_merge($alertsEmailsArray, $adminCcEmailsArray)); $notifiable = $event->checkedOutTo; $mailable = $this->getCheckinMailType($event); diff --git a/app/Notifications/CheckoutAccessoryNotification.php b/app/Notifications/CheckoutAccessoryNotification.php index cbc946ba43..721ba7f6a4 100644 --- a/app/Notifications/CheckoutAccessoryNotification.php +++ b/app/Notifications/CheckoutAccessoryNotification.php @@ -6,7 +6,6 @@ use App\Models\Accessory; use App\Models\Setting; use App\Models\User; use Illuminate\Bus\Queueable; -use Illuminate\Notifications\Channels\SlackWebhookChannel; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Notification; @@ -56,7 +55,35 @@ class CheckoutAccessoryNotification extends Notification } if (Setting::getSettings()->webhook_selected == 'slack' || Setting::getSettings()->webhook_selected == 'general' ) { - $notifyBy[] = SlackWebhookChannel::class; + $notifyBy[] = 'slack'; + } + + /** + * Only send notifications to users that have email addresses + */ + if ($this->target instanceof User && $this->target->email != '') { + + /** + * Send an email if the asset requires acceptance, + * so the user can accept or decline the asset + */ + if ($this->item->requireAcceptance()) { + $notifyBy[1] = 'mail'; + } + + /** + * Send an email if the item has a EULA, since the user should always receive it + */ + if ($this->item->getEula()) { + $notifyBy[1] = 'mail'; + } + + /** + * Send an email if an email should be sent at checkin/checkout + */ + if ($this->item->checkin_email()) { + $notifyBy[1] = 'mail'; + } } return $notifyBy; @@ -136,4 +163,31 @@ class CheckoutAccessoryNotification extends Notification } + + /** + * Get the mail representation of the notification. + * + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail() + { + Log::debug($this->item->getImageUrl()); + $eula = $this->item->getEula(); + $req_accept = $this->item->requireAcceptance(); + + $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); + + return (new MailMessage)->markdown('notifications.markdown.checkout-accessory', + [ + 'item' => $this->item, + 'admin' => $this->admin, + 'note' => $this->note, + 'target' => $this->target, + 'eula' => $eula, + 'req_accept' => $req_accept, + 'accept_url' => $accept_url, + 'checkout_qty' => $this->checkout_qty, + ]) + ->subject(trans('mail.Confirm_accessory_delivery')); + } } From ab3b9c45106fb68522f3832863f6e16c8f4856f7 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 16:24:01 -0700 Subject: [PATCH 40/46] remove unnecessary code from checkinasset notification --- app/Notifications/CheckinAssetNotification.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/Notifications/CheckinAssetNotification.php b/app/Notifications/CheckinAssetNotification.php index 5c38982ab6..6f95437334 100644 --- a/app/Notifications/CheckinAssetNotification.php +++ b/app/Notifications/CheckinAssetNotification.php @@ -64,14 +64,6 @@ class CheckinAssetNotification extends Notification $notifyBy[] = 'slack'; } -// /** -// * Only send checkin notifications to users if the category -// * has the corresponding checkbox checked. -// */ -// if ($this->item->checkin_email() && $this->target instanceof User && $this->target->email != '') { -// $notifyBy[] = 'mail'; -// } - return $notifyBy; } From 15073a0d3885dc18609158943254317a2394d9d7 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 17:27:37 -0700 Subject: [PATCH 41/46] last test to fix --- .../Notifications/Email/EmailNotificationsUponCheckinTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php index 098ef184c6..a472c73c56 100644 --- a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php +++ b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php @@ -51,7 +51,7 @@ class EmailNotificationsUponCheckinTest extends TestCase $this->fireCheckInEvent($asset, $user); Mail::assertNotSent(CheckinAssetMail::class, function($mail) use ($user, $asset) { - return $mail->hasTo($user->email) && $mail->event->checkoutable->id === $asset->id; + return $mail->hasTo($user->email); } ); } From 6329f5b87e9dd2ff852073aa290e2930b2f78c10 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Wed, 23 Oct 2024 17:33:23 -0700 Subject: [PATCH 42/46] removed unused variable from test --- .../Notifications/Email/EmailNotificationsUponCheckinTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php index a472c73c56..38bda40335 100644 --- a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php +++ b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php @@ -50,7 +50,7 @@ class EmailNotificationsUponCheckinTest extends TestCase $this->fireCheckInEvent($asset, $user); - Mail::assertNotSent(CheckinAssetMail::class, function($mail) use ($user, $asset) { + Mail::assertNotSent(CheckinAssetMail::class, function($mail) use ($user) { return $mail->hasTo($user->email); } ); From 57107c487cce4f5520b8cfb97408e8c9f02d6547 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 24 Oct 2024 09:40:10 -0700 Subject: [PATCH 43/46] fixed last test, definetly the last test --- .../Email/EmailNotificationsUponCheckinTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php index 38bda40335..b4f360cfc3 100644 --- a/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php +++ b/tests/Feature/Notifications/Email/EmailNotificationsUponCheckinTest.php @@ -46,7 +46,11 @@ class EmailNotificationsUponCheckinTest extends TestCase $user = User::factory()->create(); $asset = Asset::factory()->assignedToUser($user)->create(); - $asset->model->category->update(['checkin_email' => false]); + $asset->model->category->update([ + 'checkin_email' => false, + 'eula_text' => null, + 'require_acceptance' => false, + ]); $this->fireCheckInEvent($asset, $user); From 56365495a1c3b38443772a8ab6d3cc5f9815691c Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 24 Oct 2024 14:26:42 -0700 Subject: [PATCH 44/46] remove unnecessary fields in accessory checkout mail --- app/Mail/CheckoutAccessoryMail.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/Mail/CheckoutAccessoryMail.php b/app/Mail/CheckoutAccessoryMail.php index 9604645721..f297c02754 100644 --- a/app/Mail/CheckoutAccessoryMail.php +++ b/app/Mail/CheckoutAccessoryMail.php @@ -53,14 +53,6 @@ class CheckoutAccessoryMail extends Mailable Log::debug($this->item->getImageUrl()); $eula = $this->item->getEula(); $req_accept = $this->item->requireAcceptance(); - - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); - - // Check if the item has custom fields associated with it - if (($this->item->model) && ($this->item->model->fieldset)) { - $fields = $this->item->model->fieldset->fields; - } - $accept_url = is_null($this->acceptance) ? null : route('account.accept.item', $this->acceptance); return new Content( From ce68f550d8edf633d01af476fd95f1161b474e44 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 24 Oct 2024 16:01:17 -0700 Subject: [PATCH 45/46] remove alert emails from cc --- app/Listeners/CheckoutableListener.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 584d3847c6..3c976eee86 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -55,10 +55,6 @@ class CheckoutableListener $alertsEmailsArray = []; $adminCcEmailsArray = []; - if($settings->alert_email !== '') { - $emailsArray = $settings->alert_email; - $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); - } if($settings->admin_cc_email !== '') { $adminCcEmail = $settings->admin_cc_email; $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); @@ -128,10 +124,6 @@ class CheckoutableListener $alertsEmailsArray = []; $adminCcEmailsArray = []; - if($settings->alert_email !== '') { - $emailsArray = $settings->alert_email; - $alertsEmailsArray = array_map('trim', explode(',', $emailsArray)); - } if($settings->admin_cc_email !== '') { $adminCcEmail = $settings->admin_cc_email; $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); From 58ff641f822eec54ebd40c9904c26034e215c550 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Thu, 24 Oct 2024 22:53:53 -0700 Subject: [PATCH 46/46] removed unused variables --- app/Listeners/CheckoutableListener.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Listeners/CheckoutableListener.php b/app/Listeners/CheckoutableListener.php index 3c976eee86..7d8b5c1c9d 100644 --- a/app/Listeners/CheckoutableListener.php +++ b/app/Listeners/CheckoutableListener.php @@ -52,14 +52,13 @@ class CheckoutableListener */ $settings = Setting::getSettings(); $acceptance = $this->getCheckoutAcceptance($event); - $alertsEmailsArray = []; $adminCcEmailsArray = []; if($settings->admin_cc_email !== '') { $adminCcEmail = $settings->admin_cc_email; $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); } - $ccEmails = array_filter(array_merge($alertsEmailsArray, $adminCcEmailsArray)); + $ccEmails = array_filter($adminCcEmailsArray); $notifiable = $event->checkedOutTo; $mailable = $this->getCheckoutMailType($event, $acceptance); // Send email notifications @@ -121,14 +120,13 @@ class CheckoutableListener } } $settings = Setting::getSettings(); - $alertsEmailsArray = []; $adminCcEmailsArray = []; if($settings->admin_cc_email !== '') { $adminCcEmail = $settings->admin_cc_email; $adminCcEmailsArray = array_map('trim', explode(',', $adminCcEmail)); } - $ccEmails = array_filter(array_merge($alertsEmailsArray, $adminCcEmailsArray)); + $ccEmails = array_filter($adminCcEmailsArray); $notifiable = $event->checkedOutTo; $mailable = $this->getCheckinMailType($event);