Compare commits

...

246 Commits

Author SHA1 Message Date
snipe ac8f46c93c Bumped version for beta release 2017-08-09 19:01:07 -07:00
snipe 101a09b421 Removed chart (for now) 2017-08-09 19:00:54 -07:00
snipe cb1e3b7978 Fixed encryption warning on custom fields 2017-08-09 18:40:45 -07:00
snipe de18e2a887 Only bcrypt passwords on user save if the password value is passed 2017-08-08 14:41:58 -07:00
snipe 241bf0cd4b Allow port number to be configured via env 2017-08-08 12:36:44 -07:00
snipe 7da4fe4524 Fixes #3825 - allows fillables through location API 2017-08-08 12:36:28 -07:00
snipe 9bfd345774 Use Company transformer with payload 2017-08-03 19:55:08 -07:00
snipe df87c82ddc Fixes #3805 - add/update/delete methods for User API 2017-08-03 19:50:18 -07:00
snipe 3e8b7d9c94 Check for overall asset delete permissions before checking to see if the user can delete that specific asset 2017-08-03 19:49:41 -07:00
snipe 7adfab9d9f Fixes #3632 and #3817 - set archived to default 0 so imported assets will be included in expiring reports 2017-08-03 16:04:47 -07:00
Jason Spriggs 7c4ee54f8b Fix #3803 - Return asset object instead of just id (#3811) 2017-08-01 20:01:11 -07:00
snipe 03f9d01aab Fixes #3775 - added missing created_at and updated_at fields 2017-07-29 17:01:03 -07:00
snipe 5b420fb4b9 Fixes #3779 - corrects presenter used for Consumables 2017-07-29 16:44:51 -07:00
snipe a2d63dd3e4 Fixes #3776 - adds Company to Dept UI 2017-07-29 16:42:17 -07:00
snipe 0408509fdc Fixes #3777 - correct response for two_factor_actived for user API 2017-07-29 16:25:42 -07:00
snipe 5e47c18d68 Fixes #3786 - checkin/checkout to components UI 2017-07-29 16:13:17 -07:00
snipe b3293a7a5f Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-07-29 15:46:38 -07:00
snipe 4e5cf531f7 Fixes #3799 - use transformers on show() method as well 2017-07-29 15:46:10 -07:00
Donald M f0bbe38c71 fixes #3725 in develop branch (#3800)
added button for create Asset Model to index.blade.php in develop branch.
2017-07-29 15:33:16 -07:00
snipe ccb7556281 Fixes javascript error when custom fields exist but do not belong to any fieldsets or models 2017-07-26 17:06:58 -07:00
snipe ee7348d0d5 Better fix for javascript formatter for employee number 2017-07-26 16:47:47 -07:00
snipe 7d6bf4ac24 Fixes stupid javascript for employee_number 2017-07-26 16:26:47 -07:00
snipe cb903ab9fd Fixes manager user->name to username in Users API 2017-07-26 08:51:16 -07:00
snipe 66d8308163 More compact payload for users API on location and manager 2017-07-26 08:47:54 -07:00
snipe 847262e989 Fixes #3774 - fixes for inconsistent API responses (‘’ vs null) and adds escaping 2017-07-25 23:40:30 -07:00
snipe 59006964d1 Fixes #3771 - adds username to API response on Asset API 2017-07-25 22:11:50 -07:00
snipe ac29b142dc Adds max thumbnail width to asset listings, settings 2017-07-25 19:36:38 -07:00
snipe 978a906513 Fixes undefined error when validation fails on asset save 2017-07-25 19:32:09 -07:00
snipe dfa0714d44 Fixes #3770 - account update not saving correctly 2017-07-25 12:28:11 -07:00
snipe 0fbf9236f4 Fixes #3742 - add employee number to asset listing
Also removes asset report, since it’s basically the exact same output as the asset listing
2017-07-25 01:17:23 -07:00
snipe c64ca76b3d Fixes API route 2017-07-25 01:16:31 -07:00
snipe 73052d3fc1 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-07-25 00:24:26 -07:00
snipe ae0b639d0c Added link to AGPL 2017-07-25 00:24:22 -07:00
Jan Felix Wiebe 5cc84ca137 Use correct array when deleting users with location (#3769) 2017-07-24 23:15:15 -07:00
snipe 7510f9f128 Fixes #3753 - use route direction instead of URL 2017-07-17 16:42:39 -07:00
snipe 7c6143bbb8 Fixes #3754 - incorrect language translation location for supplier 2017-07-17 16:39:19 -07:00
snipe 346156bae1 Added colored icons to indicate status types versus status labels 2017-07-17 16:19:52 -07:00
snipe 3eea1a23f8 Slug the filename
So upoloads with weird characters like parens don’t get hoarked when trying to delete
2017-07-14 02:38:13 -07:00
snipe 1fda4593c1 Update @gibsonjoshua55 as a contributor 2017-07-12 20:41:20 -07:00
snipe 6b5a0983ee Added model validation to custom fieldsets 2017-07-12 19:34:45 -07:00
snipe ad12a5ce11 Added store/update methods to custom fields API 2017-07-12 19:34:34 -07:00
snipe ec09ea53db Changed custom fieldset API routes to resource routes for consistency 2017-07-12 19:24:21 -07:00
snipe 5abe72ce02 Added whether the field is required to the custom fieldsets transformer 2017-07-12 19:23:54 -07:00
snipe 3e3276334b Added escaping to API output 2017-07-12 19:23:15 -07:00
snipe b13e04095e Removed commented code 2017-07-12 19:22:58 -07:00
gibsonjoshua55 3cfcc43efa Adds basic GET api support for CustomFieldsets (#3697)
* Adds basic GET api support for CustomFieldsets

Currently there is not support for getting what fields a given fieldset contains
from the API.  This commit creates a new API Controller for CustomFieldsets as
well as Transformers for CustomFields CustomFieldsets.  Additionally, the api
route has been updated so that a show method can be access from
http://myapp/api/v1/fieldsets/{id}

* CustomFieldsetsTransformer only returns id and name of model

* Added index api method for CustomFieldsets

* Removes copy/paste error in CustomFieldsetController (including search)

* Added id to CustomFieldsetsTransformers

* Adds custom_fieldset_id as a field when storing and updating AssetModels

* Removed uncessesary parameter from CustomFieldsetsController.index

* Cleaned up CustomFieldset API
2017-07-12 17:51:22 -07:00
Daniel Meltzer f432f98e12 Importer tests + Fixes (#3733)
* Fix Bug in User::generateFormattedNameFromFullName

In a name "John Doe", this method would split it into "John" and " Doe",
Leaving a space in the last name when importing to the database.  Strip
this space.

* Cleanup/fix some item mapping.

Also make some changes to the importer schema to allow for unit testing.
Generate a default item mapping, and then merge that with any custom
mappings.

* Beginning work on importer unit tests.

* Strip out testrun branches from importer.  It added a lot of complexity and was not terribly useful with web importer as it stood, might reconsider down the road however.

* Normalize the mapped keys when using custom field mappings.

* Add test for custom asset import mapping.

* Make all unit tests inherit from a new custom base.

This baseclass currently calls Artisan::migrate() and seeds a Settings
instance.  This fixes unit tests after the autoincrement bits.

* Store requestable as a boolean.  Fixes some import oddities

* Work on tests for accessory importer.

* Test for custom mapping of accessory import, also adjust the internal field for purchase date.

* Update default locale fallback for currency detection

* Fix Reassignable in consumable as well.

* More importer tests and fixes.
2017-07-11 20:37:02 -07:00
snipe 9bcfe0748b Make custom fields into their own JSON array 2017-07-08 18:44:28 -07:00
snipe de5e7bd9ba Removed null formatter 2017-07-08 17:04:52 -07:00
snipe 635299cd74 Decrypt encrypted fields 2017-07-08 17:04:40 -07:00
snipe 20376daec4 Fix encryption on first save 2017-07-08 17:04:24 -07:00
snipe 50e1570543 Added additional models for #3702 2017-07-08 14:49:43 -07:00
snipe eb94c4333d Fixes #3702 - Added artisan command to walk through special characters and unescape them in the DB 2017-07-08 14:47:43 -07:00
snipe a49fd16916 Fixed delete file settings route 2017-07-08 13:42:05 -07:00
snipe 0cc9c214aa Added tooltip for undeployable items 2017-07-08 13:39:07 -07:00
snipe c48bcb7ed1 Added tooltips for checkin/checkout 2017-07-08 13:36:37 -07:00
snipe 09de201027 Removed question mark on delete title 2017-07-08 13:36:25 -07:00
snipe 6ce2127d75 Fixes incorrect link on dashboard 2017-07-08 13:36:06 -07:00
snipe e79260a0d4 Fixes #3732 - broken tooltips and weird select2 option text behavior
The solve here was a few things - first, load jquery-ui before bootstrap. They have conflicting tooltips. Second, initiate the tooltips in the wenzhixin/bootstrap-table formatter using `data-tooltip=“true”`, and thirdly, add some JS that tells BS table to inititalize tooltips within the table using that `data-tooltip=“true”` business
2017-07-08 13:21:13 -07:00
snipe 932e25ca9b Only add an update log message if the asset isn’t being checked in or out 2017-07-08 03:38:39 -07:00
snipe b02148f59e Updated formatter for location display 2017-07-08 02:24:30 -07:00
snipe 6046063666 Updated LDAP icon 2017-07-08 02:24:20 -07:00
snipe fd57617c8e Check that the LDAP extension is loaded and functions are available 2017-07-08 01:48:29 -07:00
snipe 44569558e9 Remove admin label 2017-07-08 01:41:07 -07:00
snipe d2f6c8af11 Require first name field if LDAP is enabled 2017-07-08 01:40:56 -07:00
snipe 814bf18a4b Updated phpinfo title 2017-07-08 00:23:28 -07:00
snipe 33557f3792 Nicer formatting for phpinfo output 2017-07-08 00:22:30 -07:00
snipe c2927c4a2e Added phpinfo page if debugging is enabled 2017-07-08 00:09:39 -07:00
snipe ab2b2f3043 Updated UI for Admin Settings 2017-07-07 23:44:48 -07:00
snipe 0e598702f8 Fixed error field name in settings > login note 2017-07-07 19:56:14 -07:00
snipe 9894edb008 Added login note to settings 2017-07-07 19:54:10 -07:00
snipe c2e8803d1e Addec clone button back to models, assets, licenses, etc 2017-07-07 18:45:49 -07:00
snipe 7e1f7297b3 Settings tweaks 2017-07-07 18:06:31 -07:00
snipe 3401f3dfb9 Added @uberbrady as code owner of custom fields API too 2017-07-07 17:10:23 -07:00
snipe 31cabaa4db Fixes #3724 - adds edit/delete button back to companies listing 2017-07-07 17:10:06 -07:00
snipe 06c04bf271 Created a contibuting md so GH would stop whining at me
(even though it’s documented elsewhere)
2017-07-07 16:37:11 -07:00
snipe 4c39be1f3c First stab at a code owners doc
More info:
https://github.com/blog/2392-introducing-code-owners
https://help.github.com/articles/about-codeowners/
2017-07-07 16:36:45 -07:00
snipe c8c279588f Updated language strings 2017-07-07 13:14:51 -07:00
snipe 8aa920ca3a Update composer 2017-07-07 12:59:59 -07:00
snipe 0242283a11 Updated composer 2017-06-23 18:56:42 -07:00
snipe 9e0c5e50b6 Merge branch 'develop' of github.com:snipe/snipe-it into develop
# Conflicts:
#	composer.lock
2017-06-23 18:55:18 -07:00
snipe 95d1612234 Updated composer 2017-06-23 18:52:21 -07:00
Daniel Meltzer 61c6160b98 Importer mapping - v1 (#3677)
* Move importer to an inline-template, allows for translations and easier passing of data from laravel to vue.

* Pull the modal out into a dedicated partial, move importer to views/importer.

* Add document of CSV->importer mappings.  Reorganize some code.

Progress.

* Add header_row and first_row to imports table, and process upon uploading a file

* Use an expandable table row instead of a modal for import processing.  This should allow for field mapping interaction easier.

* Fix import processing after moving method.

* Frontend importer mapping improvements.

Invert display so we show found columns and allow users to select an
importer field to map to.  Also implement sample data based on first row
of csv.

* Update select2.  Maintain selected items properly.

* Backend support for importing.  Only works on the web importer currently.  Definitely needs testing and polish.

* We no longer use vue-modal plugin.

* Add a column to track field mappings to the imports table.

* Cleanup/rename methods+refactor

* Save field mappings and import type when attempting an import, and repopulate these values when returning to the page.

* Update debugbar to fix a bug in the debugbar code.

* Fix asset tag detection.

Also rename findMatch to be a bit clearer as to what it does.
  Remove logging to file of imports for http imports because
it eats an incredible amouint of memory.

This commit also moves imports out of the hardware namespace and into
their own webcontroller and route prefix, remove dead code from
AssetController as a result.

* Dynamically limit options for select2 based on import type selected, and group them by item type.

* Add user importer.

Still need to implement emailing of passwords to new users, and probably
test a bit more.

This also bumps the memory limit for web imports up as well, I need to
profile memory usage here before too long.

* Query the db to find user matches rather than search the array.  Performance is much much better.

* Speed/memory improvements in importers.

Move to querying the db rather than maintaining an array for all
importers.  Also only store the id of items when we import, rather than
the full model.  It saves a decent amount of memory.

* Remove grouping of items in select2

With the values being set dynamically, the grouping is redundant.  It
also caused a regression with automatically guessing/matching field
names.  This is starting to get close.

* Remove debug line on every create.

* Switch migration to be text field instead of json field for compatibility with older mysql/mariadb

* Fix asset import regression matching email address.

* Rearrange travis order in attempt to fix null settings.

* Use auth::id instead of fetching it off the user.  Fixes a null object reference during seeding.
2017-06-21 16:37:37 -07:00
Daniel Meltzer d12159c042 Fix travis with new observer code (#3683)
* Rearrange travis order in attempt to fix null settings.

* Use auth::id instead of fetching it off the user.  Fixes a null object reference during seeding.
2017-06-20 20:38:13 -07:00
snipe e009bb956d Possible fix for travis donkery 2017-06-20 19:48:57 -07:00
snipe 25e99194ce Fixes #3681 - corrected fieldname for bulk asset delete 2017-06-20 14:41:30 -07:00
snipe 274f3511f5 Fixes new setup migration for auto-increment 2017-06-20 12:23:32 -07:00
snipe 5b9bcd8fa2 Add next auto-increment to settings form 2017-06-20 12:23:16 -07:00
snipe 4bde058192 Save next_auto_tag_base in settings on edit 2017-06-20 12:19:05 -07:00
snipe ffba9789b7 Fixed typo in variable name 2017-06-20 12:13:36 -07:00
snipe 770092f23f Added save/update/delete observers
This should make it easier to handle action logging between the GUI and the API
2017-06-15 20:54:14 -07:00
snipe 99f65cbf69 Hopefully fixes #3203 and #3439 2017-06-15 19:42:43 -07:00
Daniel Meltzer 5d4920c741 [WIP] Improvements to unit tests. (#3574)
* Improvemenets to unit tests.

* Break up modelfactory into multiple files, populate many states.
* Begin testing validation at the unit test level, test relationships.
* Add tests for Asset::availableForCheckout.
* Model factories now generate all needed relationships on demand,
  which allows us to unit test with a empty database.
* To faciliate the empty database, we move to using sqlite in memory as
  the unit testing database.

* Fix bug with logs of checkouts to non users.

* Fix location finding for assets.  Also Fix location show page to show users associated with location.  Still need some work to show assets.

* More test and generator improvements

* More unit test fixes. PermissionsTest is borked still.

* More Updates

* Rewrite permissionstest.  Check that we have access on the model level rather than via web requests.  Also test delete permissions.

* Fix seeders.

* Make the default asset model factory generate assets that are rtd for testing.

* Save progress.

* Rebase tests, fix department unit test, update database for functional tests.

* Update functional and api tests to use new modelfactory signatures.
2017-06-12 17:39:03 -07:00
snipe 966a736602 Patches #3640 to develop 2017-06-12 15:31:11 -07:00
Daniel Meltzer 30487bfee7 Fix importer vue issues. (#3655)
We currently depend on a "vue-strap" module to provide the modal dialog.
The default npm vue-strap is not compatible with vue2, so we need to use
a fork.  Update package.json to reflect this.  Probably makes sense to
move away from vue-strap in all my copious amounts of free time.
2017-06-12 15:24:49 -07:00
snipe 3046d7d33c Fixes #3644 - broken datepicker 2017-06-09 18:53:19 -07:00
snipe 0aa76bd946 PHPStorm lag strikes again 2017-06-09 16:49:55 -07:00
snipe 26d7fffae8 Added in/out string to general 2017-06-09 16:47:28 -07:00
snipe 14f3868b46 Update all controllers to use laravel 5 return view method 2017-06-09 16:44:03 -07:00
snipe a5cd4a0a22 Use updated view method for laravel 5 2017-06-09 16:31:25 -07:00
snipe ad816264e9 WIP import mapper #3639
@dmeltzer, I’m not sure how much extra work this will be to integrate.
2017-06-09 16:29:42 -07:00
snipe c2494fe0e5 Removed social buttons for BS styles 2017-06-09 14:59:23 -07:00
snipe 02edb74cdf Style updates 2017-06-09 14:58:43 -07:00
snipe 408bb6476f Removed some unneeded styles 2017-06-09 14:57:57 -07:00
snipe ee5b5acffb Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-06-09 12:44:49 -07:00
snipe e387673e74 Fixes #3651 - backups not working 2017-06-09 12:44:11 -07:00
Ben 17ce4ea08b Fixes #3649 (#3650)
Fixes issue #3649 with gohilurvish’s recommended fix.
2017-06-09 12:23:32 -07:00
snipe 0bc709206f Fixes #3652 - missing groups UI element in user edit view 2017-06-09 12:19:12 -07:00
snipe e9dd119b9c Fixes some vue styles 2017-06-09 02:06:10 -07:00
snipe 269997a1fb Push v3.6.5 changes into v4 2017-06-09 00:35:23 -07:00
snipe 041b794e1f Fixes #3634 - use new routes for groups 2017-06-08 20:24:26 -07:00
snipe da2d9b2374 Fixes presenter issue on user history 2017-06-08 19:09:42 -07:00
snipe a59db7062d Fix license datatable on license view 2017-06-08 18:59:53 -07:00
snipe 58b2834c54 Fixed case for userloc 2017-06-08 18:46:07 -07:00
snipe 2aaa635345 Fixes crash on asset detail view 2017-06-08 18:26:55 -07:00
snipe 8269aec71a Removed erroneous file 2017-06-08 17:51:30 -07:00
snipe d62896f945 Fixes #3414 - bulk update for asset models 2017-06-08 17:48:48 -07:00
snipe a717ca683c Fixes #3648 - missing endif in blade 2017-06-08 16:16:49 -07:00
snipe d7827fedd9 Fixed dashboard size element 2017-06-06 15:19:19 -07:00
snipe fbcc40a145 Commented out dashboard chart until proper data provided 2017-06-06 02:51:29 -07:00
snipe 12a7309ecd Note that the chart doesn’t work, to clear things up 2017-06-06 02:40:50 -07:00
snipe 9caf045930 Production assets 2017-06-06 02:36:02 -07:00
snipe 1c056d1a59 Updated asset urls 2017-06-06 02:35:26 -07:00
snipe 240a07b108 Formatting for error pages 2017-06-06 02:32:04 -07:00
snipe c977dda5bb Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-06-06 01:45:25 -07:00
snipe 03411a3ae8 Removed poop class, added comment to webpack file 2017-06-06 01:44:17 -07:00
snipe 01cc00c832 Fixing webpack. Again 2017-06-06 01:39:53 -07:00
snipe 9338b37b74 Try to fix the datepicker :(
Webpack has fucked everything. I hate everything.
2017-06-06 00:51:41 -07:00
snipe 9cd2881ad0 Initiate datepicker 2017-06-06 00:29:52 -07:00
snipe 64b483b686 Updated build css output
I don't know why I need to do this. :(
2017-06-06 00:06:29 -07:00
snipe 1f7266274d Updated manifest 2017-06-06 00:06:01 -07:00
snipe 4e5b2d1fe9 Updated font awesome 2017-06-06 00:05:47 -07:00
snipe ada2ac06f2 Minified all.css 2017-06-06 00:05:22 -07:00
snipe 9d948e8d23 Removed erroneous bower dir 2017-06-06 00:04:55 -07:00
snipe 4062228092 Updated contribs 2017-06-05 23:54:13 -07:00
Wyatt 3e67cdc501 Allows a null location value for importing LDAP users (#3598)
* Allows a null location value for importing LDAP users

* Forgot you need to set the variable to null..
2017-06-01 21:20:40 -07:00
snipe be42a0add1 Add @steveelwood as a contributor 2017-06-01 21:03:05 -07:00
snipe 6cadde23d7 Add @manassesferreira as a contributor 2017-06-01 21:00:47 -07:00
snipe a6c1f7b30b Add @n8felton as a contributor 2017-06-01 20:59:15 -07:00
snipe 1b5b0e9d19 Add @jasonspriggs as a contributor 2017-06-01 20:58:50 -07:00
snipe 2a226fd3f9 Update @pakkua80 as a contributor 2017-06-01 20:58:26 -07:00
snipe 043182593d Add @BrettFagerlund as a contributor 2017-06-01 20:57:55 -07:00
snipe 08dc07b46b Apply PR #3620 to develop (oracle linux support) 2017-06-01 20:55:30 -07:00
snipe 2d3ea4eec6 Apply PR #3616 (Docker updates) 2017-06-01 20:53:01 -07:00
snipe 74aaadcdc5 Fixes #3583 - incorrect 404 status code, use curl for checking .env 2017-06-01 20:41:23 -07:00
snipe 0238dd59a3 Fixes #3600 - wrong route for hardware 2017-06-01 20:34:01 -07:00
snipe 461ca53289 Fixes #3603 - Depreciation report crashes 2017-06-01 20:31:44 -07:00
snipe ccc0063556 Fixes #3604 - company view not displaying assets on page load 2017-06-01 20:28:09 -07:00
snipe 66145a625c Upgraded laravel mix 2017-05-31 13:57:34 -07:00
snipe cc5192c91e Updated asset url 2017-05-31 13:57:23 -07:00
snipe de5334e525 Updated with production assets 2017-05-31 13:27:17 -07:00
snipe b797604627 Fixed &%#!@@!ing ES that prevented npm run production from working 2017-05-31 13:26:48 -07:00
snipe 293981148c Few more stabs at this dumb uglify error 2017-05-31 12:56:09 -07:00
snipe 66eaff739a More npm/css/js updates 2017-05-31 12:34:05 -07:00
snipe 8b5cb6e8c2 Added build directory for misc laravel mix crap 2017-05-31 12:01:45 -07:00
snipe 7b4b2d79cf Moved CSS/JS/etc assets up one level 2017-05-31 10:31:56 -07:00
snipe c3af13298e Added webpack.mix.js
Everything is terrible
2017-05-31 10:28:53 -07:00
snipe 312fd27d11 Removed weird temp file 2017-05-31 10:28:07 -07:00
snipe 1b55d38c63 Attempts at un-fscking package.json for laravel mix 2017-05-31 10:26:27 -07:00
snipe 1992906790 Use laravel mix asset call 2017-05-31 09:41:52 -07:00
snipe b0fc2489f6 Almost fixes user history table
Something is still fucky here
2017-05-31 09:39:52 -07:00
snipe b13726880e Fixes #3601 - HTML instead of username for manager in user view 2017-05-31 09:39:30 -07:00
snipe 25dca80644 Fixes #3602 - actions missing from suppliers in v4 2017-05-31 06:52:37 -07:00
snipe 748aba3c48 Add assets dashboard feature
- also a really broken sample graph
2017-05-31 05:23:54 -07:00
snipe c9484fa30b Updated compiled assets 2017-05-31 05:23:26 -07:00
snipe d950ddbda7 Changed go button to primary class 2017-05-31 05:23:09 -07:00
snipe fd0165b4b8 New compiled assets 2017-05-31 03:32:29 -07:00
snipe fd0da6ecf0 Ignore the icon column in exports 2017-05-31 02:03:09 -07:00
snipe 7b1265cb89 Cache totals for later dashboard use 2017-05-31 02:02:55 -07:00
snipe 92052442e3 Include department in user info 2017-05-31 01:17:30 -07:00
snipe 71b668e1a3 Removed extra else to make Codacy happy 2017-05-23 15:53:39 -07:00
snipe 3c167c9d33 Remove debugging frowny-face 2017-05-23 15:06:43 -07:00
snipe 9f87f72c96 Updated route name for activity report API call 2017-05-23 14:33:36 -07:00
snipe 5e0cc93ba2 Use new formatters in bootstrap table 2017-05-23 14:33:19 -07:00
snipe 3724442318 Exclude some BS table calls if it’s just a simple ajax table with no sorting/searching 2017-05-23 14:32:58 -07:00
snipe 610a773620 Use activity report for view-assets 2017-05-23 14:32:21 -07:00
snipe a1c7d2922e Tweaks to dashboard API calls 2017-05-23 14:32:02 -07:00
snipe 8ab29c628f Added icon to presenter 2017-05-23 14:31:44 -07:00
snipe 4ada5eaa94 Added targetType method 2017-05-23 14:31:14 -07:00
snipe 5499735f3a Actionlogs API transformer 2017-05-23 14:31:04 -07:00
snipe 40e11b6661 Removed old getActivityReportDataTable() method, since we’re using the API now 2017-05-23 14:30:55 -07:00
snipe b1fa25b73e Added filter to report by user_id for activity 2017-05-23 14:30:29 -07:00
snipe 452c52a3ab Changed variable name for consistency 2017-05-23 14:30:07 -07:00
snipe 76926c97c1 Updated dashboard to use new API activity report and added category summary 2017-05-23 09:25:45 -07:00
snipe 6775c39a5e Added simple_view to use compact, no pagination view of tables 2017-05-23 09:25:20 -07:00
snipe ce856bdb0a Moves activity report into API routes 2017-05-23 09:24:53 -07:00
snipe 52f24f7587 Reports API controller 2017-05-23 09:24:36 -07:00
snipe fba7f1ccf6 Fixes #3605 - missing table close tag causing page layout bonking 2017-05-23 03:20:50 -07:00
snipe ed46dee646 Dept tests 2017-05-23 03:03:30 -07:00
snipe 332076bbe5 Fixed location test method name 2017-05-23 03:03:25 -07:00
snipe 9d45375b8a Added dept to user edit/create/bulk edit views 2017-05-23 02:51:09 -07:00
snipe d3b07411da Added depts to bootstrap-table javascript formatters 2017-05-23 02:50:51 -07:00
snipe d17d3a2ef0 Dept views 2017-05-23 02:50:27 -07:00
snipe dd8511c66a Dept strings 2017-05-23 02:50:16 -07:00
snipe f57ebc664e Added dept management to permissions 2017-05-23 02:50:08 -07:00
snipe f285bd3c29 Added Dept field to users table presenter 2017-05-23 02:49:51 -07:00
snipe aeca549bab Dept search in User query scopes 2017-05-23 02:49:27 -07:00
snipe e0d2cbef20 Allow manager to be null for dept 2017-05-23 02:49:00 -07:00
snipe 96e8109d01 Allow location/company/manager to be null via validation 2017-05-23 02:48:51 -07:00
snipe b223630f72 Added dept to User API transformer 2017-05-23 02:48:03 -07:00
snipe e9c39add4f Added dept helper reference in create/edit/bulk edit users 2017-05-23 02:47:49 -07:00
snipe 7ec1724308 Create, edit and destroy for depts 2017-05-23 02:47:25 -07:00
snipe 811ddd2f67 Include depts in returned list, sort by dept 2017-05-23 02:46:55 -07:00
snipe cefb20d46f Set dept manager ID for dept 2017-05-23 02:46:25 -07:00
snipe bb323db685 Load relationships in query 2017-05-23 02:46:03 -07:00
snipe eb3aa99e4f Added destroy method to dept 2017-05-23 02:45:51 -07:00
snipe a7592de304 Added helper for dept list 2017-05-23 02:37:37 -07:00
snipe 64f17cecbf Updated department transformer 2017-05-23 02:37:30 -07:00
snipe e2f2f9e154 Additional methods for Department web UI 2017-05-23 01:09:13 -07:00
snipe 8caf6623f1 Filter by dept for user display 2017-05-23 01:09:03 -07:00
snipe 6c623866c0 Additional API methods for departments 2017-05-23 01:08:55 -07:00
snipe 659e60fd12 Department controllers and transformer 2017-05-22 21:32:33 -07:00
snipe ae329f4160 Department model 2017-05-22 21:32:22 -07:00
snipe e314de3594 Department migration 2017-05-22 21:32:12 -07:00
snipe b0479923b1 Add link to departments 2017-05-22 21:31:58 -07:00
snipe e3a5accace Departments routes 2017-05-22 21:31:47 -07:00
snipe 0c43e64160 Licenses detail view 2017-05-18 22:10:45 -07:00
snipe 708385e23a Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-05-16 12:32:05 -07:00
Jason Spriggs 0ab37af7ab Add in location parent and child information into API requests (#3582)
* Add location hierarchy to LocationsTransformer

* Add in parent_id
2017-05-16 12:30:11 -07:00
snipe 891660d4ea Fixes #3580 - reduce minimim username size to 1 2017-05-16 12:26:38 -07:00
snipe dcfc434075 Added suppliers back to new side menu (oops) 2017-05-15 20:55:53 -07:00
snipe 0c8308f5a4 Fixes for ordering on asset listing 2017-05-15 20:55:39 -07:00
snipe 1bd798c4d2 Removed Brady’s email address 2017-05-15 19:51:05 -07:00
snipe 23be188a49 Fixes #3579 2017-05-15 19:28:26 -07:00
snipe fdd88af44a Fixes #3556 2017-05-15 19:14:55 -07:00
snipe 07882110fa Cleanup dashboard controller
We ajax this data in now
2017-05-09 00:38:45 -07:00
snipe 7a05467dbf Fixed missing password routes 2017-05-09 00:37:37 -07:00
snipe b7843ea565 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-05-08 20:07:03 -07:00
snipe 4f9a253103 Fixes #3546 - increases size of field values in custom fields for listboxes 2017-05-08 20:06:52 -07:00
snipe 322817b8b1 Bumped version 2017-05-08 20:02:52 -07:00
Daniel Meltzer 82dc06ae19 Remove php7 feature (#3548)
...
2017-05-08 18:19:34 -07:00
Daniel Meltzer 38372f2b37 Remove php7 specific feature (#3547)
Not sure how this got in... I don't remember writing it (but I guess I did!)
2017-05-08 18:19:15 -07:00
Daniel Meltzer e9b056f66c Importer fixes v2 (#3524)
* Pave the imports table

* Format error response if file is the wrong type.

* If a custom field doesn't exist, don't insert a blank string into the custom fields table

* CustomField::db_column_name can return the stored name in the db.  It's slugified when that value is set initially.  This fixes a weird issue where _1 was replaced with _xx
2017-05-03 12:14:35 -07:00
snipe f6be7caaeb Updated composer to prevent ambiguous warnings 2017-04-27 18:50:00 -07:00
snipe d7f6d8e997 Fix for completely erroneous DBAL error
This should not work, but somehow does.

¯\_(ツ)_/¯
(╯° °)╯︵ ┻━┻

I hate computers.
2017-04-27 16:56:15 -07:00
snipe 841e3efe96 Add passport commands to boot() to allow us to call them via PHP 2017-04-27 07:09:46 -07:00
snipe 8ba19aa855 Fixes explode for trusted proxy 2017-04-27 07:09:23 -07:00
snipe 5ad9e8585d New composer options 2017-04-27 05:24:30 -07:00
snipe 68e831d555 Fixes #3514 - removed debugging code that was forcing 404 2017-04-27 05:22:03 -07:00
snipe 6fbf45554b Updated phpunit, removed post install and post update commands to see if that fixes upgrade issues 2017-04-27 02:28:22 -07:00
snipe 07f8c9dc5e Added additional mail markdown config variables 2017-04-27 02:27:57 -07:00
snipe e088eea2f7 Pull out weird query scope that breaks stuff when querying large datasets 2017-04-26 22:40:20 -07:00
snipe f4cdeaa956 Fixes #3514 - move tinker requirement out of dev 2017-04-25 07:46:56 -07:00
snipe 59a4e161ff Fixes checkout buttons on licenses list 2017-04-24 21:37:20 -07:00
snipe 6d53a5f58d Updated test for new JSON 2017-04-22 19:31:22 -05:00
snipe 54a2c46101 Fixes #3491 - adds supplier info to assets listing 2017-04-22 19:14:28 -05:00
1384 changed files with 48841 additions and 94941 deletions
+74 -1
View File
@@ -491,7 +491,8 @@
"avatar_url": "https://avatars3.githubusercontent.com/u/2527115?v=3",
"profile": "https://github.com/pakkua80",
"contributions": [
"doc"
"doc",
"code"
]
},
{
@@ -646,6 +647,78 @@
"contributions": [
"code"
]
},
{
"login": "BrettFagerlund",
"name": "Brett",
"avatar_url": "https://avatars2.githubusercontent.com/u/10522541?v=3",
"profile": "https://github.com/BrettFagerlund",
"contributions": [
"test"
]
},
{
"login": "jasonspriggs",
"name": "Jason Spriggs",
"avatar_url": "https://avatars2.githubusercontent.com/u/16108587?v=3",
"profile": "http://jasonspriggs.com",
"contributions": [
"code"
]
},
{
"login": "n8felton",
"name": "Nate Felton",
"avatar_url": "https://avatars2.githubusercontent.com/u/1134568?v=3",
"profile": "http://n8felton.wordpress.com",
"contributions": [
"code"
]
},
{
"login": "manassesferreira",
"name": "Manasses Ferreira",
"avatar_url": "https://avatars2.githubusercontent.com/u/14036694?v=3",
"profile": "http://homepages.dcc.ufmg.br/~manassesferreira",
"contributions": [
"code"
]
},
{
"login": "steveelwood",
"name": "Steve",
"avatar_url": "https://avatars0.githubusercontent.com/u/15913949?v=3",
"profile": "https://github.com/steveelwood",
"contributions": [
"test"
]
},
{
"login": "matc",
"name": "matc",
"avatar_url": "https://avatars1.githubusercontent.com/u/3361683?v=3",
"profile": "http://twitter.com/matc",
"contributions": [
"test"
]
},
{
"login": "VanillaNinjaD",
"name": "Cole R. Davis",
"avatar_url": "https://avatars3.githubusercontent.com/u/7405702?v=3",
"profile": "http://www.davisracingteam.com",
"contributions": [
"test"
]
},
{
"login": "gibsonjoshua55",
"name": "gibsonjoshua55",
"avatar_url": "https://avatars2.githubusercontent.com/u/10167681?v=3",
"profile": "https://github.com/gibsonjoshua55",
"contributions": [
"code"
]
}
]
}
+3 -2
View File
@@ -1,7 +1,8 @@
APP_ENV=local
APP_ENV=testing
APP_DEBUG=true
APP_URL=http://snipe-it.localapp
DB_CONNECTION=mysql
DB_CONNECTION=sqlite_testing
DB_DEFAULT=sqlite_testing
DB_HOST=localhost
DB_DATABASE=snipeittests
DB_USERNAME=snipeit
+22
View File
@@ -0,0 +1,22 @@
# Code ownership for pull request reviews, per
# the feature detailed here:
# https://github.com/blog/2392-introducing-code-owners
# https://help.github.com/articles/about-codeowners/
# These owners will be the default owners for everything in the repo.
* @snipe
# Order is important. The last matching pattern has the most precedence.
# So if a pull request only touches javascript files, only these owners
# will be requested to review.
# For example:
# *.js @octocat @github/js
app/Importer/* @dmeltzer
app/Http/Controllers/CustomFields* @uberbrady
app/Http/Controllers/Api/CustomFields* @uberbrady
resources/views/custom_fields/* @uberbrady
docker/* @uberbrady
+1 -1
View File
@@ -22,9 +22,9 @@ before_script:
- php artisan migrate --env=testing-ci --database=mysql --force
- ./vendor/bin/codecept build
- php artisan --env=testing-ci key:generate
- php artisan --env=testing-ci snipeit:travisci-install
- php artisan --env=testing-ci db:seed --database=mysql --force
- php artisan --env=testing-ci snipeit:create-admin --first_name=Alison --last_name=Foobar --email=me@example.com --username=snipe --password=password
- php artisan --env=testing-ci snipeit:travisci-install
- php artisan --env=testing-ci passport:install
- php artisan serve --env=testing-ci --port=8000 --host=localhost &
- sleep 5
+6
View File
@@ -0,0 +1,6 @@
### Contributing
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing).
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
+26 -14
View File
@@ -1,14 +1,18 @@
FROM debian:jessie-slim
FROM ubuntu:xenial
MAINTAINER Brady Wetherington <uberbrady@gmail.com>
RUN apt-get update && apt-get install -y \
apache2 \
apache2-bin \
libapache2-mod-php5 \
php5-curl \
php5-ldap \
php5-mysql \
php5-mcrypt \
php5-gd \
libapache2-mod-php7.0 \
php7.0-curl \
php7.0-ldap \
php7.0-mysql \
php7.0-mcrypt \
php7.0-gd \
php7.0-xml \
php7.0-mbstring \
php7.0-zip \
patch \
curl \
vim \
@@ -17,13 +21,13 @@ mysql-client \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN php5enmod mcrypt
RUN php5enmod gd
RUN phpenmod mcrypt
RUN phpenmod gd
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php5/apache2/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php5/cli/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.0/apache2/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.0/cli/php.ini
RUN useradd --uid 1000 --gid 50 docker
RUN useradd -m --uid 1000 --gid 50 docker
RUN echo export APACHE_RUN_USER=docker >> /etc/apache2/envvars
RUN echo export APACHE_RUN_GROUP=staff >> /etc/apache2/envvars
@@ -66,7 +70,9 @@ RUN \
RUN cd /tmp;curl -sS https://getcomposer.org/installer | php;mv /tmp/composer.phar /usr/local/bin/composer
# Get dependencies
RUN cd /var/www/html;composer install
USER docker
RUN cd /var/www/html;composer install && rm -rf /home/docker/.composer/cache
USER root
############### APPLICATION INSTALL/INIT #################
@@ -86,7 +92,13 @@ VOLUME ["/var/lib/snipeit"]
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
# Add Tini
ENV TINI_VERSION v0.14.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
ENTRYPOINT ["/tini", "--"]
CMD ["/entrypoint.sh"]
EXPOSE 80
EXPOSE 443
+12 -11
View File
@@ -1,5 +1,5 @@
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=develop)](https://travis-ci.org/snipe/snipe-it) [![Stories in Ready](https://badge.waffle.io/snipe/snipe-it.png?label=ready+for+dev&amp;title=Ready+for+development)](http://waffle.io/snipe/snipe-it) [![Maintenance](https://img.shields.io/maintenance/yes/2016.svg)]() [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.png)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeyhead.svg?style=social)](https://twitter.com/snipeyhead) [![Zenhub](https://raw.githubusercontent.com/ZenHubIO/support/master/zenhub-badge.png)](https://zenhub.io) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=snipe/snipe-it&amp;utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-69-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-77-orange.svg?style=flat-square)](#contributors)
## Snipe-IT - Open Source Asset Management System
@@ -55,17 +55,18 @@ Please see the [translations documentation](https://snipe-it.readme.io/docs/tran
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:
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
| [<img src="https://avatars3.githubusercontent.com/u/197404?v=3" width="110px;"/><br /><sub>snipe</sub>](http://www.snipe.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=snipe) 🚇 [📖](https://github.com/snipe/snipe-it/commits?author=snipe) [⚠️](https://github.com/snipe/snipe-it/commits?author=snipe) [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Asnipe) 🎨 👀 | [<img src="https://avatars0.githubusercontent.com/u/36335?v=3" width="110px;"/><br /><sub>Brady Wetherington</sub>](http://www.uberbrady.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=uberbrady) [📖](https://github.com/snipe/snipe-it/commits?author=uberbrady) 🚇 👀 | [<img src="https://avatars0.githubusercontent.com/u/3803132?v=3" width="110px;"/><br /><sub>Daniel Meltzer</sub>](https://github.com/dmeltzer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dmeltzer) [⚠️](https://github.com/snipe/snipe-it/commits?author=dmeltzer) [📖](https://github.com/snipe/snipe-it/commits?author=dmeltzer) | [<img src="https://avatars0.githubusercontent.com/u/1609106?v=3" width="110px;"/><br /><sub>Michael T</sub>](http://www.tuckertechonline.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mtucker6784) | [<img src="https://avatars2.githubusercontent.com/u/3274937?v=3" width="110px;"/><br /><sub>madd15</sub>](https://github.com/madd15)<br />[📖](https://github.com/snipe/snipe-it/commits?author=madd15) 💬 | [<img src="https://avatars2.githubusercontent.com/u/894126?v=3" width="110px;"/><br /><sub>Vincent Sposato</sub>](https://github.com/vsposato)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vsposato) | [<img src="https://avatars0.githubusercontent.com/u/1639757?v=3" width="110px;"/><br /><sub>Andrea Bergamasco</sub>](https://github.com/vjandrea)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vjandrea) |
| [<img src="https://avatars3.githubusercontent.com/u/197404?v=3" width="110px;"/><br /><sub>snipe</sub>](http://www.snipe.net)<br />[💻](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") | [<img src="https://avatars0.githubusercontent.com/u/36335?v=3" width="110px;"/><br /><sub>Brady Wetherington</sub>](http://www.uberbrady.com)<br />[💻](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") | [<img src="https://avatars0.githubusercontent.com/u/3803132?v=3" width="110px;"/><br /><sub>Daniel Meltzer</sub>](https://github.com/dmeltzer)<br />[💻](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") | [<img src="https://avatars0.githubusercontent.com/u/1609106?v=3" width="110px;"/><br /><sub>Michael T</sub>](http://www.tuckertechonline.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mtucker6784 "Code") | [<img src="https://avatars2.githubusercontent.com/u/3274937?v=3" width="110px;"/><br /><sub>madd15</sub>](https://github.com/madd15)<br />[📖](https://github.com/snipe/snipe-it/commits?author=madd15 "Documentation") [💬](#question-madd15 "Answering Questions") | [<img src="https://avatars2.githubusercontent.com/u/894126?v=3" width="110px;"/><br /><sub>Vincent Sposato</sub>](https://github.com/vsposato)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vsposato "Code") | [<img src="https://avatars0.githubusercontent.com/u/1639757?v=3" width="110px;"/><br /><sub>Andrea Bergamasco</sub>](https://github.com/vjandrea)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vjandrea "Code") |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| [<img src="https://avatars0.githubusercontent.com/u/10640152?v=3" width="110px;"/><br /><sub>Karol</sub>](https://github.com/kpawelski)<br />🌍 [💻](https://github.com/snipe/snipe-it/commits?author=kpawelski) | [<img src="https://avatars3.githubusercontent.com/u/600106?v=3" width="110px;"/><br /><sub>morph027</sub>](http://blog.morph027.de/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=morph027) | [<img src="https://avatars3.githubusercontent.com/u/22935755?v=3" width="110px;"/><br /><sub>fvleminckx</sub>](https://github.com/fvleminckx)<br />🚇 | [<img src="https://avatars2.githubusercontent.com/u/15633547?v=3" width="110px;"/><br /><sub>itsupportcmsukorg</sub>](https://github.com/itsupportcmsukorg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=itsupportcmsukorg) [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aitsupportcmsukorg) | [<img src="https://avatars3.githubusercontent.com/u/12373799?v=3" width="110px;"/><br /><sub>Frank</sub>](https://override.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=base-zero) | [<img src="https://avatars0.githubusercontent.com/u/10137?v=3" width="110px;"/><br /><sub>Deleted user</sub>](https://github.com/ghost)<br />🌍 | [<img src="https://avatars1.githubusercontent.com/u/10802313?v=3" width="110px;"/><br /><sub>tiagom62</sub>](https://github.com/tiagom62)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tiagom62) 🚇 |
| [<img src="https://avatars3.githubusercontent.com/u/2389047?v=3" width="110px;"/><br /><sub>Ryan Stafford</sub>](https://github.com/rystaf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rystaf) | [<img src="https://avatars2.githubusercontent.com/u/10345935?v=3" width="110px;"/><br /><sub>Eammon Hanlon</sub>](https://github.com/ehanlon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ehanlon) | [<img src="https://avatars0.githubusercontent.com/u/441924?v=3" width="110px;"/><br /><sub>zjean</sub>](https://github.com/zjean)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zjean) | [<img src="https://avatars0.githubusercontent.com/u/12660103?v=3" width="110px;"/><br /><sub>Matthias Frei</sub>](http://www.frei.media)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FREImedia) | [<img src="https://avatars0.githubusercontent.com/u/3767518?v=3" width="110px;"/><br /><sub>opsydev</sub>](https://github.com/opsydev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=opsydev) | [<img src="https://avatars1.githubusercontent.com/u/82290?v=3" width="110px;"/><br /><sub>Daniel Dreier</sub>](http://www.ddreier.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ddreier) | [<img src="https://avatars0.githubusercontent.com/u/23448?v=3" width="110px;"/><br /><sub>Nikolai Prokoschenko</sub>](http://rassie.org)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rassie) |
| [<img src="https://avatars0.githubusercontent.com/u/13452757?v=3" width="110px;"/><br /><sub>Drew</sub>](https://github.com/YetAnotherCodeMonkey)<br />[💻](https://github.com/snipe/snipe-it/commits?author=YetAnotherCodeMonkey) | [<img src="https://avatars0.githubusercontent.com/u/1342320?v=3" width="110px;"/><br /><sub>Walter</sub>](https://github.com/merid14)<br />[💻](https://github.com/snipe/snipe-it/commits?author=merid14) | [<img src="https://avatars3.githubusercontent.com/u/11254614?v=3" width="110px;"/><br /><sub>Petr Baloun</sub>](https://github.com/balous)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balous) | [<img src="https://avatars0.githubusercontent.com/u/6117660?v=3" width="110px;"/><br /><sub>reidblomquist</sub>](https://github.com/reidblomquist)<br />[📖](https://github.com/snipe/snipe-it/commits?author=reidblomquist) | [<img src="https://avatars0.githubusercontent.com/u/539914?v=3" width="110px;"/><br /><sub>Mathieu Kooiman</sub>](https://github.com/mathieuk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mathieuk) | [<img src="https://avatars3.githubusercontent.com/u/6606421?v=3" width="110px;"/><br /><sub>csayre</sub>](https://github.com/csayre)<br />[📖](https://github.com/snipe/snipe-it/commits?author=csayre) | [<img src="https://avatars1.githubusercontent.com/u/768488?v=3" width="110px;"/><br /><sub>Adam Dunson</sub>](https://github.com/adamdunson)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adamdunson) |
| [<img src="https://avatars0.githubusercontent.com/u/5547470?v=3" width="110px;"/><br /><sub>Hereward</sub>](https://github.com/thehereward)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thehereward) | [<img src="https://avatars0.githubusercontent.com/u/5802977?v=3" width="110px;"/><br /><sub>swoopdk</sub>](https://github.com/swoopdk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=swoopdk) | [<img src="https://avatars1.githubusercontent.com/u/3470403?v=3" width="110px;"/><br /><sub>Abdullah Alansari</sub>](https://linkedin.com/in/ahimta)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Ahimta) | [<img src="https://avatars0.githubusercontent.com/u/796443?v=3" width="110px;"/><br /><sub>Micael Rodrigues</sub>](https://github.com/MicaelRodrigues)<br />[💻](https://github.com/snipe/snipe-it/commits?author=MicaelRodrigues) | [<img src="https://avatars0.githubusercontent.com/u/614564?v=3" width="110px;"/><br /><sub>Patrick Gallagher</sub>](http://macadmincorner.com)<br />[📖](https://github.com/snipe/snipe-it/commits?author=patgmac) | [<img src="https://avatars3.githubusercontent.com/u/7165922?v=3" width="110px;"/><br /><sub>Miliamber</sub>](https://github.com/Miliamber)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Miliamber) | [<img src="https://avatars3.githubusercontent.com/u/861766?v=3" width="110px;"/><br /><sub>hawk554</sub>](https://github.com/hawk554)<br />[💻](https://github.com/snipe/snipe-it/commits?author=hawk554) |
| [<img src="https://avatars1.githubusercontent.com/u/1695622?v=3" width="110px;"/><br /><sub>Justin Kerr</sub>](http://jbirdkerr.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbirdkerr) | [<img src="https://avatars3.githubusercontent.com/u/11426176?v=3" width="110px;"/><br /><sub>Ira W. Snyder</sub>](http://www.irasnyder.com/devel/)<br />[📖](https://github.com/snipe/snipe-it/commits?author=irasnyd) | [<img src="https://avatars2.githubusercontent.com/u/2475759?v=3" width="110px;"/><br /><sub>Aladin Alaily</sub>](https://github.com/aalaily)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aalaily) | [<img src="https://avatars0.githubusercontent.com/u/10247644?v=3" width="110px;"/><br /><sub>Chase Hansen</sub>](https://github.com/kobie-chasehansen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kobie-chasehansen) 💬 [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Akobie-chasehansen) | [<img src="https://avatars2.githubusercontent.com/u/13545400?v=3" width="110px;"/><br /><sub>IDM Helpdesk</sub>](https://github.com/IDM-Helpdesk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=IDM-Helpdesk) | [<img src="https://avatars2.githubusercontent.com/u/614439?v=3" width="110px;"/><br /><sub>Kai</sub>](http://balticer.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balticer) | [<img src="https://avatars1.githubusercontent.com/u/8762511?v=3" width="110px;"/><br /><sub>Michael Daniels</sub>](http://www.michaeldaniels.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mdaniels5757) |
| [<img src="https://avatars3.githubusercontent.com/u/1532660?v=3" width="110px;"/><br /><sub>Tom Castleman</sub>](http://tomcastleman.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tomcastleman) | [<img src="https://avatars3.githubusercontent.com/u/10723243?v=3" width="110px;"/><br /><sub>Daniel Nemanic</sub>](https://github.com/DanielNemanic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DanielNemanic) | [<img src="https://avatars0.githubusercontent.com/u/150648?v=3" width="110px;"/><br /><sub>SouthWolf</sub>](https://github.com/southwolf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=southwolf) | [<img src="https://avatars2.githubusercontent.com/u/131616?v=3" width="110px;"/><br /><sub>Ivar Nesje</sub>](https://github.com/ivarne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ivarne) | [<img src="https://avatars1.githubusercontent.com/u/62333?v=3" width="110px;"/><br /><sub>Jérémy Benoist</sub>](http://www.j0k3r.net)<br />[📖](https://github.com/snipe/snipe-it/commits?author=j0k3r) | [<img src="https://avatars2.githubusercontent.com/u/724344?v=3" width="110px;"/><br /><sub>Chris Leathley</sub>](https://github.com/cleathley)<br />🚇 | [<img src="https://avatars0.githubusercontent.com/u/972498?v=3" width="110px;"/><br /><sub>splaer</sub>](https://github.com/splaer)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Asplaer) [💻](https://github.com/snipe/snipe-it/commits?author=splaer) |
| [<img src="https://avatars1.githubusercontent.com/u/967362?v=3" width="110px;"/><br /><sub>Joe Ferguson</sub>](http://www.joeferguson.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=svpernova09) | [<img src="https://avatars3.githubusercontent.com/u/6108682?v=3" width="110px;"/><br /><sub>diwanicki</sub>](https://github.com/diwanicki)<br />[💻](https://github.com/snipe/snipe-it/commits?author=diwanicki) [📖](https://github.com/snipe/snipe-it/commits?author=diwanicki) | [<img src="https://avatars3.githubusercontent.com/u/2527115?v=3" width="110px;"/><br /><sub>Lee Thoong Ching</sub>](https://github.com/pakkua80)<br />[📖](https://github.com/snipe/snipe-it/commits?author=pakkua80) | [<img src="https://avatars1.githubusercontent.com/u/461491?v=3" width="110px;"/><br /><sub>Marek Šuppa</sub>](http://shu.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mrshu) | [<img src="https://avatars1.githubusercontent.com/u/8693762?v=3" width="110px;"/><br /><sub>Juan J. Martinez</sub>](https://github.com/mizar1616)<br />🌍 | [<img src="https://avatars1.githubusercontent.com/u/1458388?v=3" width="110px;"/><br /><sub>R Ryan Dial</sub>](https://github.com/rrdial)<br />🌍 | [<img src="https://avatars2.githubusercontent.com/u/2871745?v=3" width="110px;"/><br /><sub>Andrej Manduch</sub>](https://github.com/burlito)<br />[📖](https://github.com/snipe/snipe-it/commits?author=burlito) |
| [<img src="https://avatars0.githubusercontent.com/u/8341172?v=3" width="110px;"/><br /><sub>Jay Richards</sub>](http://www.cordeos.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=technogenus) | [<img src="https://avatars2.githubusercontent.com/u/7295127?v=3" width="110px;"/><br /><sub>Alexander Innes</sub>](https://necurity.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leostat) | [<img src="https://avatars2.githubusercontent.com/u/334485?v=3" width="110px;"/><br /><sub>Danny Garcia</sub>](https://buzzedword.codes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=buzzedword) | [<img src="https://avatars2.githubusercontent.com/u/366855?v=3" width="110px;"/><br /><sub>archpoint</sub>](https://github.com/archpoint)<br />[💻](https://github.com/snipe/snipe-it/commits?author=archpoint) | [<img src="https://avatars1.githubusercontent.com/u/67991?v=3" width="110px;"/><br /><sub>Jake McGraw</sub>](http://www.jakemcgraw.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jakemcgraw) | [<img src="https://avatars1.githubusercontent.com/u/1714374?v=3" width="110px;"/><br /><sub>FleischKarussel</sub>](https://github.com/FleischKarussel)<br />[📖](https://github.com/snipe/snipe-it/commits?author=FleischKarussel) | [<img src="https://avatars3.githubusercontent.com/u/319644?v=3" width="110px;"/><br /><sub>Dylan Yi</sub>](https://github.com/feeva)<br />[💻](https://github.com/snipe/snipe-it/commits?author=feeva) |
| [<img src="https://avatars2.githubusercontent.com/u/857740?v=3" width="110px;"/><br /><sub>Gil Rutkowski</sub>](http://FlashingCursor.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=flashingcursor) | [<img src="https://avatars3.githubusercontent.com/u/129360?v=3" width="110px;"/><br /><sub>Desmond Morris</sub>](http://www.desmondmorris.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=desmondmorris) | [<img src="https://avatars2.githubusercontent.com/u/52936?v=3" width="110px;"/><br /><sub>Nick Peelman</sub>](http://peelman.us)<br />[💻](https://github.com/snipe/snipe-it/commits?author=peelman) | [<img src="https://avatars0.githubusercontent.com/u/53161?v=3" width="110px;"/><br /><sub>Abraham Vegh</sub>](https://abrahamvegh.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=abrahamvegh) | [<img src="https://avatars0.githubusercontent.com/u/2818680?v=3" width="110px;"/><br /><sub>Mohamed Rashid</sub>](https://github.com/rashivkp)<br />[📖](https://github.com/snipe/snipe-it/commits?author=rashivkp) | [<img src="https://avatars3.githubusercontent.com/u/1509456?v=3" width="110px;"/><br /><sub>Kasey</sub>](http://hinchk.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=HinchK) |
| [<img src="https://avatars0.githubusercontent.com/u/10640152?v=3" width="110px;"/><br /><sub>Karol</sub>](https://github.com/kpawelski)<br />[🌍](#translation-kpawelski "Translation") [💻](https://github.com/snipe/snipe-it/commits?author=kpawelski "Code") | [<img src="https://avatars3.githubusercontent.com/u/600106?v=3" width="110px;"/><br /><sub>morph027</sub>](http://blog.morph027.de/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=morph027 "Code") | [<img src="https://avatars3.githubusercontent.com/u/22935755?v=3" width="110px;"/><br /><sub>fvleminckx</sub>](https://github.com/fvleminckx)<br />[🚇](#infra-fvleminckx "Infrastructure (Hosting, Build-Tools, etc)") | [<img src="https://avatars2.githubusercontent.com/u/15633547?v=3" width="110px;"/><br /><sub>itsupportcmsukorg</sub>](https://github.com/itsupportcmsukorg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=itsupportcmsukorg "Code") [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aitsupportcmsukorg "Bug reports") | [<img src="https://avatars3.githubusercontent.com/u/12373799?v=3" width="110px;"/><br /><sub>Frank</sub>](https://override.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=base-zero "Code") | [<img src="https://avatars0.githubusercontent.com/u/10137?v=3" width="110px;"/><br /><sub>Deleted user</sub>](https://github.com/ghost)<br />[🌍](#translation-ghost "Translation") | [<img src="https://avatars1.githubusercontent.com/u/10802313?v=3" width="110px;"/><br /><sub>tiagom62</sub>](https://github.com/tiagom62)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tiagom62 "Code") [🚇](#infra-tiagom62 "Infrastructure (Hosting, Build-Tools, etc)") |
| [<img src="https://avatars3.githubusercontent.com/u/2389047?v=3" width="110px;"/><br /><sub>Ryan Stafford</sub>](https://github.com/rystaf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rystaf "Code") | [<img src="https://avatars2.githubusercontent.com/u/10345935?v=3" width="110px;"/><br /><sub>Eammon Hanlon</sub>](https://github.com/ehanlon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ehanlon "Code") | [<img src="https://avatars0.githubusercontent.com/u/441924?v=3" width="110px;"/><br /><sub>zjean</sub>](https://github.com/zjean)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zjean "Code") | [<img src="https://avatars0.githubusercontent.com/u/12660103?v=3" width="110px;"/><br /><sub>Matthias Frei</sub>](http://www.frei.media)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FREImedia "Code") | [<img src="https://avatars0.githubusercontent.com/u/3767518?v=3" width="110px;"/><br /><sub>opsydev</sub>](https://github.com/opsydev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=opsydev "Code") | [<img src="https://avatars1.githubusercontent.com/u/82290?v=3" width="110px;"/><br /><sub>Daniel Dreier</sub>](http://www.ddreier.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ddreier "Code") | [<img src="https://avatars0.githubusercontent.com/u/23448?v=3" width="110px;"/><br /><sub>Nikolai Prokoschenko</sub>](http://rassie.org)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rassie "Code") |
| [<img src="https://avatars0.githubusercontent.com/u/13452757?v=3" width="110px;"/><br /><sub>Drew</sub>](https://github.com/YetAnotherCodeMonkey)<br />[💻](https://github.com/snipe/snipe-it/commits?author=YetAnotherCodeMonkey "Code") | [<img src="https://avatars0.githubusercontent.com/u/1342320?v=3" width="110px;"/><br /><sub>Walter</sub>](https://github.com/merid14)<br />[💻](https://github.com/snipe/snipe-it/commits?author=merid14 "Code") | [<img src="https://avatars3.githubusercontent.com/u/11254614?v=3" width="110px;"/><br /><sub>Petr Baloun</sub>](https://github.com/balous)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balous "Code") | [<img src="https://avatars0.githubusercontent.com/u/6117660?v=3" width="110px;"/><br /><sub>reidblomquist</sub>](https://github.com/reidblomquist)<br />[📖](https://github.com/snipe/snipe-it/commits?author=reidblomquist "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/539914?v=3" width="110px;"/><br /><sub>Mathieu Kooiman</sub>](https://github.com/mathieuk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mathieuk "Code") | [<img src="https://avatars3.githubusercontent.com/u/6606421?v=3" width="110px;"/><br /><sub>csayre</sub>](https://github.com/csayre)<br />[📖](https://github.com/snipe/snipe-it/commits?author=csayre "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/768488?v=3" width="110px;"/><br /><sub>Adam Dunson</sub>](https://github.com/adamdunson)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adamdunson "Code") |
| [<img src="https://avatars0.githubusercontent.com/u/5547470?v=3" width="110px;"/><br /><sub>Hereward</sub>](https://github.com/thehereward)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thehereward "Code") | [<img src="https://avatars0.githubusercontent.com/u/5802977?v=3" width="110px;"/><br /><sub>swoopdk</sub>](https://github.com/swoopdk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=swoopdk "Code") | [<img src="https://avatars1.githubusercontent.com/u/3470403?v=3" width="110px;"/><br /><sub>Abdullah Alansari</sub>](https://linkedin.com/in/ahimta)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Ahimta "Code") | [<img src="https://avatars0.githubusercontent.com/u/796443?v=3" width="110px;"/><br /><sub>Micael Rodrigues</sub>](https://github.com/MicaelRodrigues)<br />[💻](https://github.com/snipe/snipe-it/commits?author=MicaelRodrigues "Code") | [<img src="https://avatars0.githubusercontent.com/u/614564?v=3" width="110px;"/><br /><sub>Patrick Gallagher</sub>](http://macadmincorner.com)<br />[📖](https://github.com/snipe/snipe-it/commits?author=patgmac "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/7165922?v=3" width="110px;"/><br /><sub>Miliamber</sub>](https://github.com/Miliamber)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Miliamber "Code") | [<img src="https://avatars3.githubusercontent.com/u/861766?v=3" width="110px;"/><br /><sub>hawk554</sub>](https://github.com/hawk554)<br />[💻](https://github.com/snipe/snipe-it/commits?author=hawk554 "Code") |
| [<img src="https://avatars1.githubusercontent.com/u/1695622?v=3" width="110px;"/><br /><sub>Justin Kerr</sub>](http://jbirdkerr.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbirdkerr "Code") | [<img src="https://avatars3.githubusercontent.com/u/11426176?v=3" width="110px;"/><br /><sub>Ira W. Snyder</sub>](http://www.irasnyder.com/devel/)<br />[📖](https://github.com/snipe/snipe-it/commits?author=irasnyd "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/2475759?v=3" width="110px;"/><br /><sub>Aladin Alaily</sub>](https://github.com/aalaily)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aalaily "Code") | [<img src="https://avatars0.githubusercontent.com/u/10247644?v=3" width="110px;"/><br /><sub>Chase Hansen</sub>](https://github.com/kobie-chasehansen)<br />[💻](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") | [<img src="https://avatars2.githubusercontent.com/u/13545400?v=3" width="110px;"/><br /><sub>IDM Helpdesk</sub>](https://github.com/IDM-Helpdesk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=IDM-Helpdesk "Code") | [<img src="https://avatars2.githubusercontent.com/u/614439?v=3" width="110px;"/><br /><sub>Kai</sub>](http://balticer.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balticer "Code") | [<img src="https://avatars1.githubusercontent.com/u/8762511?v=3" width="110px;"/><br /><sub>Michael Daniels</sub>](http://www.michaeldaniels.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mdaniels5757 "Code") |
| [<img src="https://avatars3.githubusercontent.com/u/1532660?v=3" width="110px;"/><br /><sub>Tom Castleman</sub>](http://tomcastleman.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tomcastleman "Code") | [<img src="https://avatars3.githubusercontent.com/u/10723243?v=3" width="110px;"/><br /><sub>Daniel Nemanic</sub>](https://github.com/DanielNemanic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DanielNemanic "Code") | [<img src="https://avatars0.githubusercontent.com/u/150648?v=3" width="110px;"/><br /><sub>SouthWolf</sub>](https://github.com/southwolf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=southwolf "Code") | [<img src="https://avatars2.githubusercontent.com/u/131616?v=3" width="110px;"/><br /><sub>Ivar Nesje</sub>](https://github.com/ivarne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ivarne "Code") | [<img src="https://avatars1.githubusercontent.com/u/62333?v=3" width="110px;"/><br /><sub>Jérémy Benoist</sub>](http://www.j0k3r.net)<br />[📖](https://github.com/snipe/snipe-it/commits?author=j0k3r "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/724344?v=3" width="110px;"/><br /><sub>Chris Leathley</sub>](https://github.com/cleathley)<br />[🚇](#infra-cleathley "Infrastructure (Hosting, Build-Tools, etc)") | [<img src="https://avatars0.githubusercontent.com/u/972498?v=3" width="110px;"/><br /><sub>splaer</sub>](https://github.com/splaer)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Asplaer "Bug reports") [💻](https://github.com/snipe/snipe-it/commits?author=splaer "Code") |
| [<img src="https://avatars1.githubusercontent.com/u/967362?v=3" width="110px;"/><br /><sub>Joe Ferguson</sub>](http://www.joeferguson.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=svpernova09 "Code") | [<img src="https://avatars3.githubusercontent.com/u/6108682?v=3" width="110px;"/><br /><sub>diwanicki</sub>](https://github.com/diwanicki)<br />[💻](https://github.com/snipe/snipe-it/commits?author=diwanicki "Code") [📖](https://github.com/snipe/snipe-it/commits?author=diwanicki "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/2527115?v=3" width="110px;"/><br /><sub>Lee Thoong Ching</sub>](https://github.com/pakkua80)<br />[📖](https://github.com/snipe/snipe-it/commits?author=pakkua80 "Documentation") [💻](https://github.com/snipe/snipe-it/commits?author=pakkua80 "Code") | [<img src="https://avatars1.githubusercontent.com/u/461491?v=3" width="110px;"/><br /><sub>Marek Šuppa</sub>](http://shu.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mrshu "Code") | [<img src="https://avatars1.githubusercontent.com/u/8693762?v=3" width="110px;"/><br /><sub>Juan J. Martinez</sub>](https://github.com/mizar1616)<br />[🌍](#translation-mizar1616 "Translation") | [<img src="https://avatars1.githubusercontent.com/u/1458388?v=3" width="110px;"/><br /><sub>R Ryan Dial</sub>](https://github.com/rrdial)<br />[🌍](#translation-rrdial "Translation") | [<img src="https://avatars2.githubusercontent.com/u/2871745?v=3" width="110px;"/><br /><sub>Andrej Manduch</sub>](https://github.com/burlito)<br />[📖](https://github.com/snipe/snipe-it/commits?author=burlito "Documentation") |
| [<img src="https://avatars0.githubusercontent.com/u/8341172?v=3" width="110px;"/><br /><sub>Jay Richards</sub>](http://www.cordeos.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=technogenus "Code") | [<img src="https://avatars2.githubusercontent.com/u/7295127?v=3" width="110px;"/><br /><sub>Alexander Innes</sub>](https://necurity.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leostat "Code") | [<img src="https://avatars2.githubusercontent.com/u/334485?v=3" width="110px;"/><br /><sub>Danny Garcia</sub>](https://buzzedword.codes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=buzzedword "Code") | [<img src="https://avatars2.githubusercontent.com/u/366855?v=3" width="110px;"/><br /><sub>archpoint</sub>](https://github.com/archpoint)<br />[💻](https://github.com/snipe/snipe-it/commits?author=archpoint "Code") | [<img src="https://avatars1.githubusercontent.com/u/67991?v=3" width="110px;"/><br /><sub>Jake McGraw</sub>](http://www.jakemcgraw.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jakemcgraw "Code") | [<img src="https://avatars1.githubusercontent.com/u/1714374?v=3" width="110px;"/><br /><sub>FleischKarussel</sub>](https://github.com/FleischKarussel)<br />[📖](https://github.com/snipe/snipe-it/commits?author=FleischKarussel "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/319644?v=3" width="110px;"/><br /><sub>Dylan Yi</sub>](https://github.com/feeva)<br />[💻](https://github.com/snipe/snipe-it/commits?author=feeva "Code") |
| [<img src="https://avatars2.githubusercontent.com/u/857740?v=3" width="110px;"/><br /><sub>Gil Rutkowski</sub>](http://FlashingCursor.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=flashingcursor "Code") | [<img src="https://avatars3.githubusercontent.com/u/129360?v=3" width="110px;"/><br /><sub>Desmond Morris</sub>](http://www.desmondmorris.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=desmondmorris "Code") | [<img src="https://avatars2.githubusercontent.com/u/52936?v=3" width="110px;"/><br /><sub>Nick Peelman</sub>](http://peelman.us)<br />[💻](https://github.com/snipe/snipe-it/commits?author=peelman "Code") | [<img src="https://avatars0.githubusercontent.com/u/53161?v=3" width="110px;"/><br /><sub>Abraham Vegh</sub>](https://abrahamvegh.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=abrahamvegh "Code") | [<img src="https://avatars0.githubusercontent.com/u/2818680?v=3" width="110px;"/><br /><sub>Mohamed Rashid</sub>](https://github.com/rashivkp)<br />[📖](https://github.com/snipe/snipe-it/commits?author=rashivkp "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/1509456?v=3" width="110px;"/><br /><sub>Kasey</sub>](http://hinchk.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=HinchK "Code") | [<img src="https://avatars2.githubusercontent.com/u/10522541?v=3" width="110px;"/><br /><sub>Brett</sub>](https://github.com/BrettFagerlund)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=BrettFagerlund "Tests") |
| [<img src="https://avatars2.githubusercontent.com/u/16108587?v=3" width="110px;"/><br /><sub>Jason Spriggs</sub>](http://jasonspriggs.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jasonspriggs "Code") | [<img src="https://avatars2.githubusercontent.com/u/1134568?v=3" width="110px;"/><br /><sub>Nate Felton</sub>](http://n8felton.wordpress.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=n8felton "Code") | [<img src="https://avatars2.githubusercontent.com/u/14036694?v=3" width="110px;"/><br /><sub>Manasses Ferreira</sub>](http://homepages.dcc.ufmg.br/~manassesferreira)<br />[💻](https://github.com/snipe/snipe-it/commits?author=manassesferreira "Code") | [<img src="https://avatars0.githubusercontent.com/u/15913949?v=3" width="110px;"/><br /><sub>Steve</sub>](https://github.com/steveelwood)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=steveelwood "Tests") | [<img src="https://avatars1.githubusercontent.com/u/3361683?v=3" width="110px;"/><br /><sub>matc</sub>](http://twitter.com/matc)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=matc "Tests") | [<img src="https://avatars3.githubusercontent.com/u/7405702?v=3" width="110px;"/><br /><sub>Cole R. Davis</sub>](http://www.davisracingteam.com)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=VanillaNinjaD "Tests") | [<img src="https://avatars2.githubusercontent.com/u/10167681?v=3" width="110px;"/><br /><sub>gibsonjoshua55</sub>](https://github.com/gibsonjoshua55)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gibsonjoshua55 "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
+85
View File
@@ -0,0 +1,85 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class FixDoubleEscape extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:unescape';
/**
* The console command description.
*
* @var string
*/
protected $description = 'This should be run to fix some double-escaping issues from earlier versions of Snipe-IT.';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$tables = [
'\App\Models\Asset' => ['name'],
'\App\Models\License' => ['name'],
'\App\Models\Consumable' => ['name'],
'\App\Models\Accessory' => ['name'],
'\App\Models\Component' => ['name'],
'\App\Models\Company' => ['name'],
'\App\Models\Manufacturer' => ['name'],
'\App\Models\Supplier' => ['name'],
'\App\Models\Statuslabel' => ['name'],
'\App\Models\Depreciation' => ['name'],
'\App\Models\AssetModel' => ['name'],
'\App\Models\Group' => ['name'],
'\App\Models\Department' => ['name'],
'\App\Models\Location' => ['name'],
'\App\Models\User' => ['first_name', 'last_name'],
];
$count = array();
foreach ($tables as $classname => $fields) {
$count[$classname] = array();
$count[$classname]['classname'] = 0;
foreach($fields as $field) {
$count[$classname]['classname']++;
$count[$classname][$field] = 0;
foreach($classname::where("$field",'LIKE','%&%')->get() as $row) {
$this->info('Updating '.$field.' for '.$classname);
$row->{$field} = html_entity_decode($row->{$field});
$row->save();
$count[$classname][$field]++;
}
}
}
$this->info('Update complete');
}
}
+4 -4
View File
@@ -90,11 +90,11 @@ class LdapSync extends Command
LOG::debug('Location ID '.$this->option('location_id').' passed');
LOG::debug('Importing to '.$location->name.' ('.$location->id.')');
} else {
$location = new Location;
}
$location = NULL;
}
if (!isset($location)) {
LOG::debug('That location is invalid, so no location will be assigned by default.');
LOG::debug('That location is invalid or a location was not provided, so no location will be assigned by default.');
}
// Grab subsets based on location-specific DNs, and overwrite location for these users.
@@ -109,7 +109,7 @@ class LdapSync extends Command
// Delete located users from the general group.
foreach ($results as $key => $generic_entry) {
if (in_array($generic_entry[$ldap_result_username][0], $location_users)) {
if (in_array($generic_entry[$ldap_result_username][0], $usernames)) {
unset($results[$key]);
}
}
@@ -1,398 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use League\Csv\Reader;
use App\Models\User;
use App\Models\Supplier;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\Asset;
class LicenseImportCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'snipeit:license-import';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Import Licenses from CSV';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function fire()
{
$filename = $this->argument('filename');
if (!$this->option('testrun')=='true') {
$this->comment('======= Importing Licenses from '.$filename.' =========');
} else {
$this->comment('====== TEST ONLY License Import for '.$filename.' ====');
$this->comment('============== NO DATA WILL BE WRITTEN ==============');
}
if (! ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1');
}
$csv = Reader::createFromPath($this->argument('filename'));
$csv->setNewline("\r\n");
$csv->setOffset(1);
$duplicates = '';
// Loop through the records
$nbInsert = $csv->each(function ($row) use ($duplicates) {
$status_id = 1;
// Let's just map some of these entries to more user friendly words
if (array_key_exists('0', $row)) {
$user_name = trim($row[0]);
} else {
$user_name = '';
}
if (array_key_exists('1', $row)) {
$user_email = trim($row[1]);
} else {
$user_email = '';
}
if (array_key_exists('2', $row)) {
$user_username = trim($row[2]);
} else {
$user_username = '';
}
if (array_key_exists('3', $row)) {
$user_license_name = trim($row[3]);
} else {
$user_license_name = '';
}
if (array_key_exists('4', $row)) {
$user_license_serial = trim($row[4]);
} else {
$user_license_serial = '';
}
if (array_key_exists('5', $row)) {
$user_licensed_to_name = trim($row[5]);
} else {
$user_licensed_to_name = '';
}
if (array_key_exists('6', $row)) {
$user_licensed_to_email = trim($row[6]);
} else {
$user_licensed_to_email = '';
}
if (array_key_exists('7', $row)) {
$user_license_seats = trim($row[7]);
} else {
$user_license_seats = '';
}
if (array_key_exists('8', $row)) {
$user_license_reassignable = trim($row[8]);
if ($user_license_reassignable!='') {
if ((strtolower($user_license_reassignable)=='yes') || (strtolower($user_license_reassignable)=='true') || ($user_license_reassignable=='1')) {
$user_license_reassignable = 1;
}
} else {
$user_license_reassignable = 0;
}
} else {
$user_license_reassignable = 0;
}
if (array_key_exists('9', $row)) {
$user_license_supplier = trim($row[9]);
} else {
$user_license_supplier = '';
}
if (array_key_exists('10', $row)) {
$user_license_maintained = trim($row[10]);
if ($user_license_maintained!='') {
if ((strtolower($user_license_maintained)=='yes') || (strtolower($user_license_maintained)=='true') || ($user_license_maintained=='1')) {
$user_license_maintained = 1;
}
} else {
$user_license_maintained = 0;
}
} else {
$user_license_maintained = '';
}
if (array_key_exists('11', $row)) {
$user_license_notes = trim($row[11]);
} else {
$user_license_notes = '';
}
if (array_key_exists('12', $row)) {
if ($row[12]!='') {
$user_license_purchase_date = date("Y-m-d 00:00:01", strtotime($row[12]));
} else {
$user_license_purchase_date = '';
}
} else {
$user_license_purchase_date = 0;
}
if (array_key_exists('13', $row)) {
$user_licensed_to_asset = trim($row[13]);
} else {
$user_licensed_to_asset = '';
}
// A number was given instead of a name
if (is_numeric($user_name)) {
$this->comment('User '.$user_name.' is not a name - assume this user already exists');
$user_username = '';
// No name was given
} elseif ($user_name=='') {
$this->comment('No user data provided - skipping user creation, just adding license');
$first_name = '';
$last_name = '';
$user_username = '';
} else {
$name = explode(" ", $user_name);
$first_name = $name[0];
$email_last_name = '';
$email_prefix = $first_name;
if (!array_key_exists(1, $name)) {
$last_name='';
$email_last_name = $last_name;
$email_prefix = $first_name;
} else {
$last_name = str_replace($first_name, '', $user_name);
if ($this->option('email_format')=='filastname') {
$email_last_name.=str_replace(' ', '', $last_name);
$email_prefix = $first_name[0].$email_last_name;
} elseif ($this->option('email_format')=='firstname.lastname') {
$email_last_name.=str_replace(' ', '', $last_name);
$email_prefix = $first_name.'.'.$email_last_name;
} elseif ($this->option('email_format')=='firstname') {
$email_last_name.=str_replace(' ', '', $last_name);
$email_prefix = $first_name;
}
}
$user_username = $email_prefix;
// Generate an email based on their name if no email address is given
if ($user_email=='') {
if ($first_name=='Unknown') {
$status_id = 7;
}
$email = strtolower($email_prefix).'@'.$this->option('domain');
$user_email = str_replace("'", '', $email);
}
}
$this->comment('Full Name: '.$user_name);
$this->comment('First Name: '.$first_name);
$this->comment('Last Name: '.$last_name);
$this->comment('Username: '.$user_username);
$this->comment('Email: '.$user_email);
$this->comment('License Name: '.$user_license_name);
$this->comment('Serial No: '.$user_license_serial);
$this->comment('Licensed To Name: '.$user_licensed_to_name);
$this->comment('Licensed To Email: '.$user_licensed_to_email);
$this->comment('Seats: '.$user_license_seats);
$this->comment('Reassignable: '.$user_license_reassignable);
$this->comment('Supplier: '.$user_license_supplier);
$this->comment('Maintained: '.$user_license_maintained);
$this->comment('Notes: '.$user_license_notes);
$this->comment('Purchase Date: '.$user_license_purchase_date);
$this->comment('Asset ID: '.$user_licensed_to_asset);
$this->comment('------------- Action Summary ----------------');
if ($user_username!='') {
if ($user = User::where('username', $user_username)->whereNotNull('username')->first()) {
$this->comment('User '.$user_username.' already exists');
} else {
$user = new \App\Models\User;
$password = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$user->first_name = $first_name;
$user->last_name = $last_name;
$user->username = $user_username;
$user->email = $user_email;
$user->permissions = '{user":1}';
$user->password = bcrypt($password);
$user->activated = 1;
if ($user->save()) {
$this->comment('User '.$first_name.' created');
} else {
$this->error('ERROR CREATING User '.$first_name.' '.$last_name);
$this->error($user->getErrors());
}
$this->comment('User '.$first_name.' created');
}
} else {
$user = new User;
$user->user_id = null;
}
// Check for the supplier match and create it if it doesn't exist
if ($supplier = Supplier::where('name', $user_license_supplier)->first()) {
$this->comment('Supplier '.$user_license_supplier.' already exists');
} else {
$supplier = new Supplier();
$supplier->name = e($user_license_supplier);
$supplier->user_id = 1;
if ($supplier->save()) {
$this->comment('Supplier '.$user_license_supplier.' was created');
} else {
$this->comment('Something went wrong! Supplier '.$user_license_supplier.' was NOT created');
}
}
// Add the license
$license = new License();
$license->name = e($user_license_name);
if ($user_license_purchase_date!='') {
$license->purchase_date = $user_license_purchase_date;
} else {
$license->purchase_date = null;
}
$license->serial = e($user_license_serial);
$license->seats = e($user_license_seats);
$license->supplier_id = $supplier->id;
$license->user_id = 1;
if ($user_license_purchase_date!='') {
$license->purchase_date = $user_license_purchase_date;
} else {
$license->purchase_date = null;
}
$license->license_name = $user_licensed_to_name;
$license->license_email = $user_licensed_to_email;
$license->notes = e($user_license_notes);
if ($license->save()) {
$this->comment('License '.$user_license_name.' with serial number '.$user_license_serial.' was created');
$license_seat_created = 0;
for ($x = 0; $x < $user_license_seats; $x++) {
// Create the license seat entries
$license_seat = new LicenseSeat();
$license_seat->license_id = $license->id;
// Only assign the first seat to the user
if ($x==0) {
$license_seat->assigned_to = $user->id;
} else {
$license_seat->assigned_to = null;
}
if($user_licensed_to_asset) {
$asset = Asset::where('asset_tag', $user_licensed_to_asset)->first();
if($asset) {
$license_seat->asset_id = $asset->id;
}
}
if ($license_seat->save()) {
$license_seat_created++;
}
}
if ($license_seat_created > 0) {
$this->comment($license_seat_created.' seats were created');
} else {
$this->comment('Something went wrong! NO seats for '.$user_license_name.' were created');
}
} else {
$this->comment('Something went wrong! License '.$user_license_name.' was NOT created');
}
$this->comment('=====================================');
return true;
});
}
/**
* Get the console command arguments.
*
* @return array
*/
protected function getArguments()
{
return array(
array('filename', InputArgument::REQUIRED, 'File for the CSV import.'),
);
}
/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return array(
array('domain', null, InputOption::VALUE_REQUIRED, 'Email domain for generated email addresses.', null),
array('email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null),
array('testrun', null, InputOption::VALUE_REQUIRED, 'Test the output without writing to the database or not.', null),
);
}
}
+3 -5
View File
@@ -72,7 +72,6 @@ class ObjectImportCommand extends Command
$classString = "App\\Importer\\{$class}Importer";
$importer = new $classString($filename);
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
->setTestRun($this->option('testrun'))
->setUserId($this->option('user_id'))
->setUpdating($this->option('update'))
->setUsernameFormat($this->option('username_format'));
@@ -80,10 +79,10 @@ class ObjectImportCommand extends Command
$logFile = $this->option('logfile');
\Log::useFiles($logFile);
if ($this->option('testrun')) {
$this->comment('====== TEST ONLY Asset Import for '.$filename.' ====');
$this->comment('====== TEST ONLY Item Import for '.$filename.' ====');
$this->comment('============== NO DATA WILL BE WRITTEN ==============');
} else {
$this->comment('======= Importing Assets from '.$filename.' =========');
$this->comment('======= Importing Items from '.$filename.' =========');
}
$importer->import();
@@ -173,9 +172,8 @@ class ObjectImportCommand extends Command
return array(
array('email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null),
array('username_format', null, InputOption::VALUE_REQUIRED, 'The format of the username that should be generated. Options are firstname.lastname, firstname, filastname, email', null),
array('testrun', null, InputOption::VALUE_NONE, 'If set, will parse and output data without adding to database', null),
array('logfile', null, InputOption::VALUE_REQUIRED, 'The path to log output to. storage/logs/importer.log by default', storage_path('logs/importer.log') ),
array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Or Accessory', 'Asset'),
array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Accessory, License, or User', 'Asset'),
array('web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'),
array('user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1),
array('update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'),
+8 -3
View File
@@ -2,9 +2,6 @@
namespace App\Console\Commands;
use Illuminate\Console\Command;
use DB;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\AssetModel;
@@ -12,14 +9,18 @@ use App\Models\Category;
use App\Models\Company;
use App\Models\Component;
use App\Models\Consumable;
use App\Models\Department;
use App\Models\Depreciation;
use App\Models\Group;
use App\Models\Import;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use DB;
use Illuminate\Console\Command;
class PaveIt extends Command
{
@@ -63,6 +64,7 @@ class PaveIt extends Command
Company::getQuery()->delete();
Component::getQuery()->delete();
Consumable::getQuery()->delete();
Department::getQuery()->delete();
Depreciation::getQuery()->delete();
License::getQuery()->delete();
LicenseSeat::getQuery()->delete();
@@ -72,6 +74,7 @@ class PaveIt extends Command
Statuslabel::getQuery()->delete();
Supplier::getQuery()->delete();
Group::getQuery()->delete();
Import::getQuery()->delete();
DB::statement('delete from accessories_users');
DB::statement('delete from asset_logs');
@@ -107,6 +110,7 @@ class PaveIt extends Command
\DB::statement('drop table IF EXISTS custom_fields');
\DB::statement('drop table IF EXISTS custom_fieldsets');
\DB::statement('drop table IF EXISTS depreciations');
\DB::statement('drop table IF EXISTS departments');
\DB::statement('drop table IF EXISTS groups');
\DB::statement('drop table IF EXISTS history');
\DB::statement('drop table IF EXISTS components');
@@ -131,6 +135,7 @@ class PaveIt extends Command
\DB::statement('drop table IF EXISTS throttle');
\DB::statement('drop table IF EXISTS users_groups');
\DB::statement('drop table IF EXISTS users');
\DB::statement('drop table IF EXISTS imports');
}
}
}
+1 -1
View File
@@ -17,13 +17,13 @@ class Kernel extends ConsoleKernel
Commands\CreateAdmin::class,
Commands\SendExpirationAlerts::class,
Commands\SendInventoryAlerts::class,
Commands\LicenseImportCommand::class,
Commands\ObjectImportCommand::class,
Commands\Versioning::class,
Commands\SystemBackup::class,
Commands\DisableLDAP::class,
Commands\Purge::class,
Commands\LdapSync::class,
Commands\FixDoubleEscape::class
];
/**
+1 -1
View File
@@ -91,7 +91,7 @@ class Handler extends ExceptionHandler
if ($this->isHttpException($e) && (isset($statusCode)) && ($statusCode == '404' )) {
return response()->view('layouts/basic', [
'content' => view('errors/404')
]);
],$statusCode);
}
return parent::render($request, $e);
+20
View File
@@ -4,6 +4,7 @@ namespace App\Helpers;
use DB;
use App\Models\Statuslabel;
use App\Models\Location;
use App\Models\Department;
use App\Models\AssetModel;
use App\Models\Company;
use App\Models\User;
@@ -184,6 +185,25 @@ class Helper
return $category_list;
}
/**
* Get the list of categories in an array to make a dropdown menu
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.5]
* @return Array
*/
public static function departmentList()
{
$departments = Department::orderBy('name', 'asc')
->whereNull('deleted_at')
->orderBy('name', 'asc');
return array('' => trans('general.select_department')) + $departments->pluck('name', 'id')->toArray();
}
/**
* Get the list of suppliers in an array to make a dropdown menu
*
+6 -14
View File
@@ -39,7 +39,7 @@ class AccessoriesController extends Controller
public function index(Request $request)
{
$this->authorize('index', Accessory::class);
return View::make('accessories/index');
return view('accessories/index');
}
@@ -53,7 +53,7 @@ class AccessoriesController extends Controller
{
$this->authorize('create', Accessory::class);
// Show the page
return View::make('accessories/edit')
return view('accessories/edit')
->with('item', new Accessory)
->with('category_list', Helper::categoryList('accessory'))
->with('company_list', Helper::companyList())
@@ -90,7 +90,6 @@ class AccessoriesController extends Controller
// Was the accessory created?
if ($accessory->save()) {
$accessory->logCreate();
// Redirect to the new accessory page
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.create.success'));
}
@@ -108,13 +107,12 @@ class AccessoriesController extends Controller
{
// Check if the accessory exists
if (is_null($item = Accessory::find($accessoryId))) {
// Redirect to the blogs management page
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
$this->authorize($item);
return View::make('accessories/edit', compact('item'))
return view('accessories/edit', compact('item'))
->with('category_list', Helper::categoryList('accessory'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList())
@@ -131,9 +129,7 @@ class AccessoriesController extends Controller
*/
public function update(Request $request, $accessoryId = null)
{
// Check if the accessory exists
if (is_null($accessory = Accessory::find($accessoryId))) {
// Redirect to the accessory index page
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
@@ -154,7 +150,6 @@ class AccessoriesController extends Controller
// Was the accessory updated?
if ($accessory->save()) {
// Redirect to the updated accessory page
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
@@ -169,9 +164,7 @@ class AccessoriesController extends Controller
*/
public function destroy(Request $request, $accessoryId)
{
// Check if the blog post exists
if (is_null($accessory = Accessory::find($accessoryId))) {
// Redirect to the blogs management page
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
}
@@ -182,7 +175,6 @@ class AccessoriesController extends Controller
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_users', array('count'=> $accessory->hasUsers())));
}
$accessory->delete();
// Redirect to the locations management page
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.delete.success'));
}
@@ -203,7 +195,7 @@ class AccessoriesController extends Controller
$accessory = Accessory::find($accessoryID);
$this->authorize('view', $accessory);
if (isset($accessory->id)) {
return View::make('accessories/view', compact('accessory'));
return view('accessories/view', compact('accessory'));
}
// Prepare the error message
$error = trans('admin/accessories/message.does_not_exist', compact('id'));
@@ -230,7 +222,7 @@ class AccessoriesController extends Controller
$this->authorize('checkout', $accessory);
// Get the dropdown of users and then pass it to the checkout view
return View::make('accessories/checkout', compact('accessory'))->with('users_list', Helper::usersList());
return view('accessories/checkout', compact('accessory'))->with('users_list', Helper::usersList());
}
@@ -316,7 +308,7 @@ class AccessoriesController extends Controller
$accessory = Accessory::find($accessory_user->accessory_id);
$this->authorize('checkin', $accessory);
return View::make('accessories/checkin', compact('accessory'))->with('backto', $backto);
return view('accessories/checkin', compact('accessory'))->with('backto', $backto);
}
@@ -127,6 +127,7 @@ class AssetModelsController extends Controller
$this->authorize('edit', AssetModel::class);
$assetmodel = AssetModel::findOrFail($id);
$assetmodel->fill($request->all());
$assetmodel->fieldset_id = $request->get("custom_fieldset_id");
if ($assetmodel->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/assetmodels/message.update.success')));
+23 -9
View File
@@ -84,7 +84,7 @@ class AssetsController extends Controller
$assets = Company::scopeCompanyables(Asset::select('assets.*'))->with(
'assetLoc', 'assetstatus', 'defaultLoc', 'assetlog', 'company',
'model.category', 'model.manufacturer', 'model.fieldset', 'assigneduser');
'model.category', 'model.manufacturer', 'model.fieldset', 'assigneduser','supplier');
// If we should search on everything
if (($request->has('search')) && (count($filter) == 0)) {
@@ -96,6 +96,8 @@ class AssetsController extends Controller
}
}
// These are used by the API to query against specific ID numbers
if ($request->has('status_id')) {
$assets->where('status_id', '=', $request->input('status_id'));
}
@@ -112,6 +114,10 @@ class AssetsController extends Controller
$assets->ByLocationId($request->input('location_id'));
}
if ($request->has('supplier_id')) {
$assets->where('assets.supplier_id', '=', $request->input('supplier_id'));
}
if ($request->has('company_id')) {
$assets->where('assets.company_id', '=', $request->input('company_id'));
}
@@ -125,9 +131,9 @@ class AssetsController extends Controller
$offset = request('offset', 0);
$limit = $request->input('limit', 50);
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets.created_at';
$assets->orderBy($sort, $order);
// This is used by the sidenav, mostly
switch ($request->input('status')) {
case 'Deleted':
$assets->withTrashed()->Deleted();
@@ -154,7 +160,10 @@ class AssetsController extends Controller
switch ($sort) {
// This handles all of the pivot sorting (versus the assets.* fields in the allowed_columns array)
$column_sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets.created_at';
switch ($request->input('sort')) {
case 'model':
$assets->OrderModels($order);
break;
@@ -176,15 +185,17 @@ class AssetsController extends Controller
case 'status_label':
$assets->OrderStatus($order);
break;
case 'supplier':
$assets->OrderSupplier($order);
break;
case 'assigned_to':
$assets->OrderAssigned($order);
break;
default:
$assets->orderBy($sort, $order);
$assets->orderBy($column_sort, $order);
break;
}
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
return (new AssetsTransformer)->transformAssets($assets, $total);
@@ -266,7 +277,7 @@ class AssetsController extends Controller
if (isset($target)) {
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')));
}
return response()->json(Helper::formatStandardApiResponse('success', $asset->id, trans('admin/hardware/message.create.success')));
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
}
@@ -331,7 +342,7 @@ class AssetsController extends Controller
}
if ($asset->save()) {
$asset->logCreate();
if ($request->get('assigned_user')) {
$target = User::find(request('assigned_user'));
} elseif ($request->get('assigned_asset')) {
@@ -362,7 +373,10 @@ class AssetsController extends Controller
*/
public function destroy($id)
{
$this->authorize('delete', Asset::class);
if ($asset = Asset::find($id)) {
$this->authorize('delete', $asset);
DB::table('assets')
@@ -2,7 +2,7 @@
namespace App\Http\Controllers\Api;
use App\Http\Transformers\DatatablesTransformer;
use App\Http\Transformers\CompaniesTransformer;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
@@ -23,7 +23,10 @@ class CompaniesController extends Controller
$allowed_columns = ['id','name'];
$companies = Company::withCount('assets','licenses','accessories','consumables','components','users');
$companies = Company::withCount('assets','licenses','accessories','consumables','components','users')
->withCount('users')->withCount('users')->withCount('assets')
->withCount('licenses')->withCount('accessories')
->withCount('consumables')->withCount('components');
if ($request->has('search')) {
$companies->TextSearch($request->input('search'));
@@ -37,7 +40,7 @@ class CompaniesController extends Controller
$total = $companies->count();
$companies = $companies->skip($offset)->take($limit)->get();
return (new DatatablesTransformer)->transformDatatables($companies, $total);
return (new CompaniesTransformer)->transformCompanies($companies, $total);
}
@@ -57,7 +60,7 @@ class CompaniesController extends Controller
$company->fill($request->all());
if ($company->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $company, trans('admin/companies/message.create.success')));
return response()->json(Helper::formatStandardApiResponse('success', (new CompaniesTransformer)->transformCompany($company), trans('admin/companies/message.create.success')));
}
return response()
->json(Helper::formatStandardApiResponse('error', null, $company->getErrors()));
@@ -76,7 +79,8 @@ class CompaniesController extends Controller
{
$this->authorize('view', Company::class);
$company = Company::findOrFail($id);
return $company;
return (new CompaniesTransformer)->transformCompany($company);
}
@@ -97,7 +101,7 @@ class CompaniesController extends Controller
if ($company->save()) {
return response()
->json(Helper::formatStandardApiResponse('success', $company, trans('admin/companies/message.update.success')));
->json(Helper::formatStandardApiResponse('success', (new CompaniesTransformer)->transformCompany($company), trans('admin/companies/message.update.success')));
}
return response()
@@ -0,0 +1,147 @@
<?php
namespace App\Http\Controllers\Api;
use View;
use App\Models\CustomFieldset;
use App\Models\CustomField;
use Input;
use Validator;
use Redirect;
use App\Models\AssetModel;
use Lang;
use Auth;
use Illuminate\Http\Request;
use Log;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Http\Transformers\CustomFieldsTransformer;
use App\Http\Transformers\CustomFieldsetsTransformer;
use App\Http\Requests\AssetRequest;
/**
* This controller handles all actions related to Custom Asset Fieldsets for
* the Snipe-IT Asset Management application.
*
* @todo Improve documentation here.
* @todo Check for raw DB queries and try to convert them to query builder statements
* @version v2.0
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @author [Josh Gibson]
*/
class CustomFieldsetsController extends Controller
{
/**
* Shows the given fieldset and its fields
* @author [A. Gianotto] [<snipe@snipe.net>]
* @author [Josh Gibson]
* @param int $id
* @since [v1.8]
* @return View
*/
public function index()
{
$this->authorize('index', CustomFieldset::class);
$fieldsets = CustomFieldset::withCount(['fields', 'models'])->get();
$total = count($fieldsets);
return (new CustomFieldsetsTransformer)->transformCustomFieldsets($fieldsets, $total);
}
/**
* Shows the given fieldset and its fields
* @author [A. Gianotto] [<snipe@snipe.net>]
* @author [Josh Gibson]
* @param int $id
* @since [v1.8]
* @return View
*/
public function show($id)
{
$this->authorize('show', CustomFieldset::class);
if ($fieldset = CustomFieldset::find($id)) {
return (new CustomFieldsetsTransformer)->transformCustomFieldset($fieldset);
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/custom_fields/message.fieldset.does_not_exist')), 200);
}
/**
* Update the specified resource in storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->authorize('edit', CustomFieldset::class);
$fieldset = CustomFieldset::findOrFail($id);
$fieldset->fill($request->all());
if ($fieldset->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $fieldset, trans('admin/custom_fields/message.fieldset.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $fieldset->getErrors()));
}
/**
* Store a newly created resource in storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->authorize('create', CustomFieldset::class);
$fieldset = new CustomFieldset;
$fieldset->fill($request->all());
if ($fieldset->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $fieldset, trans('admin/custom_fields/message.fieldset.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $fieldset->getErrors()));
}
/**
* Delete a custom fieldset.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return Redirect
*/
public function destroy($id)
{
$this->authorize('delete', CustomFieldset::class);
$fieldset = CustomFieldset::findOrFail($id);
$modelsCount = $fieldset->models->count();
$fieldsCount = $fieldset->fields->count();
if (($modelsCount > 0) || ($fieldsCount > 0) ){
return response()->json(Helper::formatStandardApiResponse('error', null, 'Fieldset is in use.'));
}
if ($fieldset->delete()) {
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/custom_fields/message.fieldset.delete.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, 'Unspecified error'));
}
}
@@ -0,0 +1,115 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Department;
use App\Http\Transformers\DepartmentsTransformer;
use App\Helpers\Helper;
use Auth;
class DepartmentsController extends Controller
{
/**
* Display a listing of the resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$this->authorize('view', Department::class);
$allowed_columns = ['id','name'];
$departments = Department::select([
'id',
'name',
'location_id',
'company_id',
'manager_id',
'created_at',
'updated_at'
])->with('users')->with('location')->with('manager')->with('company')->withCount('users');
if ($request->has('search')) {
$departments = $departments->TextSearch($request->input('search'));
}
$offset = $request->input('offset', 0);
$limit = $request->input('limit', 50);
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
$departments->orderBy($sort, $order);
$total = $departments->count();
$departments = $departments->skip($offset)->take($limit)->get();
return (new DepartmentsTransformer)->transformDepartments($departments, $total);
}
/**
* Store a newly created resource in storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->authorize('create', Department::class);
$department = new Department;
$department->fill($request->all());
$department->user_id = Auth::user()->id;
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
if ($department->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $department, trans('admin/departments/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $department->getErrors()));
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$this->authorize('view', Department::class);
$department = Department::findOrFail($id);
return (new DepartmentsTransformer)->transformDepartment($department);
}
/**
* Validates and deletes selected location.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $locationId
* @since [v1.0]
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($id)
{
if (is_null($department = Department::find($id))) {
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.not_found'));
}
if ($department->users->count() > 0) {
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.assoc_users'));
}
$department->delete();
return redirect()->to(route('departments.index'))->with('success', trans('admin/departments/message.delete.success'));
}
}
@@ -22,7 +22,7 @@ class GroupsController extends Controller
$this->authorize('view', Group::class);
$allowed_columns = ['id','name','created_at'];
$groups = Group::select('id','name','permissions')->withCount('users');
$groups = Group::select('id','name','permissions','created_at','updated_at')->withCount('users');
if ($request->has('search')) {
$groups = $groups->TextSearch($request->input('search'));
+15 -8
View File
@@ -11,6 +11,7 @@ use App\Models\Import;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Session;
use League\Csv\Reader;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
class ImportController extends Controller
@@ -29,7 +30,7 @@ class ImportController extends Controller
}
/**
* Store a newly created resource in storage.
* Process and store a CSV upload file.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
@@ -45,7 +46,6 @@ class ImportController extends Controller
$results = [];
$import = new Import;
foreach ($files as $file) {
if (!in_array($file->getMimeType(), array(
'application/vnd.ms-excel',
'text/csv',
@@ -53,11 +53,11 @@ class ImportController extends Controller
'text/comma-separated-values',
'text/tsv'))) {
$results['error']='File type must be CSV';
return $results;
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 500);
}
$date = date('Y-m-d-his');
$fixed_filename = str_replace(' ', '-', $file->getClientOriginalName());
$fixed_filename = str_slug($file->getClientOriginalName());
try {
$file->move($path, $date.'-'.$fixed_filename);
} catch (FileException $exception) {
@@ -66,17 +66,21 @@ class ImportController extends Controller
$results['error'].= ' ' . $exception->getMessage();
}
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 500);
}
$file_name = date('Y-m-d-his').'-'.$fixed_filename;
$import->file_path = $file_name;
$import->filesize = filesize($path.'/'.$file_name);
//TODO: is there a lighter way to do this?
$reader = Reader::createFromPath("{$path}/{$file_name}");
$import->header_row = $reader->fetchOne(0);
// Grab the first row to display via ajax as the user picks fields
$import->first_row = $reader->fetchOne(1);
$import->save();
$results[] = $import;
}
$results = (new ImportsTransformer)->transformImports($results);
return [
'files' => $results
'files' => $results,
];
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.feature_disabled')), 500);
@@ -91,7 +95,7 @@ class ImportController extends Controller
{
$this->authorize('create', Asset::class);
$errors = $request->import(Import::find($import_id));
$redirectTo = "hardware";
$redirectTo = "hardware.index";
switch ($request->get('import-type')) {
case "asset":
$redirectTo = "hardware.index";
@@ -108,6 +112,9 @@ class ImportController extends Controller
case "license":
$redirectTo = "licenses.index";
break;
case "user":
$redirectTo = "users.index";
break;
}
if ($errors) { //Failure
@@ -132,7 +139,7 @@ class ImportController extends Controller
try {
unlink(config('app.private_uploads').'/imports/'.$import->file_path);
$import->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('message.import.file_delete_success')));
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/hardware/message.import.file_delete_success')));
} catch (\Exception $e) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.import.file_delete_error')), 500);
}
@@ -117,7 +117,13 @@ class LicensesController extends Controller
*/
public function show($id)
{
//
$license = License::find($id);
if (isset($license->id)) {
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
$this->authorize('view', $license);
return (new LicensesTransformer)->transformLicense($license);
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
}
@@ -21,7 +21,7 @@ class LocationsController extends Controller
{
$this->authorize('view', Location::class);
$allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at',
'updated_at'];
'updated_at','parent_id'];
$locations = Location::select([
'locations.id',
@@ -70,7 +70,7 @@ class LocationsController extends Controller
$location->fill($request->all());
if ($location->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $location, trans('admin/locations/message.create.success')));
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
@@ -108,7 +108,7 @@ class LocationsController extends Controller
$location->fill($request->all());
if ($location->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $location, trans('admin/locations/message.update.success')));
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
@@ -77,7 +77,7 @@ class ManufacturersController extends Controller
{
$this->authorize('view', Manufacturer::class);
$manufacturer = Manufacturer::findOrFail($id);
return $manufacturer;
return (new ManufacturersTransformer)->transformManufacturer($manufacturer);
}
@@ -0,0 +1,56 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Actionlog;
use App\Http\Transformers\ActionlogsTransformer;
class ReportsController extends Controller
{
/**
* Returns Activity Report JSON.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function index(Request $request)
{
$actionlogs = Actionlog::with('item', 'user', 'target');
if ($request->has('search')) {
$actionlogs = $actionlogs->TextSearch(e($request->input('search')));
}
if (($request->has('target_type')) && ($request->has('target_id'))) {
$actionlogs = $actionlogs->where('target_id','=',$request->input('target_id'))
->where('target_type','=',"App\\Models\\".ucwords($request->input('target_type')));
}
if (($request->has('item_type')) && ($request->has('item_id'))) {
$actionlogs = $actionlogs->where('item_id','=',$request->input('item_id'))
->where('item_type','=',"App\\Models\\".ucwords($request->input('item_type')));
}
$allowed_columns = [
'id',
'created_at'
];
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$offset = request('offset', 0);
$limit = request('limit', 50);
$total = $actionlogs->count();
$actionlogs = $actionlogs->orderBy($sort, $order);
$actionlogs = $actionlogs->skip($offset)->take($limit)->get();
return (new ActionlogsTransformer)->transformActionlogs($actionlogs, $total);
}
}
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Ldap;
class SettingsController extends Controller
{
@@ -73,4 +74,28 @@ class SettingsController extends Controller
{
//
}
public function getLdapTest()
{
\Log::debug('Preparing to test LDAP connection');
try {
$connection = Ldap::connectToLdap();
try {
\Log::debug('attempting to bind to LDAP for LDAP test');
Ldap::bindAdminToLdap($connection);
return response()->json(['message' => 'It worked!'], 200);
} catch (\Exception $e) {
\Log::debug('Bind failed');
return response()->json(['message' => $e->getMessage()], 400);
//return response()->json(['message' => $e->getMessage()], 500);
}
} catch (\Exception $e) {
\Log::debug('Connection failed');
return response()->json(['message' => $e->getMessage()], 600);
}
}
}
@@ -6,7 +6,7 @@ use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Supplier;
use App\Http\Transformers\DatatablesTransformer;
use App\Http\Transformers\SuppliersTransformer;
class SuppliersController extends Controller
{
@@ -23,7 +23,7 @@ class SuppliersController extends Controller
$allowed_columns = ['id','name','address','phone','contact','fax','email'];
$suppliers = Supplier::select(
array('id','name','address','address2','city','state','country','fax', 'phone','email','contact')
array('id','name','address','address2','city','state','country','fax', 'phone','email','contact','created_at','updated_at','deleted_at')
)->withCount('assets')->withCount('licenses')->whereNull('deleted_at');
@@ -39,8 +39,7 @@ class SuppliersController extends Controller
$total = $suppliers->count();
$suppliers = $suppliers->skip($offset)->take($limit)->get();
return (new DatatablesTransformer)->transformDatatables($suppliers, $total);
return $suppliers;
return (new SuppliersTransformer)->transformSuppliers($suppliers, $total);
}
@@ -77,7 +76,7 @@ class SuppliersController extends Controller
{
$this->authorize('view', Supplier::class);
$supplier = Supplier::findOrFail($id);
return $supplier;
return (new SuppliersTransformer)->transformSupplier($supplier);
}
+53 -7
View File
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
use App\Http\Transformers\UsersTransformer;
use App\Models\Company;
use App\Models\User;
use App\Helpers\Helper;
class UsersController extends Controller
{
@@ -38,8 +39,9 @@ class UsersController extends Controller
'users.company_id',
'users.last_login',
'users.deleted_at',
'users.department_id',
'users.activated'
])->with('manager', 'groups', 'userloc', 'company', 'throttle','assets','licenses','accessories','consumables')
])->with('manager', 'groups', 'userloc', 'company', 'department','throttle','assets','licenses','accessories','consumables')
->withCount('assets','licenses','accessories','consumables');
$users = Company::scopeCompanyables($users);
@@ -49,7 +51,15 @@ class UsersController extends Controller
}
if ($request->has('company_id')) {
$users = $users->where('company_id','=',$request->input('company_id'));
$users = $users->where('company_id', '=', $request->input('company_id'));
}
if ($request->has('location_id')) {
$users = $users->where('location_id', '=', $request->input('location_id'));
}
if ($request->has('department_id')) {
$users = $users->where('department_id','=',$request->input('department_id'));
}
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
@@ -63,6 +73,9 @@ class UsersController extends Controller
case 'location':
$users = $users->OrderLocation($order);
break;
case 'department':
$users = $users->OrderDepartment($order);
break;
default:
$allowed_columns =
[
@@ -75,9 +88,9 @@ class UsersController extends Controller
$users = $users->orderBy($sort, $order);
break;
}
$userCount = $users->count();
$total = $users->count();
$users = $users->skip($offset)->take($limit)->get();
return (new UsersTransformer)->transformUsers($users, $userCount);
return (new UsersTransformer)->transformUsers($users, $total);
}
@@ -91,7 +104,15 @@ class UsersController extends Controller
*/
public function store(Request $request)
{
//
$this->authorize('view', User::class);
$user = new User;
$user->fill($request->all());
$user->password = bcrypt($request->input('password'));
if ($user->save()) {
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
}
/**
@@ -120,7 +141,20 @@ class UsersController extends Controller
*/
public function update(Request $request, $id)
{
//
$this->authorize('edit', User::class);
$user = User::findOrFail($id);
$user->fill($request->all());
if ($request->has('password')) {
$user->password = bcrypt($request->input('password'));
}
if ($user->save()) {
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.update')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
}
/**
@@ -133,6 +167,18 @@ class UsersController extends Controller
*/
public function destroy($id)
{
//
$this->authorize('delete', User::class);
$user = User::findOrFail($id);
$this->authorize('delete', $user);
if ($user->assets()->count() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
}
if ($user->delete()) {
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
}
}
@@ -59,7 +59,7 @@ class AssetMaintenancesController extends Controller
*/
public function index()
{
return View::make('asset_maintenances/index');
return view('asset_maintenances/index');
}
@@ -160,7 +160,7 @@ class AssetMaintenancesController extends Controller
] + AssetMaintenance::getImprovementOptions();
// Mark the selected asset, if it came in
// Render the view
return View::make('asset_maintenances/edit')
return view('asset_maintenances/edit')
->with('asset_list', Helper::detailedAssetList())
->with('selectedAsset', request('asset_id'))
->with('supplier_list', Helper::suppliersList())
@@ -259,7 +259,7 @@ class AssetMaintenancesController extends Controller
// Get Supplier List
// Render the view
return View::make('asset_maintenances/edit')
return view('asset_maintenances/edit')
->with('asset_list', Helper::detailedAssetList())
->with('selectedAsset', null)
->with('supplier_list', Helper::suppliersList())
@@ -384,6 +384,6 @@ class AssetMaintenancesController extends Controller
return static::getInsufficientPermissionsRedirect();
}
return View::make('asset_maintenances/view')->with('assetMaintenance', $assetMaintenance);
return view('asset_maintenances/view')->with('assetMaintenance', $assetMaintenance);
}
}
+73 -4
View File
@@ -40,7 +40,7 @@ class AssetModelsController extends Controller
*/
public function index()
{
return View::make('models/index');
return view('models/index');
}
/**
@@ -53,7 +53,7 @@ class AssetModelsController extends Controller
public function create()
{
// Show the page
return View::make('models/edit')
return view('models/edit')
->with('category_list', Helper::categoryList('asset'))
->with('depreciation_list', Helper::depreciationList())
->with('manufacturer_list', Helper::manufacturerList())
@@ -297,7 +297,7 @@ class AssetModelsController extends Controller
$model = AssetModel::withTrashed()->find($modelId);
if (isset($model->id)) {
return View::make('models/view', compact('model'));
return view('models/view', compact('model'));
}
// Prepare the error message
$error = trans('admin/models/message.does_not_exist', compact('id'));
@@ -347,7 +347,7 @@ class AssetModelsController extends Controller
public function getCustomFields($modelId)
{
$model = AssetModel::find($modelId);
return View::make("models.custom_fields_form")->with("model", $model);
return view("models.custom_fields_form")->with("model", $model);
}
@@ -394,4 +394,73 @@ class AssetModelsController extends Controller
return $data;
}
/**
* Returns a view that allows the user to bulk edit model attrbutes
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.7]
* @return \Illuminate\Contracts\View\View
*/
public function postBulkEdit(Request $request)
{
$models_raw_array = Input::get('ids');
$models = AssetModel::whereIn('id', $models_raw_array)->get();
$nochange = ['NC' => 'No Change'];
$fieldset_list = $nochange + Helper::customFieldsetList();
$depreciation_list = $nochange + Helper::depreciationList();
$category_list = $nochange + Helper::categoryList('asset');
$manufacturer_list = $nochange + Helper::manufacturerList();
return view('models/bulk-edit', compact('models'))
->with('manufacturer_list', $manufacturer_list)
->with('category_list', $category_list)
->with('fieldset_list', $fieldset_list)
->with('depreciation_list', $depreciation_list);
}
/**
* Returns a view that allows the user to bulk edit model attrbutes
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.7]
* @return \Illuminate\Contracts\View\View
*/
public function postBulkEditSave(Request $request)
{
$models_raw_array = Input::get('ids');
$update_array = array();
if (($request->has('manufacturer_id') && ($request->input('manufacturer_id')!='NC'))) {
$update_array['manufacturer_id'] = $request->input('manufacturer_id');
}
if (($request->has('category_id') && ($request->input('category_id')!='NC'))) {
$update_array['category_id'] = $request->input('category_id');
}
if ($request->input('fieldset_id')!='NC') {
$update_array['fieldset_id'] = $request->input('fieldset_id');
}
if ($request->input('depreciation_id')!='NC') {
$update_array['depreciation_id'] = $request->input('depreciation_id');
}
if (count($update_array) > 0) {
AssetModel::whereIn('id', $models_raw_array)->update($update_array);
return redirect()->route('models.index')
->with('success', trans('admin/models/message.bulkedit.success'));
}
return redirect()->route('models.index')
->with('warning', trans('admin/models/message.bulkedit.error'));
}
}
+52 -105
View File
@@ -12,6 +12,7 @@ use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Company;
use App\Models\CustomField;
use App\Models\Import;
use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
@@ -74,7 +75,7 @@ class AssetsController extends Controller
} else {
$company = null;
}
return View::make('hardware/index')->with('company',$company);
return view('hardware/index')->with('company',$company);
}
/**
@@ -209,9 +210,21 @@ class AssetsController extends Controller
// FIXME: No idea why this is returning a Builder error on db_column_name.
// Need to investigate and fix. Using static method for now.
$model = AssetModel::find($request->get('model_id'));
if ($model->fieldset) {
foreach ($model->fieldset->fields as $field) {
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
if ($field->field_encrypted=='1') {
if (Gate::allows('admin')) {
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
}
} else {
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
}
}
}
@@ -254,11 +267,11 @@ class AssetsController extends Controller
//Handles company checks and permissions.
$this->authorize($item);
return View::make('hardware/edit', compact('item'))
return view('hardware/edit', compact('item'))
->with('model_list', Helper::modelList())
->with('supplier_list', Helper::suppliersList())
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList())
->with('locations_list', Helper::locationsList())
->with('statuslabel_list', Helper::statusLabelList())
->with('assigned_to', Helper::usersList())
->with('manufacturer', Helper::manufacturerList())
@@ -358,7 +371,7 @@ class AssetsController extends Controller
}
} else {
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
}
}
}
@@ -423,7 +436,7 @@ class AssetsController extends Controller
$this->authorize('checkout', $asset);
// Get the dropdown of users and then pass it to the checkout view
return View::make('hardware/checkout', compact('asset'))
return view('hardware/checkout', compact('asset'))
->with('users_list', Helper::usersList())
->with('assets_list', Helper::assetsList())
->with('locations_list', Helper::locationsList());
@@ -460,19 +473,19 @@ class AssetsController extends Controller
$admin = Auth::user();
if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) {
$checkout_at = e(Input::get('checkout_at'));
$checkout_at = Input::get('checkout_at');
} else {
$checkout_at = date("Y-m-d H:i:s");
}
if (Input::has('expected_checkin')) {
$expected_checkin = e(Input::get('expected_checkin'));
$expected_checkin = Input::get('expected_checkin');
} else {
$expected_checkin = '';
}
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), e(Input::get('name')))) {
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), Input::get('name'))) {
// Redirect to the new asset page
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.checkout.success'));
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkout.success'));
}
// Redirect to the asset management page with error
@@ -498,7 +511,7 @@ class AssetsController extends Controller
}
$this->authorize('checkin', $asset);
return View::make('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
}
@@ -564,11 +577,11 @@ class AssetsController extends Controller
if ($backto=='user') {
return redirect()->to("admin/users/".$return_to.'/view')->with('success', trans('admin/hardware/message.checkin.success'));
}
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.checkin.success'));
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success'));
}
// Redirect to the asset management page with error
return redirect()->to("hardware")->with('error', trans('admin/hardware/message.checkin.error'));
return redirect()->route("hardware.index")->with('error', trans('admin/hardware/message.checkin.error'));
}
@@ -586,11 +599,9 @@ class AssetsController extends Controller
$settings = Setting::getSettings();
$this->authorize('view', $asset);
if (isset($asset->id)) {
if (isset($asset)) {
if ($asset->userloc) {
$use_currency = $asset->userloc->currency;
} elseif ($asset->assetloc) {
if (!is_null($asset->assetloc)) {
$use_currency = $asset->assetloc->currency;
} else {
@@ -606,10 +617,10 @@ class AssetsController extends Controller
'url' => route('qr_code/hardware', $asset->id)
);
return View::make('hardware/view', compact('asset', 'qr_code', 'settings'))->with('use_currency', $use_currency);
return view('hardware/view', compact('asset', 'qr_code', 'settings'))->with('use_currency', $use_currency);
}
return redirect()->route('hardware')->with('error', trans('admin/hardware/message.does_not_exist', compact('id')));
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist', compact('id')));
}
/**
@@ -675,56 +686,6 @@ class AssetsController extends Controller
}
/**
* Get the Asset import upload page.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return View
*/
public function getImportUpload()
{
$this->authorize('create', Asset::class);
return View::make('hardware/import');
}
/**
* Process the uploaded file
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return Redirect
*/
public function postProcessImportFile(ItemImportRequest $request)
{
$this->authorize('create', Asset::class);
$errors = $request->import();
// We use hardware instead of asset in the url
$redirectTo = "hardware";
switch (request('import-type')) {
case "asset":
$redirectTo = "hardware.index";
break;
case "accessory":
$redirectTo = "accessories.index";
break;
case "consumable":
$redirectTo = "consumables.index";
break;
case "component":
$redirectTo = "components.index";
break;
}
if ($errors) { //Failure
return redirect()->back()->with('import_errors', json_decode(json_encode($errors)))->with('error', trans('admin/hardware/message.import.error'));
}
return redirect()->to(route($redirectTo))->with('success', trans('admin/hardware/message.import.success'));
}
/**
* Returns a view that presents a form to clone an asset.
*
@@ -749,16 +710,18 @@ class AssetsController extends Controller
$asset->serial = '';
$asset->assigned_to = '';
return View::make('hardware/edit')
return view('hardware/edit')
->with('supplier_list', Helper::suppliersList())
->with('model_list', Helper::modelList())
->with('statuslabel_list', Helper::statusLabelList())
->with('statuslabel_types', Helper::statusTypeList())
->with('assigned_to', Helper::usersList())
->with('item', $asset)
->with('location_list', Helper::locationsList())
->with('locations_list', Helper::locationsList())
->with('manufacturer', Helper::manufacturerList())
->with('category', Helper::categoryList('asset'))
->with('users_list', Helper::usersList())
->with('assets_list', Helper::assetsList())
->with('company_list', Helper::companyList());
}
@@ -772,7 +735,7 @@ class AssetsController extends Controller
public function getImportHistory()
{
$this->authorize('checkout', Asset::class);
return View::make('hardware/history');
return view('hardware/history');
}
/**
@@ -918,7 +881,7 @@ class AssetsController extends Controller
}
}
}
return View::make('hardware/history')->with('status', $status);
return view('hardware/history')->with('status', $status);
}
/**
@@ -937,7 +900,7 @@ class AssetsController extends Controller
if (isset($asset->id)) {
// Restore the asset
Asset::withTrashed()->where('id', $assetId)->restore();
return redirect()->route('hardware')->with('success', trans('admin/hardware/message.restore.success'));
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.restore.success'));
}
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
}
@@ -956,7 +919,7 @@ class AssetsController extends Controller
{
if (!$asset = Asset::find($assetId)) {
return redirect()->route('hardware')->with('error', trans('admin/hardware/message.does_not_exist'));
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
}
$this->authorize('update', $asset);
@@ -1013,7 +976,7 @@ class AssetsController extends Controller
$error = trans('admin/hardware/message.does_not_exist', compact('id'));
// Redirect to the hardware management page
return redirect()->route('hardware')->with('error', $error);
return redirect()->route('hardware.index')->with('error', $error);
}
/**
@@ -1046,7 +1009,7 @@ class AssetsController extends Controller
$error = trans('admin/hardware/message.does_not_exist', compact('id'));
// Redirect to the hardware management page
return redirect()->route('hardware')->with('error', $error);
return redirect()->route('hardware.index')->with('error', $error);
}
/**
@@ -1078,7 +1041,7 @@ class AssetsController extends Controller
if ($request->input('bulk_actions')=='labels') {
$count = 0;
return View::make('hardware/labels')
return view('hardware/labels')
->with('assets', Asset::find($asset_ids))
->with('settings', Setting::getSettings())
->with('count', $count)
@@ -1091,11 +1054,11 @@ class AssetsController extends Controller
$assets->each(function($asset) {
$this->authorize('delete',$asset);
});
return View::make('hardware/bulk-delete')->with('assets', $assets);
return view('hardware/bulk-delete')->with('assets', $assets);
// Bulk edit
} elseif ($request->input('bulk_actions')=='edit') {
return View::make('hardware/bulk')
return view('hardware/bulk')
->with('assets', request('ids'))
->with('supplier_list', Helper::suppliersList())
->with('statuslabel_list', Helper::statusLabelList())
@@ -1172,20 +1135,10 @@ class AssetsController extends Controller
$update_array['requestable'] = e(Input::get('requestable'));
}
if (DB::table('assets')
DB::table('assets')
->where('id', $key)
->update($update_array)) {
$logAction = new Actionlog();
$logAction->item_type = Asset::class;
$logAction->item_id = $key;
$logAction->created_at = date("Y-m-d H:i:s");
->update($update_array);
if (Input::has('rtd_location_id')) {
$logAction->location_id = e(Input::get('rtd_location_id'));
}
$logAction->user_id = Auth::user()->id;
$logAction->logaction('update');
}
} // endforeach
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.update.success'));
// no values given, nothing to update
@@ -1206,23 +1159,17 @@ class AssetsController extends Controller
public function postBulkDelete()
{
$this->authorize('delete', Asset::class);
if (Input::has('bulk_edit')) {
$assets = Asset::find(Input::get('bulk_edit'));
if (Input::has('ids')) {
$assets = Asset::find(Input::get('ids'));
foreach ($assets as $asset) {
$update_array['deleted_at'] = date('Y-m-d H:i:s');
$update_array['assigned_to'] = null;
if (DB::table('assets')
DB::table('assets')
->where('id', $asset->id)
->update($update_array)) {
$logAction = new Actionlog();
$logAction->item_type = Asset::class;
$logAction->item_id = $asset->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::user()->id;
$logAction->logaction('deleted');
}
->update($update_array);
} // endforeach
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.delete.success'));
@@ -1237,7 +1184,7 @@ class AssetsController extends Controller
$this->authorize('checkout', Asset::class);
// Filter out assets that are not deployable.
$assets_list = Company::scopeCompanyables(Asset::RTD()->get(), 'assets.company_id')->pluck('detailed_name', 'id')->toArray();
return View::make('hardware/bulk-checkout')
return view('hardware/bulk-checkout')
->with('users_list', Helper::usersList())
->with('assets_list', $assets_list);
}
@@ -55,7 +55,7 @@ class LoginController extends Controller
if (Auth::check()) {
return redirect()->intended('dashboard');
}
return View::make('auth.login');
return view('auth.login');
}
@@ -198,7 +198,7 @@ class LoginController extends Controller
$user->two_factor_secret
);
return View::make('auth.two_factor_enroll')->with('google2fa_url', $google2fa_url);
return view('auth.two_factor_enroll')->with('google2fa_url', $google2fa_url);
}
@@ -210,7 +210,7 @@ class LoginController extends Controller
*/
public function getTwoFactorAuth()
{
return View::make('auth.two_factor');
return view('auth.two_factor');
}
/**
@@ -38,7 +38,7 @@ class CategoriesController extends Controller
public function index()
{
// Show the page
return View::make('categories/index');
return view('categories/index');
}
@@ -54,7 +54,7 @@ class CategoriesController extends Controller
{
// Show the page
$category_types= Helper::categoryTypeList();
return View::make('categories/edit')->with('item', new Category)
return view('categories/edit')->with('item', new Category)
->with('category_types', $category_types);
}
@@ -105,7 +105,7 @@ class CategoriesController extends Controller
}
$category_types= Helper::categoryTypeList();
return View::make('categories/edit', compact('item'))
return view('categories/edit', compact('item'))
->with('category_types', $category_types);
}
@@ -201,7 +201,7 @@ class CategoriesController extends Controller
$category_type = $category->category_type;
$category_type_route = $category->category_type.'s';
}
return View::make('categories/view', compact('category'))
return view('categories/view', compact('category'))
->with('category_type',$category_type)
->with('category_type_route',$category_type_route);
}
+4 -4
View File
@@ -27,7 +27,7 @@ final class CompaniesController extends Controller
*/
public function index()
{
return View::make('companies/index')->with('companies', Company::all());
return view('companies/index')->with('companies', Company::all());
}
/**
@@ -39,7 +39,7 @@ final class CompaniesController extends Controller
*/
public function create()
{
return View::make('companies/edit')->with('item', new Company);
return view('companies/edit')->with('item', new Company);
}
/**
@@ -77,7 +77,7 @@ final class CompaniesController extends Controller
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.does_not_exist'));
}
return View::make('companies/edit')->with('item', $item);
return view('companies/edit')->with('item', $item);
}
/**
@@ -145,7 +145,7 @@ final class CompaniesController extends Controller
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.not_found'));
} else {
return View::make('companies/view')->with('company',$company);
return view('companies/view')->with('company',$company);
}
}
+5 -17
View File
@@ -2,7 +2,6 @@
namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Models\Actionlog;
use App\Models\Company;
use App\Models\Component;
use App\Models\CustomField;
@@ -12,7 +11,6 @@ use App\Models\Asset;
use Auth;
use Config;
use DB;
use DeepCopyTest\H;
use Input;
use Lang;
use Mail;
@@ -44,7 +42,7 @@ class ComponentsController extends Controller
public function index()
{
$this->authorize('view', Component::class);
return View::make('components/index');
return view('components/index');
}
@@ -60,7 +58,7 @@ class ComponentsController extends Controller
{
$this->authorize('create', Component::class);
// Show the page
return View::make('components/edit')
return view('components/edit')
->with('item', new Component)
->with('category_list', Helper::categoryList('component'))
->with('company_list', Helper::companyList())
@@ -79,10 +77,7 @@ class ComponentsController extends Controller
public function store()
{
$this->authorize('create', Component::class);
// create a new model instance
$component = new Component();
// Update the component data
$component->name = Input::get('name');
$component->category_id = Input::get('category_id');
$component->location_id = Input::get('location_id');
@@ -95,10 +90,7 @@ class ComponentsController extends Controller
$component->qty = Input::get('qty');
$component->user_id = Auth::id();
// Was the component created?
if ($component->save()) {
$component->logCreate();
// Redirect to the new component page
return redirect()->route('components.index')->with('success', trans('admin/components/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($component->getErrors());
@@ -115,15 +107,13 @@ class ComponentsController extends Controller
*/
public function edit($componentId = null)
{
// Check if the component exists
if (is_null($item = Component::find($componentId))) {
// Redirect to the blogs management page
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
}
$this->authorize('update', $item);
return View::make('components/edit', compact('item'))
return view('components/edit', compact('item'))
->with('category_list', Helper::categoryList('component'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList());
@@ -141,9 +131,7 @@ class ComponentsController extends Controller
*/
public function update($componentId = null)
{
// Check if the blog post exists
if (is_null($component = Component::find($componentId))) {
// Redirect to the blogs management page
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
}
@@ -215,7 +203,7 @@ class ComponentsController extends Controller
if (isset($component->id)) {
$this->authorize('view', $component);
return View::make('components/view', compact('component'));
return view('components/view', compact('component'));
}
// Prepare the error message
$error = trans('admin/components/message.does_not_exist', compact('id'));
@@ -240,7 +228,7 @@ class ComponentsController extends Controller
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
}
$this->authorize('checkout', $component);
return View::make('components/checkout', compact('component'))->with('assets_list', Helper::detailedAssetList());
return view('components/checkout', compact('component'))->with('assets_list', Helper::detailedAssetList());
}
/**
+8 -25
View File
@@ -3,7 +3,6 @@
namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Models\Actionlog;
use App\Models\Company;
use App\Models\Consumable;
use App\Models\Setting;
@@ -40,7 +39,7 @@ class ConsumablesController extends Controller
public function index()
{
$this->authorize('index', Consumable::class);
return View::make('consumables/index');
return view('consumables/index');
}
@@ -56,7 +55,7 @@ class ConsumablesController extends Controller
{
$this->authorize('create', Consumable::class);
// Show the page
return View::make('consumables/edit')
return view('consumables/edit')
->with('item', new Consumable)
->with('category_list', Helper::categoryList('consumable'))
->with('company_list', Helper::companyList())
@@ -91,10 +90,7 @@ class ConsumablesController extends Controller
$consumable->qty = Input::get('qty');
$consumable->user_id = Auth::id();
// Was the consumable created?
if ($consumable->save()) {
$consumable->logCreate();
// Redirect to the new consumable page
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.create.success'));
}
@@ -113,15 +109,13 @@ class ConsumablesController extends Controller
*/
public function edit($consumableId = null)
{
// Check if the consumable exists
if (is_null($item = Consumable::find($consumableId))) {
// Redirect to the blogs management page
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
}
$this->authorize($item);
return View::make('consumables/edit', compact('item'))
return view('consumables/edit', compact('item'))
->with('category_list', Helper::categoryList('consumable'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList())
@@ -175,9 +169,7 @@ class ConsumablesController extends Controller
*/
public function destroy($consumableId)
{
// Check if the blog post exists
if (is_null($consumable = Consumable::find($consumableId))) {
// Redirect to the blogs management page
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
}
$this->authorize($consumable);
@@ -200,13 +192,9 @@ class ConsumablesController extends Controller
$consumable = Consumable::find($consumableId);
$this->authorize($consumable);
if (isset($consumable->id)) {
return View::make('consumables/view', compact('consumable'));
return view('consumables/view', compact('consumable'));
}
// Prepare the error message
$error = trans('admin/consumables/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('consumables')->with('error', $error);
return redirect()->route('consumables')->with('error', trans('admin/consumables/message.does_not_exist', compact('id')));
}
/**
@@ -220,14 +208,11 @@ class ConsumablesController extends Controller
*/
public function getCheckout($consumableId)
{
// Check if the consumable exists
if (is_null($consumable = Consumable::find($consumableId))) {
// Redirect to the consumable management page with error
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
}
$this->authorize('checkout', $consumable);
// Get the dropdown of users and then pass it to the checkout view
return View::make('consumables/checkout', compact('consumable'))->with('users_list', Helper::usersList());
return view('consumables/checkout', compact('consumable'))->with('users_list', Helper::usersList());
}
/**
@@ -241,9 +226,7 @@ class ConsumablesController extends Controller
*/
public function postCheckout($consumableId)
{
// Check if the consumable exists
if (is_null($consumable = Consumable::find($consumableId))) {
// Redirect to the consumable management page with error
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
}
@@ -252,13 +235,13 @@ class ConsumablesController extends Controller
$admin_user = Auth::user();
$assigned_to = e(Input::get('assigned_to'));
// Check if the user exists
// Check if the user exists
if (is_null($user = User::find($assigned_to))) {
// Redirect to the consumable management page with error
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.user_does_not_exist'));
}
// Update the consumable data
// Update the consumable data
$consumable->assigned_to = e(Input::get('assigned_to'));
$consumable->users()->attach($consumable->id, [
@@ -39,7 +39,7 @@ class CustomFieldsController extends Controller
$fieldsets = CustomFieldset::with("fields", "models")->get();
$fields = CustomField::with("fieldset")->get();
return View::make("custom_fields.index")->with("custom_fieldsets", $fieldsets)->with("custom_fields", $fields);
return view("custom_fields.index")->with("custom_fieldsets", $fieldsets)->with("custom_fields", $fields);
}
@@ -57,7 +57,7 @@ class CustomFieldsController extends Controller
public function create()
{
return View::make("custom_fields.fields.edit")->with('field', new CustomField());
return view("custom_fields.fields.edit")->with('field', new CustomField());
}
@@ -155,7 +155,7 @@ class CustomFieldsController extends Controller
public function edit($id)
{
$field = CustomField::find($id);
return View::make("custom_fields.fields.edit")->with('field', $field);
return view("custom_fields.fields.edit")->with('field', $field);
}
@@ -49,7 +49,7 @@ class CustomFieldsetsController extends Controller
}
}
return View::make("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
return view("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
}
@@ -62,7 +62,7 @@ class CustomFieldsetsController extends Controller
*/
public function create()
{
return View::make("custom_fields.fieldsets.edit");
return view("custom_fields.fieldsets.edit");
}
+10 -43
View File
@@ -30,53 +30,20 @@ class DashboardController extends Controller
// Show the page
if (Auth::user()->hasAccess('admin')) {
$asset_stats['total'] = Asset::Hardware()->count();
$asset_stats=null;
$asset_stats['rtd']['total'] = Asset::Hardware()->RTD()->count();
$counts['asset'] = \App\Models\Asset::count();
$counts['accessory'] = \App\Models\Accessory::count();
$counts['license'] = \App\Models\License::assetcount();
$counts['consumable'] = \App\Models\Consumable::count();
$counts['grand_total'] = $counts['asset'] + $counts['accessory'] + $counts['license'] + $counts['consumable'];
if ($asset_stats['rtd']['total'] > 0) {
$asset_stats['rtd']['percent'] = round(($asset_stats['rtd']['total']/$asset_stats['total']) * 100);
} else {
$asset_stats['rtd']['percent'] = 0;
if ((!file_exists(storage_path().'/oauth-private.key')) || (!file_exists(storage_path().'/oauth-public.key'))) {
\Artisan::call('passport:install');
\Artisan::call('migrate', ['--force' => true]);
}
$asset_stats['pending']['total'] = Asset::Hardware()->Pending()->count();
if ($asset_stats['pending']['total'] > 0) {
$asset_stats['pending']['percent'] = round(($asset_stats['pending']['total']/$asset_stats['total']) * 100);
} else {
$asset_stats['pending']['percent'] = 0;
}
$asset_stats['deployed']['total'] = Asset::Hardware()->Deployed()->count();
if ($asset_stats['deployed']['total'] > 0) {
$asset_stats['deployed']['percent'] = round(($asset_stats['deployed']['total']/$asset_stats['total']) * 100);
} else {
$asset_stats['deployed']['percent'] = 0;
}
$asset_stats['undeployable']['total'] = Asset::Hardware()->Undeployable()->count();
if ($asset_stats['undeployable']['total'] > 0) {
$asset_stats['undeployable']['percent'] = round(($asset_stats['undeployable']['total']/$asset_stats['total']) * 100);
} else {
$asset_stats['undeployable']['percent'] = 0;
}
$asset_stats['archived']['total'] = Asset::Hardware()->Archived()->count();
if ($asset_stats['archived']['total'] > 0) {
$asset_stats['archived']['percent'] = round(($asset_stats['archived']['total']/$asset_stats['total']) * 100);
} else {
$asset_stats['archived']['percent'] = 0;
}
return View::make('dashboard')->with('asset_stats', $asset_stats);
return view('dashboard')->with('asset_stats', $asset_stats)->with('counts', $counts);
} else {
// Redirect to the profile page
return redirect()->intended('account/view-assets');
@@ -0,0 +1,164 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Department;
use App\Helpers\Helper;
use Auth;
class DepartmentsController extends Controller
{
public function __construct()
{
$this->middleware('auth');
parent::__construct();
}
/**
* Returns a view that invokes the ajax tables which actually contains
* the content for the assets listing, which is generated in getDatatable.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see AssetController::getDatatable() method that generates the JSON response
* @since [v4.0]
* @return View
*/
public function index(Request $request)
{
$this->authorize('index', Department::class);
if ($request->has('company_id')) {
$company = Company::find($request->input('company_id'));
} else {
$company = null;
}
return view('departments/index')->with('company',$company);
}
/**
* Store a newly created resource in storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->authorize('create', Department::class);
$department = new Department;
$department->fill($request->all());
$department->user_id = Auth::user()->id;
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
if ($department->save()) {
return redirect()->route("departments.index")->with('success', trans('admin/departments/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($department->getErrors());
}
/**
* Returns a view that invokes the ajax tables which actually contains
* the content for the department detail page.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @since [v4.0]
* @return \Illuminate\Contracts\View\View
*/
public function show($id)
{
$department = Department::find($id);
if (isset($department->id)) {
return view('departments/view', compact('department'));
}
return redirect()->route('departments.index')->with('error', trans('admin/departments/message.does_not_exist', compact('id')));
}
/**
* Returns a form view used to create a new department.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see DepartmentsController::postCreate() method that validates and stores the data
* @since [v4.0]
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
return view('departments/edit')->with('item', new Department)
->with('manager_list', Helper::managerList())
->with('location_list', Helper::locationsList())
->with('company_list', Helper::companyList());
}
/**
* Validates and deletes selected department.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $locationId
* @since [v4.0]
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($id)
{
if (is_null($department = Department::find($id))) {
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.not_found'));
}
if ($department->users->count() > 0) {
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.assoc_users'));
}
$department->delete();
return redirect()->back()->with('success', trans('admin/departments/message.delete.success'));
}
/**
* Makes a form view to edit location information.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LocationsController::postCreate() method that validates and stores
* @param int $locationId
* @since [v1.0]
* @return \Illuminate\Contracts\View\View
*/
public function edit($id = null)
{
if (is_null($item = Department::find($id))) {
return redirect()->back()->with('error', trans('admin/locations/message.does_not_exist'));
}
return view('departments/edit', compact('item'))
->with('manager_list', Helper::managerList())
->with('location_list', Helper::locationsList())
->with('company_list', Helper::companyList());
}
public function update(Request $request, $id) {
$this->authorize('create', Department::class);
if (is_null($department = Department::find($id))) {
return redirect()->to('admin/settings/departments')->with('error', trans('admin/departments/message.does_not_exist'));
}
$department->fill($request->all());
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
if ($department->save()) {
return redirect()->route("departments.index")->with('success', trans('admin/departments/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($department->getErrors());
}
}
@@ -32,7 +32,7 @@ class DepreciationsController extends Controller
public function index()
{
// Show the page
return View::make('depreciations/index', compact('depreciations'));
return view('depreciations/index', compact('depreciations'));
}
@@ -47,7 +47,7 @@ class DepreciationsController extends Controller
public function create()
{
// Show the page
return View::make('depreciations/edit')->with('item', new Depreciation);
return view('depreciations/edit')->with('item', new Depreciation);
}
@@ -94,7 +94,7 @@ class DepreciationsController extends Controller
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.does_not_exist'));
}
return View::make('depreciations/edit', compact('item'));
return view('depreciations/edit', compact('item'));
}
+13 -13
View File
@@ -28,10 +28,10 @@ class GroupsController extends Controller
* @since [v1.0]
* @return \Illuminate\Contracts\View\View
*/
public function getIndex()
public function index()
{
// Show the page
return View::make('groups/index', compact('groups'));
return view('groups/index', compact('groups'));
}
/**
@@ -42,7 +42,7 @@ class GroupsController extends Controller
* @since [v1.0]
* @return \Illuminate\Contracts\View\View
*/
public function getCreate()
public function create()
{
$group = new Group;
// Get all the available permissions
@@ -51,7 +51,7 @@ class GroupsController extends Controller
$selectedPermissions = Input::old('permissions', $groupPermissions);
// Show the page
return View::make('groups/edit', compact('permissions', 'selectedPermissions', 'groupPermissions'))->with('group', $group);
return view('groups/edit', compact('permissions', 'selectedPermissions', 'groupPermissions'))->with('group', $group);
}
/**
@@ -62,7 +62,7 @@ class GroupsController extends Controller
* @since [v1.0]
* @return \Illuminate\Http\RedirectResponse
*/
public function postCreate()
public function store()
{
// create a new group instance
$group = new Group();
@@ -84,13 +84,13 @@ class GroupsController extends Controller
* @since [v1.0]
* @return \Illuminate\Contracts\View\View
*/
public function getEdit($id = null)
public function edit($id = null)
{
$group = Group::find($id);
$permissions = config('permissions');
$groupPermissions = $group->decodePermissions();
$selected_array = Helper::selectedPermissionsArray($permissions, $groupPermissions);
return View::make('groups/edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'));
return view('groups.edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'));
}
/**
@@ -102,7 +102,7 @@ class GroupsController extends Controller
* @since [v1.0]
* @return \Illuminate\Http\RedirectResponse
*/
public function postEdit($id = null)
public function update($id = null)
{
$permissions = config('permissions');
if (!$group = Group::find($id)) {
@@ -113,11 +113,11 @@ class GroupsController extends Controller
if (!config('app.lock_passwords')) {
if ($group->save()) {
return redirect()->to("admin/groups")->with('success', trans('admin/groups/message.success.update'));
return redirect()->route('groups.index')->with('success', trans('admin/groups/message.success.update'));
}
return redirect()->back()->withInput()->withErrors($group->getErrors());
}
return redirect()->route('groups')->with('error', trans('general.feature_disabled'));
return redirect()->route('groups.index')->with('error', trans('general.feature_disabled'));
}
/**
@@ -129,7 +129,7 @@ class GroupsController extends Controller
* @since [v1.0]
* @return \Illuminate\Http\RedirectResponse
*/
public function getDelete($id = null)
public function destroy($id = null)
{
if (!config('app.lock_passwords')) {
if (!$group = Group::find($id)) {
@@ -137,9 +137,9 @@ class GroupsController extends Controller
}
$group->delete();
// Redirect to the group management page
return redirect()->route('groups')->with('success', trans('admin/groups/message.success.delete'));
return redirect()->route('groups.index')->with('success', trans('admin/groups/message.success.delete'));
}
return redirect()->route('groups')->with('error', trans('general.feature_disabled'));
return redirect()->route('groups.index')->with('error', trans('general.feature_disabled'));
}
}
@@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers;
use App\Http\Transformers\ImportsTransformer;
use App\Models\Import;
use Illuminate\Http\Request;
class ImportsController extends Controller
{
public function index()
{
$this->authorize('create', Asset::class);
$imports = Import::latest()->get();
$imports = (new ImportsTransformer)->transformImports($imports);
return view('importer/import')->with('imports', $imports);
}
}
+7 -13
View File
@@ -43,7 +43,7 @@ class LicensesController extends Controller
public function index()
{
$this->authorize('view', License::class);
return View::make('licenses/index');
return view('licenses/index');
}
@@ -64,7 +64,7 @@ class LicensesController extends Controller
'0' => 'No'
];
return View::make('licenses/edit')
return view('licenses/edit')
//->with('license_options',$license_options)
->with('depreciation_list', Helper::depreciationList())
->with('supplier_list', Helper::suppliersList())
@@ -113,10 +113,7 @@ class LicensesController extends Controller
$license->termination_date = $request->input('termination_date');
$license->user_id = Auth::id();
// Was the license created?
if ($license->save()) {
$license->logCreate();
// Save the license seat data
return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($license->getErrors());
@@ -145,7 +142,7 @@ class LicensesController extends Controller
'0' => 'No'
];
return View::make('licenses/edit', compact('item'))
return view('licenses/edit', compact('item'))
->with('depreciation_list', Helper::depreciationList())
->with('supplier_list', Helper::suppliersList())
->with('company_list', Helper::companyList())
@@ -167,15 +164,12 @@ class LicensesController extends Controller
*/
public function update(Request $request, $licenseId = null)
{
// Check if the license exists
if (is_null($license = License::find($licenseId))) {
// Redirect to the blogs management page
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist'));
}
$this->authorize('update', $license);
// Update the license data
$license->company_id = Company::getIdForCurrentUser($request->input('company_id'));
$license->depreciation_id = $request->input('depreciation_id');
$license->expiration_date = $request->input('expiration_date');
@@ -259,7 +253,7 @@ class LicensesController extends Controller
}
$this->authorize('checkout', $licenseSeat);
return View::make('licenses/checkout', compact('licenseSeat'))
return view('licenses/checkout', compact('licenseSeat'))
->with('users_list', Helper::usersList())
->with('asset_list', Helper::detailedAssetList());
}
@@ -369,7 +363,7 @@ class LicensesController extends Controller
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
}
$this->authorize('checkin', $licenseseat);
return View::make('licenses/checkin', compact('licenseseat'))->with('backto', $backTo);
return view('licenses/checkin', compact('licenseseat'))->with('backto', $backTo);
}
@@ -450,7 +444,7 @@ class LicensesController extends Controller
if (isset($license->id)) {
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
$this->authorize('view', $license);
return View::make('licenses/view', compact('license'));
return view('licenses/view', compact('license'));
}
$error = trans('admin/licenses/message.does_not_exist', compact('id'));
return redirect()->route('licenses.index')->with('error', $error);
@@ -475,7 +469,7 @@ class LicensesController extends Controller
$license->serial = null;
// Show the page
return View::make('licenses/edit')
return view('licenses/edit')
->with('depreciation_list', Helper::depreciationList())
->with('supplier_list', Helper::suppliersList())
->with('item', $license)
+4 -4
View File
@@ -41,7 +41,7 @@ class LocationsController extends Controller
$locations = Location::orderBy('created_at', 'DESC')->with('parent', 'assets', 'assignedassets')->get();
// Show the page
return View::make('locations/index', compact('locations'));
return view('locations/index', compact('locations'));
}
@@ -61,7 +61,7 @@ class LocationsController extends Controller
$location_options = Location::flattenLocationsArray($location_options_array);
$location_options = array('' => 'Top Level') + $location_options;
return View::make('locations/edit')
return view('locations/edit')
->with('location_options', $location_options)
->with('item', new Location);
}
@@ -154,7 +154,7 @@ class LocationsController extends Controller
$location_options = Location::flattenLocationsArray($location_options_array);
$location_options = array('' => 'Top Level') + $location_options;
return View::make('locations/edit', compact('item'))->with('location_options', $location_options);
return view('locations/edit', compact('item'))->with('location_options', $location_options);
}
@@ -243,7 +243,7 @@ class LocationsController extends Controller
$location = Location::find($locationId);
if (isset($location->id)) {
return View::make('locations/view', compact('location'));
return view('locations/view', compact('location'));
}
// Prepare the error message
$error = trans('admin/locations/message.does_not_exist', compact('id'));
@@ -33,7 +33,7 @@ class ManufacturersController extends Controller
*/
public function index()
{
return View::make('manufacturers/index', compact('manufacturers'));
return view('manufacturers/index', compact('manufacturers'));
}
@@ -47,7 +47,7 @@ class ManufacturersController extends Controller
*/
public function create()
{
return View::make('manufacturers/edit')->with('item', new Manufacturer);
return view('manufacturers/edit')->with('item', new Manufacturer);
}
@@ -95,7 +95,7 @@ class ManufacturersController extends Controller
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
}
// Show the page
return View::make('manufacturers/edit', compact('item'));
return view('manufacturers/edit', compact('item'));
}
@@ -172,7 +172,7 @@ class ManufacturersController extends Controller
$manufacturer = Manufacturer::find($manufacturerId);
if (isset($manufacturer->id)) {
return View::make('manufacturers/view', compact('manufacturer'));
return view('manufacturers/view', compact('manufacturer'));
}
// Prepare the error message
$error = trans('admin/manufacturers/message.does_not_exist', compact('id'));
+1 -1
View File
@@ -30,7 +30,7 @@ class ProfileController extends Controller
{
$user = Auth::user();
$location_list = Helper::locationsList();
return View::make('account/profile', compact('user'))->with('location_list', $location_list);
return view('account/profile', compact('user'))->with('location_list', $location_list);
}
/**
+8 -62
View File
@@ -6,21 +6,14 @@ use App\Models\Accessory;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\AssetMaintenance;
use App\Models\AssetModel;
use App\Models\Company;
use App\Models\CustomField;
use App\Models\License;
use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\View;
use Input;
use League\Csv\Reader;
use Redirect;
use Symfony\Component\HttpFoundation\StreamedResponse;
/**
@@ -42,8 +35,7 @@ class ReportsController extends Controller
public function getAccessoryReport()
{
$accessories = Accessory::orderBy('created_at', 'DESC')->with('company')->get();
return View::make('reports/accessories', compact('accessories'));
return view('reports/accessories', compact('accessories'));
}
/**
@@ -98,7 +90,7 @@ class ReportsController extends Controller
public function getAssetsReport()
{
$settings = \App\Models\Setting::first();
return View::make('reports/asset', compact('assets'))->with('settings', $settings);
return view('reports/asset', compact('assets'))->with('settings', $settings);
}
@@ -197,7 +189,7 @@ class ReportsController extends Controller
$assets = Asset::with('model', 'assignedTo', 'assetstatus', 'defaultLoc', 'assetlog', 'company')
->orderBy('created_at', 'DESC')->get();
return View::make('reports/depreciation', compact('assets'));
return view('reports/depreciation', compact('assets'));
}
/**
@@ -289,55 +281,9 @@ class ReportsController extends Controller
public function getActivityReport()
{
return View::make('reports/activity');
return view('reports/activity');
}
/**
* Returns Activity Report JSON.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getActivityReportDataTable()
{
$activitylogs = Company::scopeCompanyables(Actionlog::with('item', 'user', 'target'))->orderBy('created_at', 'DESC');
if (Input::has('search')) {
$activitylogs = $activitylogs->TextSearch(e(Input::get('search')));
}
if (Input::has('offset')) {
$offset = e(Input::get('offset'));
} else {
$offset = 0;
}
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
} else {
$limit = 50;
}
$allowed_columns = ['created_at'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
$activityCount = $activitylogs->count();
$activitylogs = $activitylogs->offset($offset)->limit($limit)->get();
$rows = array();
foreach ($activitylogs as $activity) {
$rows[] = $activity->present()->forDataTable();
}
$data = array('total'=>$activityCount, 'rows'=>$rows);
return $data;
}
/**
* Displays license report
@@ -353,7 +299,7 @@ class ReportsController extends Controller
->with('company')
->get();
return View::make('reports/licenses', compact('licenses'));
return view('reports/licenses', compact('licenses'));
}
/**
@@ -417,7 +363,7 @@ class ReportsController extends Controller
public function getCustomReport()
{
$customfields = CustomField::get();
return View::make('reports/custom')->with('customfields', $customfields);
return view('reports/custom')->with('customfields', $customfields);
}
/**
@@ -690,7 +636,7 @@ class ReportsController extends Controller
->orderBy('created_at', 'DESC')
->get();
return View::make('reports/asset_maintenances', compact('assetMaintenances'));
return view('reports/asset_maintenances', compact('assetMaintenances'));
}
@@ -765,7 +711,7 @@ class ReportsController extends Controller
{
$assetsForReport = Asset::notYetAccepted()->with('company')->get();
return View::make('reports/unaccepted_assets', compact('assetsForReport'));
return view('reports/unaccepted_assets', compact('assetsForReport'));
}
/**
+535 -149
View File
@@ -65,15 +65,24 @@ class SettingsController extends Controller
$start_settings['url_config'] = url('/');
$start_settings['real_url'] = $pageURL;
// Curl the .env file to make sure it's not accessible via a browser
$ch = curl_init($protocol . $host.'/.env');
curl_setopt($ch, CURLOPT_HEADER, true); // we want headers
curl_setopt($ch, CURLOPT_NOBODY, true); // we don't need body
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$exposed_env = @file_get_contents($protocol . $host.'/.env');
if ($exposed_env) {
$start_settings['env_exposed'] = true;
} else {
if ($httpcode == 404 || $httpcode == 403) {
$start_settings['env_exposed'] = false;
} else {
$start_settings['env_exposed'] = true;
}
if (\App::Environment('production') && (config('app.debug')==true)) {
$start_settings['debug_exposed'] = true;
} else {
@@ -120,7 +129,7 @@ class SettingsController extends Controller
$start_settings['gd'] = extension_loaded('gd');
return View::make('setup/index')
return view('setup/index')
->with('step', 1)
->with('start_settings', $start_settings)
->with('section', 'Pre-Flight Check');
@@ -181,6 +190,7 @@ class SettingsController extends Controller
$settings->user_id = 1;
$settings->email_domain = e(Input::get('email_domain'));
$settings->email_format = e(Input::get('email_format'));
$settings->next_auto_tag_base = 1;
if ((!$user->isValid()) || (!$settings->isValid())) {
@@ -215,7 +225,7 @@ class SettingsController extends Controller
*/
public function getSetupUser()
{
return View::make('setup/user')
return view('setup/user')
->with('step', 3)
->with('section', 'Create a User');
}
@@ -230,7 +240,7 @@ class SettingsController extends Controller
public function getSetupDone()
{
return View::make('setup/done')
return view('setup/done')
->with('step', 4)
->with('section', 'Done!');
}
@@ -249,7 +259,7 @@ class SettingsController extends Controller
Artisan::call('migrate', ['--force' => true]);
$output = Artisan::output();
return View::make('setup/migrate')
return view('setup/migrate')
->with('output', $output)
->with('step', 2)
->with('section', 'Create Database Tables');
@@ -264,15 +274,15 @@ class SettingsController extends Controller
* @since [v1.0]
* @return View
*/
public function getIndex()
public function index()
{
$settings = Setting::all();
return View::make('settings/index', compact('settings'));
return view('settings/index', compact('settings'));
}
/**
* Return a form to allow a super admin to update settings.
* Return the admin settings page
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
@@ -281,77 +291,460 @@ class SettingsController extends Controller
public function getEdit()
{
$setting = Setting::first();
$is_gd_installed = extension_loaded('gd');
return View::make('settings/edit', compact('setting'))->with('is_gd_installed', $is_gd_installed);
return view('settings/general', compact('setting'));
}
/**
* Validate and process settings edit form.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return Redirect
*/
public function postEdit(ImageUploadRequest $request)
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getSettings()
{
$setting = Setting::first();
return view('settings/general', compact('setting'));
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postSettings(Request $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->full_multiple_companies_support = $request->input('full_multiple_companies_support', '0');
$setting->load_remote = $request->input('load_remote', '0');
$setting->email_domain = $request->input('email_domain');
$setting->email_format = $request->input('email_format');
$setting->username_format = $request->input('username_format');
$setting->require_accept_signature = $request->input('require_accept_signature');
$setting->login_note = $request->input('login_note');
$setting->default_eula_text = $request->input('default_eula_text');
$setting->thumbnail_max_h = $request->input('thumbnail_max_h');
if (Input::get('per_page')!='') {
$setting->per_page = $request->input('per_page');
} else {
$setting->per_page = 200;
}
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getBranding()
{
$setting = Setting::first();
return view('settings.branding', compact('setting'));
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postBranding(ImageUploadRequest $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->brand = $request->input('brand', '1');
$setting->header_color = $request->input('header_color');
// Only allow the site name and CSS to be changed if lock_passwords is false
// Because public demos make people act like dicks
if (!config('app.lock_passwords')) {
$setting->site_name = $request->input('site_name');
$setting->custom_css = $request->input('custom_css');
}
// If the user wants to clear the logo, reset the brand type
if ($request->input('clear_logo')=='1') {
$setting->logo = null;
$setting->brand = 1;
// If they are uploading an image, validate it and upload it
} elseif ($request->hasFile('image')) {
if (!config('app.lock_passwords')) {
$image = $request->file('image');
$file_name = "logo.".$image->getClientOriginalExtension();
$path = public_path('uploads');
if ($image->getClientOriginalExtension()!='svg') {
Image::make($image->getRealPath())->resize(null, 40, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->save($path.'/'.$file_name);
} else {
$image->move($path, $file_name);
}
$setting->logo = $file_name;
}
}
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getSecurity()
{
$setting = Setting::first();
return view('settings.security', compact('setting'));
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postSecurity(Request $request)
{
// Check if the asset exists
if (is_null($setting = Setting::first())) {
// Redirect to the asset management page with error
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
if (!config('app.lock_passwords')) {
$setting->site_name = e(Input::get('site_name'));
$setting->custom_css = e(Input::get('custom_css'));
if (Input::get('two_factor_enabled')=='') {
if ($request->input('two_factor_enabled')=='') {
$setting->two_factor_enabled = null;
} else {
$setting->two_factor_enabled = e(Input::get('two_factor_enabled'));
$setting->two_factor_enabled = $request->input('two_factor_enabled');
}
}
if (Input::get('per_page')!='') {
$setting->per_page = e(Input::get('per_page'));
} else {
$setting->per_page = 200;
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getLocalization()
{
$setting = Setting::first();
return view('settings.localization', compact('setting'));
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postLocalization(Request $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->locale = e(Input::get('locale', 'en'));
$setting->qr_code = e(Input::get('qr_code', '0'));
$setting->full_multiple_companies_support = e(Input::get('full_multiple_companies_support', '0'));
$setting->alt_barcode = e(Input::get('alt_barcode'));
$setting->alt_barcode_enabled = e(Input::get('alt_barcode_enabled', '0'));
$setting->barcode_type = e(Input::get('barcode_type'));
$setting->load_remote = e(Input::get('load_remote', '0'));
$setting->default_currency = e(Input::get('default_currency', '$'));
$setting->qr_text = e(Input::get('qr_text'));
$setting->auto_increment_prefix = e(Input::get('auto_increment_prefix'));
$setting->auto_increment_assets = e(Input::get('auto_increment_assets', '0'));
$setting->zerofill_count = e(Input::get('zerofill_count'));
$setting->alert_interval = e(Input::get('alert_interval'));
$setting->alert_threshold = e(Input::get('alert_threshold'));
$setting->email_domain = e(Input::get('email_domain'));
$setting->email_format = e(Input::get('email_format'));
$setting->username_format = e(Input::get('username_format'));
$setting->require_accept_signature = e(Input::get('require_accept_signature'));
$setting->labels_per_page = e(Input::get('labels_per_page'));
$setting->labels_width = e(Input::get('labels_width'));
$setting->labels_height = e(Input::get('labels_height'));
$setting->labels_pmargin_left = e(Input::get('labels_pmargin_left'));
$setting->labels_pmargin_right = e(Input::get('labels_pmargin_right'));
$setting->labels_pmargin_top = e(Input::get('labels_pmargin_top'));
$setting->labels_pmargin_bottom = e(Input::get('labels_pmargin_bottom'));
$setting->labels_display_bgutter = e(Input::get('labels_display_bgutter'));
$setting->labels_display_sgutter = e(Input::get('labels_display_sgutter'));
$setting->labels_fontsize = e(Input::get('labels_fontsize'));
$setting->labels_pagewidth = e(Input::get('labels_pagewidth'));
$setting->labels_pageheight = e(Input::get('labels_pageheight'));
$setting->locale = $request->input('locale', 'en');
$setting->default_currency = $request->input('default_currency', '$');
$setting->date_display_format = $request->input('date_display_format');
$setting->time_display_format = $request->input('time_display_format');
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getAlerts()
{
$setting = Setting::first();
return view('settings.alerts', compact('setting'));
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postAlerts(Request $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$alert_email = rtrim($request->input('alert_email'), ',');
$alert_email = trim($alert_email);
$setting->alert_email = e($alert_email);
$setting->alerts_enabled = $request->input('alerts_enabled', '0');
$setting->alert_interval = $request->input('alert_interval');
$setting->alert_threshold = $request->input('alert_threshold');
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getSlack()
{
$setting = Setting::first();
return view('settings.slack', compact('setting'));
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postSlack(Request $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->slack_endpoint = $request->input('slack_endpoint');
$setting->slack_channel = $request->input('slack_channel');
$setting->slack_botname = $request->input('slack_botname');
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getAssetTags()
{
$setting = Setting::first();
return view('settings.asset_tags', compact('setting'));
}
/**
* Saves settings from form
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postAssetTags(Request $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->auto_increment_prefix = $request->input('auto_increment_prefix');
$setting->auto_increment_assets = $request->input('auto_increment_assets', '0');
$setting->zerofill_count = $request->input('zerofill_count');
$setting->next_auto_tag_base = $request->input('next_auto_tag_base');
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getBarcodes()
{
$setting = Setting::first();
$is_gd_installed = extension_loaded('gd');
return view('settings.barcodes', compact('setting'))->with('is_gd_installed',$is_gd_installed);
}
/**
* Saves settings from form
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function postBarcodes(Request $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->qr_code = $request->input('qr_code', '0');
$setting->alt_barcode = $request->input('alt_barcode');
$setting->alt_barcode_enabled = $request->input('alt_barcode_enabled', '0');
$setting->barcode_type = $request->input('barcode_type');
$setting->qr_text = $request->input('qr_text');
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function getPhpInfo()
{
if (config('app.debug')=== true) {
return view('settings.phpinfo');
}
return redirect()->route('settings.index')
->with('error', 'PHP syetem debugging information is only available when debug is enabled in your .env file.');
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function getLabels()
{
$setting = Setting::first();
return view('settings.labels', compact('setting'));
}
/**
* Saves settings from form
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function postLabels(Request $request)
{
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->labels_per_page = $request->input('labels_per_page');
$setting->labels_width = $request->input('labels_width');
$setting->labels_height = $request->input('labels_height');
$setting->labels_pmargin_left = $request->input('labels_pmargin_left');
$setting->labels_pmargin_right = $request->input('labels_pmargin_right');
$setting->labels_pmargin_top = $request->input('labels_pmargin_top');
$setting->labels_pmargin_bottom = $request->input('labels_pmargin_bottom');
$setting->labels_display_bgutter = $request->input('labels_display_bgutter');
$setting->labels_display_sgutter = $request->input('labels_display_sgutter');
$setting->labels_fontsize = $request->input('labels_fontsize');
$setting->labels_pagewidth = $request->input('labels_pagewidth');
$setting->labels_pageheight = $request->input('labels_pageheight');
if (Input::has('labels_display_name')) {
@@ -372,96 +765,78 @@ class SettingsController extends Controller
$setting->labels_display_tag = 0;
}
$alert_email = rtrim(Input::get('alert_email'), ',');
$alert_email = trim($alert_email);
$setting->alert_email = e($alert_email);
$setting->alerts_enabled = e(Input::get('alerts_enabled', '0'));
$setting->header_color = e(Input::get('header_color'));
$setting->default_eula_text = e(Input::get('default_eula_text'));
$setting->slack_endpoint = e(Input::get('slack_endpoint'));
$setting->slack_channel = e(Input::get('slack_channel'));
$setting->slack_botname = e(Input::get('slack_botname'));
$setting->ldap_enabled = e(Input::get('ldap_enabled', '0'));
$setting->ldap_server = e(Input::get('ldap_server'));
$setting->ldap_server_cert_ignore = e(Input::get('ldap_server_cert_ignore', false));
$setting->ldap_uname = e(Input::get('ldap_uname'));
if (Input::has('ldap_pword')) {
$setting->ldap_pword = Crypt::encrypt(Input::get('ldap_pword'));
}
$setting->ldap_basedn = e(Input::get('ldap_basedn'));
$setting->ldap_filter = Input::get('ldap_filter');
$setting->ldap_username_field = Input::get('ldap_username_field');
$setting->ldap_lname_field = e(Input::get('ldap_lname_field'));
$setting->ldap_fname_field = e(Input::get('ldap_fname_field'));
$setting->ldap_auth_filter_query = Input::get('ldap_auth_filter_query');
$setting->ldap_version = e(Input::get('ldap_version'));
$setting->ldap_active_flag = e(Input::get('ldap_active_flag'));
$setting->ldap_emp_num = e(Input::get('ldap_emp_num'));
$setting->ldap_email = e(Input::get('ldap_email'));
$setting->ad_domain = e(Input::get('ad_domain'));
$setting->is_ad = e(Input::get('is_ad', '0'));
$setting->ldap_tls = e(Input::get('ldap_tls', '0'));
$setting->ldap_pw_sync = e(Input::get('ldap_pw_sync', '0'));
$setting->date_display_format = e(Input::get('date_display_format'));
$setting->time_display_format = e(Input::get('time_display_format'));
if ($request->input('clear_logo')=='1') {
$setting->logo = null;
$setting->brand = 1;
} elseif ($request->hasFile('image')) {
if (!config('app.lock_passwords')) {
$image = $request->file('image');
$file_name = "logo.".$image->getClientOriginalExtension();
$path = public_path('uploads');
if ($image->getClientOriginalExtension()!='svg') {
Image::make($image->getRealPath())->resize(null, 40, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->save($path.'/'.$file_name);
} else {
$image->move($path, $file_name);
}
$setting->logo = $file_name;
}
}
if ($setting->save()) {
return redirect()->to("admin/settings/app")->with('success', trans('admin/settings/message.update.success'));
} else {
return redirect()->back()->withInput()->withErrors($setting->getErrors());
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
// Redirect to the setting management page
return redirect()->to("admin/settings/app/edit")->with('error', trans('admin/settings/message.update.error'));
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
public function getLdapTest()
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function getLdapSettings()
{
$setting = Setting::first();
return view('settings.ldap', compact('setting'));
}
/**
* Saves settings from form
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function postLdapSettings(Request $request)
{
try {
$connection = Ldap::connectToLdap();
try {
Ldap::bindAdminToLdap($connection);
return response()->json(['message' => 'It worked!'], 200);
} catch (\Exception $e) {
return response()->json(['message' => $e->getMessage()], 500);
}
return response()->json(['message' => 'It worked!'], 200);
} catch (\Exception $e) {
return response()->json(['message' => $e->getMessage()], 500);
if (is_null($setting = Setting::first())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->ldap_enabled = $request->input('ldap_enabled', '0');
$setting->ldap_server = $request->input('ldap_server');
$setting->ldap_server_cert_ignore = $request->input('ldap_server_cert_ignore', false);
$setting->ldap_uname = $request->input('ldap_uname');
if (Input::has('ldap_pword')) {
$setting->ldap_pword = Crypt::encrypt($request->input('ldap_pword'));
}
$setting->ldap_basedn = $request->input('ldap_basedn');
$setting->ldap_filter = $request->input('ldap_filter');
$setting->ldap_username_field = $request->input('ldap_username_field');
$setting->ldap_lname_field = $request->input('ldap_lname_field');
$setting->ldap_fname_field = $request->input('ldap_fname_field');
$setting->ldap_auth_filter_query = $request->input('ldap_auth_filter_query');
$setting->ldap_version = $request->input('ldap_version');
$setting->ldap_active_flag = $request->input('ldap_active_flag');
$setting->ldap_emp_num = $request->input('ldap_emp_num');
$setting->ldap_email = $request->input('ldap_email');
$setting->ad_domain = $request->input('ad_domain');
$setting->is_ad = $request->input('is_ad', '0');
$setting->ldap_tls = $request->input('ldap_tls', '0');
$setting->ldap_pw_sync = $request->input('ldap_pw_sync', '0');
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
/**
* Show the listing of backups
*
@@ -495,7 +870,7 @@ class SettingsController extends Controller
}
return View::make('settings/backups', compact('path', 'files'));
return view('settings/backups', compact('path', 'files'));
}
@@ -511,10 +886,9 @@ class SettingsController extends Controller
{
if (!config('app.lock_passwords')) {
Artisan::call('backup:run');
return redirect()->to("admin/settings/backups")->with('success', trans('admin/settings/message.backup.generated'));
return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.generated'));
} else {
return redirect()->to("admin/settings/backups")->with('error', trans('general.feature_disabled'));
return redirect()->to("settings.backups.index")->with('error', trans('general.feature_disabled'));
}
@@ -538,11 +912,11 @@ class SettingsController extends Controller
} else {
// Redirect to the backup page
return redirect()->route('settings/backups')->with('error', trans('admin/settings/message.backup.file_not_found'));
return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
}
} else {
// Redirect to the backup page
return redirect()->route('settings/backups')->with('error', trans('general.feature_disabled'));
return redirect()->route('settings.backups.index')->with('error', trans('general.feature_disabled'));
}
@@ -564,17 +938,29 @@ class SettingsController extends Controller
$file = $path.'/'.$filename;
if (file_exists($file)) {
unlink($file);
return redirect()->route('settings/backups')->with('success', trans('admin/settings/message.backup.file_deleted'));
return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.file_deleted'));
} else {
return redirect()->route('settings/backups')->with('error', trans('admin/settings/message.backup.file_not_found'));
return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
}
} else {
return redirect()->route('settings/backups')->with('error', trans('general.feature_disabled'));
return redirect()->route('settings.backups.index')->with('error', trans('general.feature_disabled'));
}
}
/**
* Return a form to allow a super admin to update settings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function getPurge()
{
return view('settings.purge-form');
}
/**
* Purges soft-deletes
*
@@ -588,7 +974,7 @@ class SettingsController extends Controller
if (Input::get('confirm_purge')=='DELETE') {
Artisan::call('snipeit:purge', ['--force'=>'true','--no-interaction'=>true]);
$output = Artisan::output();
return View::make('settings/purge')
return view('settings/purge')
->with('output', $output)->with('success', trans('admin/settings/message.purge.success'));
} else {
return redirect()->back()->with('error', trans('admin/settings/message.purge.validation_failed'));
@@ -610,6 +996,6 @@ class SettingsController extends Controller
* @return View
*/
public function api() {
return view('settings/api');
return view('settings.api');
}
}
@@ -32,7 +32,7 @@ class StatuslabelsController extends Controller
public function index()
{
return View::make('statuslabels/index', compact('statuslabels'));
return view('statuslabels/index', compact('statuslabels'));
}
public function show($id)
@@ -40,7 +40,7 @@ class StatuslabelsController extends Controller
$statuslabel = Statuslabel::find($id);
if (isset($statuslabel->id)) {
return View::make('statuslabels/view', compact('statuslabel'));
return view('statuslabels/view', compact('statuslabel'));
}
return redirect()->route('statuslabels.index')->with('error', trans('admin/locations/message.does_not_exist', compact('id')));
@@ -60,7 +60,7 @@ class StatuslabelsController extends Controller
$use_statuslabel_type = $item->getStatuslabelType();
$statuslabel_types = Helper::statusTypeList();
return View::make('statuslabels/edit', compact('statuslabel_types', 'item'))->with('use_statuslabel_type', $use_statuslabel_type);
return view('statuslabels/edit', compact('statuslabel_types', 'item'))->with('use_statuslabel_type', $use_statuslabel_type);
}
@@ -148,7 +148,7 @@ class StatuslabelsController extends Controller
$statuslabel_types = array('' => trans('admin/hardware/form.select_statustype')) + array('undeployable' => trans('admin/hardware/general.undeployable')) + array('pending' => trans('admin/hardware/general.pending')) + array('archived' => trans('admin/hardware/general.archived')) + array('deployable' => trans('admin/hardware/general.deployable'));
return View::make('statuslabels/edit', compact('item', 'statuslabel_types'))->with('use_statuslabel_type', $use_statuslabel_type);
return view('statuslabels/edit', compact('item', 'statuslabel_types'))->with('use_statuslabel_type', $use_statuslabel_type);
}
+4 -4
View File
@@ -35,7 +35,7 @@ class SuppliersController extends Controller
$suppliers = Supplier::orderBy('created_at', 'DESC')->get();
// Show the page
return View::make('suppliers/index', compact('suppliers'));
return view('suppliers/index', compact('suppliers'));
}
@@ -46,7 +46,7 @@ class SuppliersController extends Controller
*/
public function create()
{
return View::make('suppliers/edit')->with('item', new Supplier);
return view('suppliers/edit')->with('item', new Supplier);
}
@@ -126,7 +126,7 @@ class SuppliersController extends Controller
}
// Show the page
return View::make('suppliers/edit', compact('item'));
return view('suppliers/edit', compact('item'));
}
@@ -222,7 +222,7 @@ class SuppliersController extends Controller
$supplier = Supplier::find($supplierId);
if (isset($supplier->id)) {
return View::make('suppliers/view', compact('supplier'));
return view('suppliers/view', compact('supplier'));
}
// Prepare the error message
$error = trans('admin/suppliers/message.does_not_exist', compact('id'));
+55 -35
View File
@@ -61,7 +61,7 @@ class UsersController extends Controller
public function index()
{
$this->authorize('index', User::class);
return View::make('users/index');
return view('users/index');
}
/**
@@ -86,10 +86,11 @@ class UsersController extends Controller
$userPermissions = Helper::selectedPermissionsArray($permissions, Input::old('permissions', array()));
$permissions = $this->filterDisplayable($permissions);
return View::make('users/edit', compact('groups', 'userGroups', 'permissions', 'userPermissions'))
return view('users/edit', compact('groups', 'userGroups', 'permissions', 'userPermissions'))
->with('location_list', Helper::locationsList())
->with('manager_list', Helper::managerList())
->with('company_list', Helper::companyList())
->with('department_list', Helper::departmentList())
->with('user', new User);
}
@@ -120,6 +121,7 @@ class UsersController extends Controller
$user->jobtitle = $request->input('jobtitle');
$user->phone = $request->input('phone');
$user->location_id = $request->input('location_id', null);
$user->department_id = $request->input('department_id', null);
$user->company_id = Company::getIdForUser($request->input('company_id', null));
$user->manager_id = $request->input('manager_id', null);
$user->notes = $request->input('notes');
@@ -167,7 +169,7 @@ class UsersController extends Controller
* @since [v1.8]
* @return string JSON
*/
public function apiStore()
public function apiStore(Request $request)
{
$this->authorize('create', User::class);
@@ -175,12 +177,13 @@ class UsersController extends Controller
$inputs = Input::except('csrf_token', 'password_confirm', 'groups', 'email_user');
$inputs['activated'] = true;
$user->first_name = Input::get('first_name');
$user->last_name = Input::get('last_name');
$user->username = Input::get('username');
$user->email = Input::get('email');
if (Input::has('password')) {
$user->password = bcrypt(Input::get('password'));
$user->first_name = $request->input('first_name');
$user->last_name = $request->input('last_name');
$user->username = $request->input('username');
$user->email = $request->input('email');
$user->department_id = $request->input('department_id', null);
if ($request->has('password')) {
$user->password = bcrypt($request->input('password'));
}
$user->activated = true;
@@ -190,10 +193,10 @@ class UsersController extends Controller
if (Input::get('email_user') == 1) {
// Send the credentials through email
$data = array();
$data['email'] = e(Input::get('email'));
$data['first_name'] = e(Input::get('first_name'));
$data['last_name'] = e(Input::get('last_name'));
$data['password'] = e(Input::get('password'));
$data['email'] = $request->input('email');
$data['first_name'] = $request->input('first_name');
$data['last_name'] = $request->input('last_name');
$data['password'] = $request->input('password');
Mail::send('emails.send-login', $data, function ($m) use ($user) {
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
@@ -229,10 +232,10 @@ class UsersController extends Controller
return $output;
}
public function edit($id = null)
public function edit($id)
{
try {
// Get the user information
$user = User::find($id);
$this->authorize('update', $user);
$permissions = config('permissions');
@@ -243,19 +246,19 @@ class UsersController extends Controller
$user->permissions = $user->decodePermissions();
$userPermissions = Helper::selectedPermissionsArray($permissions, $user->permissions);
$permissions = $this->filterDisplayable($permissions);
} catch (UserNotFoundException $e) {
// Prepare the error message
$error = trans('admin/users/message.user_not_found', compact('id'));
// Redirect to the user management page
$error = trans('admin/users/message.user_not_found', compact('id'));
return redirect()->route('users.index')->with('error', $error);
}
// Show the page
return View::make('users/edit', compact('user', 'groups', 'userGroups', 'permissions', 'userPermissions'))
->with('location_list', Helper::locationsList())
->with('company_list', Helper::companyList())
->with('manager_list', Helper::managerList());
return view('users/edit', compact('user', 'groups', 'userGroups', 'permissions', 'userPermissions'))
->with('location_list', Helper::locationsList())
->with('department_list', Helper::departmentList())
->with('company_list', Helper::companyList())
->with('manager_list', Helper::managerList());
}
/**
@@ -329,6 +332,7 @@ class UsersController extends Controller
$user->company_id = Company::getIdForUser($request->input('company_id', null));
$user->manager_id = $request->input('manager_id', null);
$user->notes = $request->input('notes');
$user->department_id = $request->input('department_id', null);
// Strip out the superuser permission if the user isn't a superadmin
$permissions_array = $request->input('permission');
@@ -419,15 +423,16 @@ class UsersController extends Controller
$users = User::whereIn('id', $user_raw_array)->with('groups', 'assets', 'licenses', 'accessories')->get();
if ($request->input('bulk_actions')=='edit') {
return View::make('users/bulk-edit', compact('users'))
return view('users/bulk-edit', compact('users'))
->with('location_list', Helper::locationsList())
->with('company_list', Helper::companyList())
->with('manager_list', Helper::managerList())
->with('manager_list', Helper::managerList())
->with('department_list', Helper::departmentList())
->with('groups', Group::pluck('name', 'id'));
}
return View::make('users/confirm-bulk-delete', compact('users', 'statuslabel_list'));
return view('users/confirm-bulk-delete', compact('users', 'statuslabel_list'));
}
}
@@ -448,12 +453,16 @@ class UsersController extends Controller
$user_raw_array = Input::get('ids');
$update_array = array();
$manager_conflict = false;
$users = User::whereIn('id', $user_raw_array)->where('id','!=',Auth::user()->id)->get();
if ($request->has('location_id')) {
$update_array['location_id'] = $request->input('location_id');
}
if ($request->has('department_id')) {
$update_array['department_id'] = $request->input('department_id');
}
if ($request->has('company_id')) {
$update_array['company_id'] = $request->input('company_id');
}
@@ -464,7 +473,7 @@ class UsersController extends Controller
// edited.
if (!array_key_exists($request->input('manager_id'), $user_raw_array)) {
$update_array['manager_id'] = $request->input('manager_id');
$manager_conflict = false;
} else {
$manager_conflict = true;
}
@@ -636,7 +645,7 @@ class UsersController extends Controller
if (isset($user->id)) {
$this->authorize('view', $user);
return View::make('users/view', compact('user', 'userlog'));
return view('users/view', compact('user', 'userlog'));
}
}
@@ -712,7 +721,7 @@ class UsersController extends Controller
$user->id = null;
// Get this user groups
$userGroups = $user_to_clone->groups()->lists('name', 'id');
$userGroups = $user_to_clone->groups()->pluck('name', 'id');
// Get all the available permissions
$permissions = config('permissions');
$clonedPermissions = $user_to_clone->decodePermissions();
@@ -720,10 +729,11 @@ class UsersController extends Controller
$userPermissions =Helper::selectedPermissionsArray($permissions, $clonedPermissions);
// Show the page
return View::make('users/edit', compact('permissions', 'userPermissions'))
return view('users/edit', compact('permissions', 'userPermissions'))
->with('location_list', Helper::locationsList())
->with('company_list', Helper::companyList())
->with('manager_list', Helper::managerList())
->with('department_list', Helper::departmentList())
->with('user', $user)
->with('groups', Group::pluck('name', 'id'))
->with('userGroups', $userGroups)
@@ -752,7 +762,7 @@ class UsersController extends Controller
$permissions = config('permissions');
$selectedPermissions = Input::old('permissions', array('superuser' => -1));
// Show the page
return View::make('users/import', compact('selectedGroups', 'permissions', 'selectedPermissions'));
return view('users/import', compact('selectedGroups', 'permissions', 'selectedPermissions'));
}
/**
@@ -982,7 +992,7 @@ class UsersController extends Controller
return redirect()->route('users.index')->with('error', $e->getMessage());
}
return View::make('users/ldap')
return view('users/ldap')
->with('location_list', Helper::locationsList());
}
@@ -1087,6 +1097,15 @@ class UsersController extends Controller
$item["ldap_location_override"] = isset($results[$i]["ldap_location_override"]) ? $results[$i]["ldap_location_override"]:"";
$item["location_id"] = isset($results[$i]["location_id"]) ? $results[$i]["location_id"]:"";
if( array_key_exists('useraccountcontrol', $results[$i]) ) {
$enabled_accounts = [
'512', '544', '66048', '66080', '262656', '262688', '328192', '328224'
];
$item['activated'] = ( in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts) ) ? 1 : 0;
} else {
$item['activated'] = 0;
}
// User exists
$item["createorupdate"] = 'updated';
if (!$user = User::where('username', $item["username"])->first()) {
@@ -1096,12 +1115,13 @@ class UsersController extends Controller
}
// Create the user if they don't exist.
$user->first_name = e($item["firstname"]);
$user->last_name = e($item["lastname"]);
$user->username = e($item["username"]);
$user->email = e($item["email"]);
$user->first_name = $item["firstname"];
$user->last_name = $item["lastname"];
$user->username = $item["username"];
$user->email = $item["email"];
$user->employee_num = e($item["employee_number"]);
$user->activated = 1;
$user->activated = $item['activated'];
if ($item['ldap_location_override'] == true) {
$user->location_id = $item['location_id'];
} else if ($request->input('location_id')!='') {
@@ -53,7 +53,7 @@ class ViewAssetsController extends Controller
$userlog = $user->userlog->load('item', 'user', 'target');
if (isset($user->id)) {
return View::make('account/view-assets', compact('user', 'userlog'));
return view('account/view-assets', compact('user', 'userlog'));
} else {
// Prepare the error message
$error = trans('admin/users/message.user_not_found', compact('id'));
@@ -71,13 +71,13 @@ class ViewAssetsController extends Controller
$assets = Asset::with('model', 'defaultLoc', 'assetloc', 'assignedTo')->Hardware()->RequestableAssets()->get();
$models = AssetModel::with('category')->RequestableModels()->get();
return View::make('account/requestable-assets', compact('user', 'assets', 'models'));
return view('account/requestable-assets', compact('user', 'assets', 'models'));
}
public function getRequestedIndex()
{
$requestedItems = CheckoutRequest::with('user', 'requestedItem')->get();
return View::make('admin/requested-assets', compact('requestedItems'));
return view('admin/requested-assets', compact('requestedItems'));
}
@@ -280,7 +280,7 @@ class ViewAssetsController extends Controller
{
$checkoutrequests = CheckoutRequest::all();
return View::make('account/requested-items', compact($checkoutrequests));
return view('account/requested-items', compact($checkoutrequests));
}
@@ -314,7 +314,7 @@ class ViewAssetsController extends Controller
} elseif (!Company::isCurrentUserHasAccess($item)) {
return redirect()->route('requestable-assets')->with('error', trans('general.insufficient_permissions'));
} else {
return View::make('account/accept-asset', compact('item'))->with('findlog', $findlog)->with('item', $item);
return view('account/accept-asset', compact('item'))->with('findlog', $findlog)->with('item', $item);
}
}
+17 -5
View File
@@ -32,22 +32,35 @@ class ItemImportRequest extends FormRequest
public function import(Import $import)
{
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
ini_set('memory_limit', '500M');
$filename = config('app.private_uploads') . '/imports/' . $import->file_path;
$class = title_case($this->input('import-type'));
$import->import_type = $this->input('import-type');
$class = title_case($import->import_type);
$classString = "App\\Importer\\{$class}Importer";
$importer = new $classString($filename);
$import->field_map = request('column-mappings');
$import->save();
$fieldMappings=[];
if ($import->field_map) {
// We submit as csv field: column, but the importer is happier if we flip it here.
$fieldMappings = array_change_key_case(array_flip($import->field_map), CASE_LOWER);
// dd($fieldMappings);
}
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
->setUserId(Auth::id())
->setUpdating($this->has('import-update'))
->setUsernameFormat('firstname.lastname');
->setUsernameFormat('firstname.lastname')
->setFieldMappings($fieldMappings);
// $logFile = storage_path('logs/importer.log');
// \Log::useFiles($logFile);
$importer->import();
return $this->errors;
}
public function log($string)
{
return; // FUTURE IMPLEMENTATION
// \Log::Info($string);
}
public function progress($count)
@@ -58,7 +71,6 @@ class ItemImportRequest extends FormRequest
public function errorCallback($item, $field, $errorString)
{
$this->errors[$item->name][$field] = $errorString;
// $this->errors[$item->name] = $errorString;
}
private $errors;
@@ -23,17 +23,17 @@ class AccessoriesTransformer
$array = [
'id' => $accessory->id,
'name' => e($accessory->name),
'company' => ($accessory->company) ? ['id' => $accessory->company->id,'name'=> e($accessory->company->name)] : '',
'manufacturer' => ($accessory->manufacturer) ? ['id' => $accessory->manufacturer->id,'name'=> e($accessory->manufacturer->name)] : '',
'company' => ($accessory->company) ? ['id' => $accessory->company->id,'name'=> e($accessory->company->name)] : null,
'manufacturer' => ($accessory->manufacturer) ? ['id' => $accessory->manufacturer->id,'name'=> e($accessory->manufacturer->name)] : null,
'model_number' => ($accessory->model_number) ? e($accessory->model_number) : null,
'category' => ($accessory->category) ? ['id' => $accessory->category->id,'name'=> e($accessory->category->name)] : '',
'location' => ($accessory->location) ? ['id' => $accessory->location->id,'name'=> e($accessory->location->name)] : '',
'category' => ($accessory->category) ? ['id' => $accessory->category->id,'name'=> e($accessory->category->name)] : null,
'location' => ($accessory->location) ? ['id' => $accessory->location->id,'name'=> e($accessory->location->name)] : null,
'notes' => ($accessory->notes) ? e($accessory->notes) : null,
'qty' => ($accessory->qty) ? e($accessory->qty) : null,
'qty' => ($accessory->qty) ? (int) $accessory->qty : null,
'purchase_date' => ($accessory->purchase_date) ? Helper::getFormattedDateObject($accessory->purchase_date, 'date') : null,
'purchase_cost' => ($accessory->purchase_cost) ? e($accessory->purchase_cost) : null,
'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null,
'min_qty' => ($accessory->min_amt) ? e($accessory->min_amt) : null,
'min_qty' => ($accessory->min_amt) ? (int) $accessory->min_amt : null,
'remaining_qty' => $accessory->numRemaining(),
'created_at' => Helper::getFormattedDateObject($accessory->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($accessory->updated_at, 'datetime'),
@@ -0,0 +1,68 @@
<?php
namespace App\Http\Transformers;
use App\Models\Actionlog;
use Gate;
use Illuminate\Database\Eloquent\Collection;
use App\Helpers\Helper;
class ActionlogsTransformer
{
public function transformActionlogs (Collection $actionlogs, $total)
{
$array = array();
foreach ($actionlogs as $actionlog) {
$array[] = self::transformActionlog($actionlog);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformActionlog (Actionlog $actionlog)
{
$array = [
'icon' => $actionlog->present()->icon(),
'item' => ($actionlog->item) ? [
'id' => (int) $actionlog->item->id,
'name' => e($actionlog->item->getDisplayNameAttribute()),
'type' => e($actionlog->itemType()),
] : null,
'created_at' => Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($actionlog->updated_at, 'datetime'),
'action_type' => $actionlog->present()->actionType(),
'admin' => ($actionlog->user) ? [
'id' => (int) $actionlog->user->id,
'name' => e($actionlog->user->getFullNameAttribute()),
'first_name'=> e($actionlog->user->first_name),
'last_name'=> e($actionlog->user->last_name)
] : null,
'target' => ($actionlog->target) ? [
'id' => (int) $actionlog->target->id,
'name' => ($actionlog->targetType()=='user') ? e($actionlog->target->getFullNameAttribute()) : e($actionlog->target->getDisplayNameAttribute()),
'type' => e($actionlog->targetType()),
] : null,
'note' => e($actionlog->note),
];
return $array;
}
public function transformCheckedoutActionlog (Collection $accessories_users, $total)
{
$array = array();
foreach ($accessories_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
}
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
use App\Models\AssetModel;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class AssetModelsTransformer
{
@@ -21,23 +22,38 @@ class AssetModelsTransformer
{
$array = [
'id' => $assetmodel->id,
'id' => (int) $assetmodel->id,
'name' => e($assetmodel->name),
'manufacturer' => ($assetmodel->manufacturer_id) ? $assetmodel->manufacturer : null,
'image' => ($assetmodel->image!='') ? url('/').'/uploads/models/'.e($assetmodel->image) : '',
'manufacturer' => ($assetmodel->manufacturer) ? [
'id' => (int) $assetmodel->manufacturer->id,
'name'=> e($assetmodel->manufacturer->name)
] : null,
'image' => ($assetmodel->image!='') ? url('/').'/uploads/models/'.e($assetmodel->image) : null,
'model_number' => e($assetmodel->model_number),
'depreciation' => ($assetmodel->depreciation) ? $assetmodel->depreciation : 'No',
'depreciation' => ($assetmodel->depreciation) ? [
'id' => (int) $assetmodel->depreciation->id,
'name'=> e($assetmodel->depreciation->name)
] : null,
'assets_count' => $assetmodel->assets_count,
'category' => ($assetmodel->category_id) ? $assetmodel->category : null,
'fieldset' => ($assetmodel->fieldset) ? $assetmodel->fieldset : null,
'category' => ($assetmodel->category) ? [
'id' => (int) $assetmodel->category->id,
'name'=> e($assetmodel->category->name)
] : null,
'fieldset' => ($assetmodel->fieldset) ? [
'id' => (int) $assetmodel->fieldset->id,
'name'=> e($assetmodel->fieldset->name)
] : null,
'eol' => ($assetmodel->eol > 0) ? $assetmodel->eol .' months': 'None',
'notes' => e($assetmodel->notes)
'notes' => e($assetmodel->notes),
'created_at' => Helper::getFormattedDateObject($assetmodel->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($assetmodel->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('admin') ? true : false,
'delete' => Gate::allows('admin') ? true : false,
'update' => Gate::allows('update', AssetModel::class) ? true : false,
'delete' => Gate::allows('delete', AssetModel::class) ? true : false,
'clone' => Gate::allows('create', AssetModel::class) ? true : false,
];
$array += $permissions_array;
+39 -9
View File
@@ -43,6 +43,10 @@ class AssetsTransformer
'id' => (int) $asset->model->manufacturer->id,
'name'=> e($asset->model->manufacturer->name)
] : null,
'supplier' => ($asset->supplier) ? [
'id' => (int) $asset->supplier->id,
'name'=> e($asset->supplier->name)
] : null,
'notes' => e($asset->notes),
'order_number' => e($asset->order_number),
'company' => ($asset->company) ? [
@@ -60,9 +64,11 @@ class AssetsTransformer
'image' => ($asset->getImageUrl()) ? $asset->getImageUrl() : null,
'assigned_to' => ($asset->assigneduser) ? [
'id' => (int) $asset->assigneduser->id,
'username' => e($asset->assigneduser->username),
'name' => e($asset->assigneduser->getFullNameAttribute()),
'first_name'=> e($asset->assigneduser->first_name),
'last_name'=> e($asset->assigneduser->last_name)
'last_name'=> e($asset->assigneduser->last_name),
'employee_number' => e($asset->assigneduser->employee_num),
] : null,
'warranty' => ($asset->warranty_months > 0) ? e($asset->warranty_months . ' ' . trans('admin/hardware/form.months')) : null,
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
@@ -75,22 +81,46 @@ class AssetsTransformer
'user_can_checkout' => (bool) $asset->availableForCheckout(),
];
if ($asset->model->fieldset) {
$fields_array = array();
foreach ($asset->model->fieldset->fields as $field) {
if ($field->isFieldDecryptable($asset->{$field->convertUnicodeDbSlug()})) {
$decrypted = \App\Helpers\Helper::gracefulDecrypt($field,$asset->{$field->convertUnicodeDbSlug()});
$value = (Gate::allows('superadmin')) ? $decrypted : strtoupper(trans('admin/custom_fields/general.encrypted'));
// $fields_array = [$field->convertUnicodeDbSlug() => $value];
$fields_array[$field->name] = [
'field' => $field->convertUnicodeDbSlug(),
'value' => $value
];
} else {
$fields_array[$field->name] = [
'field' => $field->convertUnicodeDbSlug(),
'value' => $asset->{$field->convertUnicodeDbSlug()}
];
//$fields_array = [$field->convertUnicodeDbSlug() => $asset->{$field->convertUnicodeDbSlug()}];
}
//array += $fields_array;
$array['custom_fields'] = $fields_array;
}
}
$permissions_array['available_actions'] = [
'checkout' => (bool) Gate::allows('checkout', Asset::class),
'checkin' => (bool) Gate::allows('checkin', Asset::class),
'clone' => Gate::allows('create', Asset::class) ? true : false,
'update' => (bool) Gate::allows('update', Asset::class),
'delete' => (bool) Gate::allows('delete', Asset::class),
];
$array += $permissions_array;
if ($asset->model->fieldset) {
foreach ($asset->model->fieldset->fields as $field) {
$fields_array = [$field->name => $asset->{$field->convertUnicodeDbSlug()}];
$array += $fields_array;
}
}
return $array;
}
@@ -0,0 +1,53 @@
<?php
namespace App\Http\Transformers;
use App\Models\Company;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class CompaniesTransformer
{
public function transformCompanies (Collection $companies, $total)
{
$array = array();
foreach ($companies as $company) {
$array[] = self::transformCompany($company);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformCompany (Company $company = null)
{
if ($company) {
$array = [
'id' => e($company->id),
'name' => e($company->name),
"created_at" => Helper::getFormattedDateObject($company->created_at, 'datetime'),
"updated_at" => Helper::getFormattedDateObject($company->updated_at, 'datetime'),
"assets_count" => (int) $company->assets_count,
"licenses_count" => (int) $company->licenses_count,
"accessories_count" => (int) $company->accessories_count,
"consumables_count" => (int) $company->consumables_count,
"components_count" => (int) $company->components_count,
"users_count" => (int) $company->users_count
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Company::class) ? true : false,
'delete' => Gate::allows('delete', Company::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}
}
@@ -27,8 +27,8 @@ class ComponentsTransformer
'id' => (int) $component->location->id,
'name' => e($component->location->name)
] : null,
'qty' => number_format($component->qty),
'min_amt' => e($component->min_amt),
'qty' => ($component->qty!='') ? (int) $component->qty : null,
'min_amt' => ($component->min_amt!='') ? (int) $component->min_amt : null,
'category' => ($component->category) ? [
'id' => (int) $component->category->id,
'name' => e($component->category->name)
@@ -43,6 +43,7 @@ class ComponentsTransformer
] : null,
'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
'user_can_checkout' => ($component->numRemaining() > 0) ? 1 : 0,
];
$permissions_array['available_actions'] = [
@@ -21,20 +21,20 @@ class ConsumablesTransformer
public function transformConsumable (Consumable $consumable)
{
$array = [
'category' => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => $consumable->category->name] : null,
'company' => ($consumable->company) ? ['id' => $consumable->company->id, 'name' => $consumable->company->name] : null,
'id' => $consumable->id,
'item_no' => $consumable->item_no,
'location' => ($consumable->location) ? ['id' => $consumable->location->id, 'name' => $consumable->location->name] : null,
'manufacturer' => ($consumable->manufacturer) ? ['id' => $consumable->manufacturer->id, 'name' => $consumable->manufacturer->name] : null,
'min_amt' => $consumable->min_amt,
'model_number' => $consumable->model_number,
'name' => $consumable->name,
'id' => (int) $consumable->id,
'category' => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => e($consumable->category->name)] : null,
'company' => ($consumable->company) ? ['id' => (int) $consumable->company->id, 'name' => e($consumable->company->name)] : null,
'item_no' => e($consumable->item_no),
'location' => ($consumable->location) ? ['id' => (int) $consumable->location->id, 'name' => e($consumable->location->name)] : null,
'manufacturer' => ($consumable->manufacturer) ? ['id' => (int) $consumable->manufacturer->id, 'name' => e($consumable->manufacturer->name)] : null,
'min_amt' => (int) $consumable->min_amt,
'model_number' => e($consumable->model_number),
'name' => e($consumable->name),
'remaining' => $consumable->numRemaining(),
'order_number' => $consumable->order_number,
'order_number' => e($consumable->order_number),
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
'purchase_date' => Helper::getFormattedDateObject($consumable->purchase_date, 'date'),
'qty' => $consumable->qty,
'qty' => (int) $consumable->qty,
'created_at' => Helper::getFormattedDateObject($consumable->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($consumable->updated_at, 'datetime'),
];
@@ -0,0 +1,36 @@
<?php
namespace App\Http\Transformers;
use App\Models\CustomField;
use Illuminate\Database\Eloquent\Collection;
use App\Helpers\Helper;
use Gate;
class CustomFieldsTransformer
{
public function transformCustomFields (Collection $fields, $total)
{
$array = array();
foreach ($fields as $field) {
$array[] = self::transformCustomField($field);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformCustomField (CustomField $field)
{
$array = [
'name' => e($field->name),
'db_column_name' => e($field->db_column_name()),
'format' => e($field->format),
'required' => $field->pivot->required,
'created_at' => Helper::getFormattedDateObject($field->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($field->updated_at, 'datetime'),
];
return $array;
}
}
@@ -0,0 +1,47 @@
<?php
namespace App\Http\Transformers;
use App\Models\CustomFieldset;
use App\Models\CustomField;
use App\Models\AssetModel;
use Illuminate\Database\Eloquent\Collection;
use App\Helpers\Helper;
use Gate;
class CustomFieldsetsTransformer
{
public function transformCustomFieldsets (Collection $fieldsets, $total)
{
$array = array();
foreach ($fieldsets as $fieldset) {
$array[] = self::transformCustomFieldset($fieldset);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformCustomFieldset (CustomFieldset $fieldset)
{
$fields = $fieldset->fields;
$models = $fieldset->models;
$modelsArray = array();
foreach ($models as $model)
{
$modelsArray[] = [
'id' => $model->id,
'name' => e($model->name)
];
}
$array = [
'id' => (int) $fieldset->id,
'name' => e($fieldset->name),
'fields' => (new CustomFieldsTransformer)->transformCustomFields($fields, $fieldset->fields_count),
'models' => (new DatatablesTransformer)->transformDatatables($modelsArray, $fieldset->models_count),
'created_at' => Helper::getFormattedDateObject($fieldset->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($fieldset->updated_at, 'datetime'),
];
return $array;
}
}
@@ -0,0 +1,62 @@
<?php
namespace App\Http\Transformers;
use App\Models\Department;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class DepartmentsTransformer
{
public function transformDepartments (Collection $departments, $total)
{
$array = array();
foreach ($departments as $department) {
$array[] = self::transformDepartment($department);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformDepartment (Department $department = null)
{
if ($department) {
$array = [
'id' => (int) $department->id,
'name' => e($department->name),
'company' => ($department->company) ? [
'id' => (int) $department->company->id,
'name'=> e($department->company->name)
] : null,
'manager' => ($department->manager) ? [
'id' => (int) $department->manager->id,
'name' => e($department->manager->getFullNameAttribute()),
'first_name'=> e($department->manager->first_name),
'last_name'=> e($department->manager->last_name)
] : null,
'location' => ($department->location) ? [
'id' => (int) $department->location->id,
'name' => e($department->location->name)
] : null,
'users_count' => e($department->users_count),
'created_at' => Helper::getFormattedDateObject($department->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($department->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Department::class) ? true : false,
'delete' => Gate::allows('delete', Department::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}
}
@@ -21,7 +21,7 @@ class DepreciationsTransformer
public function transformDepreciation (Depreciation $depreciation)
{
$array = [
'id' => e($depreciation->id),
'id' => (int) $depreciation->id,
'name' => e($depreciation->name),
'months' => $depreciation->months . ' '. trans('general.months'),
'created_at' => Helper::getFormattedDateObject($depreciation->created_at, 'datetime'),
+3 -2
View File
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
use App\Models\Group;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class GroupsTransformer
{
@@ -20,10 +21,10 @@ class GroupsTransformer
public function transformGroup (Group $group)
{
$array = [
'id' => e($group->id),
'id' => (int) $group->id,
'name' => e($group->name),
'permissions' => $group->permissions,
'users_count' => $group->users_count,
'users_count' => (int) $group->users_count,
'created_at' => Helper::getFormattedDateObject($group->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($group->updated_at, 'datetime'),
];
+7 -4
View File
@@ -20,12 +20,15 @@ class ImportsTransformer
public function transformImport(Import $import)
{
$array = [
'id' => $import->id,
'file_path' => $import->file_path,
'id' => (int) $import->id,
'file_path' => e($import->file_path),
'filesize' => Setting::fileSizeConvert($import->filesize),
'name' => $import->name,
'import_type' => $import->import_type,
'name' => e($import->name),
'import_type' => e($import->import_type),
'created_at' => $import->created_at->diffForHumans(),
'header_row' => $import->header_row,
'first_row' => $import->first_row,
'field_map' => $import->field_map,
];
@@ -21,32 +21,34 @@ class LicensesTransformer
public function transformLicense (License $license)
{
$array = [
'id' => $license->id,
'id' => (int) $license->id,
'name' => e($license->name),
'company' => ($license->company) ? ['id' => $license->company->id,'name'=> e($license->company->name)] : null,
'manufacturer' => ($license->manufacturer) ? ['id' => $license->manufacturer->id,'name'=> e($license->manufacturer->name)] : null,
'company' => ($license->company) ? ['id' => (int) $license->company->id,'name'=> e($license->company->name)] : null,
'manufacturer' => ($license->manufacturer) ? ['id' => (int) $license->manufacturer->id,'name'=> e($license->manufacturer->name)] : null,
'product_key' => e($license->serial),
'order_number' => e($license->order_number),
'purchase_order' => e($license->purchase_order),
'purchase_date' => Helper::getFormattedDateObject($license->purchase_date, 'date'),
'purchase_cost' => e($license->purchase_cost),
'depreciation' => ($license->depreciation) ? ['id' => $license->depreciation->id,'name'=> e($license->depreciation->name)] : null,
'depreciation' => ($license->depreciation) ? ['id' => (int) $license->depreciation->id,'name'=> e($license->depreciation->name)] : null,
'notes' => e($license->notes),
'expiration_date' => Helper::getFormattedDateObject($license->expiration_date, 'date'),
'total_seats' => e($license->seats),
'total_seats' => (int) $license->total_seats,
'remaining_qty' => $license->remaincount(),
'min_qty' => $license->remaincount(),
'license_name' => e($license->license_name),
'license_email' => e($license->license_email),
'maintained' => ($license->maintained == 1) ? true : false,
'supplier' => ($license->supplier) ? ['id' => $license->supplier->id,'name'=> e($license->supplier->name)] : null,
'supplier' => ($license->supplier) ? ['id' => (int) $license->supplier->id,'name'=> e($license->supplier->name)] : null,
'created_at' => Helper::getFormattedDateObject($license->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
'user_can_checkout' => (bool) ($license->remaincount() > 0),
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', License::class) ? true : false,
'checkin' => Gate::allows('checkin', License::class) ? true : false,
'clone' => Gate::allows('create', License::class) ? true : false,
'update' => Gate::allows('update', License::class) ? true : false,
'delete' => Gate::allows('delete', License::class) ? true : false,
];
@@ -26,9 +26,14 @@ class LocationsTransformer
foreach($location->assets() as $asset) {
$assets_arr = ['id' => $asset->id];
}
$children_arr = [];
foreach($location->childLocations() as $child) {
$children_arr = ['id' => $child->id];
}
$array = [
'id' => e($location->id),
'id' => (int) $location->id,
'name' => e($location->name),
'address' => e($location->address),
'city' => e($location->city),
@@ -39,6 +44,8 @@ class LocationsTransformer
'assets' => $assets_arr,
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),
'parent_id' => ($location->parent_id) ? (int) $location->parent_id : null,
'children' => $children_arr,
];
$permissions_array['available_actions'] = [
@@ -23,16 +23,16 @@ class ManufacturersTransformer
if ($manufacturer) {
$array = [
'id' => e($manufacturer->id),
'id' => (int) $manufacturer->id,
'name' => e($manufacturer->name),
'url' => e($manufacturer->url),
'support_url' => e($manufacturer->support_url),
'support_phone' => e($manufacturer->support_phone),
'support_email' => e($manufacturer->support_email),
'assets_count' => e($manufacturer->assets_count),
'licenses_count' => e($manufacturer->licenses_count),
'consumables_count' => e($manufacturer->consumables_count),
'accessories_count' => e($manufacturer->accessories_count),
'assets_count' => (int) $manufacturer->assets_count,
'licenses_count' => (int) $manufacturer->licenses_count,
'consumables_count' => (int) $manufacturer->consumables_count,
'accessories_count' => (int) $manufacturer->accessories_count,
'created_at' => Helper::getFormattedDateObject($manufacturer->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($manufacturer->updated_at, 'datetime'),
];
@@ -21,7 +21,7 @@ class StatuslabelsTransformer
public function transformStatuslabel (Statuslabel $statuslabel)
{
$array = [
'id' => e($statuslabel->id),
'id' => (int) $statuslabel->id,
'name' => e($statuslabel->name),
'type' => $statuslabel->getStatuslabelType(),
'color' => ($statuslabel->color) ? e($statuslabel->color) : null,
@@ -0,0 +1,60 @@
<?php
namespace App\Http\Transformers;
use App\Models\Supplier;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class SuppliersTransformer
{
public function transformSuppliers (Collection $suppliers, $total)
{
$array = array();
foreach ($suppliers as $supplier) {
$array[] = self::transformSupplier($supplier);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformSupplier (Supplier $supplier = null)
{
if ($supplier) {
$array = [
'id' => (int) $supplier->id,
'name' => e($supplier->name),
'address' => ($supplier->address) ? e($supplier->address) : null,
'address2' => ($supplier->address2) ? e($supplier->address2) : null,
'city' => ($supplier->city) ? e($supplier->city) : null,
'state' => ($supplier->state) ? e($supplier->state) : null,
'country' => ($supplier->country) ? e($supplier->country) : null,
'fax' => ($supplier->fax) ? e($supplier->fax) : null,
'phone' => ($supplier->phone) ? e($supplier->phone) : null,
'email' => ($supplier->email) ? e($supplier->email) : null,
'contact' => ($supplier->contact) ? e($supplier->contact) : null,
'assets_count' => (int) $supplier->assets_count,
'licenses_count' => (int) $supplier->licenses_count,
'image' => ($supplier->image) ? e($supplier->image) : null,
'created_at' => Helper::getFormattedDateObject($supplier->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($supplier->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Supplier::class) ? true : false,
'delete' => Gate::allows('delete', Supplier::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}
}
+26 -11
View File
@@ -22,25 +22,39 @@ class UsersTransformer
public function transformUser (User $user)
{
$array = [
'id' => e($user->id),
'id' => (int) $user->id,
'name' => e($user->first_name).' '.($user->last_name),
'firstname' => e($user->first_name),
'lastname' => e($user->last_name),
'username' => e($user->username),
'employee_num' => e($user->employee_num),
'manager' => ($user->manager) ? (new UsersTransformer)->transformUser($user->manager) : '',
'groups' => $user->groups,
'jobtitle' => e($user->jobtitle),
'manager' => ($user->manager) ? [
'id' => (int) $user->manager->id,
'name'=> e($user->manager->username)
] : null,
'groups' => ($user->groups) ? [
'id' => (int) $user->userloc->id,
'name'=> e($user->userloc->name)
] : null,
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
'email' => e($user->email),
'location' => (new LocationsTransformer)->transformLocation($user->userloc),
'department' => ($user->department) ? [
'id' => (int) $user->department->id,
'name'=> e($user->department->name)
] : null,
'location' => ($user->userloc) ? [
'id' => (int) $user->userloc->id,
'name'=> e($user->userloc->name)
] : null,
'permissions' => $user->decodePermissions(),
'activated' => ($user->activated =='1') ? true : false,
'two_factor_activated' => ($user->activated =='1') ? true : false,
'assets_count' => $user->assets_count,
'licenses_count' => $user->licenses_count,
'accessories_count' => $user->accessories_count,
'consumables_count' => $user->consumables_count,
'company' => ($user->company) ? ['id' => $user->company->id,'name'=> e($user->company->name)] : null,
'two_factor_activated' => ($user->two_factor_active()) ? true : false,
'assets_count' => (int) $user->assets_count,
'licenses_count' => (int) $user->licenses_count,
'accessories_count' => (int) $user->accessories_count,
'consumables_count' => (int) $user->consumables_count,
'company' => ($user->company) ? ['id' => (int) $user->company->id,'name'=> e($user->company->name)] : null,
'created_at' => Helper::getFormattedDateObject($user->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($user->updated_at, 'datetime'),
'last_login' => Helper::getFormattedDateObject($user->last_login, 'datetime'),
@@ -49,6 +63,7 @@ class UsersTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', User::class) ? true : false,
'delete' => Gate::allows('delete', User::class) ? true : false,
'clone' => Gate::allows('create', User::class) ? true : false,
];
$array += $permissions_array;
+5 -17
View File
@@ -7,11 +7,9 @@ use App\Models\Accessory;
class AccessoryImporter extends ItemImporter
{
protected $accessories;
public function __construct($filename)
{
parent::__construct($filename);
$this->accessories = Accessory::all();
}
protected function handle($row)
@@ -28,36 +26,26 @@ class AccessoryImporter extends ItemImporter
*/
public function createAccessoryIfNotExists()
{
$accessoryId = $this->accessories->search(function ($key) {
return strcasecmp($key->name, $this->item['name']) == 0;
});
if ($accessoryId !== false) {
$accessory = Accessory::where('name', $this->item['name'])->first();
if ($accessory) {
if (!$this->updating) {
$this->log('A matching Accessory ' . $this->item["name"] . ' already exists. ');
return;
}
$this->log('Updating Accessory');
$accessory = $this->accessories[$accessoryId];
$accessory->update($this->sanitizeItemForUpdating($accessory));
if (!$this->testRun) {
$accessory->save();
}
$accessory->save();
return;
}
$this->log("No Matching Accessory, Creating a new one");
$accessory = new Accessory();
$accessory->fill($this->sanitizeItemForStoring($accessory));
if ($this->testRun) {
$this->log('TEST RUN - Accessory ' . $this->item["name"] . ' not created');
return;
}
if ($accessory->save()) {
$accessory->logCreate('Imported using CSV Importer');
$this->log('Accessory ' . $this->item["name"] . ' was created');
return;
}
$this->jsonError($accessory, 'Accessory');
$this->logError($accessory, 'Accessory');
}
}
+19 -24
View File
@@ -24,8 +24,10 @@ class AssetImporter extends ItemImporter
parent::handle($row);
foreach ($this->customFields as $customField) {
if ($this->item['custom_fields'][$customField->db_column_name()] = $this->array_smart_custom_field_fetch($row, $customField)) {
$this->log('Custom Field '. $customField->name.': '.$this->array_smart_custom_field_fetch($row, $customField));
$customFieldValue = $this->array_smart_custom_field_fetch($row, $customField);
if ($customFieldValue) {
$this->item['custom_fields'][$customField->db_column_name()] = $customFieldValue;
$this->log('Custom Field '. $customField->name.': '.$customFieldValue);
}
}
@@ -43,10 +45,11 @@ class AssetImporter extends ItemImporter
public function createAssetIfNotExists(array $row)
{
$editingAsset = false;
$asset = Asset::where(['asset_tag'=> $this->item['asset_tag']])->first();
$asset_tag = $this->findCsvMatch($row, "asset_tag");
$asset = Asset::where(['asset_tag'=> $asset_tag])->first();
if ($asset) {
if (!$this->updating) {
$this->log('A matching Asset ' . $this->item['asset_tag'] . ' already exists');
$this->log('A matching Asset ' . $asset_tag . ' already exists');
return;
}
@@ -56,24 +59,19 @@ class AssetImporter extends ItemImporter
$this->log("No Matching Asset, Creating a new one");
$asset = new Asset;
}
$this->item['serial'] = $this->array_smart_fetch($row, "serial number");
$this->item['image'] = $this->array_smart_fetch($row, "image");
$this->item['warranty_months'] = intval($this->array_smart_fetch($row, "warranty months"));
if ($this->item['asset_model'] = $this->createOrFetchAssetModel($row)) {
$this->item['model_id'] = $this->item['asset_model']->id;
}
if (isset($this->item["status_label"])) {
$this->item['status_id'] = $this->item["status_label"]->id;
} elseif (!$editingAsset) {
// Assume if we are editing, we already have a status and can ignore.
$this->item['image'] = $this->findCsvMatch($row, "image");
$this->item['warranty_months'] = intval($this->findCsvMatch($row, "warranty"));
$this->item['model_id'] = $this->createOrFetchAssetModel($row);
if (!$this->item['status_id'] && !$editingAsset) {
$this->log("No status field found, defaulting to first status.");
$this->item['status_id'] = $this->defaultStatusLabelId;
}
$this->item['asset_tag'] = $asset_tag;
// By default we're set this to location_id in the item.
$item = $this->sanitizeItemForStoring($asset, $editingAsset);
if (isset($this->item["location"])) {
if (isset($this->item["location_id"])) {
$item['rtd_location_id'] = $this->item['location_id'];
unset($item['location_id']);
}
@@ -87,14 +85,11 @@ class AssetImporter extends ItemImporter
$asset->{$custom_field} = $val;
}
}
if (!$this->testRun) {
if ($asset->save()) {
$asset->logCreate('Imported using csv importer');
$this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
return;
}
$this->jsonError($asset, 'Asset "' . $this->item['name'].'"');
if ($asset->save()) {
$asset->logCreate('Imported using csv importer');
$this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
return;
}
$this->logError($asset, 'Asset "' . $this->item['name'].'"');
}
}
+4 -15
View File
@@ -7,11 +7,9 @@ use App\Models\Component;
class ComponentImporter extends ItemImporter
{
protected $components;
public function __construct($filename)
{
parent::__construct($filename);
$this->components = Component::all();
}
protected function handle($row)
@@ -31,11 +29,9 @@ class ComponentImporter extends ItemImporter
$component = null;
$editingComponent = false;
$this->log("Creating Component");
$componentId = $this->components->search(function ($key) {
return strcasecmp($key->name, $this->item['name']) == 0;
});
$component = Component::where('name', $this->item['name']);
if ($componentId !== false) {
if ($component) {
$editingComponent = true;
$this->log('A matching Component ' . $this->item["name"] . ' already exists. ');
if (!$this->updating) {
@@ -45,20 +41,13 @@ class ComponentImporter extends ItemImporter
$this->log("Updating Component");
$component = $this->components[$componentId];
$component->update($this->sanitizeItemFor($component));
if (!$this->testRun) {
$component->save();
}
$component->save();
return;
}
$this->log("No matching component, creating one");
$component = new Component;
$component->fill($$this->sanitizeItemForStoring($component));
if ($this->testRun) {
$this->log('TEST RUN - Component ' . $this->item["name"] . ' not created');
return;
}
if ($component->save()) {
$component->logCreate('Imported using CSV Importer');
$this->log("Component " . $this->item["name"] . ' was created');
@@ -75,6 +64,6 @@ class ComponentImporter extends ItemImporter
}
return;
}
$this->jsonError($component, 'Component');
$this->logError($component, 'Component');
}
}
+4 -16
View File
@@ -7,11 +7,9 @@ use App\Models\Consumable;
class ConsumableImporter extends ItemImporter
{
protected $consumables;
public function __construct($filename)
{
parent::__construct($filename);
$this->consumables = Consumable::all();
}
protected function handle($row)
@@ -28,36 +26,26 @@ class ConsumableImporter extends ItemImporter
*/
public function createConsumableIfNotExists()
{
$consumableId = $this->consumables->search(function ($key) {
return strcasecmp($key->name, $this->item['name']) == 0;
});
if ($consumableId !== false) {
$consumable = Consumable::where('name', $this->item['name'])->first();
if ($consumable) {
if (!$this->updating) {
$this->log('A matching Consumable ' . $this->item["name"] . ' already exists. ');
return;
}
$this->log('Updating Consumable');
$consumable = $this->consumables[$consumableId];
$consumable->update($this->sanitizeItemForUpdating($consumable));
if (!$this->testRun) {
$consumable->save();
}
$consumable->save();
return;
}
$this->log("No matching consumable, creating one");
$consumable = new Consumable();
$consumable->fill($this->sanitizeItemForStoring($consumable));
if ($this->testRun) {
$this->log('TEST RUN - Consumable ' . $this->item['name'] . ' not created');
return;
}
if ($consumable->save()) {
$consumable->logCreate('Imported using CSV Importer');
$this->log("Consumable " . $this->item["name"] . ' was created');
return;
}
$this->jsonError($consumable, 'Consumable');
$this->logError($consumable, 'Consumable');
return;
}
}
+128 -76
View File
@@ -1,7 +1,6 @@
<?php
namespace App\Importer;
use App\Models\CustomField;
use App\Models\Setting;
use App\Models\User;
@@ -13,16 +12,7 @@ use League\Csv\Reader;
abstract class Importer
{
/**
* @var string
*/
private $filename;
private $csv;
/**
* Should we persist to database?
* @var bool
*/
protected $testRun;
protected $csv;
/**
* Id of User performing import
* @var
@@ -33,6 +23,47 @@ abstract class Importer
* @var bool
*/
protected $updating;
/**
* Default Map of item fields->csv names
* @var array
*/
private $defaultFieldMap = [
'asset_tag' => 'asset tag',
'category' => 'category',
'company' => 'company',
'item_name' => 'item name',
'image' => 'image',
'expiration_date' => 'expiration date',
'location' => 'location',
'notes' => 'notes',
'license_email' => 'licensed to email',
'license_name' => "licensed to name",
'maintained' => 'maintained',
'manufacturer' => 'manufacturer',
'asset_model' => "model name",
'model_number' => 'model number',
'order_number' => 'order number',
'purchase_cost' => 'purchase cost',
'purchase_date' => 'purchase date',
'purchase_order' => 'purchase order',
'qty' => 'quantity',
'reassignable' => 'reassignable',
'requestable' => 'requestable',
'seats' => 'seats',
'serial_number' => 'serial number',
'status' => 'status',
'supplier' => 'supplier',
'termination_date' => 'termination date',
'warranty_months' => 'warranty',
'name' => 'name',
'email' => 'email',
'username' => 'username'
];
/**
* Map of item fields->csv names
* @var array
*/
protected $fieldMap = [];
/**
* @var callable
*/
@@ -53,13 +84,18 @@ abstract class Importer
/**
* ObjectImporter constructor.
* @param string $filename
* @param string $file
*/
public function __construct(string $filename)
public function __construct($file)
{
$this->filename = $filename;
$this->csv = Reader::createFromPath($filename);
$this->fieldMap = $this->defaultFieldMap;
// By default the importer passes a url to the file.
// However, for testing we also support passing a string directly
if (is_file($file)) {
$this->csv = Reader::createFromPath($file);
} else {
$this->csv = Reader::createFromString($file);
}
$this->csv->setNewLine('\r\n');
if (! ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1');
@@ -71,6 +107,7 @@ abstract class Importer
public function import()
{
$headerRow = $this->csv->fetchOne();
$results = $this->normalizeInputArray($this->csv->fetchAssoc());
$this->customFields = CustomField::All(['name']);
DB::transaction(function () use (&$results) {
@@ -78,7 +115,9 @@ abstract class Importer
$resultsCount = sizeof($results);
foreach ($results as $row) {
$this->handle($row);
call_user_func($this->progressCallback, $resultsCount);
if ($this->progressCallback) {
call_user_func($this->progressCallback, $resultsCount);
}
$this->log('------------- Action Summary ----------------');
}
@@ -87,20 +126,6 @@ abstract class Importer
abstract protected function handle($row);
/**
* @param $results
* @return array
*/
public function normalizeInputArray($results): array
{
$newArray = [];
foreach ($results as $index => $arrayToNormalize) {
$newArray[$index] = array_change_key_case($arrayToNormalize);
}
return $newArray;
}
/**
* Check to see if the given key exists in the array, and trim excess white space before returning it
*
@@ -111,17 +136,54 @@ abstract class Importer
* @param $default string
* @return string
*/
public function array_smart_fetch(array $array, $key, $default = '')
public function findCsvMatch(array $array, $key, $default = '')
{
$val = $default;
if (array_key_exists(trim($key), $array)) {
if ($customKey = $this->lookupCustomKey($key)) {
$key = $customKey;
}
$this->log("Custom Key: ${key}");
if (array_key_exists($key, $array)) {
$val = e(Encoding::toUTF8(trim($array[ $key ])));
}
$key = title_case($key);
// $this->log("${key}: ${val}");
return $val;
}
/**
* Looks up A custom key in the custom field map
*
* @author Daniel Melzter
* @since 4.0
* @param $key string
* @return string|null
*/
public function lookupCustomKey($key)
{
// dd($this->fieldMap);
if (array_key_exists($key, $this->fieldMap)) {
$this->log("Found a match in our custom map: {$key} is " . $this->fieldMap[$key]);
return $this->fieldMap[$key];
}
return null;
}
/**
* @param $results
* @return array
*/
public function normalizeInputArray($results)
{
$newArray = [];
foreach ($results as $index => $arrayToNormalize) {
$newArray[$index] = array_change_key_case($arrayToNormalize);
}
return $newArray;
}
/**
* Figure out the fieldname of the custom field
*
@@ -133,17 +195,21 @@ abstract class Importer
public function array_smart_custom_field_fetch(array $array, $key)
{
$index_name = strtolower($key->name);
return array_key_exists($index_name, $array) ? e(trim($array[$index_name])) : '';
return array_key_exists($index_name, $array) ? e(trim($array[$index_name])) : false;
}
protected function log($string)
{
call_user_func($this->logCallback, $string);
if ($this->logCallback) {
call_user_func($this->logCallback, $string);
}
}
protected function jsonError($item, $field)
protected function logError($item, $field)
{
call_user_func($this->errorCallback, $item, $field, $item->getErrors());
if ($this->errorCallback) {
call_user_func($this->errorCallback, $item, $field, $item->getErrors());
}
}
/**
@@ -160,9 +226,9 @@ abstract class Importer
*/
protected function createOrFetchUser($row)
{
$user_name = $this->array_smart_fetch($row, "name");
$user_email = $this->array_smart_fetch($row, "email");
$user_username = $this->array_smart_fetch($row, "username");
$user_name = $this->findCsvMatch($row, "name");
$user_email = $this->findCsvMatch($row, "email");
$user_username = $this->findCsvMatch($row, "username");
$first_name = '';
$last_name = '';
// A number was given instead of a name
@@ -171,6 +237,7 @@ abstract class Importer
$user_username = '';
// No name was given
} elseif (empty($user_name)) {
$this->log('No user data provided - skipping user creation, just adding asset');
//$user_username = '';
} else {
@@ -193,12 +260,10 @@ abstract class Importer
}
}
}
$user = new User;
if ($this->testRun) {
return $user;
}
if (!empty($user_username)) {
if ($user = User::MatchEmailOrUsername($user_username, $user_email)
->whereNotNull('username')->first()) {
$this->log('User '.$user_username.' already exists');
@@ -214,43 +279,13 @@ abstract class Importer
if ($user->save()) {
$this->log('User '.$first_name.' created');
} else {
$this->jsonError($user, 'User "' . $first_name . '"');
$this->logError($user, 'User "' . $first_name . '"');
}
}
}
return $user;
}
/**
* Sets the value of filename.
*
* @param string $filename the filename
*
* @return self
*/
public function setFilename($filename)
{
$this->filename = $filename;
return $this;
}
/**
* Sets the Should we persist to database?.
*
* @param bool $testRun the test run
*
* @return self
*/
public function setTestRun($testRun)
{
$this->testRun = $testRun;
return $this;
}
/**
* Sets the Id of User performing import.
*
@@ -279,6 +314,23 @@ abstract class Importer
return $this;
}
/**
* Defines mappings of csv fields
*
* @param bool $updating the updating
*
* @return self
*/
public function setFieldMappings($fields)
{
// Some initial sanitization.
$fields = array_map('strtolower', $fields);
$this->fieldMap = array_merge($this->defaultFieldMap, $fields);
// $this->log($this->fieldMap);
return $this;
}
/**
* Sets the callbacks for the import
*
+85 -112
View File
@@ -2,6 +2,7 @@
namespace App\Importer;
use App\Importer\UserImporter;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
@@ -20,59 +21,53 @@ class ItemImporter extends Importer
protected function handle($row)
{
// TODO: CHeck if this interferes with checkout to user.. it shouldn't..
$this->item["user_id"] = $this->user_id;
$item_category = $this->array_smart_fetch($row, "category");
$item_company_name = $this->array_smart_fetch($row, "company");
$item_location = $this->array_smart_fetch($row, "location");
$item_manufacturer = $this->array_smart_fetch($row, "manufacturer");
$item_status_name = $this->array_smart_fetch($row, "status");
$item_supplier = $this->array_smart_fetch($row, "supplier");
$this->item["name"] = $this->array_smart_fetch($row, "item name");
$this->item["purchase_date"] = null;
if ($this->array_smart_fetch($row, "purchase date")!='') {
$this->item["purchase_date"] = date("Y-m-d 00:00:01", strtotime($this->array_smart_fetch($row, "purchase date")));
}
$this->item["purchase_cost"] = $this->array_smart_fetch($row, "purchase cost");
$this->item["order_number"] = $this->array_smart_fetch($row, "order number");
$this->item["notes"] = $this->array_smart_fetch($row, "notes");
$this->item["qty"] = $this->array_smart_fetch($row, "quantity");
$this->item["requestable"] = $this->array_smart_fetch($row, "requestable");
$this->item["asset_tag"] = $this->array_smart_fetch($row, "asset tag");
if ($this->item["user"] = $this->createOrFetchUser($row)) {
$this->item['assigned_to'] = $this->item['user']->id;
}
if ($this->shouldUpdateField($item_location)) {
if ($this->item["location"] = $this->createOrFetchLocation($item_location)) {
$this->item["location_id"] = $this->item["location"]->id;
}
}
$item_category = $this->findCsvMatch($row, "category");
if ($this->shouldUpdateField($item_category)) {
if ($this->item["category"] = $this->createOrFetchCategory($item_category)) {
$this->item["category_id"] = $this->item["category"]->id;
}
}
if ($this->shouldUpdateField($item_manufacturer)) {
if ($this->item["manufacturer"] = $this->createOrFetchManufacturer($item_manufacturer)) {
$this->item["manufacturer_id"] = $this->item["manufacturer"]->id;
}
$this->item["category_id"] = $this->createOrFetchCategory($item_category);
}
$item_company_name = $this->findCsvMatch($row, "company");
if ($this->shouldUpdateField($item_company_name)) {
if ($this->item["company"] = $this->createOrFetchCompany($item_company_name)) {
$this->item["company_id"] = $this->item["company"]->id;
}
$this->item["company_id"] = $this->createOrFetchCompany($item_company_name);
}
$item_location = $this->findCsvMatch($row, "location");
if ($this->shouldUpdateField($item_location)) {
$this->item["location_id"] = $this->createOrFetchLocation($item_location);
}
$item_manufacturer = $this->findCsvMatch($row, "manufacturer");
if ($this->shouldUpdateField($item_manufacturer)) {
$this->item["manufacturer_id"] = $this->createOrFetchManufacturer($item_manufacturer);
}
$item_status_name = $this->findCsvMatch($row, "status");
if ($this->shouldUpdateField($item_status_name)) {
if ($this->item["status_label"] = $this->createOrFetchStatusLabel($item_status_name)) {
$this->item["status_label_id"] = $this->item["status_label"]->id;
}
$this->item["status_id"] = $this->createOrFetchStatusLabel($item_status_name);
}
$item_supplier = $this->findCsvMatch($row, "supplier");
if ($this->shouldUpdateField($item_supplier)) {
if ($this->item['supplier'] = $this->createOrFetchSupplier($item_supplier)) {
$this->item['supplier_id'] = $this->item['supplier']->id;
$this->item['supplier_id'] = $this->createOrFetchSupplier($item_supplier);
}
$this->item["name"] = $this->findCsvMatch($row, "item_name");
$this->item["notes"] = $this->findCsvMatch($row, "notes");
$this->item["order_number"] = $this->findCsvMatch($row, "order_number");
$this->item["purchase_cost"] = $this->findCsvMatch($row, "purchase_cost");
$this->item["purchase_date"] = null;
if ($this->findCsvMatch($row, "purchase_date")!='') {
$this->item["purchase_date"] = date("Y-m-d 00:00:01", strtotime($this->findCsvMatch($row, "purchase_date")));
}
$this->item["qty"] = $this->findCsvMatch($row, "quantity");
$this->item["requestable"] = $this->findCsvMatch($row, "requestable");
$this->item["user_id"] = $this->user_id;
$this->item['serial'] = $this->findCsvMatch($row, "serial_number");
// NO need to call this method if we're running the user import.
// TODO: Merge these methods.
if(get_class($this) !== UserImporter::class) {
if ($this->item["user"] = $this->createOrFetchUser($row)) {
$this->item['assigned_to'] = $this->item['user']->id;
}
}
}
@@ -94,8 +89,8 @@ class ItemImporter extends Importer
// Create a collection for all manipulations to come.
$item = collect($this->item);
// First Filter the item down to the model's fillable fields
$item = $item->only($model->getFillable());
// Then iterate through the item and, if we are updating, remove any blank values.
if ($updating) {
$item = $item->reject(function ($value) {
@@ -108,8 +103,8 @@ class ItemImporter extends Importer
/**
* Convenience function for updating that strips the empty values.
*
*
* @param $model SnipeModel Model that's being updated.
* @return array
*/
protected function sanitizeItemForUpdating($model)
{
@@ -142,13 +137,14 @@ class ItemImporter extends Importer
* @param array
* @param $category Category
* @param $manufacturer Manufacturer
* @return AssetModel
* @return int Id of asset model created/found
* @internal param $asset_modelno string
*/
public function createOrFetchAssetModel(array $row)
{
$asset_model_name = $this->array_smart_fetch($row, "model name");
$asset_modelNumber = $this->array_smart_fetch($row, "model number");
$asset_model_name = $this->findCsvMatch($row, "asset_model");
$asset_modelNumber = $this->findCsvMatch($row, "model_number");
// TODO: At the moment, this means we can't update the model number if the model name stays the same.
if (!$this->shouldUpdateField($asset_model_name)) {
return;
@@ -162,20 +158,18 @@ class ItemImporter extends Importer
$asset_model = AssetModel::where(['name' => $asset_model_name, 'model_number' => $asset_modelNumber])->first();
if ($asset_model) {
if (!$this->updating) {
$this->log("A matching model already exists, returning it.");
return $asset_model;
return $asset_model->id;
}
$this->log("Matching Model found, updating it.");
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
$item['name'] = $asset_model_name;
$item['model_number'] = $asset_modelNumber;
$asset_model->update($item);
if (!$this->testRun) {
$asset_model->save();
}
return $asset_model;
$asset_model->save();
$this->log("Asset Model Updated");
return $asset_model->id;
}
$this->log("No Matching Model, Creating a new one");
@@ -185,18 +179,14 @@ class ItemImporter extends Importer
$item['model_number'] = $asset_modelNumber;
$asset_model->fill($item);
if ($this->testRun) {
$this->log('TEST RUN - asset_model ' . $asset_model->name . ' not created');
return $asset_model;
}
$item = null;
if ($asset_model->save()) {
$this->log('Asset Model ' . $asset_model_name . ' with model number ' . $asset_modelNumber . ' was created');
return $asset_model;
return $asset_model->id;
}
$this->jsonError($asset_model, 'Asset Model "' . $asset_model_name . '"');
return;
$this->logError($asset_model, 'Asset Model "' . $asset_model_name . '"');
return null;
}
/**
@@ -205,7 +195,7 @@ class ItemImporter extends Importer
* @author Daniel Melzter
* @since 3.0
* @param $asset_category string
* @return Category
* @return int Id of category created/found
* @internal param string $item_type
*/
public function createOrFetchCategory($asset_category)
@@ -213,6 +203,7 @@ class ItemImporter extends Importer
// Magic to transform "AssetImporter" to "asset" or similar.
$classname = class_basename(get_class($this));
$item_type = strtolower(substr($classname, 0, strpos($classname, 'Importer')));
if (empty($asset_category)) {
$asset_category = 'Unnamed Category';
}
@@ -220,7 +211,7 @@ class ItemImporter extends Importer
if ($category) {
$this->log("A matching category: " . $asset_category . " already exists");
return $category;
return $category->id;
}
$category = new Category();
@@ -228,15 +219,13 @@ class ItemImporter extends Importer
$category->category_type = $item_type;
$category->user_id = $this->user_id;
if ($this->testRun) {
return $category;
}
if ($category->save()) {
$this->log('Category ' . $asset_category . ' was created');
return $category;
return $category->id;
}
$this->jsonError($category, 'Category "'. $asset_category. '"');
$this->logError($category, 'Category "'. $asset_category. '"');
return null;
}
/**
@@ -245,28 +234,24 @@ class ItemImporter extends Importer
* @author Daniel Melzter
* @since 3.0
* @param $asset_company_name string
* @return Company
* @return int id of company created/found
*/
public function createOrFetchCompany($asset_company_name)
{
$company = Company::where(['name' => $asset_company_name])->first();
if ($company) {
$this->log('A matching Company ' . $asset_company_name . ' already exists');
return $company;
return $company->id;
}
$company = new Company();
$company->name = $asset_company_name;
if ($this->testRun) {
return $company;
}
if ($company->save()) {
$this->log('Company ' . $asset_company_name . ' was created');
return $company;
return $company->id;
}
$this->jsonError($company, 'Company');
return;
$this->logError($company, 'Company');
return null;
}
/**
@@ -279,6 +264,7 @@ class ItemImporter extends Importer
*/
public function createOrFetchStatusLabel($asset_statuslabel_name)
{
if (empty($asset_statuslabel_name)) {
return null;
}
@@ -286,7 +272,7 @@ class ItemImporter extends Importer
if ($status) {
$this->log('A matching Status ' . $asset_statuslabel_name . ' already exists');
return $status;
return $status->id;
}
$this->log("Creating a new status");
$status = new Statuslabel();
@@ -296,17 +282,13 @@ class ItemImporter extends Importer
$status->pending = 0;
$status->archived = 0;
if ($this->testRun) {
return $status;
}
if ($status->save()) {
$this->log('Status ' . $asset_statuslabel_name . ' was created');
return $status;
return $status->id;
}
$this->jsonError($status, 'Status "'. $asset_statuslabel_name . '"');
return;
$this->logError($status, 'Status "'. $asset_statuslabel_name . '"');
return null;
}
/**
@@ -328,7 +310,7 @@ class ItemImporter extends Importer
if ($manufacturer) {
$this->log('Manufacturer ' . $item_manufacturer . ' already exists') ;
return $manufacturer;
return $manufacturer->id;
}
//Otherwise create a manufacturer.
@@ -336,15 +318,12 @@ class ItemImporter extends Importer
$manufacturer->name = $item_manufacturer;
$manufacturer->user_id = $this->user_id;
if ($this->testRun) {
return $manufacturer;
}
if ($manufacturer->save()) {
$this->log('Manufacturer ' . $manufacturer->name . ' was created');
return $manufacturer;
return $manufacturer->id;
}
$this->jsonError($manufacturer, 'Manufacturer "'. $manufacturer->name . '"');
return;
$this->logError($manufacturer, 'Manufacturer "'. $manufacturer->name . '"');
return null;
}
/**
@@ -363,9 +342,9 @@ class ItemImporter extends Importer
}
$location = Location::where(['name' => $asset_location])->first();
if ($location !== false) {
if ($location) {
$this->log('Location ' . $asset_location . ' already exists');
return $location;
return $location->id;
}
// No matching locations in the collection, create a new one.
$location = new Location();
@@ -376,15 +355,12 @@ class ItemImporter extends Importer
$location->country = '';
$location->user_id = $this->user_id;
if ($this->testRun) {
return $location;
}
if ($location->save()) {
$this->log('Location ' . $asset_location . ' was created');
return $location;
return $location->id;
}
$this->jsonError($location, 'Location');
return;
$this->logError($location, 'Location');
return null;
}
/**
@@ -405,21 +381,18 @@ class ItemImporter extends Importer
if ($supplier) {
$this->log('Supplier ' . $item_supplier . ' already exists');
return $supplier;
return $supplier->id;
}
$supplier = new Supplier();
$supplier->name = $item_supplier;
$supplier->user_id = $this->user_id;
if ($this->testRun) {
return $supplier;
}
if ($supplier->save()) {
$this->log('Supplier ' . $item_supplier . ' was created');
return $supplier;
return $supplier->id;
}
$this->jsonError($supplier, 'Supplier');
return;
$this->logError($supplier, 'Supplier');
return null;
}
}
+29 -42
View File
@@ -10,18 +10,15 @@ use App\Models\Manufacturer;
class LicenseImporter extends ItemImporter
{
protected $licenses;
public function __construct($filename)
{
parent::__construct($filename);
$this->licenses = License::all();
}
protected function handle($row)
{
// ItemImporter handles the general fetching.
parent::handle($row);
$this->createLicenseIfNotExists($row);
}
@@ -36,11 +33,8 @@ class LicenseImporter extends ItemImporter
public function createLicenseIfNotExists(array $row)
{
$editingLicense = false;
$license = new License;
$license_id = $this->licenses->search(function ($key) {
return strcasecmp($key->name, $this->item['name']) == 0;
});
if ($license_id !== false) {
$license = License::where('name', $this->item['name'])->first();
if ($license) {
if (!$this->updating) {
$this->log('A matching License ' . $this->item['name'] . ' already exists');
return;
@@ -48,54 +42,47 @@ class LicenseImporter extends ItemImporter
$this->log("Updating License");
$editingLicense = true;
$license = $this->licenses[$license_id];
} else {
$this->log("No Matching License, Creating a new one");
$license = new License;
}
$asset_tag = $this->item['asset_tag'] = $this->array_smart_fetch($row, 'asset_tag'); // used for checkout out to an asset.
$this->item['expiration_date'] = $this->array_smart_fetch($row, 'expiration date');
$this->item['license_email'] = $this->array_smart_fetch($row, "licensed to email");
$this->item['license_name'] = $this->array_smart_fetch($row, "licensed to name");
$this->item['maintained'] = $this->array_smart_fetch($row, 'maintained');
$this->item['purchase_order'] = $this->array_smart_fetch($row, 'purchase_order');
$this->item['reassignable'] = $this->array_smart_fetch($row, 'reassignable');
$this->item['serial'] = $this->array_smart_fetch($row, "serial number");
$this->item['termination_date'] = $this->array_smart_fetch($row, 'termination_date');
$this->item['seats'] = $this->array_smart_fetch($row, 'seats');
$asset_tag = $this->item['asset_tag'] = $this->findCsvMatch($row, 'asset_tag'); // used for checkout out to an asset.
$this->item['expiration_date'] = $this->findCsvMatch($row, 'expiration_date');
$this->item['license_email'] = $this->findCsvMatch($row, "license_email");
$this->item['license_name'] = $this->findCsvMatch($row, "license_name");
$this->item['maintained'] = $this->findCsvMatch($row, 'maintained');
$this->item['purchase_order'] = $this->findCsvMatch($row, 'purchase_order');
$this->item['reassignable'] = $this->findCsvMatch($row, 'reassignable');
$this->item['seats'] = $this->findCsvMatch($row, 'seats');
$this->item['termination_date'] = $this->findCsvMatch($row, 'termination_date');
if ($editingLicense) {
$license->update($this->sanitizeItemForUpdating($license));
} else {
$license->fill($this->sanitizeItemForStoring($license));
}
if (!$editingLicense) {
$this->licenses->add($license);
}
if (!$this->testRun) {
if ($license->save()) {
$license->logCreate('Imported using csv importer');
$this->log('License ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
if ($license->save()) {
$license->logCreate('Imported using csv importer');
$this->log('License ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
// Lets try to checkout seats if the fields exist and we have seats.
if ($license->seats > 0) {
$user = $this->item['user'];
$asset = Asset::where('asset_tag', $asset_tag)->first();
$targetLicense = $license->licenseSeats()->first();
if ($user) {
$targetLicense->assigned_to = $user->id;
if ($asset) {
$targetLicense->asset_id = $asset->id;
}
$targetLicense->save();
} elseif ($asset) {
// Lets try to checkout seats if the fields exist and we have seats.
if ($license->seats > 0) {
$user = $this->item['user'];
$asset = Asset::where('asset_tag', $asset_tag)->first();
$targetLicense = $license->licenseSeats()->first();
if ($user) {
$targetLicense->assigned_to = $user->id;
if ($asset) {
$targetLicense->asset_id = $asset->id;
$targetLicense->save();
}
$targetLicense->save();
} elseif ($asset) {
$targetLicense->asset_id = $asset->id;
$targetLicense->save();
}
return;
}
$this->jsonError($license, 'License "' . $this->item['name'].'"');
return;
}
$this->logError($license, 'License "' . $this->item['name'].'"');
}
}
+67
View File
@@ -0,0 +1,67 @@
<?php
namespace App\Importer;
use App\Helpers\Helper;
use App\Models\User;
class UserImporter extends ItemImporter
{
protected $users;
public function __construct($filename)
{
parent::__construct($filename);
// $this->users = User::all();
}
protected function handle($row)
{
parent::handle($row);
$this->createUserIfNotExists($row);
}
/**
* Create a user if a duplicate does not exist.
* @todo Investigate how this should interact with Importer::createOrFetchUser
*
* @author Daniel Melzter
* @since 4.0
*/
public function createUserIfNotExists(array $row)
{
// User Specific Bits
$this->item['username'] = $this->findCsvMatch($row, 'username');
$this->item['first_name'] = $this->findCsvMatch($row, 'first_name');
$this->item['last_name'] = $this->findCsvMatch($row, 'last_name');
$this->item['email'] = $this->findCsvMatch($row, 'user_email');
$this->item['phone'] = $this->findCsvMatch($row, 'phone_number');
$this->item['jobtitle'] = $this->findCsvMatch($row, 'jobtitle');
$this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num');
$this->item['password'] = $this->tempPassword;
$user = User::where('username', $this->item['username'])->first();
if ($user) {
if (!$this->updating) {
$this->log('A matching User ' . $this->item["name"] . ' already exists. ');
return;
}
$this->log('Updating User');
// $user = $this->users[$userId];
$user->update($this->sanitizeItemForUpdating($user));
$user->save();
return;
}
$this->log("No matching user, creating one");
$user = new User();
$user->fill($this->sanitizeItemForStoring($user));
if ($user->save()) {
// $user->logCreate('Imported using CSV Importer');
$this->log("User " . $this->item["name"] . ' was created');
$user = null;
$this->item = null;
return;
}
$this->logError($user, 'User');
return;
}
}
+33
View File
@@ -0,0 +1,33 @@
| CSV | Item | Applicable Types |
|---------------------|------------------|-------------------------------------------|
| asset tag | asset_tag | Asset |
| category | category | All |
| company | company | All |
| item name | item_name | All |
| image | image | asset |
| expiration date | expiration_date | License |
| location | location | All |
| notes | notes | All |
| licensed to email | license_email | License |
| licensed to name | license_name | License |
| maintained | maintained | License |
| manufacturer | manufacturer | All |
| model name | asset_model | Asset |
| model number | model_number | Asset |
| order number | order_number | All ? |
| purchase cost | purchase_cost | All ? |
| purchase date | purchase_date | All ? |
| purchase order | purchase_order | License |
| quantity | qty | Accessory, Consumable, Component, License |
| reassignable | reassignable | License |
| requestable | requestable | Asset, Accessory? |
| seats | seats | License |
| serial number | serial | asset, license |
| status | status | asset ? All |
| supplier | supplier | Asset ? All |
| termination date | termination_date | License |
| warranty months | warranty_months | asset |
| User Related Fields | assigned_to | Asset |
| name | | |
| email | | |
| username | | |
+14 -7
View File
@@ -17,8 +17,11 @@ class Accessory extends SnipeModel
use Loggable, Presentable;
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $dates = ['deleted_at', 'purchase_date'];
protected $table = 'accessories';
protected $casts = [
'requestable' => 'boolean'
];
/**
* Accessory validation rules
@@ -28,7 +31,7 @@ class Accessory extends SnipeModel
'qty' => 'required|integer|min:1',
'category_id' => 'required|integer|exists:categories,id',
'company_id' => 'integer|nullable',
'min_amt' => 'integer|min:0',
'min_amt' => 'integer|min:0|nullable',
'purchase_cost' => 'numeric|nullable',
);
@@ -61,6 +64,15 @@ class Accessory extends SnipeModel
'requestable'
];
public function setRequestableAttribute($value)
{
if ($value == '') {
$value = null;
}
$this->attributes['requestable'] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
return;
}
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
@@ -152,11 +164,6 @@ class Accessory extends SnipeModel
$query->whereHas('company', function ($query) use ($search) {
$query->where('companies.name', 'LIKE', '%'.$search.'%');
});
})->orWhere(function ($query) use ($search) {
$query->whereHas('assetlog', function ($query) use ($search) {
$query->where('action_type', '=', 'checkout')
->where('created_at', 'LIKE', '%'.$search.'%');
});
})->orWhere(function ($query) use ($search) {
$query->whereHas('location', function ($query) use ($search) {
$query->where('locations.name', 'LIKE', '%'.$search.'%');
+8 -17
View File
@@ -60,6 +60,14 @@ class Actionlog extends SnipeModel
return camel_case(class_basename($this->item_type));
}
public function targetType()
{
if ($this->target_type == User::class) {
return "user";
}
return camel_case(class_basename($this->target_type));
}
public function parseItemRoute()
{
if ($this->itemType() == "asset") {
@@ -80,24 +88,7 @@ class Actionlog extends SnipeModel
}
public function parseItemIcon()
{
if ($this->itemType() == "asset") {
$itemicon = 'fa fa-barcode';
} elseif ($this->itemType() == "accessory") {
$itemicon = 'fa fa-keyboard-o';
} elseif ($this->itemType()=="consumable") {
$itemicon = 'fa fa-tint';
} elseif ($this->itemType()=="license") {
$itemicon = 'fa fa-floppy-o';
} elseif ($this->itemType()=="component") {
$itemicon = 'fa fa-hdd-o';
} else {
$itemicon = 'fa fa-paperclip';
}
return $itemicon;
}
public function uploads()
{
+62 -10
View File
@@ -139,6 +139,7 @@ class Asset extends Depreciable
* @param null $name
* @return bool
*/
//FIXME: The admin parameter is never used. Can probably be removed.
public function checkOut($target, $admin, $checkout_at = null, $expected_checkin = null, $note = null, $name = null)
{
if (!$target) {
@@ -163,7 +164,7 @@ class Asset extends Depreciable
}
if ($this->save()) {
$log = $this->logCheckout($note);
$this->logCheckout($note, $target);
// if ((($this->requireAcceptance()=='1') || ($this->getEula())) && ($user->email!='')) {
// $this->checkOutNotifyMail($log->id, $user, $checkout_at, $expected_checkin, $note);
// }
@@ -272,15 +273,15 @@ class Asset extends Depreciable
**/
public function assetLoc()
{
if ($this->assignedTo) {
return $this->assignedTo->userLoc();
}
if (!empty($this->assignedType())) {
if ($this->assignedType() == self::ASSET) {
return $this->assignedTo->assetloc(); // Recurse until we have a final location
} elseif ($this->assignedType() == self::LOCATION) {
return $this->assignedTo();
} elseif (!$this->assignedTo) {
return $this->defaultLoc();
} elseif ($this->assignedType() == self::USER) {
return $this->assignedTo->userLoc();
}
}
return $this->defaultLoc();
@@ -427,6 +428,7 @@ class Asset extends Depreciable
{
$settings = \App\Models\Setting::getSettings();
if ($settings->auto_increment_assets == '1') {
$temp_asset_tag = \DB::table('assets')
->where('physical', '=', '1')
@@ -436,14 +438,43 @@ class Asset extends Depreciable
$asset_tag = preg_replace('/^0*/', '', $asset_tag_digits);
if ($settings->zerofill_count > 0) {
return $settings->auto_increment_prefix.Asset::zerofill(($asset_tag + 1), $settings->zerofill_count);
return $settings->auto_increment_prefix.Asset::zerofill($settings->next_auto_tag_base, $settings->zerofill_count);
}
return $settings->auto_increment_prefix.($asset_tag + 1);
return $settings->auto_increment_prefix.$settings->next_auto_tag_base;
} else {
return false;
}
}
/*
* Get the next base number for the auto-incrementer. We'll add the zerofill and
* prefixes on the fly as we generate the number
*
*/
public static function nextAutoIncrement($assets)
{
$max = 1;
foreach ($assets as $asset) {
$results = preg_match ( "/\d+$/" , $asset['asset_tag'], $matches);
if ($results)
{
$number = $matches[0];
if ($number > $max)
{
$max = $number;
}
}
}
return $max + 1;
}
public static function zerofill($num, $zerofill = 3)
{
@@ -689,9 +720,9 @@ class Asset extends Depreciable
/**
* Query builder scope to get accepted assets
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param \Illuminate\Database\Query\Builder $query Query builder instance
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeAccepted($query)
{
@@ -727,10 +758,15 @@ class Asset extends Depreciable
$query->where('manufacturers.name', 'LIKE', '%'.$search.'%');
});
});
})->orWhere(function ($query) use ($search) {
$query->whereHas('assetstatus', function ($query) use ($search) {
$query->where('status_labels.name', 'LIKE', '%'.$search.'%');
});
})->orWhere(function ($query) use ($search) {
$query->whereHas('supplier', function ($query) use ($search) {
$query->where('suppliers.name', 'LIKE', '%'.$search.'%');
});
})->orWhere(function ($query) use ($search) {
$query->whereHas('company', function ($query) use ($search) {
$query->where('companies.name', 'LIKE', '%'.$search.'%');
@@ -937,7 +973,7 @@ class Asset extends Depreciable
return $query->join('status_labels', 'assets.status_id', '=', 'status_labels.id')->orderBy('status_labels.name', $order);
}
/**
/**
* Query builder scope to order on company
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
@@ -1025,6 +1061,20 @@ class Asset extends Depreciable
return $query->join('locations', 'locations.id', '=', 'assets.rtd_location_id')->orderBy('locations.name', $order);
}
/**
* Query builder scope to order on supplier name
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderSupplier($query, $order)
{
return $query->leftJoin('suppliers', 'assets.supplier_id', '=', 'suppliers.id')->orderBy('suppliers.name', $order);
}
/**
* Query builder scope to search on location ID
*
@@ -1047,4 +1097,6 @@ class Asset extends Depreciable
});
});
}
}
+1 -1
View File
@@ -55,7 +55,7 @@ class AssetModel extends SnipeModel
*
* @var array
*/
protected $fillable = ['name','manufacturer_id','category_id','eol', 'user_id'];
protected $fillable = ['name','manufacturer_id','category_id','eol', 'user_id', 'fieldset_id'];
public function assets()
{
+11
View File
@@ -14,6 +14,9 @@ class Consumable extends SnipeModel
protected $dates = ['deleted_at'];
protected $table = 'consumables';
protected $casts = [
'requestable' => 'boolean'
];
/**
@@ -56,6 +59,14 @@ class Consumable extends SnipeModel
'requestable'
];
public function setRequestableAttribute($value)
{
if ($value == '') {
$value = null;
}
$this->attributes['requestable'] = filter_var($value, FILTER_VALIDATE_BOOLEAN);
return;
}
public function admin()
{
+2 -1
View File
@@ -101,7 +101,8 @@ class CustomField extends Model
public function db_column_name()
{
return self::convertUnicodeDbSlug();
return $this->db_column;
// return self::convertUnicodeDbSlug();
}
//mutators for 'format' attribute
+12
View File
@@ -3,6 +3,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Gate;
use Watson\Validating\ValidatingTrait;
class CustomFieldset extends Model
{
@@ -12,6 +13,17 @@ class CustomFieldset extends Model
"name" => "required|unique:custom_fieldsets"
];
/**
* Whether the model should inject it's identifier to the unique
* validation rules before attempting validation. If this property
* is not set in the model it will default to true.
*
* @var boolean
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;
public function fields()
{
return $this->belongsToMany('\App\Models\CustomField')->withPivot(["required","order"])->orderBy("pivot_order");
+97
View File
@@ -0,0 +1,97 @@
<?php
namespace App\Models;
use App\Http\Traits\UniqueUndeletedTrait;
use Illuminate\Database\Eloquent\Model;
use Log;
use Watson\Validating\ValidatingTrait;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\SnipeModel;
use App\Models\User;
class Department extends SnipeModel
{
/**
* Whether the model should inject it's identifier to the unique
* validation rules before attempting validation. If this property
* is not set in the model it will default to true.
*
* @var boolean
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait, UniqueUndeletedTrait;
protected $rules = [
'name' => 'required|max:255',
'user_id' => 'required',
'location_id' => 'numeric|nullable',
'company_id' => 'numeric|nullable',
'manager_id' => 'numeric|nullable',
];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'user_id',
'name',
'location_id',
'company_id',
'manager_id',
'notes',
];
public function company()
{
return $this->belongsTo('\App\Models\Company', 'company_id');
}
/**
* Even though we allow allow for checkout to things beyond users
* this method is an easy way of seeing if we are checked out to a user.
* @return mixed
*/
public function users()
{
return $this->hasMany('\App\Models\User', 'department_id');
}
/**
* Return the manager in charge of the dept
* @return mixed
*/
public function manager()
{
return $this->belongsTo('\App\Models\User', 'manager_id');
}
public function location()
{
return $this->belongsTo('\App\Models\Location', 'location_id');
}
/**
* Query builder scope to search on text
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $search Search term
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeTextsearch($query, $search)
{
return $query->where('name', 'LIKE', "%$search%")
->orWhere('notes', 'LIKE', "%$search%");
}
}
+5
View File
@@ -6,4 +6,9 @@ use Illuminate\Database\Eloquent\Model;
class Import extends Model
{
protected $casts = [
'header_row' => 'array',
'first_row' => 'array',
'field_map' => 'json'
];
}
+1 -1
View File
@@ -43,7 +43,7 @@ class Location extends SnipeModel
*
* @var array
*/
protected $fillable = ['name'];
protected $fillable = ['name','parent_id','address','address2','city','state', 'country','zip','ldap_ou'];
protected $hidden = ['user_id'];
public function users()
+11 -6
View File
@@ -45,12 +45,17 @@ trait Loggable
$log->user_id = Auth::user()->id;
// @FIXME This needs to be generalized with new asset checkout.
if (!is_null($this->asset_id) || isset($target)) {
$log->target_type = Asset::class;
$log->target_id = $this->asset_id;
} elseif (!is_null($this->assigned_to)) {
$log->target_type = User::class;
$log->target_id = $this->assigned_to;
if(isset($target)) {
$log->target_type = get_class($target);
$log->target_id = $target->id;
} else {
if (!is_null($this->asset_id)) {
$log->target_type = Asset::class;
$log->target_id = $this->asset_id;
} elseif (!is_null($this->assigned_to)) {
$log->target_type = User::class;
$log->target_id = $this->assigned_to;
}
}
$item = call_user_func(array($log->target_type, 'find'), $log->target_id);
+6 -4
View File
@@ -14,14 +14,14 @@ class Setting extends Model
protected $rules = [
"brand" => 'required|min:1|numeric',
"qr_text" => 'min:1|max:31',
"qr_text" => 'max:31',
"logo_img" => 'mimes:jpeg,bmp,png,gif',
"alert_email" => 'email_array',
"slack_endpoint" => 'url',
"default_currency" => 'required',
"locale" => 'required',
"slack_channel" => 'regex:/(?<!\w)#\w+/',
"slack_botname" => 'string',
"slack_endpoint" => 'url|required_with:slack_channel',
"slack_channel" => 'regex:/(?<!\w)#\w+/|required_with:slack_endpoint',
"slack_botname" => 'string|nullable',
'labels_per_page' => 'numeric',
'labels_width' => 'numeric',
'labels_height' => 'numeric',
@@ -39,9 +39,11 @@ class Setting extends Model
"ldap_basedn" => 'sometimes|required_if:ldap_enabled,1',
"ldap_filter" => 'sometimes|required_if:ldap_enabled,1',
"ldap_username_field" => 'sometimes|required_if:ldap_enabled,1',
"ldap_fname_field" => 'sometimes|required_if:ldap_enabled,1',
"ldap_lname_field" => 'sometimes|required_if:ldap_enabled,1',
"ldap_auth_filter_query" => 'sometimes|required_if:ldap_enabled,1',
"ldap_version" => 'sometimes|required_if:ldap_enabled,1',
"thumbnail_max_h" => 'numeric|max:500|min:25',
];
protected $fillable = ['site_name','email_domain','email_format','username_format'];
+59 -4
View File
@@ -21,10 +21,22 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
use Notifiable;
use Presentable;
protected $dates = ['deleted_at'];
protected $hidden = ['password'];
protected $hidden = ['password','remember_token','permissions','reset_password_code','persist_code'];
protected $table = 'users';
protected $injectUniqueIdentifier = true;
protected $fillable = ['first_name', 'last_name', 'email','password','username'];
protected $fillable = [
'email',
'last_name',
'company_id',
'department_id',
'employee_num',
'jobtitle',
'location_id',
'password',
'phone_number',
'username',
'first_name',
];
protected $casts = [
'activated' => 'boolean',
@@ -38,7 +50,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
protected $rules = [
'first_name' => 'required|string|min:1',
'username' => 'required|string|min:2|unique_undeleted',
'username' => 'required|string|min:1|unique_undeleted',
'email' => 'email',
'password' => 'required|min:6',
'locale' => 'max:10'
@@ -106,6 +118,11 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
return $this->belongsTo('\App\Models\Company', 'company_id');
}
public function department()
{
return $this->belongsTo('\App\Models\Department', 'department_id');
}
public function isActivated()
{
return $this->activated ==1;
@@ -300,7 +317,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
// There is a last name given
} else {
$last_name = str_replace($first_name, '', $users_name);
$last_name = str_replace($first_name . ' ', '', $users_name);
if ($format=='filastname') {
$email_last_name.=str_replace(' ', '', $last_name);
@@ -328,6 +345,25 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
}
/**
* Check whether two-factor authorization is required and the user has activated it
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
*
* @return bool
*/
public function two_factor_active () {
if (Setting::getSettings()->two_factor_enabled !='0') {
if (($this->two_factor_optin =='1') && ($this->two_factor_enrolled)) {
return true;
}
}
return false;
}
public function decodePermissions()
{
@@ -358,6 +394,11 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
$query->where('locations.name', 'LIKE', '%'.$search.'%');
});
})
->orWhere(function ($query) use ($search) {
$query->whereHas('department', function ($query) use ($search) {
$query->where('departments.name', 'LIKE', '%'.$search.'%');
});
})
->orWhere(function ($query) use ($search) {
$query->whereHas('groups', function ($query) use ($search) {
$query->where('groups.name', 'LIKE', '%'.$search.'%');
@@ -413,4 +454,18 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
{
return $query->leftJoin('locations', 'users.location_id', '=', 'locations.id')->orderBy('locations.name', $order);
}
/**
* Query builder scope to order on department
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderDepartment($query, $order)
{
return $query->leftJoin('departments', 'users.department_id', '=', 'departments.id')->orderBy('departments.name', $order);
}
}
+67
View File
@@ -0,0 +1,67 @@
<?php
namespace App\Observers;
use App\Models\Accessory;
use App\Models\Setting;
use App\Models\Actionlog;
use Auth;
class AccessoryObserver
{
/**
* Listen to the User created event.
*
* @param Accessory $accessory
* @return void
*/
public function updated(Accessory $accessory)
{
$logAction = new Actionlog();
$logAction->item_type = Accessory::class;
$logAction->item_id = $accessory->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('update');
}
/**
* Listen to the Accessory created event, and increment
* the next_auto_tag_base value in the settings table when i
* a new accessory is created.
*
* @param Accessory $accessory
* @return void
*/
public function created(Accessory $accessory)
{
$settings = Setting::first();
$settings->increment('next_auto_tag_base');
$logAction = new Actionlog();
$logAction->item_type = Accessory::class;
$logAction->item_id = $accessory->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('create');
}
/**
* Listen to the Accessory deleting event.
*
* @param Accessory $accessory
* @return void
*/
public function deleting(Accessory $accessory)
{
$logAction = new Actionlog();
$logAction->item_type = Accessory::class;
$logAction->item_id = $accessory->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('delete');
}
}
+73
View File
@@ -0,0 +1,73 @@
<?php
namespace App\Observers;
use App\Models\Asset;
use App\Models\Setting;
use App\Models\Actionlog;
use Auth;
class AssetObserver
{
/**
* Listen to the User created event.
*
* @param Asset $asset
* @return void
*/
public function updating(Asset $asset)
{
if (($asset->getAttributes()['assigned_to'] == $asset->getOriginal()['assigned_to'])
&& ($asset->getAttributes()['last_checkout'] == $asset->getOriginal()['last_checkout'])
&& ($asset->getAttributes()['status_id'] == $asset->getOriginal()['status_id']))
{
$logAction = new Actionlog();
$logAction->item_type = Asset::class;
$logAction->item_id = $asset->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('update');
}
}
/**
* Listen to the Asset created event, and increment
* the next_auto_tag_base value in the settings table when i
* a new asset is created.
*
* @param Asset $asset
* @return void
*/
public function created(Asset $asset)
{
$settings = Setting::first();
$settings->increment('next_auto_tag_base');
$logAction = new Actionlog();
$logAction->item_type = Asset::class;
$logAction->item_id = $asset->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('create');
}
/**
* Listen to the Asset deleting event.
*
* @param Asset $asset
* @return void
*/
public function deleting(Asset $asset)
{
$logAction = new Actionlog();
$logAction->item_type = Asset::class;
$logAction->item_id = $asset->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('delete');
}
}
+67
View File
@@ -0,0 +1,67 @@
<?php
namespace App\Observers;
use App\Models\Component;
use App\Models\Setting;
use App\Models\Actionlog;
use Auth;
class ComponentObserver
{
/**
* Listen to the User created event.
*
* @param Component $component
* @return void
*/
public function updated(Component $component)
{
$logAction = new Actionlog();
$logAction->item_type = Component::class;
$logAction->item_id = $component->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('update');
}
/**
* Listen to the Component created event, and increment
* the next_auto_tag_base value in the settings table when i
* a new component is created.
*
* @param Component $component
* @return void
*/
public function created(Component $component)
{
$settings = Setting::first();
$settings->increment('next_auto_tag_base');
$logAction = new Actionlog();
$logAction->item_type = Component::class;
$logAction->item_id = $component->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('create');
}
/**
* Listen to the Component deleting event.
*
* @param Component $component
* @return void
*/
public function deleting(Component $component)
{
$logAction = new Actionlog();
$logAction->item_type = Component::class;
$logAction->item_id = $component->id;
$logAction->created_at = date("Y-m-d H:i:s");
$logAction->user_id = Auth::id();
$logAction->logaction('delete');
}
}

Some files were not shown because too many files have changed in this diff Show More