diff --git a/app/Console/Commands/RecryptFromMcrypt.php b/app/Console/Commands/RecryptFromMcrypt.php index f9b39183ab..a45a1c9bc4 100644 --- a/app/Console/Commands/RecryptFromMcrypt.php +++ b/app/Console/Commands/RecryptFromMcrypt.php @@ -49,7 +49,7 @@ class RecryptFromMcrypt extends Command // If not, we can try to use the current APP_KEY if looks like it's old $legacy_key = env('LEGACY_APP_KEY'); $key_parts = explode(':', $legacy_key); - $legacy_cipher = env('LEGACY_CIPHER'); + $legacy_cipher = env('LEGACY_CIPHER', 'rijndael-256'); $errors = array(); if (!$legacy_key) { diff --git a/app/Console/Commands/SyncAssetLocations.php b/app/Console/Commands/SyncAssetLocations.php new file mode 100644 index 0000000000..a98cedcdb1 --- /dev/null +++ b/app/Console/Commands/SyncAssetLocations.php @@ -0,0 +1,137 @@ +get(); + $bar = $this->output->createProgressBar(count($total_assets)); + + // Unassigned + $rtd_assets = Asset::whereNull('assigned_to')->with('defaultLoc')->get(); + $output['info'][] = 'There are '.$rtd_assets->count().' unassigned assets.'; + + foreach ($rtd_assets as $rtd_asset) { + $output['info'][] = 'Setting Unassigned Asset ' . $rtd_asset->id . ' ('.$rtd_asset->asset_tag.') to location: ' . $rtd_asset->rtd_location_id . " because their default location is: " . $rtd_asset->rtd_location_id; + $rtd_asset->location_id=$rtd_asset->rtd_location_id; + $rtd_asset->unsetEventDispatcher(); + $rtd_asset->save(); + $bar->advance(); + } + + $assigned_user_assets = Asset::where('assigned_type','App\Models\User')->whereNotNull('assigned_to')->get(); + $output['info'][] = 'There are '.$assigned_user_assets->count().' assets checked out to users.'; + foreach ($assigned_user_assets as $assigned_user_asset) { + if (($assigned_user_asset->assignedTo) && ($assigned_user_asset->assignedTo->userLoc)) { + $new_location=$assigned_user_asset->assignedTo->userloc->id; + $output['info'][] ='Setting User Asset ' . $assigned_user_asset->id . ' ('.$assigned_user_asset->asset_tag.') to ' . $assigned_user_asset->assignedTo->userLoc->name . ' which is id: ' . $new_location; + } else { + $output['error'][] ='Asset ' . $assigned_user_asset->id . ' ('.$assigned_user_asset->asset_tag.') still has no location! '; + $new_location=$assigned_user_asset->rtd_location_id; + } + $assigned_user_asset->location_id=$new_location; + $assigned_user_asset->unsetEventDispatcher(); + $assigned_user_asset->save(); + $bar->advance(); + + } + + $assigned_location_assets = Asset::where('assigned_type','App\Models\Location') + ->whereNotNull('assigned_to')->get(); + $output['info'][] = 'There are '.$assigned_location_assets->count().' assets checked out to locations.'; + + foreach ($assigned_location_assets as $assigned_location_asset) { + $assigned_location_asset->location_id = $assigned_location_asset->assignedTo->id; + + $output['info'][] ='Setting Location Assigned asset ' . $assigned_location_asset->id . ' ('.$assigned_location_asset->asset_tag.') that is checked out to '.$assigned_location_asset->assignedTo->name.' (#'.$assigned_location_asset->assignedTo->id.') to location: ' . $assigned_location_asset->assetLoc()->id; + $assigned_location_asset->unsetEventDispatcher(); + $assigned_location_asset->save(); + $bar->advance(); + } + + + // Assigned to assets + $assigned_asset_assets = Asset::where('assigned_type','App\Models\Asset') + ->whereNotNull('assigned_to')->get(); + $output['info'][] ='Asset-assigned assets: '.$assigned_asset_assets->count(); + + foreach ($assigned_asset_assets as $assigned_asset_asset) { + $assigned_asset_asset->location_id = $assigned_asset_asset->assetLoc()->id; + $output['info'][] ='Setting Asset Assigned asset ' . $assigned_asset_asset->assetLoc()->id. ' ('.$assigned_asset_asset->asset_tag.') location to: ' . $assigned_asset_asset->assetLoc()->id; + $assigned_asset_asset->unsetEventDispatcher(); + $assigned_asset_asset->save(); + $bar->advance(); + + } + + $unlocated_assets = Asset::whereNull("location_id")->get(); + $output['info'][] ='Assets still without a location: '.$unlocated_assets->count(); + foreach($unlocated_assets as $unlocated_asset) { + $output['warn'][] ='Asset: '.$unlocated_asset->id.' still has no location. '; + $bar->advance(); + } + + $bar->finish(); + $this->info("\n"); + + + if (($this->option('output')=='all') || ($this->option('output')=='info')) { + foreach ($output['info'] as $key => $output_text) { + $this->info($output_text); + } + } + if (($this->option('output')=='all') || ($this->option('output')=='warn')) { + foreach ($output['warn'] as $key => $output_text) { + $this->warn($output_text); + } + } + if (($this->option('output')=='all') || ($this->option('output')=='error')) { + foreach ($output['error'] as $key => $output_text) { + $this->error($output_text); + } + } + + + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 0f81098b19..cc104d8e4b 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -26,7 +26,8 @@ class Kernel extends ConsoleKernel Commands\LdapSync::class, Commands\FixDoubleEscape::class, Commands\RecryptFromMcrypt::class, - Commands\ResetDemoSettings::class + Commands\ResetDemoSettings::class, + Commands\SyncAssetLocations::class, ]; /** diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index dfc725ad39..2f44ac7965 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -112,7 +112,7 @@ class AssetsController extends Controller } if ($request->has('location_id')) { - $assets->ByLocationId($request->input('location_id')); + $assets->where('assets.location_id', '=', $request->input('location_id')); } if ($request->has('supplier_id')) { @@ -421,6 +421,8 @@ class AssetsController extends Controller $asset->requestable = $request->get('requestable') : ''; ($request->has('rtd_location_id')) ? $asset->rtd_location_id = $request->get('rtd_location_id') : ''; + ($request->has('rtd_location_id')) ? + $asset->location_id = $request->get('rtd_location_id') : ''; ($request->has('company_id')) ? $asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : ''; @@ -438,14 +440,17 @@ class AssetsController extends Controller if ($request->get('assigned_user')) { $target = User::find(request('assigned_user')); + $location = $target->location_id; } elseif ($request->get('assigned_asset')) { $target = Asset::find(request('assigned_asset')); + $location = $target->location_id; } elseif ($request->get('assigned_location')) { $target = Location::find(request('assigned_location')); + $location = $target->id; } if (isset($target)) { - $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name'))); + $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location); } return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success'))); @@ -512,14 +517,18 @@ class AssetsController extends Controller ]; if ($request->has('user_id')) { $target = User::find($request->input('user_id')); + $location = $target->location_id; $error_payload['target_id'] = $request->input('user_id'); $error_payload['target_type'] = User::class; // Don't let the user check an asset out to itself } elseif ($request->has('asset_id')) { $target = Asset::where('id','!=',$asset_id)->find($request->input('asset_id')); + $location = $target->location_id; $error_payload['target_id'] = $request->input('asset_id'); $error_payload['target_type'] = Asset::class; } elseif ($request->has('location_id')) { + $target = Location::find($request->input('location_id')); + $location = $target->id; $target = Location::find($request->input('location_id')); $error_payload['target_id'] = $request->input('location_id'); $error_payload['target_type'] = Location::class; @@ -541,13 +550,11 @@ class AssetsController extends Controller $asset->location_id = $target->rtd_location_id; } - // Overwrite that if the target has a location ID though - if ($target->location_id!='') { - $asset->location_id = $target->location_id; - } + $asset->location_id = $location; + - if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name)) { + if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name, $location)) { return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.success'))); } @@ -563,7 +570,7 @@ class AssetsController extends Controller * @since [v4.0] * @return JsonResponse */ - public function checkin($asset_id) + public function checkin(Request $request, $asset_id) { $this->authorize('checkin', Asset::class); $asset = Asset::findOrFail($asset_id); @@ -581,6 +588,13 @@ class AssetsController extends Controller $asset->assignedTo()->disassociate($asset); $asset->accepted = null; $asset->name = e(Input::get('name')); + $asset->location_id = $asset->rtd_location_id; + + if ($request->has('location_id')) { + $asset->location_id = $request->input('location_id'); + } + + $asset->location_id = $asset->rtd_location_id; if (Input::has('status_id')) { $asset->status_id = e(Input::get('status_id')); diff --git a/app/Http/Controllers/Api/LocationsController.php b/app/Http/Controllers/Api/LocationsController.php index 27140fff29..6bc2491221 100644 --- a/app/Http/Controllers/Api/LocationsController.php +++ b/app/Http/Controllers/Api/LocationsController.php @@ -24,7 +24,7 @@ class LocationsController extends Controller $allowed_columns = [ 'id','name','address','address2','city','state','country','zip','created_at', 'updated_at','parent_id', 'manager_id','image', - 'rtd_assets_count','users_count','assets_count']; + 'assigned_assets_count','users_count','assets_count']; $locations = Location::with('parent', 'manager', 'childLocations')->select([ 'locations.id', @@ -41,7 +41,7 @@ class LocationsController extends Controller 'locations.updated_at', 'locations.image', 'locations.currency' - ])->withCount('rtd_assets') + ])->withCount('assignedAssets') ->withCount('assets') ->withCount('users'); diff --git a/app/Http/Controllers/AssetsController.php b/app/Http/Controllers/AssetsController.php index 7daea872c0..f4861f4db2 100755 --- a/app/Http/Controllers/AssetsController.php +++ b/app/Http/Controllers/AssetsController.php @@ -160,6 +160,10 @@ class AssetsController extends Controller $asset->requestable = request('requestable', 0); $asset->rtd_location_id = request('rtd_location_id', null); + if ($asset->assigned_to=='') { + $asset->location_id = $request->input('rtd_location_id', null); + } + // Create the image (if one was chosen.) if ($request->has('image')) { $image = $request->input('image'); @@ -199,8 +203,6 @@ class AssetsController extends Controller // Update custom fields in the database. // Validation for these fields is handled through the AssetRequest form request - // FIXME: No idea why this is returning a Builder error on db_column_name. - // Need to investigate and fix. Using static method for now. $model = AssetModel::find($request->get('model_id')); if ($model->fieldset) { @@ -218,15 +220,20 @@ class AssetsController extends Controller // Was the asset created? if ($asset->save()) { $asset->logCreate(); + if (request('assigned_user')) { $target = User::find(request('assigned_user')); + $location = $target->location_id; } elseif (request('assigned_asset')) { $target = Asset::find(request('assigned_asset')); + $location = $target->location_id; } elseif (request('assigned_location')) { $target = Location::find(request('assigned_location')); + $location = $target->id; } + if (isset($target)) { - $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e(Input::get('name'))); + $asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e(Input::get('name')), $location); } // Redirect to the asset listing page \Session::flash('success', trans('admin/hardware/message.create.success')); @@ -289,6 +296,11 @@ class AssetsController extends Controller $asset->requestable = $request->has('requestable'); $asset->rtd_location_id = $request->input('rtd_location_id', null); + if ($asset->assigned_to=='') { + $asset->location_id = $request->input('rtd_location_id', null); + } + + if ($request->has('image_delete')) { unlink(public_path().'/uploads/assets/'.$asset->image); $asset->image = ''; @@ -546,6 +558,8 @@ class AssetsController extends Controller $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')); } diff --git a/app/Http/Transformers/LocationsTransformer.php b/app/Http/Transformers/LocationsTransformer.php index 3009f93ead..636c039a91 100644 --- a/app/Http/Transformers/LocationsTransformer.php +++ b/app/Http/Transformers/LocationsTransformer.php @@ -39,8 +39,8 @@ class LocationsTransformer 'state' => e($location->state), 'country' => e($location->country), 'zip' => e($location->zip), - 'assets_count' => (int) $location->assets_count, - 'rtd_assets_count' => (int) $location->rtd_assets_count, + 'assigned_assets_count' => (int) $location->assigned_assets_count, + 'assets_count' => (int) $location->assets_count, 'users_count' => (int) $location->users_count, 'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'), diff --git a/app/Models/Asset.php b/app/Models/Asset.php index df0905ba52..cb5aee97cd 100644 --- a/app/Models/Asset.php +++ b/app/Models/Asset.php @@ -144,7 +144,7 @@ class Asset extends Depreciable * @return bool */ //FIXME: The admin parameter is never used. Can probably be removed. - public function checkOut($target, $admin = null, $checkout_at = null, $expected_checkin = null, $note = null, $name = null) + public function checkOut($target, $admin = null, $checkout_at = null, $expected_checkin = null, $note = null, $name = null, $location = null) { if (!$target) { return false; @@ -163,6 +163,10 @@ class Asset extends Depreciable $this->name = $name; } + if ($location != null) { + $this->location_id = $location; + } + if ($this->requireAcceptance()) { if(get_class($target) != User::class) { throw new CheckoutNotAllowed; @@ -1117,14 +1121,7 @@ class Asset extends Depreciable $query->where('locations.id', '=', $search); }); }); - // FIXME: This needs porting to checkout to non-user. - // ->orWhere(function ($query) use ($search) { - // $query->whereHas('assigneduser', function ($query) use ($search) { - // $query->whereHas('userloc', function ($query) use ($search) { - // $query->where('locations.id', '=', $search); - // }); - // }); - // }); + } diff --git a/app/Models/Location.php b/app/Models/Location.php index 6a416a4173..bfc7cebf70 100755 --- a/app/Models/Location.php +++ b/app/Models/Location.php @@ -54,7 +54,12 @@ class Location extends SnipeModel public function assets() { - return $this->hasMany('\App\Models\Asset', 'location_id'); + return $this->hasMany('\App\Models\Asset', 'location_id') + ->whereHas('assetstatus', function ($query) { + $query->where('status_labels.deployable', '=', 1) + ->orWhere('status_labels.pending', '=', 1) + ->orWhere('status_labels.archived', '=', 0); + }); } public function rtd_assets() @@ -92,7 +97,6 @@ class Location extends SnipeModel public function assignedAssets() { return $this->morphMany('App\Models\Asset', 'assigned', 'assigned_type', 'assigned_to')->withTrashed(); - // return $this->hasMany('\App\Models\Asset', 'assigned_to')->withTrashed(); } public function setLdapOuAttribute($ldap_ou) diff --git a/resources/views/locations/index.blade.php b/resources/views/locations/index.blade.php index ab023f776e..c1034fdd6a 100755 --- a/resources/views/locations/index.blade.php +++ b/resources/views/locations/index.blade.php @@ -31,8 +31,8 @@ {{ trans('admin/locations/table.name') }} {{ trans('general.image') }} {{ trans('admin/locations/table.parent') }} - {{ trans('admin/locations/table.assets_rtd') }} - {{ trans('admin/locations/table.assets_checkedout') }} + {{ trans('admin/locations/table.assets_rtd') }} + {{ trans('admin/locations/table.assets_checkedout') }} {{ trans('general.people') }} {{ trans('general.currency') }} {{ trans('admin/locations/table.address') }}