FMCS/Companyable Trait: refactor API call to use canCheckoutTo

This commit is contained in:
snipe
2026-06-13 14:38:32 +01:00
parent e3a9872d28
commit 43a32071f1
4 changed files with 76 additions and 25 deletions
+1 -23
View File
@@ -913,29 +913,7 @@ class AssetsController extends Controller
private function checkoutCompanyMismatchResponse(Asset $asset, User|Asset|Location $target): ?JsonResponse
{
if (Setting::getSettings()->full_multiple_companies_support != '1' || is_null($asset->company_id)) {
return null;
}
// For users with multiple companies, check all their associated companies,
// not just the primary company_id column.
if ($target instanceof User) {
if (! $target->canReceiveFromCompany((int) $asset->company_id)) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.error_user_company')));
}
return null;
}
if (is_null($target->company_id)) {
// Target has no company — only a mismatch when floater mode is off.
$nonUserMismatch = ! Setting::getSettings()->null_company_is_floater;
} else {
// Both sides have a company; require an exact match.
$nonUserMismatch = (int) $asset->company_id !== (int) $target->company_id;
}
if ($nonUserMismatch) {
if (! $asset->canCheckoutTo($target)) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.error_user_company')));
}
+5 -1
View File
@@ -41,7 +41,11 @@ trait CompanyableTrait
}
if (! $this->company_id) {
return true;
if (is_null($target->company_id)) {
return true;
}
return (bool) $settings->null_company_is_floater;
}
if ($target instanceof User) {
@@ -63,7 +63,7 @@ class CheckoutAccessoryTest extends TestCase
]);
}
public function test_checkout_to_user_succeeds_when_accessory_has_no_company_with_fmcs_enabled()
public function test_checkout_to_user_is_blocked_when_accessory_has_no_company_with_fmcs_enabled_without_floater()
{
$accessory = Accessory::factory()->create(['qty' => 5, 'company_id' => null]);
[$companyA] = Company::factory()->count(1)->create();
@@ -71,6 +71,33 @@ class CheckoutAccessoryTest extends TestCase
$user->companies()->sync([$companyA->id]);
$this->settings->enableMultipleFullCompanySupport();
$this->settings->disableFloaterMode();
$actor = User::factory()->superuser()->create();
$this->actingAs($actor)
->post(route('accessories.checkout.store', $accessory), [
'checkout_to_type' => 'user',
'assigned_user' => $user->id,
'checkout_qty' => 1,
'redirect_option' => 'index',
])
->assertRedirect();
$this->assertDatabaseMissing('accessories_checkout', [
'accessory_id' => $accessory->id,
'assigned_to' => $user->id,
]);
}
public function test_checkout_to_user_succeeds_when_accessory_has_no_company_with_floater_enabled()
{
$accessory = Accessory::factory()->create(['qty' => 5, 'company_id' => null]);
[$companyA] = Company::factory()->count(1)->create();
$user = User::factory()->for($companyA)->create();
$user->companies()->sync([$companyA->id]);
$this->settings->enableFloaterMode();
$actor = User::factory()->superuser()->create();
@@ -408,4 +408,46 @@ class AssetCheckoutTest extends TestCase
$this->assertTrue((bool) $asset->fresh()->requestable);
}
public function test_null_company_asset_cannot_be_checked_out_to_companied_user_when_fmcs_enabled_without_floater()
{
$this->settings->enableMultipleFullCompanySupport();
$this->settings->disableFloaterMode();
$company = Company::factory()->create();
$actor = User::factory()->superuser()->create();
$nullCompanyAsset = Asset::factory()->create(['company_id' => null]);
$companiedUser = User::factory()->for($company)->create();
$this->actingAsForApi($actor)
->postJson(route('api.asset.checkout', $nullCompanyAsset), [
'checkout_to_type' => 'user',
'assigned_user' => $companiedUser->id,
])
->assertOk()
->assertStatusMessageIs('error')
->assertMessagesAre(trans('general.error_user_company'));
$this->assertNull($nullCompanyAsset->fresh()->assigned_to);
}
public function test_null_company_asset_can_be_checked_out_to_companied_user_when_floater_enabled()
{
$this->settings->enableFloaterMode();
$company = Company::factory()->create();
$actor = User::factory()->superuser()->create();
$nullCompanyAsset = Asset::factory()->create(['company_id' => null]);
$companiedUser = User::factory()->for($company)->create();
$this->actingAsForApi($actor)
->postJson(route('api.asset.checkout', $nullCompanyAsset), [
'checkout_to_type' => 'user',
'assigned_user' => $companiedUser->id,
])
->assertOk()
->assertStatusMessageIs('success');
$this->assertEquals($companiedUser->id, $nullCompanyAsset->fresh()->assigned_to);
}
}