Skip to content
Closed
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
5 changes: 4 additions & 1 deletion app/Events/CheckoutableCheckedIn.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,21 @@ class CheckoutableCheckedIn

public $originalValues;

public ?string $filename;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct($checkoutable, $checkedOutTo, User $checkedInBy, $note, $action_date = null, $originalValues = [])
public function __construct($checkoutable, $checkedOutTo, User $checkedInBy, $note, $action_date = null, $originalValues = [], ?string $filename = null)
{
$this->checkoutable = $checkoutable;
$this->checkedOutTo = $checkedOutTo;
$this->checkedInBy = $checkedInBy;
$this->note = $note;
$this->action_date = $action_date ?? date('Y-m-d H:i:s');
$this->originalValues = $originalValues;
$this->filename = $filename;
}
}
5 changes: 4 additions & 1 deletion app/Events/CheckoutableCheckedOut.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ class CheckoutableCheckedOut

public bool $signInPlace;

public ?string $filename;

/**
* Create a new event instance.
*
* @return void
*/
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [], $quantity = 1, bool $signInPlace = false)
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [], $quantity = 1, bool $signInPlace = false, ?string $filename = null)
{
$this->checkoutable = $checkoutable;
$this->checkedOutTo = $checkedOutTo;
Expand All @@ -38,5 +40,6 @@ public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $n
$this->originalValues = $originalValues;
$this->quantity = $quantity;
$this->signInPlace = $signInPlace;
$this->filename = $filename;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
use App\Events\CheckoutableCheckedIn;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Requests\UploadFileRequest;
use App\Models\Accessory;
use App\Models\AccessoryCheckout;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class AccessoryCheckinController extends Controller
Expand Down Expand Up @@ -53,7 +53,7 @@ public function create($accessoryUserId = null, $backto = null): View|RedirectRe
* @param null $accessoryCheckoutId
* @param string $backto
*/
public function store(Request $request, $accessoryCheckoutId = null, $backto = null): RedirectResponse
public function store(UploadFileRequest $request, $accessoryCheckoutId = null, $backto = null): RedirectResponse
{
if (is_null($accessory_checkout = AccessoryCheckout::find($accessoryCheckoutId))) {
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
Expand All @@ -75,9 +75,14 @@ public function store(Request $request, $accessoryCheckoutId = null, $backto = n
$checkin_at = $request->input('checkin_at').' '.$checkin_hours;
}

$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/accessories/', 'checkin-'.$accessory->id, $request->file('file'));
}

// Was the accessory updated?
if ($accessory_checkout->delete()) {
event(new CheckoutableCheckedIn($accessory, $accessory_checkout->assignedTo, auth()->user(), $request->input('note'), $checkin_at));
event(new CheckoutableCheckedIn($accessory, $accessory_checkout->assignedTo, auth()->user(), $request->input('note'), $checkin_at, [], $file_name));

session()->put(['redirect_option' => $request->input('redirect_option')]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ public function store(AccessoryCheckoutRequest $request, Accessory $accessory):
$accessory_checkout->save();
}

$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/accessories/', 'checkout-'.$accessory->id, $request->file('file'));
}

event(new CheckoutableCheckedOut(
$accessory,
$target,
Expand All @@ -104,6 +109,7 @@ public function store(AccessoryCheckoutRequest $request, Accessory $accessory):
[],
$accessory->checkout_qty,
$request->boolean('sign_in_place'),
$file_name,
));

$request->request->add(['checkout_to_type' => request('checkout_to_type')]);
Expand Down
24 changes: 21 additions & 3 deletions app/Http/Controllers/Api/AccessoriesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Http\Requests\AccessoryCheckoutRequest;
use App\Http\Requests\ImageUploadRequest;
use App\Http\Requests\StoreAccessoryRequest;
use App\Http\Requests\UploadFileRequest;
use App\Http\Traits\CheckInOutTrait;
use App\Http\Transformers\AccessoriesTransformer;
use App\Http\Transformers\ActionlogsTransformer;
Expand All @@ -22,6 +23,7 @@
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;

class AccessoriesController extends Controller
{
Expand Down Expand Up @@ -314,8 +316,13 @@ public function checkout(AccessoryCheckoutRequest $request, Accessory $accessory
$accessory->checkout_qty = $request->input('checkout_qty', 1);
$payload = null;

$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/accessories/', 'checkout-'.$accessory->id, $request->file('file'));
}

// Keep checkout rows and checkout log/event atomic to avoid ghost assignments.
DB::transaction(function () use ($accessory, $request, $target, &$payload): void {
DB::transaction(function () use ($accessory, $request, $target, $file_name, &$payload): void {
for ($i = 0; $i < $accessory->checkout_qty; $i++) {

$accessory_checkout = new AccessoryCheckout([
Expand Down Expand Up @@ -347,6 +354,8 @@ public function checkout(AccessoryCheckoutRequest $request, Accessory $accessory
$request->input('note'),
[],
$accessory->checkout_qty,
false,
$file_name,
));
});

Expand All @@ -367,7 +376,7 @@ public function checkout(AccessoryCheckoutRequest $request, Accessory $accessory
*
* @internal param int $accessoryId
*/
public function checkin(Request $request, $accessoryUserId = null)
public function checkin(UploadFileRequest $request, $accessoryUserId = null)
{
if (is_null($accessory_checkout = AccessoryCheckout::find($accessoryUserId))) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/message.does_not_exist', ['id' => $accessoryUserId])));
Expand All @@ -376,7 +385,16 @@ public function checkin(Request $request, $accessoryUserId = null)
$accessory = Accessory::find($accessory_checkout->accessory_id);
$this->authorize('checkin', $accessory);

$accessory->logCheckin(User::find($accessory_checkout->assigned_to), $request->input('note'));
$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/accessories/', 'checkin-'.$accessory->id, $request->file('file'));
}

$accessory->logCheckin(User::find($accessory_checkout->assigned_to), $request->input('note'), null, []);

if ($file_name && Gate::allows('files', $accessory)) {
$accessory->logUpload($file_name, null);
}

// Was the accessory updated?
if ($accessory_checkout->delete()) {
Expand Down
21 changes: 16 additions & 5 deletions app/Http/Controllers/Api/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use App\Http\Requests\ImageUploadRequest;
use App\Http\Requests\StoreAssetRequest;
use App\Http\Requests\UpdateAssetRequest;
use App\Http\Requests\UploadFileRequest;
use App\Http\Traits\MigratesLegacyAssetLocations;
use App\Http\Transformers\ActionlogsTransformer;
use App\Http\Transformers\AssetsTransformer;
Expand Down Expand Up @@ -1085,9 +1086,14 @@
// $asset->location_id = $target->rtd_location_id;
// }

$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/assets/', 'checkout-'.$asset->id, $request->file('file'));
}

// Keep checkout mutation + checkout logging/event side effects atomic.
$wasCheckedOut = DB::transaction(function () use ($asset, $target, $checkout_at, $expected_checkin, $note, $asset_name): bool {
return $asset->checkOut($target, auth()->user(), $checkout_at, $expected_checkin, $note, $asset_name, $asset->location_id);
$wasCheckedOut = DB::transaction(function () use ($asset, $target, $checkout_at, $expected_checkin, $note, $asset_name, $file_name): bool {
return $asset->checkOut($target, auth()->user(), $checkout_at, $expected_checkin, $note, $asset_name, $asset->location_id, false, $file_name);
});

if ($wasCheckedOut) {
Expand All @@ -1106,7 +1112,7 @@
*
* @since [v4.0]
*/
public function checkin(Request $request, $asset_id): JsonResponse
public function checkin(UploadFileRequest $request, $asset_id): JsonResponse

Check warning on line 1115 in app/Http/Controllers/Api/AssetsController.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

app/Http/Controllers/Api/AssetsController.php#L1115

The method checkin() has an NPath complexity of 864. The configured NPath complexity threshold is 200.
{
$asset = Asset::with('model')->findOrFail($asset_id);
$this->authorize('checkin', $asset);
Expand Down Expand Up @@ -1173,14 +1179,19 @@
$acceptance->delete();
});

$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/assets/', 'checkin-'.$asset->id, $request->file('file'));
}

if ($asset->save()) {

// Update the location of any child assets
Asset::where('assigned_type', Asset::class)
->where('assigned_to', $asset->id)
->update(['location_id' => $asset->location_id]);

event(new CheckoutableCheckedIn($asset, $target, auth()->user(), $request->input('note'), $checkin_at, $originalValues));
event(new CheckoutableCheckedIn($asset, $target, auth()->user(), $request->input('note'), $checkin_at, $originalValues, $file_name));

return response()->json(Helper::formatStandardApiResponse('success', [
'asset_tag' => e($asset->asset_tag),
Expand All @@ -1199,7 +1210,7 @@
*
* @since [v6.0]
*/
public function checkinByTag(Request $request, $tag = null): JsonResponse
public function checkinByTag(UploadFileRequest $request, $tag = null): JsonResponse
{
$this->authorize('checkin', Asset::class);
if ($tag == null && null !== ($request->input('asset_tag'))) {
Expand Down
22 changes: 19 additions & 3 deletions app/Http/Controllers/Api/ComponentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Requests\ImageUploadRequest;
use App\Http\Requests\UploadFileRequest;
use App\Http\Transformers\ActionlogsTransformer;
use App\Http\Transformers\ComponentsTransformer;
use App\Models\Asset;
Expand All @@ -17,6 +18,7 @@
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;

Expand Down Expand Up @@ -290,7 +292,7 @@
*
* @param int $componentId
*/
public function checkout(Request $request, $componentId): JsonResponse
public function checkout(UploadFileRequest $request, $componentId): JsonResponse

Check warning on line 295 in app/Http/Controllers/Api/ComponentsController.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

app/Http/Controllers/Api/ComponentsController.php#L295

The method checkout() has an NPath complexity of 296. The configured NPath complexity threshold is 200.
{
// Check if the component exists
if (! $component = Component::find($componentId)) {
Expand Down Expand Up @@ -327,6 +329,11 @@
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.error_user_company')));
}

$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/components/', 'checkout-'.$component->id, $request->file('file'));
}

// Keep pivot + action log in one transaction so checkout is all-or-nothing.
DB::transaction(function () use ($component, $request, $asset): void {
$component->assigned_to = $request->input('assigned_to');
Expand All @@ -343,6 +350,10 @@
$component->logCheckout($request->input('note'), $asset, null, [], $request->get('assigned_qty', 1));
});

if ($file_name && Gate::allows('files', $component)) {
$component->logUpload($file_name, null);
}

return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/components/message.checkout.success')));
}

Expand All @@ -356,7 +367,7 @@
*
* @since [v5.1.8]
*/
public function checkin(Request $request, $component_asset_id): JsonResponse
public function checkin(UploadFileRequest $request, $component_asset_id): JsonResponse
{
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
if (is_null($component = Component::find($component_assets->component_id))) {
Expand Down Expand Up @@ -394,7 +405,12 @@

$asset = Asset::find($component_assets->asset_id);

event(new CheckoutableCheckedIn($component, $asset, auth()->user(), $request->input('note'), Carbon::now()));
$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/components/', 'checkin-'.$component->id, $request->file('file'));
}

event(new CheckoutableCheckedIn($component, $asset, auth()->user(), $request->input('note'), Carbon::now(), [], $file_name));

return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/components/message.checkin.success')));
}
Expand Down
12 changes: 10 additions & 2 deletions app/Http/Controllers/Api/ConsumablesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Http\Requests\FilterRequest;
use App\Http\Requests\ImageUploadRequest;
use App\Http\Requests\StoreConsumableRequest;
use App\Http\Requests\UploadFileRequest;
use App\Http\Transformers\ActionlogsTransformer;
use App\Http\Transformers\ConsumablesTransformer;
use App\Http\Transformers\SelectlistTransformer;
Expand Down Expand Up @@ -282,7 +283,7 @@
*
* @since [v4.9.5]
*/
public function checkout(Request $request, $id): JsonResponse
public function checkout(UploadFileRequest $request, $id): JsonResponse

Check warning on line 286 in app/Http/Controllers/Api/ConsumablesController.php

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

app/Http/Controllers/Api/ConsumablesController.php#L286

The method checkout() has an NPath complexity of 576. The configured NPath complexity threshold is 200.
{
// Check if the consumable exists
if (! $consumable = Consumable::with('users')->find($id)) {
Expand Down Expand Up @@ -322,8 +323,13 @@
// Update the consumable data
$consumable->assigned_to = $request->input('assigned_to');

$file_name = null;
if ($request->hasFile('file')) {
$file_name = $request->handleFile('private_uploads/consumables/', 'checkout-'.$consumable->id, $request->file('file'));
}

// Keep pivot writes and checkout log/event atomic to avoid partial checkout state.
DB::transaction(function () use ($consumable, $request, $user): void {
DB::transaction(function () use ($consumable, $request, $user, $file_name): void {
for ($i = 0; $i < $consumable->checkout_qty; $i++) {
$consumable->users()->attach($consumable->id,
[
Expand All @@ -342,6 +348,8 @@
$request->input('note'),
[],
$consumable->checkout_qty,
false,
$file_name,
));
});

Expand Down
Loading
Loading