diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php
index bf7edc75514e..0b3b30d339e3 100644
--- a/app/Http/Controllers/Api/AssetsController.php
+++ b/app/Http/Controllers/Api/AssetsController.php
@@ -1225,6 +1225,7 @@ public function audit(Request $request, Asset $asset): JsonResponse
*/
public function requestable(Request $request): JsonResponse | array
{
+
$this->authorize('viewRequestable', Asset::class);
$allowed_columns = [
@@ -1257,9 +1258,6 @@ public function requestable(Request $request): JsonResponse | array
'requests'
);
-
-
-
if ($request->filled('search')) {
$assets->TextSearch($request->input('search'));
}
diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php
index dac6fb49695d..2521a03bc3b5 100644
--- a/app/Http/Controllers/SettingsController.php
+++ b/app/Http/Controllers/SettingsController.php
@@ -331,6 +331,7 @@ public function postSettings(Request $request) : RedirectResponse
}
}
+ $setting->request_unassigned_deployable = $request->input('request_unassigned_deployable', '0');
$setting->unique_serial = $request->input('unique_serial', '0');
$setting->shortcuts_enabled = $request->input('shortcuts_enabled', '0');
$setting->show_images_in_email = $request->input('show_images_in_email', '0');
diff --git a/app/Http/Controllers/ViewAssetsController.php b/app/Http/Controllers/ViewAssetsController.php
index 2b767650ade3..e4acd530c95a 100755
--- a/app/Http/Controllers/ViewAssetsController.php
+++ b/app/Http/Controllers/ViewAssetsController.php
@@ -155,7 +155,30 @@ public function getIndex(Request $request) : View | RedirectResponse
public function getRequestableIndex() : View
{
$assets = Asset::with('model', 'defaultLoc', 'location', 'assignedTo', 'requests')->Hardware()->RequestableAssets();
- $models = AssetModel::with('category', 'requests', 'assets')->RequestableModels()->get();
+ $onlyUnassignedDeployable = Setting::getSettings()->request_unassigned_deployable;
+ $models = AssetModel::with([
+ 'category',
+ 'requests',
+ 'assets' => function ($q) use ($onlyUnassignedDeployable) {
+ if ($onlyUnassignedDeployable) {
+ // Unassigned + deployable (not archived)
+ $q->whereNull('assets.assigned_to')
+ ->whereHas('assetstatus', function ($s) {
+ $s->where('deployable', 1);
+ });
+ } else {
+ // Requestable + (deployable OR pending) but never archived
+ $q->where('requestable', 1)
+ ->whereHas('assetstatus', function ($s) {
+ $s->where('archived', 0)
+ ->where(function ($s) {
+ $s->where('deployable', 1)
+ ->orWhere('pending', 1);
+ });
+ });
+ }
+ },
+ ])->RequestableModels()->get();
return view('account/requestable-assets', compact('assets', 'models'));
}
diff --git a/app/Models/Asset.php b/app/Models/Asset.php
index d588690ba4bd..2734716ec3c3 100644
--- a/app/Models/Asset.php
+++ b/app/Models/Asset.php
@@ -1655,10 +1655,19 @@ public function scopeDeployed($query)
public function scopeRequestableAssets($query): Builder
{
$table = $query->getModel()->getTable();
-
- return Company::scopeCompanyables($query->where($table.'.requestable', '=', 1))
- ->whereHas(
- 'assetstatus', function ($query) {
+ $query = Company::scopeCompanyables($query->where($table . '.requestable', '=', 1));
+ $onlyUnassignedDeployable = Setting::getSettings()->request_unassigned_deployable;
+
+ if ($onlyUnassignedDeployable) {
+ // Unassigned + Deployable ONLY
+ $query
+ ->whereNull($table . '.assigned_to')
+ ->whereHas('assetstatus', function ($q) {
+ $q->where('deployable', 1)
+ ->where('archived', 0);
+ });
+ } else {
+ $query->whereHas('assetstatus', function ($query) {
$query->where(
function ($query) {
$query->where('deployable', '=', 1)
@@ -1666,7 +1675,9 @@ function ($query) {
}
)->orWhere('pending', '=', 1); // we've decided that even though an asset may be 'pending', you can still request it
}
- );
+ );
+ }
+ return $query;
}
diff --git a/database/migrations/2025_11_05_225413_add_request_only_deployable_to_settings_table.php b/database/migrations/2025_11_05_225413_add_request_only_deployable_to_settings_table.php
new file mode 100644
index 000000000000..33f44850f055
--- /dev/null
+++ b/database/migrations/2025_11_05_225413_add_request_only_deployable_to_settings_table.php
@@ -0,0 +1,28 @@
+boolean('request_unassigned_deployable')->after('unique_serial')->default(false);
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ */
+ public function down(): void
+ {
+ Schema::table('settings', function (Blueprint $table) {
+ $table->dropColumn('request_unassigned_deployable');
+ });
+ }
+};
diff --git a/resources/lang/en-US/admin/settings/general.php b/resources/lang/en-US/admin/settings/general.php
index 41c608c7ba83..6d0893e2ec5c 100644
--- a/resources/lang/en-US/admin/settings/general.php
+++ b/resources/lang/en-US/admin/settings/general.php
@@ -413,6 +413,8 @@
'default_avatar_help' => 'This image will be displayed as a profile if a user does not have a profile photo.',
'restore_default_avatar' => 'Restore original system default avatar',
'restore_default_avatar_help' => '',
+ 'request_unassigned_deployable_help_text' => 'Only assets with a status type of deployable and that are unassigned will be shown under requestable assets.',
+ 'request_unassigned_deployable' => 'Request Unassigned Deployable Assets Only',
'due_checkin_days' => 'Due For Checkin Warning',
'due_checkin_days_help' => 'How many days before the expected checkin of an asset should it be listed in the "Due for checkin" page?',
'no_groups' => 'No groups have been created yet. Visit Admin Settings > Permission Groups to add one.',
diff --git a/resources/views/account/requestable-assets.blade.php b/resources/views/account/requestable-assets.blade.php
index 4190a9126f5f..24ff694ee7b3 100644
--- a/resources/views/account/requestable-assets.blade.php
+++ b/resources/views/account/requestable-assets.blade.php
@@ -135,7 +135,7 @@ class="table table-striped snipe-table"
@endcan
-