From bb03e00279bf339dad9c898d700ef7b4df1ab4ef Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Mon, 6 Jan 2025 11:26:45 -0800 Subject: [PATCH 1/5] fix deprecation on asset obs get unaccept report to populate --- app/Console/Commands/SendExpirationAlerts.php | 10 +++-- app/Http/Controllers/ReportsController.php | 45 ++++++++++++------- app/Observers/AssetObserver.php | 2 +- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/app/Console/Commands/SendExpirationAlerts.php b/app/Console/Commands/SendExpirationAlerts.php index 025ba2ce239e..2cb36bb82764 100644 --- a/app/Console/Commands/SendExpirationAlerts.php +++ b/app/Console/Commands/SendExpirationAlerts.php @@ -9,6 +9,7 @@ use App\Notifications\ExpiringAssetsNotification; use App\Notifications\ExpiringLicenseNotification; use Illuminate\Console\Command; +use Illuminate\Support\Facades\Notification; class SendExpirationAlerts extends Command { @@ -45,7 +46,7 @@ public function handle() $threshold = $settings->alert_interval; if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) { - + $this->info('alerts'); // Send a rollup to the admin, if settings dictate $recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) { return new AlertRecipient($item); @@ -54,15 +55,17 @@ public function handle() // Expiring Assets $assets = Asset::getExpiringWarrantee($threshold); if ($assets->count() > 0) { + $this->info('expiring warrantees'); $this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold])); - \Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold)); + Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold)); } // Expiring licenses $licenses = License::getExpiringLicenses($threshold); if ($licenses->count() > 0) { + $this->info('expiring licenses'); $this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $threshold])); - \Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold)); + Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold)); } } else { if ($settings->alert_email == '') { @@ -71,5 +74,6 @@ public function handle() $this->info('Alerts are disabled in the settings. No mail will be sent'); } } + $this->info('nothing here.'); } } diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 03f7ec1c3f65..5596a046d4b2 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1093,30 +1093,43 @@ public function getAssetAcceptanceReport($deleted = false) : View $this->authorize('reports.view'); $showDeleted = $deleted == 'deleted'; - /** - * Get all assets with pending checkout acceptances - */ - if($showDeleted) { - $acceptances = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')->withTrashed()->with(['assignedTo' , 'checkoutable.assignedTo', 'checkoutable.model'])->get(); + $assetsForReport = collect(); + + $query = CheckoutAcceptance::pending() + ->where('checkoutable_type', 'App\Models\Asset') + ->with(['checkoutable.assignedTo', 'checkoutable.model']); // Eager load common relationships + + if ($showDeleted) { + $query->withTrashed()->with(['assignedTo']); } else { - $acceptances = CheckoutAcceptance::pending()->where('checkoutable_type', 'App\Models\Asset')->with(['assignedTo' => function ($query) { + $query->with(['assignedTo' => function ($query) { $query->withTrashed(); - }, 'checkoutable.assignedTo', 'checkoutable.model'])->get(); + }]); } - $assetsForReport = $acceptances - ->filter(function ($acceptance) { +// Process records in chunks + $query->chunk(100, function ($chunk) use (&$assetsForReport) { + + $filtered = $chunk->filter(function ($acceptance) { $acceptance_checkoutable_flag = false; - if ($acceptance->checkoutable){ - $acceptance_checkoutable_flag = $acceptance->checkoutable->checkedOutToUser(); + + if($acceptance->checkoutable) { + $acceptance_checkoutable_flag = $acceptance->assignedTo; } - - return $acceptance->checkoutable_type == 'App\Models\Asset' && $acceptance_checkoutable_flag; - }) - ->map(function($acceptance) { - return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance]; + // Return true if criteria match + return $acceptance->checkoutable_type === 'App\Models\Asset' && $acceptance_checkoutable_flag; + })->map(function ($acceptance) { + + return [ + 'assetItem' => $acceptance->checkoutable, + 'acceptance' => $acceptance, + ]; }); + // Merge results into the main collection + $assetsForReport = $assetsForReport->merge($filtered); + }); + return view('reports/unaccepted_assets', compact('assetsForReport','showDeleted' )); } diff --git a/app/Observers/AssetObserver.php b/app/Observers/AssetObserver.php index 0d01428ea8e9..421a93b9d7d2 100644 --- a/app/Observers/AssetObserver.php +++ b/app/Observers/AssetObserver.php @@ -80,7 +80,7 @@ public function created(Asset $asset) { if ($settings = Setting::getSettings()) { $tag = $asset->asset_tag; - $prefix = $settings->auto_increment_prefix; + $prefix = (string)($settings->auto_increment_prefix ?? ''); $number = substr($tag, strlen($prefix)); // IF - auto_increment_assets is on, AND (there is no prefix OR the prefix matches the start of the tag) // AND the rest of the string after the prefix is all digits, THEN... From e12c7473f8d32e40c669dfce0596f4d91d6d4622 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 7 Jan 2025 09:08:36 -0800 Subject: [PATCH 2/5] tinkering with the polymorphic eager load --- app/Http/Controllers/ReportsController.php | 9 ++++---- app/Http/Traits/CheckoutableTrait.php | 24 ++++++++++++++++++++++ app/Models/Asset.php | 2 ++ app/Models/CheckoutAcceptance.php | 4 +++- 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 app/Http/Traits/CheckoutableTrait.php diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index fbe0aa0384d3..4b50b4e74713 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1117,7 +1117,8 @@ public function getAssetAcceptanceReport($deleted = false) : View if ($showDeleted) { $query->withTrashed()->with(['assignedTo']); - } else { + } + else { $query->with(['assignedTo' => function ($query) { $query->withTrashed(); }]); @@ -1129,10 +1130,10 @@ public function getAssetAcceptanceReport($deleted = false) : View $filtered = $chunk->filter(function ($acceptance) { $acceptance_checkoutable_flag = false; - if($acceptance->checkoutable) { - $acceptance_checkoutable_flag = $acceptance->assignedTo; + if ($acceptance->checkoutable){ + $acceptance_checkoutable_flag = $acceptance->checkoutable->assignedTo(); } - // Return true if criteria match + // Return true if user return $acceptance->checkoutable_type === 'App\Models\Asset' && $acceptance_checkoutable_flag; })->map(function ($acceptance) { diff --git a/app/Http/Traits/CheckoutableTrait.php b/app/Http/Traits/CheckoutableTrait.php new file mode 100644 index 000000000000..f97e18ea4ad2 --- /dev/null +++ b/app/Http/Traits/CheckoutableTrait.php @@ -0,0 +1,24 @@ +assignedType() === self::USER; + } + + public function checkedOutToLocation(): bool + { + return $this->assignedType() === self::LOCATION; + } + + public function checkedOutToAsset(): bool + { + return $this->assignedType() === self::ASSET; + } +} \ No newline at end of file diff --git a/app/Models/Asset.php b/app/Models/Asset.php index ce8b870eb2e0..839f0ac22c0f 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -5,6 +5,7 @@ use App\Events\CheckoutableCheckedOut; use App\Exceptions\CheckoutNotAllowed; use App\Helpers\Helper; +use App\Http\Traits\CheckoutableTrait; use App\Http\Traits\UniqueUndeletedTrait; use App\Models\Traits\Acceptable; use App\Models\Traits\Searchable; @@ -33,6 +34,7 @@ class Asset extends Depreciable protected $with = ['model', 'adminuser']; use CompanyableTrait; + use CheckoutableTrait; use HasFactory, Loggable, Requestable, Presentable, SoftDeletes, ValidatingTrait, UniqueUndeletedTrait; public const LOCATION = 'location'; diff --git a/app/Models/CheckoutAcceptance.php b/app/Models/CheckoutAcceptance.php index b1c6c7914104..69afc3c8535f 100644 --- a/app/Models/CheckoutAcceptance.php +++ b/app/Models/CheckoutAcceptance.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Http\Traits\CheckoutableTrait; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -11,6 +12,7 @@ class CheckoutAcceptance extends Model { use HasFactory, SoftDeletes, Notifiable; + use CheckoutableTrait; protected $casts = [ 'accepted_at' => 'datetime', @@ -35,7 +37,7 @@ public function routeNotificationForMail() /** * The resource that was is out * - * @return Illuminate\Database\Eloquent\Relations\MorphTo + * @return \Illuminate\Database\Eloquent\Relations\MorphTo */ public function checkoutable() { From 97b765b5cc45db28e24b1f8a2dc7a8d6aa985ba1 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 7 Jan 2025 15:06:09 -0800 Subject: [PATCH 3/5] improved reports query, could be further optimized --- app/Http/Controllers/ReportsController.php | 57 ++++++++++++---------- app/Http/Traits/CheckoutableTrait.php | 24 --------- app/Models/Asset.php | 2 - app/Models/CheckoutAcceptance.php | 2 - 4 files changed, 30 insertions(+), 55 deletions(-) delete mode 100644 app/Http/Traits/CheckoutableTrait.php diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 4b50b4e74713..99f7fdfccf2a 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -11,6 +11,7 @@ use App\Models\Category; use App\Models\AssetMaintenance; use App\Models\CheckoutAcceptance; +use App\Models\Company; use App\Models\CustomField; use App\Models\Depreciation; use App\Models\License; @@ -18,6 +19,7 @@ use App\Models\Setting; use App\Notifications\CheckoutAssetNotification; use Carbon\Carbon; +use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Mail; @@ -1109,43 +1111,44 @@ public function getAssetAcceptanceReport($deleted = false) : View $this->authorize('reports.view'); $showDeleted = $deleted == 'deleted'; +// $acceptances = CheckoutAcceptance::pending() +// ->where('checkoutable_type', 'App\Models\Asset') +// ->withTrashed() +// ->with([ +// 'assignedTo', +// 'checkoutable.assignedTo', +// 'checkoutable.model' +// ])->get(); $assetsForReport = collect(); $query = CheckoutAcceptance::pending() ->where('checkoutable_type', 'App\Models\Asset') - ->with(['checkoutable.assignedTo', 'checkoutable.model']); // Eager load common relationships + ->with([ + 'checkoutable' => function (MorphTo $query) { + $query->morphWith([ + AssetModel::class => ['model'], + Company::class => ['company'], + Asset::class => ['assignedTo'], + ])->with('model.category'); + }, + 'assignedTo' => function($query){ + $query->withTrashed(); + } + ]); if ($showDeleted) { - $query->withTrashed()->with(['assignedTo']); - } - else { - $query->with(['assignedTo' => function ($query) { - $query->withTrashed(); - }]); + $query->withTrashed(); } -// Process records in chunks - $query->chunk(100, function ($chunk) use (&$assetsForReport) { - - $filtered = $chunk->filter(function ($acceptance) { - $acceptance_checkoutable_flag = false; - - if ($acceptance->checkoutable){ - $acceptance_checkoutable_flag = $acceptance->checkoutable->assignedTo(); - } - // Return true if user - return $acceptance->checkoutable_type === 'App\Models\Asset' && $acceptance_checkoutable_flag; - })->map(function ($acceptance) { - - return [ - 'assetItem' => $acceptance->checkoutable, - 'acceptance' => $acceptance, - ]; + $assetsForReport = $query->get() + ->map(function ($acceptance) { + return [ + 'assetItem' => $acceptance->checkoutable, + 'acceptance' => $acceptance, + ]; }); - // Merge results into the main collection - $assetsForReport = $assetsForReport->merge($filtered); - }); + return view('reports/unaccepted_assets', compact('assetsForReport','showDeleted' )); } diff --git a/app/Http/Traits/CheckoutableTrait.php b/app/Http/Traits/CheckoutableTrait.php deleted file mode 100644 index f97e18ea4ad2..000000000000 --- a/app/Http/Traits/CheckoutableTrait.php +++ /dev/null @@ -1,24 +0,0 @@ -assignedType() === self::USER; - } - - public function checkedOutToLocation(): bool - { - return $this->assignedType() === self::LOCATION; - } - - public function checkedOutToAsset(): bool - { - return $this->assignedType() === self::ASSET; - } -} \ No newline at end of file diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 839f0ac22c0f..ce8b870eb2e0 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -5,7 +5,6 @@ use App\Events\CheckoutableCheckedOut; use App\Exceptions\CheckoutNotAllowed; use App\Helpers\Helper; -use App\Http\Traits\CheckoutableTrait; use App\Http\Traits\UniqueUndeletedTrait; use App\Models\Traits\Acceptable; use App\Models\Traits\Searchable; @@ -34,7 +33,6 @@ class Asset extends Depreciable protected $with = ['model', 'adminuser']; use CompanyableTrait; - use CheckoutableTrait; use HasFactory, Loggable, Requestable, Presentable, SoftDeletes, ValidatingTrait, UniqueUndeletedTrait; public const LOCATION = 'location'; diff --git a/app/Models/CheckoutAcceptance.php b/app/Models/CheckoutAcceptance.php index 69afc3c8535f..e44a330ebc91 100644 --- a/app/Models/CheckoutAcceptance.php +++ b/app/Models/CheckoutAcceptance.php @@ -2,7 +2,6 @@ namespace App\Models; -use App\Http\Traits\CheckoutableTrait; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -12,7 +11,6 @@ class CheckoutAcceptance extends Model { use HasFactory, SoftDeletes, Notifiable; - use CheckoutableTrait; protected $casts = [ 'accepted_at' => 'datetime', From c699baf519c5b6b6efbc0f7d1695598245dacdc0 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 7 Jan 2025 15:10:00 -0800 Subject: [PATCH 4/5] removed commented out code, and unrelated crap --- app/Console/Commands/SendExpirationAlerts.php | 10 +++------- app/Http/Controllers/ReportsController.php | 10 ---------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/app/Console/Commands/SendExpirationAlerts.php b/app/Console/Commands/SendExpirationAlerts.php index 2cb36bb82764..025ba2ce239e 100644 --- a/app/Console/Commands/SendExpirationAlerts.php +++ b/app/Console/Commands/SendExpirationAlerts.php @@ -9,7 +9,6 @@ use App\Notifications\ExpiringAssetsNotification; use App\Notifications\ExpiringLicenseNotification; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Notification; class SendExpirationAlerts extends Command { @@ -46,7 +45,7 @@ public function handle() $threshold = $settings->alert_interval; if (($settings->alert_email != '') && ($settings->alerts_enabled == 1)) { - $this->info('alerts'); + // Send a rollup to the admin, if settings dictate $recipients = collect(explode(',', $settings->alert_email))->map(function ($item, $key) { return new AlertRecipient($item); @@ -55,17 +54,15 @@ public function handle() // Expiring Assets $assets = Asset::getExpiringWarrantee($threshold); if ($assets->count() > 0) { - $this->info('expiring warrantees'); $this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $threshold])); - Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold)); + \Notification::send($recipients, new ExpiringAssetsNotification($assets, $threshold)); } // Expiring licenses $licenses = License::getExpiringLicenses($threshold); if ($licenses->count() > 0) { - $this->info('expiring licenses'); $this->info(trans_choice('mail.license_expiring_alert', $licenses->count(), ['count' => $licenses->count(), 'threshold' => $threshold])); - Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold)); + \Notification::send($recipients, new ExpiringLicenseNotification($licenses, $threshold)); } } else { if ($settings->alert_email == '') { @@ -74,6 +71,5 @@ public function handle() $this->info('Alerts are disabled in the settings. No mail will be sent'); } } - $this->info('nothing here.'); } } diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 99f7fdfccf2a..566e813544a9 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1111,16 +1111,6 @@ public function getAssetAcceptanceReport($deleted = false) : View $this->authorize('reports.view'); $showDeleted = $deleted == 'deleted'; -// $acceptances = CheckoutAcceptance::pending() -// ->where('checkoutable_type', 'App\Models\Asset') -// ->withTrashed() -// ->with([ -// 'assignedTo', -// 'checkoutable.assignedTo', -// 'checkoutable.model' -// ])->get(); - $assetsForReport = collect(); - $query = CheckoutAcceptance::pending() ->where('checkoutable_type', 'App\Models\Asset') ->with([ From 92762896efaa587f3a96de3474f2fc11764f3886 Mon Sep 17 00:00:00 2001 From: Godfrey M Date: Tue, 7 Jan 2025 15:10:46 -0800 Subject: [PATCH 5/5] moar removal --- app/Http/Controllers/ReportsController.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 566e813544a9..8b0652818fdf 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1137,8 +1137,6 @@ public function getAssetAcceptanceReport($deleted = false) : View 'acceptance' => $acceptance, ]; }); - // Merge results into the main collection - return view('reports/unaccepted_assets', compact('assetsForReport','showDeleted' )); }