mirror of
https://github.com/snipe/snipe-it.git
synced 2025-02-02 08:21:09 -08:00
Merge pull request #15160 from snipe/fixes/allow_cloning_of_deleted_assets
Allow cloning of deleted assets
This commit is contained in:
commit
8368fb5c41
|
@ -576,26 +576,20 @@ class AssetsController extends Controller
|
|||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getClone($assetId = null)
|
||||
public function getClone(Asset $asset)
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($asset_to_clone = Asset::find($assetId))) {
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('create', $asset_to_clone);
|
||||
|
||||
$asset = clone $asset_to_clone;
|
||||
$asset->id = null;
|
||||
$asset->asset_tag = '';
|
||||
$asset->serial = '';
|
||||
$asset->assigned_to = '';
|
||||
$this->authorize('create', $asset);
|
||||
$cloned = clone $asset;
|
||||
$cloned->id = null;
|
||||
$cloned->asset_tag = '';
|
||||
$cloned->serial = '';
|
||||
$cloned->assigned_to = '';
|
||||
$cloned->deleted_at = '';
|
||||
|
||||
return view('hardware/edit')
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('statuslabel_types', Helper::statusTypeList())
|
||||
->with('item', $asset);
|
||||
->with('item', $cloned);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div class="col-md-12">
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs hidden-print">
|
||||
|
@ -197,16 +197,25 @@
|
|||
@endif
|
||||
@endif
|
||||
|
||||
|
||||
@can('update', $asset)
|
||||
@if ($asset->deleted_at=='')
|
||||
@if ($asset->deleted_at=='')
|
||||
@can('update', $asset)
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<a href="{{ route('hardware.edit', $asset->id) }}" class="btn btn-sm btn-primary btn-block hidden-print">
|
||||
{{ trans('admin/hardware/general.edit') }}
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
@endcan
|
||||
@endcan
|
||||
|
||||
@can('audit', \App\Models\Asset::class)
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<span class="tooltip-wrapper"{!! (!$asset->model ? ' data-tooltip="true" title="'.trans('admin/hardware/general.model_invalid_fix').'"' : '') !!}>
|
||||
<a href="{{ route('asset.audit.create', $asset->id) }}" class="btn btn-sm btn-primary btn-block hidden-print{{ (!$asset->model ? ' disabled' : '') }}">
|
||||
{{ trans('general.audit') }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
@endcan
|
||||
@endif
|
||||
|
||||
@can('create', $asset)
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
|
@ -216,16 +225,6 @@
|
|||
</div>
|
||||
@endcan
|
||||
|
||||
@can('audit', \App\Models\Asset::class)
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<span class="tooltip-wrapper"{!! (!$asset->model ? ' data-tooltip="true" title="'.trans('admin/hardware/general.model_invalid_fix').'"' : '') !!}>
|
||||
<a href="{{ route('asset.audit.create', $asset->id) }}" class="btn btn-sm btn-primary btn-block hidden-print{{ (!$asset->model ? ' disabled' : '') }}">
|
||||
{{ trans('general.audit') }}
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
@endcan
|
||||
|
||||
@can('delete', $asset)
|
||||
<div class="col-md-12" style="padding-top: 30px; padding-bottom: 30px;">
|
||||
@if ($asset->deleted_at=='')
|
||||
|
|
|
@ -78,17 +78,14 @@ Route::group(
|
|||
[AssetsController::class, 'getAssetBySerial']
|
||||
)->where('any', '.*')->name('findbyserial/hardware');
|
||||
|
||||
Route::get('{assetId}/clone',
|
||||
Route::get('{asset}/clone',
|
||||
[AssetsController::class, 'getClone']
|
||||
)->name('clone/hardware');
|
||||
)->name('clone/hardware')->withTrashed();
|
||||
|
||||
Route::get('{assetId}/label',
|
||||
[AssetsController::class, 'getLabel']
|
||||
)->name('label/hardware');
|
||||
|
||||
Route::post('{assetId}/clone',
|
||||
[AssetsController::class, 'postCreate']
|
||||
);
|
||||
|
||||
|
||||
Route::get('{assetId}/checkout',
|
||||
[AssetCheckoutController::class, 'create']
|
||||
|
|
37
tests/Feature/Assets/Ui/CloneAssetTest.php
Normal file
37
tests/Feature/Assets/Ui/CloneAssetTest.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Feature\Assets\Ui;
|
||||
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class CloneAssetTest extends TestCase
|
||||
{
|
||||
public function testPermissionRequiredToCreateAssetModel()
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
$this->actingAs(User::factory()->create())
|
||||
->get(route('clone/hardware', $asset))
|
||||
->assertForbidden();
|
||||
}
|
||||
|
||||
public function testPageCanBeAccessed(): void
|
||||
{
|
||||
$asset = Asset::factory()->create();
|
||||
$response = $this->actingAs(User::factory()->createAssets()->create())
|
||||
->get(route('clone/hardware', $asset));
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function testAssetCanBeCloned()
|
||||
{
|
||||
$asset_to_clone = Asset::factory()->create(['name'=>'Asset to clone']);
|
||||
$this->actingAs(User::factory()->createAssets()->create())
|
||||
->get(route('clone/hardware', $asset_to_clone))
|
||||
->assertOk()
|
||||
->assertSee([
|
||||
'Asset to clone'
|
||||
], false);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue