mirror of
https://github.com/snipe/snipe-it.git
synced 2025-10-29 19:31:41 +00:00
Merge remote-tracking branch 'origin/develop'
# Conflicts: # public/css/build/app.css # public/css/build/app.css.map # public/css/build/overrides.css # public/css/build/overrides.css.map # public/css/dist/all.css # public/mix-manifest.json
This commit is contained in:
commit
0b60c6a939
@ -647,6 +647,15 @@ class BulkAssetsController extends Controller
|
||||
|
||||
$assets = Asset::findOrFail($asset_ids);
|
||||
|
||||
// Prevent checking out assets that are already checked out
|
||||
if ($assets->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]);
|
||||
|
||||
return redirect(route('hardware.bulkcheckout.show'))
|
||||
->with('error', trans('general.error_assets_already_checked_out'));
|
||||
}
|
||||
|
||||
if (request('checkout_to_type') == 'asset') {
|
||||
foreach ($asset_ids as $asset_id) {
|
||||
if ($target->id == $asset_id) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
public/css/dist/all.css
vendored
2
public/css/dist/all.css
vendored
File diff suppressed because one or more lines are too long
@ -2,8 +2,8 @@
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=5c191843e0bb9292ec6b7f0a3c5765b3",
|
||||
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=bf1a348eae3e60c62b8879953f7df14c",
|
||||
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=146086d653897e2557af5e68f6f8c56f",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=da2636d15880131386d4077637ec9be2",
|
||||
"/css/build/app.css": "/css/build/app.css?id=813a3e9610d1108dbe35f62435d436fd",
|
||||
"/css/build/overrides.css": "/css/build/overrides.css?id=3f6ab7e6902cca7d96e637b82dc95e65",
|
||||
"/css/build/app.css": "/css/build/app.css?id=5876cf8fb09a66f8f9e0b2472c9cc9f8",
|
||||
"/css/build/AdminLTE.css": "/css/build/AdminLTE.css?id=bdf169bc2141f453390614c138cdce95",
|
||||
"/css/dist/skins/skin-yellow.css": "/css/dist/skins/skin-yellow.css?id=e1e6e1c64cf14fc350585aaeb0e42f6b",
|
||||
"/css/dist/skins/skin-yellow-dark.css": "/css/dist/skins/skin-yellow-dark.css?id=08ae1b3e66008966ce5d600ea3ad04a2",
|
||||
@ -19,7 +19,7 @@
|
||||
"/css/dist/skins/skin-blue.css": "/css/dist/skins/skin-blue.css?id=68a92d85c8e351dfb38a835307f126ec",
|
||||
"/css/dist/skins/skin-blue-dark.css": "/css/dist/skins/skin-blue-dark.css?id=cbb20ad6182b658f34117bf96a621b63",
|
||||
"/css/dist/skins/skin-black.css": "/css/dist/skins/skin-black.css?id=84e2ee950ae04444988b37038e5a3951",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=a480f24f1a8b590f3686e529fd25309b",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=88a000a091cb26a138368945df92ab83",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced1cf5f13147f7",
|
||||
"/js/select2/i18n/af.js": "/js/select2/i18n/af.js?id=4f6fcd73488ce79fae1b7a90aceaecde",
|
||||
|
||||
@ -1260,4 +1260,8 @@ caption.tableCaption {
|
||||
clip: rect(0,0,0,0);
|
||||
white-space: preserve;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
input[name="columnsSearch"] {
|
||||
width: 120px;
|
||||
}
|
||||
@ -520,6 +520,7 @@ return [
|
||||
'item_name_var' => ':item Name',
|
||||
'error_user_company' => 'Checkout target company and asset company do not match',
|
||||
'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',
|
||||
'error_assets_already_checked_out' => 'One or more of the assets are already checked out',
|
||||
'importer' => [
|
||||
'checked_out_to_fullname' => 'Checked Out to: Full Name',
|
||||
'checked_out_to_first_name' => 'Checked Out to: First Name',
|
||||
|
||||
@ -61,6 +61,7 @@
|
||||
|
||||
@if ($category->category_type=='asset')
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="categoryAssetsTable"
|
||||
id="categoryAssetsTable"
|
||||
data-buttons="assetButtons"
|
||||
|
||||
@ -94,6 +94,7 @@
|
||||
data-cookie-id-table="assetsListingTable"
|
||||
data-id-table="assetsListingTable"
|
||||
data-side-pagination="server"
|
||||
data-show-columns-search="true"
|
||||
data-sort-order="asc"
|
||||
data-toolbar="#assetsBulkEditToolbar"
|
||||
data-bulk-button-id="#bulkAssetEditButton"
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="depreciationsAssetTable"
|
||||
data-id-table="depreciationsAssetTable"
|
||||
id="depreciationsAssetTable"
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
<table
|
||||
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="dueAssetcheckinListing"
|
||||
data-id-table="dueAssetcheckinListing"
|
||||
data-side-pagination="server"
|
||||
|
||||
@ -47,6 +47,8 @@
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="box">
|
||||
@ -66,6 +68,7 @@
|
||||
data-show-footer="true"
|
||||
data-sort-order="asc"
|
||||
data-sort-name="name"
|
||||
data-show-columns-search="true"
|
||||
data-toolbar="#assetsBulkEditToolbar"
|
||||
data-bulk-button-id="#bulkAssetEditButton"
|
||||
data-bulk-form-id="#assetsBulkForm"
|
||||
|
||||
@ -1285,6 +1285,7 @@
|
||||
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="assetsTable"
|
||||
data-id-table="assetsTable"
|
||||
data-side-pagination="server"
|
||||
|
||||
@ -210,6 +210,7 @@
|
||||
@include('partials.asset-bulk-actions')
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="assetsListingTable"
|
||||
data-id-table="assetsListingTable"
|
||||
data-side-pagination="server"
|
||||
@ -237,6 +238,7 @@
|
||||
<table
|
||||
role="table"
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="assetsAssignedListingTable"
|
||||
data-id-table="assetsAssignedListingTable"
|
||||
data-side-pagination="server"
|
||||
@ -262,6 +264,7 @@
|
||||
<table
|
||||
role="table"
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="RTDassetsListingTable"
|
||||
data-id-table="RTDassetsListingTable"
|
||||
data-side-pagination="server"
|
||||
|
||||
@ -104,6 +104,7 @@
|
||||
<div class="table table-responsive">
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="assetsListingTable"
|
||||
data-id-table="assetsListingTable"
|
||||
data-toolbar="#assetsBulkEditToolbar"
|
||||
|
||||
@ -87,6 +87,7 @@
|
||||
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="assetListingTable"
|
||||
data-id-table="assetListingTable"
|
||||
data-side-pagination="server"
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
data-bulk-button-id="#bulkAssetEditButton"
|
||||
data-bulk-form-id="#assetsBulkForm"
|
||||
id="assetsListingTable"
|
||||
data-show-columns-search="true"
|
||||
data-buttons="assetButtons"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{route('api.assets.index', ['status_id' => $statuslabel->id]) }}"
|
||||
|
||||
@ -114,6 +114,7 @@
|
||||
<table
|
||||
data-cookie-id-table="suppliersAssetsTable"
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-id-table="suppliersAssetsTable"
|
||||
data-show-footer="true"
|
||||
data-side-pagination="server"
|
||||
|
||||
@ -836,6 +836,7 @@
|
||||
|
||||
<table
|
||||
data-columns="{{ \App\Presenters\AssetPresenter::dataTableLayout() }}"
|
||||
data-show-columns-search="true"
|
||||
data-cookie-id-table="userAssetsListingTable"
|
||||
data-id-table="userAssetsListingTable"
|
||||
data-side-pagination="server"
|
||||
|
||||
@ -4,8 +4,10 @@ namespace Tests\Feature\Checkouts\Ui;
|
||||
|
||||
use App\Mail\CheckoutAssetMail;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Location;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\ExpectationFailedException;
|
||||
use Tests\TestCase;
|
||||
|
||||
@ -89,4 +91,63 @@ class BulkAssetCheckoutTest extends TestCase
|
||||
$this->fail('Asset checkout email was sent when the entire checkout failed.');
|
||||
}
|
||||
}
|
||||
|
||||
public static function checkoutTargets()
|
||||
{
|
||||
yield 'Checkout to user' => [
|
||||
function () {
|
||||
return [
|
||||
'type' => 'user',
|
||||
'target' => User::factory()->forCompany()->create(),
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
yield 'Checkout to asset' => [
|
||||
function () {
|
||||
return [
|
||||
'type' => 'asset',
|
||||
'target' => Asset::factory()->forCompany()->create(),
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
yield 'Checkout to location' => [
|
||||
function () {
|
||||
return [
|
||||
'type' => 'location',
|
||||
'target' => Location::factory()->forCompany()->create(),
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('checkoutTargets')]
|
||||
public function test_prevents_checkouts_of_checked_out_items($data)
|
||||
{
|
||||
['type' => $type, 'target' => $target] = $data();
|
||||
|
||||
$asset = Asset::factory()->create();
|
||||
$checkedOutAsset = Asset::factory()->assignedToUser()->create();
|
||||
$existingUserId = $checkedOutAsset->assigned_to;
|
||||
|
||||
$response = $this->actingAs(User::factory()->superuser()->create())
|
||||
->post(route('hardware.bulkcheckout.store'), [
|
||||
'selected_assets' => [
|
||||
$asset->id,
|
||||
$checkedOutAsset->id,
|
||||
],
|
||||
'checkout_to_type' => $type,
|
||||
"assigned_$type" => $target->id,
|
||||
]);
|
||||
|
||||
$this->assertEquals(
|
||||
$existingUserId,
|
||||
$checkedOutAsset->fresh()->assigned_to,
|
||||
'Asset was checked out when it should have been prevented.'
|
||||
);
|
||||
|
||||
// ensure redirected back
|
||||
$response->assertRedirectToRoute('hardware.bulkcheckout.show');
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user