mirror of
https://github.com/snipe/snipe-it.git
synced 2024-11-10 23:54:12 -08:00
Merge branch 'develop'
This commit is contained in:
commit
dc10f18188
|
@ -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) {
|
||||
|
|
137
app/Console/Commands/SyncAssetLocations.php
Normal file
137
app/Console/Commands/SyncAssetLocations.php
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
@ -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'));
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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'));
|
||||
}
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue