From d9a53460ffff6000f5ffca3b84553273644cbcf7 Mon Sep 17 00:00:00 2001 From: Florent Bervas Date: Wed, 10 Jul 2024 17:05:39 +0000 Subject: [PATCH 01/25] Fix design inconsistency between assets and assigned assets in Print All Assigned report --- resources/views/users/print.blade.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/resources/views/users/print.blade.php b/resources/views/users/print.blade.php index bdea19ab7c..acadf16a03 100644 --- a/resources/views/users/print.blade.php +++ b/resources/views/users/print.blade.php @@ -151,20 +151,25 @@ {{ $counter }}.{{ $assignedCounter }} - + @if ($asset->getImageUrl()) @endif {{ $asset->asset_tag }} {{ $asset->name }} - {{ $asset->model->category->name }} + {{ (($asset->model) && ($asset->model->category)) ? $asset->model->category->name : trans('general.invalid_category') }} + {{ ($asset->model) ? $asset->model->name : trans('general.invalid_model') }} {{ ($asset->defaultLoc) ? $asset->defaultLoc->name : '' }} {{ ($asset->location) ? $asset->location->name : '' }} - {{ $asset->model->name }} {{ $asset->serial }} - {{ $asset->last_checkout }} - + + {{ Helper::getFormattedDateObject($asset->last_checkout, 'datetime', false) }} + + @if (($asset->assetlog->first()) && ($asset->assetlog->first()->accept_signature!='')) + + @endif + @php $assignedCounter++ From 82743abadcd5327394707a3993a297cdd582296e Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 14:15:18 +0100 Subject: [PATCH 02/25] Cleans up the consumables index controller Signed-off-by: snipe --- .../Controllers/Api/ConsumablesController.php | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/app/Http/Controllers/Api/ConsumablesController.php b/app/Http/Controllers/Api/ConsumablesController.php index 7c65e49bcd..3054d9c03f 100644 --- a/app/Http/Controllers/Api/ConsumablesController.php +++ b/app/Http/Controllers/Api/ConsumablesController.php @@ -27,27 +27,8 @@ class ConsumablesController extends Controller { $this->authorize('index', Consumable::class); - // This array is what determines which fields should be allowed to be sorted on ON the table itself, no relations - // Relations will be handled in query scopes a little further down. - $allowed_columns = - [ - 'id', - 'name', - 'order_number', - 'min_amt', - 'purchase_date', - 'purchase_cost', - 'company', - 'category', - 'model_number', - 'item_no', - 'qty', - 'image', - 'notes', - ]; - - $consumables = Consumable::select('consumables.*') - ->with('company', 'location', 'category', 'users', 'manufacturer'); + $consumables = Consumable::with('company', 'location', 'category', 'manufacturer') + ->withCount('users as consumables_users_count'); if ($request->filled('search')) { $consumables = $consumables->TextSearch(e($request->input('search'))); @@ -89,15 +70,9 @@ class ConsumablesController extends Controller // Make sure the offset and limit are actually integers and do not exceed system limits $offset = ($request->input('offset') > $consumables->count()) ? $consumables->count() : app('api_offset_value'); $limit = app('api_limit_value'); - - $allowed_columns = ['id', 'name', 'order_number', 'min_amt', 'purchase_date', 'purchase_cost', 'company', 'category', 'model_number', 'item_no', 'manufacturer', 'location', 'qty', 'image']; $order = $request->input('order') === 'asc' ? 'asc' : 'desc'; - $sort_override = $request->input('sort'); - $column_sort = in_array($sort_override, $allowed_columns) ? $sort_override : 'created_at'; - - - switch ($sort_override) { + switch ($request->input('sort')) { case 'category': $consumables = $consumables->OrderCategory($order); break; @@ -111,10 +86,30 @@ class ConsumablesController extends Controller $consumables = $consumables->OrderCompany($order); break; case 'supplier': - $components = $consumables->OrderSupplier($order); + $consumables = $consumables->OrderSupplier($order); break; default: - $consumables = $consumables->orderBy($column_sort, $order); + // This array is what determines which fields should be allowed to be sorted on ON the table itself. + // These must match a column on the consumables table directly. + $allowed_columns = [ + 'id', + 'name', + 'order_number', + 'min_amt', + 'purchase_date', + 'purchase_cost', + 'company', + 'category', + 'model_number', + 'item_no', + 'manufacturer', + 'location', + 'qty', + 'image' + ]; + + $sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at'; + $consumables = $consumables->orderBy($sort, $order); break; } From 9e9b07f10f1c37ae5070add08d7f3163905f3e29 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 15:23:59 +0100 Subject: [PATCH 03/25] Removed duplicate status check Signed-off-by: snipe --- tests/Feature/Categories/Api/IndexCategoriesTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Feature/Categories/Api/IndexCategoriesTest.php b/tests/Feature/Categories/Api/IndexCategoriesTest.php index fc48fdc547..d27bfbb068 100644 --- a/tests/Feature/Categories/Api/IndexCategoriesTest.php +++ b/tests/Feature/Categories/Api/IndexCategoriesTest.php @@ -32,7 +32,6 @@ class IndexCategoriesTest extends TestCase 'limit' => '20', ])) ->assertOk() - ->assertOk() ->assertJsonStructure([ 'total', 'rows', From da2b64c96d9551d220eddf37c10b452d87d155eb Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 15:24:08 +0100 Subject: [PATCH 04/25] Added string Signed-off-by: snipe --- resources/lang/en-US/admin/consumables/message.php | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/lang/en-US/admin/consumables/message.php b/resources/lang/en-US/admin/consumables/message.php index c0d0aa7f68..e2591503bf 100644 --- a/resources/lang/en-US/admin/consumables/message.php +++ b/resources/lang/en-US/admin/consumables/message.php @@ -2,6 +2,7 @@ return array( + 'invalid_category_type' => 'The category must be a consumable category.', 'does_not_exist' => 'Consumable does not exist.', 'create' => array( From a6b2f5df1d01a28d1de77c5f0e5c473c6be64549 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 15:24:56 +0100 Subject: [PATCH 05/25] Added tests Signed-off-by: snipe --- .../Consumables/Api/ConsumableUpdateTest.php | 52 +++++++++++++++++++ .../Consumables/Api/ConsumableViewTest.php | 51 ++++++++++++++++++ .../Consumables/Ui/ConsumableViewTest.php | 26 ++++++++++ 3 files changed, 129 insertions(+) create mode 100644 tests/Feature/Consumables/Api/ConsumableUpdateTest.php create mode 100644 tests/Feature/Consumables/Api/ConsumableViewTest.php create mode 100644 tests/Feature/Consumables/Ui/ConsumableViewTest.php diff --git a/tests/Feature/Consumables/Api/ConsumableUpdateTest.php b/tests/Feature/Consumables/Api/ConsumableUpdateTest.php new file mode 100644 index 0000000000..1c1e05d4d4 --- /dev/null +++ b/tests/Feature/Consumables/Api/ConsumableUpdateTest.php @@ -0,0 +1,52 @@ +create(); + + $this->actingAsForApi(User::factory()->superuser()->create()) + ->patchJson(route('api.consumables.update', $consumable), [ + 'name' => 'Test Consumable', + ]) + ->assertOk() + ->assertStatusMessageIs('success') + ->assertStatus(200) + ->json(); + + $consumable->refresh(); + $this->assertEquals('Test Consumable', $consumable->name, 'Name was not updated'); + + } + + public function testCannotUpdateConsumableViaPatchWithInvalidCategoryType() + { + $category = Category::factory()->create(['category_type' => 'asset']); + $consumable = Consumable::factory()->create(); + + $this->actingAsForApi(User::factory()->superuser()->create()) + ->patchJson(route('api.consumables.update', $consumable), [ + 'name' => 'Test Consumable', + 'category_id' => $category->id, + ]) + ->assertOk() + ->assertStatusMessageIs('error') + ->assertStatus(200) + ->json(); + + $category->refresh(); + $this->assertNotEquals('Test Consumable', $consumable->name, 'Name was not updated'); + $this->assertNotEquals('consumable', $consumable->category_id, 'Category was not updated'); + + } + +} diff --git a/tests/Feature/Consumables/Api/ConsumableViewTest.php b/tests/Feature/Consumables/Api/ConsumableViewTest.php new file mode 100644 index 0000000000..c6410216e1 --- /dev/null +++ b/tests/Feature/Consumables/Api/ConsumableViewTest.php @@ -0,0 +1,51 @@ +count(2)->create(); + + $consumableA = Consumable::factory()->for($companyA)->create(); + $consumableB = Consumable::factory()->for($companyB)->create(); + + $superUser = $companyA->users()->save(User::factory()->superuser()->make()); + $userInCompanyA = $companyA->users()->save(User::factory()->viewConsumables()->make()); + $userInCompanyB = $companyB->users()->save(User::factory()->viewConsumables()->make()); + + $this->settings->disableMultipleFullCompanySupport(); + + $this->actingAsForApi($superUser) + ->getJson(route('api.consumables.show', $consumableA)) + ->assertOk(); + + $this->actingAsForApi($userInCompanyA) + ->getJson(route('api.consumables.show', $consumableA)) + ->assertOk(); + + $this->actingAsForApi($userInCompanyB) + ->getJson(route('api.consumables.show', $consumableB)) + ->assertOk(); + + $this->settings->enableMultipleFullCompanySupport(); + + $this->actingAsForApi($superUser) + ->getJson(route('api.consumables.show', $consumableA)) + ->assertOk(); + + $this->actingAsForApi($userInCompanyA) + ->getJson(route('api.consumables.index')) + ->assertOk(); + + $this->actingAsForApi($userInCompanyB) + ->getJson(route('api.consumables.index')) + ->assertOk(); + } +} diff --git a/tests/Feature/Consumables/Ui/ConsumableViewTest.php b/tests/Feature/Consumables/Ui/ConsumableViewTest.php new file mode 100644 index 0000000000..9633896c2d --- /dev/null +++ b/tests/Feature/Consumables/Ui/ConsumableViewTest.php @@ -0,0 +1,26 @@ +create(); + $this->actingAs(User::factory()->create()) + ->get(route('consumables.show', $consumable)) + ->assertForbidden(); + } + + public function testUserCanListConsumables() + { + $consumable = Consumable::factory()->create(); + $this->actingAs(User::factory()->superuser()->create()) + ->get(route('consumables.show', $consumable)) + ->assertOk(); + } +} From a7a1a377dae867c80a7c252eb0a30b957c83411a Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 15:25:07 +0100 Subject: [PATCH 06/25] Added form request for consumables Signed-off-by: snipe --- app/Http/Requests/StoreConsumableRequest.php | 56 ++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 app/Http/Requests/StoreConsumableRequest.php diff --git a/app/Http/Requests/StoreConsumableRequest.php b/app/Http/Requests/StoreConsumableRequest.php new file mode 100644 index 0000000000..9062b07cc5 --- /dev/null +++ b/app/Http/Requests/StoreConsumableRequest.php @@ -0,0 +1,56 @@ +category_id) { + if ($category = Category::find($this->category_id)) { + $this->merge([ + 'category_type' => $category->category_type ?? null, + ]); + } + } + + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return array_merge( + ['category_type' => 'in:consumable'], + parent::rules(), + ); + } + + public function messages(): array + { + $messages = ['category_type.in' => trans('admin/consumables/message.invalid_category_type')]; + return $messages; + } + + public function response(array $errors) + { + return $this->redirector->back()->withInput()->withErrors($errors, $this->errorBag); + } +} From 2b5463475c955359d12b0037ce4f6e206388008a Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 15:25:26 +0100 Subject: [PATCH 07/25] Added test Signed-off-by: snipe --- .../Consumables/Api/ConsumableIndexTest.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/Feature/Consumables/Api/ConsumableIndexTest.php b/tests/Feature/Consumables/Api/ConsumableIndexTest.php index b16dfdfa53..f1d3ad7f0b 100644 --- a/tests/Feature/Consumables/Api/ConsumableIndexTest.php +++ b/tests/Feature/Consumables/Api/ConsumableIndexTest.php @@ -54,4 +54,29 @@ class ConsumableIndexTest extends TestCase ->assertResponseDoesNotContainInRows($consumableA) ->assertResponseContainsInRows($consumableB); } + + public function testConsumableIndexReturnsExpectedSearchResults() + { + Consumable::factory()->count(10)->create(); + Consumable::factory()->count(1)->create(['name' => 'My Test Consumable']); + + $this->actingAsForApi(User::factory()->superuser()->create()) + ->getJson( + route('api.consumables.index', [ + 'search' => 'My Test Consumable', + 'sort' => 'name', + 'order' => 'asc', + 'offset' => '0', + 'limit' => '20', + ])) + ->assertOk() + ->assertJsonStructure([ + 'total', + 'rows', + ]) + ->assertJson([ + 'total' => 1, + ]); + + } } From abd79219ddc92d983fc4833beb987941865d1a12 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 15:26:24 +0100 Subject: [PATCH 08/25] Use form request to check for valid category Signed-off-by: snipe --- app/Http/Controllers/Api/ConsumablesController.php | 5 +++-- .../Consumables/ConsumablesController.php | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Api/ConsumablesController.php b/app/Http/Controllers/Api/ConsumablesController.php index 3054d9c03f..ccb0593d73 100644 --- a/app/Http/Controllers/Api/ConsumablesController.php +++ b/app/Http/Controllers/Api/ConsumablesController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api; use App\Events\CheckoutableCheckedOut; use App\Helpers\Helper; use App\Http\Controllers\Controller; +use App\Http\Requests\StoreConsumableRequest; use App\Http\Transformers\ConsumablesTransformer; use App\Http\Transformers\SelectlistTransformer; use App\Models\Company; @@ -126,7 +127,7 @@ class ConsumablesController extends Controller * @since [v4.0] * @param \App\Http\Requests\ImageUploadRequest $request */ - public function store(ImageUploadRequest $request) : JsonResponse + public function store(StoreConsumableRequest $request) : JsonResponse { $this->authorize('create', Consumable::class); $consumable = new Consumable; @@ -162,7 +163,7 @@ class ConsumablesController extends Controller * @param \App\Http\Requests\ImageUploadRequest $request * @param int $id */ - public function update(ImageUploadRequest $request, $id) : JsonResponse + public function update(StoreConsumableRequest $request, $id) : JsonResponse { $this->authorize('update', Consumable::class); $consumable = Consumable::findOrFail($id); diff --git a/app/Http/Controllers/Consumables/ConsumablesController.php b/app/Http/Controllers/Consumables/ConsumablesController.php index b33e6e07a9..e438e33bc9 100644 --- a/app/Http/Controllers/Consumables/ConsumablesController.php +++ b/app/Http/Controllers/Consumables/ConsumablesController.php @@ -8,8 +8,10 @@ use App\Http\Requests\ImageUploadRequest; use App\Models\Company; use App\Models\Consumable; use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Validator; +use Illuminate\Http\RedirectResponse; +use \Illuminate\Contracts\View\View; +use App\Http\Requests\StoreConsumableRequest; /** * This controller handles all actions related to Consumables for @@ -62,7 +64,7 @@ class ConsumablesController extends Controller * @return \Illuminate\Http\RedirectResponse * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function store(ImageUploadRequest $request) + public function store(StoreConsumableRequest $request) { $this->authorize('create', Consumable::class); $consumable = new Consumable(); @@ -99,10 +101,8 @@ class ConsumablesController extends Controller * @param int $consumableId * @see ConsumablesController::postEdit() method that stores the form data. * @since [v1.0] - * @return \Illuminate\Contracts\View\View - * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function edit($consumableId = null) + public function edit($consumableId = null) : View | RedirectResponse { if ($item = Consumable::find($consumableId)) { $this->authorize($item); @@ -124,7 +124,7 @@ class ConsumablesController extends Controller * @see ConsumablesController::getEdit() method that stores the form data. * @since [v1.0] */ - public function update(ImageUploadRequest $request, $consumableId = null) + public function update(StoreConsumableRequest $request, $consumableId = null) { if (is_null($consumable = Consumable::find($consumableId))) { return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist')); From 759bb822ff9316040975be61f39d9c9f8f50ab69 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 15:59:18 +0100 Subject: [PATCH 09/25] Make sure the user exists Signed-off-by: snipe --- app/Models/ConsumableAssignment.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Models/ConsumableAssignment.php b/app/Models/ConsumableAssignment.php index 1e21a7f7d2..ae84cd19dc 100644 --- a/app/Models/ConsumableAssignment.php +++ b/app/Models/ConsumableAssignment.php @@ -3,13 +3,19 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Watson\Validating\ValidatingTrait; class ConsumableAssignment extends Model { use CompanyableTrait; + use ValidatingTrait; protected $table = 'consumables_users'; + public $rules = [ + 'assigned_to' => 'exists:users,id', + ]; + public function consumable() { return $this->belongsTo(\App\Models\Consumable::class); From 9676d934d29693830c2073c92696e2dd0f80e504 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:00:08 +0100 Subject: [PATCH 10/25] Drop the with users on the create checkout screen Signed-off-by: snipe --- .../Consumables/ConsumableCheckoutController.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Consumables/ConsumableCheckoutController.php b/app/Http/Controllers/Consumables/ConsumableCheckoutController.php index 919cd1698f..fd690fede8 100644 --- a/app/Http/Controllers/Consumables/ConsumableCheckoutController.php +++ b/app/Http/Controllers/Consumables/ConsumableCheckoutController.php @@ -4,12 +4,11 @@ namespace App\Http\Controllers\Consumables; use App\Events\CheckoutableCheckedOut; use App\Http\Controllers\Controller; -use App\Models\Accessory; use App\Models\Consumable; use App\Models\User; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\Input; +use \Illuminate\Contracts\View\View; +use \Illuminate\Http\RedirectResponse; class ConsumableCheckoutController extends Controller { @@ -20,13 +19,11 @@ class ConsumableCheckoutController extends Controller * @see ConsumableCheckoutController::store() method that stores the data. * @since [v1.0] * @param int $id - * @return \Illuminate\Contracts\View\View - * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function create($id) + public function create($id) : View | RedirectResponse { - if ($consumable = Consumable::with('users')->find($id)) { + if ($consumable = Consumable::find($id)) { $this->authorize('checkout', $consumable); From e123eeea9e893583f106ccd90174b05171853c2d Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:00:20 +0100 Subject: [PATCH 11/25] Added error message if category type is invalid Signed-off-by: snipe --- resources/views/partials/forms/edit/category-select.blade.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/views/partials/forms/edit/category-select.blade.php b/resources/views/partials/forms/edit/category-select.blade.php index f555c6240b..66800deedf 100644 --- a/resources/views/partials/forms/edit/category-select.blade.php +++ b/resources/views/partials/forms/edit/category-select.blade.php @@ -25,4 +25,6 @@ {!! $errors->first($fieldname, '
') !!} + + {!! $errors->first('category_type', '
') !!} From b10441c92867d58d3b80cf97d07549614942a21e Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:01:18 +0100 Subject: [PATCH 12/25] Detach associated pivot records Signed-off-by: snipe --- app/Http/Controllers/Consumables/ConsumablesController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/Consumables/ConsumablesController.php b/app/Http/Controllers/Consumables/ConsumablesController.php index e438e33bc9..f6b4f0139b 100644 --- a/app/Http/Controllers/Consumables/ConsumablesController.php +++ b/app/Http/Controllers/Consumables/ConsumablesController.php @@ -182,6 +182,7 @@ class ConsumablesController extends Controller return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found')); } $this->authorize($consumable); + $consumable->users()->detach(); $consumable->delete(); // Redirect to the locations management page return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.delete.success')); From d9a114090bd8b05e43d4c706cc15a6528e5fef7f Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:18:33 +0100 Subject: [PATCH 13/25] Added buttons Signed-off-by: snipe --- resources/views/consumables/view.blade.php | 53 ++++++++++++++++------ 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/resources/views/consumables/view.blade.php b/resources/views/consumables/view.blade.php index 80987335ff..b56015524e 100644 --- a/resources/views/consumables/view.blade.php +++ b/resources/views/consumables/view.blade.php @@ -176,6 +176,7 @@ {{ trans('general.delete') }} + @endforeach @@ -254,6 +255,19 @@ @endif + @if ($consumable->notes) + +
+ + {{ trans('general.notes') }}: + +
+
+ {!! nl2br(Helper::parseEscapedMarkedownInline($consumable->notes)) !!} +
+ + @endif + @can('checkout', \App\Models\Consumable::class)
@@ -268,22 +282,24 @@ @endif
+ @can('update', \App\Models\Consumable::class) + + @endcan + + @can('delete', $consumable) +
+ @if ($consumable->deleted_at=='') + + {{ trans('general.delete') }} + @endif +
+ @endcan @endcan - @if ($consumable->notes) - -
- - {{ trans('general.notes') }}: - -
-
- {!! nl2br(Helper::parseEscapedMarkedownInline($consumable->notes)) !!} -
- - @endif - @@ -297,5 +313,16 @@ @stop @section('moar_scripts') + + @include ('partials.bootstrap-table', ['exportFile' => 'consumable' . $consumable->name . '-export', 'search' => false]) @stop From 94bfe7d9c8b75191c61a98815bd38736193f9ac3 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:18:42 +0100 Subject: [PATCH 14/25] Require the user exists Signed-off-by: snipe --- app/Models/ConsumableAssignment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/ConsumableAssignment.php b/app/Models/ConsumableAssignment.php index ae84cd19dc..db0cfa4bd6 100644 --- a/app/Models/ConsumableAssignment.php +++ b/app/Models/ConsumableAssignment.php @@ -13,7 +13,7 @@ class ConsumableAssignment extends Model protected $table = 'consumables_users'; public $rules = [ - 'assigned_to' => 'exists:users,id', + 'assigned_to' => 'required|exists:users,id', ]; public function consumable() From 42dbc894e0a601911b1ae9058a7c382e886d3da0 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:21:45 +0100 Subject: [PATCH 15/25] Better handle numRemaining for consumables Signed-off-by: snipe --- app/Models/Consumable.php | 43 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/app/Models/Consumable.php b/app/Models/Consumable.php index 008dffa4ca..944ac5bfde 100644 --- a/app/Models/Consumable.php +++ b/app/Models/Consumable.php @@ -10,12 +10,21 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Facades\Storage; use Watson\Validating\ValidatingTrait; +use Illuminate\Database\Eloquent\Relations\Relation; +use App\Presenters\ConsumablePresenter; +use App\Models\Actionlog; +use App\Models\ConsumableAssignment; +use App\Models\User; +use App\Models\Location; +use App\Models\Manufacturer; +use App\Models\Supplier; +use App\Models\Category; class Consumable extends SnipeModel { use HasFactory; - protected $presenter = \App\Presenters\ConsumablePresenter::class; + protected $presenter = ConsumablePresenter::class; use CompanyableTrait; use Loggable, Presentable; use SoftDeletes; @@ -37,10 +46,10 @@ class Consumable extends SnipeModel */ public $rules = [ 'name' => 'required|min:3|max:255', - 'qty' => 'required|integer|min:0', + 'qty' => 'required|integer|min:0|max:99999', 'category_id' => 'required|integer', 'company_id' => 'integer|nullable', - 'min_amt' => 'integer|min:0|nullable', + 'min_amt' => 'integer|min:0|max:99999|nullable', 'purchase_cost' => 'numeric|nullable|gte:0', 'purchase_date' => 'date_format:Y-m-d|nullable', ]; @@ -109,7 +118,7 @@ class Consumable extends SnipeModel */ public function uploads() { - return $this->hasMany(\App\Models\Actionlog::class, 'item_id') + return $this->hasMany(Actionlog::class, 'item_id') ->where('item_type', '=', self::class) ->where('action_type', '=', 'uploaded') ->whereNotNull('filename') @@ -147,7 +156,7 @@ class Consumable extends SnipeModel */ public function admin() { - return $this->belongsTo(\App\Models\User::class, 'user_id'); + return $this->belongsTo(User::class, 'user_id'); } /** @@ -159,7 +168,7 @@ class Consumable extends SnipeModel */ public function consumableAssignments() { - return $this->hasMany(\App\Models\ConsumableAssignment::class); + return $this->hasMany(ConsumableAssignment::class); } /** @@ -183,7 +192,7 @@ class Consumable extends SnipeModel */ public function manufacturer() { - return $this->belongsTo(\App\Models\Manufacturer::class, 'manufacturer_id'); + return $this->belongsTo(Manufacturer::class, 'manufacturer_id'); } /** @@ -195,7 +204,7 @@ class Consumable extends SnipeModel */ public function location() { - return $this->belongsTo(\App\Models\Location::class, 'location_id'); + return $this->belongsTo(Location::class, 'location_id'); } /** @@ -207,7 +216,7 @@ class Consumable extends SnipeModel */ public function category() { - return $this->belongsTo(\App\Models\Category::class, 'category_id'); + return $this->belongsTo(Category::class, 'category_id'); } @@ -220,7 +229,7 @@ class Consumable extends SnipeModel */ public function assetlog() { - return $this->hasMany(\App\Models\Actionlog::class, 'item_id')->where('item_type', self::class)->orderBy('created_at', 'desc')->withTrashed(); + return $this->hasMany(Actionlog::class, 'item_id')->where('item_type', self::class)->orderBy('created_at', 'desc')->withTrashed(); } /** @@ -244,11 +253,10 @@ class Consumable extends SnipeModel * * @author [A. Gianotto] [] * @since [v3.0] - * @return \Illuminate\Database\Eloquent\Relations\Relation */ - public function users() + public function users() : Relation { - return $this->belongsToMany(\App\Models\User::class, 'consumables_users', 'consumable_id', 'assigned_to')->withPivot('user_id')->withTrashed()->withTimestamps(); + return $this->belongsToMany(User::class, 'consumables_users', 'consumable_id', 'assigned_to')->withPivot('user_id')->withTrashed()->withTimestamps(); } /** @@ -260,7 +268,7 @@ class Consumable extends SnipeModel */ public function supplier() { - return $this->belongsTo(\App\Models\Supplier::class, 'supplier_id'); + return $this->belongsTo(Supplier::class, 'supplier_id'); } @@ -317,10 +325,7 @@ class Consumable extends SnipeModel */ public function numCheckedOut() { - $checkedout = 0; - $checkedout = $this->users->count(); - - return $checkedout; + return $this->consumables_users_count ?? $this->users()->count(); } /** @@ -332,7 +337,7 @@ class Consumable extends SnipeModel */ public function numRemaining() { - $checkedout = $this->users->count(); + $checkedout = $this->numCheckedOut(); $total = $this->qty; $remaining = $total - $checkedout; From 67d6f7119d5270af49553a1ff0fc2f217e95b2a0 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:22:04 +0100 Subject: [PATCH 16/25] Prevent a ludicrous amount of consumables Signed-off-by: snipe --- resources/views/partials/forms/edit/quantity.blade.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/views/partials/forms/edit/quantity.blade.php b/resources/views/partials/forms/edit/quantity.blade.php index f8a421adcd..b41d13f650 100644 --- a/resources/views/partials/forms/edit/quantity.blade.php +++ b/resources/views/partials/forms/edit/quantity.blade.php @@ -4,8 +4,10 @@
- +
+
{!! $errors->first('qty', '') !!} +
From 00d7b36c3653dc7ceed101c1c6976584879ca88f Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:22:22 +0100 Subject: [PATCH 17/25] Eager load suppliers Signed-off-by: snipe --- app/Http/Controllers/Api/ConsumablesController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ConsumablesController.php b/app/Http/Controllers/Api/ConsumablesController.php index ccb0593d73..1665b7f4f0 100644 --- a/app/Http/Controllers/Api/ConsumablesController.php +++ b/app/Http/Controllers/Api/ConsumablesController.php @@ -28,7 +28,7 @@ class ConsumablesController extends Controller { $this->authorize('index', Consumable::class); - $consumables = Consumable::with('company', 'location', 'category', 'manufacturer') + $consumables = Consumable::with('company', 'location', 'category', 'supplier', 'manufacturer') ->withCount('users as consumables_users_count'); if ($request->filled('search')) { From 2415408a5005404dd142d8f29870ea67a713160d Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:22:41 +0100 Subject: [PATCH 18/25] Prevent ludicrious amount of min_qty Signed-off-by: snipe --- .../views/partials/forms/edit/minimum_quantity.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/partials/forms/edit/minimum_quantity.blade.php b/resources/views/partials/forms/edit/minimum_quantity.blade.php index 1566ab2e9c..798c6fe72d 100644 --- a/resources/views/partials/forms/edit/minimum_quantity.blade.php +++ b/resources/views/partials/forms/edit/minimum_quantity.blade.php @@ -3,13 +3,13 @@
- +
{!! $errors->first('min_amt', '') !!} From 58bc84436c6892b05523b855140745ef0baa32b6 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:23:05 +0100 Subject: [PATCH 19/25] Fixed incorrect jquery validation class Signed-off-by: snipe --- resources/views/layouts/default.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index 74e9d5be6f..63c5bca440 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -976,7 +976,7 @@ dir="{{ in_array(app()->getLocale(),['ar-SA','fa-IR', 'he-IL']) ? 'rtl' : 'ltr' // Reference: https://jqueryvalidation.org/validate/ $('#create-form').validate({ ignore: 'input[type=hidden]', - errorClass: 'help-block form-error', + errorClass: 'alert-msg', errorElement: 'span', errorPlacement: function(error, element) { $(element).hasClass('select2') || $(element).hasClass('js-data-ajax') From 5108b1f3eda32f9e61d80d8ffd87f914a1bfa97c Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:35:16 +0100 Subject: [PATCH 20/25] Capture the log meta for what was changed Signed-off-by: snipe --- app/Observers/ConsumableObserver.php | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/app/Observers/ConsumableObserver.php b/app/Observers/ConsumableObserver.php index 08c56d2ee2..27b3c7f976 100644 --- a/app/Observers/ConsumableObserver.php +++ b/app/Observers/ConsumableObserver.php @@ -16,12 +16,26 @@ class ConsumableObserver */ public function updated(Consumable $consumable) { - $logAction = new Actionlog(); - $logAction->item_type = Consumable::class; - $logAction->item_id = $consumable->id; - $logAction->created_at = date('Y-m-d H:i:s'); - $logAction->user_id = Auth::id(); - $logAction->logaction('update'); + + $changed = []; + + foreach ($consumable->getRawOriginal() as $key => $value) { + // Check and see if the value changed + if ($consumable->getRawOriginal()[$key] != $consumable->getAttributes()[$key]) { + $changed[$key]['old'] = $consumable->getRawOriginal()[$key]; + $changed[$key]['new'] = $consumable->getAttributes()[$key]; + } + } + + if (count($changed) > 0) { + $logAction = new Actionlog(); + $logAction->item_type = Consumable::class; + $logAction->item_id = $consumable->id; + $logAction->created_at = date('Y-m-d H:i:s'); + $logAction->user_id = Auth::id(); + $logAction->log_meta = json_encode($changed); + $logAction->logaction('update'); + } } /** From 23f1489b2b9075bd6078748702f7b35767d9d23a Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 16:46:49 +0100 Subject: [PATCH 21/25] Added history tab Signed-off-by: snipe --- resources/views/consumables/view.blade.php | 62 +++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/resources/views/consumables/view.blade.php b/resources/views/consumables/view.blade.php index b56015524e..e6b8137238 100644 --- a/resources/views/consumables/view.blade.php +++ b/resources/views/consumables/view.blade.php @@ -45,6 +45,17 @@ @endcan +
  • + + + + +
  • + @can('update', $consumable)
  • @@ -95,7 +106,56 @@
  • - @can('consumables.files', $consumable) +
    + +
    +
    + + + + + + + + + + + + + + + + + + + +
    {{ trans('general.date') }}{{ trans('general.admin') }}{{ trans('general.action') }}{{ trans('general.file_name') }}{{ trans('general.item') }}{{ trans('general.target') }}{{ trans('general.notes') }}{{ trans('general.signature') }}{{ trans('general.download') }}{{ trans('admin/hardware/table.changed')}}{{ trans('admin/settings/general.login_ip') }}{{ trans('admin/settings/general.login_user_agent') }}{{ trans('general.action_source') }}
    +
    +
    +
    + + + @can('consumables.files', $consumable)
    From d4a66f9b6c5a349dbfed1da84c76d3776534ed93 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 17:00:12 +0100 Subject: [PATCH 22/25] Use better icon for deleting Signed-off-by: snipe --- app/Presenters/ActionlogPresenter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Presenters/ActionlogPresenter.php b/app/Presenters/ActionlogPresenter.php index 2794b6c5fb..ebbe3d7823 100644 --- a/app/Presenters/ActionlogPresenter.php +++ b/app/Presenters/ActionlogPresenter.php @@ -75,7 +75,7 @@ class ActionlogPresenter extends Presenter } if ($this->actionType()=='delete') { - return 'fa-solid fa-user-xmark'; + return 'fa-solid fa-trash'; } if ($this->actionType()=='update') { From c2fe3b54590932346cb358d5c677c02b9822ccff Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 17:00:38 +0100 Subject: [PATCH 23/25] Use the observer to delete associated files and detach users Signed-off-by: snipe --- .../Consumables/ConsumablesController.php | 2 +- app/Observers/ConsumableObserver.php | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Consumables/ConsumablesController.php b/app/Http/Controllers/Consumables/ConsumablesController.php index f6b4f0139b..5685944a5c 100644 --- a/app/Http/Controllers/Consumables/ConsumablesController.php +++ b/app/Http/Controllers/Consumables/ConsumablesController.php @@ -182,7 +182,7 @@ class ConsumablesController extends Controller return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found')); } $this->authorize($consumable); - $consumable->users()->detach(); + $consumable->delete(); // Redirect to the locations management page return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.delete.success')); diff --git a/app/Observers/ConsumableObserver.php b/app/Observers/ConsumableObserver.php index 27b3c7f976..1bd6e7cde8 100644 --- a/app/Observers/ConsumableObserver.php +++ b/app/Observers/ConsumableObserver.php @@ -5,6 +5,8 @@ namespace App\Observers; use App\Models\Actionlog; use App\Models\Consumable; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Storage; class ConsumableObserver { @@ -66,6 +68,28 @@ class ConsumableObserver */ public function deleting(Consumable $consumable) { + + $consumable->users()->detach(); + + foreach ($consumable->uploads() as $file) { + try { + Storage::disk('public')->delete('consumables/'.$file); + } catch (\Exception $e) { + Log::info($e); + } + } + + try { + Storage::disk('public')->delete('consumables/'.$consumable->image); + } catch (\Exception $e) { + Log::info($e); + } + + $consumable->image = null; + $consumable->save(); + + + $logAction = new Actionlog(); $logAction->item_type = Consumable::class; $logAction->item_id = $consumable->id; From 1527679f4b9eb596ad4034ee0971be2314f603c9 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 17:26:43 +0100 Subject: [PATCH 24/25] Handle deletions on the observer Signed-off-by: snipe --- app/Observers/ConsumableObserver.php | 8 ++++++-- .../views/consumables/checkout.blade.php | 19 +++++++++++++++++++ resources/views/consumables/view.blade.php | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/Observers/ConsumableObserver.php b/app/Observers/ConsumableObserver.php index 1bd6e7cde8..377995ebb9 100644 --- a/app/Observers/ConsumableObserver.php +++ b/app/Observers/ConsumableObserver.php @@ -70,15 +70,19 @@ class ConsumableObserver { $consumable->users()->detach(); + $uploads = $consumable->uploads; - foreach ($consumable->uploads() as $file) { + foreach ($uploads as $file) { try { - Storage::disk('public')->delete('consumables/'.$file); + Storage::delete('private_uploads/consumables/'.$file->filename); + $file->delete(); } catch (\Exception $e) { Log::info($e); } } + + try { Storage::disk('public')->delete('consumables/'.$consumable->image); } catch (\Exception $e) { diff --git a/resources/views/consumables/checkout.blade.php b/resources/views/consumables/checkout.blade.php index bde94bc6f4..29b68b6ce7 100644 --- a/resources/views/consumables/checkout.blade.php +++ b/resources/views/consumables/checkout.blade.php @@ -37,6 +37,25 @@
    @endif + +
    + +
    +

    {{ $consumable->qty }}

    +
    +
    + + +
    + +
    +

    {{ $consumable->numRemaining() }}

    +
    +
    + + + + @include ('partials.forms.edit.user-select', ['translated_name' => trans('general.select_user'), 'fieldname' => 'assigned_to', 'required'=> 'true']) diff --git a/resources/views/consumables/view.blade.php b/resources/views/consumables/view.blade.php index e6b8137238..5a25659fbe 100644 --- a/resources/views/consumables/view.blade.php +++ b/resources/views/consumables/view.blade.php @@ -351,7 +351,7 @@ @can('delete', $consumable)
    @if ($consumable->deleted_at=='') - {{ trans('general.delete') }} @endif From aebe96913a210e255e4210d7a7a313c76707a5ba Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 11 Jul 2024 17:31:20 +0100 Subject: [PATCH 25/25] Add @FlorentDotMe as a contributor --- .all-contributorsrc | 9 + CONTRIBUTORS.md | 506 +++++--------------------------------------- 2 files changed, 60 insertions(+), 455 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index d7624a4314..8ccce80edf 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -3136,6 +3136,15 @@ "contributions": [ "doc" ] + }, + { + "login": "FlorentDotMe", + "name": "Florent Bervas", + "avatar_url": "https://avatars.githubusercontent.com/u/292081?v=4", + "profile": "http://spoontux.net", + "contributions": [ + "code" + ] } ] } diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c0ca7951dd..54ab4d8ac1 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,461 +1,57 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)) who have helped Snipe-IT get this far: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    snipe
    snipe

    πŸ’» πŸš‡ πŸ“– ⚠️ πŸ› 🎨 πŸ‘€
    Brady Wetherington
    Brady Wetherington

    πŸ’» πŸ“– πŸš‡ πŸ‘€
    Daniel Meltzer
    Daniel Meltzer

    πŸ’» ⚠️ πŸ“–
    Michael T
    Michael T

    πŸ’»
    madd15
    madd15

    πŸ“– πŸ’¬
    Vincent Sposato
    Vincent Sposato

    πŸ’»
    Andrea Bergamasco
    Andrea Bergamasco

    πŸ’»
    Karol
    Karol

    🌍 πŸ’»
    morph027
    morph027

    πŸ’»
    fvleminckx
    fvleminckx

    πŸš‡
    itsupportcmsukorg
    itsupportcmsukorg

    πŸ’» πŸ›
    Frank
    Frank

    πŸ’»
    Deleted user
    Deleted user

    🌍 πŸ’»
    tiagom62
    tiagom62

    πŸ’» πŸš‡
    Ryan Stafford
    Ryan Stafford

    πŸ’»
    Eammon Hanlon
    Eammon Hanlon

    πŸ’»
    zjean
    zjean

    πŸ’»
    Matthias Frei
    Matthias Frei

    πŸ’»
    opsydev
    opsydev

    πŸ’»
    Daniel Dreier
    Daniel Dreier

    πŸ’»
    Nikolai Prokoschenko
    Nikolai Prokoschenko

    πŸ’»
    Drew
    Drew

    πŸ’»
    Walter
    Walter

    πŸ’»
    Petr Baloun
    Petr Baloun

    πŸ’»
    reidblomquist
    reidblomquist

    πŸ“–
    Mathieu Kooiman
    Mathieu Kooiman

    πŸ’»
    csayre
    csayre

    πŸ“–
    Adam Dunson
    Adam Dunson

    πŸ’»
    Hereward
    Hereward

    πŸ’»
    swoopdk
    swoopdk

    πŸ’»
    Abdullah Alansari
    Abdullah Alansari

    πŸ’»
    Micael Rodrigues
    Micael Rodrigues

    πŸ’»
    Patrick Gallagher
    Patrick Gallagher

    πŸ“–
    Miliamber
    Miliamber

    πŸ’»
    hawk554
    hawk554

    πŸ’»
    Justin Kerr
    Justin Kerr

    πŸ’»
    Ira W. Snyder
    Ira W. Snyder

    πŸ“–
    Aladin Alaily
    Aladin Alaily

    πŸ’»
    Chase Hansen
    Chase Hansen

    πŸ’» πŸ’¬ πŸ›
    IDM Helpdesk
    IDM Helpdesk

    πŸ’»
    Kai
    Kai

    πŸ’»
    Michael Daniels
    Michael Daniels

    πŸ’»
    Tom Castleman
    Tom Castleman

    πŸ’»
    Daniel Nemanic
    Daniel Nemanic

    πŸ’»
    SouthWolf
    SouthWolf

    πŸ’»
    Ivar Nesje
    Ivar Nesje

    πŸ’»
    JΓ©rΓ©my Benoist
    JΓ©rΓ©my Benoist

    πŸ“–
    Chris Leathley
    Chris Leathley

    πŸš‡
    splaer
    splaer

    πŸ› πŸ’»
    Joe Ferguson
    Joe Ferguson

    πŸ’»
    diwanicki
    diwanicki

    πŸ’» πŸ“–
    Lee Thoong Ching
    Lee Thoong Ching

    πŸ“– πŸ’»
    Marek Ε uppa
    Marek Ε uppa

    πŸ’»
    Juan J. Martinez
    Juan J. Martinez

    🌍
    R Ryan Dial
    R Ryan Dial

    🌍
    Andrej Manduch
    Andrej Manduch

    πŸ“–
    Jay Richards
    Jay Richards

    πŸ’»
    Alexander Innes
    Alexander Innes

    πŸ’»
    Danny Garcia
    Danny Garcia

    πŸ’»
    archpoint
    archpoint

    πŸ’»
    Jake McGraw
    Jake McGraw

    πŸ’»
    FleischKarussel
    FleischKarussel

    πŸ“–
    Dylan Yi
    Dylan Yi

    πŸ’»
    Gil Rutkowski
    Gil Rutkowski

    πŸ’»
    Desmond Morris
    Desmond Morris

    πŸ’»
    Nick Peelman
    Nick Peelman

    πŸ’»
    Abraham Vegh
    Abraham Vegh

    πŸ’»
    Mohamed Rashid
    Mohamed Rashid

    πŸ“–
    Kasey
    Kasey

    πŸ’»
    Brett
    Brett

    ⚠️
    Jason Spriggs
    Jason Spriggs

    πŸ’»
    Nate Felton
    Nate Felton

    πŸ’»
    Manasses Ferreira
    Manasses Ferreira

    πŸ’»
    Steve
    Steve

    ⚠️
    matc
    matc

    ⚠️
    Cole R. Davis
    Cole R. Davis

    ⚠️
    gibsonjoshua55
    gibsonjoshua55

    πŸ’»
    Robin Temme
    Robin Temme

    πŸ’»
    Iman
    Iman

    πŸ’»
    Richard Hofman
    Richard Hofman

    πŸ’»
    gizzmojr
    gizzmojr

    πŸ’»
    Jenny Li
    Jenny Li

    πŸ“–
    Geoff Young
    Geoff Young

    πŸ’»
    Elliot Blackburn
    Elliot Blackburn

    πŸ“–
    TΓ΅nis Ormisson
    TΓ΅nis Ormisson

    πŸ’»
    Nicolai Essig
    Nicolai Essig

    πŸ’»
    Danielle
    Danielle

    πŸ“–
    Lawrence
    Lawrence

    ⚠️ πŸ›
    uknzaeinozpas
    uknzaeinozpas

    ⚠️ πŸ’»
    Ryan
    Ryan

    πŸ“–
    vcordes79
    vcordes79

    πŸ’»
    fordster78
    fordster78

    πŸ’»
    CronKz
    CronKz

    πŸ’» 🌍
    Tim Bishop
    Tim Bishop

    πŸ’»
    Sean McIlvenna
    Sean McIlvenna

    πŸ’»
    cepacs
    cepacs

    πŸ› πŸ“–
    lea-mink
    lea-mink

    πŸ’»
    Hannah Tinkler
    Hannah Tinkler

    πŸ’»
    Doeke Zanstra
    Doeke Zanstra

    πŸ’»
    Djamon Staal
    Djamon Staal

    πŸ’»
    Earl Ramirez
    Earl Ramirez

    πŸ’»
    Richard Ray Thomas
    Richard Ray Thomas

    πŸ’»
    Ryan Kuba
    Ryan Kuba

    πŸ’»
    Brian Monroe
    Brian Monroe

    πŸ’»
    plexorama
    plexorama

    πŸ’»
    Till Deeke
    Till Deeke

    πŸ’»
    5quirrel
    5quirrel

    πŸ’»
    Jason
    Jason

    πŸ’»
    Antti
    Antti

    πŸ’»
    DeusMaximus
    DeusMaximus

    πŸ’»
    a-royal
    a-royal

    🌍
    Alberto Aldrigo
    Alberto Aldrigo

    🌍
    Alex Stanev
    Alex Stanev

    🌍
    Andreas Rehm
    Andreas Rehm

    🌍
    Andreas Erhard
    Andreas Erhard

    🌍
    AndrΓ©s Vanegas JimΓ©nez
    AndrΓ©s Vanegas JimΓ©nez

    🌍
    Antonio Schiavon
    Antonio Schiavon

    🌍
    benunter
    benunter

    🌍
    Borys Ε»muda
    Borys Ε»muda

    🌍
    chibacityblues
    chibacityblues

    🌍
    Chien Wei Lin
    Chien Wei Lin

    🌍
    Christian Schuster
    Christian Schuster

    🌍
    Christian Stefanus
    Christian Stefanus

    🌍
    wxcafΓ©
    wxcafΓ©

    🌍
    dpyroc
    dpyroc

    🌍
    Daniel Friedlmaier
    Daniel Friedlmaier

    🌍
    Daniel Heene
    Daniel Heene

    🌍
    danielcb
    danielcb

    🌍
    Dominik Senti
    Dominik Senti

    🌍
    Eric Gautheron
    Eric Gautheron

    🌍
    Erlend PilΓΈ
    Erlend PilΓΈ

    🌍
    Fabio Rapposelli
    Fabio Rapposelli

    🌍
    Felipe Barros
    Felipe Barros

    🌍
    Fernando Possebon
    Fernando Possebon

    🌍
    gdraque
    gdraque

    🌍
    Georg Wallisch
    Georg Wallisch

    🌍
    Gerardo Robles
    Gerardo Robles

    🌍
    Gluek
    Gluek

    🌍
    AdnanAbuShahad
    AdnanAbuShahad

    🌍
    Hafidzi My
    Hafidzi My

    🌍
    Harim Park
    Harim Park

    🌍
    Henrik Kentsson
    Henrik Kentsson

    🌍
    Husnul Yaqien
    Husnul Yaqien

    🌍
    Ibrahim
    Ibrahim

    🌍
    igolman
    igolman

    🌍
    itangiang
    itangiang

    🌍
    jarby1211
    jarby1211

    🌍
    Jhonn Willker
    Jhonn Willker

    🌍
    Jose
    Jose

    🌍
    laopangzi
    laopangzi

    🌍
    Lars Strojny
    Lars Strojny

    🌍
    MarcosBL
    MarcosBL

    🌍
    marie joy cajes
    marie joy cajes

    🌍
    Mark S. Johansen
    Mark S. Johansen

    🌍
    Martin Stub
    Martin Stub

    🌍
    Meyer Flavio
    Meyer Flavio

    🌍
    Micael Rodrigues
    Micael Rodrigues

    🌍
    Mikael Rasmussen
    Mikael Rasmussen

    🌍
    IxFail
    IxFail

    🌍
    Mohammed Fota
    Mohammed Fota

    🌍
    Moayad Alserihi
    Moayad Alserihi

    🌍
    saymd
    saymd

    🌍
    Patrik Larsson
    Patrik Larsson

    🌍
    drcryo
    drcryo

    🌍
    pawel1615
    pawel1615

    🌍
    bodrovics
    bodrovics

    🌍
    priatna
    priatna

    🌍
    Fan Jiang
    Fan Jiang

    🌍
    ragnarcx
    ragnarcx

    🌍
    Rein van Haaren
    Rein van Haaren

    🌍
    Teguh Dwicaksana
    Teguh Dwicaksana

    🌍
    fraccie
    fraccie

    🌍
    vinzruzell
    vinzruzell

    🌍
    Kevin Austin
    Kevin Austin

    🌍
    Wira Sandy
    Wira Sandy

    🌍
    Илья
    Илья

    🌍
    GodUseVPN
    GodUseVPN

    🌍
    周周
    周周

    🌍
    Sam
    Sam

    πŸ’»
    Azerothian
    Azerothian

    πŸ’»
    Wes Hulette
    Wes Hulette

    πŸ’»
    patrict
    patrict

    πŸ’»
    Dmitriy Minaev
    Dmitriy Minaev

    πŸ’»
    liquidhorse
    liquidhorse

    πŸ’»
    Jordi Boggiano
    Jordi Boggiano

    πŸ’»
    Ivan Nieto
    Ivan Nieto

    πŸ’»
    Ben RUBSON
    Ben RUBSON

    πŸ’»
    NMathar
    NMathar

    πŸ’»
    Steffen
    Steffen

    πŸ’»
    Sxderp
    Sxderp

    πŸ’»
    fanta8897
    fanta8897

    πŸ’»
    Andrey Bolonin
    Andrey Bolonin

    πŸ’»
    shinayoshi
    shinayoshi

    πŸ’»
    Hubert
    Hubert

    πŸ’»
    KeenRivals
    KeenRivals

    πŸ’»
    omyno
    omyno

    πŸ’»
    Evgeny
    Evgeny

    πŸ’»
    Colin Campbell
    Colin Campbell

    πŸ’»
    Ľubomír Kučera
    Ľubomír Kučera

    πŸ’»
    Martin Meredith
    Martin Meredith

    πŸ’»
    Tim Farmer
    Tim Farmer

    πŸ’»
    MariΓ‘n Skrip
    MariΓ‘n Skrip

    πŸ’»
    Godfrey Martinez
    Godfrey Martinez

    πŸ’»
    bigtreeEdo
    bigtreeEdo

    πŸ’»
    Colin  McNeil
    Colin McNeil

    πŸ’»
    JoKneeMo
    JoKneeMo

    πŸ’»
    Joshi
    Joshi

    πŸ’»
    Anthony Burns
    Anthony Burns

    πŸ’»
    johnson-yi
    johnson-yi

    πŸ’»
    Sanjay Govind
    Sanjay Govind

    πŸ’»
    Peter Upfold
    Peter Upfold

    πŸ’»
    Jared Biel
    Jared Biel

    πŸ’»
    Dampfklon
    Dampfklon

    πŸ’»
    Charles Hamilton
    Charles Hamilton

    πŸ’»
    Giuseppe Iannello
    Giuseppe Iannello

    πŸ’»
    Peter Dave Hello
    Peter Dave Hello

    πŸ’»
    sigmoidal
    sigmoidal

    πŸ’»
    Vincent LainΓ©
    Vincent LainΓ©

    πŸ’»
    Lucas Pleß
    Lucas Pleß

    πŸ’»
    Ian Littman
    Ian Littman

    πŸ’»
    JoΓ£o Paulo
    JoΓ£o Paulo

    πŸ’»
    ThoBur
    ThoBur

    πŸ’»
    Alexander Chibrikin
    Alexander Chibrikin

    πŸ’»
    Anthony Winstanley
    Anthony Winstanley

    πŸ’»
    Folke
    Folke

    πŸ’»
    Bennett Blodinger
    Bennett Blodinger

    πŸ’»
    NMC
    NMC

    πŸ’»
    andres-baller
    andres-baller

    πŸ’»
    sean-borg
    sean-borg

    πŸ’»
    EDVLeer
    EDVLeer

    πŸ’»
    Kurokat
    Kurokat

    πŸ’»
    Kevin KΓΆllmann
    Kevin KΓΆllmann

    πŸ’»
    sw-mreyes
    sw-mreyes

    πŸ’»
    Joel Pittet
    Joel Pittet

    πŸ’»
    Eli Young
    Eli Young

    πŸ’»
    Raell Dottin
    Raell Dottin

    πŸ’»
    Tom Misilo
    Tom Misilo

    πŸ’»
    David Davenne
    David Davenne

    πŸ’»
    Mark Stenglein
    Mark Stenglein

    πŸ’»
    ajsy
    ajsy

    πŸ’»
    Jan Kiesewetter
    Jan Kiesewetter

    πŸ’»
    Tetrachloromethane250
    Tetrachloromethane250

    πŸ’»
    Lars Kajes
    Lars Kajes

    πŸ’»
    Joly0
    Joly0

    πŸ’»
    theburger
    theburger

    πŸ’»
    David Valin Alonso
    David Valin Alonso

    πŸ’»
    andreaci
    andreaci

    πŸ’»
    Jelle Sebreghts
    Jelle Sebreghts

    πŸ’»
    Michael Pietsch
    Michael Pietsch

    Masudul Haque Shihab
    Masudul Haque Shihab

    πŸ’»
    Supapong Areeprasertkul
    Supapong Areeprasertkul

    πŸ’»
    Peter Sarossy
    Peter Sarossy

    πŸ’»
    Renee Margaret McConahy
    Renee Margaret McConahy

    πŸ’»
    JohnnyPicnic
    JohnnyPicnic

    πŸ’»
    markbrule
    markbrule

    πŸ’»
    Mike Campbell
    Mike Campbell

    πŸ’»
    tbrconnect
    tbrconnect

    πŸ’»
    kcoyo
    kcoyo

    πŸ’»
    Travis Miller
    Travis Miller

    πŸ’»
    Evan Taylor
    Evan Taylor

    πŸ’»
    Petri Asikainen
    Petri Asikainen

    πŸ’»
    derdeagle
    derdeagle

    πŸ’»
    Mike Frysinger
    Mike Frysinger

    πŸ’»
    ALPHA
    ALPHA

    πŸ’»
    FliegenKLATSCH
    FliegenKLATSCH

    πŸ’»
    Jeremy Price
    Jeremy Price

    πŸ’»
    Toreg87
    Toreg87

    πŸ’»
    Matthew Nickson
    Matthew Nickson

    πŸ’»
    Jethro Nederhof
    Jethro Nederhof

    πŸ’»
    Oskar Stenberg
    Oskar Stenberg

    πŸ’»
    Robert-Azelis
    Robert-Azelis

    πŸ’»
    Alexander William Smith
    Alexander William Smith

    πŸ’»
    LEITWERK AG
    LEITWERK AG

    πŸ’»
    Adam
    Adam

    πŸ’»
    Ian
    Ian

    πŸ’»
    Shao Yu-Lung (Allen)
    Shao Yu-Lung (Allen)

    πŸ’»
    Haxatron
    Haxatron

    πŸ’»
    PlaneNuts
    PlaneNuts

    πŸ’»
    Bradley Coudriet
    Bradley Coudriet

    πŸ’»
    Dalton Durst
    Dalton Durst

    πŸ’»
    Alex Janes
    Alex Janes

    πŸ’»
    Nuraeil
    Nuraeil

    πŸ’»
    TenOfTens
    TenOfTens

    πŸ’»
    waffle
    waffle

    πŸ’»
    Yevhenii Huzii
    Yevhenii Huzii

    πŸ’»
    Achmad Fienan Rahardianto
    Achmad Fienan Rahardianto

    πŸ’»
    Yevhenii Huzii
    Yevhenii Huzii

    πŸ’»
    Christian Weirich
    Christian Weirich

    πŸ’»
    denzfarid
    denzfarid

    ntbutler-nbcs
    ntbutler-nbcs

    πŸ’»
    Naveen
    Naveen

    πŸ’»
    Mike Roquemore
    Mike Roquemore

    πŸ’»
    Daniel Reeder
    Daniel Reeder

    🌍 🌍 πŸ’»
    vickyjaura183
    vickyjaura183

    πŸ’»
    Peace
    Peace

    πŸ’»
    Kyle Gordon
    Kyle Gordon

    πŸ’»
    Katharina Drexel
    Katharina Drexel

    πŸ’»
    David Sferruzza
    David Sferruzza

    πŸ’»
    Rick Nelson
    Rick Nelson

    πŸ’»
    BasO12
    BasO12

    πŸ’»
    Vautia
    Vautia

    πŸ’»
    Chris Hartjes
    Chris Hartjes

    πŸ’»
    geo-chen
    geo-chen

    πŸ’»
    Phan Nguyen
    Phan Nguyen

    πŸ’»
    Iisakki Jaakkola
    Iisakki Jaakkola

    πŸ’»
    Ikko Ashimine
    Ikko Ashimine

    πŸ’»
    Lukas Fehling
    Lukas Fehling

    πŸ’»
    Fernando Almeida
    Fernando Almeida

    πŸ’»
    akemidx
    akemidx

    πŸ’»
    Oguz Bilgic
    Oguz Bilgic

    πŸ’»
    Scooter Crawford
    Scooter Crawford

    πŸ’»
    subdriven
    subdriven

    πŸ’»
    Andrew Savinykh
    Andrew Savinykh

    πŸ’»
    Tadayuki Onishi
    Tadayuki Onishi

    πŸ’»
    Florian
    Florian

    πŸ’»
    Spencer Long
    Spencer Long

    πŸ’»
    Marcus Moore
    Marcus Moore

    πŸ’»
    Martin Meredith
    Martin Meredith

    dboth
    dboth

    πŸ’»
    Zachary Fleck
    Zachary Fleck

    πŸ’»
    VIKAAS-A
    VIKAAS-A

    πŸ’»
    Abdul Kareem
    Abdul Kareem

    πŸ’»
    NojoudAlshehri
    NojoudAlshehri

    πŸ’»
    Stefan Stidl
    Stefan Stidl

    πŸ’»
    Quentin Aymard
    Quentin Aymard

    πŸ’»
    Grant Le Roux
    Grant Le Roux

    πŸ’»
    Bogdan
    Bogdan

    πŸ’»
    mmanjos
    mmanjos

    πŸ’»
    Abdelaziz Faki
    Abdelaziz Faki

    πŸ’»
    bilias
    bilias

    πŸ’»
    coach1988
    coach1988

    πŸ’»
    MrM
    MrM

    πŸ’»
    koiakoia
    koiakoia

    πŸ’»
    Mustafa Online
    Mustafa Online

    πŸ’»
    franceslui
    franceslui

    πŸ’»
    Q4kK
    Q4kK

    πŸ’»
    squintfox
    squintfox

    πŸ’»
    Jeff Clay
    Jeff Clay

    πŸ’»
    Phil J R
    Phil J R

    πŸ’»
    i_virus
    i_virus

    πŸ’»
    Paul Grime
    Paul Grime

    πŸ’»
    Lee Porte
    Lee Porte

    πŸ’»
    BRYAN
    BRYAN

    πŸ’» ⚠️
    U-H-T
    U-H-T

    πŸ’»
    Matt Tyree
    Matt Tyree

    πŸ“–
    - - - - +| [
    snipe](http://www.snipe.net)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=snipe "Code") [πŸš‡](#infra-snipe "Infrastructure (Hosting, Build-Tools, etc)") [πŸ“–](https://github.com/snipe/snipe-it/commits?author=snipe "Documentation") [⚠️](https://github.com/snipe/snipe-it/commits?author=snipe "Tests") [πŸ›](https://github.com/snipe/snipe-it/issues?q=author%3Asnipe "Bug reports") [🎨](#design-snipe "Design") [πŸ‘€](#review-snipe "Reviewed Pull Requests") | [
    Brady Wetherington](http://www.uberbrady.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=uberbrady "Code") [πŸ“–](https://github.com/snipe/snipe-it/commits?author=uberbrady "Documentation") [πŸš‡](#infra-uberbrady "Infrastructure (Hosting, Build-Tools, etc)") [πŸ‘€](#review-uberbrady "Reviewed Pull Requests") | [
    Daniel Meltzer](https://github.com/dmeltzer)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=dmeltzer "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=dmeltzer "Tests") [πŸ“–](https://github.com/snipe/snipe-it/commits?author=dmeltzer "Documentation") | [
    Michael T](http://www.tuckertechonline.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mtucker6784 "Code") | [
    madd15](https://github.com/madd15)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=madd15 "Documentation") [πŸ’¬](#question-madd15 "Answering Questions") | [
    Vincent Sposato](https://github.com/vsposato)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=vsposato "Code") | [
    Andrea Bergamasco](https://github.com/vjandrea)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=vjandrea "Code") | +| :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| [
    Karol](https://github.com/kpawelski)
    [🌍](#translation-kpawelski "Translation") [πŸ’»](https://github.com/snipe/snipe-it/commits?author=kpawelski "Code") | [
    morph027](http://blog.morph027.de/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=morph027 "Code") | [
    fvleminckx](https://github.com/fvleminckx)
    [πŸš‡](#infra-fvleminckx "Infrastructure (Hosting, Build-Tools, etc)") | [
    itsupportcmsukorg](https://github.com/itsupportcmsukorg)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=itsupportcmsukorg "Code") [πŸ›](https://github.com/snipe/snipe-it/issues?q=author%3Aitsupportcmsukorg "Bug reports") | [
    Frank](https://override.io)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=base-zero "Code") | [
    Deleted user](https://github.com/ghost)
    [🌍](#translation-ghost "Translation") [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ghost "Code") | [
    tiagom62](https://github.com/tiagom62)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=tiagom62 "Code") [πŸš‡](#infra-tiagom62 "Infrastructure (Hosting, Build-Tools, etc)") | +| [
    Ryan Stafford](https://github.com/rystaf)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=rystaf "Code") | [
    Eammon Hanlon](https://github.com/ehanlon)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ehanlon "Code") | [
    zjean](https://github.com/zjean)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=zjean "Code") | [
    Matthias Frei](http://www.frei.media)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=FREImedia "Code") | [
    opsydev](https://github.com/opsydev)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=opsydev "Code") | [
    Daniel Dreier](http://www.ddreier.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ddreier "Code") | [
    Nikolai Prokoschenko](http://rassie.org)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=rassie "Code") | +| [
    Drew](https://github.com/YetAnotherCodeMonkey)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=YetAnotherCodeMonkey "Code") | [
    Walter](https://github.com/merid14)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=merid14 "Code") | [
    Petr Baloun](https://github.com/balous)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=balous "Code") | [
    reidblomquist](https://github.com/reidblomquist)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=reidblomquist "Documentation") | [
    Mathieu Kooiman](https://github.com/mathieuk)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mathieuk "Code") | [
    csayre](https://github.com/csayre)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=csayre "Documentation") | [
    Adam Dunson](https://github.com/adamdunson)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=adamdunson "Code") | +| [
    Hereward](https://github.com/thehereward)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=thehereward "Code") | [
    swoopdk](https://github.com/swoopdk)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=swoopdk "Code") | [
    Abdullah Alansari](https://linkedin.com/in/ahimta)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Ahimta "Code") | [
    Micael Rodrigues](https://github.com/MicaelRodrigues)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=MicaelRodrigues "Code") | [
    Patrick Gallagher](http://macadmincorner.com)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=patgmac "Documentation") | [
    Miliamber](https://github.com/Miliamber)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Miliamber "Code") | [
    hawk554](https://github.com/hawk554)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=hawk554 "Code") | +| [
    Justin Kerr](http://jbirdkerr.net)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jbirdkerr "Code") | [
    Ira W. Snyder](http://www.irasnyder.com/devel/)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=irasnyd "Documentation") | [
    Aladin Alaily](https://github.com/aalaily)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=aalaily "Code") | [
    Chase Hansen](https://github.com/kobie-chasehansen)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=kobie-chasehansen "Code") [πŸ’¬](#question-kobie-chasehansen "Answering Questions") [πŸ›](https://github.com/snipe/snipe-it/issues?q=author%3Akobie-chasehansen "Bug reports") | [
    IDM Helpdesk](https://github.com/IDM-Helpdesk)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=IDM-Helpdesk "Code") | [
    Kai](http://balticer.de)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=balticer "Code") | [
    Michael Daniels](http://www.michaeldaniels.me)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mdaniels5757 "Code") | +| [
    Tom Castleman](http://tomcastleman.me)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=tomcastleman "Code") | [
    Daniel Nemanic](https://github.com/DanielNemanic)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=DanielNemanic "Code") | [
    SouthWolf](https://github.com/southwolf)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=southwolf "Code") | [
    Ivar Nesje](https://github.com/ivarne)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ivarne "Code") | [
    JΓ©rΓ©my Benoist](http://www.j0k3r.net)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=j0k3r "Documentation") | [
    Chris Leathley](https://github.com/cleathley)
    [πŸš‡](#infra-cleathley "Infrastructure (Hosting, Build-Tools, etc)") | [
    splaer](https://github.com/splaer)
    [πŸ›](https://github.com/snipe/snipe-it/issues?q=author%3Asplaer "Bug reports") [πŸ’»](https://github.com/snipe/snipe-it/commits?author=splaer "Code") | +| [
    Joe Ferguson](http://www.joeferguson.me)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=svpernova09 "Code") | [
    diwanicki](https://github.com/diwanicki)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=diwanicki "Code") [πŸ“–](https://github.com/snipe/snipe-it/commits?author=diwanicki "Documentation") | [
    Lee Thoong Ching](https://github.com/pakkua80)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=pakkua80 "Documentation") [πŸ’»](https://github.com/snipe/snipe-it/commits?author=pakkua80 "Code") | [
    Marek Ε uppa](http://shu.io)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mrshu "Code") | [
    Juan J. Martinez](https://github.com/mizar1616)
    [🌍](#translation-mizar1616 "Translation") | [
    R Ryan Dial](https://github.com/rrdial)
    [🌍](#translation-rrdial "Translation") | [
    Andrej Manduch](https://github.com/burlito)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=burlito "Documentation") | +| [
    Jay Richards](http://www.cordeos.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=technogenus "Code") | [
    Alexander Innes](https://necurity.co.uk)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=leostat "Code") | [
    Danny Garcia](https://buzzedword.codes)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=buzzedword "Code") | [
    archpoint](https://github.com/archpoint)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=archpoint "Code") | [
    Jake McGraw](http://www.jakemcgraw.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jakemcgraw "Code") | [
    FleischKarussel](https://github.com/FleischKarussel)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=FleischKarussel "Documentation") | [
    Dylan Yi](https://github.com/feeva)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=feeva "Code") | +| [
    Gil Rutkowski](http://FlashingCursor.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=flashingcursor "Code") | [
    Desmond Morris](http://www.desmondmorris.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=desmondmorris "Code") | [
    Nick Peelman](http://peelman.us)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=peelman "Code") | [
    Abraham Vegh](https://abrahamvegh.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=abrahamvegh "Code") | [
    Mohamed Rashid](https://github.com/rashivkp)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=rashivkp "Documentation") | [
    Kasey](http://hinchk.github.io)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=HinchK "Code") | [
    Brett](https://github.com/BrettFagerlund)
    [⚠️](https://github.com/snipe/snipe-it/commits?author=BrettFagerlund "Tests") | +| [
    Jason Spriggs](http://jasonspriggs.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jasonspriggs "Code") | [
    Nate Felton](http://n8felton.wordpress.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=n8felton "Code") | [
    Manasses Ferreira](http://homepages.dcc.ufmg.br/~manassesferreira)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=manassesferreira "Code") | [
    Steve](https://github.com/steveelwood)
    [⚠️](https://github.com/snipe/snipe-it/commits?author=steveelwood "Tests") | [
    matc](http://twitter.com/matc)
    [⚠️](https://github.com/snipe/snipe-it/commits?author=matc "Tests") | [
    Cole R. Davis](http://www.davisracingteam.com)
    [⚠️](https://github.com/snipe/snipe-it/commits?author=VanillaNinjaD "Tests") | [
    gibsonjoshua55](https://github.com/gibsonjoshua55)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=gibsonjoshua55 "Code") | +| [
    Robin Temme](https://github.com/zwerch)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") | [
    Iman](https://github.com/imanghafoori1)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=imanghafoori1 "Code") | [
    Richard Hofman](https://github.com/richardhofman6)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=richardhofman6 "Code") | [
    gizzmojr](https://github.com/gizzmojr)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=gizzmojr "Code") | [
    Jenny Li](https://github.com/imjennyli)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=imjennyli "Documentation") | [
    Geoff Young](https://github.com/GeoffYoung)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=GeoffYoung "Code") | [
    Elliot Blackburn](http://www.elliotblackburn.com)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=BlueHatbRit "Documentation") | +| [
    TΓ΅nis Ormisson](http://andmemasin.eu)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=TonisOrmisson "Code") | [
    Nicolai Essig](http://www.nicolai-essig.de)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=thakilla "Code") | [
    Danielle](https://github.com/techincolor)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=techincolor "Documentation") | [
    Lawrence](https://github.com/TheVakman)
    [⚠️](https://github.com/snipe/snipe-it/commits?author=TheVakman "Tests") [πŸ›](https://github.com/snipe/snipe-it/issues?q=author%3ATheVakman "Bug reports") | [
    uknzaeinozpas](https://github.com/uknzaeinozpas)
    [⚠️](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Tests") [πŸ’»](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Code") | [
    Ryan](https://github.com/Gelob)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=Gelob "Documentation") | [
    vcordes79](https://github.com/vcordes79)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=vcordes79 "Code") | +| [
    fordster78](https://github.com/fordster78)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=fordster78 "Code") | [
    CronKz](https://github.com/CronKz)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=CronKz "Code") [🌍](#translation-CronKz "Translation") | [
    Tim Bishop](https://github.com/tdb)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=tdb "Code") | [
    Sean McIlvenna](https://www.seanmcilvenna.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=seanmcilvenna "Code") | [
    cepacs](https://github.com/cepacs)
    [πŸ›](https://github.com/snipe/snipe-it/issues?q=author%3Acepacs "Bug reports") [πŸ“–](https://github.com/snipe/snipe-it/commits?author=cepacs "Documentation") | [
    lea-mink](https://github.com/lea-mink)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=lea-mink "Code") | [
    Hannah Tinkler](https://github.com/hannahtinkler)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=hannahtinkler "Code") | +| [
    Doeke Zanstra](https://github.com/doekman)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=doekman "Code") | [
    Djamon Staal](https://www.sdhd.nl/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=SjamonDaal "Code") | [
    Earl Ramirez](https://github.com/EarlRamirez)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=EarlRamirez "Code") | [
    Richard Ray Thomas](https://github.com/RichardRay)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=RichardRay "Code") | [
    Ryan Kuba](https://www.taisun.io/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=thelamer "Code") | [
    Brian Monroe](https://github.com/ParadoxGuitarist)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ParadoxGuitarist "Code") | [
    plexorama](https://github.com/plexorama)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=plexorama "Code") | +| [
    Till Deeke](https://tilldeeke.de)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=tilldeeke "Code") | [
    5quirrel](https://github.com/5quirrel)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=5quirrel "Code") | [
    Jason](https://github.com/jasonlshelton)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jasonlshelton "Code") | [
    Antti](https://github.com/chemfy)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=chemfy "Code") | [
    DeusMaximus](https://github.com/DeusMaximus)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=DeusMaximus "Code") | [
    a-royal](https://github.com/A-ROYAL)
    [🌍](#translation-A-ROYAL "Translation") | [
    Alberto Aldrigo](https://github.com/albertoaldrigo)
    [🌍](#translation-albertoaldrigo "Translation") | +| [
    Alex Stanev](http://alex.stanev.org/blog)
    [🌍](#translation-RealEnder "Translation") | [
    Andreas Rehm](http://devel.itsolution2.de)
    [🌍](#translation-sirrus "Translation") | [
    Andreas Erhard](https://github.com/xelan)
    [🌍](#translation-xelan "Translation") | [
    AndrΓ©s Vanegas JimΓ©nez](https://github.com/angeldeejay)
    [🌍](#translation-angeldeejay "Translation") | [
    Antonio Schiavon](https://github.com/aschiavon91)
    [🌍](#translation-aschiavon91 "Translation") | [
    benunter](https://github.com/benunter)
    [🌍](#translation-benunter "Translation") | [
    Borys Ε»muda](http://catweb24.pl)
    [🌍](#translation-rudashi "Translation") | +| [
    chibacityblues](https://github.com/chibacityblues)
    [🌍](#translation-chibacityblues "Translation") | [
    Chien Wei Lin](https://github.com/cwlin0416)
    [🌍](#translation-cwlin0416 "Translation") | [
    Christian Schuster](https://github.com/Againstreality)
    [🌍](#translation-Againstreality "Translation") | [
    Christian Stefanus](http://chriss.webhostid.com)
    [🌍](#translation-kopi-item "Translation") | [
    wxcafΓ©](http://wxcafe.net)
    [🌍](#translation-wxcafe "Translation") | [
    dpyroc](https://github.com/dpyroc)
    [🌍](#translation-dpyroc "Translation") | [
    Daniel Friedlmaier](http://www.friedlmaier.net)
    [🌍](#translation-da-friedl "Translation") | +| [
    Daniel Heene](https://github.com/danielheene)
    [🌍](#translation-danielheene "Translation") | [
    danielcb](https://github.com/danielcb)
    [🌍](#translation-danielcb "Translation") | [
    Dominik Senti](https://github.com/dominiksenti)
    [🌍](#translation-dominiksenti "Translation") | [
    Eric Gautheron](http://www.konectik.com)
    [🌍](#translation-EpixFr "Translation") | [
    Erlend PilΓΈ](https://erlpil.com)
    [🌍](#translation-Erlpil "Translation") | [
    Fabio Rapposelli](http://fabio.technology)
    [🌍](#translation-frapposelli "Translation") | [
    Felipe Barros](https://github.com/fgbs)
    [🌍](#translation-fgbs "Translation") | +| [
    Fernando Possebon](https://github.com/possebon)
    [🌍](#translation-possebon "Translation") | [
    gdraque](https://github.com/gdraque)
    [🌍](#translation-gdraque "Translation") | [
    Georg Wallisch](https://github.com/georgwallisch)
    [🌍](#translation-georgwallisch "Translation") | [
    Gerardo Robles](https://github.com/jgroblesr85)
    [🌍](#translation-jgroblesr85 "Translation") | [
    Gluek](https://t.me/Gluek)
    [🌍](#translation-mrgluek "Translation") | [
    AdnanAbuShahad](https://github.com/AdnanAbuShahad)
    [🌍](#translation-AdnanAbuShahad "Translation") | [
    Hafidzi My](https://hafidzi.my)
    [🌍](#translation-hafidzi "Translation") | +| [
    Harim Park](https://github.com/fofwisdom)
    [🌍](#translation-fofwisdom "Translation") | [
    Henrik Kentsson](http://www.kentsson.se)
    [🌍](#translation-Kentsson "Translation") | [
    Husnul Yaqien](https://github.com/husnulyaqien)
    [🌍](#translation-husnulyaqien "Translation") | [
    Ibrahim](http://abaalkhail.org)
    [🌍](#translation-abaalkh "Translation") | [
    igolman](https://github.com/igolman)
    [🌍](#translation-igolman "Translation") | [
    itangiang](https://github.com/itangiang)
    [🌍](#translation-itangiang "Translation") | [
    jarby1211](https://github.com/jarby1211)
    [🌍](#translation-jarby1211 "Translation") | +| [
    Jhonn Willker](http://jwillker.com)
    [🌍](#translation-JohnWillker "Translation") | [
    Jose](https://github.com/joxelito94)
    [🌍](#translation-joxelito94 "Translation") | [
    laopangzi](https://github.com/laopangzi)
    [🌍](#translation-laopangzi "Translation") | [
    Lars Strojny](http://usrportage.de)
    [🌍](#translation-lstrojny "Translation") | [
    MarcosBL](http://twitter.com/marcosbl)
    [🌍](#translation-MarcosBL "Translation") | [
    marie joy cajes](https://github.com/mariejoyacajes)
    [🌍](#translation-mariejoyacajes "Translation") | [
    Mark S. Johansen](http://www.markjohansen.dk)
    [🌍](#translation-msjohansen "Translation") | +| [
    Martin Stub](http://martinstub.dk)
    [🌍](#translation-stubben "Translation") | [
    Meyer Flavio](https://github.com/meyerf99)
    [🌍](#translation-meyerf99 "Translation") | [
    Micael Rodrigues](https://github.com/MicaelRodrigues)
    [🌍](#translation-MicaelRodrigues "Translation") | [
    Mikael Rasmussen](http://rubixy.com/)
    [🌍](#translation-mikaelssen "Translation") | [
    IxFail](https://github.com/IxFail)
    [🌍](#translation-IxFail "Translation") | [
    Mohammed Fota](http://www.mohammedfota.com)
    [🌍](#translation-MohammedFota "Translation") | [
    Moayad Alserihi](https://github.com/omego)
    [🌍](#translation-omego "Translation") | +| [
    saymd](https://github.com/saymd)
    [🌍](#translation-saymd "Translation") | [
    Patrik Larsson](https://nordsken.se)
    [🌍](#translation-pooot "Translation") | [
    drcryo](https://github.com/drcryo)
    [🌍](#translation-drcryo "Translation") | [
    pawel1615](https://github.com/pawel1615)
    [🌍](#translation-pawel1615 "Translation") | [
    bodrovics](https://github.com/bodrovics)
    [🌍](#translation-bodrovics "Translation") | [
    priatna](https://github.com/priatna)
    [🌍](#translation-priatna "Translation") | [
    Fan Jiang](https://amayume.net)
    [🌍](#translation-ProfFan "Translation") | +| [
    ragnarcx](https://github.com/ragnarcx)
    [🌍](#translation-ragnarcx "Translation") | [
    Rein van Haaren](http://www.reinvanhaaren.nl/)
    [🌍](#translation-reinvanhaaren "Translation") | [
    Teguh Dwicaksana](http://dheche.songolimo.net)
    [🌍](#translation-dheche "Translation") | [
    fraccie](https://github.com/FRaccie)
    [🌍](#translation-FRaccie "Translation") | [
    vinzruzell](https://github.com/vinzruzell)
    [🌍](#translation-vinzruzell "Translation") | [
    Kevin Austin](http://kevinaustin.com)
    [🌍](#translation-vipsystem "Translation") | [
    Wira Sandy](http://azuraweb.xyz)
    [🌍](#translation-wira-sandy "Translation") | +| [
    Илья](https://github.com/GrayHoax)
    [🌍](#translation-GrayHoax "Translation") | [
    GodUseVPN](https://github.com/godusevpn)
    [🌍](#translation-godusevpn "Translation") | [
    周周](https://github.com/EngrZhou)
    [🌍](#translation-EngrZhou "Translation") | [
    Sam](https://github.com/takuy)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=takuy "Code") | [
    Azerothian](https://www.illisian.com.au)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Azerothian "Code") | [
    Wes Hulette](http://macfoo.wordpress.com/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jwhulette "Code") | [
    patrict](https://github.com/patrict)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=patrict "Code") | +| [
    Dmitriy Minaev](https://github.com/VELIKII-DIVAN)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=VELIKII-DIVAN "Code") | [
    liquidhorse](https://github.com/liquidhorse)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=liquidhorse "Code") | [
    Jordi Boggiano](https://seld.be/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Seldaek "Code") | [
    Ivan Nieto](https://github.com/inietov)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=inietov "Code") | [
    Ben RUBSON](https://github.com/benrubson)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=benrubson "Code") | [
    NMathar](https://github.com/NMathar)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=NMathar "Code") | [
    Steffen](https://github.com/smb)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=smb "Code") | +| [
    Sxderp](https://github.com/Sxderp)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Sxderp "Code") | [
    fanta8897](https://github.com/fanta8897)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=fanta8897 "Code") | [
    Andrey Bolonin](https://andreybolonin.com/phpconsulting/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=andreybolonin "Code") | [
    shinayoshi](http://www.shinayoshi.net/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=shinayoshi "Code") | [
    Hubert](https://github.com/reuser)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=reuser "Code") | [
    KeenRivals](https://brashear.me)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=KeenRivals "Code") | [
    omyno](https://github.com/omyno)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=omyno "Code") | +| [
    Evgeny](https://github.com/jackka)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jackka "Code") | [
    Colin Campbell](https://digitalist.se)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=colin-campbell "Code") | [
    Ľubomír Kučera](https://github.com/lubo)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=lubo "Code") | [
    Martin Meredith](https://www.sourceguru.net)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Mezzle "Code") | [
    Tim Farmer](https://github.com/timothyfarmer)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=timothyfarmer "Code") | [
    MariΓ‘n Skrip](https://github.com/mskrip)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mskrip "Code") | [
    Godfrey Martinez](https://github.com/Godmartinz)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Godmartinz "Code") | +| [
    bigtreeEdo](https://github.com/bigtreeEdo)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=bigtreeEdo "Code") | [
    Colin McNeil](https://colinmcneil.me/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ColinMcNeil "Code") | [
    JoKneeMo](https://github.com/JoKneeMo)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=JoKneeMo "Code") | [
    Joshi](http://www.redbridge.se)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=joshi-redbridge "Code") | [
    Anthony Burns](https://github.com/anthonypburns)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=anthonypburns "Code") | [
    johnson-yi](https://github.com/johnson-yi)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=johnson-yi "Code") | [
    Sanjay Govind](https://tangentmc.net)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=sanjay900 "Code") | +| [
    Peter Upfold](https://peter.upfold.org.uk/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=PeterUpfold "Code") | [
    Jared Biel](https://github.com/jbiel)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jbiel "Code") | [
    Dampfklon](https://github.com/dampfklon)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=dampfklon "Code") | [
    Charles Hamilton](https://communityclosing.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=chamilton-ccn "Code") | [
    Giuseppe Iannello](https://github.com/giannello)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=giannello "Code") | [
    Peter Dave Hello](https://www.peterdavehello.org/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=PeterDaveHello "Code") | [
    sigmoidal](https://github.com/sigmoidal)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=sigmoidal "Code") | +| [
    Vincent LainΓ©](https://github.com/phenixdotnet)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=phenixdotnet "Code") | [
    Lucas Pleß](http://www.lucas-pless.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=derlucas "Code") | [
    Ian Littman](http://twitter.com/iansltx)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=iansltx "Code") | [
    JoΓ£o Paulo](https://github.com/PauloLuna)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=PauloLuna "Code") | [
    ThoBur](https://github.com/ThoBur)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ThoBur "Code") | [
    Alexander Chibrikin](http://phpprofi.ru/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=alek13 "Code") | [
    Anthony Winstanley](https://github.com/winstan)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=winstan "Code") | +| [
    Folke](https://github.com/fashberg)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=fashberg "Code") | [
    Bennett Blodinger](https://github.com/benwa)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=benwa "Code") | [
    NMC](https://nmc.dev)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ncareau "Code") | [
    andres-baller](https://github.com/andres-baller)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=andres-baller "Code") | [
    sean-borg](https://github.com/sean-borg)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=sean-borg "Code") | [
    EDVLeer](https://github.com/EDVLeer)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=EDVLeer "Code") | [
    Kurokat](https://github.com/Kurokat)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Kurokat "Code") | +| [
    Kevin KΓΆllmann](https://www.kevinkoellmann.de)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=koelle25 "Code") | [
    sw-mreyes](https://github.com/sw-mreyes)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=sw-mreyes "Code") | [
    Joel Pittet](https://pittet.ca)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=joelpittet "Code") | [
    Eli Young](https://elyscape.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=elyscape "Code") | [
    Raell Dottin](https://github.com/raelldottin)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=raelldottin "Code") | [
    Tom Misilo](https://github.com/misilot)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=misilot "Code") | [
    David Davenne](http://david.davenne.be)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=JuustoMestari "Code") | +| [
    Mark Stenglein](https://markstenglein.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ocelotsloth "Code") | [
    ajsy](https://github.com/ajsy)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ajsy "Code") | [
    Jan Kiesewetter](https://github.com/t3easy)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=t3easy "Code") | [
    Tetrachloromethane250](https://github.com/Tetrachloromethane250)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Tetrachloromethane250 "Code") | [
    Lars Kajes](https://www.kajes.se/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=kajes "Code") | [
    Joly0](https://github.com/Joly0)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Joly0 "Code") | [
    theburger](https://github.com/limeless)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=limeless "Code") | +| [
    David Valin Alonso](https://github.com/deivishome)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=deivishome "Code") | [
    andreaci](https://github.com/andreaci)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=andreaci "Code") | [
    Jelle Sebreghts](http://www.jellesebreghts.be)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Jelle-S "Code") | [
    Michael Pietsch](https://github.com/Skywalker-11)
    | [
    Masudul Haque Shihab](https://github.com/sh1hab)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=sh1hab "Code") | [
    Supapong Areeprasertkul](http://www.freedomdive.com/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=zybersup "Code") | [
    Peter Sarossy](https://github.com/psarossy)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=psarossy "Code") | +| [
    Renee Margaret McConahy](https://github.com/nepella)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=nepella "Code") | [
    JohnnyPicnic](https://github.com/JohnnyPicnic)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=JohnnyPicnic "Code") | [
    markbrule](https://github.com/markbrule)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=markbrule "Code") | [
    Mike Campbell](https://github.com/mikecmpbll)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mikecmpbll "Code") | [
    tbrconnect](https://github.com/tbrconnect)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=tbrconnect "Code") | [
    kcoyo](https://github.com/kcoyo)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=kcoyo "Code") | [
    Travis Miller](https://travismiller.com/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=travismiller "Code") | +| [
    Evan Taylor](https://github.com/Delta5)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Delta5 "Code") | [
    Petri Asikainen](https://github.com/PetriAsi)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=PetriAsi "Code") | [
    derdeagle](https://github.com/derdeagle)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=derdeagle "Code") | [
    Mike Frysinger](https://wh0rd.org/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=vapier "Code") | [
    ALPHA](https://github.com/AL4AL)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=AL4AL "Code") | [
    FliegenKLATSCH](https://www.ifern.de)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=FliegenKLATSCH "Code") | [
    Jeremy Price](https://github.com/jerm)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jerm "Code") | +| [
    Toreg87](https://github.com/Toreg87)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Toreg87 "Code") | [
    Matthew Nickson](https://github.com/Computroniks)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Computroniks "Code") | [
    Jethro Nederhof](https://jethron.id.au)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jethron "Code") | [
    Oskar Stenberg](https://github.com/01ste02)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=01ste02 "Code") | [
    Robert-Azelis](https://github.com/Robert-Azelis)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Robert-Azelis "Code") | [
    Alexander William Smith](https://github.com/alwism)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=alwism "Code") | [
    LEITWERK AG](https://www.leitwerk.de/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=leitwerk-ag "Code") | +| [
    Adam](http://www.aboutcher.co.uk)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=adamboutcher "Code") | [
    Ian](https://snksrv.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=sneak-it "Code") | [
    Shao Yu-Lung (Allen)](http://blog.bestlong.idv.tw/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=bestlong "Code") | [
    Haxatron](https://github.com/Haxatron)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Haxatron "Code") | [
    PlaneNuts](https://github.com/PlaneNuts)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=PlaneNuts "Code") | [
    Bradley Coudriet](http://bjcpgd.cias.rit.edu)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=exula "Code") | [
    Dalton Durst](https://daltondur.st)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=UniversalSuperBox "Code") | +| [
    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") | [
    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") | +| [
    akemidx](https://github.com/akemidx)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [
    Oguz Bilgic](http://oguz.site)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [
    Scooter Crawford](https://github.com/scoo73r)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [
    subdriven](https://github.com/subdriven)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [
    Andrew Savinykh](https://github.com/AndrewSav)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") | [
    Tadayuki Onishi](https://kenchan0130.github.io)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=kenchan0130 "Code") | [
    Florian](https://github.com/floschoepfer)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=floschoepfer "Code") | +| [
    Spencer Long](http://spencerlong.com)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [
    Marcus Moore](https://github.com/marcusmoore)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [
    Martin Meredith](https://github.com/Mezzle)
    | [
    dboth](http://dboth.de)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=dboth "Code") | [
    Zachary Fleck](https://github.com/zacharyfleck)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=zacharyfleck "Code") | [
    VIKAAS-A](https://github.com/vikaas-cyper)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=vikaas-cyper "Code") | [
    Abdul Kareem](https://github.com/ak-piracha)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=ak-piracha "Code") | +| [
    NojoudAlshehri](https://github.com/NojoudAlshehri)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=NojoudAlshehri "Code") | [
    Stefan Stidl](https://github.com/stefanstidlffg)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=stefanstidlffg "Code") | [
    Quentin Aymard](https://github.com/qay21)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=qay21 "Code") | [
    Grant Le Roux](https://github.com/cram42)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=cram42 "Code") | [
    Bogdan](http://@singrity)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Singrity "Code") | [
    mmanjos](https://github.com/mmanjos)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mmanjos "Code") | [
    Abdelaziz Faki](https://azooz2014.github.io/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Azooz2014 "Code") | +| [
    bilias](https://github.com/bilias)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=bilias "Code") | [
    coach1988](https://github.com/coach1988)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=coach1988 "Code") | [
    MrM](https://github.com/mauro-miatello)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mauro-miatello "Code") | [
    koiakoia](https://github.com/koiakoia)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=koiakoia "Code") | [
    Mustafa Online](https://github.com/mustafa-online)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=mustafa-online "Code") | [
    franceslui](https://github.com/franceslui)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=franceslui "Code") | [
    Q4kK](https://github.com/Q4kK)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=Q4kK "Code") | +| [
    squintfox](https://github.com/squintfox)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=squintfox "Code") | [
    Jeff Clay](https://github.com/jeffclay)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=jeffclay "Code") | [
    Phil J R](https://github.com/PP-JN-RL)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=PP-JN-RL "Code") | [
    i_virus](https://www.corelight.com/)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=chandanchowdhury "Code") | [
    Paul Grime](https://github.com/gitgrimbo)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=gitgrimbo "Code") | [
    Lee Porte](https://leeporte.co.uk)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=LeePorte "Code") | [
    BRYAN ](https://github.com/bryanlopezinc)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=bryanlopezinc "Tests") | +| [
    U-H-T](https://github.com/U-H-T)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=U-H-T "Code") | [
    Matt Tyree](https://github.com/Tyree)
    [πŸ“–](https://github.com/snipe/snipe-it/commits?author=Tyree "Documentation") | [
    Florent Bervas](http://spoontux.net)
    [πŸ’»](https://github.com/snipe/snipe-it/commits?author=FlorentDotMe "Code") | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!