mirror of
https://github.com/snipe/snipe-it.git
synced 2025-03-05 20:52:15 -08:00
Merge d1683d1c65
into c5dd942f3d
This commit is contained in:
commit
94b0574a23
|
@ -184,15 +184,15 @@ class AccessoriesController extends Controller
|
||||||
*/
|
*/
|
||||||
public function destroy($accessoryId) : RedirectResponse
|
public function destroy($accessoryId) : RedirectResponse
|
||||||
{
|
{
|
||||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
if (is_null($accessory = Accessory::withCount('checkouts as checkouts_count')->find($accessoryId))) {
|
||||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->authorize($accessory);
|
$this->authorize($accessory);
|
||||||
|
|
||||||
|
|
||||||
if ($accessory->hasUsers() > 0) {
|
if ($accessory->checkouts_count > 0) {
|
||||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_users', ['count'=> $accessory->hasUsers()]));
|
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/general.delete_disabled'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($accessory->image) {
|
if ($accessory->image) {
|
||||||
|
|
|
@ -249,11 +249,11 @@ class AccessoriesController extends Controller
|
||||||
public function destroy($id)
|
public function destroy($id)
|
||||||
{
|
{
|
||||||
$this->authorize('delete', Accessory::class);
|
$this->authorize('delete', Accessory::class);
|
||||||
$accessory = Accessory::findOrFail($id);
|
$accessory = Accessory::withCount('checkouts as checkouts_count')->findOrFail($id);
|
||||||
$this->authorize($accessory);
|
$this->authorize($accessory);
|
||||||
|
|
||||||
if ($accessory->hasUsers() > 0) {
|
if ($accessory->checkouts_count > 0) {
|
||||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/message.assoc_users', ['count'=> $accessory->hasUsers()])));
|
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/general.delete_disabled')));
|
||||||
}
|
}
|
||||||
|
|
||||||
$accessory->delete();
|
$accessory->delete();
|
||||||
|
|
|
@ -53,7 +53,7 @@ class AccessoriesTransformer
|
||||||
'checkout' => Gate::allows('checkout', Accessory::class),
|
'checkout' => Gate::allows('checkout', Accessory::class),
|
||||||
'checkin' => false,
|
'checkin' => false,
|
||||||
'update' => Gate::allows('update', Accessory::class),
|
'update' => Gate::allows('update', Accessory::class),
|
||||||
'delete' => Gate::allows('delete', Accessory::class),
|
'delete' => $accessory->checkouts_count === 0 && Gate::allows('delete', Accessory::class),
|
||||||
'clone' => Gate::allows('create', Accessory::class),
|
'clone' => Gate::allows('create', Accessory::class),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Accessory;
|
use App\Models\Accessory;
|
||||||
|
use App\Models\Asset;
|
||||||
use App\Models\Category;
|
use App\Models\Category;
|
||||||
use App\Models\Location;
|
use App\Models\Location;
|
||||||
use App\Models\Manufacturer;
|
use App\Models\Manufacturer;
|
||||||
|
@ -170,4 +171,30 @@ class AccessoryFactory extends Factory
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function checkedOutToAsset(Asset $asset = null)
|
||||||
|
{
|
||||||
|
return $this->afterCreating(function (Accessory $accessory) use ($asset) {
|
||||||
|
$accessory->checkouts()->create([
|
||||||
|
'accessory_id' => $accessory->id,
|
||||||
|
'created_at' => Carbon::now(),
|
||||||
|
'created_by' => 1,
|
||||||
|
'assigned_to' => $asset->id ?? Asset::factory()->create()->id,
|
||||||
|
'assigned_type' => Asset::class,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkedOutToLocation(Location $location = null)
|
||||||
|
{
|
||||||
|
return $this->afterCreating(function (Accessory $accessory) use ($location) {
|
||||||
|
$accessory->checkouts()->create([
|
||||||
|
'accessory_id' => $accessory->id,
|
||||||
|
'created_at' => Carbon::now(),
|
||||||
|
'created_by' => 1,
|
||||||
|
'assigned_to' => $location->id ?? Location::factory()->create()->id,
|
||||||
|
'assigned_type' => Location::class,
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Tests\Feature\Accessories\Api;
|
||||||
use App\Models\Accessory;
|
use App\Models\Accessory;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use PHPUnit\Framework\Attributes\DataProvider;
|
||||||
use Tests\Concerns\TestsFullMultipleCompaniesSupport;
|
use Tests\Concerns\TestsFullMultipleCompaniesSupport;
|
||||||
use Tests\Concerns\TestsPermissionsRequirement;
|
use Tests\Concerns\TestsPermissionsRequirement;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
@ -53,9 +54,17 @@ class DeleteAccessoriesTest extends TestCase implements TestsFullMultipleCompani
|
||||||
$this->assertSoftDeleted($accessoryC);
|
$this->assertSoftDeleted($accessoryC);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCannotDeleteAccessoryThatHasCheckouts()
|
public static function checkedOutAccessories()
|
||||||
{
|
{
|
||||||
$accessory = Accessory::factory()->checkedOutToUser()->create();
|
yield 'checked out to user' => [fn() => Accessory::factory()->checkedOutToUser()->create()];
|
||||||
|
yield 'checked out to asset' => [fn() => Accessory::factory()->checkedOutToAsset()->create()];
|
||||||
|
yield 'checked out to location' => [fn() => Accessory::factory()->checkedOutToLocation()->create()];
|
||||||
|
}
|
||||||
|
|
||||||
|
#[DataProvider('checkedOutAccessories')]
|
||||||
|
public function testCannotDeleteAccessoryThatHasCheckouts($data)
|
||||||
|
{
|
||||||
|
$accessory = $data();
|
||||||
|
|
||||||
$this->actingAsForApi(User::factory()->deleteAccessories()->create())
|
$this->actingAsForApi(User::factory()->deleteAccessories()->create())
|
||||||
->deleteJson(route('api.accessories.destroy', $accessory))
|
->deleteJson(route('api.accessories.destroy', $accessory))
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace Tests\Feature\Accessories\Ui;
|
||||||
use App\Models\Accessory;
|
use App\Models\Accessory;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use PHPUnit\Framework\Attributes\DataProvider;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
class DeleteAccessoryTest extends TestCase
|
class DeleteAccessoryTest extends TestCase
|
||||||
|
@ -29,9 +30,17 @@ class DeleteAccessoryTest extends TestCase
|
||||||
$this->assertFalse($accessoryForCompanyA->refresh()->trashed(), 'Accessory should not be deleted');
|
$this->assertFalse($accessoryForCompanyA->refresh()->trashed(), 'Accessory should not be deleted');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCannotDeleteAccessoryThatHasCheckouts()
|
public static function checkedOutAccessories()
|
||||||
{
|
{
|
||||||
$accessory = Accessory::factory()->checkedOutToUser()->create();
|
yield 'checked out to user' => [fn() => Accessory::factory()->checkedOutToUser()->create()];
|
||||||
|
yield 'checked out to asset' => [fn() => Accessory::factory()->checkedOutToAsset()->create()];
|
||||||
|
yield 'checked out to location' => [fn() => Accessory::factory()->checkedOutToLocation()->create()];
|
||||||
|
}
|
||||||
|
|
||||||
|
#[DataProvider('checkedOutAccessories')]
|
||||||
|
public function testCannotDeleteAccessoryThatHasCheckouts($data)
|
||||||
|
{
|
||||||
|
$accessory = $data();
|
||||||
|
|
||||||
$this->actingAs(User::factory()->deleteAccessories()->create())
|
$this->actingAs(User::factory()->deleteAccessories()->create())
|
||||||
->delete(route('accessories.destroy', $accessory->id))
|
->delete(route('accessories.destroy', $accessory->id))
|
||||||
|
|
Loading…
Reference in a new issue