Merge branch 'develop'

This commit is contained in:
snipe 2017-11-03 21:53:13 -07:00
commit dc10f18188
10 changed files with 197 additions and 30 deletions

View file

@ -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) {

View file

@ -0,0 +1,137 @@
<?php
namespace App\Console\Commands;
use App\Models\CustomField;
use Illuminate\Console\Command;
use App\Models\Asset;
use Illuminate\Support\Facades\Storage;
class SyncAssetLocations extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:sync-asset-locations {--output= : info|warn|error|all} ';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This utility will sync the location_id of assets based on current state. It should not normally be needed, but is a safeguard in case we missed something in the Great Migration when flattening the assets to location relationship.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$output['info'] = [];
$output['warn'] = [];
$output['error'] = [];
$total_assets = Asset::whereNull('deleted_at')->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);
}
}
}
}

View file

@ -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,
];
/**

View file

@ -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'));

View file

@ -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');

View file

@ -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'));
}

View file

@ -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'),

View file

@ -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);
// });
// });
// });
}

View file

@ -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)

View file

@ -31,8 +31,8 @@
<th data-sortable="true" data-formatter="locationsLinkFormatter" data-field="name" data-searchable="true">{{ trans('admin/locations/table.name') }}</th>
<th data-sortable="true" data-field="image" data-visible="false" data-formatter="imageFormatter">{{ trans('general.image') }}</th>
<th data-sortable="true" data-field="parent" data-formatter="locationsLinkObjFormatter">{{ trans('admin/locations/table.parent') }}</th>
<th data-searchable="false" data-sortable="true" data-field="rtd_assets_count">{{ trans('admin/locations/table.assets_rtd') }}</th>
<th data-searchable="false" data-sortable="true" data-field="assets_count">{{ trans('admin/locations/table.assets_checkedout') }}</th>
<th data-searchable="false" data-sortable="true" data-field="assets_count">{{ trans('admin/locations/table.assets_rtd') }}</th>
<th data-searchable="false" data-sortable="true" data-field="assigned_assets_count">{{ trans('admin/locations/table.assets_checkedout') }}</th>
<th data-searchable="false" data-sortable="true" data-field="users_count">{{ trans('general.people') }}</th>
<th data-searchable="true" data-sortable="true" data-field="currency">{{ trans('general.currency') }}</th>
<th data-searchable="true" data-sortable="true" data-field="address">{{ trans('admin/locations/table.address') }}</th>