diff --git a/app/Http/Controllers/Assets/BulkAssetsController.php b/app/Http/Controllers/Assets/BulkAssetsController.php index 8419098936..a744db5788 100644 --- a/app/Http/Controllers/Assets/BulkAssetsController.php +++ b/app/Http/Controllers/Assets/BulkAssetsController.php @@ -14,6 +14,7 @@ use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Session; use App\Http\Requests\AssetCheckoutRequest; +use App\Models\CustomField; class BulkAssetsController extends Controller { @@ -31,7 +32,7 @@ class BulkAssetsController extends Controller public function edit(Request $request) { $this->authorize('view', Asset::class); - + if (! $request->filled('ids')) { return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected')); } @@ -41,6 +42,17 @@ class BulkAssetsController extends Controller 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'); + $modelNames = []; + foreach($models as $model) { + $modelNames[] = $model->model->name; + } if ($request->filled('bulk_actions')) { switch ($request->input('bulk_actions')) { @@ -74,7 +86,9 @@ class BulkAssetsController extends Controller $this->authorize('update', Asset::class); return view('hardware/bulk') ->with('assets', $asset_ids) - ->with('statuslabel_list', Helper::statusLabelList()); + ->with('statuslabel_list', Helper::statusLabelList()) + ->with('models', $models->pluck(['model'])) + ->with('modelNames', $modelNames); } } @@ -92,6 +106,7 @@ class BulkAssetsController extends Controller public function update(Request $request) { $this->authorize('update', Asset::class); + $error_bag = []; // Get the back url from the session and then destroy the session $bulk_back_url = route('hardware.index'); @@ -100,12 +115,21 @@ class BulkAssetsController extends Controller } - if (! $request->filled('ids') || count($request->input('ids')) <= 0) { + $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) { 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; + } if (($request->filled('purchase_date')) || ($request->filled('expected_checkin')) || ($request->filled('purchase_cost')) @@ -121,6 +145,7 @@ class BulkAssetsController extends Controller || ($request->filled('null_purchase_date')) || ($request->filled('null_expected_checkin_date')) || ($request->filled('null_next_audit_date')) + || ($request->anyFilled($custom_field_columns)) ) { foreach ($assets as $assetId) { @@ -136,6 +161,9 @@ class BulkAssetsController extends Controller ->conditionallyAddItem('supplier_id') ->conditionallyAddItem('warranty_months') ->conditionallyAddItem('next_audit_date'); + foreach ($custom_field_columns as $key => $custom_field_column) { + $this->conditionallyAddItem($custom_field_column); + } if ($request->input('null_purchase_date')=='1') { $this->update_array['purchase_date'] = null; @@ -168,11 +196,11 @@ class BulkAssetsController extends Controller } $changed = []; - $asset = Asset::where('id' ,$assetId)->get(); + $assetCollection = Asset::where('id' ,$assetId)->get(); foreach ($this->update_array as $key => $value) { - if ($this->update_array[$key] != $asset->toArray()[0][$key]) { - $changed[$key]['old'] = $asset->toArray()[0][$key]; + if ($this->update_array[$key] != $assetCollection->toArray()[0][$key]) { + $changed[$key]['old'] = $assetCollection->toArray()[0][$key]; $changed[$key]['new'] = $this->update_array[$key]; } } @@ -184,17 +212,47 @@ class BulkAssetsController extends Controller $logAction->user_id = Auth::id(); $logAction->log_meta = json_encode($changed); $logAction->logaction('update'); - - DB::table('assets') - ->where('id', $assetId) - ->update($this->update_array); - } // endforeach - + + if($custom_fields_present) { + $asset = Asset::find($assetId); + $assetCustomFields = $asset->model()->first()->fieldset; + if($assetCustomFields && $assetCustomFields->fields) { + foreach ($assetCustomFields->fields as $field) { + if (array_key_exists($field->db_column, $this->update_array)) { + $asset->{$field->db_column} = $this->update_array[$field->db_column]; + $saved = $asset->save(); + if(!$saved) { + $error_bag[] = $asset->getErrors(); + } + continue; + } else { + $array = $this->update_array; + array_except($array, $field->db_column); + $asset->save($array); + } + if (!$asset->save()) { + $error_bag[] = $asset->getErrors(); + } + } + } + } else { + Asset::find($assetId)->update($this->update_array); + } + } + if(!empty($error_bag)) { + $errors = []; + //find the customfield name from the name of the messagebag items + foreach ($error_bag as $key => $bag) { + foreach($bag->keys() as $key => $value) { + CustomField::where('db_column', $value)->get()->map(function($item) use (&$errors) { + $errors[] = $item->name; + }); + } + } + return redirect($bulk_back_url)->with('bulk_errors', array_unique($errors)); + } return redirect($bulk_back_url)->with('success', trans('admin/hardware/message.update.success')); - - } - // no values given, nothing to update return redirect($bulk_back_url)->with('warning', trans('admin/hardware/message.update.nothing_updated')); } diff --git a/app/Models/AssetModel.php b/app/Models/AssetModel.php index e4e5ac720a..aed1b925ef 100755 --- a/app/Models/AssetModel.php +++ b/app/Models/AssetModel.php @@ -150,6 +150,11 @@ class AssetModel extends SnipeModel { return $this->belongsTo(\App\Models\CustomFieldset::class, 'fieldset_id'); } + + public function customFields() + { + return $this->fieldset()->first()->fields(); + } /** * Establishes the model -> custom field default values relationship diff --git a/app/Models/CustomField.php b/app/Models/CustomField.php index e7fddd1aad..c98dbe637c 100644 --- a/app/Models/CustomField.php +++ b/app/Models/CustomField.php @@ -9,7 +9,6 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Validation\Rule; use Schema; use Watson\Validating\ValidatingTrait; - class CustomField extends Model { use HasFactory; @@ -182,6 +181,11 @@ class CustomField extends Model { return $this->belongsToMany(\App\Models\CustomFieldset::class); } + + public function assetModels() + { + return $this->fieldset()->with('models')->get()->pluck('models')->flatten()->unique('id'); + } /** * Establishes the customfield -> admin user relationship diff --git a/resources/lang/en/admin/hardware/form.php b/resources/lang/en/admin/hardware/form.php index 6bcb884bab..ef877c8377 100644 --- a/resources/lang/en/admin/hardware/form.php +++ b/resources/lang/en/admin/hardware/form.php @@ -10,6 +10,9 @@ return [ 'bulk_update' => 'Bulk Update Assets', 'bulk_update_help' => 'This form allows you to update multiple assets at once. Only fill in the fields you need to change. Any fields left blank will remain unchanged. ', 'bulk_update_warn' => 'You are about to edit the properties of a single asset.|You are about to edit the properties of :asset_count assets.', + 'bulk_update_with_custom_field' => 'Note the assets are :asset_model_count different types of models.', + 'bulk_update_model_prefix' => 'On Models', + 'bulk_update_custom_field_unique' => 'This is a unique field and can not be bulk edited.', 'checkedout_to' => 'Checked Out To', 'checkout_date' => 'Checkout Date', 'checkin_date' => 'Checkin Date', diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index 632a0a590f..9a78092179 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -365,6 +365,7 @@ return [ 'licenses_count' => 'Licenses Count', 'notification_error' => 'Error:', 'notification_error_hint' => 'Please check the form below for errors', + 'notification_bulk_error_hint' => 'The following fields had validation errors and were not edited:', 'notification_success' => 'Success:', 'notification_warning' => 'Warning:', 'notification_info' => 'Info:', diff --git a/resources/views/hardware/bulk.blade.php b/resources/views/hardware/bulk.blade.php index c2fe105a2d..667126ec99 100755 --- a/resources/views/hardware/bulk.blade.php +++ b/resources/views/hardware/bulk.blade.php @@ -21,6 +21,9 @@
{{ 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
@@ -182,6 +185,8 @@ + @include("models/custom_fields_form_bulk_edit",["models" => $models]) + @foreach ($assets as $key => $value) @endforeach diff --git a/resources/views/models/custom_fields_form_bulk_edit.blade.php b/resources/views/models/custom_fields_form_bulk_edit.blade.php new file mode 100644 index 0000000000..e974c3f6eb --- /dev/null +++ b/resources/views/models/custom_fields_form_bulk_edit.blade.php @@ -0,0 +1,119 @@ +@php +//set array up before loop so it doesn't get wiped at every iteration + $fields = []; +@endphp +@foreach($models as $model) +@if (($model) && ($model->fieldset)) + @foreach($model->fieldset->fields AS $field) + @php + //prevents some duplicate queries - open to a better way of skipping dupes in output + //its ugly, but if we'd rather deal with duplicate queries we can get rid of this. + if (in_array($field->db_column_name(), $fields)) { + $duplicate = true; + continue; + } else { + $duplicate = false; + } + $fields[] = $field->db_column_name(); + @endphp + +
+ +
+ + @if ($field->element!='text') + + @if ($field->element=='listbox') + {{ Form::select($field->db_column_name(), $field->formatFieldValuesAsArray(), + Request::old($field->db_column_name(),(isset($item) ? Helper::gracefulDecrypt($field, htmlspecialchars($item->{$field->db_column_name()}, ENT_QUOTES)) : $field->defaultValue($model->id))), ['class'=>'format select2 form-control']) }} + + @elseif ($field->element=='textarea') + @if($field->is_unique) + + @endif + @if(!$field->is_unique) + + @endif + @elseif ($field->element=='checkbox') + + @foreach ($field->formatFieldValuesAsArray() as $key => $value) +
+ +
+ @endforeach + @elseif ($field->element=='radio') + @foreach ($field->formatFieldValuesAsArray() as $value) +
+ +
+ @endforeach + + @endif + + @else + + + @if ($field->format=='DATE') + +
+
+ + +
+
+ + + @else + + @if (($field->field_encrypted=='0') || (Gate::allows('admin'))) + @if ($field->is_unique) + + @endif + @if(!$field->is_unique) + + @endif + @else + + @endif + + @endif + + @endif + + @if ($field->help_text!='') +

{{ $field->help_text }}

+ @endif + +

{{ trans('admin/hardware/form.bulk_update_model_prefix') }}: + {{$field->assetModels()->pluck('name')->intersect($modelNames)->implode(', ')}} +

+ + + + + first($field->db_column_name()); + if ($errormessage) { + $errormessage=preg_replace('/ snipeit /', '', $errormessage); + print(''); + } + ?> +
+ + @if ($field->field_encrypted) +
+ +
+ @endif + + +
+ @endforeach +@endif + @endforeach diff --git a/resources/views/notifications.blade.php b/resources/views/notifications.blade.php index 0935c28582..ca7945d563 100755 --- a/resources/views/notifications.blade.php +++ b/resources/views/notifications.blade.php @@ -115,6 +115,23 @@ @endif +@if ($messages = Session::get('bulk_errors')) +
+
+ + + {{ trans('general.notification_error') }} + {{ trans('general.notification_bulk_error_hint') }} + @foreach($messages as $message) +
    +
  • {{ $message }}
  • +
+ @endforeach +
+
+@endif + + @if ($message = Session::get('warning'))