diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 2dd323a10..a4e74cddd 100644 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -36,6 +36,7 @@ class UsersController extends Controller $users = User::select([ 'users.activated', + 'users.created_by', 'users.address', 'users.avatar', 'users.city', @@ -66,7 +67,7 @@ class UsersController extends Controller 'users.remote', 'users.ldap_import', - ])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables') + ])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',) ->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count'); $users = Company::scopeCompanyables($users); @@ -89,6 +90,10 @@ class UsersController extends Controller $users = $users->where('users.location_id', '=', $request->input('location_id')); } + if ($request->filled('created_by')) { + $users = $users->where('users.created_by', '=', $request->input('created_by')); + } + if ($request->filled('email')) { $users = $users->where('users.email', '=', $request->input('email')); } @@ -182,6 +187,9 @@ class UsersController extends Controller case 'department': $users = $users->OrderDepartment($order); break; + case 'created_by': + $users = $users->CreatedBy($order); + break; case 'company': $users = $users->OrderCompany($order); break; diff --git a/app/Http/Controllers/Users/UsersController.php b/app/Http/Controllers/Users/UsersController.php index 0f69e5925..c67cbcb28 100755 --- a/app/Http/Controllers/Users/UsersController.php +++ b/app/Http/Controllers/Users/UsersController.php @@ -117,6 +117,7 @@ class UsersController extends Controller $user->zip = $request->input('zip', null); $user->remote = $request->input('remote', 0); $user->website = $request->input('website', null); + $user->created_by = Auth::user()->id; // Strip out the superuser permission if the user isn't a superadmin $permissions_array = $request->input('permission'); diff --git a/app/Http/Transformers/UsersTransformer.php b/app/Http/Transformers/UsersTransformer.php index 5366a524c..9a498a325 100644 --- a/app/Http/Transformers/UsersTransformer.php +++ b/app/Http/Transformers/UsersTransformer.php @@ -63,6 +63,10 @@ class UsersTransformer 'accessories_count' => (int) $user->accessories_count, 'consumables_count' => (int) $user->consumables_count, 'company' => ($user->company) ? ['id' => (int) $user->company->id, 'name'=> e($user->company->name)] : null, + 'created_by' => ($user->createdBy) ? [ + 'id' => (int) $user->createdBy->id, + 'name'=> e($user->createdBy->present()->fullName), + ] : null, 'created_at' => Helper::getFormattedDateObject($user->created_at, 'datetime'), 'updated_at' => Helper::getFormattedDateObject($user->updated_at, 'datetime'), 'last_login' => Helper::getFormattedDateObject($user->last_login, 'datetime'), diff --git a/app/Models/User.php b/app/Models/User.php index 5c539ad1c..6dad9baee 100755 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -561,6 +561,18 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo return false; } + /** + * Get the admin user who created this user + * + * @author [A. Gianotto] [] + * @since [v6.0.5] + * @return \Illuminate\Database\Eloquent\Relations\Relation + */ + public function createdBy() + { + return $this->belongsTo(\App\Models\User::class, 'created_by')->withTrashed(); + } + /** * Check whether two-factor authorization is required and the user has activated it * and enrolled a device @@ -685,6 +697,23 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo return $query->leftJoin('departments as departments_users', 'users.department_id', '=', 'departments_users.id')->orderBy('departments_users.name', $order); } + /** + * Query builder scope to order on admin user + * + * @param \Illuminate\Database\Query\Builder $query Query builder instance + * @param string $order Order + * + * @return \Illuminate\Database\Query\Builder Modified query builder + */ + public function scopeCreatedBy($query, $order) + { + // Left join here, or it will only return results with parents + return $query->leftJoin('users as admin_user', 'users.created_by', '=', 'admin_user.id') + ->orderBy('admin_user.first_name', $order) + ->orderBy('admin_user.last_name', $order); + } + + /** * Query builder scope to order on company * diff --git a/app/Presenters/UserPresenter.php b/app/Presenters/UserPresenter.php index 7654eb5e2..985348ca6 100644 --- a/app/Presenters/UserPresenter.php +++ b/app/Presenters/UserPresenter.php @@ -285,6 +285,14 @@ class UserPresenter extends Presenter 'visible' => true, 'formatter' => 'trueFalseFormatter', ], + [ + 'field' => 'created_by', + 'searchable' => false, + 'sortable' => true, + 'title' => trans('general.admin'), + 'visible' => false, + 'formatter' => 'usersLinkObjFormatter', + ], [ 'field' => 'created_at', 'searchable' => true, diff --git a/database/migrations/2022_06_23_164407_add_user_id_to_users.php b/database/migrations/2022_06_23_164407_add_user_id_to_users.php new file mode 100644 index 000000000..04a7bf68a --- /dev/null +++ b/database/migrations/2022_06_23_164407_add_user_id_to_users.php @@ -0,0 +1,34 @@ +integer('created_by')->after('activated')->nullable()->default(null); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + if (Schema::hasColumn('users', 'created_by')) { + $table->dropColumn('created_by'); + } + }); + } +} diff --git a/resources/assets/less/skins/skin-black-dark.less b/resources/assets/less/skins/skin-black-dark.less index 1ad32cc4e..ab1d52d4d 100644 --- a/resources/assets/less/skins/skin-black-dark.less +++ b/resources/assets/less/skins/skin-black-dark.less @@ -137,7 +137,9 @@ a { .bootstrap-table .fixed-table-container .table thead th .sortable { color: var(--nav-link); } - +.bootstrap-table .fixed-table-toolbar .columns label { + color:#000; +} .thead, .navbar-nav>li>a:link { color: var(--nav-link); } diff --git a/resources/assets/less/skins/skin-blue-dark.less b/resources/assets/less/skins/skin-blue-dark.less index 56233c505..c4a0d6925 100644 --- a/resources/assets/less/skins/skin-blue-dark.less +++ b/resources/assets/less/skins/skin-blue-dark.less @@ -132,7 +132,9 @@ a { .bootstrap-table .fixed-table-container .table thead th .sortable { color: var(--nav-link); } - +.bootstrap-table .fixed-table-toolbar .columns label { + color:#000; +} .thead, .navbar-nav>li>a:link { color: var(--nav-link); } @@ -149,7 +151,9 @@ a:link { .btn-primary.hover { color: var(--nav-link); } - +.bootstrap-table .fixed-table-toolbar .columns label { + color:#000; +} .small-box h3, .small-box p { color: var(--nav-link) !important; a:hover { diff --git a/resources/assets/less/skins/skin-orange-dark.less b/resources/assets/less/skins/skin-orange-dark.less index 51a37f424..17847a135 100644 --- a/resources/assets/less/skins/skin-orange-dark.less +++ b/resources/assets/less/skins/skin-orange-dark.less @@ -119,6 +119,9 @@ .bootstrap-table .fixed-table-container .table thead th .sortable { color: var(--nav-link); } +.bootstrap-table .fixed-table-toolbar .columns label { + color:#000; +} .thead, .navbar-nav>li>a:link { color: var(--nav-link); diff --git a/resources/assets/less/skins/skin-purple-dark.less b/resources/assets/less/skins/skin-purple-dark.less index c84622345..aee201bf4 100644 --- a/resources/assets/less/skins/skin-purple-dark.less +++ b/resources/assets/less/skins/skin-purple-dark.less @@ -132,7 +132,9 @@ a { .bootstrap-table .fixed-table-container .table thead th .sortable { color: var(--nav-link); } - +.bootstrap-table .fixed-table-toolbar .columns label { + color:#000; +} .thead, .navbar-nav>li>a:link { color: var(--nav-link); } diff --git a/resources/assets/less/skins/skin-red-dark.less b/resources/assets/less/skins/skin-red-dark.less index 2195224cb..fae36405c 100644 --- a/resources/assets/less/skins/skin-red-dark.less +++ b/resources/assets/less/skins/skin-red-dark.less @@ -133,6 +133,9 @@ a { .bootstrap-table .fixed-table-container .table thead th .sortable { color: var(--nav-link); } +.bootstrap-table .fixed-table-toolbar .columns label { + color:#000; +} .thead, .navbar-nav>li>a:link { color: var(--nav-link); diff --git a/resources/assets/less/skins/skin-yellow-dark.less b/resources/assets/less/skins/skin-yellow-dark.less index 88ace6295..dd1ecc05f 100644 --- a/resources/assets/less/skins/skin-yellow-dark.less +++ b/resources/assets/less/skins/skin-yellow-dark.less @@ -103,10 +103,10 @@ a { --back-main: #333; --back-sub: #3d4144; --back-sub-alt: rgba(0, 0, 0, 0.36); - --button-default: #FFFF00; - --button-primary: darken(#FFFF00, 25%); - --button-hover: darken(#FFFF00, 30%); - --header: #FFFF00; /* Use same as Header picker */ + --button-default: #FFCC32; + --button-primary: darken(#FFCC32, 25%); + --button-hover: darken(#FFCC32, 30%); + --header: #FFCC32; /* Use same as Header picker */ --text-main: #BBB; --text-sub: #9b9b9b; --link: #F0E68C; /* Use same as Header picker, lighten by 70% */ @@ -131,7 +131,9 @@ a.btn.btn-default{ .bootstrap-table .fixed-table-container .table thead th .sortable { color: var(--nav-link); } - +.bootstrap-table .fixed-table-toolbar .columns label { + color:#000; +} .thead, .navbar-nav>li>a:link { color: var(--nav-link); } diff --git a/resources/views/users/view.blade.php b/resources/views/users/view.blade.php index 41f7b4774..c41afe19f 100755 --- a/resources/views/users/view.blade.php +++ b/resources/views/users/view.blade.php @@ -463,6 +463,17 @@
{{ \App\Helpers\Helper::getFormattedDateObject($user->created_at, 'datetime')['formatted']}} + + @if ($user->createdBy) + by + @if ($user->createdBy->deleted_at=='') + {{ $user->createdBy->present()->fullName }} + @else + {{ $user->createdBy->present()->fullName }} + @endif + + + @endif
@endif