mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-10 07:34:06 -08:00
Merge remote-tracking branch 'origin/develop'
This commit is contained in:
commit
df2b52c537
|
@ -7,6 +7,8 @@ use App\Helpers\Helper;
|
|||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Setting;
|
||||
use App\View\Label;
|
||||
use Illuminate\Http\Request;
|
||||
|
@ -23,6 +25,13 @@ class BulkAssetsController extends Controller
|
|||
/**
|
||||
* Display the bulk edit page.
|
||||
*
|
||||
* This method is super weird because it's kinda of like a controller within a controller.
|
||||
* It's main function is to determine what the bulk action in, and then return a view with
|
||||
* the information that view needs, be it bulk delete, bulk edit, restore, etc.
|
||||
*
|
||||
* This is something that made sense at the time, but sort of doesn't make sense now. A JS front-end to determine form
|
||||
* action would make a lot more sense here and make things a lot more clear.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return View
|
||||
* @internal param int $assetId
|
||||
|
@ -32,7 +41,10 @@ class BulkAssetsController extends Controller
|
|||
public function edit(Request $request)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
|
||||
/**
|
||||
* No asset IDs were passed
|
||||
*/
|
||||
if (! $request->filled('ids')) {
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected'));
|
||||
}
|
||||
|
@ -41,59 +53,52 @@ class BulkAssetsController extends Controller
|
|||
$bulk_back_url = request()->headers->get('referer');
|
||||
session(['bulk_back_url' => $bulk_back_url]);
|
||||
|
||||
$asset_ids = array_values(array_unique($request->input('ids')));
|
||||
|
||||
//custom fields logic
|
||||
$asset_custom_field = Asset::with(['model.fieldset.fields', 'model'])->whereIn('id', $asset_ids)->whereHas('model', function ($query) {
|
||||
return $query->where('fieldset_id', '!=', null);
|
||||
})->get();
|
||||
|
||||
$models = $asset_custom_field->unique('model_id');
|
||||
$asset_ids = $request->input('ids');
|
||||
$assets = Asset::with('assignedTo', 'location', 'model')->find($asset_ids);
|
||||
|
||||
$models = $assets->unique('model_id');
|
||||
$modelNames = [];
|
||||
foreach($models as $model) {
|
||||
$modelNames[] = $model->model->name;
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('bulk_actions')) {
|
||||
|
||||
|
||||
switch ($request->input('bulk_actions')) {
|
||||
case 'labels':
|
||||
$this->authorize('view', Asset::class);
|
||||
$assets_found = Asset::find($asset_ids);
|
||||
|
||||
if ($assets_found->isEmpty()){
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
return (new Label)
|
||||
->with('assets', $assets_found)
|
||||
->with('assets', $assets)
|
||||
->with('settings', Setting::getSettings())
|
||||
->with('bulkedit', true)
|
||||
->with('count', 0);
|
||||
|
||||
case 'delete':
|
||||
$this->authorize('delete', Asset::class);
|
||||
$assets = Asset::with('assignedTo', 'location')->find($asset_ids);
|
||||
$assets->each(function ($asset) {
|
||||
$this->authorize('delete', $asset);
|
||||
$assets->each(function ($assets) {
|
||||
$this->authorize('delete', $assets);
|
||||
});
|
||||
|
||||
return view('hardware/bulk-delete')->with('assets', $assets);
|
||||
|
||||
case 'restore':
|
||||
$this->authorize('update', Asset::class);
|
||||
$assets = Asset::withTrashed()->find($asset_ids);
|
||||
$assets = Asset::withTrashed()->find($asset_ids);
|
||||
$assets->each(function ($asset) {
|
||||
$this->authorize('delete', $asset);
|
||||
});
|
||||
|
||||
return view('hardware/bulk-restore')->with('assets', $assets);
|
||||
|
||||
case 'edit':
|
||||
$this->authorize('update', Asset::class);
|
||||
|
||||
return view('hardware/bulk')
|
||||
->with('assets', $asset_ids)
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('models', $models->pluck(['model']))
|
||||
->with('models', $models->pluck(['model']))
|
||||
->with('modelNames', $modelNames);
|
||||
}
|
||||
}
|
||||
|
@ -117,25 +122,31 @@ class BulkAssetsController extends Controller
|
|||
|
||||
// Get the back url from the session and then destroy the session
|
||||
$bulk_back_url = route('hardware.index');
|
||||
|
||||
if ($request->session()->has('bulk_back_url')) {
|
||||
$bulk_back_url = $request->session()->pull('bulk_back_url');
|
||||
}
|
||||
|
||||
$custom_field_columns = CustomField::all()->pluck('db_column')->toArray();
|
||||
|
||||
|
||||
if (Session::exists('ids')) {
|
||||
$assets = Session::get('ids');
|
||||
} elseif (! $request->filled('ids') || count($request->input('ids')) <= 0) {
|
||||
if (! $request->filled('ids') || count($request->input('ids')) == 0) {
|
||||
return redirect($bulk_back_url)->with('error', trans('admin/hardware/message.update.no_assets_selected'));
|
||||
}
|
||||
|
||||
$assets = array_keys($request->input('ids'));
|
||||
|
||||
if ($request->anyFilled($custom_field_columns)) {
|
||||
$custom_fields_present = true;
|
||||
} else {
|
||||
$custom_fields_present = false;
|
||||
}
|
||||
|
||||
|
||||
$assets = Asset::whereIn('id', array_keys($request->input('ids')))->get();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* If ANY of these are filled, prepare to update the values on the assets.
|
||||
*
|
||||
* Additional checks will be needed for some of them to make sure the values
|
||||
* make sense (for example, changing the status ID to something incompatible with
|
||||
* its checkout status.
|
||||
*/
|
||||
|
||||
if (($request->filled('purchase_date'))
|
||||
|| ($request->filled('expected_checkin'))
|
||||
|| ($request->filled('purchase_cost'))
|
||||
|
@ -154,22 +165,32 @@ class BulkAssetsController extends Controller
|
|||
|| ($request->anyFilled($custom_field_columns))
|
||||
|
||||
) {
|
||||
foreach ($assets as $assetId) {
|
||||
// Let's loop through those assets and build an update array
|
||||
foreach ($assets as $asset) {
|
||||
|
||||
$this->update_array = [];
|
||||
|
||||
/**
|
||||
* Leave out model_id and status here because we do math on that later. We have to do some extra
|
||||
* validation and checks on those two.
|
||||
*
|
||||
* It's tempting to make these match the request check above, but some of these values require
|
||||
* extra work to make sure the data makes sense.
|
||||
*/
|
||||
$this->conditionallyAddItem('purchase_date')
|
||||
->conditionallyAddItem('expected_checkin')
|
||||
->conditionallyAddItem('order_number')
|
||||
->conditionallyAddItem('requestable')
|
||||
->conditionallyAddItem('status_id')
|
||||
->conditionallyAddItem('supplier_id')
|
||||
->conditionallyAddItem('warranty_months')
|
||||
->conditionallyAddItem('next_audit_date');
|
||||
foreach ($custom_field_columns as $key => $custom_field_column) {
|
||||
$this->conditionallyAddItem($custom_field_column);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Blank out fields that were requested to be blanked out via checkbox
|
||||
*/
|
||||
if ($request->input('null_purchase_date')=='1') {
|
||||
$this->update_array['purchase_date'] = null;
|
||||
}
|
||||
|
@ -186,7 +207,6 @@ class BulkAssetsController extends Controller
|
|||
$this->update_array['purchase_cost'] = $request->input('purchase_cost');
|
||||
}
|
||||
|
||||
|
||||
if ($request->filled('company_id')) {
|
||||
$this->update_array['company_id'] = $request->input('company_id');
|
||||
if ($request->input('company_id') == 'clear') {
|
||||
|
@ -194,88 +214,129 @@ class BulkAssetsController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We're trying to change the model ID - we need to do some extra checks here to make sure
|
||||
* the custom field values work for the custom fieldset rules around this asset. Uniqueness
|
||||
* and requiredness across the fieldset is particularly important, since those are
|
||||
* fieldset-specific attributes.
|
||||
*/
|
||||
if ($request->filled('model_id')) {
|
||||
$this->update_array['model_id'] = AssetModel::find($request->input('model_id'))->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* We're trying to change the status ID - we need to do some extra checks here to
|
||||
* make sure the status label type is one that makes sense for the state of the asset,
|
||||
* for example, we shouldn't be able to make an asset archived if it's currently assigned
|
||||
* to someone/something.
|
||||
*/
|
||||
if ($request->filled('status_id')) {
|
||||
$updated_status = Statuslabel::find($request->input('status_id'));
|
||||
|
||||
// We cannot assign a non-deployable status type if the asset is already assigned.
|
||||
// This could probably be added to a form request.
|
||||
// If the asset isn't assigned, we don't care what the status is.
|
||||
// Otherwise we need to make sure the status type is still a deployable one.
|
||||
if (
|
||||
($asset->assigned_to == '')
|
||||
|| ($updated_status->deployable == '1') && ($asset->assetstatus->deployable == '1')
|
||||
) {
|
||||
$this->update_array['status_id'] = $updated_status->id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* We're changing the location ID - figure out which location we should apply
|
||||
* this change to:
|
||||
*
|
||||
* 0 - RTD location only
|
||||
* 1 - location ID and RTD location ID
|
||||
* 2 - location ID only
|
||||
*
|
||||
* Note: this is kinda dumb and we should just use human-readable values IMHO. - snipe
|
||||
*/
|
||||
if ($request->filled('rtd_location_id')) {
|
||||
|
||||
if (($request->filled('update_real_loc')) && (($request->input('update_real_loc')) == '0')) {
|
||||
$this->update_array['rtd_location_id'] = $request->input('rtd_location_id');
|
||||
}
|
||||
|
||||
if (($request->filled('update_real_loc')) && (($request->input('update_real_loc')) == '1')) {
|
||||
$this->update_array['location_id'] = $request->input('rtd_location_id');
|
||||
$this->update_array['rtd_location_id'] = $request->input('rtd_location_id');
|
||||
}
|
||||
|
||||
if (($request->filled('update_real_loc')) && (($request->input('update_real_loc')) == '2')) {
|
||||
$this->update_array['location_id'] = $request->input('rtd_location_id');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ------------------------------------------------------------------------------
|
||||
* ANYTHING that happens past this foreach
|
||||
* WILL NOT BE logged in the edit log_meta data
|
||||
* ------------------------------------------------------------------------------
|
||||
*/
|
||||
$changed = [];
|
||||
$asset = Asset::find($assetId);
|
||||
|
||||
foreach ($this->update_array as $key => $value) {
|
||||
|
||||
if ($this->update_array[$key] != $asset->{$key}) {
|
||||
$changed[$key]['old'] = $asset->{$key};
|
||||
$changed[$key]['new'] = $this->update_array[$key];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($custom_fields_present) {
|
||||
|
||||
$model = $asset->model()->first();
|
||||
/**
|
||||
* Start all the custom fields shenanigans
|
||||
*/
|
||||
|
||||
// Use the rules of the new model fieldsets if the model changed
|
||||
if ($request->filled('model_id')) {
|
||||
$this->update_array['model_id'] = $request->input('model_id');
|
||||
$model = \App\Models\AssetModel::find($request->input('model_id'));
|
||||
}
|
||||
// Does the model have a fieldset?
|
||||
if ($asset->model->fieldset) {
|
||||
foreach ($asset->model->fieldset->fields as $field) {
|
||||
|
||||
if ((array_key_exists($field->db_column, $this->update_array)) && ($field->field_encrypted == '1')) {
|
||||
$decrypted_old = Helper::gracefulDecrypt($field, $asset->{$field->db_column});
|
||||
|
||||
// Make sure this model is valid
|
||||
$assetCustomFields = ($model) ? $model->fieldset : null;
|
||||
|
||||
if ($assetCustomFields && $assetCustomFields->fields) {
|
||||
|
||||
foreach ($assetCustomFields->fields as $field) {
|
||||
|
||||
if ((array_key_exists($field->db_column, $this->update_array)) && ($field->field_encrypted=='1')) {
|
||||
$decrypted_old = Helper::gracefulDecrypt($field, $asset->{$field->db_column});
|
||||
|
||||
/*
|
||||
* Check if the decrypted existing value is different from one we just submitted
|
||||
* and if not, pull it out of the object since it shouldn't really be updating at all.
|
||||
* If we don't do this, it will try to re-encrypt it, and the same value encrypted two
|
||||
* different times will have different values, so it will *look* like it was updated
|
||||
* but it wasn't.
|
||||
*/
|
||||
if ($decrypted_old != $this->update_array[$field->db_column]) {
|
||||
$asset->{$field->db_column} = \Crypt::encrypt($this->update_array[$field->db_column]);
|
||||
} else {
|
||||
/*
|
||||
* Remove the encrypted custom field from the update_array, since nothing changed
|
||||
*/
|
||||
unset($this->update_array[$field->db_column]);
|
||||
unset($asset->{$field->db_column});
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the decrypted existing value is different from one we just submitted
|
||||
* and if not, pull it out of the object since it shouldn't really be updating at all.
|
||||
* If we don't do this, it will try to re-encrypt it, and the same value encrypted two
|
||||
* different times will have different values, so it will *look* like it was updated
|
||||
* but it wasn't.
|
||||
*/
|
||||
if ($decrypted_old != $this->update_array[$field->db_column]) {
|
||||
$asset->{$field->db_column} = \Crypt::encrypt($this->update_array[$field->db_column]);
|
||||
} else {
|
||||
/*
|
||||
* These custom fields aren't encrypted, just carry on as usual
|
||||
* Remove the encrypted custom field from the update_array, since nothing changed
|
||||
*/
|
||||
unset($this->update_array[$field->db_column]);
|
||||
unset($asset->{$field->db_column});
|
||||
}
|
||||
|
||||
/*
|
||||
* These custom fields aren't encrypted, just carry on as usual
|
||||
*/
|
||||
} else {
|
||||
|
||||
if ((array_key_exists($field->db_column, $this->update_array)) && ($asset->{$field->db_column} != $this->update_array[$field->db_column])) {
|
||||
|
||||
// Check if this is an array, and if so, flatten it
|
||||
if (is_array($this->update_array[$field->db_column])) {
|
||||
$asset->{$field->db_column} = implode(', ', $this->update_array[$field->db_column]);
|
||||
} else {
|
||||
|
||||
|
||||
if ((array_key_exists($field->db_column, $this->update_array)) && ($asset->{$field->db_column} != $this->update_array[$field->db_column])) {
|
||||
|
||||
// Check if this is an array, and if so, flatten it
|
||||
if (is_array($this->update_array[$field->db_column])) {
|
||||
$asset->{$field->db_column} = implode(', ', $this->update_array[$field->db_column]);
|
||||
} else {
|
||||
$asset->{$field->db_column} = $this->update_array[$field->db_column];
|
||||
}
|
||||
}
|
||||
$asset->{$field->db_column} = $this->update_array[$field->db_column];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // endforeach
|
||||
} // end custom field check
|
||||
} // end custom fields handler
|
||||
|
||||
} // endforeach
|
||||
}
|
||||
|
||||
|
||||
// Check if it passes validation, and then try to save
|
||||
|
|
|
@ -266,7 +266,7 @@ class Asset extends Depreciable
|
|||
|
||||
/**
|
||||
* Determines if an asset is available for checkout.
|
||||
* This checks to see if the it's checked out to an invalid (deleted) user
|
||||
* This checks to see if it's checked out to an invalid (deleted) user
|
||||
* OR if the assigned_to and deleted_at fields on the asset are empty AND
|
||||
* that the status is deployable
|
||||
*
|
||||
|
@ -753,7 +753,7 @@ class Asset extends Depreciable
|
|||
}
|
||||
|
||||
/**
|
||||
* Establishes the asset -> status relationship
|
||||
* Establishes the asset -> license seats relationship
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use App\Models\Asset;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
@ -50,7 +51,7 @@ class DenormalizedEolAndAddColumnForExplicitDateToAssets extends Migration
|
|||
->whereNotNull('model_id')
|
||||
->join('models', 'assets.model_id', '=', 'models.id')
|
||||
->update([
|
||||
'asset_eol_date' => DB::raw('DATE_ADD(purchase_date, INTERVAL ' . DB::getTablePrefix() . 'models.eol MONTH)')
|
||||
'asset_eol_date' => $this->eolUpdateExpression(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -66,4 +67,22 @@ class DenormalizedEolAndAddColumnForExplicitDateToAssets extends Migration
|
|||
$table->dropColumn('eol_explicit');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the correct database expression for either
|
||||
* mysql, postgres, or sqlite depending on the driver being used.
|
||||
*/
|
||||
private function eolUpdateExpression(): Expression
|
||||
{
|
||||
if (DB::getDriverName() === 'sqlite') {
|
||||
return DB::raw("DATE(purchase_date, '+' || (SELECT eol FROM " . DB::getTablePrefix() . "models WHERE models.id = assets.model_id) || ' months')");
|
||||
}
|
||||
|
||||
if (DB::getDriverName() === 'pgsql') {
|
||||
return DB::raw("date(purchase_date + interval '1 month' * (SELECT eol FROM " . DB::getTablePrefix() . "models WHERE models.id = assets.model_id))");
|
||||
}
|
||||
|
||||
// Default to MySQL's method
|
||||
return DB::raw('DATE_ADD(purchase_date, INTERVAL ' . DB::getTablePrefix() . 'models.eol MONTH)');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ return [
|
|||
'ad_append_domain_help' => 'User isn\'t required to write "username@domain.local", they can just type "username".',
|
||||
'admin_cc_email' => 'CC Email',
|
||||
'admin_cc_email_help' => 'If you would like to send a copy of checkin/checkout emails that are sent to users to an additional email account, enter it here. Otherwise leave this field blank.',
|
||||
'admin_settings' => 'Admin Settings',
|
||||
'is_ad' => 'This is an Active Directory server',
|
||||
'alerts' => 'Alerts',
|
||||
'alert_title' => 'Update Notification Settings',
|
||||
|
|
|
@ -21,6 +21,7 @@ return array(
|
|||
'manager' => 'Manager',
|
||||
'managed_locations' => 'Managed Locations',
|
||||
'name' => 'Name',
|
||||
'nogroup' => 'No groups have been created yet. To add one, visit: ',
|
||||
'notes' => 'Notes',
|
||||
'password_confirm' => 'Confirm Password',
|
||||
'password' => 'Password',
|
||||
|
|
|
@ -491,5 +491,6 @@ return [
|
|||
'upload_error' => 'Error uploading file. Please check that there are no empty rows and that no column names are duplicated.',
|
||||
'copy_to_clipboard' => 'Copy to Clipboard',
|
||||
'copied' => 'Copied!',
|
||||
'status_compatibility' => 'If assets are already assigned, they cannot be changed to a non-deployable status type and this value change will be skipped.',
|
||||
|
||||
];
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<tr>
|
||||
<td></td>
|
||||
<td>{{ trans('admin/hardware/table.id') }}</td>
|
||||
<td>{{ trans('admin/hardware/table.name') }}</td>
|
||||
<td>{{ trans('admin/hardware/form.name') }}</td>
|
||||
<td>{{ trans('admin/hardware/table.location')}}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
|
@ -19,18 +19,22 @@
|
|||
|
||||
<p>{{ trans('admin/hardware/form.bulk_update_help') }}</p>
|
||||
|
||||
<div class="callout callout-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i> {{ trans_choice('admin/hardware/form.bulk_update_warn', count($assets), ['asset_count' => count($assets)]) }}
|
||||
@if (count($models) > 0)
|
||||
{{ trans_choice('admin/hardware/form.bulk_update_with_custom_field', count($models), ['asset_model_count' => count($models)]) }}
|
||||
@endif
|
||||
</div>
|
||||
|
||||
|
||||
<form class="form-horizontal" method="post" action="{{ route('hardware/bulksave') }}" autocomplete="off" role="form">
|
||||
{{ csrf_field() }}
|
||||
|
||||
<div class="box box-default">
|
||||
<div class="box-body">
|
||||
|
||||
<div class="callout callout-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i> {{ trans_choice('admin/hardware/form.bulk_update_warn', count($assets), ['asset_count' => count($assets)]) }}
|
||||
|
||||
@if (count($models) > 0)
|
||||
{{ trans_choice('admin/hardware/form.bulk_update_with_custom_field', count($models), ['asset_model_count' => count($models)]) }}
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<!-- Purchase Date -->
|
||||
<div class="form-group {{ $errors->has('purchase_date') ? ' has-error' : '' }}">
|
||||
<label for="purchase_date" class="col-md-3 control-label">{{ trans('admin/hardware/form.date') }}</label>
|
||||
|
@ -76,6 +80,7 @@
|
|||
</label>
|
||||
<div class="col-md-7">
|
||||
{{ Form::select('status_id', $statuslabel_list , old('status_id'), array('class'=>'select2', 'style'=>'width:100%', 'aria-label'=>'status_id')) }}
|
||||
<p class="help-block">{{ trans('general.status_compatibility') }}</p>
|
||||
{!! $errors->first('status_id', '<span class="alert-msg" aria-hidden="true"><i class="fas fa-times" aria-hidden="true"></i> :message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -189,8 +194,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
@include("models/custom_fields_form_bulk_edit",["models" => $models])
|
||||
|
||||
@include("models/custom_fields_form_bulk_edit",["models" => $models])
|
||||
|
||||
@foreach ($assets as $key => $value)
|
||||
<input type="hidden" name="ids[{{ $value }}]" value="1">
|
||||
@endforeach
|
||||
|
|
|
@ -1206,15 +1206,15 @@
|
|||
<thead>
|
||||
<tr>
|
||||
<th data-visible="true" data-field="icon" style="width: 40px;" class="hidden-xs" data-formatter="iconFormatter">{{ trans('admin/hardware/table.icon') }}</th>
|
||||
<th class="col-sm-2" data-visible="true" data-field="action_date" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
|
||||
<th class="col-sm-1" data-visible="true" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
||||
<th class="col-sm-1" data-visible="true" data-field="action_type">{{ trans('general.action') }}</th>
|
||||
<th class="col-sm-2" data-visible="true" data-field="item" data-formatter="polymorphicItemFormatter">{{ trans('general.item') }}</th>
|
||||
<th class="col-sm-2" data-visible="true" data-field="target" data-formatter="polymorphicItemFormatter">{{ trans('general.target') }}</th>
|
||||
<th class="col-sm-2" data-field="note">{{ trans('general.notes') }}</th>
|
||||
<th class="col-md-3" data-field="signature_file" data-visible="false" data-formatter="imageFormatter">{{ trans('general.signature') }}</th>
|
||||
<th class="col-md-3" data-visible="false" data-field="file" data-visible="false" data-formatter="fileUploadFormatter">{{ trans('general.download') }}</th>
|
||||
<th class="col-sm-2" data-field="log_meta" data-visible="true" data-formatter="changeLogFormatter">{{ trans('admin/hardware/table.changed')}}</th>
|
||||
<th data-visible="true" data-field="action_date" data-formatter="dateDisplayFormatter">{{ trans('general.date') }}</th>
|
||||
<th data-visible="true" data-field="admin" data-formatter="usersLinkObjFormatter">{{ trans('general.admin') }}</th>
|
||||
<th data-visible="true" data-field="action_type">{{ trans('general.action') }}</th>
|
||||
<th data-visible="true" data-field="item" data-formatter="polymorphicItemFormatter">{{ trans('general.item') }}</th>
|
||||
<th data-visible="true" data-field="target" data-formatter="polymorphicItemFormatter">{{ trans('general.target') }}</th>
|
||||
<th data-field="note">{{ trans('general.notes') }}</th>
|
||||
<th data-field="signature_file" data-visible="false" data-formatter="imageFormatter">{{ trans('general.signature') }}</th>
|
||||
<th data-visible="false" data-field="file" data-visible="false" data-formatter="fileUploadFormatter">{{ trans('general.download') }}</th>
|
||||
<th data-field="log_meta" data-visible="true" data-formatter="changeLogFormatter">{{ trans('admin/hardware/table.changed')}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
|
|
|
@ -553,7 +553,7 @@
|
|||
</div>
|
||||
@endif
|
||||
@else
|
||||
<p>No groups have been created yet. Visit <code>Admin Settings > Permission Groups</code> to add one.</p>
|
||||
<p>{{ trans('admin/users/table.nogroup') }} <code>{{ trans('admin/settings/general.admin_settings') }} <i class="fa fa-cogs"></i> > {{ trans('general.groups') }} <i class="fas fa-user-friends"></i></code> </p>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
|
|
@ -638,13 +638,14 @@
|
|||
|
||||
</div>
|
||||
@endif
|
||||
@if($user->getUserTotalCost()->total_user_cost > 0)
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-3">
|
||||
{{ trans('admin/users/table.total_assets_cost') }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{Helper::formatCurrencyOutput($user->getUserTotalCost()->total_user_cost)}}
|
||||
|
||||
<a id="optional_info" class="text-primary">
|
||||
<i class="fa fa-caret-right fa-2x" id="optional_info_icon"></i>
|
||||
<strong>{{ trans('admin/hardware/form.optional_infos') }}</strong>
|
||||
|
@ -658,13 +659,10 @@
|
|||
{{trans('general.accessories').': '.Helper::formatCurrencyOutput($user->getUserTotalCost()->accessory_cost)}}<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!--/.row-->
|
||||
@endif
|
||||
</div> <!--/end striped container-->
|
||||
</div> <!-- end col-md-9 -->
|
||||
|
||||
|
||||
|
||||
</div> <!--/.row-->
|
||||
</div><!-- /.tab-pane -->
|
||||
|
||||
|
|
Loading…
Reference in a new issue