where('checkoutable_type', 'App\Models\Asset') ->whereHas('checkoutable', function($query) { $query->where('accepted_at', null) ->where('declined_at', null); }) ->with(['assignedTo', 'checkoutable.assignedTo', 'checkoutable.model', 'checkoutable.adminuser']) ->get(); $count = 0; $unacceptedAssetGroups = $pending ->filter(function($acceptance) { return $acceptance->checkoutable_type == 'App\Models\Asset'; }) ->map(function($acceptance) { return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance]; }) ->groupBy(function($item) { return $item['acceptance']->assignedTo ? $item['acceptance']->assignedTo->id : ''; }); foreach($unacceptedAssetGroups as $unacceptedAssetGroup) { // The [0] is weird, but it allows for the item_count to work and grabs the appropriate info for each user. // Collapsing and flattening the collection doesn't work above. $acceptance = $unacceptedAssetGroup[0]['acceptance']; $locale = $acceptance->assignedTo?->locale; $email = $acceptance->assignedTo?->email; if(!$email){ $this->info($acceptance->assignedTo->present()->fullName().' has no email address.'); } $item_count = $unacceptedAssetGroup->count(); if ($locale && $email) { Mail::to($email)->send((new UnacceptedAssetReminderMail($acceptance, $item_count))->locale($locale)); } elseif ($email) { Mail::to($email)->send((new UnacceptedAssetReminderMail($acceptance, $item_count))); } $count++; } $this->info($count.' users notified.'); return 0; } }