Prevent deleting accessory that has checkouts via UI

This commit is contained in:
Marcus Moore 2025-03-05 15:56:01 -08:00
parent 64f49afce1
commit 8c21d625fc
No known key found for this signature in database
4 changed files with 42 additions and 5 deletions

View file

@ -184,15 +184,15 @@ class AccessoriesController extends Controller
*/
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'));
}
$this->authorize($accessory);
if ($accessory->hasUsers() > 0) {
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_users', ['count'=> $accessory->hasUsers()]));
if ($accessory->checkouts_count > 0) {
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_checkouts', ['count' => $accessory->checkouts_count]));
}
if ($accessory->image) {

View file

@ -3,6 +3,7 @@
namespace Database\Factories;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\Category;
use App\Models\Location;
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,
]);
});
}
}

View file

@ -5,6 +5,7 @@ return array(
'does_not_exist' => 'The accessory [:id] does not exist.',
'not_found' => 'That accessory was not found.',
'assoc_users' => 'This accessory currently has :count items checked out to users. Please check in the accessories and and try again. ',
'assoc_checkouts' => 'This accessory currently has :count items checked out. Please check in the accessories and and try again.',
'create' => array(
'error' => 'The accessory was not created, please try again.',

View file

@ -5,6 +5,7 @@ namespace Tests\Feature\Accessories\Ui;
use App\Models\Accessory;
use App\Models\Company;
use App\Models\User;
use PHPUnit\Framework\Attributes\DataProvider;
use Tests\TestCase;
class DeleteAccessoryTest extends TestCase
@ -29,9 +30,17 @@ class DeleteAccessoryTest extends TestCase
$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())
->delete(route('accessories.destroy', $accessory->id))