diff --git a/app/Http/Controllers/Assets/AssetCheckinController.php b/app/Http/Controllers/Assets/AssetCheckinController.php index f84a468a60..4452bfa51d 100644 --- a/app/Http/Controllers/Assets/AssetCheckinController.php +++ b/app/Http/Controllers/Assets/AssetCheckinController.php @@ -27,18 +27,12 @@ class AssetCheckinController extends Controller * @param string $backto * @since [v1.0] */ - public function create($assetId, $backto = null) : View | RedirectResponse + public function create(Asset $asset, $backto = null) : View | RedirectResponse { - // Check if the asset exists - if (is_null($asset = Asset::find($assetId))) { - // Redirect to the asset management page with error - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); - } $this->authorize('checkin', $asset); // This asset is already checked in, redirect - if (is_null($asset->assignedTo)) { return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in')); } @@ -47,7 +41,11 @@ class AssetCheckinController extends Controller return redirect()->route('hardware.show', $asset->id)->with('error', trans('admin/hardware/general.model_invalid_fix')); } - return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto)->with('table_name', 'Assets'); + return view('hardware/checkin', compact('asset')) + ->with('item', $asset) + ->with('statusLabel_list', Helper::statusLabelList()) + ->with('backto', $backto) + ->with('table_name', 'Assets'); } /** @@ -91,6 +89,9 @@ class AssetCheckinController extends Controller $asset->status_id = e($request->get('status_id')); } + // Add any custom fields that should be included in the checkout + $asset->customFieldsForCheckinCheckout('display_checkin'); + $this->migrateLegacyLocations($asset); $asset->location_id = $asset->rtd_location_id; @@ -128,6 +129,9 @@ class AssetCheckinController extends Controller session()->put('redirect_option', $request->get('redirect_option')); + // Add any custom fields that should be included in the checkout + $asset->customFieldsForCheckinCheckout('display_checkin'); + if ($asset->save()) { event(new CheckoutableCheckedIn($asset, $target, auth()->user(), $request->input('note'), $checkin_at, $originalValues)); diff --git a/app/Http/Controllers/Assets/AssetCheckoutController.php b/app/Http/Controllers/Assets/AssetCheckoutController.php index 8710240293..4d8c9ffda2 100644 --- a/app/Http/Controllers/Assets/AssetCheckoutController.php +++ b/app/Http/Controllers/Assets/AssetCheckoutController.php @@ -39,7 +39,8 @@ class AssetCheckoutController extends Controller if ($asset->availableForCheckout()) { return view('hardware/checkout', compact('asset')) ->with('statusLabel_list', Helper::deployableStatusLabelList()) - ->with('table_name', 'Assets'); + ->with('table_name', 'Assets') + ->with('item', $asset); } return redirect()->route('hardware.index') @@ -88,6 +89,7 @@ class AssetCheckoutController extends Controller $asset->status_id = $request->get('status_id'); } + if(!empty($asset->licenseseats->all())){ if(request('checkout_to_type') == 'user') { foreach ($asset->licenseseats as $seat){ @@ -97,23 +99,26 @@ class AssetCheckoutController extends Controller } } + // Add any custom fields that should be included in the checkout + $asset->customFieldsForCheckinCheckout('display_checkout'); + $settings = \App\Models\Setting::getSettings(); // We have to check whether $target->company_id is null here since locations don't have a company yet if (($settings->full_multiple_companies_support) && ((!is_null($target->company_id)) && (!is_null($asset->company_id)))) { if ($target->company_id != $asset->company_id){ - return redirect()->to("hardware/$assetId/checkout")->with('error', trans('general.error_user_company')); + return redirect()->route('hardware.checkout.create', $asset)->with('error', trans('general.error_user_company')); } } - session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]); + session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]); if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->get('note'), $request->get('name'))) { return redirect()->to(Helper::getRedirectOption($request, $asset->id, 'Assets')) ->with('success', trans('admin/hardware/message.checkout.success')); } // Redirect to the asset management page with error - return redirect()->to("hardware/$assetId/checkout")->with('error', trans('admin/hardware/message.checkout.error').$asset->getErrors()); + return redirect()->route("hardware.checkout.create", $asset)->with('error', trans('admin/hardware/message.checkout.error').$asset->getErrors()); } catch (ModelNotFoundException $e) { return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($asset->getErrors()); } catch (CheckoutNotAllowed $e) { diff --git a/app/Http/Controllers/CustomFieldsController.php b/app/Http/Controllers/CustomFieldsController.php index 1a5fa80ffa..7c0bdefa29 100644 --- a/app/Http/Controllers/CustomFieldsController.php +++ b/app/Http/Controllers/CustomFieldsController.php @@ -104,6 +104,8 @@ class CustomFieldsController extends Controller "auto_add_to_fieldsets" => $request->get("auto_add_to_fieldsets", 0), "show_in_listview" => $request->get("show_in_listview", 0), "show_in_requestable_list" => $request->get("show_in_requestable_list", 0), + "display_checkin" => $request->get("display_checkin", 0), + "display_checkout" => $request->get("display_checkout", 0), "created_by" => auth()->id() ]); @@ -246,6 +248,8 @@ class CustomFieldsController extends Controller $field->auto_add_to_fieldsets = $request->get("auto_add_to_fieldsets", 0); $field->show_in_listview = $request->get("show_in_listview", 0); $field->show_in_requestable_list = $request->get("show_in_requestable_list", 0); + $field->display_checkin = $request->get("display_checkin", 0); + $field->display_checkout = $request->get("display_checkout", 0); if ($request->get('format') == 'CUSTOM REGEX') { $field->format = e($request->get('custom_format')); diff --git a/app/Models/Asset.php b/app/Models/Asset.php index 0d4606e4b4..c571578172 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -413,6 +413,17 @@ class Asset extends Depreciable return $this->rules; } + public function customFieldsForCheckinCheckout($checkin_checkout) { + // Check to see if any of the custom fields were included on the form and if they have any values + if (($this->model) && ($this->model->fieldset) && ($this->model->fieldset->fields)) { + foreach ($this->model->fieldset->fields as $field) { + if (($field->{$checkin_checkout} == 1) && (request()->has($field->db_column))){ + $this->{$field->db_column} = request()->get($field->db_column); + } + } + } + } + /** * Establishes the asset -> depreciation relationship diff --git a/app/Models/Loggable.php b/app/Models/Loggable.php index 72a7a7f262..bd12050dc7 100644 --- a/app/Models/Loggable.php +++ b/app/Models/Loggable.php @@ -34,7 +34,11 @@ trait Loggable */ public function logCheckout($note, $target, $action_date = null, $originalValues = []) { + $log = new Actionlog; + + $fields_array = []; + $log = $this->determineLogItemType($log); if (auth()->user()) { $log->created_by = auth()->id(); @@ -55,6 +59,7 @@ trait Loggable $log->target_type = get_class($target); $log->target_id = $target->id; + // Figure out what the target is if ($log->target_type == Location::class) { $log->location_id = $target->id; @@ -64,6 +69,21 @@ trait Loggable $log->location_id = $target->location_id; } + if (static::class == Asset::class) { + if ($asset = Asset::find($log->item_id)) { + + // add the custom fields that were changed + if ($asset->model->fieldset) { + $fields_array = []; + foreach ($asset->model->fieldset->fields as $field) { + if ($field->display_checkout == 1) { + $fields_array[$field->db_column] = $asset->{$field->db_column}; + } + } + } + } + } + $log->note = $note; $log->action_date = $action_date; @@ -72,7 +92,10 @@ trait Loggable } $changed = []; - $originalValues = array_intersect_key($originalValues, array_flip(['action_date','name','status_id','location_id','expected_checkin'])); + $array_to_flip = array_keys($fields_array); + $array_to_flip = array_merge($array_to_flip, ['action_date','name','status_id','location_id','expected_checkin']); + $originalValues = array_intersect_key($originalValues, array_flip($array_to_flip)); + foreach ($originalValues as $key => $value) { if ($key == 'action_date' && $value != $action_date) { @@ -119,6 +142,8 @@ trait Loggable { $log = new Actionlog; + $fields_array = []; + if($target != null){ $log->target_type = get_class($target); $log->target_id = $target->id; @@ -135,6 +160,16 @@ trait Loggable if (static::class == Asset::class) { if ($asset = Asset::find($log->item_id)) { $asset->increment('checkin_counter', 1); + + // add the custom fields that were changed + if ($asset->model->fieldset) { + $fields_array = []; + foreach ($asset->model->fieldset->fields as $field) { + if ($field->display_checkin == 1) { + $fields_array[$field->db_column] = $asset->{$field->db_column}; + } + } + } } } } @@ -152,9 +187,14 @@ trait Loggable } $changed = []; - $originalValues = array_intersect_key($originalValues, array_flip(['action_date','name','status_id','location_id','rtd_location_id','expected_checkin'])); + + $array_to_flip = array_keys($fields_array); + $array_to_flip = array_merge($array_to_flip, ['action_date','name','status_id','location_id','expected_checkin']); + + $originalValues = array_intersect_key($originalValues, array_flip($array_to_flip)); foreach ($originalValues as $key => $value) { + if ($key == 'action_date' && $value != $action_date) { $changed[$key]['old'] = $value; $changed[$key]['new'] = is_string($action_date) ? $action_date : $action_date->format('Y-m-d H:i:s'); diff --git a/database/migrations/2025_02_22_144518_add_checkin_checkout_to_customfields.php b/database/migrations/2025_02_22_144518_add_checkin_checkout_to_customfields.php new file mode 100644 index 0000000000..28aceee43b --- /dev/null +++ b/database/migrations/2025_02_22_144518_add_checkin_checkout_to_customfields.php @@ -0,0 +1,30 @@ +boolean('display_checkin')->default(0); + $table->boolean('display_checkout')->default(0); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('custom_fields', function (Blueprint $table) { + $table->dropColumn('display_checkin'); + $table->dropColumn('display_checkout'); + }); + } +}; diff --git a/resources/lang/en-US/admin/custom_fields/general.php b/resources/lang/en-US/admin/custom_fields/general.php index e3c21d1f0c..b231fab1d1 100644 --- a/resources/lang/en-US/admin/custom_fields/general.php +++ b/resources/lang/en-US/admin/custom_fields/general.php @@ -57,5 +57,7 @@ return [ 'show_in_requestable_list_short' => 'Show in requestable assets list', 'show_in_requestable_list' => 'Show value in requestable assets list. Encrypted fields will not be shown', 'encrypted_options' => 'This field is encrypted, so some display options will not be available.', + 'display_checkin' => 'Display in checkin forms', + 'display_checkout' => 'Display in checkout forms', ]; diff --git a/resources/views/custom_fields/fields/edit.blade.php b/resources/views/custom_fields/fields/edit.blade.php index b0da258520..9b8449eb74 100644 --- a/resources/views/custom_fields/fields/edit.blade.php +++ b/resources/views/custom_fields/fields/edit.blade.php @@ -157,7 +157,7 @@ -