Skip to content

Commit 62a58fa

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents c67ca50 + 7d07420 commit 62a58fa

File tree

7 files changed

+65
-11
lines changed

7 files changed

+65
-11
lines changed

app/Http/Controllers/Assets/BulkAssetsController.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,21 @@ public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse
656656
->with('error', trans('general.error_assets_already_checked_out'));
657657
}
658658

659+
// Prevent checking out assets across companies if FMCS enabled
660+
if (Setting::getSettings()->full_multiple_companies_support && $target->company_id) {
661+
$company_ids = $assets->pluck('company_id')->unique();
662+
663+
// if there is more than one unique company id or the singular company id does not match
664+
// then the checkout is invalid
665+
if ($company_ids->count() > 1 || $company_ids->first() != $target->company_id) {
666+
// re-add the asset ids so the assets select is re-populated
667+
$request->session()->flashInput(['selected_assets' => $asset_ids]);
668+
669+
return redirect(route('hardware.bulkcheckout.show'))
670+
->with('error', trans('general.error_user_company_multiple'));
671+
}
672+
}
673+
659674
if (request('checkout_to_type') == 'asset') {
660675
foreach ($asset_ids as $asset_id) {
661676
if ($target->id == $asset_id) {

resources/lang/en-US/general.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@
519519
'item_notes' => ':item Notes',
520520
'item_name_var' => ':item Name',
521521
'error_user_company' => 'Checkout target company and asset company do not match',
522+
'error_user_company_multiple' => 'One or more of the checkout target company and asset company do not match',
522523
'error_user_company_accept_view' => 'An Asset assigned to you belongs to a different company so you can\'t accept nor deny it, please check with your manager',
523524
'error_assets_already_checked_out' => 'One or more of the assets are already checked out',
524525
'importer' => [

resources/views/hardware/checkout.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
</div>
9595

9696
@include ('partials.forms.checkout-selector', ['user_select' => 'true','asset_select' => 'true', 'location_select' => 'true'])
97-
@include ('partials.forms.edit.user-select', ['translated_name' => trans('general.user'), 'fieldname' => 'assigned_user', 'style' => session('checkout_to_type') == 'user' ? '' : 'display: none;'])
97+
@include ('partials.forms.edit.user-select', ['translated_name' => trans('general.user'), 'fieldname' => 'assigned_user', 'style' => (session('checkout_to_type') ?: 'user') == 'user' ? '' : 'display: none;'])
9898
<!-- We have to pass unselect here so that we don't default to the asset that's being checked out. We want that asset to be pre-selected everywhere else. -->
9999
@include ('partials.forms.edit.asset-select', ['translated_name' => trans('general.select_asset'), 'fieldname' => 'assigned_asset', 'company_id' => $asset->company_id, 'unselect' => 'true', 'style' => session('checkout_to_type') == 'asset' ? '' : 'display: none;'])
100100
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'assigned_location', 'style' => session('checkout_to_type') == 'location' ? '' : 'display: none;'])

resources/views/partials/forms/checkout-selector.blade.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,25 @@
44

55
<div class="btn-group" data-toggle="buttons">
66
@if ((isset($user_select)) && ($user_select!='false'))
7-
<label class="btn btn-default{{ session('checkout_to_type') == 'user' ? ' active' : '' }}">
8-
<input name="checkout_to_type" value="user" aria-label="checkout_to_type" type="radio" checked="checked">
7+
<label class="btn btn-default{{ (session('checkout_to_type') ?: 'user') == 'user' ? ' active' : '' }}">
8+
<input name="checkout_to_type" value="user" aria-label="checkout_to_type"
9+
type="radio" {{ (session('checkout_to_type') ?: 'user') == 'user' ? 'checked' : '' }}>
910
<x-icon type="user" />
1011
{{ trans('general.user') }}
1112
</label>
1213
@endif
1314
@if ((isset($asset_select)) && ($asset_select!='false'))
14-
<label class="btn btn-default{{ session('checkout_to_type') == 'asset' ? ' active' : '' }}">
15-
<input name="checkout_to_type" value="asset" aria-label="checkout_to_type" type="radio">
15+
<label class="btn btn-default{{ session('checkout_to_type') == 'asset' ? ' active' : '' }}">
16+
<input name="checkout_to_type" value="asset" aria-label="checkout_to_type"
17+
type="radio" {{ session('checkout_to_type') == 'asset' ? 'checked': '' }}>
1618
<i class="fas fa-barcode" aria-hidden="true"></i>
1719
{{ trans('general.asset') }}
1820
</label>
1921
@endif
2022
@if ((isset($location_select)) && ($location_select!='false'))
21-
<label class="btn btn-default{{ session('checkout_to_type') == 'location' ? ' active' : '' }}">
22-
<input name="checkout_to_type" value="location" aria-label="checkout_to_type" class="active" type="radio">
23+
<label class="btn btn-default{{ session('checkout_to_type') == 'location' ? ' active' : '' }}">
24+
<input name="checkout_to_type" value="location" aria-label="checkout_to_type"
25+
type="radio" {{ session('checkout_to_type') == 'location' ? 'checked' : '' }}>
2326
<i class="fas fa-map-marker-alt" aria-hidden="true"></i>
2427
{{ trans('general.location') }}
2528
</label>

resources/views/settings/backups.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class="btn btn-warning btn-sm restore-backup {{ (config('app.lock_passwords')) ?
150150
<div class="box-body">
151151

152152
<p>
153-
{!! trans('admin/settings/general.backups_path', ['path'=> 'storage/app/backup']) !!}
153+
{!! trans('admin/settings/general.backups_path', ['path'=> 'storage/app/backups']) !!}
154154
</p>
155155

156156
@if (config('app.lock_passwords')===true)

routes/api.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,7 @@
583583
// the model name to be the parameter - and i think it's a good differentiation in the code while we convert the others.
584584
Route::patch('/hardware/{asset}', [Api\AssetsController::class, 'update'])->name('api.assets.update');
585585
Route::put('/hardware/{asset}', [Api\AssetsController::class, 'update'])->name('api.assets.put-update');
586-
587-
Route::put('/hardware/{asset}', [Api\AssetsController::class, 'update'])->name('api.assets.put-update');
588-
586+
589587
Route::resource('hardware',
590588
Api\AssetsController::class,
591589
['names' => [

tests/Feature/Checkouts/Ui/BulkAssetCheckoutTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use App\Mail\CheckoutAssetMail;
66
use App\Models\Asset;
7+
use App\Models\Company;
78
use App\Models\Location;
89
use App\Models\User;
910
use Illuminate\Support\Facades\Mail;
@@ -122,6 +123,42 @@ function () {
122123
];
123124
}
124125

126+
#[DataProvider('checkoutTargets')]
127+
public function test_adheres_to_full_multiple_company_support($data)
128+
{
129+
['type' => $type, 'target' => $target] = $data();
130+
131+
$this->settings->enableMultipleFullCompanySupport();
132+
133+
// create two companies
134+
[$companyA, $companyB] = Company::factory()->count(2)->create();
135+
136+
// create an asset for each company
137+
$assetForCompanyA = Asset::factory()->for($companyA)->create();
138+
$assetForCompanyB = Asset::factory()->for($companyB)->create();
139+
140+
$this->assertNull($assetForCompanyA->assigned_to, 'Asset should not be assigned before attempting this test case.');
141+
$this->assertNull($assetForCompanyB->assigned_to, 'Asset should not be assigned before attempting this test case.');
142+
143+
// attempt to bulk checkout both items to the target
144+
$response = $this->actingAs(User::factory()->superuser()->create())
145+
->post(route('hardware.bulkcheckout.store'), [
146+
'selected_assets' => [
147+
$assetForCompanyA->id,
148+
$assetForCompanyB->id,
149+
],
150+
'checkout_to_type' => $type,
151+
"assigned_$type" => $target->id,
152+
]);
153+
154+
// ensure bulk checkout is blocked
155+
$this->assertNull($assetForCompanyA->fresh()->assigned_to, 'Asset was checked out across companies.');
156+
$this->assertNull($assetForCompanyB->fresh()->assigned_to, 'Asset was checked out across companies.');
157+
158+
// ensure redirected back
159+
$response->assertRedirectToRoute('hardware.bulkcheckout.show');
160+
}
161+
125162
#[DataProvider('checkoutTargets')]
126163
public function test_prevents_checkouts_of_checked_out_items($data)
127164
{

0 commit comments

Comments
 (0)