Merge branch 'develop'

This commit is contained in:
snipe 2017-12-12 07:22:30 -08:00
commit 694c6f3ec6
20 changed files with 197 additions and 79 deletions

View file

@ -22,10 +22,21 @@ class CompaniesController extends Controller
{
$this->authorize('view', Company::class);
$allowed_columns = ['id','name'];
$allowed_columns = [
'id',
'name',
'created_at',
'updated_at',
'users_count',
'assets_count',
'licenses_count',
'accessories_count',
'consumables_count',
'components_count',
];
$companies = Company::withCount('assets','licenses','accessories','consumables','components','users')
->withCount('users')->withCount('users')->withCount('assets')
->withCount('users')->withCount('assets')
->withCount('licenses')->withCount('accessories')
->withCount('consumables')->withCount('components');

View file

@ -149,7 +149,7 @@ class ComponentsController extends Controller
*/
public function getAssets(Request $request, $id)
{
$this->authorize('index', Asset::class);
$this->authorize('view', \App\Models\Asset::class);
$component = Component::findOrFail($id);
$assets = $component->assets();

View file

@ -219,7 +219,7 @@ class AssetsController extends Controller
// Was the asset created?
if ($asset->save()) {
$asset->logCreate();
if (request('assigned_user')) {
$target = User::find(request('assigned_user'));

View file

@ -315,7 +315,7 @@ class LicensesController extends Controller
$licenseSeat->asset_id = $request->input('asset_id');
// Override asset's assigned user if available
if ($target->assigned_to!='') {
if ($target->checkedOutToUser()) {
$licenseSeat->assigned_to = $target->assigned_to;
}

View file

@ -54,6 +54,7 @@ class ActionlogsTransformer
'note' => ($actionlog->note) ? e($actionlog->note): null,
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
'log_meta' => ($actionlog->log_meta) ? json_decode($actionlog->log_meta): null,
];

View file

@ -53,7 +53,7 @@ class AssetModelsTransformer
$permissions_array['available_actions'] = [
'update' => (Gate::allows('update', AssetModel::class) && ($assetmodel->deleted_at=='')) ? true : false,
'delete' => (Gate::allows('delete', AssetModel::class) && ($assetmodel->deleted_at=='')) ? true : false,
'delete' => (Gate::allows('delete', AssetModel::class) && ($assetmodel->assets_count==0) && ($assetmodel->deleted_at=='')) ? true : false,
'clone' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at=='')) ,
'restore' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at!='')) ? true : false,
];

View file

@ -38,7 +38,7 @@ class CompaniesTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Company::class) ? true : false,
'delete' => Gate::allows('delete', Company::class) ? true : false,
'delete' => (Gate::allows('delete', Category::class) && ($company->assets_count == 0) && ($company->accessories_count == 0) && ($company->consumables_count == 0) && ($company->components_count == 0) && ($company->users_count == 0)) ? true : false,
];
$array += $permissions_array;

View file

@ -47,7 +47,7 @@ class DepartmentsTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Department::class) ? true : false,
'delete' => Gate::allows('delete', Department::class) ? true : false,
'delete' => (Gate::allows('delete', Department::class) && ($department->users_count==0) && ($department->deleted_at=='')) ? true : false,
];
$array += $permissions_array;

View file

@ -57,7 +57,7 @@ class LocationsTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Location::class) ? true : false,
'delete' => Gate::allows('delete', Location::class) ? true : false,
'delete' => (Gate::allows('delete', Department::class) && ($location->assigned_assets_count==0) && ($location->assets_count==0) && ($location->users_count==0) && ($location->deleted_at=='')) ? true : false,
];
$array += $permissions_array;

View file

@ -40,7 +40,7 @@ class ManufacturersTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Manufacturer::class) ? true : false,
'delete' => Gate::allows('delete', Manufacturer::class) ? true : false,
'delete' => (Gate::allows('delete', Manufacturer::class) && ($manufacturer->assets_count == 0) && ($manufacturer->licenses_count==0) && ($manufacturer->consumables_count==0) && ($manufacturer->accessories_count==0) && ($manufacturer->deleted_at=='')) ? true : false,
];
$array += $permissions_array;

View file

@ -218,7 +218,8 @@ class Actionlog extends SnipeModel
$query->where('companies.name', 'LIKE', '%'.$search.'%');
});
})->orWhere('action_type', 'LIKE', '%'.$search.'%')
->orWhere('note', 'LIKE', '%'.$search.'%');
->orWhere('note', 'LIKE', '%'.$search.'%')
->orWhere('log_meta', 'LIKE', '%'.$search.'%');
}
});

View file

@ -18,18 +18,36 @@ class AssetObserver
public function updating(Asset $asset)
{
if ((isset($asset->getOriginal()['assigned_to'])) && ($asset->getAttributes()['assigned_to'] == $asset->getOriginal()['assigned_to'])
// If the asset isn't being checked out or audited, log the update.
// (Those other actions already create log entries.)
if (($asset->getAttributes()['assigned_to'] == $asset->getOriginal()['assigned_to'])
&& ($asset->getAttributes()['next_audit_date'] == $asset->getOriginal()['next_audit_date'])
&& ($asset->getAttributes()['last_checkout'] == $asset->getOriginal()['last_checkout'])
&& ($asset->getAttributes()['status_id'] == $asset->getOriginal()['status_id']))
&& ($asset->getAttributes()['last_checkout'] == $asset->getOriginal()['last_checkout']))
{
$changed = [];
foreach ($asset->getOriginal() as $key => $value) {
if ($asset->getOriginal()[$key] != $asset->getAttributes()[$key]) {
$changed[$key]['old'] = $asset->getOriginal()[$key];
$changed[$key]['new'] = $asset->getAttributes()[$key];
}
}
$logAction = new Actionlog();
$logAction->item_type = Asset::class;
$logAction->item_id = $asset->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->log_meta = json_encode($changed);
$logAction->logaction('update');
} else {
\Log::debug('Something else happened');
\Log::debug($asset->getOriginal()['assigned_to'].' == '.$asset->getAttributes()['assigned_to']);
\Log::debug($asset->getOriginal()['next_audit_date'].' == '.$asset->getAttributes()['next_audit_date']);
\Log::debug($asset->getOriginal()['last_checkout'].' == '.$asset->getAttributes()['last_checkout']);
}
}

View file

@ -41,51 +41,51 @@ class CompanyPresenter extends Presenter
],[
"field" => "users_count",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"title" => '<span class="hidden-xs"><i class="fa fa-users"></i></span><span class="hidden-md hidden-lg">'.trans('general.users').'</span></th>',
"visible" => true,
],[
"field" => "assets_count",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"title" => '<span class="hidden-xs"><i class="fa fa-barcode"></i></span><span class="hidden-md hidden-lg">'.trans('general.assets').'</span>',
"visible" => true,
],[
"field" => "licenses_count",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"visible" => true,
"title" => ' <span class="hidden-xs"><i class="fa fa-floppy-o"></i></span><span class="hidden-md hidden-lg">'.trans('general.licenses').'</span>',
],[
"field" => "accessories_count",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"visible" => true,
"title" => ' <span class="hidden-xs"><i class="fa fa-keyboard-o"></i></span><span class="hidden-md hidden-lg">'.trans('general.accessories').'</span>',
],[
"field" => "consumables_count",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"visible" => true,
"title" => ' <span class="hidden-xs"><i class="fa fa-tint"></i></span><span class="hidden-md hidden-lg">'.trans('general.consumables').'</span>',
],[
"field" => "components_count",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"visible" => true,
"title" => ' <span class="hidden-xs"><i class="fa fa-hdd-o"></i></span><span class="hidden-md hidden-lg">'.trans('general.components').'</span>',
],[
"field" => "updated_at",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"visible" => false,
"title" => trans('general.updated_at'),
],[
"field" => "created_at",
"searchable" => false,
"sortable" => false,
"sortable" => true,
"visible" => false,
"title" => trans('general.created_at'),
],[

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddActionlogMeta extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('action_logs', function (Blueprint $table) {
$table->text('log_meta')->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('action_logs', function (Blueprint $table) {
$table->dropColumn('log_meta');
});
}
}

View file

@ -143,29 +143,32 @@
<tr>
<td>{{ trans('admin/hardware/form.manufacturer') }}</td>
<td>
@can('view', \App\Models\Manufacturer::class)
<a href="{{ route('manufacturers.show', $asset->model->manufacturer->id) }}">
{{ $asset->model->manufacturer->name }}
</a>
@else
{{ $asset->model->manufacturer->name }}
@endcan
<ul class="list-unstyled" style="line-height: 25px;">
@can('view', \App\Models\Manufacturer::class)
@if ($asset->model->manufacturer->url)
<br><i class="fa fa-globe"></i> <a href="{{ $asset->model->manufacturer->url }}">{{ $asset->model->manufacturer->url }}</a>
@endif
<li><a href="{{ route('manufacturers.show', $asset->model->manufacturer->id) }}">
{{ $asset->model->manufacturer->name }}</li>
</a>
@else
<li> {{ $asset->model->manufacturer->name }}</li>
@endcan
@if ($asset->model->manufacturer->support_url)
<br><i class="fa fa-life-ring"></i> <a href="{{ $asset->model->manufacturer->support_url }}">{{ $asset->model->manufacturer->support_url }}</a>
@endif
@if ($asset->model->manufacturer->url)
<li><i class="fa fa-globe"></i> <a href="{{ $asset->model->manufacturer->url }}">{{ $asset->model->manufacturer->url }}</a></li>
@endif
@if ($asset->model->manufacturer->support_phone)
<br><i class="fa fa-phone"></i> {{ $asset->model->manufacturer->support_phone }}
@endif
@if ($asset->model->manufacturer->support_url)
<li><i class="fa fa-life-ring"></i> <a href="{{ $asset->model->manufacturer->support_url }}">{{ $asset->model->manufacturer->support_url }}</a></li>
@endif
@if ($asset->model->manufacturer->support_email)
<br><i class="fa fa-envelope"></i> <a href="mailto:{{ $asset->model->manufacturer->support_email }}">{{ $asset->model->manufacturer->support_email }}</a>
@endif
@if ($asset->model->manufacturer->support_phone)
<li><i class="fa fa-phone"></i> {{ $asset->model->manufacturer->support_phone }}</li>
@endif
@if ($asset->model->manufacturer->support_email)
<li><i class="fa fa-envelope"></i> <a href="mailto:{{ $asset->model->manufacturer->support_email }}">{{ $asset->model->manufacturer->support_email }}</a></li>
@endif
</ul>
</td>
</tr>
@endif
@ -426,7 +429,7 @@
{!! $asset->assignedTo->present()->glyph() . ' ' .$asset->assignedTo->present()->nameUrl() !!}
</p>
<ul class="list-unstyled">
<ul class="list-unstyled" style="line-height: 25px;">
@if ((isset($asset->assignedTo->email)) && ($asset->assignedTo->email!=''))
<li><i class="fa fa-envelope-o"></i> <a href="mailto:{{ $asset->assignedTo->email }}">{{ $asset->assignedTo->email }}</a></li>
@endif
@ -614,26 +617,33 @@
<div class="col-md-12">
<table
class="table table-striped snipe-table"
name="assetHistory"
name="asset-history"
id="table"
class="table table-striped snipe-table"
data-sort-order="desc"
data-height="400"
data-show-columns="true"
data-search="true"
data-cookie="true"
data-show-refresh="true"
data-cookie-id-table="asset-history"
data-url="{{ route('api.activity.index', ['item_id' => $asset->id, 'item_type' => 'asset']) }}">
<thead>
<tr>
<th data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter"></th>
<th class="col-sm-2" data-field="created_at" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
<th class="col-sm-2" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
<th class="col-sm-2" data-field="action_type">{{ trans('general.action') }}</th>
<th class="col-sm-1" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
<th class="col-sm-1" data-field="action_type">{{ trans('general.action') }}</th>
<th class="col-sm-2" data-field="item" data-formatter="polymorphicItemFormatter">{{ trans('general.item') }}</th>
<th class="col-sm-2" data-field="target" data-formatter="polymorphicItemFormatter">{{ trans('general.target') }}</th>
<th class="col-sm-2" data-field="note">{{ trans('general.notes') }}</th>
@if ($snipeSettings->require_accept_signature=='1')
<th class="col-md-3" data-field="signature_file" data-formatter="imageFormatter">{{ trans('general.signature') }}</th>
<th class="col-md-3" data-field="signature_file" data-visible="false" data-formatter="imageFormatter">{{ trans('general.signature') }}</th>
@endif
<th class="col-sm-2" data-field="log_meta" data-visible="false" data-formatter="changeLogFormatter">Changed</th>
</tr>
</thead>
</table>
</div>
</div> <!-- /.row -->
</div> <!-- /.tab-pane history -->
@ -673,7 +683,7 @@
<tr>
<th class="col-md-4">{{ trans('general.notes') }}</th>
<th class="col-md-2"></th>
<th class="col-md-4"><span class="line"></span>{{ trans('general.file_name') }}</th>
<th class="col-md-4">{{ trans('general.file_name') }}</th>
<th class="col-md-2"></th>
<th class="col-md-2"></th>
</tr>

View file

@ -479,7 +479,7 @@
</a>
</li>
@endcan
@can('index', \App\Models\Consumable::class)
@can('view', \App\Models\Component::class)
<li{!! (Request::is('consunmables*') ? ' class="active"' : '') !!}>
<a href="{{ url('consumables') }}">
<i class="fa fa-tint"></i>

View file

@ -56,34 +56,44 @@
<td>Seat {{ $count }} </td>
<td>
@if (($licensedto->user) && ($licensedto->deleted_at == NULL))
@can('users.view')
<a href="{{ route('users.show', $licensedto->assigned_to) }}">
<i class="fa fa-user"></i>
{{ $licensedto->user->present()->fullName() }}
</a>
@else
<i class="fa fa-user"></i>
{{ $licensedto->user->present()->fullName() }}
@endcan
@elseif (($licensedto->user) && ($licensedto->deleted_at != NULL))
<del>{{ $licensedto->user->present()->fullName() }}</del>
@elseif ($licensedto->asset)
@if ($licensedto->asset->assigned_to != 0)
@can('users.view')
{!! $licensedto->asset->assignedTo->present()->nameUrl() !!}
@else
{{ $licensedto->asset->assignedTo->present()->name() }}
@endcan
@endif
@endif
</td>
<td>
@if ($licensedto->asset)
@can('view', $licensedto->asset)
<a href="{{ route('hardware.show', $licensedto->asset_id) }}">
<i class="fa fa-barcode"></i>
{{ $licensedto->asset->name }} {{ $licensedto->asset->asset_tag }}
</a>
@else
<i class="fa fa-barcode"></i>
{{ $licensedto->asset->name }} {{ $licensedto->asset->asset_tag }}
@endcan
@if ($licensedto->asset->location)
@can('locations.view')
({!! $licensedto->asset->location->present()->nameUrl() !!})
@else
({{ $licensedto->asset->location->present()->name() }})
@endcan
@endif
@endif
</td>
<td>

View file

@ -42,27 +42,48 @@
</div><!-- /.box-header -->
@endif
<div class="box-body">
<table
name="modelassets"
id="table"
class="snipe-table"
data-url="{{ route('api.assets.index',['model_id'=> $model->id]) }}"
data-cookie="true"
data-click-to-select="true"
data-cookie-id-table="modeldetailsViewTable">
<thead>
<tr>
<th data-sortable="true" data-field="id" data-searchable="false" data-visible="false">{{ trans('general.id') }}</th>
<th data-sortable="false" data-field="company" data-searchable="false" data-visible="false" data-formatter="companiesLinkObjFormatter">{{ trans('admin/companies/table.title') }}</th>
<th data-sortable="true" data-field="name" data-searchable="true" data-formatter="hardwareLinkFormatter">{{ trans('general.name') }}</th>
<th data-sortable="true" data-field="asset_tag" data-formatter="hardwareLinkFormatter">{{ trans('general.asset_tag') }}</th>
<th data-sortable="true" data-field="serial" data-formatter="hardwareLinkFormatter">{{ trans('admin/hardware/table.serial') }}</th>
<th data-sortable="false" data-field="assigned_to" data-formatter="polymorphicItemFormatter">{{ trans('general.user') }}</th>
<th data-sortable="false" data-field="inout" data-formatter="hardwareInOutFormatter">{{ trans('admin/hardware/table.change') }}</th>
<th data-switchable="false" data-searchable="false" data-sortable="false" data-field="actions" data-formatter="hardwareActionsFormatter">{{ trans('table.actions') }}</th>
</tr>
</thead>
</table>
<div class="row">
<div class="col-md-12">
{{ Form::open([
'method' => 'POST',
'route' => ['hardware/bulkedit'],
'class' => 'form-inline',
'id' => 'bulkForm']) }}
<div id="toolbar">
<select name="bulk_actions" class="form-control select2">
<option value="edit">Edit</option>
<option value="delete">Delete</option>
<option value="labels">Generate Labels</option>
</select>
<button class="btn btn-primary" id="bulkEdit" disabled>Go</button>
</div>
<table
name="modelassets"
id="table"
class="snipe-table"
data-toolbar="#toolbar"
data-url="{{ route('api.assets.index',['model_id'=> $model->id]) }}"
data-cookie="true"
data-click-to-select="true"
data-cookie-id-table="model-assets">
<thead>
<tr>
<th data-checkbox="true" data-field="checkbox"></th>
<th data-sortable="true" data-field="id" data-searchable="false" data-visible="false">{{ trans('general.id') }}</th>
<th data-sortable="false" data-field="company" data-searchable="false" data-visible="false" data-formatter="companiesLinkObjFormatter">{{ trans('admin/companies/table.title') }}</th>
<th data-sortable="true" data-field="name" data-searchable="true" data-formatter="hardwareLinkFormatter">{{ trans('general.name') }}</th>
<th data-sortable="true" data-field="asset_tag" data-formatter="hardwareLinkFormatter">{{ trans('general.asset_tag') }}</th>
<th data-sortable="true" data-field="serial" data-formatter="hardwareLinkFormatter">{{ trans('admin/hardware/table.serial') }}</th>
<th data-sortable="false" data-field="assigned_to" data-formatter="polymorphicItemFormatter">{{ trans('admin/hardware/form.checkedout_to') }}</th>
<th data-sortable="false" data-field="inout" data-formatter="hardwareInOutFormatter">{{ trans('admin/hardware/table.change') }}</th>
<th data-switchable="false" data-searchable="false" data-sortable="false" data-field="actions" data-formatter="hardwareActionsFormatter">{{ trans('table.actions') }}</th>
</tr>
</thead>
</table>
{{ Form::close() }}
</div>
</div>
</div> <!-- /.box-body-->
</div> <!-- /.box-default-->
</div> <!-- /.col-md-9-->

View file

@ -395,6 +395,19 @@
}
}
function changeLogFormatter(value) {
var result = '';
for (var index in value) {
result += index + ': <del>' + value[index].old + '</del> <i class="fa fa-long-arrow-right" aria-hidden="true"></i> ' + value[index].new + '<br>'
}
return result;
}
function deployedLocationFormatter(row, value) {
if ((row) && (row!=undefined)) {
return '<a href="{{ url('/') }}/locations/' + row.id + '"> ' + row.name + '</a>';

View file

@ -32,6 +32,7 @@
<th class="col-sm-3" data-field="item" data-formatter="polymorphicItemFormatter">{{ trans('general.item') }}</th>
<th class="col-sm-2" data-field="target" data-formatter="polymorphicItemFormatter">To</th>
<th class="col-sm-1" data-field="note">{{ trans('general.notes') }}</th>
<th class="col-sm-2" data-field="log_meta" data-visible="false" data-formatter="changeLogFormatter">Changed</th>
</tr>
</thead>
</table>