Compare commits

...

9 Commits

Author SHA1 Message Date
snipe 70c8ad9797 Bumped minor version 2019-10-28 13:55:21 -07:00
snipe 0290257734 Limit license seats to 999 to prevent latency 2019-10-28 13:48:18 -07:00
snipe 4fe689dc5d Merge branch 'master' of https://github.com/snipe/snipe-it 2019-10-21 15:45:17 -07:00
snipe 0769f585ea Disallow locations from being their own parents 2019-10-21 15:45:05 -07:00
snipe 04562e6d4a Added 4260352 to ldapsync enabled account constraint 2019-10-18 17:48:50 -07:00
snipe 22d2ad9248 Fixes nested location selectlist (#7483)
* Rename child locations method

* Use Ajax dropdown for locations selectlist for edit/create

* Removed locations database call on edit/create blades for faster loading

* Updated locations controller to use the new iterator

* Increase pagination on locations controller to 500

We’re already loading all of that data up beforehand anyway, so no point in keeping the query smaller.

* Fixed the else to make codacy happy

* Improve the design and performance of the nested location selectlist (#7484)

* Improve the design and performance of the nested location selectlist

* Fixed parse errors

* Removed debugging code/comments
2019-10-02 03:56:56 -07:00
snipe 6deb26fafe Remove unused variable 2019-09-30 19:37:52 -07:00
snipe 6c1de7ff05 Apply fix for #6642 to master 2019-09-30 19:21:57 -07:00
snipe 7f5f4a1297 Added softwarew support and hardware support to maintenance types 2019-09-24 01:34:23 -07:00
12 changed files with 118 additions and 100 deletions
+1 -1
View File
@@ -189,7 +189,7 @@ class LdapSync extends Command
// Sync activated state for Active Directory.
if ( array_key_exists('useraccountcontrol', $results[$i]) ) {
$enabled_accounts = [
'512', '544', '66048', '66080', '262656', '262688', '328192', '328224'
'512', '544', '66048', '66080', '262656', '262688', '328192', '328224', '4260352'
];
$user->activated = ( in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts) ) ? 1 : 0;
}
@@ -8,6 +8,8 @@ use App\Helpers\Helper;
use App\Models\Location;
use App\Http\Transformers\LocationsTransformer;
use App\Http\Transformers\SelectlistTransformer;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
class LocationsController extends Controller
{
@@ -26,7 +28,7 @@ class LocationsController extends Controller
'updated_at','manager_id','image',
'assigned_assets_count','users_count','assets_count','currency'];
$locations = Location::with('parent', 'manager', 'childLocations')->select([
$locations = Location::with('parent', 'manager', 'children')->select([
'locations.id',
'locations.name',
'locations.address',
@@ -109,7 +111,7 @@ class LocationsController extends Controller
public function show($id)
{
$this->authorize('view', Location::class);
$location = Location::with('parent', 'manager', 'childLocations')
$location = Location::with('parent', 'manager', 'children')
->select([
'locations.id',
'locations.name',
@@ -146,6 +148,13 @@ class LocationsController extends Controller
{
$this->authorize('update', Location::class);
$location = Location::findOrFail($id);
if ($request->input('parent_id') == $id) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'A location cannot be its own parent. Please select a different parent ID.'));
}
$location->fill($request->all());
if ($location->save()) {
@@ -181,6 +190,27 @@ class LocationsController extends Controller
/**
* Gets a paginated collection for the select2 menus
*
* This is handled slightly differently as of ~4.7.8-pre, as
* we have to do some recursive magic to get the hierarchy to display
* properly when looking at the parent/child relationship in the
* rich menus.
*
* This means we can't use the normal pagination that we use elsewhere
* in our selectlists, since we have to get the full set before we can
* determine which location is parent/child/grandchild, etc.
*
* This also means that hierarchy display gets a little funky when people
* use the Select2 search functionality, but there's not much we can do about
* that right now.
*
* As a result, instead of paginating as part of the query, we have to grab
* the entire data set, and then invoke a paginator manually and pass that
* through to the SelectListTransformer.
*
* Many thanks to @uberbrady for the help getting this working better.
* Recursion still sucks, but I guess he doesn't have to get in the
* sea... this time.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0.16]
* @see \App\Http\Transformers\SelectlistTransformer
@@ -192,25 +222,39 @@ class LocationsController extends Controller
$locations = Location::select([
'locations.id',
'locations.name',
'locations.parent_id',
'locations.image',
]);
$page = 1;
if ($request->filled('page')) {
$page = $request->input('page');
}
if ($request->filled('search')) {
$locations = $locations->where('locations.name', 'LIKE', '%'.$request->get('search').'%');
\Log::debug('Searching... ');
$locations = $locations->where('locations.name', 'LIKE', '%'.$request->input('search').'%');
}
$locations = $locations->orderBy('name', 'ASC')->paginate(50);
$locations = $locations->orderBy('name', 'ASC')->get();
// Loop through and set some custom properties for the transformer to use.
// This lets us have more flexibility in special cases like assets, where
// they may not have a ->name value but we want to display something anyway
$locations_with_children = [];
foreach ($locations as $location) {
$location->use_text = $location->name;
$location->use_image = ($location->image) ? url('/').'/uploads/locations/'.$location->image : null;
if(!array_key_exists($location->parent_id, $locations_with_children)) {
$locations_with_children[$location->parent_id] = [];
}
$locations_with_children[$location->parent_id][] = $location;
}
return (new SelectlistTransformer)->transformSelectlist($locations);
$location_options = Location::indenter($locations_with_children);
$locations_formatted = new Collection($location_options);
$paginated_results = new LengthAwarePaginator($locations_formatted->forPage($page, 500), $locations_formatted->count(), 500, $page, []);
//return [];
return (new SelectlistTransformer)->transformSelectlist($paginated_results);
}
}
+7 -17
View File
@@ -41,8 +41,6 @@ class LocationsController extends Controller
{
// Grab all the locations
$this->authorize('view', Location::class);
$locations = Location::orderBy('created_at', 'DESC')->with('parent', 'assets', 'assignedassets')->get();
// Show the page
return view('locations/index');
}
@@ -59,14 +57,7 @@ class LocationsController extends Controller
public function create()
{
$this->authorize('create', Location::class);
$locations = Location::orderBy('name', 'ASC')->get();
$location_options_array = Location::getLocationHierarchy($locations);
$location_options = Location::flattenLocationsArray($location_options_array);
$location_options = array('' => 'Top Level') + $location_options;
return view('locations/edit')
->with('location_options', $location_options)
->with('item', new Location);
}
@@ -132,14 +123,8 @@ class LocationsController extends Controller
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
}
// Show the page
$locations = Location::orderBy('name', 'ASC')->get();
$location_options_array = Location::getLocationHierarchy($locations);
$location_options = Location::flattenLocationsArray($location_options_array);
$location_options = array('' => 'Top Level') + $location_options;
return view('locations/edit', compact('item'))
->with('location_options', $location_options);
return view('locations/edit', compact('item'));
}
@@ -160,6 +145,11 @@ class LocationsController extends Controller
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
}
if ($request->input('parent_id') == $locationId) {
return redirect()->back()->withInput()->with('error', 'A location cannot be its own parent. Please select a different parent location.');
}
// Update the location data
$location->name = $request->input('name');
$location->parent_id = $request->input('parent_id', null);
@@ -229,7 +219,7 @@ class LocationsController extends Controller
if ($location->users->count() > 0) {
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_users'));
} elseif ($location->childLocations->count() > 0) {
} elseif ($location->children->count() > 0) {
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_child_loc'));
} elseif ($location->assets->count() > 0) {
@@ -23,7 +23,7 @@ class LocationsTransformer
if ($location) {
$children_arr = [];
foreach($location->childLocations as $child) {
foreach($location->children as $child) {
$children_arr[] = [
'id' => (int) $child->id,
'name' => $child->name
+10 -2
View File
@@ -27,9 +27,17 @@ class AssetImporter extends ItemImporter
foreach ($this->customFields as $customField) {
$customFieldValue = $this->array_smart_custom_field_fetch($row, $customField);
if ($customFieldValue) {
$this->item['custom_fields'][$customField->db_column_name()] = $customFieldValue;
$this->log('Custom Field '. $customField->name.': '.$customFieldValue);
if ($customField->field_encrypted == 1) {
$this->item['custom_fields'][$customField->db_column_name()] = \Crypt::encrypt($customFieldValue);
$this->log('Custom Field '. $customField->name.': '.\Crypt::encrypt($customFieldValue));
} else {
$this->item['custom_fields'][$customField->db_column_name()] = $customFieldValue;
$this->log('Custom Field '. $customField->name.': '.$customFieldValue);
}
} else {
// Clear out previous data.
$this->item['custom_fields'][$customField->db_column_name()] = null;
+2 -1
View File
@@ -73,7 +73,8 @@ class AssetMaintenance extends Model implements ICompanyableChild
trans('admin/asset_maintenances/general.upgrade') => trans('admin/asset_maintenances/general.upgrade'),
'PAT test' => 'PAT test',
trans('admin/asset_maintenances/general.calibration') => trans('admin/asset_maintenances/general.calibration'),
'PAT test' => 'PAT test',
'Software Support' => trans('admin/asset_maintenances/general.software_support'),
'Hardware Support' => trans('admin/asset_maintenances/general.hardware_support'),
];
}
+1 -1
View File
@@ -48,7 +48,7 @@ class License extends Depreciable
protected $table = 'licenses';
protected $rules = array(
'name' => 'required|string|min:3|max:255',
'seats' => 'required|min:1|max:1000000|integer',
'seats' => 'required|min:1|max:999|integer',
'license_email' => 'email|nullable|max:120',
'license_name' => 'string|nullable|max:100',
'notes' => 'string|nullable',
+29 -50
View File
@@ -113,7 +113,8 @@ class Location extends SnipeModel
public function parent()
{
return $this->belongsTo('\App\Models\Location', 'parent_id','id');
return $this->belongsTo('\App\Models\Location', 'parent_id','id')
->with('parent');
}
public function manager()
@@ -121,9 +122,9 @@ class Location extends SnipeModel
return $this->belongsTo('\App\Models\User', 'manager_id');
}
public function childLocations()
{
return $this->hasMany('\App\Models\Location', 'parent_id');
public function children() {
return $this->hasMany('\App\Models\Location','parent_id')
->with('children');
}
// I don't think we need this anymore since we de-normed location_id in assets?
@@ -137,59 +138,37 @@ class Location extends SnipeModel
return $this->attributes['ldap_ou'] = empty($ldap_ou) ? null : $ldap_ou;
}
public static function getLocationHierarchy($locations, $parent_id = null)
{
/**
* Query builder scope to order on parent
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
$op = array();
foreach ($locations as $location) {
if ($location['parent_id'] == $parent_id) {
$op[$location['id']] =
array(
'name' => $location['name'],
'parent_id' => $location['parent_id']
);
// Using recursion
$children = Location::getLocationHierarchy($locations, $location['id']);
if ($children) {
$op[$location['id']]['children'] = $children;
}
}
public static function indenter($locations_with_children, $parent_id = null, $prefix = '') {
$results = Array();
if (!array_key_exists($parent_id, $locations_with_children)) {
return [];
}
return $op;
foreach ($locations_with_children[$parent_id] as $location) {
$location->use_text = $prefix.' '.$location->name;
$location->use_image = ($location->image) ? url('/').'/uploads/locations/'.$location->image : null;
$results[] = $location;
//now append the children. (if we have any)
if (array_key_exists($location->id, $locations_with_children)) {
$results = array_merge($results, Location::indenter($locations_with_children, $location->id,$prefix.'--'));
}
}
return $results;
}
public static function flattenLocationsArray($location_options_array = null)
{
$location_options = array();
foreach ($location_options_array as $id => $value) {
// get the top level key value
$location_options[$id] = $value['name'];
// If there is a key named children, it has child locations and we have to walk it
if (array_key_exists('children', $value)) {
foreach ($value['children'] as $child_id => $child_location_array) {
$child_location_options = Location::flattenLocationsArray($value['children']);
foreach ($child_location_options as $child_id => $child_name) {
$location_options[$child_id] = '--'.$child_name;
}
}
}
}
return $location_options;
}
/**
* Query builder scope to order on parent
+5 -5
View File
@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v4.7.7',
'full_app_version' => 'v4.7.7 - build 4160-gb8f7cd81e',
'build_version' => '4160',
'app_version' => 'v4.7.8',
'full_app_version' => 'v4.7.8 - build 4170-g4fe689dc5',
'build_version' => '4170',
'prerelease_version' => '',
'hash_version' => 'gb8f7cd81e',
'full_hash' => 'v4.7.7-41-gb8f7cd81e',
'hash_version' => 'g4fe689dc5',
'full_hash' => 'v4.7.8-7-g4fe689dc5',
'branch' => 'master',
);
@@ -8,5 +8,7 @@
'repair' => 'Repair',
'maintenance' => 'Maintenance',
'upgrade' => 'Upgrade',
'calibration' => 'Calibration'
'calibration' => 'Calibration',
'software_support' => 'Software Support',
'hardware_support' => 'Hardware Support',
];
@@ -7,5 +7,7 @@
'view' => 'Voir les détails de la maintenance d\'actif',
'repair' => 'Réparation',
'maintenance' => 'Entretien',
'upgrade' => 'Mise à niveau'
'upgrade' => 'Mise à niveau',
'software_support' => 'Support logiciel',
'hardware_support' => 'Support matériel',
];
+2 -10
View File
@@ -10,16 +10,8 @@
@section('inputFields')
@include ('partials.forms.edit.name', ['translated_name' => trans('admin/locations/table.name')])
<!-- Parent-->
<div class="form-group {{ $errors->has('parent_id') ? ' has-error' : '' }}">
<label for="parent_id" class="col-md-3 control-label">
{{ trans('admin/locations/table.parent') }}
</label>
<div class="col-md-9{{ (\App\Helpers\Helper::checkIfRequired($item, 'parent_id')) ? ' required' : '' }}">
{!! Form::select('parent_id', $location_options , Input::old('parent_id', $item->parent_id), array('class'=>'select2 parent', 'style'=>'width:350px')) !!}
{!! $errors->first('parent_id', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
<!-- parent -->
@include ('partials.forms.edit.location-select', ['translated_name' => trans('admin/locations/table.parent'), 'fieldname' => 'parent_id'])
<!-- Manager-->
@include ('partials.forms.edit.user-select', ['translated_name' => trans('admin/users/table.manager'), 'fieldname' => 'manager_id'])