diff --git a/.all-contributorsrc b/.all-contributorsrc index c910b1b48..7f9f3f8de 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2783,6 +2783,24 @@ "contributions": [ "code" ] + }, + { + "login": "lukasfehling", + "name": "Lukas Fehling", + "avatar_url": "https://avatars.githubusercontent.com/u/56871540?v=4", + "profile": "https://github.com/lukasfehling", + "contributions": [ + "code" + ] + }, + { + "login": "fernando-almeida", + "name": "Fernando Almeida", + "avatar_url": "https://avatars.githubusercontent.com/u/1975990?v=4", + "profile": "https://github.com/fernando-almeida", + "contributions": [ + "code" + ] } ] } diff --git a/README.md b/README.md index 918a47fa0..199f11f43 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade) -[![All Contributors](https://img.shields.io/badge/all_contributors-306-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev) +[![All Contributors](https://img.shields.io/badge/all_contributors-308-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev) ## Snipe-IT - Open Source Asset Management System @@ -138,7 +138,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken | [
Alex Janes](https://adagiohealth.org)
[💻](https://github.com/snipe/snipe-it/commits?author=adagioajanes "Code") | [
Nuraeil](https://github.com/nuraeil)
[💻](https://github.com/snipe/snipe-it/commits?author=nuraeil "Code") | [
TenOfTens](https://github.com/TenOfTens)
[💻](https://github.com/snipe/snipe-it/commits?author=TenOfTens "Code") | [
waffle](https://ditisjens.be/)
[💻](https://github.com/snipe/snipe-it/commits?author=insert-waffle "Code") | [
Yevhenii Huzii](https://github.com/QveenSi)
[💻](https://github.com/snipe/snipe-it/commits?author=QveenSi "Code") | [
Achmad Fienan Rahardianto](https://github.com/veenone)
[💻](https://github.com/snipe/snipe-it/commits?author=veenone "Code") | [
Yevhenii Huzii](https://github.com/QveenSi)
[💻](https://github.com/snipe/snipe-it/commits?author=QveenSi "Code") | | [
Christian Weirich](https://github.com/chrisweirich)
[💻](https://github.com/snipe/snipe-it/commits?author=chrisweirich "Code") | [
denzfarid](https://github.com/denzfarid)
| [
ntbutler-nbcs](https://github.com/ntbutler-nbcs)
[💻](https://github.com/snipe/snipe-it/commits?author=ntbutler-nbcs "Code") | [
Naveen](https://naveensrinivasan.dev)
[💻](https://github.com/snipe/snipe-it/commits?author=naveensrinivasan "Code") | [
Mike Roquemore](https://github.com/mikeroq)
[💻](https://github.com/snipe/snipe-it/commits?author=mikeroq "Code") | [
Daniel Reeder](https://github.com/reederda)
[🌍](#translation-reederda "Translation") [🌍](#translation-reederda "Translation") [💻](https://github.com/snipe/snipe-it/commits?author=reederda "Code") | [
vickyjaura183](https://github.com/vickyjaura183)
[💻](https://github.com/snipe/snipe-it/commits?author=vickyjaura183 "Code") | | [
Peace](https://github.com/julian-piehl)
[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [
Kyle Gordon](https://github.com/kylegordon)
[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [
Katharina Drexel](http://www.bfh.ch)
[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [
David Sferruzza](https://david.sferruzza.fr/)
[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [
Rick Nelson](https://github.com/rnelsonee)
[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [
BasO12](https://github.com/BasO12)
[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [
Vautia](https://github.com/Vautia)
[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") | -| [
Chris Hartjes](http://www.littlehart.net/atthekeyboard)
[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [
geo-chen](https://github.com/geo-chen)
[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [
Phan Nguyen](https://github.com/nh314)
[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [
Iisakki Jaakkola](https://github.com/StarlessNights)
[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [
Ikko Ashimine](https://bandism.net/)
[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | +| [
Chris Hartjes](http://www.littlehart.net/atthekeyboard)
[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [
geo-chen](https://github.com/geo-chen)
[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [
Phan Nguyen](https://github.com/nh314)
[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [
Iisakki Jaakkola](https://github.com/StarlessNights)
[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [
Ikko Ashimine](https://bandism.net/)
[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [
Lukas Fehling](https://github.com/lukasfehling)
[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [
Fernando Almeida](https://github.com/fernando-almeida)
[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! diff --git a/app/Http/Controllers/Api/AssetsController.php b/app/Http/Controllers/Api/AssetsController.php index 9d6c3f116..ee37c3ad0 100644 --- a/app/Http/Controllers/Api/AssetsController.php +++ b/app/Http/Controllers/Api/AssetsController.php @@ -120,7 +120,6 @@ class AssetsController extends Controller if ($filter_non_deprecable_assets) { $non_deprecable_models = AssetModel::select('id')->whereNotNull('depreciation_id')->get(); - $assets->InModelList($non_deprecable_models->toArray()); } @@ -141,6 +140,14 @@ class AssetsController extends Controller $assets->where('assets.status_id', '=', $request->input('status_id')); } + if ($request->filled('asset_tag')) { + $assets->where('assets.asset_tag', '=', $request->input('asset_tag')); + } + + if ($request->filled('serial')) { + $assets->where('assets.serial', '=', $request->input('serial')); + } + if ($request->input('requestable') == 'true') { $assets->where('assets.requestable', '=', '1'); } @@ -357,19 +364,28 @@ class AssetsController extends Controller /** * Returns JSON with information about an asset (by tag) for detail view. * - * @author [A. Gianotto] [] * @param string $tag * @since [v4.2.1] - * @return JsonResponse + * @author [A. Gianotto] [] + * @return \Illuminate\Http\JsonResponse */ public function showByTag(Request $request, $tag) { - if ($asset = Asset::with('assetstatus')->with('assignedTo')->where('asset_tag', $tag)->first()) { - $this->authorize('view', $asset); + $this->authorize('index', Asset::class); + $assets = Asset::where('asset_tag', $tag)->with('assetstatus')->with('assignedTo'); - return (new AssetsTransformer)->transformAsset($asset, $request); + // Check if they've passed ?deleted=true + if ($request->input('deleted', 'false') == 'true') { + $assets = $assets->withTrashed(); + } + + $assets = $assets->get(); + + if (($assets) && ($assets->count() > 0)) { + return (new AssetsTransformer)->transformAssets($assets, $assets->count()); + } else { + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200); } - return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200); } @@ -379,28 +395,24 @@ class AssetsController extends Controller * @author [A. Gianotto] [] * @param string $serial * @since [v4.2.1] - * @return JsonResponse + * @return \Illuminate\Http\JsonResponse */ public function showBySerial(Request $request, $serial) { $this->authorize('index', Asset::class); - if ($assets = Asset::with('assetstatus')->with('assignedTo') - ->withTrashed()->where('serial', $serial)->get()) { - return (new AssetsTransformer)->transformAssets($assets, $assets->count()); - } - return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200); + $assets = Asset::where('serial', $serial)->with('assetstatus')->with('assignedTo'); - $assets = Asset::with('assetstatus')->with('assignedTo'); - - if ($request->input('deleted', 'false') === 'true') { + // Check if they've passed ?deleted=true + if ($request->input('deleted', 'false') == 'true') { $assets = $assets->withTrashed(); - } + } - $assets = $assets->where('serial', $serial)->get(); - if ($assets) { + $assets = $assets->get(); + + if (($assets) && ($assets->count() > 0)) { return (new AssetsTransformer)->transformAssets($assets, $assets->count()); } else { - return response()->json(Helper::formatStandardApiResponse('error', null, 'Asset not found'), 200); + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200); } } diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index eded29f82..4a243c7cb 100644 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -15,6 +15,7 @@ use App\Models\Asset; use App\Models\Company; use App\Models\License; use App\Models\User; +use App\Notifications\CurrentInventory; use Auth; use Illuminate\Http\Request; use App\Http\Requests\ImageUploadRequest; @@ -490,6 +491,37 @@ class UsersController extends Controller return (new AssetsTransformer)->transformAssets($assets, $assets->count(), $request); } + /** + * Notify a specific user via email with all of his assigned assets. + * + * @author [Lukas Fehling] [] + * @since [v6.0.13] + * @param Request $request + * @param $id + * @return string JSON + */ + public function emailAssetList(Request $request, $id) + { + $user = User::findOrFail($id); + + if (empty($user->email)) { + return response()->json( + [ + 'status' => 'error', + 'message' => 'This user has no email set.', + 'payload' => null, + ], 404); + } + + $user->notify((new CurrentInventory($user))); + + return response()->json( + [ + 'status' => 'success', + 'message' => 'The user was notified about his current inventory.', + 'payload' => null, + ], 200); + } /** * Return JSON containing a list of consumables assigned to a user. diff --git a/app/Http/Transformers/AssetsTransformer.php b/app/Http/Transformers/AssetsTransformer.php index cda96e5a4..30744c92c 100644 --- a/app/Http/Transformers/AssetsTransformer.php +++ b/app/Http/Transformers/AssetsTransformer.php @@ -131,7 +131,7 @@ class AssetsTransformer $array['custom_fields'] = $fields_array; } } else { - $array['custom_fields'] = []; + $array['custom_fields'] = new \stdClass; // HACK to force generation of empty object instead of empty list } $permissions_array['available_actions'] = [ diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index ceceeefdb..2093afecb 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -1301,8 +1301,8 @@ {{ $file->filename }} @endif - - {{ Helper::formatFilesizeUnits(@Storage::size('private_uploads/assetmodels/'.$file->filename)) }} + + {{ (Storage::exists('private_uploads/assetmodels/'.$file->filename)) ? Helper::formatFilesizeUnits(Storage::size('private_uploads/assetmodels/'.$file->filename)) : '' }} @if ($file->note) diff --git a/routes/api.php b/routes/api.php index d27f14601..d9db5b78e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -976,6 +976,13 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi ] )->name('api.users.assetlist'); + Route::post('{user}/email', + [ + Api\UsersController::class, + 'emailAssetList' + ] + )->name('api.users.email_assets'); + Route::get('{user}/accessories', [ Api\UsersController::class,