Merge pull request #15160 from snipe/fixes/allow_cloning_of_deleted_assets

Allow cloning of deleted assets
This commit is contained in:
snipe 2024-07-24 18:09:55 +01:00 committed by GitHub
commit 8368fb5c41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 64 additions and 37 deletions

View file

@ -576,26 +576,20 @@ class AssetsController extends Controller
* @since [v1.0] * @since [v1.0]
* @return \Illuminate\Contracts\View\View * @return \Illuminate\Contracts\View\View
*/ */
public function getClone($assetId = null) public function getClone(Asset $asset)
{ {
// Check if the asset exists $this->authorize('create', $asset);
if (is_null($asset_to_clone = Asset::find($assetId))) { $cloned = clone $asset;
// Redirect to the asset management page $cloned->id = null;
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); $cloned->asset_tag = '';
} $cloned->serial = '';
$cloned->assigned_to = '';
$this->authorize('create', $asset_to_clone); $cloned->deleted_at = '';
$asset = clone $asset_to_clone;
$asset->id = null;
$asset->asset_tag = '';
$asset->serial = '';
$asset->assigned_to = '';
return view('hardware/edit') return view('hardware/edit')
->with('statuslabel_list', Helper::statusLabelList()) ->with('statuslabel_list', Helper::statusLabelList())
->with('statuslabel_types', Helper::statusTypeList()) ->with('statuslabel_types', Helper::statusTypeList())
->with('item', $asset); ->with('item', $cloned);
} }
/** /**

View file

@ -197,23 +197,13 @@
@endif @endif
@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;"> <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"> <a href="{{ route('hardware.edit', $asset->id) }}" class="btn btn-sm btn-primary btn-block hidden-print">
{{ trans('admin/hardware/general.edit') }} {{ trans('admin/hardware/general.edit') }}
</a> </a>
</div> </div>
@endif
@endcan
@can('create', $asset)
<div class="col-md-12" style="padding-top: 5px;">
<a href="{{ route('clone/hardware', $asset->id) }}" class="btn btn-sm btn-primary btn-block hidden-print">
{{ trans('admin/hardware/general.clone') }}
</a>
</div>
@endcan @endcan
@can('audit', \App\Models\Asset::class) @can('audit', \App\Models\Asset::class)
@ -225,6 +215,15 @@
</span> </span>
</div> </div>
@endcan @endcan
@endif
@can('create', $asset)
<div class="col-md-12" style="padding-top: 5px;">
<a href="{{ route('clone/hardware', $asset->id) }}" class="btn btn-sm btn-primary btn-block hidden-print">
{{ trans('admin/hardware/general.clone') }}
</a>
</div>
@endcan
@can('delete', $asset) @can('delete', $asset)
<div class="col-md-12" style="padding-top: 30px; padding-bottom: 30px;"> <div class="col-md-12" style="padding-top: 30px; padding-bottom: 30px;">

View file

@ -78,17 +78,14 @@ Route::group(
[AssetsController::class, 'getAssetBySerial'] [AssetsController::class, 'getAssetBySerial']
)->where('any', '.*')->name('findbyserial/hardware'); )->where('any', '.*')->name('findbyserial/hardware');
Route::get('{assetId}/clone', Route::get('{asset}/clone',
[AssetsController::class, 'getClone'] [AssetsController::class, 'getClone']
)->name('clone/hardware'); )->name('clone/hardware')->withTrashed();
Route::get('{assetId}/label', Route::get('{assetId}/label',
[AssetsController::class, 'getLabel'] [AssetsController::class, 'getLabel']
)->name('label/hardware'); )->name('label/hardware');
Route::post('{assetId}/clone',
[AssetsController::class, 'postCreate']
);
Route::get('{assetId}/checkout', Route::get('{assetId}/checkout',
[AssetCheckoutController::class, 'create'] [AssetCheckoutController::class, 'create']

View 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);
}
}