Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions app/Events/AssetsTransferredInBulk.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php


namespace App\Events;

use App\Models\Asset;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;

class AssetsTransferredInBulk
{
use Dispatchable, SerializesModels;

public function __construct(
public Collection $transferable,
public Model $transferredTo,
public Model $transferredFrom,
public User $admin,
public string $transferred_at,
public string $expected_checkin,
public string $note,

public array $originalValues,
)
{
}

}
54 changes: 43 additions & 11 deletions app/Http/Controllers/Assets/BulkAssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Controllers\Assets;

use App\Events\AssetsTransferredInBulk;
use App\Helpers\Helper;
use App\Http\Controllers\CheckInOutRequest;
use App\Http\Controllers\Controller;
Expand All @@ -12,6 +13,7 @@
use App\View\Label;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Context;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
Expand Down Expand Up @@ -620,17 +622,19 @@ public function destroy(Request $request) : RedirectResponse
public function showCheckout() : View
{
$this->authorize('checkout', Asset::class);

$alreadyAssigned = collect();

if (old('selected_assets') && is_array(old('selected_assets'))) {
$assets = Asset::findMany(old('selected_assets'));
if (!Setting::getSettings()->allow_bulk_asset_transfer) {

[$assignable, $alreadyAssigned] = $assets->partition(function (Asset $asset) {
return !$asset->assigned_to;
});
if (old('selected_assets') && is_array(old('selected_assets'))) {
$assets = Asset::findMany(old('selected_assets'));

session()->flashInput(['selected_assets' => $assignable->pluck('id')->values()->toArray()]);
[$assignable, $alreadyAssigned] = $assets->partition(function (Asset $asset) {
return !$asset->assigned_to;
});

session()->flashInput(['selected_assets' => $assignable->pluck('id')->values()->toArray()]);
}
}

$do_not_change = ['' => trans('general.do_not_change')];
Expand All @@ -649,6 +653,7 @@ public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse
{
$this->authorize('checkout', Asset::class);


try {
$admin = auth()->user();

Expand All @@ -663,8 +668,9 @@ public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse

$assets = Asset::findOrFail($asset_ids);

// Prevent checking out assets that are already checked out
if ($assets->pluck('assigned_to')->unique()->filter()->isNotEmpty()) {
[$alreadyAssigned, $unassigned] = $assets->collect()->partition(fn ($asset) => !is_null($asset->assigned_to));

if ($unassigned->pluck('assigned_to')->unique()->filter()->isNotEmpty()){
// re-add the asset ids so the assets select is re-populated
$request->session()->flashInput(['selected_assets' => $asset_ids]);

Expand Down Expand Up @@ -706,8 +712,8 @@ public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse
}

$errors = [];
DB::transaction(function () use ($target, $admin, $checkout_at, $expected_checkin, &$errors, $assets, $request) { //NOTE: $errors is passsed by reference!
foreach ($assets as $asset) {
DB::transaction(function () use ($target, $admin, $checkout_at, $expected_checkin, &$errors, $unassigned, $alreadyAssigned, $request) { //NOTE: $errors is passsed by reference!
foreach ($unassigned as $asset) {
$this->authorize('checkout', $asset);

// See if there is a status label passed
Expand All @@ -730,6 +736,32 @@ public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse
$errors = array_merge_recursive($errors, $asset->getErrors()->toArray());
}
}
if ($alreadyAssigned->isNotEmpty() && Setting::getSettings()->allow_bulk_asset_transfer) {
Context::add('action', 'bulk_transfer');
foreach ($alreadyAssigned as $asset) {
$this->authorize('checkout', $asset);
$transferredFrom = $asset->assignedTo;
// See if there is a status label passed
if ($request->filled('status_id')) {
$asset->status_id = $request->get('status_id');
}

$checkout_success = $asset->transfer($alreadyAssigned, $target, $transferredFrom, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $asset->name, null);

//TODO - I think this logic is duplicated in the checkOut method?
if ($target->location_id != '') {
$asset->location_id = $target->location_id;
// TODO - I don't know why this is being saved without events
$asset::withoutEvents(function () use ($asset) {
$asset->save();
});
}

if (!$checkout_success) {
$errors = array_merge_recursive($errors, $asset->getErrors()->toArray());
}
}
}
});

if (! $errors) {
Expand Down
1 change: 1 addition & 0 deletions app/Http/Controllers/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ public function postSettings(Request $request) : RedirectResponse
$setting->dash_chart_type = $request->input('dash_chart_type');
$setting->profile_edit = $request->input('profile_edit', 0);
$setting->require_checkinout_notes = $request->input('require_checkinout_notes', 0);
$setting->allow_bulk_asset_transfer = $request->input('allow_bulk_asset_transfer', 0);
$setting->manager_view_enabled = $request->input('manager_view_enabled', 0);


Expand Down
5 changes: 5 additions & 0 deletions app/Listeners/CheckoutableListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use App\Notifications\CheckoutLicenseSeatNotification;
use GuzzleHttp\Exception\ClientException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Context;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use Exception;
Expand Down Expand Up @@ -434,6 +435,10 @@ private function shouldSendCheckoutEmailToUser(Model $checkoutable): bool
* 3. The item should send an email at check-in/check-out
*/

if (Context::get('action') === 'transfer') {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be bulk_transfer right?

return true;
}

if ($checkoutable->requireAcceptance()) {
return true;
}
Expand Down
11 changes: 11 additions & 0 deletions app/Listeners/LogListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Events\AccessoryCheckedOut;
use App\Events\AssetCheckedIn;
use App\Events\AssetCheckedOut;
use App\Events\AssetsTransferredInBulk;
use App\Events\CheckoutableCheckedIn;
use App\Events\CheckoutableCheckedOut;
use App\Events\CheckoutAccepted;
Expand Down Expand Up @@ -75,6 +76,15 @@ public function onCheckoutAccepted(CheckoutAccepted $event)
$logaction->save();
}

/**
* @throws \Exception
*/
public function onAssetsTransferredInBulk(AssetsTransferredInBulk $event): void
{
Log::debug('event passed to the listener:');
$event->transferable->logCheckout($event->note, $event->transferredTo, $event->transferable->last_checkout, $event->originalValues, true);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hit an exception here: Property [last_checkout] does not exist on this collection instance.


}
public function onCheckoutDeclined(CheckoutDeclined $event)
{
$logaction = new Actionlog();
Expand Down Expand Up @@ -140,6 +150,7 @@ public function subscribe($events)
$list = [
'CheckoutableCheckedIn',
'CheckoutableCheckedOut',
'AssetsTransferredInBulk',
'CheckoutAccepted',
'CheckoutDeclined',
'UserMerged',
Expand Down
Loading
Loading