From 638a7b2d910cc22d298c28620634aadbffbf9d9a Mon Sep 17 00:00:00 2001 From: Daniel Meltzer Date: Mon, 16 Jul 2018 19:44:03 -0500 Subject: [PATCH] Assetcontroller cleanup (#5858) * Extract method/cleanup * Remove apiStore method that is unusued since api controllers. * Use proper model exception * Remove old user importer. This is now supported by the general importer framework. * Refactor AssetsController methods. This is a giant diff without many functional changes, mostly cosmetic. I've pulled a number of methods out of assetscontroller, preferring instead to create some more targetted controllers for related actions. I think this cleans up the file some, and suggests some places for future targetted improvement. Fix weird missing things. * Fix Unit test failing after date changes. * Pass valid string to be translated. * Some method cleanup for codacy. * Extract trait for common checkout uses and codacy fixes. --- app/Exceptions/CheckoutNotAllowed.php | 11 +- .../Controllers/AccessoriesController.php | 4 +- .../Controllers/AssetCheckinController.php | 104 +++ .../Controllers/AssetCheckoutController.php | 96 +++ app/Http/Controllers/AssetFilesController.php | 125 ++++ .../Controllers/AssetModelsController.php | 40 -- app/Http/Controllers/AssetsController.php | 646 ++---------------- app/Http/Controllers/BulkAssetsController.php | 249 +++++++ app/Http/Controllers/CheckInOutRequest.php | 56 ++ app/Http/Controllers/LocationsController.php | 36 - .../Controllers/StatuslabelsController.php | 30 - app/Http/Controllers/SuppliersController.php | 17 - app/Http/Controllers/UsersController.php | 226 +----- app/Importer/Importer.php | 47 +- resources/views/hardware/view.blade.php | 2 +- resources/views/users/import.blade.php | 109 --- resources/views/users/index.blade.php | 1 - routes/web/hardware.php | 26 +- routes/web/users.php | 2 - tests/unit/AssetMaintenanceTest.php | 4 +- 20 files changed, 764 insertions(+), 1067 deletions(-) create mode 100644 app/Http/Controllers/AssetCheckinController.php create mode 100644 app/Http/Controllers/AssetCheckoutController.php create mode 100644 app/Http/Controllers/AssetFilesController.php create mode 100644 app/Http/Controllers/BulkAssetsController.php create mode 100644 app/Http/Controllers/CheckInOutRequest.php delete mode 100644 resources/views/users/import.blade.php diff --git a/app/Exceptions/CheckoutNotAllowed.php b/app/Exceptions/CheckoutNotAllowed.php index dc80a44f4e..91bf2b865b 100644 --- a/app/Exceptions/CheckoutNotAllowed.php +++ b/app/Exceptions/CheckoutNotAllowed.php @@ -5,8 +5,17 @@ namespace App\Exceptions; use Exception; class CheckoutNotAllowed extends Exception { + + private $errorMessage; + + function __construct($errorMessage = null) + { + $this->errorMessage = $errorMessage; + + parent::__construct($errorMessage); + } public function __toString() { - return "A checkout is not allowed under these circumstances"; + return is_null($this->errorMessage) ? "A checkout is not allowed under these circumstances" : $this->errorMessage; } } diff --git a/app/Http/Controllers/AccessoriesController.php b/app/Http/Controllers/AccessoriesController.php index 50723d47db..c98b739ab0 100755 --- a/app/Http/Controllers/AccessoriesController.php +++ b/app/Http/Controllers/AccessoriesController.php @@ -166,10 +166,8 @@ class AccessoriesController extends Controller $accessory->supplier_id = request('supplier_id'); if ($request->hasFile('image')) { - + if (!config('app.lock_passwords')) { - - $image = $request->file('image'); $ext = $image->getClientOriginalExtension(); $file_name = "accessory-".str_random(18).'.'.$ext; diff --git a/app/Http/Controllers/AssetCheckinController.php b/app/Http/Controllers/AssetCheckinController.php new file mode 100644 index 0000000000..e03ea8b529 --- /dev/null +++ b/app/Http/Controllers/AssetCheckinController.php @@ -0,0 +1,104 @@ +] + * @param int $assetId + * @param string $backto + * @since [v1.0] + * @return View + */ + public function create($assetId, $backto = null) + { + // 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); + return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto); + } + + /** + * Validate and process the form data to check an asset back into inventory. + * + * @author [A. Gianotto] [] + * @param AssetCheckinRequest $request + * @param int $assetId + * @param null $backto + * @return Redirect + * @since [v1.0] + */ + public function store(AssetCheckinRequest $request, $assetId = null, $backto = null) + { + // 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); + + if ($asset->assignedType() == Asset::USER) { + $user = $asset->assignedTo; + } + if (is_null($target = $asset->assignedTo)) { + return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in')); + } + + $asset->expected_checkin = null; + $asset->last_checkout = null; + $asset->assigned_to = null; + $asset->assignedTo()->disassociate($asset); + $asset->assigned_type = null; + $asset->accepted = null; + $asset->name = e($request->get('name')); + + if ($request->has('status_id')) { + $asset->status_id = e($request->get('status_id')); + } + + $asset->location_id = $asset->rtd_location_id; + + if ($request->has('location_id')) { + $asset->location_id = e($request->get('location_id')); + } + + // Was the asset updated? + if ($asset->save()) { + $logaction = $asset->logCheckin($target, e(request('note'))); + + $data['log_id'] = $logaction->id; + $data['first_name'] = get_class($target) == User::class ? $target->first_name : ''; + $data['last_name'] = get_class($target) == User::class ? $target->last_name : ''; + $data['item_name'] = $asset->present()->name(); + $data['checkin_date'] = $logaction->created_at; + $data['item_tag'] = $asset->asset_tag; + $data['item_serial'] = $asset->serial; + $data['note'] = $logaction->note; + $data['manufacturer_name'] = $asset->model->manufacturer->name; + $data['model_name'] = $asset->model->name; + $data['model_number'] = $asset->model->model_number; + + if ($backto=='user') { + return redirect()->route("users.show", $user->id)->with('success', trans('admin/hardware/message.checkin.success')); + } + return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success')); + } + // Redirect to the asset management page with error + return redirect()->route("hardware.index")->with('error', trans('admin/hardware/message.checkin.error')); + } +} diff --git a/app/Http/Controllers/AssetCheckoutController.php b/app/Http/Controllers/AssetCheckoutController.php new file mode 100644 index 0000000000..7220c35fa5 --- /dev/null +++ b/app/Http/Controllers/AssetCheckoutController.php @@ -0,0 +1,96 @@ +] + * @param int $assetId + * @since [v1.0] + * @return View + */ + public function create($assetId) + { + // Check if the asset exists + if (is_null($asset = Asset::find(e($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('checkout', $asset); + + if ($asset->availableForCheckout()) { + return view('hardware/checkout', compact('asset')); + } + return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available')); + + // Get the dropdown of users and then pass it to the checkout view + + } + + /** + * Validate and process the form data to check out an asset to a user. + * + * @author [A. Gianotto] [] + * @param AssetCheckoutRequest $request + * @param int $assetId + * @return Redirect + * @since [v1.0] + */ + public function store(AssetCheckoutRequest $request, $assetId) + { + try { + // Check if the asset exists + if (!$asset = Asset::find($assetId)) { + return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); + } elseif (!$asset->availableForCheckout()) { + return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available')); + } + $this->authorize('checkout', $asset); + $admin = Auth::user(); + + $target = $this->determineCheckoutTarget($asset); + if ($asset->is($target)) { + throw new CheckoutNotAllowed('You cannot check an asset out to itself.'); + } + $asset = $this->updateAssetLocation($asset, $target); + + $checkout_at = date("Y-m-d H:i:s"); + if (($request->has('checkout_at')) && ($request->get('checkout_at')!= date("Y-m-d"))) { + $checkout_at = $request->get('checkout_at'); + } + + $expected_checkin = ''; + if ($request->has('expected_checkin')) { + $expected_checkin = $request->get('expected_checkin'); + } + + if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $request->get('name'))) { + return redirect()->route("hardware.index")->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'))->withErrors($asset->getErrors()); + } catch (ModelNotFoundException $e) { + return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($asset->getErrors()); + } catch (CheckoutNotAllowed $e) { + return redirect()->back()->with('error', $e->getMessage()); + } + } + +} diff --git a/app/Http/Controllers/AssetFilesController.php b/app/Http/Controllers/AssetFilesController.php new file mode 100644 index 0000000000..4ca30232d5 --- /dev/null +++ b/app/Http/Controllers/AssetFilesController.php @@ -0,0 +1,125 @@ +] + * @param AssetFileRequest $request + * @param int $assetId + * @return Redirect + * @since [v1.0] + */ + public function store(AssetFileRequest $request, $assetId = null) + { + if (!$asset = Asset::find($assetId)) { + return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); + } + + $this->authorize('update', $asset); + + $destinationPath = config('app.private_uploads').'/assets'; + + if ($request->hasFile('assetfile')) { + foreach ($request->file('assetfile') as $file) { + $extension = $file->getClientOriginalExtension(); + $filename = 'hardware-'.$asset->id.'-'.str_random(8); + $filename .= '-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension; + $file->move($destinationPath, $filename); + $asset->logUpload($filename, e($request->get('notes'))); + } + return redirect()->back()->with('success', trans('admin/hardware/message.upload.success')); + } + + return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles')); + } + + /** + * Check for permissions and display the file. + * + * @author [A. Gianotto] [] + * @param int $assetId + * @param int $fileId + * @since [v1.0] + * @return View + */ + public function show($assetId = null, $fileId = null, $download = true) + { + $asset = Asset::find($assetId); + // the asset is valid + if (isset($asset->id)) { + $this->authorize('view', $asset); + + if (!$log = Actionlog::find($fileId)) { + return response('No matching record for that asset/file', 500) + ->header('Content-Type', 'text/plain'); + } + + $file = $log->get_src('assets'); + + if ($log->action_type =='audit') { + $file = $log->get_src('audits'); + } + + if (!file_exists($file)) { + return response('File '.$file.' not found on server', 404) + ->header('Content-Type', 'text/plain'); + } + + if ($download != 'true') { + if ($contents = file_get_contents($file)) { + return Response::make($contents)->header('Content-Type', mime_content_type($file)); + } + return JsonResponse::create(["error" => "Failed validation: "], 500); + } + return Response::download($file); + } + // Prepare the error message + $error = trans('admin/hardware/message.does_not_exist', ['id' => $fileId]); + + // Redirect to the hardware management page + return redirect()->route('hardware.index')->with('error', $error); + } + + /** + * Delete the associated file + * + * @author [A. Gianotto] [] + * @param int $assetId + * @param int $fileId + * @since [v1.0] + * @return View + */ + public function destroy($assetId = null, $fileId = null) + { + $asset = Asset::find($assetId); + $this->authorize('update', $asset); + $destinationPath = config('app.private_uploads').'/imports/assets'; + + // the asset is valid + if (isset($asset->id)) { + $this->authorize('update', $asset); + + $log = Actionlog::find($fileId); + $full_filename = $destinationPath.'/'.$log->filename; + if (file_exists($full_filename)) { + unlink($destinationPath.'/'.$log->filename); + } + $log->delete(); + return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success')); + } + + // Redirect to the hardware management page + return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); + } +} diff --git a/app/Http/Controllers/AssetModelsController.php b/app/Http/Controllers/AssetModelsController.php index 4ea273a8b3..0ae3c59e88 100755 --- a/app/Http/Controllers/AssetModelsController.php +++ b/app/Http/Controllers/AssetModelsController.php @@ -120,46 +120,6 @@ class AssetModelsController extends Controller return redirect()->back()->withInput()->withErrors($model->getErrors()); } - /** - * Validates and stores new Asset Model data created from the - * modal form on the Asset Creation view. - * - * @author [A. Gianotto] [] - * @since [v2.0] - * @param Request $request - * @return String JSON - */ - public function apiStore(Request $request) - { - //COPYPASTA!!!! FIXME - $this->authorize('create', AssetModel::class); - $model = new AssetModel; - - $settings=Input::all(); - $settings['eol']= null; - - $model->name=$request->input('name'); - $model->manufacturer_id = $request->input('manufacturer_id'); - $model->category_id = $request->input('category_id'); - $model->model_number = $request->input('model_number'); - $model->user_id = Auth::id(); - $model->notes = $request->input('notes'); - $model->eol= null; - - if ($request->input('fieldset_id')=='') { - $model->fieldset_id = null; - } else { - $model->fieldset_id = e($request->input('fieldset_id')); - } - - if ($model->save()) { - return JsonResponse::create($model); - } else { - return JsonResponse::create(["error" => "Failed validation: ".print_r($model->getErrors()->all('
  • :message
  • '), true)], 500); - } - } - - /** * Returns a view containing the asset model edit form. * diff --git a/app/Http/Controllers/AssetsController.php b/app/Http/Controllers/AssetsController.php index bceb3a574a..6abd9d76de 100755 --- a/app/Http/Controllers/AssetsController.php +++ b/app/Http/Controllers/AssetsController.php @@ -79,24 +79,6 @@ class AssetsController extends Controller return view('hardware/index')->with('company', $company); } - /** - * Searches the assets table by asset tag, and redirects if it finds one - * - * @author [A. Gianotto] [] - * @since [v3.0] - * @return Redirect - */ - public function getAssetByTag() - { - $topsearch = (Input::get('topsearch')=="true"); - - if (!$asset = Asset::where('asset_tag', '=', Input::get('assetTag'))->first()) { - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); - } - $this->authorize('view', $asset); - return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch); - } - /** * Returns a view that presents a form to create a new asset. * @@ -149,7 +131,7 @@ class AssetsController extends Controller $asset->depreciate = '0'; $asset->status_id = request('status_id', 0); $asset->warranty_months = request('warranty_months', null); - $asset->purchase_cost = Helper::ParseFloat(Input::get('purchase_cost')); + $asset->purchase_cost = Helper::ParseFloat($request->get('purchase_cost')); $asset->purchase_date = request('purchase_date', null); $asset->assigned_to = request('assigned_to', null); $asset->supplier_id = request('supplier_id', 0); @@ -161,7 +143,7 @@ class AssetsController extends Controller } // Create the image (if one was chosen.) - if ($request->has('image')) { + if ($request->hasFile('image')) { $image = $request->input('image'); // After modification, the image is prefixed by mime info like the following: @@ -229,7 +211,7 @@ class AssetsController extends Controller } if (isset($target)) { - $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e(Input::get('name')), $location); + $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')), $location); } // Redirect to the asset listing page \Session::flash('success', trans('admin/hardware/message.create.success')); @@ -263,6 +245,49 @@ class AssetsController extends Controller } + /** + * Returns a view that presents information about an asset for detail view. + * + * @author [A. Gianotto] [] + * @param int $assetId + * @since [v1.0] + * @return View + */ + public function show($assetId = null) + { + $asset = Asset::withTrashed()->find($assetId); + $this->authorize('view', $asset); + $settings = Setting::getSettings(); + + if (isset($asset)) { + $audit_log = Actionlog::where('action_type', '=', 'audit') + ->where('item_id', '=', $assetId) + ->where('item_type', '=', Asset::class) + ->orderBy('created_at', 'DESC')->first(); + + if ($asset->location) { + $use_currency = $asset->location->currency; + } else { + if ($settings->default_currency!='') { + $use_currency = $settings->default_currency; + } else { + $use_currency = trans('general.currency'); + } + } + + $qr_code = (object) array( + 'display' => $settings->qr_code == '1', + 'url' => route('qr_code/hardware', $asset->id) + ); + + return view('hardware/view', compact('asset', 'qr_code', 'settings')) + ->with('use_currency', $use_currency)->with('audit_log', $audit_log); + } + + return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); + } + + /** * Validate and process asset edit form. * @@ -318,7 +343,7 @@ class AssetsController extends Controller $asset->physical = '1'; // Update the image - if (Input::has('image')) { + if ($request->has('image')) { $image = $request->input('image'); // See postCreate for more explaination of the following. $header = explode(';', $image, 2)[0]; @@ -405,248 +430,25 @@ class AssetsController extends Controller return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success')); } - /** - * Returns a view that presents a form to check an asset out to a - * user. - * - * @author [A. Gianotto] [] - * @param int $assetId - * @since [v1.0] - * @return View - */ - public function getCheckout($assetId) - { - // Check if the asset exists - if (is_null($asset = Asset::find(e($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('checkout', $asset); - - if ($asset->availableForCheckout()) { - return view('hardware/checkout', compact('asset')); - } - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available')); - - // Get the dropdown of users and then pass it to the checkout view - - } /** - * Validate and process the form data to check out an asset to a user. + * Searches the assets table by asset tag, and redirects if it finds one * * @author [A. Gianotto] [] - * @param AssetCheckoutRequest $request - * @param int $assetId + * @since [v3.0] * @return Redirect - * @since [v1.0] */ - public function postCheckout(AssetCheckoutRequest $request, $assetId) + public function getAssetByTag() { - // Check if the asset exists - if (!$asset = Asset::find($assetId)) { - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); - } elseif (!$asset->availableForCheckout()) { - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkout.not_available')); - } - $this->authorize('checkout', $asset); - $admin = Auth::user(); + $topsearch = ($request->get('topsearch')=="true"); - - // This item is checked out to a location - if (request('checkout_to_type')=='location') { - $target = Location::find(request('assigned_location')); - $asset->location_id = ($target) ? $target->id : ''; - - } elseif (request('checkout_to_type')=='asset') { - - if (request('assigned_asset') == $assetId) { - return redirect()->back()->with('error', 'You cannot check an asset out to itself.'); - } - - $target = Asset::where('id','!=',$assetId)->find(request('assigned_asset')); - $asset->location_id = $target->rtd_location_id; - - // Override with the asset's location_id if it has one - if ($target->location_id!='') { - $asset->location_id = ($target) ? $target->location_id : ''; - } - - } elseif (request('checkout_to_type')=='user') { - // Fetch the target and set the asset's new location_id - $target = User::find(request('assigned_user')); - $asset->location_id = ($target) ? $target->location_id : ''; - } - - // No valid target was found - error out - if (!$target) { - return redirect()->back()->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($asset->getErrors()); - } - - - if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) { - $checkout_at = Input::get('checkout_at'); - } else { - $checkout_at = date("Y-m-d H:i:s"); - } - - if (Input::has('expected_checkin')) { - $expected_checkin = Input::get('expected_checkin'); - } else { - $expected_checkin = ''; - } - - - if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), Input::get('name'))) { - return redirect()->route("hardware.index")->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'))->withErrors($asset->getErrors()); - } - - - /** - * Returns a view that presents a form to check an asset back into inventory. - * - * @author [A. Gianotto] [] - * @param int $assetId - * @param string $backto - * @since [v1.0] - * @return View - */ - public function getCheckin($assetId, $backto = null) - { - // Check if the asset exists - if (is_null($asset = Asset::find($assetId))) { - // Redirect to the asset management page with error + if (!$asset = Asset::where('asset_tag', '=', $request->get('assetTag'))->first()) { return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); } - - $this->authorize('checkin', $asset); - return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto); - } - - - /** - * Validate and process the form data to check an asset back into inventory. - * - * @author [A. Gianotto] [] - * @param AssetCheckinRequest $request - * @param int $assetId - * @param null $backto - * @return Redirect - * @since [v1.0] - */ - public function postCheckin(AssetCheckinRequest $request, $assetId = null, $backto = null) - { - // 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); - - $admin = Auth::user(); - if ($asset->assignedType() == Asset::USER) { - $user = $asset->assignedTo; - } - if (is_null($target = $asset->assignedTo)) { - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in')); - } - - $asset->expected_checkin = null; - $asset->last_checkout = null; - $asset->assigned_to = null; - $asset->assignedTo()->disassociate($asset); - $asset->assigned_type = null; - $asset->accepted = null; - $asset->name = e(Input::get('name')); - - if (Input::has('status_id')) { - $asset->status_id = e(Input::get('status_id')); - } - - $asset->location_id = $asset->rtd_location_id; - - if (Input::has('location_id')) { - $asset->location_id = e(Input::get('location_id')); - } - - // Was the asset updated? - if ($asset->save()) { - $logaction = $asset->logCheckin($target, e(request('note'))); - - $data['log_id'] = $logaction->id; - $data['first_name'] = get_class($target) == User::class ? $target->first_name : ''; - $data['last_name'] = get_class($target) == User::class ? $target->last_name : ''; - $data['item_name'] = $asset->present()->name(); - $data['checkin_date'] = $logaction->created_at; - $data['item_tag'] = $asset->asset_tag; - $data['item_serial'] = $asset->serial; - $data['note'] = $logaction->note; - $data['manufacturer_name'] = $asset->model->manufacturer->name; - $data['model_name'] = $asset->model->name; - $data['model_number'] = $asset->model->model_number; - - if ($backto=='user') { - return redirect()->route("users.show", $user->id)->with('success', trans('admin/hardware/message.checkin.success')); - } - return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success')); - } - - // Redirect to the asset management page with error - return redirect()->route("hardware.index")->with('error', trans('admin/hardware/message.checkin.error')); - } - - - /** - * Returns a view that presents information about an asset for detail view. - * - * @author [A. Gianotto] [] - * @param int $assetId - * @since [v1.0] - * @return View - */ - public function show($assetId = null) - { - - $asset = Asset::withTrashed()->find($assetId); $this->authorize('view', $asset); - $settings = Setting::getSettings(); - - - - if (isset($asset)) { - $audit_log = Actionlog::where('action_type', '=', 'audit') - ->where('item_id', '=', $assetId) - ->where('item_type', '=', Asset::class) - ->orderBy('created_at', 'DESC')->first(); - - if ($asset->location) { - $use_currency = $asset->location->currency; - } else { - if ($settings->default_currency!='') { - $use_currency = $settings->default_currency; - } else { - $use_currency = trans('general.currency'); - } - } - - $qr_code = (object) array( - 'display' => $settings->qr_code == '1', - 'url' => route('qr_code/hardware', $asset->id) - ); - - return view('hardware/view', compact('asset', 'qr_code', 'settings')) - ->with('use_currency', $use_currency)->with('audit_log', $audit_log); - } - - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); + return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch); } - /** * Return a QR code for the asset * @@ -924,348 +726,6 @@ class AssetsController extends Controller return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); } - - /** - * Upload a file to the server. - * - * @author [A. Gianotto] [] - * @param AssetFileRequest $request - * @param int $assetId - * @return Redirect - * @since [v1.0] - */ - public function postUpload(AssetFileRequest $request, $assetId = null) - { - - if (!$asset = Asset::find($assetId)) { - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); - } - - $this->authorize('update', $asset); - - $destinationPath = config('app.private_uploads').'/assets'; - - if ($request->hasFile('assetfile')) { - foreach ($request->file('assetfile') as $file) { - $extension = $file->getClientOriginalExtension(); - $filename = 'hardware-'.$asset->id.'-'.str_random(8).'-'.str_slug(basename($file->getClientOriginalName(), '.'.$extension)).'.'.$extension; - $file->move($destinationPath, $filename); - $asset->logUpload($filename, e(Input::get('notes'))); - } - return redirect()->back()->with('success', trans('admin/hardware/message.upload.success')); - } - - return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles')); - } - - /** - * Delete the associated file - * - * @author [A. Gianotto] [] - * @param int $assetId - * @param int $fileId - * @since [v1.0] - * @return View - */ - public function deleteFile($assetId = null, $fileId = null) - { - $asset = Asset::find($assetId); - $this->authorize('update', $asset); - $destinationPath = config('app.private_uploads').'/imports/assets'; - - // the asset is valid - if (isset($asset->id)) { - $this->authorize('update', $asset); - - $log = Actionlog::find($fileId); - $full_filename = $destinationPath.'/'.$log->filename; - if (file_exists($full_filename)) { - unlink($destinationPath.'/'.$log->filename); - } - $log->delete(); - return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success')); - } - - // Redirect to the hardware management page - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist')); - } - - /** - * Check for permissions and display the file. - * - * @author [A. Gianotto] [] - * @param int $assetId - * @param int $fileId - * @since [v1.0] - * @return View - */ - public function displayFile($assetId = null, $fileId = null, $download = true) - { - - $asset = Asset::find($assetId); - - if (isset($asset->id)) { - - $this->authorize('view', $asset); - - if (!$log = Actionlog::find($fileId)) { - return response('No matching record for that asset/file', 500) - ->header('Content-Type', 'text/plain'); - } - - $file = $log->get_src('assets'); - - if ($log->action_type =='audit') { - $file = $log->get_src('audits'); - } - - - if (!file_exists($file)) { - return response('File '.$file.' not found on server', 404) - ->header('Content-Type', 'text/plain'); - } - - if ($download != 'true') { - if ($contents = file_get_contents($file)) { - return Response::make($contents)->header('Content-Type', $filetype); - } - return JsonResponse::create(["error" => "Failed validation: "], 500); - } - return Response::download($file); - } - - // Redirect to the hardware management page - return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist', compact('id'))); - } - - /** - * Display the bulk edit page. - * - * @author [A. Gianotto] [] - * @return View - * @internal param int $assetId - * @since [v2.0] - */ - public function postBulkEdit(Request $request) - { - $this->authorize('update', Asset::class); - - if (!$request->has('ids')) { - return redirect()->back()->with('error', 'No assets selected'); - } - - $asset_raw_array = $request->input('ids'); - foreach ($asset_raw_array as $asset_id => $value) { - $asset_ids[] = $asset_id; - } - - - if ($request->has('bulk_actions')) { - if ($request->input('bulk_actions')=='labels') { - $count = 0; - return view('hardware/labels') - ->with('assets', Asset::find($asset_ids)) - ->with('settings', Setting::getSettings()) - ->with('count', $count); - } elseif ($request->input('bulk_actions')=='delete') { - $assets = Asset::with('assignedTo', 'location')->find($asset_ids); - $assets->each(function ($asset) { - $this->authorize('delete', $asset); - }); - return view('hardware/bulk-delete')->with('assets', $assets); - // Bulk edit - } elseif ($request->input('bulk_actions')=='edit') { - return view('hardware/bulk') - ->with('assets', request('ids')) - ->with('statuslabel_list', Helper::statusLabelList()); - } - } - return redirect()->back()->with('error', 'No action selected'); - } - - /** - * Save bulk edits - * - * @author [A. Gianotto] [] - * @return Redirect - * @internal param array $assets - * @since [v2.0] - */ - public function postBulkSave(Request $request) - { - $this->authorize('update', Asset::class); - - \Log::debug($request->input('ids')); - - if (($request->has('ids')) && (count($request->input('ids')) > 0)) { - $assets = $request->input('ids'); - if (($request->has('purchase_date')) - || ($request->has('purchase_cost')) - || ($request->has('supplier_id')) - || ($request->has('order_number')) - || ($request->has('warranty_months')) - || ($request->has('rtd_location_id')) - || ($request->has('requestable')) - || ($request->has('company_id')) - || ($request->has('status_id')) - || ($request->has('model_id')) - ) { - foreach ($assets as $key => $value) { - $update_array = array(); - - if ($request->has('purchase_date')) { - $update_array['purchase_date'] = $request->input('purchase_date'); - } - if ($request->has('purchase_cost')) { - $update_array['purchase_cost'] = Helper::ParseFloat($request->input('purchase_cost')); - } - if ($request->has('supplier_id')) { - $update_array['supplier_id'] = $request->input('supplier_id'); - } - if ($request->has('model_id')) { - $update_array['model_id'] = $request->input('model_id'); - } - if ($request->has('company_id')) { - if ($request->input('company_id')=="clear") { - $update_array['company_id'] = null; - } else { - $update_array['company_id'] = $request->input('company_id'); - } - } - if ($request->has('order_number')) { - $update_array['order_number'] = $request->input('order_number'); - } - if ($request->has('warranty_months')) { - $update_array['warranty_months'] = $request->input('warranty_months'); - } - - - if ($request->has('rtd_location_id')) { - $update_array['rtd_location_id'] = $request->input('rtd_location_id'); - if (($request->has('update_real_loc')) - && (($request->input('update_real_loc')) == '1')) - { - $update_array['location_id'] = $request->input('rtd_location_id'); - } - } - - if ($request->has('status_id')) { - $update_array['status_id'] = $request->input('status_id'); - } - if ($request->has('requestable')) { - $update_array['requestable'] = $request->input('requestable'); - } - - DB::table('assets') - ->where('id', $key) - ->update($update_array); - } // endforeach - return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.update.success')); - // no values given, nothing to update - } - return redirect()->route("hardware.index")->with('warning', trans('admin/hardware/message.update.nothing_updated')); - } // endif - return redirect()->route("hardware.index")->with('warning', trans('No assets selected, so nothing was updated.')); - } - - /** - * Save bulk deleted. - * - * @author [A. Gianotto] [] - * @return View - * @internal param array $assets - * @since [v2.0] - */ - public function postBulkDelete() - { - $this->authorize('delete', Asset::class); - - if (Input::has('ids')) { - $assets = Asset::find(Input::get('ids')); - foreach ($assets as $asset) { - $update_array['deleted_at'] = date('Y-m-d H:i:s'); - $update_array['assigned_to'] = null; - - DB::table('assets') - ->where('id', $asset->id) - ->update($update_array); - } // endforeach - return redirect()->to("hardware")->with('success', trans('admin/hardware/message.delete.success')); - // no values given, nothing to update - } - return redirect()->to("hardware")->with('info', trans('admin/hardware/message.delete.nothing_updated')); - } - - - public function getBulkCheckout() - { - $this->authorize('checkout', Asset::class); - return view('hardware/bulk-checkout'); - } - - public function postBulkCheckout(Request $request) - { - $admin = Auth::user(); - // Find checkout to type - if (request('checkout_to_type')=='location') { - $target = Location::find(request('assigned_location')); - } elseif (request('checkout_to_type')=='asset') { - $target = Asset::find(request('assigned_asset')); - } elseif (request('checkout_to_type')=='user') { - $target = User::find(request('assigned_user')); - } - if (!is_array(Input::get('selected_assets'))) { - return redirect()->route('hardware/bulkcheckout')->withInput()->with('error', trans('admin/hardware/message.checkout.no_assets_selected')); - } - - $asset_ids = array_filter(Input::get('selected_assets')); - foreach ($asset_ids as $asset_id) { - if ($target->id == $asset_id && request('checkout_to_type')=='asset') { - return redirect()->back()->with('error', 'You cannot check an asset out to itself.'); - } - } - if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) { - $checkout_at = e(Input::get('checkout_at')); - } else { - $checkout_at = date("Y-m-d H:i:s"); - } - - if (Input::has('expected_checkin')) { - $expected_checkin = e(Input::get('expected_checkin')); - } else { - $expected_checkin = ''; - } - - - $errors = []; - DB::transaction(function () use ($target, $admin, $checkout_at, $expected_checkin, $errors, $asset_ids) { - - foreach ($asset_ids as $asset_id) { - $asset = Asset::find($asset_id); - $this->authorize('checkout', $asset); - $error = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), null); - - if ($target->location_id!='') { - $asset->location_id = $target->location_id; - $asset->unsetEventDispatcher(); - $asset->save(); - } - - if ($error) { - array_merge_recursive($errors, $asset->getErrors()->toArray()); - } - } - }); - - if (!$errors) { - // Redirect to the new asset page - return redirect()->to("hardware")->with('success', trans('admin/hardware/message.checkout.success')); - } - // Redirect to the asset management page with error - return redirect()->to("hardware/bulk-checkout")->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($errors); - } - - public function quickScan() { $this->authorize('audit', Asset::class); diff --git a/app/Http/Controllers/BulkAssetsController.php b/app/Http/Controllers/BulkAssetsController.php new file mode 100644 index 0000000000..cec9adf7f8 --- /dev/null +++ b/app/Http/Controllers/BulkAssetsController.php @@ -0,0 +1,249 @@ +] + * @return View + * @internal param int $assetId + * @since [v2.0] + */ + public function edit(Request $request) + { + $this->authorize('update', Asset::class); + + if (!$request->has('ids')) { + return redirect()->back()->with('error', 'No assets selected'); + } + + $asset_ids = array_keys($request->input('ids')); + + if ($request->has('bulk_actions')) { + switch($request->input('bulk_actions')) { + case 'labels': + return view('hardware/labels') + ->with('assets', Asset::find($asset_ids)) + ->with('settings', Setting::getSettings()) + ->with('count', 0); + case 'delete': + $assets = Asset::with('assignedTo', 'location')->find($asset_ids); + $assets->each(function ($asset) { + $this->authorize('delete', $asset); + }); + return view('hardware/bulk-delete')->with('assets', $assets); + case 'edit': + return view('hardware/bulk') + ->with('assets', request('ids')) + ->with('statuslabel_list', Helper::statusLabelList()); + } + } + return redirect()->back()->with('error', 'No action selected'); + } + + /** + * Save bulk edits + * + * @author [A. Gianotto] [] + * @return Redirect + * @internal param array $assets + * @since [v2.0] + */ + public function update(Request $request) + { + $this->authorize('update', Asset::class); + + \Log::debug($request->input('ids')); + + if(!$request->has('ids') || count($request->input('ids')) <= 0) { + return redirect()->route("hardware.index")->with('warning', trans('No assets selected, so nothing was updated.')); + } + + $assets = array_keys($request->input('ids')); + + if (($request->has('purchase_date')) + || ($request->has('purchase_cost')) + || ($request->has('supplier_id')) + || ($request->has('order_number')) + || ($request->has('warranty_months')) + || ($request->has('rtd_location_id')) + || ($request->has('requestable')) + || ($request->has('company_id')) + || ($request->has('status_id')) + || ($request->has('model_id')) + ) { + foreach ($assets as $assetId) { + $this->update_array = []; + + $this->conditionallyAddItem('purchase_date') + ->conditionallyAddItem('model_id') + ->conditionallyAddItem('order_number') + ->conditionallyAddItem('requestable') + ->conditionallyAddItem('status_id') + ->conditionallyAddItem('supplier_id') + ->conditionallyAddItem('warranty_months'); + + if ($request->has('purchase_cost')) { + $this->update_array['purchase_cost'] = Helper::ParseFloat($request->input('purchase_cost')); + } + + if ($request->has('company_id')) { + $this->update_array['company_id'] = $request->input('company_id'); + if ($request->input('company_id')=="clear") { + $this->update_array['company_id'] = null; + } + } + + if ($request->has('rtd_location_id')) { + $this->update_array['rtd_location_id'] = $request->input('rtd_location_id'); + if (($request->has('update_real_loc')) && (($request->input('update_real_loc')) == '1')) { + $this->update_array['location_id'] = $request->input('rtd_location_id'); + } + } + + DB::table('assets') + ->where('id', $assetId) + ->update($this->update_array); + } // endforeach + return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.update.success')); + // no values given, nothing to update + } + return redirect()->route("hardware.index")->with('warning', trans('admin/hardware/message.update.nothing_updated')); + + } + + /** + * Array to store update data per item + * @var Array + */ + private $update_array; + /** + * Adds parameter to update array for an item if it exists in request + * @param String $field field name + * @return this Model for Chaining + */ + protected function conditionallyAddItem($field) + { + if(request()->has($field)) { + $this->update_array[$field] = request()->input($field); + } + return $this; + } + + /** + * Save bulk deleted. + * + * @author [A. Gianotto] [] + * @return View + * @internal param array $assets + * @since [v2.0] + */ + public function destroy(Request $request) + { + $this->authorize('delete', Asset::class); + + if ($request->has('ids')) { + $assets = Asset::find($request->get('ids')); + foreach ($assets as $asset) { + $update_array['deleted_at'] = date('Y-m-d H:i:s'); + $update_array['assigned_to'] = null; + + DB::table('assets') + ->where('id', $asset->id) + ->update($update_array); + } // endforeach + return redirect()->to("hardware")->with('success', trans('admin/hardware/message.delete.success')); + // no values given, nothing to update + } + return redirect()->to("hardware")->with('info', trans('admin/hardware/message.delete.nothing_updated')); + } + + /** + * Show Bulk Checkout Page + * @return View View to checkout multiple assets + */ + public function showCheckout() + { + $this->authorize('checkout', Asset::class); + // Filter out assets that are not deployable. + + return view('hardware/bulk-checkout'); + } + + /** + * Process Multiple Checkout Request + * @return View + */ + public function storeCheckout(Request $request) + { + try { + $admin = Auth::user(); + + $target = $this->determineCheckoutTarget(); + + if (!is_array($request->get('selected_assets'))) { + return redirect()->route('hardware/bulkcheckout')->withInput()->with('error', trans('admin/hardware/message.checkout.no_assets_selected')); + } + + $asset_ids = array_filter($request->get('selected_assets')); + + foreach ($asset_ids as $asset_id) { + if ($target->id == $asset_id && request('checkout_to_type') =='asset') { + return redirect()->back()->with('error', 'You cannot check an asset out to itself.'); + } + } + $checkout_at = date("Y-m-d H:i:s"); + if (($request->has('checkout_at')) && ($request->get('checkout_at')!= date("Y-m-d"))) { + $checkout_at = e($request->get('checkout_at')); + } + + $expected_checkin = ''; + + if ($request->has('expected_checkin')) { + $expected_checkin = e($request->get('expected_checkin')); + } + + $errors = []; + DB::transaction(function () use ($target, $admin, $checkout_at, $expected_checkin, $errors, $asset_ids, $request) { + + foreach ($asset_ids as $asset_id) { + $asset = Asset::findOrFail($asset_id); + $this->authorize('checkout', $asset); + $error = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), null); + + if ($target->location_id!='') { + $asset->location_id = $target->location_id; + $asset->unsetEventDispatcher(); + $asset->save(); + } + + if ($error) { + array_merge_recursive($errors, $asset->getErrors()->toArray()); + } + } + }); + + if (!$errors) { + // Redirect to the new asset page + return redirect()->to("hardware")->with('success', trans('admin/hardware/message.checkout.success')); + } + // Redirect to the asset management page with error + return redirect()->to("hardware/bulk-checkout")->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($errors); + } catch (ModelNotFoundException $e) { + return redirect()->to("hardware/bulk-checkout")->with('error', $e->getErrors()); + } + } +} diff --git a/app/Http/Controllers/CheckInOutRequest.php b/app/Http/Controllers/CheckInOutRequest.php new file mode 100644 index 0000000000..f88d6acda7 --- /dev/null +++ b/app/Http/Controllers/CheckInOutRequest.php @@ -0,0 +1,56 @@ +location_id = $target->id; + break; + case 'asset': + $asset->location_id = $target->rtd_location_id; + // Override with the asset's location_id if it has one + if ($target->location_id!='') { + $asset->location_id = $target->location_id; + } + break; + case 'user': + $asset->location_id = $target->location_id; + break; + } + return $asset; + } +} diff --git a/app/Http/Controllers/LocationsController.php b/app/Http/Controllers/LocationsController.php index 80671f0165..8a5e3c531a 100755 --- a/app/Http/Controllers/LocationsController.php +++ b/app/Http/Controllers/LocationsController.php @@ -114,42 +114,6 @@ class LocationsController extends Controller return redirect()->back()->withInput()->withErrors($location->getErrors()); } - /** - * Validates and stores a new location created via the Create Asset form modal. - * - * @todo Check if a Form Request would work better here. - * @author [A. Gianotto] [] - * @see AssetsController::getCreate() method that makes the form - * @since [v1.0] - * @return String JSON - */ - public function apiStore(Request $request) - { - $this->authorize('create', Location::class); - $new['currency']=Setting::first()->default_currency; - - // create a new location instance - $location = new Location(); - - // Save the location data - $location->name = $request->input('name'); - $location->currency = Setting::first()->default_currency; //e(Input::get('currency')); - $location->address = ''; //e(Input::get('address')); - // $location->address2 = e(Input::get('address2')); - $location->city = $request->input('city'); - $location->state = '';//e(Input::get('state')); - $location->country = $request->input('country'); - // $location->zip = e(Input::get('zip')); - $location->user_id = Auth::id(); - - // Was the location created? - if ($location->save()) { - return JsonResponse::create($location); - } - // failure - return JsonResponse::create(["error" => "Failed validation: ".print_r($location->getErrors(), true)], 500); - } - /** * Makes a form view to edit location information. diff --git a/app/Http/Controllers/StatuslabelsController.php b/app/Http/Controllers/StatuslabelsController.php index a264dd77f7..9c609ebb96 100755 --- a/app/Http/Controllers/StatuslabelsController.php +++ b/app/Http/Controllers/StatuslabelsController.php @@ -103,36 +103,6 @@ class StatuslabelsController extends Controller return redirect()->back()->withInput()->withErrors($statusLabel->getErrors()); } - /** - * @param Request $request - * @return JsonResponse - */ - public function apiStore(Request $request) - { - $this->authorize('create', Statuslabel::class); - $statuslabel = new Statuslabel(); - if (!$request->has('statuslabel_types')) { - return JsonResponse::create(["error" => trans('validation.statuslabel_type')], 500); - } - $statustype = Statuslabel::getStatuslabelTypesForDB(Input::get('statuslabel_types')); - $statuslabel->name = Input::get('name'); - $statuslabel->user_id = Auth::id(); - $statuslabel->notes = ''; - $statuslabel->deployable = $statustype['deployable']; - $statuslabel->pending = $statustype['pending']; - $statuslabel->archived = $statustype['archived']; - - - if ($statuslabel->isValid()) { - $statuslabel->save(); - // Redirect to the new Statuslabel page - return JsonResponse::create($statuslabel); - } - return JsonResponse::create(["error" => $statuslabel->getErrors()->first()], 500); - - } - - /** * Statuslabel update. * diff --git a/app/Http/Controllers/SuppliersController.php b/app/Http/Controllers/SuppliersController.php index d9726c4b31..ce7de94f35 100755 --- a/app/Http/Controllers/SuppliersController.php +++ b/app/Http/Controllers/SuppliersController.php @@ -97,23 +97,6 @@ class SuppliersController extends Controller return redirect()->back()->withInput()->withErrors($supplier->getErrors()); } - /** - * @param Request $request - * @return JsonResponse - */ - public function apiStore(Request $request) - { - $this->authorize('create', Supplier::class); - $supplier = new Supplier; - $supplier->name = $request->input('name'); - $supplier->user_id = Auth::id(); - - if ($supplier->save()) { - return JsonResponse::create($supplier); - } - return JsonResponse::create(["error" => "Failed validation: ".print_r($supplier->getErrors(), true)], 500); - } - /** * Supplier update. * diff --git a/app/Http/Controllers/UsersController.php b/app/Http/Controllers/UsersController.php index 662888c624..bd9c662b91 100755 --- a/app/Http/Controllers/UsersController.php +++ b/app/Http/Controllers/UsersController.php @@ -1,26 +1,30 @@ back()->withInput()->withErrors($user->getErrors()); } - /** - * JSON handler for creating a user through a modal popup - * - * @todo Handle validation more graciously - * @author [B. Wetherington] [] - * @since [v1.8] - * @return string JSON - */ - public function apiStore(SaveUserRequest $request) - { - $this->authorize('create', User::class); - $user = new User; - $inputs = Input::except('csrf_token', 'password_confirm', 'groups', 'email_user'); - $inputs['activated'] = true; - - $user->first_name = $request->input('first_name'); - $user->last_name = $request->input('last_name'); - $user->username = $request->input('username'); - $user->email = $request->input('email'); - $user->department_id = $request->input('department_id', null); - if ($request->has('password')) { - $user->password = bcrypt($request->input('password')); - } - $user->activated = true; - - // Was the user created? - if ($user->save()) { - - if (Input::get('email_user') == 1) { - // Send the credentials through email - $data = array(); - $data['email'] = $request->input('email'); - $data['username'] = $request->input('username'); - $data['first_name'] = $request->input('first_name'); - $data['last_name'] = e($request->input('last_name')); - $data['password'] = $request->input('password'); - - $user->notify(new WelcomeNotification($data)); - - /*Mail::send('emails.send-login', $data, function ($m) use ($user) { - $m->to($user->email, $user->first_name . ' ' . $user->last_name); - $m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name')); - $m->subject(trans('mail.welcome', ['name' => $user->first_name])); - });*/ - } - - return JsonResponse::create($user); - - } - return JsonResponse::create(["error" => "Failed validation: " . print_r($user->getErrors(), true)], 500); - } - - /** - * Returns a view that displays the edit user form - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @param $permissions - * @return View - * @internal param int $id - */ private function filterDisplayable($permissions) { @@ -237,6 +177,15 @@ class UsersController extends Controller return $output; } + /** + * Returns a view that displays the edit user form + * + * @author [A. Gianotto] [] + * @since [v1.0] + * @param $permissions + * @return View + * @internal param int $id + */ public function edit($id) { @@ -382,7 +331,7 @@ class UsersController extends Controller { try { // Get user information - $user = User::find($id); + $user = User::findOrFail($id); // Authorize takes care of many of our logic checks now. $this->authorize('delete', User::class); @@ -420,7 +369,7 @@ class UsersController extends Controller // Redirect to the user management page return redirect()->route('users.index')->with('success', $success); - } catch (UserNotFoundException $e) { + } catch (ModelNotFoundException $e) { // Prepare the error message $error = trans('admin/users/message.user_not_found', compact('id')); // Redirect to the user management page @@ -551,7 +500,7 @@ class UsersController extends Controller if (($key = array_search(Auth::user()->id, $user_raw_array)) !== false) { unset($user_raw_array[$key]); } - + if (!config('app.lock_passwords')) { @@ -762,129 +711,6 @@ class UsersController extends Controller } } - /** - * Return user import view - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @return \Illuminate\Contracts\View\View - */ - public function getImport() - { - $this->authorize('update', User::class); - // Selected groups - $selectedGroups = Input::old('groups', array()); - // Get all the available permissions - $permissions = config('permissions'); - $selectedPermissions = Input::old('permissions', array('superuser' => -1)); - // Show the page - return view('users/import', compact('selectedGroups', 'permissions', 'selectedPermissions')); - } - - /** - * Handle user import file - * - * @author [A. Gianotto] [] - * @since [v1.0] - * @return \Illuminate\Http\RedirectResponse - */ - public function postImport() - { - $this->authorize('update', User::class); - if (!ini_get("auto_detect_line_endings")) { - ini_set("auto_detect_line_endings", '1'); - } - - $csv = Reader::createFromPath(Input::file('user_import_csv')); - $csv->setNewline("\r\n"); - - if (Input::get('has_headers') == 1) { - $csv->setOffset(1); - } - - $duplicates = ''; - - $nbInsert = $csv->each(function ($row) use ($duplicates) { - - if (array_key_exists(2, $row)) { - - if (Input::get('activate') == 1) { - $activated = '1'; - } else { - $activated = '0'; - } - - $pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 15); - - // Location - if (array_key_exists('4', $row)) { - $user_location_id = trim($row[4]); - if ($user_location_id=='') { - $user_location_id = null; - } - } - - - - try { - // Check if this email already exists in the system - $user = User::where('username', $row[2])->first(); - if ($user) { - $duplicates .= $row[2] . ', '; - } else { - - $newuser = array( - 'first_name' => trim(e($row[0])), - 'last_name' => trim(e($row[1])), - 'username' => trim(e($row[2])), - 'email' => trim(e($row[3])), - 'password' => bcrypt($pass), - 'activated' => $activated, - 'location_id' => trim(e($user_location_id)), - 'phone' => trim(e($row[5])), - 'jobtitle' => trim(e($row[6])), - 'employee_num' => trim(e($row[7])), - 'company_id' => Company::getIdForUser($row[8]), - 'permissions' => '{"user":1}', - 'notes' => 'Imported user' - ); - - DB::table('users')->insert($newuser); - - - if (((Input::get('email_user') == 1) && !config('app.lock_passwords'))) { - // Send the credentials through email - if ($row[3] != '') { - $data = array(); - $data['email'] = trim(e($row[4])); - $data['username'] = trim(e($row[2])); - $data['first_name'] = trim(e($row[0])); - $data['last_name'] = trim(e($row[1])); - $data['password'] = $pass; - - if ($newuser['email']) { - $user = User::where('username', $row[2])->first(); - $user->notify(new WelcomeNotification($data)); - - /*Mail::send('emails.send-login', $data, function ($m) use ($newuser) { - $m->to($newuser['email'], $newuser['first_name'] . ' ' . $newuser['last_name']); - $m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name')); - $m->subject(trans('mail.welcome', ['name' => $newuser['first_name']])); - });*/ - } - } - } - } - } catch (Exception $e) { - echo 'Caught exception: ', $e->getMessage(), "\n"; - } - return true; - } - }); - return redirect()->route('users.index')->with('duplicates', $duplicates)->with('success', 'Success'); - } - - /** * Return JSON response with a list of user details for the getIndex() view. * diff --git a/app/Importer/Importer.php b/app/Importer/Importer.php index 1ec04157ba..221e2b9860 100644 --- a/app/Importer/Importer.php +++ b/app/Importer/Importer.php @@ -95,7 +95,6 @@ abstract class Importer if (! ini_get("auto_detect_line_endings")) { ini_set("auto_detect_line_endings", '1'); } - // By default the importer passes a url to the file. // However, for testing we also support passing a string directly if (is_file($file)) { @@ -113,24 +112,7 @@ abstract class Importer $headerRow = $this->csv->fetchOne(); $results = $this->normalizeInputArray($this->csv->fetchAssoc()); - // Stolen From https://adamwathan.me/2016/07/14/customizing-keys-when-mapping-collections/ - // This 'inverts' the fields such that we have a collection of fields indexed by name. - $cFs = CustomField::All(); - $this->customFields = $cFs->reduce(function ($nameLookup, $field) { - $nameLookup[$field['name']] = $field; - return $nameLookup; - }); - // Remove any custom fields that do not exist in the header row. This prevents nulling out values that shouldn't exist. - // In detail, we compare the lower case name of custom fields (indexed by name) to the keys in the header row. This - // results in an array with only custom fields that are in the file. - if ($this->customFields) { - $this->customFields = array_intersect_key( - array_change_key_case($this->customFields), - array_change_key_case(array_flip($headerRow)) - ); - } - - + $this->populateCustomFields($headerRow); DB::transaction(function () use (&$results) { Model::unguard(); @@ -146,8 +128,35 @@ abstract class Importer }); } + abstract protected function handle($row); + /** + * Fetch custom fields from database and translate/parse them into a format + * appropriate for use in the importer. + * @return void + * @author Daniel Meltzer + * @since 5.0 + */ + protected function populateCustomFields($headerRow) + { + // Stolen From https://adamwathan.me/2016/07/14/customizing-keys-when-mapping-collections/ + // This 'inverts' the fields such that we have a collection of fields indexed by name. + $this->customFields = CustomField::All()->reduce(function ($nameLookup, $field) { + $nameLookup[$field['name']] = $field; + return $nameLookup; + }); + // Remove any custom fields that do not exist in the header row. This prevents nulling out values that shouldn't exist. + // In detail, we compare the lower case name of custom fields (indexed by name) to the keys in the header row. This + // results in an array with only custom fields that are in the file. + if ($this->customFields) { + $this->customFields = array_intersect_key( + array_change_key_case($this->customFields), + array_change_key_case(array_flip($headerRow)) + ); + } + + } /** * Check to see if the given key exists in the array, and trim excess white space before returning it * diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index db134f7160..c14e50037f 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -860,7 +860,7 @@ @can('update', \App\Models\Asset::class) - + @endcan diff --git a/resources/views/users/import.blade.php b/resources/views/users/import.blade.php deleted file mode 100644 index 782fe1bcf3..0000000000 --- a/resources/views/users/import.blade.php +++ /dev/null @@ -1,109 +0,0 @@ -@extends('layouts/default') - -{{-- Page title --}} -@section('title') -Create a User -@parent -@stop - -@section('header_right') - {{ trans('general.back') }} -@stop - -{{-- Page content --}} -@section('content') - - -
    -
    -
    -
    -
    - - @if (config('app.lock_passwords')) -

    CSV uploads are disabled on the demo.

    - @endif - - - - - @if (Session::get('message')) -

    - You have an error in your CSV file:
    - {{ Session::get('message') }} -

    - @endif - -

    - Upload a CSV file with one or more users. Passwords will be auto-generated. The CSV should have the first fields as: -

    - -

    - firstName,lastName, username, email, location_id, phone, jobtitle, employee_num, company_id. -

    - -

    - Any additional fields to the right of those fields will be ignored. Email is optional, however users will not be able to recover their passwords or receive EULAs if you do not provide an email address. If you wish to include a company association, you must reference the ID number of an existing company - companies will not be created on the fly. -

    - - - - -
    - -
    - - Select Import File... - @if (config('app.lock_passwords')) - - @else - - @endif - - - -
    -
    - - -
    -
    -
    -
    - {{ Form::checkbox('has_headers', '1', Input::old('has_headers')) }} This CSV has a header row -
    -
    - - -
    -
    -
    -
    - {{ Form::checkbox('email_user', '1', Input::old('email_user')) }} Email these users their credentials? (Only possible where email address is included with user data.) -
    -
    - - -
    -
    -
    -
    - {{ Form::checkbox('activate', '1', Input::old('activate')) }} Activate user? -
    -
    -
    - - -
    -
    -
    -
    - -@stop diff --git a/resources/views/users/index.blade.php b/resources/views/users/index.blade.php index 2935dab0e5..1ad0c4af7a 100755 --- a/resources/views/users/index.blade.php +++ b/resources/views/users/index.blade.php @@ -18,7 +18,6 @@ @if ($snipeSettings->ldap_enabled == 1) LDAP Sync @endif - {{ trans('general.import') }} {{ trans('general.create') }} @endcan diff --git a/routes/web/hardware.php b/routes/web/hardware.php index d0d597d6a4..081098806a 100644 --- a/routes/web/hardware.php +++ b/routes/web/hardware.php @@ -64,20 +64,20 @@ Route::group( Route::get('{assetId}/checkout', [ 'as' => 'checkout/hardware', - 'uses' => 'AssetsController@getCheckout' + 'uses' => 'AssetCheckoutController@create' ]); Route::post('{assetId}/checkout', [ 'as' => 'checkout/hardware', - 'uses' => 'AssetsController@postCheckout' + 'uses' => 'AssetCheckoutController@store' ]); Route::get('{assetId}/checkin/{backto?}', [ 'as' => 'checkin/hardware', - 'uses' => 'AssetsController@getCheckin' + 'uses' => 'AssetCheckinController@create' ]); Route::post('{assetId}/checkin/{backto?}', [ 'as' => 'checkin/hardware', - 'uses' => 'AssetsController@postCheckin' + 'uses' => 'AssetCheckinController@store' ]); Route::get('{assetId}/view', [ 'as' => 'hardware.view', @@ -91,17 +91,17 @@ Route::group( ]); Route::post('{assetId}/upload', [ 'as' => 'upload/asset', - 'uses' => 'AssetsController@postUpload' + 'uses' => 'AssetFilesController@store' ]); - Route::get('{assetId}/showfile/{fileId}', [ + Route::get('{assetId}/showfile/{fileId}/{download?}', [ 'as' => 'show/assetfile', - 'uses' => 'AssetsController@displayFile' + 'uses' => 'AssetFilesController@show' ]); Route::delete('{assetId}/showfile/{fileId}/delete', [ 'as' => 'delete/assetfile', - 'uses' => 'AssetsController@deleteFile' + 'uses' => 'AssetFilesController@destroy' ]); @@ -109,32 +109,32 @@ Route::group( 'bulkedit', [ 'as' => 'hardware/bulkedit', - 'uses' => 'AssetsController@postBulkEdit' + 'uses' => 'BulkAssetsController@edit' ] ); Route::post( 'bulkdelete', [ 'as' => 'hardware/bulkdelete', - 'uses' => 'AssetsController@postBulkDelete' + 'uses' => 'BulkAssetsController@destroy' ] ); Route::post( 'bulksave', [ 'as' => 'hardware/bulksave', - 'uses' => 'AssetsController@postBulkSave' + 'uses' => 'BulkAssetsController@update' ] ); # Bulk checkout / checkin Route::get( 'bulkcheckout', [ 'as' => 'hardware/bulkcheckout', - 'uses' => 'AssetsController@getBulkCheckout' + 'uses' => 'BulkAssetsController@showCheckout' ]); Route::post( 'bulkcheckout', [ 'as' => 'hardware/bulkcheckout', - 'uses' => 'AssetsController@postBulkCheckout' + 'uses' => 'BulkAssetsController@storeCheckout' ]); diff --git a/routes/web/users.php b/routes/web/users.php index 1541e36bea..0dd24311c3 100644 --- a/routes/web/users.php +++ b/routes/web/users.php @@ -5,8 +5,6 @@ Route::group([ 'prefix' => 'users', 'middleware' => ['auth']], function () { Route::get('ldap', ['as' => 'ldap/user', 'uses' => 'UsersController@getLDAP' ]); Route::post('ldap', 'UsersController@postLDAP'); - Route::get('import', [ 'as' => 'import/user', 'uses' => 'UsersController@getImport' ]); - Route::post('import', [ 'uses' => 'UsersController@postImport' ]); Route::get('export', [ 'as' => 'users.export', 'uses' => 'UsersController@getExportUserCsv' ]); Route::get('{userId}/clone', [ 'as' => 'clone/user', 'uses' => 'UsersController@getClone' ]); Route::post('{userId}/clone', [ 'uses' => 'UsersController@postCreate' ]); diff --git a/tests/unit/AssetMaintenanceTest.php b/tests/unit/AssetMaintenanceTest.php index 1f9e5b4ef1..0d56f07d06 100644 --- a/tests/unit/AssetMaintenanceTest.php +++ b/tests/unit/AssetMaintenanceTest.php @@ -59,7 +59,7 @@ class AssetMaintenanceTest extends BaseTest $c->completion_date = '0000-00-00'; $this->assertTrue($c->completion_date===null); $c->completion_date = '2017-05-12'; - $this->assertTrue($c->completion_date==='2017-05-12'); + $this->assertTrue($c->completion_date==Carbon::parse('2017-05-12')); } -} \ No newline at end of file +}