Merge pull request #16295 from snipe/#16282_adds_accessories_tab_to_assets

Fixed #16282 - adds accessories tab to assets
This commit is contained in:
snipe 2025-02-22 14:21:32 +00:00 committed by GitHub
commit 84a29378cd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 147 additions and 7 deletions

View file

@ -1230,7 +1230,10 @@ class AssetsController extends Controller
{
$this->authorize('view', Asset::class);
$this->authorize('view', $asset);
$accessory_checkouts = AccessoryCheckout::AssetsAssigned()->with('adminuser')->with('accessories');
$accessory_checkouts = AccessoryCheckout::AssetsAssigned()
->where('assigned_to', $asset->id)
->with('adminuser')
->with('accessories');
$offset = ($request->input('offset') > $accessory_checkouts->count()) ? $accessory_checkouts->count() : app('api_offset_value');
$limit = app('api_limit_value');
@ -1239,6 +1242,8 @@ class AssetsController extends Controller
$accessory_checkouts = $accessory_checkouts->skip($offset)->take($limit)->get();
return (new AssetsTransformer)->transformCheckedoutAccessories($accessory_checkouts, $total);
}
/**
* Generate asset labels by tag
*

View file

@ -309,6 +309,7 @@ class AssetsTransformer
'id' => $accessory_checkout->accessory->id,
'name' => $accessory_checkout->accessory->name,
],
'assigned_to' => $accessory_checkout->assigned_to,
'image' => ($accessory_checkout->accessory->image) ? Storage::disk('public')->url('accessories/'.e($accessory_checkout->accessory->image)) : null,
'note' => $accessory_checkout->note ? e($accessory_checkout->note) : null,
'created_by' => $accessory_checkout->adminuser ? [

View file

@ -100,6 +100,7 @@ class LocationsTransformer
$array = [
'id' => $accessory_checkout->id,
'assigned_to' => $accessory_checkout->assigned_to,
'accessory' => [
'id' => $accessory_checkout->accessory->id,
'name' => $accessory_checkout->accessory->name,

View file

@ -57,7 +57,7 @@ class AccessoryCheckout extends Model
*/
public function adminuser()
{
return $this->hasOne(\App\Models\User::class, 'created_by');
return $this->hasOne(\App\Models\User::class, 'id', 'created_by');
}
/**
@ -118,7 +118,7 @@ class AccessoryCheckout extends Model
$query->where('assigned_type', '=', Location::class);
}
public function scopeAssetAssigned(Builder $query): void
public function scopeAssetsAssigned(Builder $query): void
{
$query->where('assigned_type', '=', Asset::class);
}

View file

@ -523,6 +523,18 @@ class Asset extends Depreciable
return $this->morphMany(self::class, 'assigned', 'assigned_type', 'assigned_to')->withTrashed();
}
/**
* Establishes the accessory -> asset assignment relationship
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v3.0]
* @return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assignedAccessories()
{
return $this->morphMany(\App\Models\AccessoryCheckout::class, 'assigned', 'assigned_type', 'assigned_to');
}
/**
* Get the asset's location based on the assigned user

View file

@ -352,6 +352,74 @@ class AssetPresenter extends Presenter
return json_encode($layout);
}
public static function assignedAccessoriesDataTableLayout()
{
$layout = [
[
'field' => 'id',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'title' => trans('general.id'),
'visible' => false,
],
[
'field' => 'accessory',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'title' => trans('general.accessory'),
'visible' => true,
'formatter' => 'accessoriesLinkObjFormatter',
],
[
'field' => 'image',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'title' => trans('general.image'),
'visible' => true,
'formatter' => 'imageFormatter',
],
[
'field' => 'note',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'title' => trans('general.notes'),
'visible' => true,
],
[
'field' => 'created_at',
'searchable' => false,
'sortable' => false,
'switchable' => true,
'title' => trans('admin/hardware/table.checkout_date'),
'visible' => true,
'formatter' => 'dateDisplayFormatter',
],
[
'field' => 'created_by',
'searchable' => false,
'sortable' => false,
'title' => trans('general.created_by'),
'visible' => false,
'formatter' => 'usersLinkObjFormatter',
],
[
'field' => 'available_actions',
'searchable' => false,
'sortable' => false,
'switchable' => false,
'title' => trans('table.actions'),
'formatter' => 'accessoriesInOutFormatter',
],
];
return json_encode($layout);
}
/**
* Generate html link to this items name.
* @return string

View file

@ -77,13 +77,30 @@
<span class="hidden-lg hidden-md">
<x-icon type="assets" class="fa-2x" />
</span>
<span class="hidden-xs hidden-sm">{{ trans('general.assets') }}
<span class="hidden-xs hidden-sm">
{{ trans('general.assets') }}
{!! ($asset->assignedAssets()->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->assignedAssets()->count()).'</span>' : '' !!}
</span>
</a>
</li>
@if ($asset->assignedAccessories->count() > 0)
<li>
<a href="#accessories_assigned" data-toggle="tab" data-tooltip="true">
<span class="hidden-lg hidden-md">
<i class="fas fa-keyboard fa-2x"></i>
</span>
<span class="hidden-xs hidden-sm">
{{ trans('general.accessories_assigned') }}
{!! ($asset->assignedAccessories()->count() > 0 ) ? '<span class="badge badge-secondary">'.number_format($asset->assignedAccessories()->count()).'</span>' : '' !!}
</span>
</a>
</li>
@endif
<li>
<a href="#history" data-toggle="tab">
@ -1294,6 +1311,40 @@
</div> <!-- /.tab-pane software -->
<div class="tab-pane" id="accessories_assigned">
<div class="table table-responsive">
<h2 class="box-title" style="float:left">
{{ trans('general.accessories_assigned') }}
</h2>
<table
data-columns="{{ \App\Presenters\AssetPresenter::assignedAccessoriesDataTableLayout() }}"
data-cookie-id-table="accessoriesAssignedListingTable"
data-pagination="true"
data-id-table="accessoriesAssignedListingTable"
data-search="true"
data-side-pagination="server"
data-show-columns="true"
data-show-export="true"
data-show-refresh="true"
data-sort-order="asc"
data-click-to-select="true"
id="accessoriesAssignedListingTable"
class="table table-striped snipe-table"
data-url="{{ route('api.assets.assigned_accessories', ['asset' => $asset]) }}"
data-export-options='{
"fileName": "export-locations-{{ str_slug($asset->name) }}-accessories-{{ date('Y-m-d') }}",
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
}'>
</table>
</div><!-- /.table-responsive -->
</div><!-- /.tab-pane -->
<div class="tab-pane fade" id="maintenances">
<div class="row{{($asset->assetmaintenances->count() > 0 ) ? '' : ' hidden-print'}}">
<div class="col-md-12">

View file

@ -314,11 +314,13 @@
</div><!-- /.tab-pane -->
<div class="tab-pane" id="accessories_assigned">
<h2 class="box-title">
Assigned Accessories
</h2>
<div class="table table-responsive">
<h2 class="box-title" style="float:left">
{{ trans('general.accessories_assigned') }}
</h2>
<table
data-columns="{{ \App\Presenters\LocationPresenter::assignedAccessoriesDataTableLayout() }}"
data-cookie-id-table="accessoriesAssignedListingTable"