Compare commits

...

520 Commits

Author SHA1 Message Date
snipe
a7132fcdd7 Updated translation strings 2017-04-06 21:36:33 -07:00
snipe
7305169b79 Removed extra comments 2017-04-06 21:18:42 -07:00
snipe
dcd8e800b1 Moved statuslabels API for route priority 2017-04-06 21:18:35 -07:00
snipe
9c637ba62c Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-04-06 21:03:47 -07:00
snipe
ef42bcc223 Update Crowdin configuration file 2017-04-06 20:59:24 -07:00
snipe
120c08b3a3 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-04-06 20:08:52 -07:00
snipe
e32d2f98b5 Added nameUrl presenters (for now) 2017-04-06 20:08:47 -07:00
snipe
aa354e883e Removed erroneous comments 2017-04-06 20:08:38 -07:00
itsupportcmsukorg
89ba221765 fix upload hour so it's 24hr instead of always AM (#3480)
correct an error where logUpload was trying to save 12-hr time to a 24-hr field, e.g. 15:00 (3pm) was becoming 3:00 (3am)
2017-04-06 19:48:15 -07:00
snipe
c7acbc0eee Stunning hook 2017-04-06 19:45:47 -07:00
snipe
961c019554 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-03-31 15:48:49 -07:00
snipe
b2e122c1e9 Add @HinchK as a contributor 2017-03-31 15:46:42 -07:00
Kasey
5663429280 applying PR #3456 changes to develop branch (#3472)
* updating with changes made to master

apply PR # 3456 to develop as well

* updating develop with changes made to master

apply PR # 3456 to develop as well

* updating paveit with passport-created oauth tables
2017-03-31 15:43:37 -07:00
Daniel Meltzer
1bb89db451 A few fixes (#3437)
* This method was renamed, so we need to rename the eager load

* Readd tinker to the composer dev packages.

* Update sql dump for functional tests.
2017-03-31 13:48:31 -07:00
Andrea Bergamasco
7ee172888d /api_tests: Completed tests for basic CRUD for Assets and Components (#3426)
* Refactored AssetsTransformer

Casted all ids to int, escaped all text values,

* Added warranty_expires attribute to Asset model

$asset->warranty_expires contains a Carbon object with the warranty
expiration date. Returns null when either purchase_date or
warranty_months are not set.

* Ignoring php-cs cache files

* Restored asset tests expectations

Work in progress - tests still fail

* API controller refactoring, fixed HTTP status codes in responses

* Restored $request->get - debugging

* Added further checks in ApiAssetsCest::updateAssetWithPatch

* /api_tests: Fixed bugs in update() method + code formatting

* /api_tests: Minor code formatting

* /api_tests: Mirrored test code for PATCH and PUT methods

* Removed repeated code

* Test cleanup

* Fixed issues with update() through PATCH and PUT methods

* Added API test suite to .travis.yml
2017-03-31 13:48:11 -07:00
snipe
45ac1de6bb Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-03-14 16:21:49 -07:00
snipe
f45a3fedca Remove circle-ci config 2017-03-14 16:21:37 -07:00
Andrea Bergamasco
99cc8293ef Fixed undefined metod in unit/PermissionTest (#3422)
* Refactored AssetsTransformer

Casted all ids to int, escaped all text values,

* Added warranty_expires attribute to Asset model

$asset->warranty_expires contains a Carbon object with the warranty
expiration date. Returns null when either purchase_date or
warranty_months are not set.

* Ignoring php-cs cache files

* Restored asset tests expectations

Work in progress - tests still fail

* API controller refactoring, fixed HTTP status codes in responses

* Restored $request->get - debugging

* Added further checks in ApiAssetsCest::updateAssetWithPatch

* Fixed undefined method

* Fixed initial underscore trimmed by str_slug

* CustomFieldTest now works where intl PHP extension is not installed

If a server doesn't have the intl php extension installed, the custom fields tests failed. Now the tests perform the same check done in the CustomField class.
2017-03-14 08:39:03 -07:00
Andrea Bergamasco
e03ebc3fd0 AssetTransformer refactoring, restored tests (#3407)
* Refactored AssetsTransformer

Casted all ids to int, escaped all text values,

* Added warranty_expires attribute to Asset model

$asset->warranty_expires contains a Carbon object with the warranty
expiration date. Returns null when either purchase_date or
warranty_months are not set.

* Ignoring php-cs cache files

* Restored asset tests expectations

Work in progress - tests still fail

* API controller refactoring, fixed HTTP status codes in responses

* Restored $request->get - debugging

* Added further checks in ApiAssetsCest::updateAssetWithPatch
2017-03-14 08:37:39 -07:00
snipe
0469a44582 Bumped codeception version to fix travis breakage
Tests are still failing, but for the right reasons now
2017-03-11 17:12:21 -08:00
snipe
6f269e18fe Remove useless validation for custom CSS 2017-03-11 15:34:54 -08:00
snipe
c5dd33f213 Switch to post 2017-03-11 15:25:19 -08:00
snipe
c8c5c05351 Added asset checkin/checkout API methods 2017-03-11 14:04:52 -08:00
snipe
c3cc2c924f Updated route for asset display 2017-03-11 12:14:41 -08:00
snipe
70761b8157 Status label view 2017-03-11 12:14:19 -08:00
snipe
8dbd9fb299 Added additional permissions for checkin/checkout buttons 2017-03-11 12:14:10 -08:00
snipe
00aa06882c Fixed incorrect route for components 2017-03-11 12:13:35 -08:00
snipe
e475ccc1d4 Use new presenter for colum headers 2017-03-11 12:13:14 -08:00
snipe
542adfa926 Updated sidenav to use proper status labels 2017-03-11 12:12:10 -08:00
snipe
36ad82a041 Updated todo for user_can_checkout 2017-03-11 12:11:39 -08:00
snipe
79197a719e Fixes BS tables for items that don’t have a checkin 2017-03-11 12:11:24 -08:00
snipe
742e3d044e API improvements
Components still need some work here
2017-03-11 10:05:50 -08:00
snipe
a4697f046e Some model/manufacturer cleanup 2017-03-11 08:53:02 -08:00
snipe
2c3b9426fe Update @uberbrady as a contributor 2017-03-11 08:21:37 -08:00
snipe
ae6828a0fa Removed dumb code comment 2017-03-11 08:03:30 -08:00
snipe
2a4bf65883 Basic sanity checking on some of the API controllers 2017-03-11 08:03:16 -08:00
snipe
9027bd1d9d Added in/out to model view display 2017-03-11 08:01:22 -08:00
snipe
f079be5e2f More small README changes 2017-03-11 08:01:05 -08:00
snipe
343da2968a Small README updates 2017-03-11 07:59:45 -08:00
snipe
35705813b3 Add @rashivkp as a contributor 2017-03-11 07:53:03 -08:00
snipe
5e3daee212 Add @abrahamvegh as a contributor 2017-03-11 07:52:39 -08:00
snipe
25d7345bbd Add @peelman as a contributor 2017-03-11 07:52:20 -08:00
snipe
76f5b6c0f0 Add @desmondmorris as a contributor 2017-03-11 07:52:03 -08:00
snipe
9da84a1d4d Add @flashingcursor as a contributor 2017-03-11 07:51:46 -08:00
snipe
2523072b1d Add @feeva as a contributor 2017-03-11 07:51:32 -08:00
snipe
f38ef8db7f Add @FleischKarussel as a contributor 2017-03-11 07:51:03 -08:00
snipe
d2b79ce39e Add @jakemcgraw as a contributor 2017-03-11 07:50:53 -08:00
snipe
6b47b0480e Add @archpoint as a contributor 2017-03-11 07:45:40 -08:00
snipe
a916cbb0d0 Add @buzzedword as a contributor 2017-03-11 07:45:25 -08:00
snipe
5f7c7503ec Add @leostat as a contributor 2017-03-11 07:45:05 -08:00
snipe
e6b88fa565 Add @technogenus as a contributor 2017-03-11 07:44:50 -08:00
snipe
db1730ae06 Add @burlito as a contributor 2017-03-11 07:44:34 -08:00
snipe
1366d0bfb9 Add @rrdial as a contributor 2017-03-11 07:44:21 -08:00
snipe
cf4698d2ed Add @mizar1616 as a contributor 2017-03-11 07:43:58 -08:00
snipe
8875ce7243 Add @mrshu as a contributor 2017-03-11 07:43:47 -08:00
snipe
07f3ae5e0b Add @pakkua80 as a contributor 2017-03-11 07:43:21 -08:00
snipe
cbca7e45c3 Add @diwanicki as a contributor 2017-03-11 07:43:06 -08:00
snipe
9fccec661b Add @svpernova09 as a contributor 2017-03-11 07:42:34 -08:00
snipe
bf837af73a Update @splaer as a contributor 2017-03-11 07:42:03 -08:00
snipe
bd8fc5a07f Add @splaer as a contributor 2017-03-11 07:41:52 -08:00
snipe
564a9f0ed7 Add @cleathley as a contributor 2017-03-11 07:41:39 -08:00
snipe
ded648f293 Add @j0k3r as a contributor 2017-03-11 07:41:06 -08:00
snipe
0b156098df Add @ivarne as a contributor 2017-03-11 07:40:42 -08:00
snipe
3e4fe838f0 Add @southwolf as a contributor 2017-03-11 07:40:29 -08:00
snipe
b3f6e4e47e Add @DanielNemanic as a contributor 2017-03-11 07:40:17 -08:00
snipe
68f3c1727c Add @tomcastleman as a contributor 2017-03-11 07:40:03 -08:00
snipe
79e9072c0a Add @mdaniels5757 as a contributor 2017-03-11 07:39:32 -08:00
snipe
619a1dc63f Add @balticer as a contributor 2017-03-11 07:39:09 -08:00
snipe
82b072ed44 Add @IDM-Helpdesk as a contributor 2017-03-11 07:38:56 -08:00
snipe
839a053077 Add @kobie-chasehansen as a contributor 2017-03-11 07:37:24 -08:00
snipe
6fb7f0d7b6 Add @aalaily as a contributor 2017-03-11 07:36:50 -08:00
snipe
2e3f18d5f2 Add @irasnyd as a contributor 2017-03-11 07:36:37 -08:00
snipe
7c4ccaf75c Add @jbirdkerr as a contributor 2017-03-11 07:36:26 -08:00
snipe
482cdaadcd Add @hawk554 as a contributor 2017-03-11 07:36:12 -08:00
snipe
323899034e Add @Miliamber as a contributor 2017-03-11 07:35:50 -08:00
snipe
79bfc1c246 Add @patgmac as a contributor 2017-03-11 07:35:35 -08:00
snipe
8f7e1b0e81 Add @MicaelRodrigues as a contributor 2017-03-11 07:35:17 -08:00
snipe
2e27456444 Add @Ahimta as a contributor 2017-03-11 07:35:05 -08:00
snipe
52140929c4 Add @swoopdk as a contributor 2017-03-11 07:34:52 -08:00
snipe
4dd732a6eb Add @thehereward as a contributor 2017-03-11 07:34:33 -08:00
snipe
b7d0432aa6 Add @adamdunson as a contributor 2017-03-11 07:34:22 -08:00
snipe
dfd275467e Add @csayre as a contributor 2017-03-11 07:33:54 -08:00
snipe
e6a9657da1 Add @mathieuk as a contributor 2017-03-11 07:33:19 -08:00
snipe
c836c64b0c Add @reidblomquist as a contributor 2017-03-11 07:33:05 -08:00
snipe
847c604d73 Add @balous as a contributor 2017-03-11 07:32:48 -08:00
snipe
67d00ec521 More contributor updates 2017-03-11 07:30:56 -08:00
snipe
edfab0111b Add @merid14 as a contributor 2017-03-11 07:30:05 -08:00
snipe
daa9ccfcf8 Add @YetAnotherCodeMonkey as a contributor 2017-03-11 07:29:41 -08:00
snipe
1aeea54105 Add @rassie as a contributor 2017-03-11 07:29:29 -08:00
snipe
510fb59a56 Add @ddreier as a contributor 2017-03-11 07:29:18 -08:00
snipe
c355ff8fb7 Add @opsydev as a contributor 2017-03-11 07:29:05 -08:00
snipe
8c6aa6d900 Update @tiagom62 as a contributor 2017-03-11 07:28:15 -08:00
snipe
04a79f8ad3 Add @FREImedia as a contributor 2017-03-11 07:27:53 -08:00
snipe
114e064326 Update @itsupportcmsukorg as a contributor 2017-03-11 07:27:22 -08:00
snipe
5854c62cd4 More contributor updates 2017-03-11 07:14:20 -08:00
snipe
1a5899e276 Updated README 2017-03-11 06:56:37 -08:00
snipe
5959308d6e Add @vjandrea as a contributor 2017-03-11 06:54:15 -08:00
snipe
f586304086 Add @vsposato as a contributor 2017-03-11 06:53:53 -08:00
snipe
39707943f6 Add @madd15 as a contributor 2017-03-11 06:53:46 -08:00
snipe
e58100252b Add @mtucker6784 as a contributor 2017-03-11 06:51:23 -08:00
snipe
5bd6869be5 Add @dmeltzer as a contributor 2017-03-11 06:49:34 -08:00
snipe
4c2bba8734 Add @uberbrady as a contributor 2017-03-11 06:48:49 -08:00
snipe
4e81b97145 Toggle visibility of fields in categories presenter 2017-03-11 05:30:14 -08:00
snipe
a680541fe8 Fixed target variable 2017-03-11 05:17:02 -08:00
snipe
793d9e9250 Fixed routes that didn’t have auth requirement 2017-03-11 05:16:56 -08:00
snipe
b51b51b949 Removed logging 2017-03-11 04:49:14 -08:00
snipe
23b1a4ca34 Higher per page 2017-03-11 04:39:35 -08:00
snipe
5b450c5978 Disambiguated company_id in assets api controller 2017-03-11 04:39:28 -08:00
snipe
875d0dd343 Added advanced search to assets 2017-03-11 04:26:01 -08:00
snipe
119e0772c1 Dragtable libraries
(These don’t work exactly as expected - weird CSS behavior)
2017-03-11 03:09:53 -08:00
snipe
b16ff263ec Addtional search filters for licenses API 2017-03-11 02:57:19 -08:00
snipe
bb2b6cb642 Foxed license name in licenses API 2017-03-11 02:52:50 -08:00
snipe
d799ab2a9c Narrowed down the accessories, consumables, etc APIs for manufacturer filtering 2017-03-11 02:49:24 -08:00
snipe
c511073bc2 Fixes checkin/checkout for assets on manufacturers detail page 2017-03-11 02:03:13 -08:00
snipe
5803af7409 Use date display formatter on licenses 2017-03-10 22:09:35 -08:00
snipe
caf2f648b1 Added updated/created to locations API 2017-03-10 22:09:21 -08:00
snipe
c132036f5c Fixes #3311 - more fields for manufacturers 2017-03-10 22:08:59 -08:00
snipe
1682867d02 Added employee number back into user listings 2017-03-10 20:58:09 -08:00
snipe
da66eecd74 Allow string as employee number 2017-03-10 20:57:57 -08:00
snipe
73f5457b1b Fixed subnav permissions in Asset Menu for expanded permissions 2017-03-10 20:48:58 -08:00
snipe
f1fd152513 Fixes #3335 - added additional pagination at top of table 2017-03-10 20:35:03 -08:00
snipe
bf99534f8d Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-03-10 20:07:49 -08:00
snipe
ad510cecd5 Fixes #2422 - Adds bulk edit for select user attributes 2017-03-10 20:07:44 -08:00
Karol
4af2a8eb35 Update user(view) for support multilanguage (#3383)
Update user(view) for support multilanguage. Added lang var. and strings
2017-03-10 16:58:29 -08:00
snipe
fee60ec8dc Fixes #3145 2017-03-10 16:49:26 -08:00
snipe
01ae8802c1 Fix user export 2017-03-03 19:54:06 -08:00
snipe
318ac2be9a Break cookie 2017-03-03 19:53:58 -08:00
snipe
8dfc44d4fd Removed old unused files 2017-03-03 19:28:08 -08:00
snipe
69b014a342 Switch to URL 2017-03-03 19:07:57 -08:00
snipe
5d8faa934b Fixed link in error pages 2017-03-03 19:06:34 -08:00
snipe
878f4f868d Added date formatter to consumables 2017-03-03 19:04:54 -08:00
snipe
9af5600c69 Wordwrap in side nav so it doesn’t cut off 2017-03-03 18:50:05 -08:00
snipe
2e274b5f21 Fixed user upload route 2017-03-03 18:41:13 -08:00
snipe
97dd5a58fb Removed space between time and AM/PM 2017-03-03 18:28:22 -08:00
snipe
51fccbdda4 Added last login to user menu 2017-03-03 18:28:13 -08:00
snipe
2b4443f810 Fixed user created at in listing 2017-03-03 18:16:23 -08:00
snipe
a9950392c4 Fixed weird sidenav breakage from smaller font size 2017-03-03 18:03:20 -08:00
snipe
6a2fd74219 Fixed API gate names in tranformers for new, more granular admin stuff 2017-03-03 17:56:05 -08:00
snipe
097096aa24 More custom date display via API 2017-03-03 17:53:42 -08:00
snipe
4f1669189e Try to make the select all checkbox work for users.
Not sure where/how this broke?
2017-03-03 17:30:37 -08:00
snipe
3c53ff9329 Set protected date formats 2017-03-03 17:30:19 -08:00
snipe
b5424462c9 Moved non-superadmin settings into sidebar 2017-03-03 17:30:12 -08:00
snipe
dc38e575d9 Allow date/time formatting selection in settings 2017-03-03 17:29:41 -08:00
snipe
161bd7acce Fixed double-encoding of ampersand 2017-03-03 17:17:51 -08:00
snipe
c6c3ddba3e Remove detail() presenter 2017-02-23 17:01:01 -08:00
snipe
ce2babcafb Fixed name display in transformer for asset listing 2017-02-23 17:00:50 -08:00
Andrea Bergamasco
c0c02eebd2 REST API - Refactoring of routes file, more tests added (#3345)
* Toggles the disabled state of auto_increment_prefix

To insert a prefix you had to toggle the checkbox, save the settings and reload. With this script it is immediate. Fixes #1390

* Delete asset image: made checkbox more visible

Related to #3153

* Added personal-access-token component

* Created basic API testing configuration

* First version of /components endpoind cest

* On-the-fly bearer token generation

* Completed testing of PATCH and PUT methods

* Added /components/{id}/assets route with tests

* Updated route and dataTable in view

* Completed test assertion

* Added links to assets in ComponentsAssets view

* Linked Company in AssetView page

* Fixed purchase_cost format expectation in ApiComponentsCest

* Refactored api routes file

Sorted all prefixes in alphabetical order, removed duplicate routes. For every prefix I placed first Route::resource and then any additional route in a Route::group. Expanded arrays for readability and consistency. Removed useless calls as create and edit everywhere.

* Refactored and added one more test to ApiComponentsAssetsCest

* Marked one test as incomplete, 404 response should return json

* Fixed value expectation

* Refactored getToken()

* Added API debugging routes

* Added more information to ValidationException reporting

Now the payload contains the validation errors for each invalid
attribute.

* /apitests: refactored expectations in component assertions

* Created ApiAssetsCest

* /apitests: Cleanup in Exceptions/Handler

* Reverted change to use

* Marked two tests as incomplete, looking for solutions
2017-02-23 16:32:35 -08:00
snipe
9ccaad8b9c Added created_at and modified_at to asset listing/api 2017-02-23 16:23:02 -08:00
snipe
9e7f998df5 Add model_number to accessory search 2017-02-22 22:55:20 -08:00
Andrea Bergamasco
e7f7d739ed Bugfixes based on functional tests (#3338)
* Toggles the disabled state of auto_increment_prefix

To insert a prefix you had to toggle the checkbox, save the settings and reload. With this script it is immediate. Fixes #1390

* Delete asset image: made checkbox more visible

Related to #3153

* Added personal-access-token component

* Created basic API testing configuration

* First version of /components endpoind cest

* On-the-fly bearer token generation

* Completed testing of PATCH and PUT methods

* Added /components/{id}/assets route with tests

* Updated route and dataTable in view

* Completed test assertion

* Added links to assets in ComponentsAssets view

* Linked Company in AssetView page

* Bugfixes based on functional tests

* Removed unused function

* Marked tests as incomplete

* Added check for  existence in groups/edit.blade.php
2017-02-22 22:49:19 -08:00
Daniel Meltzer
ad9470b6f8 Assorted fixed (#3332)
* Better error handling of failed file uploads.  Also improve formatting of modal dialog

* Readd app.js to the js build, fixes collapsing sidebar

* Update JS

* Fix font size.  We need to explicitly set the font size for the table because everywhere else that comes from bootstrap-tables
2017-02-22 22:49:06 -08:00
snipe
381526e488 Additional permissions 2017-02-22 22:21:26 -08:00
snipe
7cf42ecf9e New side menu for “other stuff”?
Need to figure out what to call this
2017-02-22 22:21:17 -08:00
snipe
8c20c2bd39 Fixed Illuminate path 2017-02-22 22:20:57 -08:00
snipe
904be03ffd Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-02-22 22:20:32 -08:00
snipe
ebbc2a60c3 Fix JS error when there is no row.update/delete defined 2017-02-21 15:40:25 -08:00
snipe
53ba2bbb4e Updated method for eager loading assets 2017-02-21 15:39:59 -08:00
snipe
2c6f323820 Increase max EOL 2017-02-21 15:39:46 -08:00
snipe
f520eaa6ce Increase max depreciation months 2017-02-21 15:39:39 -08:00
Andrea Bergamasco
fde46251de Components Assets view + stubbed API tests (#3325)
* Toggles the disabled state of auto_increment_prefix

To insert a prefix you had to toggle the checkbox, save the settings and reload. With this script it is immediate. Fixes #1390

* Delete asset image: made checkbox more visible

Related to #3153

* Added personal-access-token component

* Created basic API testing configuration

* First version of /components endpoind cest

* On-the-fly bearer token generation

* Completed testing of PATCH and PUT methods

* Added /components/{id}/assets route with tests

* Updated route and dataTable in view

* Completed test assertion

* Added links to assets in ComponentsAssets view

* Linked Company in AssetView page
2017-02-21 14:26:46 -08:00
Andrea Bergamasco
4f73a13c6b Hotfix/translate row delete msg (#3305)
* Toggles the disabled state of auto_increment_prefix

To insert a prefix you had to toggle the checkbox, save the settings and reload. With this script it is immediate. Fixes #1390

* Delete asset image: made checkbox more visible

Related to #3153

* Added missing translation to bootstrap table partial

The "Are you sure to delete" confirmation was hardcoded. Added translation row to all locales and other small corrections to it/general lang file.
2017-02-21 14:25:46 -08:00
snipe
edf36cd850 Sigh. 2017-02-17 18:30:48 -08:00
snipe
a710c98b50 Set string length because laravel is dumb sometimes 2017-02-17 18:26:53 -08:00
snipe
8fe8ff71e8 Category improvements 2017-02-16 00:32:33 -08:00
snipe
a18e90c22a Fix delete modals 2017-02-15 23:04:49 -08:00
Andrea Bergamasco
d9fe39c00e Delete asset image: made checkbox more visible (#3293)
Related to #3153
2017-02-15 21:52:10 -08:00
Andrea Bergamasco
9975d55249 jQuery script to toggle the disabled state of auto_increment_prefix (#3292)
* Toggles the disabled state of auto_increment_prefix

To insert a prefix you had to toggle the checkbox, save the settings and reload. With this script it is immediate.

* Toggles the disabled state of auto_increment_prefix

To insert a prefix you had to toggle the checkbox, save the settings and reload. With this script it is immediate. Fixes #1390
2017-02-15 21:51:30 -08:00
snipe
c67b44b3d5 Moving license index to new API format 2017-02-10 18:43:30 -08:00
snipe
eb3767890e Changed font size
This seems wrong - shouldn’t need to upload 10 files for a one-line CSS change
2017-02-10 18:42:38 -08:00
snipe
74c5c55838 Removed outdated comment 2017-02-08 18:25:06 -08:00
snipe
eea90dda78 Added Gate integration into API transformers 2017-02-08 18:24:55 -08:00
snipe
959fafe04b Expanded checkin/checkout buttons formatter 2017-02-08 18:21:03 -08:00
snipe
2892e32095 Set visible to true for checkin/checkout buttons 2017-02-08 18:20:44 -08:00
snipe
8cce1a3882 Fixed users formatter method 2017-02-08 18:20:23 -08:00
snipe
86198badbb Added more company_id filtering, more transformers 2017-02-08 08:48:41 -08:00
snipe
2986747fd7 Fixed sidenav status type filtering 2017-02-08 03:51:52 -08:00
snipe
72ec362f72 Search on status label type 2017-02-08 03:37:44 -08:00
snipe
4cf01e4f48 Added ability to search by company_id and location_id 2017-02-08 03:31:42 -08:00
snipe
dd6a477355 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-02-06 18:49:13 -08:00
snipe
6d40a98a16 User assets presenter for column headers 2017-02-06 18:49:08 -08:00
snipe
584e2ba618 Added a space 2017-02-06 18:47:54 -08:00
Daniel Meltzer
79f3ca3074 Modify the jquery that fires select2 to prevent it being run twice on the importer vue select2 (which is created separately). (#3276) 2017-02-06 18:04:36 -08:00
snipe
1751a8c0e0 Switched to presented for ugly BS table column headers 2017-02-03 22:20:11 -08:00
snipe
d37b9fe169 Use hardrware listing for status labels detail link 2017-02-03 20:34:09 -08:00
snipe
8b0066cbad Fixed user link formatter on models detail 2017-02-03 20:22:41 -08:00
snipe
98e0ecbd88 Added manufacturer sorting on models 2017-02-03 20:20:03 -08:00
snipe
2c0df6159f Added formatting for Suppliers index 2017-02-03 20:19:54 -08:00
snipe
9cae6066a0 Added asset by manufacturer listing 2017-02-03 19:52:00 -08:00
snipe
f1c4aed5b5 Removed additional groups API fields 2017-02-03 19:35:22 -08:00
snipe
78f2b30b31 Removed the plus icon from file uploader in vue
I cannot believe I have to check in 7 files just for this. Vue is garbage.
2017-02-03 19:35:07 -08:00
snipe
1e2a23e955 Use main assets API to pull view pages for assets listings 2017-02-03 19:34:24 -08:00
snipe
a69090c91c Moved import to top level sidenav 2017-02-03 19:33:40 -08:00
snipe
85d5b75de6 Removed console debugging messages 2017-02-03 03:55:43 -08:00
snipe
cddd3cdb81 Added spinner icon to loading message 2017-02-03 03:54:38 -08:00
snipe
729b709de2 Include notes in custom asset report 2017-02-03 02:16:37 -08:00
snipe
f1592aa63f Tighter asset API responses, sanitization 2017-02-03 02:04:17 -08:00
snipe
cdb6349035 Updated JS 2017-02-03 01:45:41 -08:00
snipe
6c1a827ed0 Added warranty info to listing 2017-02-03 01:45:12 -08:00
snipe
f9bed9264f Removed oops state if model has no fields 2017-02-02 19:11:10 -08:00
snipe
ca490fd129 Updated javascript 2017-02-02 19:00:42 -08:00
snipe
93719b2214 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-02-02 18:55:29 -08:00
snipe
0c3840503e Laravel 5.4 2017-02-02 18:54:54 -08:00
snipe
498dc9da43 Removed duplicate header 2017-02-02 18:54:31 -08:00
Brady Wetherington
7dbbe862ce Tried to fix build environment/select2 (#3262) 2017-02-02 18:53:50 -08:00
snipe
d19cc9d9c1 Added legacy redirector 2017-02-02 18:14:25 -08:00
snipe
b7d3b65bae Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-02-02 17:12:55 -08:00
Daniel Meltzer
3c8910eeab Add select2 to node for now. (#3243) 2017-02-02 17:07:26 -08:00
snipe
18e2db24bd Updated groups index route name 2017-02-01 19:13:17 -08:00
snipe
f1a83bd007 Fixed bulk delete 2017-02-01 19:07:39 -08:00
snipe
12c5ca67ff Pulled accidental debugging exit 2017-02-01 18:56:47 -08:00
snipe
00f7cc028b Fix dumb icon bug 2017-02-01 18:54:43 -08:00
snipe
bf919e133c Center boolean results in the list 2017-02-01 18:53:27 -08:00
snipe
541a5e6776 Groups API starter
Edit/Create still broken for some reason
2017-02-01 18:50:28 -08:00
snipe
464c524375 Depreciations API 2017-02-01 17:59:03 -08:00
snipe
7086ac8a8b Tweaks to status labelas listing display 2017-02-01 17:48:28 -08:00
snipe
7642d17fb8 Fix category listing 2017-01-26 21:11:27 -08:00
snipe
a80af854ba Switch companyName to company 2017-01-26 21:05:33 -08:00
snipe
99d837fa50 Added API methods and UI to view assets associated with a particular model 2017-01-26 21:02:59 -08:00
snipe
8d50bb19af Switched to route from redirect->to 2017-01-26 20:13:59 -08:00
snipe
ec7e89ecb8 Added Helper 2017-01-26 20:08:15 -08:00
snipe
377cb8e5d1 Use Locations transformer for location API 2017-01-26 20:08:06 -08:00
snipe
c7003897ae Fixed Locations transformer for assigned assets 2017-01-26 20:07:46 -08:00
snipe
231f4dce07 Basic components API 2017-01-26 19:16:06 -08:00
snipe
5e9e6da577 Basic consumables API 2017-01-26 18:46:18 -08:00
snipe
0e1f5c173c Added blue-imp to package.json 2017-01-26 18:31:24 -08:00
snipe
34ab78ef99 Updated db column name test for various languages 2017-01-26 16:57:23 -08:00
snipe
11810ae9ad Minor CSS changes 2017-01-26 14:56:34 -08:00
snipe
5d3568136e Added some printer-friendly stuff 2017-01-26 06:20:53 -08:00
snipe
9ac9c6f1bc Updated convertUnicodeDbSlug to use Patchwork if intl isn’t installed 2017-01-26 04:59:14 -08:00
snipe
863735a6e5 Fix utf encoding on DB 2017-01-26 04:52:38 -08:00
snipe
d02a7064e3 Added patchwork for fallback for systems without intl 2017-01-26 04:52:30 -08:00
snipe
b4c6d0c897 Added optional help text field to custom fields 2017-01-26 04:52:11 -08:00
snipe
b0f84fa82b Updated migration to fix field names 2017-01-26 04:49:01 -08:00
snipe
19313e4b83 Fixed borked down() method in migration 2017-01-26 04:48:43 -08:00
snipe
5e9c69711b Set trimonsearch to false to prevent weird trimming on search queries 2017-01-26 04:48:22 -08:00
snipe
cbff2ec57d Removed log comment 2017-01-25 22:29:05 -08:00
snipe
a688822899 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-01-25 21:33:25 -08:00
snipe
481722507d Composer update 2017-01-25 21:33:11 -08:00
Daniel Meltzer
5ba2ec881c Vue importer (#3235)
* Begin work on vueifying the importer

* Beginning work on migrating the importer to use a vue/components for future interactivity

Update JS

More importer work.  Move to a vue based modal, begin handling of processing.  Still need to port error messages.

More importer work.  Move to a vue based modal, begin handling of processing.  Still need to port error messages.

Update importer.  Add error display.  Fix modal, update vue-strap to vue2

More progress.  Add select2 vue bits.

* Move to querying the db to find importer matches.  It scales better on large datasets.

Fix select2 related issues.  We were trying to initialize it twice, which led to the custom data being overwritten.

* Better error handling on uploads and deletion of files.  Restore progressbar on upload.

* Add support for generic exception reporting if app.debug is enabled.

* Handle Http 500 errors better.  Display errors if debug is enabled.  Assorted cleanups.

* Fix codacy issues, remove unused methods.

* Only bind vue to the importer for now.

* Load vue for passport as well.
2017-01-25 21:29:23 -08:00
snipe
a9bf34cf61 Minor transformer cleanup 2017-01-25 21:01:00 -08:00
snipe
855d775c41 Fix fieldset blade path 2017-01-25 18:39:45 -08:00
snipe
dc47a0fad6 Fixes #2551 - use UTF-8 safe slugging for MySQL columns 2017-01-25 18:38:20 -08:00
snipe
de869c7ed0 Switched to labels for clearer UI on fieldsets 2017-01-25 05:14:39 -08:00
snipe
ec88d54a5b Prevent demo users from deleting/creating API keys 2017-01-25 05:03:30 -08:00
snipe
2a7469d898 Fix uniqueness issue on saving edited fields 2017-01-25 04:52:47 -08:00
snipe
b1a80f8ed8 Fixes #1684 - Allow editing of custom fields
@uberbrady can finally get out of the sea
2017-01-25 04:34:11 -08:00
snipe
7350514a0d Moved custom fields blades to fit the rest of the app convention 2017-01-25 04:31:18 -08:00
snipe
af211c1203 Remove unused method 2017-01-25 03:10:44 -08:00
snipe
ed7e967f4a Helper cleanup, slug helper 2017-01-25 03:10:35 -08:00
snipe
80da0f801c Fixes #2921 - use toUTF8 instead of fixUTF8 2017-01-25 03:10:18 -08:00
snipe
5f49e7c1a7 Accessories API routes
Still a bit of a WIP
2017-01-25 02:19:26 -08:00
snipe
75d35273c9 Pull image formatter out of dynamic loop, pass full url to formatter 2017-01-24 22:46:07 -08:00
snipe
04bb180a80 More bootstrap tables formatting 2017-01-24 22:25:17 -08:00
snipe
8f12486f6c More generic javascript formatters, updated api routes 2017-01-24 21:04:38 -08:00
snipe
f13719bf32 Updated named route for consumables 2017-01-24 19:24:59 -08:00
snipe
c907414e71 Added escaping 2017-01-24 19:24:47 -08:00
snipe
945d910ca2 Added columns to be ignored on export 2017-01-24 19:24:33 -08:00
snipe
e8310c8f3c Additional API routes for licenses, manufacturers 2017-01-24 18:58:07 -08:00
snipe
e4e4e6ae47 Licenses transformer for API 2017-01-24 18:57:33 -08:00
snipe
afacee90ae Fixed variable for transformer 2017-01-24 18:57:21 -08:00
snipe
ebe3f58805 Added missing manufacturer data on save 2017-01-24 18:57:03 -08:00
snipe
88faefe1ed Licenses listing index API 2017-01-24 18:56:27 -08:00
snipe
8f0ab1e719 Fixed weird status code error on ajax 2017-01-24 18:56:15 -08:00
snipe
b019e6e950 Removed closures from routes files so that we can allow people to cache routes for performance optimization 2017-01-24 17:37:07 -08:00
snipe
eea779c16d Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-01-24 17:07:23 -08:00
snipe
b1dcc208e9 Updated vue dist 2017-01-24 17:07:17 -08:00
snipe
d0f062458e Additional API transformers, formatters 2017-01-24 17:07:00 -08:00
snipe
6d2a37fa80 Remove google font from maintenance mode template 2017-01-24 17:03:48 -08:00
snipe
9d555f5436 Fixes #3139 and #3230 - use native font stack, removing google fonts
Especially helpful for those running Snipe-IT in a closed environment
2017-01-24 17:02:39 -08:00
Daniel Meltzer
0f9e39e4cd Avoid magic numbers in the seeders, instead adjust order of seeding and load relationships directly. (#3224) 2017-01-22 14:57:09 -08:00
Daniel Meltzer
df4c7e32b1 Another Travis Fix (#3211)
Make sure we use the testing env for passport:install so we write to the correct db.
2017-01-19 11:48:06 -08:00
snipe
ad4bf83aaa Add ability to view assets by status label
This should be refactored. Lots of copypaste from the assets views here
2017-01-18 20:41:40 -08:00
snipe
19cb428fb0 Asset and status formatters 2017-01-18 19:46:43 -08:00
snipe
b7555e780c Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-01-18 19:38:54 -08:00
snipe
ea3d45882d Fix bulk actions with new bootstrap tables checkboxes 2017-01-18 19:38:42 -08:00
snipe
bebb653a70 Pull common formatters into partial 2017-01-18 19:28:35 -08:00
Daniel Meltzer
a2bf685901 Seeds and tests (#3210)
* Update composer phpcs

* Fix failing model validation in the database seeders.  Should make travis happy.  Also fix a few test issues
2017-01-18 16:50:33 -08:00
snipe
5d14acaac4 Fixed bulk actions using native bootstrap-tables checkall 2017-01-18 07:40:40 -08:00
snipe
47cf734f72 Hide the app div
This will need to be fixed later, but the flash of unstyled content on the non-api pages was making me cray
2017-01-18 05:02:00 -08:00
snipe
3161420eb3 ¯\_(ツ)_/¯ no idea why this doesn’t seem to matter
Too sleepy to investigate it right now
2017-01-18 04:59:56 -08:00
snipe
297034c037 APIified custom fields reorder 2017-01-18 04:58:56 -08:00
snipe
db7b1b586c Fixed custom fields improprly nested form tags 2017-01-18 04:58:31 -08:00
snipe
f6ccbfc9b0 Fixed stupid font error for fontawesome 2017-01-18 04:34:59 -08:00
snipe
eac025263b Basic hardware bootstrap table formatter 2017-01-18 04:16:25 -08:00
snipe
8a4a4264cd Formatters for bootstyra-tables users listing
We should probably abstract these out, since we use similar or the same fields imn other places
2017-01-18 04:12:13 -08:00
snipe
fd594ed608 Gitkeep 2017-01-18 03:56:46 -08:00
snipe
39b4725114 Load assigneruser relationship 2017-01-13 22:17:20 -08:00
snipe
f642013774 Check for validity before trying to display relation data 2017-01-13 22:06:12 -08:00
snipe
b462888850 Derp 2017-01-13 21:15:36 -08:00
snipe
9bc10edc8d Rervet that for now - still need to only enable dropdown if more than one is selected 2017-01-13 21:05:02 -08:00
snipe
e284e9900a Use native boostrap tables check-all 2017-01-13 21:02:55 -08:00
snipe
ba71122449 Removed old datatable method from Locations 2017-01-13 21:00:25 -08:00
snipe
d39b7e19eb Updated debugbar settings 2017-01-13 21:00:02 -08:00
snipe
e54036991c Updated trusted proxy config for newer version 2017-01-13 20:59:54 -08:00
snipe
acd8eafc8c VERY basic example of dynamic buttons in table 2017-01-13 20:58:17 -08:00
snipe
2879114fe9 Misc API cleanup for assets 2017-01-13 11:41:00 -08:00
snipe
b968839a1d Pull out extraneous use statements 2017-01-13 11:38:25 -08:00
snipe
89edda2c23 Manufacturers API 2017-01-13 09:37:06 -08:00
snipe
73eee1b7b1 Derp. Really check for valid category_type in Category model now 2017-01-13 09:28:08 -08:00
snipe
213a234bef Check for valid category types in validation 2017-01-13 09:27:32 -08:00
snipe
14ddcc56a2 Categories API 2017-01-13 09:01:10 -08:00
snipe
edca6ad19d Make eol, notes sortable on asset model 2017-01-13 08:41:17 -08:00
snipe
ae540af2a9 Additional fields for asset models 2017-01-13 08:39:02 -08:00
snipe
34f427920b Removed legacy getDataTable method from status labels 2017-01-13 08:18:37 -08:00
snipe
e7a243f8bc Added search, sorting to assetmodels 2017-01-13 08:18:22 -08:00
snipe
66f724cd35 Added created_at to status labels for consistency 2017-01-13 07:55:03 -08:00
snipe
b423fa3bd4 Added sorting, searching, etc to status labels index 2017-01-13 07:47:39 -08:00
snipe
295744be64 Added searching, sorting, etc to locations API 2017-01-13 07:40:08 -08:00
snipe
fbbf5e77b4 Make sure the category and manufacturer ids exist 2017-01-13 07:14:32 -08:00
snipe
c7e1b426e7 Additional API routes and controllers for models, suppliers, users, locations and status labels 2017-01-13 04:50:20 -08:00
snipe
bc5fcf8736 Fixed dashboard chart 2017-01-13 03:19:39 -08:00
snipe
06d66f6e94 Fixed formatting 2017-01-13 01:45:14 -08:00
snipe
f9a501d774 Fixed array name 2017-01-13 01:44:47 -08:00
snipe
f54fcb88e2 Fixed formatting 2017-01-13 01:43:51 -08:00
snipe
58b1ac5f0f Some route/transformer edits 2017-01-13 00:13:57 -08:00
snipe
d2f84a2329 Added some hidden fields 2017-01-13 00:12:26 -08:00
snipe
4f35c8af3e Docblock edits 2017-01-12 23:43:45 -08:00
snipe
a35323131f Updated documentation link 2017-01-12 23:43:20 -08:00
snipe
fbd6dcbfbb Fixed path to query builder in docblocks 2017-01-12 23:42:59 -08:00
snipe
9c41881d99 Use transformers for API response
This is experimental
2017-01-12 23:42:39 -08:00
snipe
f52680b971 Masde response formatting a little nicer 2017-01-12 23:41:45 -08:00
snipe
e66e830b44 Added additional routes 2017-01-12 23:41:08 -08:00
snipe
6d7c226acd Experimental transformers 2017-01-12 23:40:35 -08:00
snipe
ca2fa3dab9 Added transformer autoload 2017-01-12 23:40:23 -08:00
snipe
267f0bdfea Added additional API routes 2017-01-12 19:41:01 -08:00
snipe
2f43f78e62 Validated category_id on accessories, name model_number fillable 2017-01-12 19:40:42 -08:00
snipe
b11a951e95 Starter API controllers 2017-01-12 19:40:20 -08:00
snipe
ed325d2fe5 Let whatever the other error is fall through 2017-01-12 19:38:40 -08:00
snipe
3c6010679a Nicer handler for JSON model not found errors 2017-01-12 19:06:39 -08:00
snipe
d9d048f90d Fixed #2303 - redirect correctly after login 2017-01-12 07:09:44 -08:00
snipe
b7a650e986 Switched ordering of status labels and status label types to more user-friednly config 2017-01-12 06:50:54 -08:00
snipe
534e40feb8 Fixed bad fieldset call 2017-01-12 03:55:54 -08:00
snipe
a283b13069 Handled bad model id 2017-01-12 03:53:52 -08:00
snipe
41b864cc49 Added update method for assets 2017-01-12 03:48:18 -08:00
snipe
03874a5481 Validate asset model and status on the model level 2017-01-12 03:47:45 -08:00
snipe
7d2d6a3c1b Removed unused use statements 2017-01-12 02:53:43 -08:00
snipe
29b5678a8d Format destroy responses 2017-01-12 02:50:55 -08:00
snipe
93542f3478 Make sure the model_id and status_id actually exist 2017-01-12 02:41:02 -08:00
snipe
8f2019c62e Added DELETE for destroy method 2017-01-12 02:20:32 -08:00
snipe
fddcc0fefd Added better form request handling
This will break a ton of things
2017-01-12 02:20:20 -08:00
snipe
15373d5f4a Fixed a few asset API issues 2017-01-12 02:19:55 -08:00
snipe
704ee59541 WTF why is name required?? 2017-01-12 02:19:36 -08:00
snipe
5a848566f9 Helper method to standardize JSON responses 2017-01-12 02:19:17 -08:00
snipe
268308004c Fixed number of results returned 2017-01-11 23:45:03 -08:00
snipe
0cf4014b75 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-01-11 23:41:02 -08:00
snipe
95f2d94e01 Added create/destroy methods for asset API 2017-01-11 23:40:56 -08:00
Richard Hofman
c506f30562 Add support for location-specific LDAP OUs. (#3176)
* Add support for location-specific LDAP OUs.

* Shortened variable names as suggested by Codacy review.
2017-01-11 23:37:14 -08:00
snipe
2c695cf7e5 404 JSON response if the asset is not found
(Brady and I will argue about this forever)
2017-01-11 19:12:25 -08:00
snipe
74696d5ded View asset API 2017-01-11 19:00:34 -08:00
snipe
7a124e85d6 Cleaned up unused use statements 2017-01-11 18:26:05 -08:00
snipe
b8d81c0734 Added order_number to presenter 2017-01-11 18:25:53 -08:00
snipe
900e6e2419 Starter asset API 2017-01-11 18:14:06 -08:00
snipe
ff2c489af4 Fixed javascript conflicts, fixing select2 and icheck 2017-01-11 17:07:27 -08:00
snipe
55d0f8c0df I think this is necessary for the Vue.js version? 2017-01-11 15:21:33 -08:00
snipe
aefbb76592 Possible fix for acceptance tests (needs oauth key) 2017-01-11 15:14:33 -08:00
snipe
73d45e9a14 Fixed CSRF on create asset ajax 2017-01-11 15:03:04 -08:00
snipe
15bab7fa9e Test Auth::guard('api')->user() as user_id 2017-01-11 14:55:04 -08:00
snipe
8f31ee318e Removed extra commented out crap 2017-01-11 14:54:50 -08:00
snipe
c7167fc73c Only allow users to create a new user via modal if they have users.create permission 2017-01-11 14:54:39 -08:00
snipe
9e4a391b8b Updated auth:api in kernel 2017-01-11 14:54:11 -08:00
snipe
1d2489cf9c Updated composer lock 2017-01-11 14:53:51 -08:00
snipe
1364494e92 Updated JS 2017-01-11 14:52:32 -08:00
snipe
dbf3a074f7 Fix CSRF issue on bootstrap tables 2017-01-11 14:52:05 -08:00
snipe
4940bf05f0 Removed auth:api from api middleware since it happens magically now 2017-01-11 14:51:00 -08:00
snipe
c08fe196c4 Fix api middleware call 2017-01-11 14:50:38 -08:00
snipe
93a087b29a Set longer token expiration 2017-01-11 14:50:26 -08:00
snipe
4590054c75 Fixed path in comments 2017-01-11 14:50:13 -08:00
snipe
80e047f679 Removed poop 2017-01-11 14:45:47 -08:00
snipe
86926675ce Fixed passport token generation 2017-01-11 08:44:34 -08:00
snipe
41f58efb70 Font-awesome for bower 2017-01-11 06:53:49 -08:00
snipe
e2d5401f3a Stop double-loading jquery 2017-01-11 05:51:13 -08:00
Daniel Meltzer
9bbfb64f17 Add a use declaration to Userscontroller to prevent assigning the wrong item_type. Should fix/prevent #3160 (#3168) 2017-01-11 04:27:05 -08:00
snipe
84154d936a Added self.api permission 2017-01-11 04:05:39 -08:00
snipe
57d0eba58f API blade cleanup 2017-01-11 04:05:32 -08:00
snipe
a02f406fa6 Removed personal access token from settings api page 2017-01-11 03:58:09 -08:00
snipe
19fcda5c25 Basic API management
I’m getting a 500 on personal token creation, but there’s nothing in the logs, so I have no idea what’s wrong
2017-01-11 03:55:47 -08:00
snipe
b5ddd9ab0a More vue/api work 2017-01-11 03:38:55 -08:00
snipe
d14ed4a73c Bower components 2017-01-11 03:05:06 -08:00
snipe
33ffc58ffe Fixed vue issue with api 2017-01-11 01:27:02 -08:00
snipe
11d86d83b6 Fixing JS to actually use vue 2017-01-11 01:02:32 -08:00
snipe
c99f9e321f Temprarily disable auto-phpcs 2017-01-10 23:22:00 -08:00
snipe
b7bbc44052 Removed unneeded use statement 2017-01-10 23:21:47 -08:00
snipe
34a9564f30 Updated language strings 2017-01-10 17:53:06 -08:00
snipe
3060de8e0c Merge branch 'develop' of github.com:snipe/snipe-it into develop 2017-01-10 17:11:11 -08:00
Daniel Meltzer
44683c784f Importer: Add License Importer and refactor (#3143)
* Major code simplification of the importers.

Move towards using Model::fill and Model::update rather than reinventing
the wheel.  This makes the updating/creating logic a lot clearer, and
allows for the deletion of a lot of code.  Also allows for supporting of
more fields in the future really easily.

* Cleanup constructors and use setters instead.

* Set the LC_MONETARY locale, and use it to strip currency symbols in Helper::parseFloat()

* Move licenseseat creation/deletion logic into an event handler on the model rather than the controller.

* Move the logging of parsed values to array_smart_fetch rather than writing it out everywhere

* Move to storing dates as carbon rather than strings.  Allows for the parsing of more arbitrary strings from the importer

* Add a license importer with support for checking out to users or assets.

* Make a directory for sample/mock import csvs and populate it

* Adjust how we store/retrieve dates to fix some issues the tests found.
2017-01-10 16:19:18 -08:00
snipe
b4bed2a11f Move cipher into the .env 2017-01-09 19:41:24 -08:00
snipe
57d2b88900 Remove number formatting 2017-01-06 03:14:32 -08:00
snipe
208ccab4c1 Fixes #3104, #2914 and #2918 - auto-increment incorrectly generating next ID 2017-01-06 02:54:06 -08:00
Daniel Meltzer
6ce20c32b1 Component Importer and various Importer Fixes (#3132)
* Importer fix: we were trimming the wrong part of the classname when creating a category.  This led to categories not being recognized.

* Add a component importer.  Uses same fields as consumable importer.  Only trick: If an asset_tag is present, we checkout a component to that asset on import

Enable component importer.  Also calculate the importer classname in a cleaner fashion.

* Fix comparisons.  find can return an index of 0, which is falsy.
2017-01-05 15:45:12 -08:00
Daniel Meltzer
816d2fd095 More minor fixes (#3126)
* Update composer phpcs

* Minor Fixes found while working.
ALlow user_id to be nullable in category model validation

Point to the correct route in accessoriespresenter datatable.  Also add name() method

Add a translated category name

Fix typo in translation

* Add a method to the asset presenter to show deployed when asset is deployed.  Fixes #3114
2017-01-03 16:55:43 -08:00
Bob Clough
f999c797e5 Allow a license to be pre-checked-out to an asset. (#3124)
Some licenses, such as windows licenses, are machine specific.  This
commit allows an extra field to be added to the license importer to
allow these licenses to be imported and attached directly to an asset
2017-01-03 16:55:21 -08:00
snipe
6351746c62 Bumped to v4.0-develop 2016-12-30 16:28:47 -08:00
Daniel Meltzer
3a6bbcc615 More improvements (#3116)
* Restore display of deleted items in the logs

* Fix functional tests.
2016-12-30 11:44:47 -08:00
Daniel Meltzer
8a782bf34a Present assetlogs (#3112)
* Set user if asset is checked out to user.  fixes email problems.

* Use sometimes validation to ignore this when no values are present.

* Move Actionlog details to a presenter and port the activity table to use it.  Still need to port other parts of the application, but this consolidates a lot of logic.

* Attempt test fix

* Port users,licenses, and assets view to use the presenter to generate table values.
2016-12-29 22:23:36 -08:00
snipe
6029bea2de Fixed error if user not set 2016-12-29 18:19:08 -08:00
Daniel Meltzer
4ad9c3623e Show a glyph in the assets datatable. (#3111) 2016-12-29 18:12:27 -08:00
snipe
4c5fce847b Removed user “new” buttons next to non-user options 2016-12-29 17:41:39 -08:00
snipe
0581499029 Fixed migration 2016-12-29 17:26:50 -08:00
snipe
16bd78fb3f Removed stray poop 2016-12-29 17:26:21 -08:00
snipe
199fdf39ec Merge branch 'dmeltzer-checkout-to-things-v1' into develop 2016-12-29 16:20:37 -08:00
snipe
221cf1f9c8 Merge branch 'checkout-to-things-v1' of https://github.com/dmeltzer/snipe-it into dmeltzer-checkout-to-things-v1
# Conflicts:
#	app/Http/Controllers/AssetsController.php
#	app/Http/Controllers/ReportsController.php
#	app/Http/Controllers/UsersController.php
#	app/Presenters/AssetPresenter.php
2016-12-29 16:20:17 -08:00
Daniel Meltzer
ce8eda1325 Fix some accessory sorting (#3108)
Fixes at least some of #3045
2016-12-29 15:50:18 -08:00
snipe
51ceaedfaf Small phpcbf cleanup 2016-12-29 14:02:18 -08:00
Daniel Meltzer
62dd474d44 Update dump with new migration. 2016-12-29 14:06:16 -05:00
Daniel Meltzer
aa2d3cf026 The assets method was renamed to assignedAssets in User class. Adjust places to reflect that 2016-12-29 11:45:37 -05:00
Daniel Meltzer
fa974b93c0 This authorization is now handled in the controller. 2016-12-29 11:44:34 -05:00
Daniel Meltzer
13b51bc934 Allow checkout of item to things on create page. Need to test validation better and maybe extract code to one place for checkout.blade and edit.blade 2016-12-29 11:10:52 -05:00
Daniel Meltzer
7ccd71978c Cleanup checkedout to part of asset view. 2016-12-29 09:56:19 -05:00
Daniel Meltzer
8cc695b65f Port more assignedUser to assignedTo. 2016-12-29 09:31:16 -05:00
Daniel Meltzer
165487ac92 Add migration 2016-12-27 22:04:30 -05:00
Daniel Meltzer
719463ef54 Progress 2016-12-27 22:04:11 -05:00
snipe
fd805bde50 Fixes #1247 - allow SVG logo upload 2016-12-27 17:31:53 -08:00
snipe
55415e8f56 Fix image resizing for later version of Intervention 2016-12-27 17:31:29 -08:00
Daniel Meltzer
d262aec4c3 Save Progress. 2016-12-27 19:24:41 -05:00
Daniel Meltzer
13cf11368f Reformat all view files. (#3105)
* Reformat all view files.  Check for matching tags and rearrange to make everything line up.

* Fix regression on asset create where the log was no longer saved.
2016-12-27 12:03:47 -08:00
Daniel Meltzer
cafafe851c Notification rework (#3103)
* Move slack integration to laravel5.3 style notifications, part 1.

* Fix consumable tab when active.

* Move the slack notifiable to the settings model.  Move all slack notifications into logCheckout/logCheckin.  Should think about refactoring this as an event at some point still.  Move Asset checkin/checkout to use the general loggable trait rather than it's own solution.

* Fix a logic error where assets with a non deployable status would show checkin instead of no button at all.

* Fix an html formatting error that resulted in us not closing a form.  This would cause the checkin page to try to submit a delete request (related to the modal form) rather than the desired checkin request.  Also fix formatting in this file.
2016-12-26 15:19:04 -08:00
Daniel Meltzer
06af9311fc Move sanitization of input to the model attribute setters. This cleans up a lot of checks in the various controller methods and ensures data will be set in the model accurately regardless of where it's set. Add unit tests for these methods (#3102) 2016-12-26 15:17:46 -08:00
Daniel Meltzer
fd450e2773 Two asset maintence related fixes (#3101)
* Fix maintenances create button, and post to the proper route in maintences edit

* Fix consumable tab when active.

* Fix an html formatting error that resulted in us not closing a form.  This would cause the checkin page to try to submit a delete request (related to the modal form) rather than the desired checkin request.  Also fix formatting in this file.

* Use log mail driver for testing, should fix the functional issue.  Disable acceptance tests on travis for now.

* Fix Category edit page.

* EOL Can be null.
2016-12-26 15:17:12 -08:00
Daniel Meltzer
57374955a8 Importer rework (#3100)
* Step 1 of refactoring importer to use separate classes.

* Port web importer.  Fix an issue with validation where index 0 would be treated as false and cause weird results.

* Farewall, AssetImport.  You've served us well.
2016-12-26 15:16:42 -08:00
snipe
8857faee65 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-12-23 19:23:27 -08:00
Daniel Meltzer
02c1a45025 View presenters (#3099)
* Add presenters for models.  Move bootstrap table JSON generation to these presenters, which cleans up controllers a lot.  Move view specific modifications from the models to the presenters as well.

* Fix some issues found by travis and codacy

* Fix a few more issues found while testing.

* Attempt another acceptance test fix

* Try something else

* Maybe..

* Move conditionals out of the datatable method and into dedicated url methods.
2016-12-23 19:23:07 -08:00
snipe
d1fecb6128 Added php codesniffer 2016-12-23 18:32:07 -08:00
snipe
40615f9504 Merge branch 'develop' of github.com:snipe/snipe-it into develop
# Conflicts:
#	app/Http/Controllers/StatuslabelsController.php
2016-12-23 17:53:03 -08:00
Daniel Meltzer
61543f3a04 Add presenters for models. (#3098)
* Add presenters for models.  Move bootstrap table JSON generation to these presenters, which cleans up controllers a lot.  Move view specific modifications from the models to the presenters as well.

* Fix some issues found by travis and codacy

* Fix a few more issues found while testing.

* Attempt another acceptance test fix

* Try something else

* Maybe..
2016-12-23 17:52:00 -08:00
snipe
297b9d25f0 Fixed issue with status labels 2016-12-23 16:07:58 -08:00
snipe
94a6b555a8 Darker red for warning 2016-12-22 21:21:10 -08:00
snipe
0cf5ad120b Removed todo 2016-12-22 21:09:01 -08:00
snipe
93dd27339b Fixed missing with clause 2016-12-22 21:08:43 -08:00
snipe
42db9563ae Updated composer lock 2016-12-22 21:03:52 -08:00
snipe
fc18aa7f6d Fixes bug #3086 - unabel to create asset from asset model screen 2016-12-22 17:08:42 -08:00
snipe
d6b7036518 NOT FINISHED: Added case for component import
This is not finished. The actual component creation isn’t written yet
2016-12-22 16:06:55 -08:00
snipe
2fe984013b Fixes #3092 - user location not being exported correctly 2016-12-22 15:53:34 -08:00
Daniel Meltzer
323c3807fa Cleanup controller escaping (#3084)
* Make delete routes work.  We put a little form in the modal that spoofs the delete field.

* Fix route on creating a user.

* Fix redundant id parameter.

* Port acceptance tests to new urls.

* Initial work on migrating to model based policies instead of global gates.  Will allow for much more detailed permissions bits in the future.

* This needs to stay for the dashboard checks.

* Add user states for permissions to build tests.

* Build up unit tests for gates/permissions.  Move accessories/consumables/assets to policies instead of in authserviceprovider

* Migrate various locations to new syntax.  Update test to be more specific

* Fix functional tests.

Add an artisan command for installing a settings setup on travis-ci

* Try a different id... Need to come up with a better way of passing the id for tests that need an existing one.

* Try to fix travis

* Update urls to use routes and not hardcode old paths.  Also fix some migration errors found along the way.:

* Add a environment for travis functional tests.

* Adjust config file to make travis use it.

* Use redirect()->route instead of redirect()-to

* Dump all failures in the output directory if travis fails.

* Cleanups and minor fixes.

* Adjust the supplier modelfactory to comply with new validation restrictions.

* Some test fixes.

* Locales can be longer than 5 characters according to faker... fex gez_ET.  Increase lenght in mysql and add a validation

* Update test database dump to latest migrations.

* Extend Supplier phone/fax length.

This catches issues found in testing with a phone number with a five digit extension.  fex (356) 654-3024 x36632

Also move away from escaping all values put into eloquent.  Eloquent
already uses PDO parameter binding, and this was leading to names like
Mr Ryan O'Malley turning into an html escaped version of that name when
stored.  All values should be escaped when using {{}}, we'll just have
to be more cautious when we use {!!, but I think we already are?

* Remove additional escaping here, like we did in suppliers controller.

* No need to eager load all of these relationships when we can call the count on the querybuilder directly

* Work on controller cleanup

* Always start from scrach, catches more issues this way.

* Update sql dump.  Remove old code from permissions test.

* Generate a deletable item on demand in the test, rather than relying on one existing.  I think we should probably move to mock all the database stuff at some point..

* More travis related fixes

* Break script into multiple functional lines

* Update all controllers to use the new helper, also cleanup syntax and docblocks along the way.
2016-12-19 22:00:50 -08:00
Daniel Meltzer
cd8c585377 Discussion: Moving to policies for controller based authorization (#3080)
* Make delete routes work.  We put a little form in the modal that spoofs the delete field.

* Fix route on creating a user.

* Fix redundant id parameter.

* Port acceptance tests to new urls.

* Initial work on migrating to model based policies instead of global gates.  Will allow for much more detailed permissions bits in the future.

* This needs to stay for the dashboard checks.

* Add user states for permissions to build tests.

* Build up unit tests for gates/permissions.  Move accessories/consumables/assets to policies instead of in authserviceprovider

* Migrate various locations to new syntax.  Update test to be more specific

* Fix functional tests.

Add an artisan command for installing a settings setup on travis-ci

* Try a different id... Need to come up with a better way of passing the id for tests that need an existing one.

* Try to fix travis

* Update urls to use routes and not hardcode old paths.  Also fix some migration errors found along the way.:

* Add a environment for travis functional tests.

* Adjust config file to make travis use it.

* Use redirect()->route instead of redirect()-to

* Dump all failures in the output directory if travis fails.

* Cleanups and minor fixes.

* Adjust the supplier modelfactory to comply with new validation restrictions.

* Some test fixes.

* Locales can be longer than 5 characters according to faker... fex gez_ET.  Increase lenght in mysql and add a validation

* Update test database dump to latest migrations.
2016-12-19 11:04:28 -08:00
Daniel Meltzer
ae2cb5fe68 Make delete routes work. (#3077)
* Make delete routes work.  We put a little form in the modal that spoofs the delete field.

* Fix route on creating a user.

* Fix redundant id parameter.

* Port acceptance tests to new urls.
2016-12-19 10:42:33 -08:00
snipe
c7e98366be Fixed Users functional test 2016-12-15 21:17:11 -08:00
snipe
84e1b531fd Bumped hash 2016-12-15 20:53:50 -08:00
snipe
9ea05bacf3 User resource routes 2016-12-15 20:52:39 -08:00
snipe
76344a8c9b Misc view rounte cleanups 2016-12-15 20:09:51 -08:00
snipe
4751bcd002 Use redirect()->route instead of ->to 2016-12-15 20:02:47 -08:00
snipe
f832b15cf3 Components routes 2016-12-15 19:59:42 -08:00
snipe
e685e0f019 Cleaned up custom fields controllers, views, names, etc 2016-12-15 19:17:07 -08:00
snipe
040774d646 One more /admin fix 2016-12-15 18:25:39 -08:00
snipe
37b4b29653 Fixed URL for statuslabels route 2016-12-15 18:23:26 -08:00
snipe
01f9deb5a6 Fixed forgotten to-> to ->route 2016-12-15 18:20:41 -08:00
snipe
d6b41759f0 Updated manufacturers, suppliers, depreciations for new route resources 2016-12-15 18:18:13 -08:00
snipe
e8945ad85e Fixed hardware.show for controller 2016-12-15 18:17:20 -08:00
snipe
406b828b4e Updated named location routes in hardware 2016-12-15 17:18:22 -08:00
snipe
c308fbce0d Updated resources, named routes, tests for Locations 2016-12-15 17:12:22 -08:00
snipe
3e4be6671e Updated categories with resty routes 2016-12-15 16:42:47 -08:00
snipe
2bb94e6806 Removed old hardware delete route to force failure 2016-12-15 16:42:28 -08:00
snipe
f182a7db2a Removed leading slash for url helper 2016-12-15 16:42:14 -08:00
snipe
aab0933856 Use url() helper over URL::to 2016-12-15 16:41:36 -08:00
snipe
b7a2c4c26d Use Request instead of Input:: 2016-12-15 15:56:52 -08:00
snipe
c6ab34faee Updated Companies for #3059 2016-12-15 15:48:30 -08:00
snipe
6c8e9327c1 Fixed Request path 2016-12-15 15:47:08 -08:00
snipe
8ad509d7f1 Update validation in AssetRequest form request 2016-12-15 15:24:55 -08:00
snipe
e5286229e0 Small model validations 2016-12-15 15:15:26 -08:00
snipe
cf2b57cb15 More for #3057 2016-12-15 15:15:11 -08:00
snipe
4603000d12 Removed print_r 2016-12-15 15:14:08 -08:00
snipe
816affc83b Tests updated for #3066 2016-12-15 15:14:00 -08:00
snipe
ad1bf86a08 And still more license route updates 2016-12-15 13:07:34 -08:00
snipe
bea1a93e9b More license route updates 2016-12-15 12:48:15 -08:00
snipe
1ab414453f Use $request instead of Input:: 2016-12-15 12:47:12 -08:00
snipe
eb9207d0fe Fixed license routes in getDataTable 2016-12-15 12:14:16 -08:00
snipe
0c5d3d1c74 Updated license routes 2016-12-15 11:57:19 -08:00
snipe
456e4a633e Corrected route for license view 2016-12-15 11:41:08 -08:00
snipe
3106c336bb Temporarily remove Vue extras 2016-12-15 06:11:53 -08:00
snipe
d46e77c037 Updated test for #3066 2016-12-15 06:11:32 -08:00
snipe
a6b975b168 More updates for #3060, #3058 2016-12-15 06:11:03 -08:00
snipe
8faffb1889 Started to fix some of the URLs and routes in test (#3066) 2016-12-15 04:28:16 -08:00
snipe
b17e380aae Removed stray echo tag 2016-12-15 04:27:33 -08:00
snipe
9b167d87d2 Updated to use named routes (#3060), some FORM spoofing for PUT (#3061)
(Updating assets isn’t currently working - investigating that)
2016-12-15 04:27:17 -08:00
snipe
7f65c6e472 Started to break API routes out (#3058) 2016-12-15 04:12:18 -08:00
snipe
2f03c5ddb0 Updated validation to allow nullable integrers #3064 2016-12-15 04:11:31 -08:00
snipe
e67b3e474f Use more RESTy method names, uses route names where possible (#3059, #3060) 2016-12-15 04:09:40 -08:00
snipe
a369a111e0 Updated validation for nullable integers 2016-12-15 01:37:19 -08:00
snipe
112ee3c8ff Removed extra api in prefix, added v1 2016-12-14 17:49:52 -08:00
snipe
a8e09728a5 Passport vue edits 2016-12-14 12:10:28 -08:00
snipe
899493e4d5 Not so much for the nightlies ;) 2016-12-14 11:23:18 -08:00
snipe
30bc3cbe9b Make company ID nullable 2016-12-14 11:12:21 -08:00
snipe
030207d626 Downgrade laravel-backup for users not on PHP7 2016-12-14 11:11:48 -08:00
snipe
fb0cce0640 Try nightly and latest 5.6.4 2016-12-14 11:01:32 -08:00
snipe
4753d70946 Travis doesn’t support 5.6.4, so remove it 2016-12-14 11:00:03 -08:00
snipe
38eb910999 Updated email template with signoff and Site Name 2016-12-14 10:54:22 -08:00
snipe
9840683c97 Moved API routes into API routes file 2016-12-14 10:54:05 -08:00
snipe
43619fa3c9 Moved API routes into API route file 2016-12-14 10:53:53 -08:00
snipe
4f2439ae1c Add Passport API token generator 2016-12-14 10:53:01 -08:00
snipe
a80ece9b84 New passport views 2016-12-14 10:17:07 -08:00
snipe
25f60264bd Passport scaffolding 2016-12-14 10:06:05 -08:00
snipe
97a1a166f0 Ignore generated OAuth keys 2016-12-14 10:05:54 -08:00
snipe
91fe136fd3 More nullables 2016-12-14 09:58:12 -08:00
snipe
37c847ea08 Clearer/updated/named custom fields routes
This is still broken
2016-12-14 09:56:23 -08:00
snipe
37f93a2861 Better validation using nullable 2016-12-14 09:55:45 -08:00
snipe
7c774352e5 Fix depreciated lists() method 2016-12-14 09:55:35 -08:00
snipe
863e200430 Hopefully fixes tons of PEBKAC where users have the wrong app.url 2016-12-14 08:20:05 -08:00
snipe
8e5977ad84 Updated maintenance views 2016-12-14 07:56:01 -08:00
snipe
a8d5d4a446 Specified PHP 5.6.4 for unit tests 2016-12-14 06:36:25 -08:00
snipe
68ac4abe2c Updated throttling override for 5.3 2016-12-14 06:30:51 -08:00
snipe
69031d4215 Put notifiable back in 2016-12-14 05:07:02 -08:00
snipe
433adb1dcb Updated traits and method names for 5.3 2016-12-14 05:06:51 -08:00
snipe
5cd7e84d98 Renamed Password controllers to new 5.3 versions 2016-12-14 05:06:15 -08:00
snipe
6f55db1251 Updated email addy 2016-12-14 04:38:03 -08:00
snipe
44312b0026 Removes c3 becase fuck codeception and fuck travis.io 2016-12-14 04:37:54 -08:00
snipe
c5b24c83df Updated app config for 5.3
THIS WILL BREAK ON UPGRADE RIGHT NOW.

I need to more gracefully handle the switch between mcrypt and the new cipher
2016-12-14 04:33:27 -08:00
snipe
f6e567d5d4 Updated dependencies for 5.3 2016-12-14 04:32:34 -08:00
snipe
b83f73f7d6 Updated providers for 5.3 2016-12-14 04:32:24 -08:00
snipe
8ca5c6c25e Moved routes to new new routes files for 5.3 2016-12-14 04:32:10 -08:00
snipe
f0dd4c5a97 Remove middleware for checking for maintenance
This is (mostly) a built-in feature in Laravel 5.3
2016-12-14 04:31:19 -08:00
snipe
65db55908a Rename to AuthController to LoginController 2016-12-14 04:30:56 -08:00
snipe
dd28c5709e Add action=“” to form (possible IE11 fix) 2016-12-12 19:23:41 -08:00
snipe
42fe481f71 Bumped hash 2016-12-12 19:06:36 -08:00
snipe
95f1a98b96 Removed extraneous closing label tags 2016-12-12 19:03:45 -08:00
snipe
6f1e0d6d9f Updated readme with security notice 2016-12-12 19:03:12 -08:00
snipe
ae66bba0f1 Fixes #3015 - increase size of state field in suppliers 2016-12-07 17:50:20 -08:00
snipe
32c5a258a7 Updated hash 2016-12-07 17:14:48 -08:00
snipe
e7ac860f77 Supress error if pagination isn’t set up on the server 2016-12-07 17:07:48 -08:00
snipe
899a991a3b Added package.json 2016-12-07 17:07:07 -08:00
snipe
f26d86dff2 Updated gulpfile 2016-12-07 17:06:48 -08:00
snipe
84317f7f50 Fixes #2990 - disabled autocomplete on login 2016-12-06 11:50:20 -08:00
3985 changed files with 583857 additions and 182596 deletions

651
.all-contributorsrc Normal file
View File

@@ -0,0 +1,651 @@
{
"projectName": "snipe-it",
"projectOwner": "snipe",
"files": [
"README.md"
],
"imageSize": 110,
"commit": true,
"contributors": [
{
"login": "snipe",
"name": "snipe",
"avatar_url": "https://avatars3.githubusercontent.com/u/197404?v=3",
"profile": "http://www.snipe.net",
"contributions": [
"code",
"infra",
"doc",
"test",
"bug",
"design",
"review"
]
},
{
"login": "uberbrady",
"name": "Brady Wetherington",
"avatar_url": "https://avatars0.githubusercontent.com/u/36335?v=3",
"profile": "http://www.uberbrady.com",
"contributions": [
"code",
"doc",
"infra",
"review"
]
},
{
"login": "dmeltzer",
"name": "Daniel Meltzer",
"avatar_url": "https://avatars0.githubusercontent.com/u/3803132?v=3",
"profile": "https://github.com/dmeltzer",
"contributions": [
"code",
"test",
"doc"
]
},
{
"login": "mtucker6784",
"name": "Michael T",
"avatar_url": "https://avatars0.githubusercontent.com/u/1609106?v=3",
"profile": "http://www.tuckertechonline.com",
"contributions": [
"code"
]
},
{
"login": "madd15",
"name": "madd15",
"avatar_url": "https://avatars2.githubusercontent.com/u/3274937?v=3",
"profile": "https://github.com/madd15",
"contributions": [
"doc",
"question"
]
},
{
"login": "vsposato",
"name": "Vincent Sposato",
"avatar_url": "https://avatars2.githubusercontent.com/u/894126?v=3",
"profile": "https://github.com/vsposato",
"contributions": [
"code"
]
},
{
"login": "vjandrea",
"name": "Andrea Bergamasco",
"avatar_url": "https://avatars0.githubusercontent.com/u/1639757?v=3",
"profile": "https://github.com/vjandrea",
"contributions": [
"code"
]
},
{
"login": "kpawelski",
"name": "Karol",
"avatar_url": "https://avatars0.githubusercontent.com/u/10640152?v=3",
"profile": "https://github.com/kpawelski",
"contributions": [
"translation",
"code"
]
},
{
"login": "morph027",
"name": "morph027",
"avatar_url": "https://avatars3.githubusercontent.com/u/600106?v=3",
"profile": "http://blog.morph027.de/",
"contributions": [
"code"
]
},
{
"login": "fvleminckx",
"name": "fvleminckx",
"avatar_url": "https://avatars3.githubusercontent.com/u/22935755?v=3",
"profile": "https://github.com/fvleminckx",
"contributions": [
"infra"
]
},
{
"login": "itsupportcmsukorg",
"name": "itsupportcmsukorg",
"avatar_url": "https://avatars2.githubusercontent.com/u/15633547?v=3",
"profile": "https://github.com/itsupportcmsukorg",
"contributions": [
"code",
"bug"
]
},
{
"login": "base-zero",
"name": "Frank",
"avatar_url": "https://avatars3.githubusercontent.com/u/12373799?v=3",
"profile": "https://override.io",
"contributions": [
"code"
]
},
{
"login": "ghost",
"name": "Deleted user",
"avatar_url": "https://avatars0.githubusercontent.com/u/10137?v=3",
"profile": "https://github.com/ghost",
"contributions": [
"translation"
]
},
{
"login": "tiagom62",
"name": "tiagom62",
"avatar_url": "https://avatars1.githubusercontent.com/u/10802313?v=3",
"profile": "https://github.com/tiagom62",
"contributions": [
"code",
"infra"
]
},
{
"login": "rystaf",
"name": "Ryan Stafford",
"avatar_url": "https://avatars3.githubusercontent.com/u/2389047?v=3",
"profile": "https://github.com/rystaf",
"contributions": [
"code"
]
},
{
"login": "ehanlon",
"name": "Eammon Hanlon",
"avatar_url": "https://avatars2.githubusercontent.com/u/10345935?v=3",
"profile": "https://github.com/ehanlon",
"contributions": [
"code"
]
},
{
"login": "zjean",
"name": "zjean",
"avatar_url": "https://avatars0.githubusercontent.com/u/441924?v=3",
"profile": "https://github.com/zjean",
"contributions": [
"code"
]
},
{
"login": "FREImedia",
"name": "Matthias Frei",
"avatar_url": "https://avatars0.githubusercontent.com/u/12660103?v=3",
"profile": "http://www.frei.media",
"contributions": [
"code"
]
},
{
"login": "opsydev",
"name": "opsydev",
"avatar_url": "https://avatars0.githubusercontent.com/u/3767518?v=3",
"profile": "https://github.com/opsydev",
"contributions": [
"code"
]
},
{
"login": "ddreier",
"name": "Daniel Dreier",
"avatar_url": "https://avatars1.githubusercontent.com/u/82290?v=3",
"profile": "http://www.ddreier.com",
"contributions": [
"code"
]
},
{
"login": "rassie",
"name": "Nikolai Prokoschenko",
"avatar_url": "https://avatars0.githubusercontent.com/u/23448?v=3",
"profile": "http://rassie.org",
"contributions": [
"code"
]
},
{
"login": "YetAnotherCodeMonkey",
"name": "Drew",
"avatar_url": "https://avatars0.githubusercontent.com/u/13452757?v=3",
"profile": "https://github.com/YetAnotherCodeMonkey",
"contributions": [
"code"
]
},
{
"login": "merid14",
"name": "Walter",
"avatar_url": "https://avatars0.githubusercontent.com/u/1342320?v=3",
"profile": "https://github.com/merid14",
"contributions": [
"code"
]
},
{
"login": "balous",
"name": "Petr Baloun",
"avatar_url": "https://avatars3.githubusercontent.com/u/11254614?v=3",
"profile": "https://github.com/balous",
"contributions": [
"code"
]
},
{
"login": "reidblomquist",
"name": "reidblomquist",
"avatar_url": "https://avatars0.githubusercontent.com/u/6117660?v=3",
"profile": "https://github.com/reidblomquist",
"contributions": [
"doc"
]
},
{
"login": "mathieuk",
"name": "Mathieu Kooiman",
"avatar_url": "https://avatars0.githubusercontent.com/u/539914?v=3",
"profile": "https://github.com/mathieuk",
"contributions": [
"code"
]
},
{
"login": "csayre",
"name": "csayre",
"avatar_url": "https://avatars3.githubusercontent.com/u/6606421?v=3",
"profile": "https://github.com/csayre",
"contributions": [
"doc"
]
},
{
"login": "adamdunson",
"name": "Adam Dunson",
"avatar_url": "https://avatars1.githubusercontent.com/u/768488?v=3",
"profile": "https://github.com/adamdunson",
"contributions": [
"code"
]
},
{
"login": "thehereward",
"name": "Hereward",
"avatar_url": "https://avatars0.githubusercontent.com/u/5547470?v=3",
"profile": "https://github.com/thehereward",
"contributions": [
"code"
]
},
{
"login": "swoopdk",
"name": "swoopdk",
"avatar_url": "https://avatars0.githubusercontent.com/u/5802977?v=3",
"profile": "https://github.com/swoopdk",
"contributions": [
"code"
]
},
{
"login": "Ahimta",
"name": "Abdullah Alansari",
"avatar_url": "https://avatars1.githubusercontent.com/u/3470403?v=3",
"profile": "https://linkedin.com/in/ahimta",
"contributions": [
"code"
]
},
{
"login": "MicaelRodrigues",
"name": "Micael Rodrigues",
"avatar_url": "https://avatars0.githubusercontent.com/u/796443?v=3",
"profile": "https://github.com/MicaelRodrigues",
"contributions": [
"code"
]
},
{
"login": "patgmac",
"name": "Patrick Gallagher",
"avatar_url": "https://avatars0.githubusercontent.com/u/614564?v=3",
"profile": "http://macadmincorner.com",
"contributions": [
"doc"
]
},
{
"login": "Miliamber",
"name": "Miliamber",
"avatar_url": "https://avatars3.githubusercontent.com/u/7165922?v=3",
"profile": "https://github.com/Miliamber",
"contributions": [
"code"
]
},
{
"login": "hawk554",
"name": "hawk554",
"avatar_url": "https://avatars3.githubusercontent.com/u/861766?v=3",
"profile": "https://github.com/hawk554",
"contributions": [
"code"
]
},
{
"login": "jbirdkerr",
"name": "Justin Kerr",
"avatar_url": "https://avatars1.githubusercontent.com/u/1695622?v=3",
"profile": "http://jbirdkerr.net",
"contributions": [
"code"
]
},
{
"login": "irasnyd",
"name": "Ira W. Snyder",
"avatar_url": "https://avatars3.githubusercontent.com/u/11426176?v=3",
"profile": "http://www.irasnyder.com/devel/",
"contributions": [
"doc"
]
},
{
"login": "aalaily",
"name": "Aladin Alaily",
"avatar_url": "https://avatars2.githubusercontent.com/u/2475759?v=3",
"profile": "https://github.com/aalaily",
"contributions": [
"code"
]
},
{
"login": "kobie-chasehansen",
"name": "Chase Hansen",
"avatar_url": "https://avatars0.githubusercontent.com/u/10247644?v=3",
"profile": "https://github.com/kobie-chasehansen",
"contributions": [
"code",
"question",
"bug"
]
},
{
"login": "IDM-Helpdesk",
"name": "IDM Helpdesk",
"avatar_url": "https://avatars2.githubusercontent.com/u/13545400?v=3",
"profile": "https://github.com/IDM-Helpdesk",
"contributions": [
"code"
]
},
{
"login": "balticer",
"name": "Kai",
"avatar_url": "https://avatars2.githubusercontent.com/u/614439?v=3",
"profile": "http://balticer.de",
"contributions": [
"code"
]
},
{
"login": "mdaniels5757",
"name": "Michael Daniels",
"avatar_url": "https://avatars1.githubusercontent.com/u/8762511?v=3",
"profile": "http://www.michaeldaniels.me",
"contributions": [
"code"
]
},
{
"login": "tomcastleman",
"name": "Tom Castleman",
"avatar_url": "https://avatars3.githubusercontent.com/u/1532660?v=3",
"profile": "http://tomcastleman.me",
"contributions": [
"code"
]
},
{
"login": "DanielNemanic",
"name": "Daniel Nemanic",
"avatar_url": "https://avatars3.githubusercontent.com/u/10723243?v=3",
"profile": "https://github.com/DanielNemanic",
"contributions": [
"code"
]
},
{
"login": "southwolf",
"name": "SouthWolf",
"avatar_url": "https://avatars0.githubusercontent.com/u/150648?v=3",
"profile": "https://github.com/southwolf",
"contributions": [
"code"
]
},
{
"login": "ivarne",
"name": "Ivar Nesje",
"avatar_url": "https://avatars2.githubusercontent.com/u/131616?v=3",
"profile": "https://github.com/ivarne",
"contributions": [
"code"
]
},
{
"login": "j0k3r",
"name": "Jérémy Benoist",
"avatar_url": "https://avatars1.githubusercontent.com/u/62333?v=3",
"profile": "http://www.j0k3r.net",
"contributions": [
"doc"
]
},
{
"login": "cleathley",
"name": "Chris Leathley",
"avatar_url": "https://avatars2.githubusercontent.com/u/724344?v=3",
"profile": "https://github.com/cleathley",
"contributions": [
"infra"
]
},
{
"login": "splaer",
"name": "splaer",
"avatar_url": "https://avatars0.githubusercontent.com/u/972498?v=3",
"profile": "https://github.com/splaer",
"contributions": [
"bug",
"code"
]
},
{
"login": "svpernova09",
"name": "Joe Ferguson",
"avatar_url": "https://avatars1.githubusercontent.com/u/967362?v=3",
"profile": "http://www.joeferguson.me",
"contributions": [
"code"
]
},
{
"login": "diwanicki",
"name": "diwanicki",
"avatar_url": "https://avatars3.githubusercontent.com/u/6108682?v=3",
"profile": "https://github.com/diwanicki",
"contributions": [
"code",
"doc"
]
},
{
"login": "pakkua80",
"name": "Lee Thoong Ching",
"avatar_url": "https://avatars3.githubusercontent.com/u/2527115?v=3",
"profile": "https://github.com/pakkua80",
"contributions": [
"doc"
]
},
{
"login": "mrshu",
"name": "Marek Šuppa",
"avatar_url": "https://avatars1.githubusercontent.com/u/461491?v=3",
"profile": "http://shu.io",
"contributions": [
"code"
]
},
{
"login": "mizar1616",
"name": "Juan J. Martinez",
"avatar_url": "https://avatars1.githubusercontent.com/u/8693762?v=3",
"profile": "https://github.com/mizar1616",
"contributions": [
"translation"
]
},
{
"login": "rrdial",
"name": "R Ryan Dial",
"avatar_url": "https://avatars1.githubusercontent.com/u/1458388?v=3",
"profile": "https://github.com/rrdial",
"contributions": [
"translation"
]
},
{
"login": "burlito",
"name": "Andrej Manduch",
"avatar_url": "https://avatars2.githubusercontent.com/u/2871745?v=3",
"profile": "https://github.com/burlito",
"contributions": [
"doc"
]
},
{
"login": "technogenus",
"name": "Jay Richards",
"avatar_url": "https://avatars0.githubusercontent.com/u/8341172?v=3",
"profile": "http://www.cordeos.com",
"contributions": [
"code"
]
},
{
"login": "leostat",
"name": "Alexander Innes",
"avatar_url": "https://avatars2.githubusercontent.com/u/7295127?v=3",
"profile": "https://necurity.co.uk",
"contributions": [
"code"
]
},
{
"login": "buzzedword",
"name": "Danny Garcia",
"avatar_url": "https://avatars2.githubusercontent.com/u/334485?v=3",
"profile": "https://buzzedword.codes",
"contributions": [
"code"
]
},
{
"login": "archpoint",
"name": "archpoint",
"avatar_url": "https://avatars2.githubusercontent.com/u/366855?v=3",
"profile": "https://github.com/archpoint",
"contributions": [
"code"
]
},
{
"login": "jakemcgraw",
"name": "Jake McGraw",
"avatar_url": "https://avatars1.githubusercontent.com/u/67991?v=3",
"profile": "http://www.jakemcgraw.com",
"contributions": [
"code"
]
},
{
"login": "FleischKarussel",
"name": "FleischKarussel",
"avatar_url": "https://avatars1.githubusercontent.com/u/1714374?v=3",
"profile": "https://github.com/FleischKarussel",
"contributions": [
"doc"
]
},
{
"login": "feeva",
"name": "Dylan Yi",
"avatar_url": "https://avatars3.githubusercontent.com/u/319644?v=3",
"profile": "https://github.com/feeva",
"contributions": [
"code"
]
},
{
"login": "flashingcursor",
"name": "Gil Rutkowski",
"avatar_url": "https://avatars2.githubusercontent.com/u/857740?v=3",
"profile": "http://FlashingCursor.com",
"contributions": [
"code"
]
},
{
"login": "desmondmorris",
"name": "Desmond Morris",
"avatar_url": "https://avatars3.githubusercontent.com/u/129360?v=3",
"profile": "http://www.desmondmorris.com",
"contributions": [
"code"
]
},
{
"login": "peelman",
"name": "Nick Peelman",
"avatar_url": "https://avatars2.githubusercontent.com/u/52936?v=3",
"profile": "http://peelman.us",
"contributions": [
"code"
]
},
{
"login": "abrahamvegh",
"name": "Abraham Vegh",
"avatar_url": "https://avatars0.githubusercontent.com/u/53161?v=3",
"profile": "https://abrahamvegh.com",
"contributions": [
"code"
]
},
{
"login": "rashivkp",
"name": "Mohamed Rashid",
"avatar_url": "https://avatars0.githubusercontent.com/u/2818680?v=3",
"profile": "https://github.com/rashivkp",
"contributions": [
"doc"
]
},
{
"login": "HinchK",
"name": "Kasey",
"avatar_url": "https://avatars3.githubusercontent.com/u/1509456?v=3",
"profile": "http://hinchk.github.io",
"contributions": [
"code"
]
}
]
}

View File

@@ -93,3 +93,4 @@ APP_LOCKED=false
FILESYSTEM_DISK=local
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
ALLOW_IFRAMING=false
APP_CIPHER=AES-256-CBC

View File

@@ -3,7 +3,7 @@
# --------------------------------------------
APP_ENV=testing
APP_DEBUG=true
APP_KEY=ChangeMe
APP_KEY=base64:glJpcM7BYwWiBggp3SQ/+NlRkqsBQMaGEOjemXqJzOU=
APP_URL=http://localhost:8000
APP_TIMEZONE='US/Pacific'
APP_LOCALE=en
@@ -21,7 +21,7 @@ DB_PASSWORD=null
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
# --------------------------------------------
MAIL_DRIVER=smtp
MAIL_DRIVER=log
MAIL_HOST=email-smtp.us-west-2.amazonaws.com
MAIL_PORT=587
MAIL_USERNAME=YOURUSERNAME
@@ -69,3 +69,4 @@ SECURE_COOKIES=false
# OPTIONAL: APP LOG FORMAT
# --------------------------------------------
APP_LOG=single
APP_LOG_LEVEL=debug

View File

@@ -21,7 +21,7 @@ DB_PASSWORD=null
# --------------------------------------------
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
# --------------------------------------------
MAIL_DRIVER=smtp
MAIL_DRIVER=log
MAIL_HOST=email-smtp.us-west-2.amazonaws.com
MAIL_PORT=587
MAIL_USERNAME=YOURUSERNAME

View File

@@ -7,3 +7,15 @@ DB_DATABASE=snipeittests
DB_USERNAME=snipeit
DB_PASSWORD=snipe
APP_KEY=base64:tu9NRh/a6+dCXBDGvg0Gv/0TcABnFsbT4AKxrr8mwQo=
# --------------------------------------------
# OPTIONAL: LOGIN THROTTLING
# (LOGIN_LOCKOUT_DURATIONin minutes)
# --------------------------------------------
LOGIN_MAX_ATTEMPTS=1000000
LOGIN_LOCKOUT_DURATION=100000000
MAIL_DRIVER=log
MAIL_FROM_ADDR=you@example.com
MAIL_FROM_NAME=Snipe-IT

4
.gitignore vendored
View File

@@ -38,3 +38,7 @@ tests/_data/scenarios
tests/_output/*
tests/_support/_generated/*
/npm-debug.log
/storage/oauth-private.key
/storage/oauth-public.key
*.cache

View File

@@ -14,18 +14,19 @@ php:
# execute any number of scripts before the test run, custom env's are available as variables
before_script:
- phantomjs --webdriver=4444 &
- sleep 10
- sleep 4
- mysql -e "create database IF NOT EXISTS snipeit_unit;" -utravis
- composer self-update
- composer install -n --prefer-source
- cp .env.testing-ci .env
- chmod -R 777 storage
- php artisan migrate --database=mysql --force
- php artisan migrate --env=testing-ci --database=mysql --force
- ./vendor/bin/codecept build
- php artisan key:generate
- php artisan db:seed --database=mysql --force
- php artisan snipeit:create-admin --first_name=Alison --last_name=Foobar --email=me@example.com --username=snipe --password=password
- php artisan serve --port=8000 --host=localhost &
- php artisan --env=testing-ci key:generate
- 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
- pip install --user codecov
- sleep 5
@@ -34,16 +35,21 @@ before_script:
# omitting "script:" will default to phpunit
# use the $DB env variable to determine the phpunit.xml to use
# script: ./vendor/bin/codecept run --env testing-ci - broken :(
script: ./vendor/bin/codecept run unit --env testing-ci
# script: ./vendor/bin/codecept run --env testing-ci
script:
- ./vendor/bin/codecept run unit --env testing-ci
# - ./vendor/bin/codecept run acceptance --env=testing-ci
- ./vendor/bin/codecept run functional --env=functional-travis
#script: ./vendor/bin/codecept run
- ./vendor/bin/codecept run api --env=testing-ci
after_success:
- codecov
after_failure:
- cat tests/_output/AccessoriesCept.fail.html
- cat tests/_output/*.fail.html
- curl http://localhost:8000/login
- cat storage/logs/laravel.log
# configure notifications (email, IRC, campfire etc)
notifications:

View File

@@ -1,4 +1,4 @@
FROM ubuntu:trusty
FROM debian:jessie-slim
MAINTAINER Brady Wetherington <uberbrady@gmail.com>
RUN apt-get update && apt-get install -y \
@@ -13,7 +13,9 @@ patch \
curl \
vim \
git \
mysql-client
mysql-client \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN php5enmod mcrypt
RUN php5enmod gd
@@ -55,7 +57,6 @@ RUN chown -R docker /var/www/html
RUN \
rm -r "/var/www/html/storage/private_uploads" && ln -fs "/var/lib/snipeit/data/private_uploads" "/var/www/html/storage/private_uploads" \
&& mkdir -p "/var/lib/snipeit/data/uploads/{assets,avatars,barcodes,models,suppliers}" \
&& rm -rf "/var/www/html/public/uploads" && ln -fs "/var/lib/snipeit/data/uploads" "/var/www/html/public/uploads" \
&& rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups"

View File

@@ -1,11 +1,12 @@
[![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)
## Snipe-IT - Open Source Asset Management System
This is a FOSS project for asset management in IT Operations. Knowing who has which laptop, when it was purchased in order to depreciate it correctly, handling software licenses, etc.
It is built on [Laravel 5.2](http://laravel.com).
It is built on [Laravel 5.4](http://laravel.com).
Snipe-IT is actively developed and we're [releasing quite frequently](https://github.com/snipe/snipe-it/releases). ([Check out the live demo here](https://snipeitapp.com/demo/).)
@@ -21,12 +22,14 @@ If you're having trouble with the installation, please check the [Common Issues]
-----
### User's Manual
For help using Snipe-IT, check out the [user's manual](https://snipe-it-manual.readme.io/docs).
For help using Snipe-IT, check out the [user's manual](https://snipe-it.readme.io/docs/overview).
-----
### Bug Reports & Feature Requests
Feel free to check out the [GitHub Issues for this project](https://github.com/snipe/snipe-it/issues) to open a bug report or see what open issues you can help with. Please search through existing issues (open and closed) to see if your question hasn't already been answered before opening a new issue.
Feel free to check out the [GitHub Issues for this project](https://github.com/snipe/snipe-it/issues) to open a bug report or see what open issues you can help with. Please search through existing issues (open *and* closed) to see if your question has already been answered before opening a new issue.
**PLEASE see the [Getting Help Guidelines](https://snipe-it.readme.io/docs/getting-help) and [Common Issues](https://snipe-it.readme.io/docs/common-issues) before opening a ticket, and be sure to complete all of the questions in the Github Issue template to help us to help you as quickly as possible.**
-----
@@ -47,9 +50,37 @@ Please see the [translations documentation](https://snipe-it.readme.io/docs/tran
-----
### Contributors
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://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) |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
-----
### 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.
-----
### Security
To report a security vulnerability, please email security@snipeitapp.com instead of using the issue tracker.

View File

@@ -1,463 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\User;
use App\Models\Location;
use App\Models\Category;
use App\Models\AssetModel;
use App\Models\Company;
use App\Models\Asset;
use App\Models\Manufacturer;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Illuminate\Console\Command;
use League\Csv\Reader;
class AssetImportCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'snipeit:asset-import';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Import Assets 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 Assets from '.$filename.' =========');
} else {
$this->comment('====== TEST ONLY Asset 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
// User's name
if (array_key_exists('0', $row)) {
$user_name = trim($row[0]);
} else {
$user_name = '';
}
// User's email
if (array_key_exists('1', $row)) {
$user_email = trim($row[1]);
} else {
$user_email = '';
}
// User's email
if (array_key_exists('2', $row)) {
$user_username = trim($row[2]);
} else {
$user_username = '';
}
// Asset Name
if (array_key_exists('3', $row)) {
$user_asset_asset_name = trim($row[3]);
} else {
$user_asset_asset_name = '';
}
// Asset Category
if (array_key_exists('4', $row)) {
$user_asset_category = trim($row[4]);
} else {
$user_asset_category = '';
}
// Asset Name
if (array_key_exists('5', $row)) {
$user_asset_name = trim($row[5]);
} else {
$user_asset_name = '';
}
// Asset Manufacturer
if (array_key_exists('6', $row)) {
$user_asset_mfgr = trim($row[6]);
} else {
$user_asset_mfgr = '';
}
// Asset model number
if (array_key_exists('7', $row)) {
$user_asset_modelno = trim($row[7]);
} else {
$user_asset_modelno = '';
}
// Asset serial number
if (array_key_exists('8', $row)) {
$user_asset_serial = trim($row[8]);
} else {
$user_asset_serial = '';
}
// Asset tag
if (array_key_exists('9', $row)) {
$user_asset_tag = trim($row[9]);
} else {
$user_asset_tag = '';
}
// Asset location
if (array_key_exists('10', $row)) {
$user_asset_location = trim($row[10]);
} else {
$user_asset_location = '';
}
// Asset notes
if (array_key_exists('11', $row)) {
$user_asset_notes = trim($row[11]);
} else {
$user_asset_notes = '';
}
// Asset purchase date
if (array_key_exists('12', $row)) {
if ($row[12]!='') {
$user_asset_purchase_date = date("Y-m-d 00:00:01", strtotime($row[12]));
} else {
$user_asset_purchase_date = '';
}
} else {
$user_asset_purchase_date = '';
}
// Asset purchase cost
if (array_key_exists('13', $row)) {
if ($row[13]!='') {
$user_asset_purchase_cost = trim($row[13]);
} else {
$user_asset_purchase_cost = '';
}
} else {
$user_asset_purchase_cost = '';
}
// Asset Company Name
if (array_key_exists('14', $row)) {
if ($row[14]!='') {
$user_asset_company_name = trim($row[14]);
} else {
$user_asset_company_name= '';
}
} else {
$user_asset_company_name = '';
}
// 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 = '';
$first_name = '';
$last_name = '';
// No name was given
} elseif ($user_name=='') {
$this->comment('No user data provided - skipping user creation, just adding asset');
$first_name = '';
$last_name = '';
//$user_username = '';
} else {
$user_email_array = User::generateFormattedNameFromFullName($this->option('email_format'), $user_name);
$first_name = $user_email_array['first_name'];
$last_name = $user_email_array['last_name'];
if ($user_email=='') {
$user_email = $user_email_array['username'].'@'.config('app.domain');
}
if ($user_username=='') {
if ($this->option('username_format')=='email') {
$user_username = $user_email;
} else {
$user_name_array = User::generateFormattedNameFromFullName($this->option('username_format'), $user_name);
$user_username = $user_name_array['username'];
}
}
}
$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('Category Name: '.$user_asset_category);
$this->comment('Item: '.$user_asset_name);
$this->comment('Manufacturer ID: '.$user_asset_mfgr);
$this->comment('Model No: '.$user_asset_modelno);
$this->comment('Serial No: '.$user_asset_serial);
$this->comment('Asset Tag: '.$user_asset_tag);
$this->comment('Location: '.$user_asset_location);
$this->comment('Purchase Date: '.$user_asset_purchase_date);
$this->comment('Purchase Cost: '.$user_asset_purchase_cost);
$this->comment('Notes: '.$user_asset_notes);
$this->comment('Company Name: '.$user_asset_company_name);
$this->comment('------------- Action Summary ----------------');
if ($user_username!='') {
if ($user = User::MatchEmailOrUsername($user_username, $user_email)
->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());
}
}
} else {
$user = new User;
}
// Check for the location match and create it if it doesn't exist
if ($location = Location::where('name', e($user_asset_location))->first()) {
$this->comment('Location '.$user_asset_location.' already exists');
} else {
$location = new Location();
if ($user_asset_location!='') {
$location->name = e($user_asset_location);
$location->address = '';
$location->city = '';
$location->state = '';
$location->country = '';
$location->user_id = 1;
if (!$this->option('testrun')=='true') {
if ($location->save()) {
$this->comment('Location '.$user_asset_location.' was created');
} else {
$this->error('Something went wrong! Location '.$user_asset_location.' was NOT created');
$this->error($location->getErrors());
}
} else {
$this->comment('Location '.$user_asset_location.' was (not) created - test run only');
}
} else {
$this->comment('No location given, so none created.');
}
}
if (e($user_asset_category)=='') {
$category_name = 'Unnamed Category';
} else {
$category_name = e($user_asset_category);
}
// Check for the category match and create it if it doesn't exist
if ($category = Category::where('name', e($category_name))->where('category_type', 'asset')->first()) {
$this->comment('Category '.$category_name.' already exists');
} else {
$category = new Category();
$category->name = e($category_name);
$category->category_type = 'asset';
$category->user_id = 1;
if ($category->save()) {
$this->comment('Category '.$user_asset_category.' was created');
} else {
$this->error('Something went wrong! Category '.$user_asset_category.' was NOT created');
$this->error($category->getErrors());
}
}
// Check for the manufacturer match and create it if it doesn't exist
if ($manufacturer = Manufacturer::where('name', e($user_asset_mfgr))->first()) {
$this->comment('Manufacturer '.$user_asset_mfgr.' already exists');
} else {
$manufacturer = new Manufacturer();
$manufacturer->name = e($user_asset_mfgr);
$manufacturer->user_id = 1;
if ($manufacturer->save()) {
$this->comment('Manufacturer '.$user_asset_mfgr.' was created');
} else {
$this->error('Something went wrong! Manufacturer '.$user_asset_mfgr.' was NOT created: '. $manufacturer->getErrors()->first());
}
}
// Check for the asset model match and create it if it doesn't exist
if ($asset_model = AssetModel::where('name', e($user_asset_name))->where('modelno', e($user_asset_modelno))->where('category_id', $category->id)->where('manufacturer_id', $manufacturer->id)->first()) {
$this->comment('The Asset Model '.$user_asset_name.' with model number '.$user_asset_modelno.' already exists');
} else {
$asset_model = new AssetModel();
$asset_model->name = e($user_asset_name);
$asset_model->manufacturer_id = $manufacturer->id;
$asset_model->modelno = e($user_asset_modelno);
$asset_model->category_id = $category->id;
$asset_model->user_id = 1;
if ($asset_model->save()) {
$this->comment('Asset Model '.$user_asset_name.' with model number '.$user_asset_modelno.' was created');
} else {
$this->error('Something went wrong! Asset Model '.$user_asset_name.' was NOT created: '.$asset_model->getErrors()->first());
}
}
// Check for the asset company match and create it if it doesn't exist
if ($user_asset_company_name!='') {
if ($company = Company::where('name', e($user_asset_company_name))->first()) {
$this->comment('Company '.$user_asset_company_name.' already exists');
} else {
$company = new Company();
$company->name = e($user_asset_company_name);
if ($company->save()) {
$this->comment('Company '.$user_asset_company_name.' was created');
} else {
$this->error('Something went wrong! Company '.$user_asset_company_name.' was NOT created: '.$company->getErrors()->first());
}
}
} else {
$company = new Company();
}
// Check for the asset match and create it if it doesn't exist
if ($asset = Asset::where('asset_tag', e($user_asset_tag))->first()) {
$this->comment('The Asset with asset tag '.$user_asset_tag.' already exists');
} else {
$asset = new Asset();
$asset->name = e($user_asset_asset_name);
if ($user_asset_purchase_date!='') {
$asset->purchase_date = $user_asset_purchase_date;
} else {
$asset->purchase_date = null;
}
if ($user_asset_purchase_cost!='') {
$asset->purchase_cost = ParseFloat(e($user_asset_purchase_cost));
} else {
$asset->purchase_cost = 0.00;
}
$asset->serial = e($user_asset_serial);
$asset->asset_tag = e($user_asset_tag);
$asset->model_id = $asset_model->id;
$asset->assigned_to = $user->id;
$asset->rtd_location_id = $location->id;
$asset->user_id = 1;
$asset->status_id = $status_id;
$asset->company_id = $company->id;
if ($user_asset_purchase_date!='') {
$asset->purchase_date = $user_asset_purchase_date;
} else {
$asset->purchase_date = null;
}
$asset->notes = e($user_asset_notes);
if ($asset->save()) {
$this->comment('Asset '.$user_asset_name.' with serial number '.$user_asset_serial.' was created');
} else {
$this->error('Something went wrong! Asset '.$user_asset_name.' was NOT created: '.$asset->getErrors()->first());
}
}
$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('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_REQUIRED, 'Test the output without writing to the database or not.', null),
);
}
}

View File

@@ -69,12 +69,24 @@ class LdapSync extends Command
$results = Ldap::findLdapUsers();
$ldap_ou_locations = Location::whereNotNull('ldap_ou')->get();
if (sizeof($ldap_ou_locations) > 0) {
LOG::debug('Some locations have special OUs set. Locations will be automatically set for users in those OUs.');
}
$results = Ldap::findLdapUsers();
for ($i = 0; $i < $results["count"]; $i++) {
$results[$i]["ldap_location_override"] = false;
$results[$i]["location_id"] = 0;
}
if ($this->option('location')!='') {
$location = Location::where('name','=',$this->option('location'))->first();
$location = Location::where('name', '=', $this->option('location'))->first();
LOG::debug('Location name '.$this->option('location').' passed');
LOG::debug('Importing to '.$location->name.' ('.$location->id.')');
} elseif ($this->option('location_id')!='') {
$location = Location::where('id','=',$this->option('location_id'))->first();
$location = Location::where('id', '=', $this->option('location_id'))->first();
LOG::debug('Location ID '.$this->option('location_id').' passed');
LOG::debug('Importing to '.$location->name.' ('.$location->id.')');
} else {
@@ -82,9 +94,30 @@ class LdapSync extends Command
}
if (!isset($location)) {
LOG::debug('That location is invalid, so no location will be assigned.');
LOG::debug('That location is invalid, so no location will be assigned by default.');
}
// Grab subsets based on location-specific DNs, and overwrite location for these users.
foreach ($ldap_ou_locations as $ldap_loc) {
$location_users = Ldap::findLdapUsers($ldap_loc->ldap_ou);
$usernames = array();
for ($i = 0; $i < $location_users["count"]; $i++) {
$location_users[$i]["ldap_location_override"] = true;
$location_users[$i]["location_id"] = $ldap_loc->id;
$usernames[] = $location_users[$i][$ldap_result_username][0];
}
// Delete located users from the general group.
foreach ($results as $key => $generic_entry) {
if (in_array($generic_entry[$ldap_result_username][0], $location_users)) {
unset($results[$key]);
}
}
$global_count = $results['count'];
$results = array_merge($location_users, $results);
$results['count'] = $global_count;
}
$tmp_pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$pass = bcrypt($tmp_pass);
@@ -99,6 +132,9 @@ class LdapSync extends Command
$item["lastname"] = isset($results[$i][$ldap_result_last_name][0]) ? $results[$i][$ldap_result_last_name][0] : "";
$item["firstname"] = isset($results[$i][$ldap_result_first_name][0]) ? $results[$i][$ldap_result_first_name][0] : "";
$item["email"] = isset($results[$i][$ldap_result_email][0]) ? $results[$i][$ldap_result_email][0] : "" ;
$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"]:"";
// User exists
$item["createorupdate"] = 'updated';
@@ -118,7 +154,9 @@ class LdapSync extends Command
$user->employee_num = e($item["employee_number"]);
$user->activated = 1;
if ($location) {
if ($item['ldap_location_override'] == true) {
$user->location_id = $item['location_id'];
} else if ($location) {
$user->location_id = e($location->id);
}
@@ -146,7 +184,7 @@ class LdapSync extends Command
if ($this->option('summary')) {
for ($x = 0; $x < count($summary); $x++) {
if ($summary[$x]['status']=='error') {
$this->error('ERROR: '.$summary[$x]['firstname'].' '.$summary[$x]['lastname'].' (username: '.$summary[$x]['username'].' was not imported: '.$summary[$x]['note'] );
$this->error('ERROR: '.$summary[$x]['firstname'].' '.$summary[$x]['lastname'].' (username: '.$summary[$x]['username'].' was not imported: '.$summary[$x]['note']);
} else {
$this->info('User '.$summary[$x]['firstname'].' '.$summary[$x]['lastname'].' (username: '.$summary[$x]['username'].' was '.strtoupper($summary[$x]['createorupdate']).'.');
}
@@ -159,6 +197,4 @@ class LdapSync extends Command
}
}

View File

@@ -9,6 +9,7 @@ use App\Models\User;
use App\Models\Supplier;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\Asset;
class LicenseImportCommand extends Command
{
@@ -168,6 +169,12 @@ class LicenseImportCommand extends Command
$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');
@@ -238,6 +245,7 @@ class LicenseImportCommand extends Command
$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 ----------------');
@@ -327,6 +335,13 @@ class LicenseImportCommand extends Command
$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++;
}

File diff suppressed because it is too large Load Diff

View File

@@ -117,6 +117,11 @@ class PaveIt extends Command
\DB::statement('drop table IF EXISTS manufacturers');
\DB::statement('drop table IF EXISTS models');
\DB::statement('drop table IF EXISTS migrations');
\DB::statement('drop table IF EXISTS oauth_access_tokens');
\DB::statement('drop table IF EXISTS oauth_auth_codes');
\DB::statement('drop table IF EXISTS oauth_clients');
\DB::statement('drop table IF EXISTS oauth_personal_access_clients');
\DB::statement('drop table IF EXISTS oauth_refresh_tokens');
\DB::statement('drop table IF EXISTS password_resets');
\DB::statement('drop table IF EXISTS requested_assets');
\DB::statement('drop table IF EXISTS requests');

View File

@@ -65,7 +65,7 @@ class Purge extends Command
$asset_maintenances = 0;
foreach ($assets as $asset) {
$this->info('- Asset "'.$asset->showAssetName().'" deleted.');
$this->info('- Asset "'.$asset->present()->name().'" deleted.');
$asset_assoc += $asset->assetlog()->count();
$asset->assetlog()->forceDelete();
$asset_maintenances += $asset->assetmaintenances()->count();

View File

@@ -55,7 +55,7 @@ class SendExpirationAlerts extends Command
foreach ($expiring_assets as $asset) {
$expires = $asset->warrantee_expires();
$expires = $asset->present()->warrantee_expires();
$difference = round(abs(strtotime($expires) - strtotime($now))/86400);
if ($difference > 30) {
@@ -64,11 +64,11 @@ class SendExpirationAlerts extends Command
$asset_data['email_content'] .= '<tr style="background-color:#d9534f;">';
}
$asset_data['email_content'] .= '<td><a href="'.config('app.url').'/hardware/'.e($asset->id).'/view">';
$asset_data['email_content'] .= $asset->showAssetName().'</a></td><td>'.e($asset->asset_tag).'</td>';
$asset_data['email_content'] .= '<td>'.e($asset->warrantee_expires()).'</td>';
$asset_data['email_content'] .= $asset->present()->name().'</a></td><td>'.e($asset->asset_tag).'</td>';
$asset_data['email_content'] .= '<td>'.e($asset->present()->warrantee_expires()).'</td>';
$asset_data['email_content'] .= '<td>'.$difference.' '.trans('mail.days').'</td>';
$asset_data['email_content'] .= '<td>'.($asset->supplier ? e($asset->supplier->name) : '').'</td>';
$asset_data['email_content'] .= '<td>'.($asset->assigneduser ? e($asset->assigneduser->fullName()) : '').'</td>';
$asset_data['email_content'] .= '<td>'.($asset->assignedTo ? e($asset->assignedTo->present()->name()) : '').'</td>';
$asset_data['email_content'] .= '</tr>';
}
@@ -89,7 +89,7 @@ class SendExpirationAlerts extends Command
} else {
$license_data['email_content'] .= '<tr style="background-color:#d9534f;">';
}
$license_data['email_content'] .= '<td><a href="'.config('app.url').'/admin/licenses/'.$license->id.'/view">';
$license_data['email_content'] .= '<td><a href="'.route('licenses.show', $license->id).'">';
$license_data['email_content'] .= $license->name.'</a></td>';
$license_data['email_content'] .= '<td>'.$license->expiration_date.'</td>';
$license_data['email_content'] .= '<td>'.$difference.' days</td>';

View File

@@ -42,7 +42,7 @@ class Versioning extends Command
{
$versionFile = 'config/version.php';
$hash_version = str_replace("\n",'',shell_exec('git describe --tags'));
$hash_version = str_replace("\n", '', shell_exec('git describe --tags'));
$version = explode('-', $hash_version);
@@ -52,18 +52,19 @@ class Versioning extends Command
'build_version' => $version[1],
'hash_version' => $version[2],
'full_hash' => $hash_version),
true);
true
);
// Construct our file content
$content = <<<CON
$content = <<<CON
<?php
return $array;
CON;
// And finally write the file and output the current version
\File::put($versionFile, $content);
$this->line('Setting version: '. config('version.app_version').' build '.config('version.build_version').' ('.config('version.hash_version').')');
\File::put($versionFile, $content);
$this->line('Setting version: '. config('version.app_version').' build '.config('version.build_version').' ('.config('version.hash_version').')');
}
/**

View File

@@ -40,4 +40,9 @@ class Kernel extends ConsoleKernel
$schedule->command('snipeit:backup')->weekly();
$schedule->command('backup:clean')->daily();
}
protected function commands()
{
require base_path('routes/console.php');
}
}

View File

@@ -3,11 +3,10 @@
namespace App\Exceptions;
use Exception;
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use App\Helpers\Helper;
use Illuminate\Validation\ValidationException;
class Handler extends ExceptionHandler
{
@@ -17,10 +16,12 @@ class Handler extends ExceptionHandler
* @var array
*/
protected $dontReport = [
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
\Illuminate\Auth\AuthenticationException::class,
\Illuminate\Auth\Access\AuthorizationException::class,
\Symfony\Component\HttpKernel\Exception\HttpException::class,
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
\Illuminate\Session\TokenMismatchException::class,
\Illuminate\Validation\ValidationException::class,
];
/**
@@ -28,12 +29,12 @@ class Handler extends ExceptionHandler
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
* @param \Exception $exception
* @return void
*/
public function report(Exception $e)
public function report(Exception $exception)
{
parent::report($e);
parent::report($exception);
}
/**
@@ -45,23 +46,71 @@ class Handler extends ExceptionHandler
*/
public function render($request, Exception $e)
{
// CSRF token mismatch error
if ($e instanceof \Illuminate\Session\TokenMismatchException) {
return redirect()->back()->with('error', trans('general.token_expired'));
return redirect()->back()->with('error', trans('general.token_expired'));
}
if ($this->isHttpException($e)) {
$statusCode = $e->getStatusCode();
// Handle Ajax requests that fail because the model doesn't exist
if ($request->ajax() || $request->wantsJson()) {
switch ($statusCode) {
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
$className = last(explode('\\', $e->getModel()));
return response()->json(Helper::formatStandardApiResponse('error', null, $className . ' not found'), 200);
}
case '404':
return response()->view('layouts/basic', [
'content' => view('errors/404')
]);
}
if ($e instanceof \Illuminate\Validation\ValidationException) {
return response()->json(Helper::formatStandardApiResponse('error', $e->response['messages'], $e->getMessage(), 400));
}
if ($this->isHttpException($e)) {
$statusCode = $e->getStatusCode();
switch ($e->getStatusCode()) {
case '404':
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode . ' endpoint not found'), 404);
case '405':
return response()->json(Helper::formatStandardApiResponse('error', null, 'Method not allowed'), 405);
default:
return response()->json(Helper::formatStandardApiResponse('error', null, $statusCode), 405);
}
}
// Try to parse 500 Errors ina bit nicer way when debug is enabled.
if (config('app.debug')) {
return response()->json(Helper::formatStandardApiResponse('error', null, "An Error has occured! " . $e->getMessage()), 500);
}
}
if ($this->isHttpException($e) && (isset($statusCode)) && ($statusCode == '404' )) {
return response()->view('layouts/basic', [
'content' => view('errors/404')
]);
}
return parent::render($request, $e);
}
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthorized.'], 401);
}
return redirect()->guest('login');
}
}

View File

@@ -17,6 +17,7 @@ use App\Models\Component;
use App\Models\Accessory;
use App\Models\Consumable;
use App\Models\Asset;
use App\Models\Setting;
use Crypt;
use Illuminate\Contracts\Encryption\DecryptException;
@@ -31,7 +32,8 @@ class Helper
* @since [v2.0]
* @return String
*/
public static function parseEscapedMarkedown($str) {
public static function parseEscapedMarkedown($str)
{
$Parsedown = new \Parsedown();
if ($str) {
@@ -123,6 +125,8 @@ class Helper
$LocaleInfo = localeconv();
$floatString = str_replace(",", "", $floatString);
$floatString = str_replace($LocaleInfo["decimal_point"], ".", $floatString);
// Strip Currency symbol
$floatString = str_replace($LocaleInfo['currency_symbol'], '', $floatString);
return floatval($floatString);
}
@@ -139,7 +143,7 @@ class Helper
$models = AssetModel::with('manufacturer')->get();
$model_array[''] = trans('general.select_model');
foreach ($models as $model) {
$model_array[$model->id] = $model->displayModelName();
$model_array[$model->id] = $model->present()->modelName();
}
return $model_array;
}
@@ -153,9 +157,10 @@ class Helper
*/
public static function companyList()
{
$company_list = array('0' => trans('general.select_company')) + DB::table('companies')
$company_list = array('' => trans('general.select_company')) + DB::table('companies')
->orderBy('name', 'asc')
->pluck('name', 'id');
->pluck('name', 'id')
->toArray();
return $company_list;
}
@@ -172,8 +177,9 @@ class Helper
$categories = Category::orderBy('name', 'asc')
->whereNull('deleted_at')
->orderBy('name', 'asc');
if(!empty($category_type))
if (!empty($category_type)) {
$categories = $categories->where('category_type', '=', $category_type);
}
$category_list = array('' => trans('general.select_category')) + $categories->pluck('name', 'id')->toArray();
return $category_list;
}
@@ -203,7 +209,7 @@ class Helper
*/
public static function statusLabelList()
{
$statuslabel_list = array('' => trans('general.select_statuslabel')) + Statuslabel::orderBy('name', 'asc')
$statuslabel_list = array('' => trans('general.select_statuslabel')) + Statuslabel::orderBy('deployable', 'desc')
->pluck('name', 'id')->toArray();
return $statuslabel_list;
}
@@ -248,7 +254,12 @@ class Helper
*/
public static function statusTypeList()
{
$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'));
$statuslabel_types =
array('' => trans('admin/hardware/form.select_statustype'))
+ array('deployable' => trans('admin/hardware/general.deployable'))
+ array('pending' => trans('admin/hardware/general.pending'))
+ array('undeployable' => trans('admin/hardware/general.undeployable'))
+ array('archived' => trans('admin/hardware/general.archived'));
return $statuslabel_types;
}
@@ -265,7 +276,7 @@ class Helper
User::where('deleted_at', '=', null)
->orderBy('last_name', 'asc')
->orderBy('first_name', 'asc')->get()
->lists('complete_name', 'id')->toArray();
->pluck('complete_name', 'id')->toArray();
return $manager_list;
}
@@ -308,10 +319,10 @@ class Helper
{
$users_list = array( '' => trans('general.select_user')) +
Company::scopeCompanyables(User::where('deleted_at', '=', null))
->where('show_in_list','=',1)
->where('show_in_list', '=', 1)
->orderBy('last_name', 'asc')
->orderBy('first_name', 'asc')->get()
->lists('complete_name', 'id')->toArray();
->pluck('complete_name', 'id')->toArray();
return $users_list;
}
@@ -336,11 +347,11 @@ class Helper
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.5]
* @return Array
* @return array
*/
public static function detailedAssetList()
{
$assets = array('' => trans('general.select_asset')) + Company::scopeCompanyables(Asset::with('assignedUser', 'model'), 'assets.company_id')->get()->lists('detailed_name', 'id')->toArray();
$assets = array('' => trans('general.select_asset')) + Company::scopeCompanyables(Asset::with('assignedTo', 'model'), 'assets.company_id')->get()->pluck('detailed_name', 'id')->toArray();
return $assets;
}
@@ -367,8 +378,8 @@ class Helper
*/
public static function predefined_formats()
{
$keys=array_keys(CustomField::$PredefinedFormats);
$stuff=array_combine($keys, $keys);
$keys = array_keys(CustomField::$PredefinedFormats);
$stuff = array_combine($keys, $keys);
return $stuff+["" => trans('admin/custom_fields/general.custom_format')];
}
@@ -553,7 +564,7 @@ class Helper
if ($permission[$x]['display'] === true) {
if ($selected_arr) {
if (array_key_exists($permission_name,$selected_arr)) {
if (array_key_exists($permission_name, $selected_arr)) {
$permissions_arr[$permission_name] = $selected_arr[$permission_name];
} else {
$permissions_arr[$permission_name] = '0';
@@ -584,7 +595,8 @@ class Helper
* @since [v3.0]
* @return boolean
*/
public static function checkIfRequired($class, $field) {
public static function checkIfRequired($class, $field)
{
$rules = $class::rules();
foreach ($rules as $rule_name => $rule) {
if ($rule_name == $field) {
@@ -611,28 +623,10 @@ class Helper
*/
public static function array_smart_fetch(array $array, $key, $default = '')
{
array_change_key_case($array, CASE_LOWER);
array_change_key_case($array, CASE_LOWER);
return array_key_exists(strtolower($key), array_change_key_case($array)) ? e(trim($array[ $key ])) : $default;
}
/**
* Check to see if the given key exists in the array, and trim excess white space before returning it
*
* @author A. Gianotto
* @since 3.2
* @param $array array
* @return string
*/
public static function getLastDateFromHistoryArray(array $array)
{
foreach ($array as $key => $value) {
// echo '<pre>';
// echo 'last:'.$key;
// print_r($array);
// echo '</pre>';
}
}
/**
* Gracefully handle decrypting the legacy data (encrypted via mcrypt) and use the new
@@ -646,7 +640,8 @@ class Helper
* @param String $string
* @return string
*/
public static function gracefulDecrypt(CustomField $field, $string) {
public static function gracefulDecrypt(CustomField $field, $string)
{
if ($field->isFieldDecryptable($string)) {
@@ -663,26 +658,53 @@ class Helper
}
/**
* Strip HTML out of returned JSON. This is pretty gross, and I'd like to find a better way
* to handle this, but the REST API will solve some of these problems anyway.
*
* This is not currently used, but will be.
*
* @author A. Gianotto
* @since 3.4
* @param $array array
* @return Array
*/
public static function stripTagsFromJSON(Array $array) {
foreach ($array as $key => $value) {
$clean_value = strip_tags($value);
$clean_array[$key] = $clean_value;
public static function formatStandardApiResponse($status, $payload = null, $messages = null) {
$array['status'] = $status;
($payload) ? $array['payload'] = $payload : '';
if (($messages) && (count($messages) > 0)) {
$array['messages'] = $messages;
}
return $clean_array;
return $array;
}
/*
Possible solution for unicode fieldnames
*/
public static function make_slug($string) {
return preg_replace('/\s+/u', '_', trim($string));
}
public static function getFormattedDateObject($date, $type = 'datetime', $array = true) {
if ($date=='') {
return null;
}
$settings = Setting::getSettings();
$tmp_date = new \Carbon($date);
if ($type == 'datetime') {
$dt['datetime'] = $tmp_date->format('Y-m-d H:i:s');
$dt['formatted'] = $tmp_date->format($settings->date_display_format .' '. $settings->time_display_format);
} else {
$dt['date'] = $tmp_date->format('Y-m-d');
$dt['formatted'] = $tmp_date->format($settings->date_display_format);
}
if ($array == 'true') {
return $dt;
}
return $dt['formatted'];
}
}

View File

@@ -3,9 +3,7 @@ namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Models\Accessory;
use App\Models\Actionlog;
use App\Models\Company;
use App\Models\Setting;
use App\Models\User;
use Auth;
use Carbon\Carbon;
@@ -16,7 +14,7 @@ use Input;
use Lang;
use Mail;
use Redirect;
use Request;
use Illuminate\Http\Request;
use Slack;
use Str;
use View;
@@ -38,8 +36,9 @@ class AccessoriesController extends Controller
* @since [v1.0]
* @return View
*/
public function getIndex(Request $request)
public function index(Request $request)
{
$this->authorize('index', Accessory::class);
return View::make('accessories/index');
}
@@ -50,8 +49,9 @@ class AccessoriesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @return View
*/
public function getCreate(Request $request)
public function create(Request $request)
{
$this->authorize('create', Accessory::class);
// Show the page
return View::make('accessories/edit')
->with('item', new Accessory)
@@ -68,45 +68,32 @@ class AccessoriesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @return Redirect
*/
public function postCreate(Request $request)
public function store(Request $request)
{
$this->authorize(Accessory::class);
// create a new model instance
$accessory = new Accessory();
// Update the accessory data
$accessory->name = e(Input::get('name'));
$accessory->category_id = e(Input::get('category_id'));
$accessory->location_id = e(Input::get('location_id'));
$accessory->min_amt = e(Input::get('min_amt'));
$accessory->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
$accessory->order_number = e(Input::get('order_number'));
$accessory->manufacturer_id = e(Input::get('manufacturer_id'));
$accessory->model_number = e(Input::get('model_number'));
if (e(Input::get('purchase_date')) == '') {
$accessory->purchase_date = null;
} else {
$accessory->purchase_date = e(Input::get('purchase_date'));
}
if (e(Input::get('purchase_cost')) == '0.00') {
$accessory->purchase_cost = null;
} else {
$accessory->purchase_cost = Helper::ParseFloat(e(Input::get('purchase_cost')));
}
$accessory->qty = e(Input::get('qty'));
$accessory->name = request('name');
$accessory->category_id = request('category_id');
$accessory->location_id = request('location_id');
$accessory->min_amt = request('min_amt');
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
$accessory->order_number = request('order_number');
$accessory->manufacturer_id = request('manufacturer_id');
$accessory->model_number = request('model_number');
$accessory->purchase_date = request('purchase_date');
$accessory->purchase_cost = Helper::ParseFloat(request('purchase_cost'));
$accessory->qty = request('qty');
$accessory->user_id = Auth::user()->id;
// Was the accessory created?
if ($accessory->save()) {
$accessory->logCreate();
// Redirect to the new accessory page
return redirect()->to("admin/accessories")->with('success', trans('admin/accessories/message.create.success'));
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
}
@@ -117,16 +104,16 @@ class AccessoriesController extends Controller
* @param int $accessoryId
* @return View
*/
public function getEdit(Request $request, $accessoryId = null)
public function edit(Request $request, $accessoryId = null)
{
// Check if the accessory exists
if (is_null($item = Accessory::find($accessoryId))) {
// Redirect to the blogs management page
return redirect()->to('admin/accessories')->with('error', trans('admin/accessories/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($item)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
$this->authorize($item);
return View::make('accessories/edit', compact('item'))
->with('category_list', Helper::categoryList('accessory'))
->with('company_list', Helper::companyList())
@@ -142,54 +129,35 @@ class AccessoriesController extends Controller
* @param int $accessoryId
* @return Redirect
*/
public function postEdit(Request $request, $accessoryId = null)
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()->to('admin/accessories')->with('error', trans('admin/accessories/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($accessory)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
// Update the accessory data
$accessory->name = e(Input::get('name'));
$this->authorize($accessory);
if (e(Input::get('location_id')) == '') {
$accessory->location_id = null;
} else {
$accessory->location_id = e(Input::get('location_id'));
}
$accessory->min_amt = e(Input::get('min_amt'));
$accessory->category_id = e(Input::get('category_id'));
$accessory->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
$accessory->manufacturer_id = e(Input::get('manufacturer_id'));
$accessory->order_number = e(Input::get('order_number'));
$accessory->model_number = e(Input::get('model_number'));
if (e(Input::get('purchase_date')) == '') {
$accessory->purchase_date = null;
} else {
$accessory->purchase_date = e(Input::get('purchase_date'));
}
if (e(Input::get('purchase_cost')) == '0.00') {
$accessory->purchase_cost = null;
} else {
$accessory->purchase_cost = e(Input::get('purchase_cost'));
}
$accessory->qty = e(Input::get('qty'));
// Update the accessory data
$accessory->name = request('name');
$accessory->location_id = request('location_id');
$accessory->min_amt = request('min_amt');
$accessory->category_id = request('category_id');
$accessory->company_id = Company::getIdForCurrentUser(request('company_id'));
$accessory->manufacturer_id = request('manufacturer_id');
$accessory->order_number = request('order_number');
$accessory->model_number = request('model_number');
$accessory->purchase_date = request('purchase_date');
$accessory->purchase_cost = request('purchase_cost');
$accessory->qty = request('qty');
// Was the accessory updated?
if ($accessory->save()) {
// Redirect to the updated accessory page
return redirect()->to("admin/accessories")->with('success', trans('admin/accessories/message.update.success'));
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
}
/**
@@ -199,26 +167,23 @@ class AccessoriesController extends Controller
* @param int $accessoryId
* @return Redirect
*/
public function getDelete(Request $request, $accessoryId)
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()->to('admin/accessories')->with('error', trans('admin/accessories/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($accessory)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
}
$this->authorize($accessory);
if ($accessory->hasUsers() > 0) {
return redirect()->to('admin/accessories')->with('error', trans('admin/accessories/message.assoc_users', array('count'=> $accessory->hasUsers())));
} else {
$accessory->delete();
// Redirect to the locations management page
return redirect()->to('admin/accessories')->with('success', trans('admin/accessories/message.delete.success'));
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'));
}
@@ -228,31 +193,23 @@ class AccessoriesController extends Controller
* the content for the accessory detail view, which is generated in getDataView.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $accessoryId
* @param int $accessoryID
* @see AccessoriesController::getDataView() method that generates the JSON response
* @since [v1.0]
* @return View
*/
public function getView(Request $request, $accessoryID = null)
public function show(Request $request, $accessoryID = null)
{
$accessory = Accessory::find($accessoryID);
$this->authorize('view', $accessory);
if (isset($accessory->id)) {
if (!Company::isCurrentUserHasAccess($accessory)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
} else {
return View::make('accessories/view', compact('accessory'));
}
} else {
// Prepare the error message
$error = trans('admin/accessories/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('accessories')->with('error', $error);
return View::make('accessories/view', compact('accessory'));
}
// Prepare the error message
$error = trans('admin/accessories/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('accessories')->with('error', $error);
}
/**
@@ -267,15 +224,13 @@ class AccessoriesController extends Controller
// Check if the accessory exists
if (is_null($accessory = Accessory::find($accessoryId))) {
// Redirect to the accessory management page with error
return redirect()->to('accessories')->with('error', trans('admin/accessories/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($accessory)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
}
// Get the dropdown of users and then pass it to the checkout view
$users_list = Helper::usersList();
$this->authorize('checkout', $accessory);
return View::make('accessories/checkout', compact('accessory'))->with('users_list', $users_list);
// 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());
}
@@ -294,64 +249,28 @@ class AccessoriesController extends Controller
// Check if the accessory exists
if (is_null($accessory = Accessory::find($accessoryId))) {
// Redirect to the accessory management page with error
return redirect()->to('accessories')->with('error', trans('admin/accessories/message.user_not_found'));
} elseif (!Company::isCurrentUserHasAccess($accessory)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.user_not_found'));
}
$this->authorize('checkout', $accessory);
if (!$user = User::find(Input::get('assigned_to'))) {
return redirect()->to('admin/accessories')->with('error', trans('admin/accessories/message.not_found'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
}
// Update the accessory data
$accessory->assigned_to = e(Input::get('assigned_to'));
$accessory->assigned_to = e(Input::get('assigned_to'));
$accessory->users()->attach($accessory->id, array(
'accessory_id' => $accessory->id,
'created_at' => Carbon::now(),
'user_id' => Auth::user()->id,
'assigned_to' => e(Input::get('assigned_to'))));
$accessory->users()->attach($accessory->id, [
'accessory_id' => $accessory->id,
'created_at' => Carbon::now(),
'user_id' => Auth::id(),
'assigned_to' => $request->get('assigned_to')
]);
$logaction = $accessory->logCheckout(e(Input::get('note')));
$admin_user = Auth::user();
$settings = Setting::getSettings();
if ($settings->slack_endpoint) {
$slack_settings = [
'username' => $settings->botname,
'channel' => $settings->slack_channel,
'link_names' => true
];
$client = new \Maknz\Slack\Client($settings->slack_endpoint, $slack_settings);
try {
$client->attach([
'color' => 'good',
'fields' => [
[
'title' => 'Checked Out:',
'value' => 'Accessory <'.config('app.url').'/admin/accessories/'.$accessory->id.'/view'.'|'.$accessory->name.'> checked out to <'.config('app.url').'/admin/users/'.$user->id.'/view|'.$user->fullName().'> by <'.config('app.url').'/admin/users/'.$admin_user->id.'/view'.'|'.$admin_user->fullName().'>.'
],
[
'title' => 'Note:',
'value' => e(Input::get('note'))
],
]
])->send('Accessory Checked Out');
} catch (Exception $e) {
}
}
$accessory_user = DB::table('accessories_users')->where('assigned_to', '=', $accessory->assigned_to)->where('accessory_id', '=', $accessory->id)->first();
DB::table('accessories_users')->where('assigned_to', '=', $accessory->assigned_to)->where('accessory_id', '=', $accessory->id)->first();
$data['log_id'] = $logaction->id;
$data['eula'] = $accessory->getEula();
@@ -362,8 +281,7 @@ class AccessoriesController extends Controller
$data['expected_checkin'] = '';
$data['note'] = $logaction->note;
$data['require_acceptance'] = $accessory->requireAcceptance();
// TODO: Port this to new mail notifications
if (($accessory->requireAcceptance()=='1') || ($accessory->getEula())) {
Mail::send('emails.accept-accessory', $data, function ($m) use ($user) {
@@ -374,104 +292,62 @@ class AccessoriesController extends Controller
}
// Redirect to the new accessory page
return redirect()->to("admin/accessories")->with('success', trans('admin/accessories/message.checkout.success'));
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.checkout.success'));
}
/**
* Check the accessory back into inventory
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $accessoryId
* @return View
**/
/**
* Check the accessory back into inventory
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param Request $request
* @param integer $accessoryUserId
* @param string $backto
* @return View
* @internal param int $accessoryId
*/
public function getCheckin(Request $request, $accessoryUserId = null, $backto = null)
{
// Check if the accessory exists
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
// Redirect to the accessory management page with error
return redirect()->to('admin/accessories')->with('error', trans('admin/accessories/message.not_found'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
}
$accessory = Accessory::find($accessory_user->accessory_id);
if (!Company::isCurrentUserHasAccess($accessory)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
} else {
return View::make('accessories/checkin', compact('accessory'))->with('backto', $backto);
}
$this->authorize('checkin', $accessory);
return View::make('accessories/checkin', compact('accessory'))->with('backto', $backto);
}
/**
* Check in the item so that it can be checked out again to someone else
*
* @uses Accessory::checkin_email() to determine if an email can and should be sent
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $accessoryId
* @return Redirect
**/
/**
* Check in the item so that it can be checked out again to someone else
*
* @uses Accessory::checkin_email() to determine if an email can and should be sent
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param Request $request
* @param integer $accessoryUserId
* @param string $backto
* @return Redirect
* @internal param int $accessoryId
*/
public function postCheckin(Request $request, $accessoryUserId = null, $backto = null)
{
// Check if the accessory exists
if (is_null($accessory_user = DB::table('accessories_users')->find($accessoryUserId))) {
// Redirect to the accessory management page with error
return redirect()->to('admin/accessories')->with('error', trans('admin/accessories/message.not_found'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
}
$accessory = Accessory::find($accessory_user->accessory_id);
if (!Company::isCurrentUserHasAccess($accessory)) {
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
}
$this->authorize('checkin', $accessory);
$return_to = e($accessory_user->assigned_to);
$logaction = $accessory->logCheckin(User::find($return_to), e(Input::get('note')));
$admin_user = Auth::user();
// Was the accessory updated?
// Was the accessory updated?
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {
$settings = Setting::getSettings();
if ($settings->slack_endpoint) {
$slack_settings = [
'username' => e($settings->botname),
'channel' => e($settings->slack_channel),
'link_names' => true
];
$client = new \Maknz\Slack\Client($settings->slack_endpoint, $slack_settings);
try {
$client->attach([
'color' => 'good',
'fields' => [
[
'title' => 'Checked In:',
'value' => class_basename(strtoupper($logaction->item_type)).' <'.config('app.url').'/admin/accessories/'.e($accessory->id).'/view'.'|'.e($accessory->name).'> checked in by <'.config('app.url').'/admin/users/'.e($admin_user->id).'/view'.'|'.e($admin_user->fullName()).'>.'
],
[
'title' => 'Note:',
'value' => e($logaction->note)
],
]
])->send('Accessory Checked In');
} catch (Exception $e) {
}
}
if (!is_null($accessory_user->assigned_to)) {
$user = User::find($accessory_user->assigned_to);
}
@@ -493,45 +369,45 @@ class AccessoriesController extends Controller
}
if ($backto=='user') {
return redirect()->to("admin/users/".$return_to.'/view')->with('success', trans('admin/accessories/message.checkin.success'));
} else {
return redirect()->to("admin/accessories/".$accessory->id."/view")->with('success', trans('admin/accessories/message.checkin.success'));
return redirect()->route("users.show", $return_to)->with('success', trans('admin/accessories/message.checkin.success'));
}
return redirect()->route("accessories.show", $accessory->id)->with('success', trans('admin/accessories/message.checkin.success'));
}
// Redirect to the accessory management page with error
return redirect()->to("admin/accessories")->with('error', trans('admin/accessories/message.checkin.error'));
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.checkin.error'));
}
/**
* Generates the JSON response for accessories listing view.
*
* Example:
* {
* "actions": "(links to available actions)",
* "category": "(link to category)",
* "companyName": "My Company",
* "location": "My Location",
* "min_amt": 2,
* "name": "(link to accessory),
* "numRemaining": 6,
* "order_number": null,
* "purchase_cost": "0.00",
* "purchase_date": null,
* "qty": 7
* },
*
* The names of the fields in the returns JSON correspond directly to the the
* names of the fields in the bootstrap-tables in the view.
*
* For debugging, see at /api/accessories/list
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $accessoryId
* @return string JSON containing accessories and their associated atrributes.
**/
* Generates the JSON response for accessories listing view.
*
* Example:
* {
* "actions": "(links to available actions)",
* "category": "(link to category)",
* "company": "My Company",
* "location": "My Location",
* "min_amt": 2,
* "name": "(link to accessory),
* "numRemaining": 6,
* "order_number": null,
* "purchase_cost": "0.00",
* "purchase_date": null,
* "qty": 7
* },
*
* The names of the fields in the returns JSON correspond directly to the the
* names of the fields in the bootstrap-tables in the view.
*
* For debugging, see at /api/accessories/list
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param Request $request
* @return string JSON containing accessories and their associated atrributes.
* @internal param int $accessoryId
*/
public function getDatatable(Request $request)
{
$this->authorize('index', Accessory::class);
$accessories = Company::scopeCompanyables(
Accessory::select('accessories.*')
->whereNull('accessories.deleted_at')
@@ -540,21 +416,10 @@ class AccessoriesController extends Controller
if (Input::has('search')) {
$accessories = $accessories->TextSearch(e(Input::get('search')));
}
$offset = request('offset', 0);
$limit = request('limit', 50);
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 = ['name','min_amt','order_number','purchase_date','purchase_cost','companyName','category','model_number'];
$allowed_columns = ['name','min_amt','order_number','purchase_date','purchase_cost','company','category','model_number', 'manufacturer', 'location'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
@@ -562,9 +427,15 @@ class AccessoriesController extends Controller
case 'category':
$accessories = $accessories->OrderCategory($order);
break;
case 'companyName':
case 'company':
$accessories = $accessories->OrderCompany($order);
break;
case 'location':
$accessories = $accessories->OrderLocation($order);
break;
case 'manufacturer':
$accessories = $accessories->OrderManufacturer($order);
break;
default:
$accessories = $accessories->orderBy($sort, $order);
break;
@@ -576,39 +447,7 @@ class AccessoriesController extends Controller
$rows = array();
foreach ($accessories as $accessory) {
$actions = '<nobr>';
if (Gate::allows('accessories.checkout')) {
$actions .= '<a href="' . route('checkout/accessory',
$accessory->id) . '" style="margin-right:5px;" class="btn btn-info btn-sm" ' . (($accessory->numRemaining() > 0) ? '' : ' disabled') . '>' . trans('general.checkout') . '</a>';
}
if (Gate::allows('accessories.edit')) {
$actions .= '<a href="' . route('update/accessory',
$accessory->id) . '" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a>';
}
if (Gate::allows('accessories.delete')) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/accessory',
$accessory->id) . '" data-content="' . trans('admin/accessories/message.delete.confirm') . '" data-title="' . trans('general.delete') . ' ' . htmlspecialchars($accessory->name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
}
$actions .= '</nobr>';
$company = $accessory->company;
$rows[] = array(
'name' => '<a href="'.url('admin/accessories/'.$accessory->id).'/view">'. $accessory->name.'</a>',
'category' => ($accessory->category) ? (string)link_to('admin/settings/categories/'.$accessory->category->id.'/view', $accessory->category->name) : '',
'model_number' => e($accessory->model_number),
'qty' => e($accessory->qty),
'order_number' => e($accessory->order_number),
'min_amt' => e($accessory->min_amt),
'location' => ($accessory->location) ? e($accessory->location->name): '',
'purchase_date' => e($accessory->purchase_date),
'purchase_cost' => Helper::formatCurrencyOutput($accessory->purchase_cost),
'numRemaining' => $accessory->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name),
'manufacturer' => $accessory->manufacturer ? (string) link_to('/admin/settings/manufacturers/'.$accessory->manufacturer_id.'/view', $accessory->manufacturer->name) : ''
);
$rows[] = $accessory->present()->forDataTable();
}
$data = array('total'=>$accessCount, 'rows'=>$rows);
@@ -657,15 +496,14 @@ class AccessoriesController extends Controller
foreach ($accessory_users as $user) {
$actions = '';
if (Gate::allows('accessories.checkin')) {
$actions .= '<a href="' . route('checkin/accessory',
$user->pivot->id) . '" class="btn btn-info btn-sm">Checkin</a>';
if (Gate::allows('checkin', $accessory)) {
$actions .= Helper::generateDatatableButton('checkin', route('checkin/accessory', $user->pivot->id));
}
if (Gate::allows('users.view')) {
$name = (string) link_to('/admin/users/'.$user->id.'/view', e($user->fullName()));
if (Gate::allows('view', $user)) {
$name = (string) link_to_route('users.show', e($user->present()->fullName()), [$user->id]);
} else {
$name = e($user->fullName());
$name = e($user->present()->fullName());
}
$rows[] = array(

View File

@@ -9,7 +9,7 @@ class ActionlogController extends Controller
{
public function displaySig($filename)
{
$this->authorize('view', \App\Models\Asset::class);
$file = config('app.private_uploads') . '/signatures/' . $filename;
$filetype = Helper::checkUploadIsImage($file);
$contents = file_get_contents($file);

View File

@@ -0,0 +1,182 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Accessory;
use App\Http\Transformers\AccessoriesTransformer;
class AccessoriesController 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', Accessory::class);
$allowed_columns = ['id','name','model_number','eol','notes','created_at','min_amt','company_id'];
$accessories = Accessory::whereNull('accessories.deleted_at')->with('category', 'company', 'manufacturer', 'users', 'location');
if ($request->has('search')) {
$accessories = $accessories->TextSearch($request->input('search'));
}
if ($request->has('company_id')) {
$accessories->where('company_id','=',$request->input('company_id'));
}
if ($request->has('manufacturer_id')) {
$accessories->where('manufacturer_id','=',$request->input('manufacturer_id'));
}
$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';
switch ($sort) {
case 'category':
$accessories = $accessories->OrderCategory($order);
break;
case 'company':
$accessories = $accessories->OrderCompany($order);
break;
default:
$accessories = $accessories->orderBy($sort, $order);
break;
}
$accessories->orderBy($sort, $order);
$total = $accessories->count();
$accessories = $accessories->skip($offset)->take($limit)->get();
return (new AccessoriesTransformer)->transformAccessories($accessories, $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', Accessory::class);
$accessory = new Accessory;
$accessory->fill($request->all());
if ($accessory->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $accessory, trans('admin/accessories/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $accessory->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', Accessory::class);
$accessory = Accessory::findOrFail($id);
$accessory_users = $accessory->users;
return (new AccessoriesTransformer)->transformAccessory($accessory);
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function accessory_detail($id)
{
$this->authorize('view', Accessory::class);
$accessory = Accessory::findOrFail($id);
return (new AccessoriesTransformer)->transformAccessory($accessory);
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function checkedout($id)
{
$this->authorize('view', Accessory::class);
$accessory = Accessory::findOrFail($id)->with('users')->first();
$accessories_users = $accessory->users;
$total = $accessories_users->count();
return (new AccessoriesTransformer)->transformCheckedoutAccessories($accessories_users, $total);
}
/**
* 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', Accessory::class);
$accessory = Accessory::findOrFail($id);
$accessory->fill($request->all());
if ($accessory->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $accessory, trans('admin/accessories/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $accessory->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Accessory::class);
$accessory = Accessory::findOrFail($id);
$this->authorize($accessory);
if ($accessory->hasUsers() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/accessories/message.assoc_users', array('count'=> $accessory->hasUsers()))));
}
$accessory->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/accessories/message.delete.success')));
}
}

View File

@@ -0,0 +1,160 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\AssetModel;
use App\Models\Asset;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use Illuminate\Http\Request;
use App\Http\Transformers\AssetModelsTransformer;
use App\Http\Transformers\AssetsTransformer;
/**
* This class controls all actions related to asset models for
* the Snipe-IT Asset Management application.
*
* @version v4.0
* @author [A. Gianotto] [<snipe@snipe.net>]
*/
class AssetModelsController 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', AssetModel::class);
$allowed_columns = ['id','image','name','model_number','eol','notes','created_at','manufacturer'];
$assetmodels = AssetModel::select(['models.id','models.image','models.name','model_number','eol','models.notes','models.created_at','category_id','manufacturer_id','depreciation_id','fieldset_id'])
->with('category','depreciation', 'manufacturer','fieldset')
->withCount('assets');
if ($request->has('search')) {
$assetmodels->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') : 'models.created_at';
switch ($sort) {
case 'manufacturer':
$assetmodels->OrderManufacturer($order);
break;
default:
$assetmodels->orderBy($sort, $order);
break;
}
$total = $assetmodels->count();
$assetmodels = $assetmodels->skip($offset)->take($limit)->get();
return (new AssetModelsTransformer)->transformAssetModels($assetmodels, $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', AssetModel::class);
$assetmodel = new AssetModel;
$assetmodel->fill($request->all());
if ($assetmodel->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/assetmodels/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->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', AssetModel::class);
$assetmodel = AssetModel::withCount('assets')->findOrFail($id);
return (new AssetModelsTransformer)->transformAssetModel($assetmodel);
}
/**
* Display the specified resource's assets
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function assets($id)
{
$this->authorize('view', AssetModel::class);
$assets = Asset::where('model_id','=',$id)->get();
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
}
/**
* 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', AssetModel::class);
$assetmodel = AssetModel::findOrFail($id);
$assetmodel->fill($request->all());
if ($assetmodel->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/assetmodels/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', AssetModel::class);
$assetmodel = AssetModel::findOrFail($id);
$this->authorize('delete', $assetmodel);
if ($assetmodel->assets()->count() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.assoc_users')));
}
$assetmodel->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/assetmodels/message.delete.success')));
}
}

View File

@@ -0,0 +1,483 @@
<?php
namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Requests\AssetRequest;
use App\Http\Transformers\AssetsTransformer;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Company;
use App\Models\CustomField;
use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
use Artisan;
use Auth;
use Carbon\Carbon;
use Config;
use DB;
use Gate;
use Illuminate\Http\Request;
use Input;
use Lang;
use Log;
use Mail;
use Paginator;
use Response;
use Slack;
use Str;
use TCPDF;
use Validator;
use View;
/**
* This class controls all actions related to assets for
* the Snipe-IT Asset Management application.
*
* @version v1.0
* @author [A. Gianotto] [<snipe@snipe.net>]
*/
class AssetsController extends Controller
{
/**
* Returns JSON listing of all assets
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $assetId
* @since [v4.0]
* @return JsonResponse
*/
public function index(Request $request)
{
$this->authorize('index', Asset::class);
$allowed_columns = [
'id',
'name',
'asset_tag',
'serial',
'model_number',
'last_checkout',
'notes',
'expected_checkin',
'order_number',
'image',
'assigned_to',
'created_at',
'updated_at',
'purchase_date',
'purchase_cost'
];
$filter = array();
if ($request->has('filter')) {
$filter = json_decode($request->input('filter'));
}
$all_custom_fields = CustomField::all(); //used as a 'cache' of custom fields throughout this page load
foreach ($all_custom_fields as $field) {
$allowed_columns[]=$field->db_column_name();
}
$assets = Company::scopeCompanyables(Asset::select('assets.*'))->with(
'assetLoc', 'assetstatus', 'defaultLoc', 'assetlog', 'company',
'model.category', 'model.manufacturer', 'model.fieldset', 'assigneduser');
// If we should search on everything
if (($request->has('search')) && (count($filter) == 0)) {
$assets->TextSearch($request->input('search'));
// otherwise loop through the filters and search strictly on them
} else {
if (count($filter) > 0) {
$assets->ByFilter($filter);
}
}
if ($request->has('status_id')) {
$assets->where('status_id', '=', $request->input('status_id'));
}
if ($request->has('model_id')) {
$assets->InModelList([$request->input('model_id')]);
}
if ($request->has('category_id')) {
$assets->InCategory($request->input('category_id'));
}
if ($request->has('location_id')) {
$assets->ByLocationId($request->input('location_id'));
}
if ($request->has('company_id')) {
$assets->where('assets.company_id', '=', $request->input('company_id'));
}
if ($request->has('manufacturer_id')) {
$assets->ByManufacturer($request->input('manufacturer_id'));
}
$request->has('order_number') ? $assets = $assets->where('order_number', '=', e($request->get('order_number'))) : '';
$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);
switch ($request->input('status')) {
case 'Deleted':
$assets->withTrashed()->Deleted();
break;
case 'Pending':
$assets->Pending();
break;
case 'RTD':
$assets->RTD();
break;
case 'Undeployable':
$assets->Undeployable();
break;
case 'Archived':
$assets->Archived();
break;
case 'Requestable':
$assets->RequestableAssets();
break;
case 'Deployed':
$assets->Deployed();
break;
}
switch ($sort) {
case 'model':
$assets->OrderModels($order);
break;
case 'model_number':
$assets->OrderModelNumber($order);
break;
case 'category':
$assets->OrderCategory($order);
break;
case 'manufacturer':
$assets->OrderManufacturer($order);
break;
case 'company':
$assets->OrderCompany($order);
break;
case 'location':
$assets->OrderLocation($order);
break;
case 'status_label':
$assets->OrderStatus($order);
break;
case 'assigned_to':
$assets->OrderAssigned($order);
break;
default:
$assets->orderBy($sort, $order);
break;
}
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
return (new AssetsTransformer)->transformAssets($assets, $total);
}
/**
* Returns JSON with information about an asset for detail view.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $assetId
* @since [v4.0]
* @return JsonResponse
*/
public function show($id)
{
if ($asset = Asset::withTrashed()->find($id)) {
$this->authorize('view', $asset);
return (new AssetsTransformer)->transformAsset($asset);
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
}
/**
* Accepts a POST request to create a new asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param Request $request
* @since [v4.0]
* @return JsonResponse
*/
public function store(AssetRequest $request)
{
// $this->authorize('create', Asset::class);
$asset = new Asset();
$asset->model()->associate(AssetModel::find((int) $request->get('model_id')));
$asset->name = $request->get('name');
$asset->serial = $request->get('serial');
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id'));
$asset->model_id = $request->get('model_id');
$asset->order_number = $request->get('order_number');
$asset->notes = $request->get('notes');
$asset->asset_tag = $request->get('asset_tag');
$asset->user_id = Auth::id();
$asset->archived = '0';
$asset->physical = '1';
$asset->depreciate = '0';
$asset->status_id = $request->get('status_id', 0);
$asset->warranty_months = $request->get('warranty_months', null);
$asset->purchase_cost = Helper::ParseFloat($request->get('purchase_cost'));
$asset->purchase_date = $request->get('purchase_date', null);
$asset->assigned_to = $request->get('assigned_to', null);
$asset->supplier_id = $request->get('supplier_id', 0);
$asset->requestable = $request->get('requestable', 0);
$asset->rtd_location_id = $request->get('rtd_location_id', null);
// Update custom fields in the database.
// Validation for these fields is handled through the AssetRequest form request
$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 ($asset->save()) {
$asset->logCreate();
if ($request->get('assigned_user')) {
$target = User::find(request('assigned_user'));
} elseif ($request->get('assigned_asset')) {
$target = Asset::find(request('assigned_asset'));
} elseif ($request->get('assigned_location')) {
$target = Location::find(request('assigned_location'));
}
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('error', null, $asset->getErrors()), 200);
}
/**
* Accepts a POST request to update an asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param Request $request
* @since [v4.0]
* @return JsonResponse
*/
public function update(Request $request, $id)
{
$this->authorize('create', Asset::class);
if ($asset = Asset::find($id)) {
($request->has('model_id')) ?
$asset->model()->associate(AssetModel::find($request->get('model_id'))) : '';
($request->has('name')) ?
$asset->name = $request->get('name') : '';
($request->has('serial')) ?
$asset->serial = $request->get('serial') : '';
($request->has('model_id')) ?
$asset->model_id = $request->get('model_id') : '';
($request->has('order_number')) ?
$asset->order_number = $request->get('order_number') : '';
($request->has('notes')) ?
$asset->notes = $request->get('notes') : '';
($request->has('asset_tag')) ?
$asset->asset_tag = $request->get('asset_tag') : '';
($request->has('archived')) ?
$asset->archived = $request->get('archived') : '';
($request->has('status_id')) ?
$asset->status_id = $request->get('status_id') : '';
($request->has('warranty_months')) ?
$asset->warranty_months = $request->get('warranty_months') : '';
($request->has('purchase_cost')) ?
$asset->purchase_cost = Helper::ParseFloat($request->get('purchase_cost')) : '';
($request->has('purchase_date')) ?
$asset->purchase_date = $request->get('purchase_date') : '';
($request->has('assigned_to')) ?
$asset->assigned_to = $request->get('assigned_to') : '';
($request->has('supplier_id')) ?
$asset->supplier_id = $request->get('supplier_id') : '';
($request->has('requestable')) ?
$asset->requestable = $request->get('requestable') : '';
($request->has('rtd_location_id')) ?
$asset->rtd_location_id = $request->get('rtd_location_id') : '';
($request->has('company_id')) ?
$asset->company_id = Company::getIdForCurrentUser($request->get('company_id')) : '';
if ($request->has('model_id')) {
if (($model = AssetModel::find($request->get('model_id'))) && (isset($model->fieldset))) {
foreach ($model->fieldset->fields as $field) {
if ($request->has($field->convertUnicodeDbSlug())) {
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
}
}
}
}
if ($asset->save()) {
$asset->logCreate();
if ($request->get('assigned_user')) {
$target = User::find(request('assigned_user'));
} elseif ($request->get('assigned_asset')) {
$target = Asset::find(request('assigned_asset'));
} elseif ($request->get('assigned_location')) {
$target = Location::find(request('assigned_location'));
}
if (isset($target)) {
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')));
}
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
}
/**
* Delete a given asset (mark as deleted).
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $assetId
* @since [v4.0]
* @return JsonResponse
*/
public function destroy($id)
{
if ($asset = Asset::find($id)) {
$this->authorize('delete', $asset);
DB::table('assets')
->where('id', $asset->id)
->update(array('assigned_to' => null));
$asset->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/hardware/message.delete.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
}
/**
* Checkout an asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $assetId
* @since [v4.0]
* @return JsonResponse
*/
public function checkout(Request $request, $asset_id)
{
$this->authorize('checkout', Asset::class);
$asset = Asset::findOrFail($asset_id);
if (!$asset->availableForCheckout()) {
return response()->json(Helper::formatStandardApiResponse('error', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.not_available')));
}
$this->authorize('checkout', $asset);
if ($request->has('user_id')) {
$target = User::find($request->input('user_id'));
} elseif ($request->has('asset_id')) {
$target = Asset::find($request->input('asset_id'));
} elseif ($request->has('location_id')) {
$target = Location::find($request->input('location_id'));
}
if (!isset($target)) {
return response()->json(Helper::formatStandardApiResponse('error', ['asset'=> e($asset->asset_tag)], 'No valid checkout target specified for asset '.e($asset->asset_tag).'.'));
}
$checkout_at = request('checkout_at', date("Y-m-d H:i:s"));
$expected_checkin = request('expected_checkin', null);
$note = request('note', null);
$asset_name = request('name', null);
if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name)) {
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.error')))->withErrors($asset->getErrors());
}
/**
* Checkin an asset
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $assetId
* @since [v4.0]
* @return JsonResponse
*/
public function checkin($asset_id)
{
$this->authorize('checkin', Asset::class);
$asset = Asset::findOrFail($asset_id);
$this->authorize('checkin', $asset);
$user = $asset->assignedUser;
if (is_null($target = $asset->assignedTo)) {
return response()->json(Helper::formatStandardApiResponse('error', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.already_checked_in')));
}
$asset->expected_checkin = null;
$asset->last_checkout = null;
$asset->assigned_to = null;
$asset->assignedTo()->disassociate($asset);
$asset->accepted = null;
$asset->name = e(Input::get('name'));
if (Input::has('status_id')) {
$asset->status_id = e(Input::get('status_id'));
}
// Was the asset updated?
if ($asset->save()) {
$logaction = $asset->logCheckin($target, e(request('note')));
$data['log_id'] = $logaction->id;
$data['first_name'] = get_class($target) == User::class ? $target->first_name : '';
$data['item_name'] = $asset->present()->name();
$data['checkin_date'] = $logaction->created_at;
$data['item_tag'] = $asset->asset_tag;
$data['item_serial'] = $asset->serial;
$data['note'] = $logaction->note;
if ((($asset->checkin_email()=='1')) && (isset($user)) && (!config('app.lock_passwords'))) {
Mail::send('emails.checkin-asset', $data, function ($m) use ($user) {
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
$m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name'));
$m->subject(trans('mail.Confirm_Asset_Checkin'));
});
}
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.success')));
}
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.error')));
}
}

View File

@@ -0,0 +1,130 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Category;
use App\Http\Transformers\CategoriesTransformer;
class CategoriesController 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', Category::class);
$allowed_columns = ['id', 'name','category_type','use_default_eula','require_acceptance','checkin_email'];
$categories = Category::select(['id', 'name','category_type','use_default_eula','require_acceptance','checkin_email'])
->withCount('assets', 'accessories', 'consumables', 'components');
if ($request->has('search')) {
$categories = $categories->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';
$categories->orderBy($sort, $order);
$total = $categories->count();
$categories = $categories->skip($offset)->take($limit)->get();
return (new CategoriesTransformer)->transformCategories($categories, $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', Category::class);
$category = new Category;
$category->fill($request->all());
if ($category->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $category, trans('admin/categories/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $category->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', Category::class);
$category = Category::findOrFail($id);
return $category;
}
/**
* 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', Category::class);
$category = Category::findOrFail($id);
$category->fill($request->all());
if ($category->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $category, trans('admin/categories/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $category->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Category::class);
$category = Category::findOrFail($id);
if ($category->has_models() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'model'])));
} elseif ($category->accessories()->count() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory'])));
} elseif ($category->consumables()->count() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable'])));
} elseif ($category->components()->count() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/categories/message.assoc_items', ['asset_type'=>'component'])));
}
$category->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/categories/message.delete.success')));
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Transformers\DatatablesTransformer;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Company;
class CompaniesController 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', Company::class);
$allowed_columns = ['id','name'];
$companies = Company::withCount('assets','licenses','accessories','consumables','components','users');
if ($request->has('search')) {
$companies->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';
$companies->orderBy($sort, $order);
$total = $companies->count();
$companies = $companies->skip($offset)->take($limit)->get();
return (new DatatablesTransformer)->transformDatatables($companies, $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', Company::class);
$company = new Company;
$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('error', null, $company->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', Company::class);
$company = Company::findOrFail($id);
return $company;
}
/**
* 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', Company::class);
$company = Company::findOrFail($id);
$company->fill($request->all());
if ($company->save()) {
return response()
->json(Helper::formatStandardApiResponse('success', $company, trans('admin/companies/message.update.success')));
}
return response()
->json(Helper::formatStandardApiResponse('error', null, $company->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Company::class);
$company = Company::findOrFail($id);
$this->authorize('delete', $company);
try {
$company->delete();
return response()
->json(Helper::formatStandardApiResponse('success', null, trans('admin/companies/message.delete.success')));
} catch (\Illuminate\Database\QueryException $exception) {
/*
* NOTE: This happens when there's a foreign key constraint violation
* For example when rows in other tables are referencing this company
*/
if ($exception->getCode() == 23000) {
return response()
->json(Helper::formatStandardApiResponse('error', null, trans('admin/companies/message.assoc_users')));
} else {
throw $exception;
}
}
}
}

View File

@@ -0,0 +1,163 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Transformers\AssetsTransformer;
use App\Http\Transformers\ComponentsTransformer;
use App\Http\Transformers\ComponentsAssetsTransformer;
use App\Models\Component;
use App\Models\Company;
use App\Helpers\Helper;
class ComponentsController 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', Component::class);
$components = Company::scopeCompanyables(Component::select('components.*')->whereNull('components.deleted_at')
->with('company', 'location', 'category'));
if ($request->has('search')) {
$components = $components->TextSearch($request->input('search'));
}
$offset = request('offset', 0);
$limit = request('limit', 50);
$allowed_columns = ['id','name','min_amt','order_number','serial','purchase_date','purchase_cost','company','category','qty','location'];
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
switch ($sort) {
case 'category':
$components = $components->OrderCategory($order);
break;
case 'location':
$components = $components->OrderLocation($order);
break;
case 'company':
$components = $components->OrderCompany($order);
break;
default:
$components = $components->orderBy($sort, $order);
break;
}
$total = $components->count();
$components = $components->skip($offset)->take($limit)->get();
return (new ComponentsTransformer)->transformComponents($components, $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', Component::class);
$component = new Component;
$component->fill($request->all());
if ($component->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $component, trans('admin/components/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $component->getErrors()));
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$this->authorize('view', Component::class);
$component = Component::find($id);
if ($component) {
return (new ComponentsTransformer)->transformComponent($component);
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.does_not_exist')));
}
/**
* 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', Component::class);
$component = Component::findOrFail($id);
$component->fill($request->all());
if ($component->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $component, trans('admin/components/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $component->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Component::class);
$component = Component::findOrFail($id);
$this->authorize('delete', $component);
$component->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/components/message.delete.success')));
}
/**
* Display all assets attached to a component
*
* @author [A. Bergamasco] [@vjandrea]
* @since [v4.0]
* @param Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function getAssets(Request $request, $id)
{
$this->authorize('index', Asset::class);
$component = Component::findOrFail($id);
$assets = $component->assets();
$offset = request('offset', 0);
$limit = $request->input('limit', 50);
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
return (new ComponentsAssetsTransformer)->transformAssets($assets, $total);
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Company;
use App\Models\Consumable;
use App\Http\Transformers\ConsumablesTransformer;
use App\Helpers\Helper;
class ConsumablesController 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('index', Consumable::class);
$consumables = Company::scopeCompanyables(
Consumable::select('consumables.*')
->whereNull('consumables.deleted_at')
->with('company', 'location', 'category', 'users', 'manufacturer')
);
if ($request->has('search')) {
$consumables = $consumables->TextSearch(e($request->input('search')));
}
if ($request->has('company_id')) {
$consumables->where('company_id','=',$request->input('company_id'));
}
if ($request->has('manufacturer_id')) {
$consumables->where('manufacturer_id','=',$request->input('manufacturer_id'));
}
$offset = request('offset', 0);
$limit = request('limit', 50);
$allowed_columns = ['id','name','order_number','min_amt','purchase_date','purchase_cost','company','category','model_number', 'item_no', 'manufacturer','location','qty'];
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
switch ($sort) {
case 'category':
$consumables = $consumables->OrderCategory($order);
break;
case 'location':
$consumables = $consumables->OrderLocation($order);
break;
case 'manufacturer':
$consumables = $consumables->OrderManufacturer($order);
break;
case 'company':
$consumables = $consumables->OrderCompany($order);
break;
default:
$consumables = $consumables->orderBy($sort, $order);
break;
}
$total = $consumables->count();
$consumables = $consumables->skip($offset)->take($limit)->get();
return (new ConsumablesTransformer)->transformConsumables($consumables, $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', Consumable::class);
$consumable = new Consumable;
$consumable->fill($request->all());
if ($consumable->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $consumable, trans('admin/consumables/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $consumable->getErrors()));
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$this->authorize('view', Consumable::class);
$consumable = Consumable::findOrFail($id);
return (new ConsumablesTransformer)->transformConsumable($consumable);
}
/**
* 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', Consumable::class);
$consumable = Consumable::findOrFail($id);
$consumable->fill($request->all());
if ($consumable->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $consumable, trans('admin/consumables/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $consumable->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Consumable::class);
$consumable = Consumable::findOrFail($id);
$this->authorize('delete', $consumable);
$consumable->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.delete.success')));
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\CustomFieldset;
class CustomFieldsController extends Controller
{
/**
* Reorder the custom fields within a fieldset
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v3.0]
* @return Array
*/
public function postReorder(Request $request, $id)
{
$fieldset = CustomFieldset::find($id);
$fields = array();
$order_array = array();
$items = $request->input('item');
foreach ($items as $order => $field_id) {
$order_array[$field_id] = $order;
}
foreach ($fieldset->fields as $field) {
$fields[$field->id] = ['required' => $field->pivot->required, 'order' => $order_array[$field->id]];
}
return $fieldset->fields()->sync($fields);
}
/**
* Delete a custom field.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return Redirect
*/
public function destroy($field_id)
{
$field = CustomField::find($field_id);
if ($field->fieldset->count() >0) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'Field is in use.'));
} else {
$field->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/custom_fields/message.field.delete.success')));
}
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Depreciation;
use App\Http\Transformers\DepreciationsTransformer;
class DepreciationsController 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', Depreciation::class);
$allowed_columns = ['id','name','created_at'];
$depreciations = Depreciation::select('id','name','months','user_id','created_at','updated_at');
if ($request->has('search')) {
$depreciations = $depreciations->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';
$depreciations->orderBy($sort, $order);
$total = $depreciations->count();
$depreciations = $depreciations->skip($offset)->take($limit)->get();
return (new DepreciationsTransformer)->transformDepreciations($depreciations, $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', Depreciation::class);
$depreciation = new Depreciation;
$depreciation->fill($request->all());
if ($depreciation->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $depreciation, trans('admin/depreciations/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $depreciation->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', Depreciation::class);
$depreciation = Depreciation::findOrFail($id);
return (new DepreciationsTransformer)->transformDepreciation($depreciation);
}
/**
* 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', Depreciation::class);
$depreciation = Depreciation::findOrFail($id);
$depreciation->fill($request->all());
if ($depreciation->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $depreciation, trans('admin/depreciations/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $depreciation->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Depreciation::class);
$depreciation = Depreciation::findOrFail($id);
$this->authorize('delete', $depreciation);
if ($depreciation->has_models() > 0) {
return response()->json(Helper::formatStandardApiResponse('error', trans('admin/depreciations/message.assoc_users')));
}
$depreciation->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/depreciations/message.delete.success')));
}
}

View File

@@ -0,0 +1,121 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Group;
use App\Http\Transformers\GroupsTransformer;
class GroupsController 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', Group::class);
$allowed_columns = ['id','name','created_at'];
$groups = Group::select('id','name','permissions')->withCount('users');
if ($request->has('search')) {
$groups = $groups->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';
$groups->orderBy($sort, $order);
$total = $groups->count();
$groups = $groups->skip($offset)->take($limit)->get();
return (new GroupsTransformer)->transformGroups($groups, $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', Group::class);
$group = new Group;
$group->fill($request->all());
if ($group->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $group, trans('admin/groups/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $group->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', Group::class);
$group = Group::findOrFail($id);
return $group;
}
/**
* 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', Group::class);
$group = Group::findOrFail($id);
$group->fill($request->all());
if ($group->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $group, trans('admin/groups/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $group->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Group::class);
$group = Group::findOrFail($id);
$this->authorize('delete', $group);
$group->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/groups/message.delete.success')));
}
}

View File

@@ -0,0 +1,140 @@
<?php
namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Requests\ItemImportRequest;
use App\Http\Transformers\ImportsTransformer;
use App\Models\Company;
use App\Models\Import;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Session;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
class ImportController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
$imports = Import::latest()->get();
return (new ImportsTransformer)->transformImports($imports);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store()
{
//
if (!Company::isCurrentUserAuthorized()) {
return redirect()->route('hardware.index')->with('error', trans('general.insufficient_permissions'));
} elseif (!config('app.lock_passwords')) {
$files = Input::file('files');
$path = config('app.private_uploads').'/imports';
$results = [];
$import = new Import;
foreach ($files as $file) {
if (!in_array($file->getMimeType(), array(
'application/vnd.ms-excel',
'text/csv',
'text/plain',
'text/comma-separated-values',
'text/tsv'))) {
$results['error']='File type must be CSV';
return $results;
}
$date = date('Y-m-d-his');
$fixed_filename = str_replace(' ', '-', $file->getClientOriginalName());
try {
$file->move($path, $date.'-'.$fixed_filename);
} catch (FileException $exception) {
$results['error']=trans('admin/hardware/message.upload.error');
if (config('app.debug')) {
$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);
$import->save();
$results[] = $import;
}
$results = (new ImportsTransformer)->transformImports($results);
return [
'files' => $results
];
}
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.feature_disabled')), 500);
}
/**
* Processes the specified Import.
*
* @param \App\Import $import
* @return \Illuminate\Http\Response
*/
public function process(ItemImportRequest $request, $import_id)
{
$this->authorize('create', Asset::class);
$errors = $request->import(Import::find($import_id));
$redirectTo = "hardware";
switch ($request->get('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;
case "license":
$redirectTo = "licenses.index";
break;
}
if ($errors) { //Failure
return response()->json(Helper::formatStandardApiResponse('import-errors', null, $errors), 500);
}
//Flash message before the redirect
Session::flash('success', trans('admin/hardware/message.import.success'));
return response()->json(Helper::formatStandardApiResponse('success', null, ['redirect_url' => route($redirectTo)]));
}
/**
* Remove the specified resource from storage.
*
* @param \App\Import $import
* @return \Illuminate\Http\Response
*/
public function destroy($import_id)
{
$this->authorize('create', Asset::class);
$import = Import::find($import_id);
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')));
} catch (\Exception $e) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.import.file_delete_error')), 500);
}
}
}

View File

@@ -0,0 +1,150 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Transformers\LicensesTransformer;
use App\Models\License;
use App\Models\Company;
class LicensesController 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', License::class);
$licenses = Company::scopeCompanyables(License::with('company', 'licenseSeatsRelation', 'manufacturer'));
if ($request->has('search')) {
$licenses = $licenses->TextSearch($request->input('search'));
}
if ($request->has('company_id')) {
$licenses->where('company_id','=',$request->input('company_id'));
}
if ($request->has('name')) {
$licenses->where('licenses.name','=',$request->input('name'));
}
if ($request->has('product_key')) {
$licenses->where('licenses.serial','=',$request->input('product_key'));
}
if ($request->has('order_number')) {
$licenses->where('order_number','=',$request->input('order_number'));
}
if ($request->has('purchase_order')) {
$licenses->where('purchase_order','=',$request->input('purchase_order'));
}
if ($request->has('license_name')) {
$licenses->where('license_name','=',$request->input('license_name'));
}
if ($request->has('license_email')) {
$licenses->where('license_email','=',$request->input('license_email'));
}
if ($request->has('manufacturer_id')) {
$licenses->where('manufacturer_id','=',$request->input('manufacturer_id'));
}
if ($request->has('depreciation_id')) {
$licenses->where('depreciation_id','=',$request->input('depreciation_id'));
}
if ($request->has('supplier_id')) {
$licenses->where('supplier_id','=',$request->input('supplier_id'));
}
$offset = request('offset', 0);
$limit = request('limit', 50);
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','manufacturer','company','license_name','license_email'];
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
switch ($sort) {
case 'manufacturer':
$licenses = $licenses->OrderManufacturer($order);
break;
case 'company':
$licenses = $licenses->OrderCompany($order);
break;
default:
$licenses = $licenses->orderBy($sort, $order);
break;
}
$total = $licenses->count();
$licenses = $licenses->skip($offset)->take($limit)->get();
return (new LicensesTransformer)->transformLicenses($licenses, $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)
{
//
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* 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)
{
//
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@@ -0,0 +1,134 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Location;
use App\Http\Transformers\LocationsTransformer;
class LocationsController 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', Location::class);
$allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at',
'updated_at'];
$locations = Location::select([
'locations.id',
'locations.name',
'locations.address',
'locations.address2',
'locations.city',
'locations.state',
'locations.zip',
'locations.country',
'locations.parent_id',
'locations.created_at',
'locations.updated_at',
'locations.currency'
])->withCount('assets')->withCount('users');
if ($request->has('search')) {
$locations = $locations->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';
$locations->orderBy($sort, $order);
$total = $locations->count();
$locations = $locations->skip($offset)->take($limit)->get();
return (new LocationsTransformer)->transformLocations($locations, $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', Location::class);
$location = new Location;
$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('error', null, $location->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', Location::class);
$location = Location::findOrFail($id);
return (new LocationsTransformer)->transformLocation($location);
}
/**
* 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', Location::class);
$location = Location::findOrFail($id);
$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('error', null, $location->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Location::class);
$location = Location::findOrFail($id);
$this->authorize('delete', $location);
$location->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success')));
}
}

View File

@@ -0,0 +1,123 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Manufacturer;
use App\Http\Transformers\DatatablesTransformer;
use App\Http\Transformers\ManufacturersTransformer;
class ManufacturersController 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', Manufacturer::class);
$allowed_columns = ['id','name','url','support_url','support_email','support_phone','created_at','updated_at'];
$manufacturers = Manufacturer::select(
array('id','name','url','support_url','support_email','support_phone','created_at','updated_at')
)->withCount('assets')->withCount('licenses')->withCount('consumables')->withCount('accessories');
if ($request->has('search')) {
$manufacturers = $manufacturers->TextSearch($request->input('search'));
}
$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') : 'created_at';
$manufacturers->orderBy($sort, $order);
$total = $manufacturers->count();
$manufacturers = $manufacturers->skip($offset)->take($limit)->get();
return (new ManufacturersTransformer)->transformManufacturers($manufacturers, $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', Manufacturer::class);
$manufacturer = new Manufacturer;
$manufacturer->fill($request->all());
if ($manufacturer->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $manufacturer, trans('admin/manufacturers/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $manufacturer->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', Manufacturer::class);
$manufacturer = Manufacturer::findOrFail($id);
return $manufacturer;
}
/**
* 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', Manufacturer::class);
$manufacturer = Manufacturer::findOrFail($id);
$manufacturer->fill($request->all());
if ($manufacturer->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $manufacturer, trans('admin/manufacturers/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $manufacturer->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Manufacturer::class);
$manufacturer = Manufacturer::findOrFail($id);
$this->authorize('delete', $manufacturer);
$manufacturer->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/manufacturers/message.delete.success')));
}
}

View File

@@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class SettingsController extends Controller
{
/**
* Display a listing of the resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* 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)
{
//
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* 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)
{
//
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@@ -0,0 +1,216 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Statuslabel;
use App\Models\Asset;
use App\Http\Transformers\StatuslabelsTransformer;
use App\Http\Transformers\AssetsTransformer;
class StatuslabelsController 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', Statuslabel::class);
$allowed_columns = ['id','name','created_at'];
$statuslabels = Statuslabel::withCount('assets');
if ($request->has('search')) {
$statuslabels = $statuslabels->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';
$statuslabels->orderBy($sort, $order);
$total = $statuslabels->count();
$statuslabels = $statuslabels->skip($offset)->take($limit)->get();
return (new StatuslabelsTransformer)->transformStatuslabels($statuslabels, $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', Statuslabel::class);
$statuslabel = new Statuslabel;
$statuslabel->fill($request->all());
if ($statuslabel->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $statuslabel, trans('admin/statuslabels/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $statuslabel->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', Statuslabel::class);
$statuslabel = Statuslabel::findOrFail($id);
return $statuslabel;
}
/**
* 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', Statuslabel::class);
$statuslabel = Statuslabel::findOrFail($id);
$statuslabel->fill($request->all());
if ($statuslabel->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $statuslabel, trans('admin/statuslabels/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $statuslabel->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Statuslabel::class);
$statuslabel = Statuslabel::findOrFail($id);
$this->authorize('delete', $statuslabel);
$statuslabel->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/statuslabels/message.delete.success')));
}
/**
* Show a count of assets by status label for pie chart
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return \Illuminate\Http\Response
*/
public function getAssetCountByStatuslabel()
{
$statusLabels = Statuslabel::with('assets')->get();
$labels=[];
$points=[];
$colors=[];
foreach ($statusLabels as $statusLabel) {
if ($statusLabel->assets()->count() > 0) {
$labels[]=$statusLabel->name;
$points[]=$statusLabel->assets()->whereNull('assigned_to')->count();
if ($statusLabel->color!='') {
$colors[]=$statusLabel->color;
}
}
}
$labels[]='Deployed';
$points[]=Asset::whereNotNull('assigned_to')->count();
$colors_array = array_merge($colors, Helper::chartColors());
$result= [
"labels" => $labels,
"datasets" => [ [
"data" => $points,
"backgroundColor" => $colors_array,
"hoverBackgroundColor" => $colors_array
]]
];
return $result;
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function assets(Request $request, $id)
{
$this->authorize('view', Statuslabel::class);
$this->authorize('index', Asset::class);
$assets = Asset::where('status_id','=',$id);
$allowed_columns = [
'id',
'name'
];
$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') : 'created_at';
$assets->orderBy($sort, $order);
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
return (new AssetsTransformer)->transformAssets($assets, $total);
}
/**
* Returns a boolean response based on whether the status label
* is one that is deployable.
*
* This is used by the hardware create/edit view to determine whether
* we should provide a dropdown of users for them to check the asset out to.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return Bool
*/
public function checkIfDeployable($id) {
$statuslabel = Statuslabel::findOrFail($id);
if ($statuslabel->getStatuslabelType()=='deployable') {
return '1';
}
return '0';
}
}

View File

@@ -0,0 +1,123 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Helpers\Helper;
use App\Models\Supplier;
use App\Http\Transformers\DatatablesTransformer;
class SuppliersController 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', Supplier::class);
$allowed_columns = ['id','name','address','phone','contact','fax','email'];
$suppliers = Supplier::select(
array('id','name','address','address2','city','state','country','fax', 'phone','email','contact')
)->withCount('assets')->withCount('licenses')->whereNull('deleted_at');
if ($request->has('search')) {
$suppliers = $suppliers->TextSearch($request->input('search'));
}
$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') : 'created_at';
$suppliers->orderBy($sort, $order);
$total = $suppliers->count();
$suppliers = $suppliers->skip($offset)->take($limit)->get();
return (new DatatablesTransformer)->transformDatatables($suppliers, $total);
return $suppliers;
}
/**
* 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', Supplier::class);
$supplier = new Supplier;
$supplier->fill($request->all());
if ($supplier->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $supplier, trans('admin/suppliers/message.create.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $supplier->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', Supplier::class);
$supplier = Supplier::findOrFail($id);
return $supplier;
}
/**
* 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', Supplier::class);
$supplier = Supplier::findOrFail($id);
$supplier->fill($request->all());
if ($supplier->save()) {
return response()->json(Helper::formatStandardApiResponse('success', $supplier, trans('admin/suppliers/message.update.success')));
}
return response()->json(Helper::formatStandardApiResponse('error', null, $supplier->getErrors()));
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$this->authorize('delete', Supplier::class);
$supplier = Supplier::findOrFail($id);
$this->authorize('delete', $supplier);
$supplier->delete();
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/suppliers/message.delete.success')));
}
}

View File

@@ -0,0 +1,138 @@
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Transformers\UsersTransformer;
use App\Models\Company;
use App\Models\User;
class UsersController 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', User::class);
$users = User::select([
'users.id',
'users.employee_num',
'users.two_factor_enrolled',
'users.jobtitle',
'users.email',
'users.username',
'users.location_id',
'users.manager_id',
'users.first_name',
'users.last_name',
'users.created_at',
'users.notes',
'users.company_id',
'users.last_login',
'users.deleted_at',
'users.activated'
])->with('manager', 'groups', 'userloc', 'company', 'throttle','assets','licenses','accessories','consumables')
->withCount('assets','licenses','accessories','consumables');
$users = Company::scopeCompanyables($users);
if ($request->has('search')) {
$users = $users->TextSearch($request->input('search'));
}
if ($request->has('company_id')) {
$users = $users->where('company_id','=',$request->input('company_id'));
}
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$offset = request('offset', 0);
$limit = request('limit', 50);
switch ($request->input('sort')) {
case 'manager':
$users = $users->OrderManager($order);
break;
case 'location':
$users = $users->OrderLocation($order);
break;
default:
$allowed_columns =
[
'last_name','first_name','email','jobtitle','username','employee_num',
'assets','accessories', 'consumables','licenses','groups','activated','created_at',
'two_factor_enrolled','two_factor_optin','last_login'
];
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
$users = $users->orderBy($sort, $order);
break;
}
$userCount = $users->count();
$users = $users->skip($offset)->take($limit)->get();
return (new UsersTransformer)->transformUsers($users, $userCount);
}
/**
* 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)
{
//
}
/**
* Display the specified resource.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$this->authorize('view', User::class);
$user = User::findOrFail($id);
return (new UsersTransformer)->transformUser($user);
}
/**
* 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)
{
//
}
/**
* Remove the specified resource from storage.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View File

@@ -9,11 +9,9 @@ use Input;
use Lang;
use Log;
use Mail;
use Redirect;
use Response;
use Slack;
use Str;
use App\Models\Supplier;
use TCPDF;
use Validator;
use View;
@@ -22,6 +20,7 @@ use App\Models\Asset;
use App\Helpers\Helper;
use Auth;
use Gate;
use Illuminate\Http\Request;
/**
* This controller handles all actions related to Asset Maintenance for
@@ -43,7 +42,7 @@ class AssetMaintenancesController extends Controller
*/
private static function getInsufficientPermissionsRedirect()
{
return redirect()->route('asset_maintenances')
return redirect()->route('maintenances.index')
->with('error', trans('general.insufficient_permissions'));
}
@@ -58,9 +57,8 @@ class AssetMaintenancesController extends Controller
* @since [v1.8]
* @return View
*/
public function getIndex()
public function index()
{
return View::make('asset_maintenances/index');
}
@@ -74,34 +72,20 @@ class AssetMaintenancesController extends Controller
* @since [v1.8]
* @return String JSON
*/
public function getDatatable()
public function getDatatable(Request $request)
{
$maintenances = AssetMaintenance::with('asset', 'supplier', 'asset.company','admin');
$maintenances = AssetMaintenance::with('asset', 'supplier', 'asset.company', 'admin');
if (Input::has('search')) {
$maintenances = $maintenances->TextSearch(e(Input::get('search')));
$maintenances = $maintenances->TextSearch(e($request->input('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;
}
$offset = request('offset', 0);
$limit = request('limit', 50);
$allowed_columns = ['id','title','asset_maintenance_time','asset_maintenance_type','cost','start_date','completion_date','notes','user_id'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
switch ($sort) {
case 'user_id':
@@ -120,10 +104,15 @@ class AssetMaintenancesController extends Controller
foreach ($maintenances as $maintenance) {
$actions = '';
if (Gate::allows('assets.edit')) {
$actions .= '<nobr><a href="' . route('update/asset_maintenance',
$maintenance->id) . '" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a><a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/asset_maintenance',
$maintenance->id) . '" data-content="' . trans('admin/asset_maintenances/message.delete.confirm') . '" data-title="' . trans('general.delete') . ' ' . htmlspecialchars($maintenance->title) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></nobr>';
if (Gate::allows('update', Asset::class)) {
$actions .= Helper::generateDatatableButton('edit', route('maintenances.edit', $maintenance->id));
$actions .= Helper::generateDatatableButton(
'delete',
route('maintenances.destroy', $maintenance->id),
$enabled = true,
trans('admin/asset_maintenances/message.delete.confirm'),
$maintenance->title
);
}
if (($maintenance->cost) && (isset($maintenance->asset)) && ($maintenance->asset->assetloc) && ($maintenance->asset->assetloc->currency!='')) {
@@ -131,21 +120,21 @@ class AssetMaintenancesController extends Controller
} else {
$maintenance_cost = $settings->default_currency.$maintenance->cost;
}
$rows[] = array(
'id' => $maintenance->id,
'asset_name' => ($maintenance->asset) ? (string)link_to('/hardware/'.$maintenance->asset->id.'/view', $maintenance->asset->showAssetName()) : 'Deleted Asset' ,
'asset_name' => ($maintenance->asset) ? (string)link_to_route('maintenances.show', $maintenance->asset->present()->Name(), ['maintenance' => $maintenance->asset->id]) : 'Deleted Asset' ,
'title' => $maintenance->title,
'notes' => $maintenance->notes,
'supplier' => ($maintenance->supplier) ? (string)link_to('/admin/settings/suppliers/'.$maintenance->supplier->id.'/view', $maintenance->supplier->name) : 'Deleted Supplier',
'supplier' => ($maintenance->supplier) ? (string)link_to_route('suppliers.show', $maintenance->supplier->name, ['maintenance'=>$maintenance->supplier->id]) : 'Deleted Supplier',
'cost' => $maintenance_cost,
'asset_maintenance_type' => e($maintenance->asset_maintenance_type),
'start_date' => $maintenance->start_date,
'asset_maintenance_time' => $maintenance->asset_maintenance_time,
'completion_date' => $maintenance->completion_date,
'user_id' => ($maintenance->admin) ? (string)link_to('/admin/users/'.$maintenance->admin->id.'/view', $maintenance->admin->fullName()) : '',
'user_id' => ($maintenance->admin) ? (string)link_to_route('users.show', $maintenance->admin->present()->fullName(), ['user'=>$maintenance->admin->id]) : '',
'actions' => $actions,
'companyName' => ($maintenance->asset->company) ? $maintenance->asset->company->name : ''
'company' => ($maintenance->asset->company) ? $maintenance->asset->company->name : ''
);
}
@@ -155,32 +144,26 @@ class AssetMaintenancesController extends Controller
}
/**
* Returns a form view to create a new asset maintenance.
*
* @see AssetMaintenancesController::postCreate() method that stores the data
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @version v1.0
* @since [v1.8]
* @return mixed
*/
public function getCreate($assetId = null)
* Returns a form view to create a new asset maintenance.
*
* @see AssetMaintenancesController::postCreate() method that stores the data
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @version v1.0
* @since [v1.8]
* @return mixed
*/
public function create()
{
// Prepare Asset Maintenance Type List
$assetMaintenanceType = [
'' => 'Select an asset maintenance type',
] + AssetMaintenance::getImprovementOptions();
// Mark the selected asset, if it came in
$selectedAsset = $assetId;
$assets = Helper::detailedAssetList();
$supplier_list = Helper::suppliersList();
// Render the view
return View::make('asset_maintenances/edit')
->with('asset_list', $assets)
->with('selectedAsset', $selectedAsset)
->with('supplier_list', $supplier_list)
->with('asset_list', Helper::detailedAssetList())
->with('selectedAsset', request('asset_id'))
->with('supplier_list', Helper::suppliersList())
->with('assetMaintenanceType', $assetMaintenanceType)
->with('item', new AssetMaintenance);
}
@@ -194,62 +177,29 @@ class AssetMaintenancesController extends Controller
* @since [v1.8]
* @return mixed
*/
public function postCreate()
public function store(Request $request)
{
// get the POST data
$new = Input::all();
// create a new model instance
$assetMaintenance = new AssetMaintenance();
if (e(Input::get('supplier_id')) == '') {
$assetMaintenance->supplier_id = null;
} else {
$assetMaintenance->supplier_id = e(Input::get('supplier_id'));
}
if (e(Input::get('is_warranty')) == '') {
$assetMaintenance->is_warranty = 0;
} else {
$assetMaintenance->is_warranty = e(Input::get('is_warranty'));
}
if (e(Input::get('cost')) == '') {
$assetMaintenance->cost = '';
} else {
$assetMaintenance->cost = Helper::ParseFloat(e(Input::get('cost')));
}
if (e(Input::get('notes')) == '') {
$assetMaintenance->notes = null;
} else {
$assetMaintenance->notes = e(Input::get('notes'));
}
$asset = Asset::find(e(Input::get('asset_id')));
$assetMaintenance->supplier_id = $request->input('supplier_id');
$assetMaintenance->is_warranty = $request->input('is_warranty');
$assetMaintenance->cost = e($request->input('cost'));
$assetMaintenance->notes = e($request->input('notes'));
$asset = Asset::find(e($request->input('asset_id')));
if (!Company::isCurrentUserHasAccess($asset)) {
return static::getInsufficientPermissionsRedirect();
}
// Save the asset maintenance data
$assetMaintenance->asset_id = e(Input::get('asset_id'));
$assetMaintenance->asset_maintenance_type = e(Input::get('asset_maintenance_type'));
$assetMaintenance->title = e(Input::get('title'));
$assetMaintenance->start_date = e(Input::get('start_date'));
$assetMaintenance->completion_date = e(Input::get('completion_date'));
$assetMaintenance->user_id = Auth::user()->id;
$assetMaintenance->asset_id = $request->input('asset_id');
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
$assetMaintenance->title = $request->input('title');
$assetMaintenance->start_date = $request->input('start_date');
$assetMaintenance->completion_date = $request->input('completion_date');
$assetMaintenance->user_id = Auth::id();
if (( $assetMaintenance->completion_date == "" )
|| ( $assetMaintenance->completion_date == "0000-00-00" )
) {
$assetMaintenance->completion_date = null;
}
if (( $assetMaintenance->completion_date !== "" )
&& ( $assetMaintenance->completion_date !== "0000-00-00" )
if (( $assetMaintenance->completion_date !== null )
&& ( $assetMaintenance->start_date !== "" )
&& ( $assetMaintenance->start_date !== "0000-00-00" )
) {
@@ -260,17 +210,13 @@ class AssetMaintenancesController extends Controller
// Was the asset maintenance created?
if ($assetMaintenance->save()) {
// Redirect to the new asset maintenance page
return redirect()->to("admin/asset_maintenances")
return redirect()->route('maintenances.index')
->with('success', trans('admin/asset_maintenances/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($assetMaintenance->getErrors());
}
/**
@@ -283,12 +229,12 @@ class AssetMaintenancesController extends Controller
* @since [v1.8]
* @return mixed
*/
public function getEdit($assetMaintenanceId = null)
public function edit($assetMaintenanceId = null)
{
// Check if the asset maintenance exists
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
// Redirect to the improvement management page
return redirect()->to('admin/asset_maintenances')
return redirect()->route('maintenances.index')
->with('error', trans('admin/asset_maintenances/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
return static::getInsufficientPermissionsRedirect();
@@ -311,88 +257,59 @@ class AssetMaintenancesController extends Controller
'' => 'Select an improvement type',
] + AssetMaintenance::getImprovementOptions();
$assets = Company::scopeCompanyables(Asset::with('model','assignedUser')->get(), 'assets.company_id')->lists('detailed_name', 'id');
// Get Supplier List
$supplier_list = Helper::suppliersList();
// Render the view
return View::make('asset_maintenances/edit')
->with('asset_list', $assets)
->with('asset_list', Helper::detailedAssetList())
->with('selectedAsset', null)
->with('supplier_list', $supplier_list)
->with('supplier_list', Helper::suppliersList())
->with('assetMaintenanceType', $assetMaintenanceType)
->with('item', $assetMaintenance);
}
/**
* Validates and stores an update to an asset maintenance
*
* @see AssetMaintenancesController::postEdit() method that stores the data
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @param int $assetMaintenanceId
* @version v1.0
* @since [v1.8]
* @return mixed
*/
public function postEdit($assetMaintenanceId = null)
* Validates and stores an update to an asset maintenance
*
* @see AssetMaintenancesController::postEdit() method that stores the data
* @author Vincent Sposato <vincent.sposato@gmail.com>
* @param Request $request
* @param int $assetMaintenanceId
* @return mixed
* @version v1.0
* @since [v1.8]
*/
public function update(Request $request, $assetMaintenanceId = null)
{
// get the POST data
$new = Input::all();
// Check if the asset maintenance exists
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
// Redirect to the asset maintenance management page
return redirect()->to('admin/asset_maintenances')
return redirect()->route('maintenances.index')
->with('error', trans('admin/asset_maintenances/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
return static::getInsufficientPermissionsRedirect();
}
$assetMaintenance->supplier_id = e($request->input('supplier_id'));
$assetMaintenance->is_warranty = e($request->input('is_warranty'));
$assetMaintenance->cost = Helper::ParseFloat(e($request->input('cost')));
$assetMaintenance->notes = e($request->input('notes'));
if (e(Input::get('supplier_id')) == '') {
$assetMaintenance->supplier_id = null;
} else {
$assetMaintenance->supplier_id = e(Input::get('supplier_id'));
}
if (e(Input::get('is_warranty')) == '') {
$assetMaintenance->is_warranty = 0;
} else {
$assetMaintenance->is_warranty = e(Input::get('is_warranty'));
}
if (e(Input::get('cost')) == '') {
$assetMaintenance->cost = '';
} else {
$assetMaintenance->cost = Helper::ParseFloat(e(Input::get('cost')));
}
if (e(Input::get('notes')) == '') {
$assetMaintenance->notes = null;
} else {
$assetMaintenance->notes = e(Input::get('notes'));
}
$asset = Asset::find(e(Input::get('asset_id')));
$asset = Asset::find(request('asset_id'));
if (!Company::isCurrentUserHasAccess($asset)) {
return static::getInsufficientPermissionsRedirect();
}
// Save the asset maintenance data
$assetMaintenance->asset_id = e(Input::get('asset_id'));
$assetMaintenance->asset_maintenance_type = e(Input::get('asset_maintenance_type'));
$assetMaintenance->title = e(Input::get('title'));
$assetMaintenance->start_date = e(Input::get('start_date'));
$assetMaintenance->completion_date = e(Input::get('completion_date'));
$assetMaintenance->asset_id = $request->input('asset_id');
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
$assetMaintenance->title = $request->input('title');
$assetMaintenance->start_date = $request->input('start_date');
$assetMaintenance->completion_date = $request->input('completion_date');
if (( $assetMaintenance->completion_date == "" )
|| ( $assetMaintenance->completion_date == "0000-00-00" )
if (( $assetMaintenance->completion_date == null )
) {
$assetMaintenance->completion_date = null;
if (( $assetMaintenance->asset_maintenance_time !== 0 )
|| ( !is_null($assetMaintenance->asset_maintenance_time) )
) {
@@ -400,8 +317,7 @@ class AssetMaintenancesController extends Controller
}
}
if (( $assetMaintenance->completion_date !== "" )
&& ( $assetMaintenance->completion_date !== "0000-00-00" )
if (( $assetMaintenance->completion_date !== null )
&& ( $assetMaintenance->start_date !== "" )
&& ( $assetMaintenance->start_date !== "0000-00-00" )
) {
@@ -414,12 +330,10 @@ class AssetMaintenancesController extends Controller
if ($assetMaintenance->save()) {
// Redirect to the new asset maintenance page
return redirect()->to("admin/asset_maintenances")
->with('success', trans('admin/asset_maintenances/message.create.success'));
return redirect()->route('maintenances.index')
->with('success', trans('admin/asset_maintenances/message.edit.success'));
}
return redirect()->back() ->withInput()->withErrors($assetMaintenance->getErrors());
return redirect()->back()->withInput()->withErrors($assetMaintenance->getErrors());
}
/**
@@ -431,12 +345,12 @@ class AssetMaintenancesController extends Controller
* @since [v1.8]
* @return mixed
*/
public function getDelete($assetMaintenanceId)
public function destroy($assetMaintenanceId)
{
// Check if the asset maintenance exists
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
// Redirect to the asset maintenance management page
return redirect()->to('admin/asset_maintenances')
return redirect()->route('maintenances.index')
->with('error', trans('admin/asset_maintenances/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
return static::getInsufficientPermissionsRedirect();
@@ -446,7 +360,7 @@ class AssetMaintenancesController extends Controller
$assetMaintenance->delete();
// Redirect to the asset_maintenance management page
return redirect()->to('admin/asset_maintenances')
return redirect()->route('maintenances.index')
->with('success', trans('admin/asset_maintenances/message.delete.success'));
}
@@ -459,12 +373,12 @@ class AssetMaintenancesController extends Controller
* @since [v1.8]
* @return View
*/
public function getView($assetMaintenanceId)
public function show($assetMaintenanceId)
{
// Check if the asset maintenance exists
if (is_null($assetMaintenance = AssetMaintenance::find($assetMaintenanceId))) {
// Redirect to the asset maintenance management page
return redirect()->to('admin/asset_maintenances')
return redirect()->route('maintenances.index')
->with('error', trans('admin/asset_maintenances/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
return static::getInsufficientPermissionsRedirect();

View File

@@ -1,6 +1,7 @@
<?php
namespace App\Http\Controllers;
use App\Models\CustomField;
use Image;
use Input;
use Lang;
@@ -15,6 +16,7 @@ use App\Models\Asset;
use App\Models\Company;
use Config;
use App\Helpers\Helper;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -36,9 +38,8 @@ class AssetModelsController extends Controller
* @since [v1.0]
* @return View
*/
public function getIndex()
public function index()
{
// Show the page
return View::make('models/index');
}
@@ -49,16 +50,13 @@ class AssetModelsController extends Controller
* @since [v1.0]
* @return View
*/
public function getCreate()
public function create()
{
// Show the page
$depreciation_list = Helper::depreciationList();
$manufacturer_list = Helper::manufacturerList();
$category_list = Helper::categoryList('asset');
return View::make('models/edit')
->with('category_list', $category_list)
->with('depreciation_list', $depreciation_list)
->with('manufacturer_list', $manufacturer_list)
->with('category_list', Helper::categoryList('asset'))
->with('depreciation_list', Helper::depreciationList())
->with('manufacturer_list', Helper::manufacturerList())
->with('item', new AssetModel);
}
@@ -70,39 +68,27 @@ class AssetModelsController extends Controller
* @since [v1.0]
* @return Redirect
*/
public function postCreate()
public function store(Request $request)
{
// Create a new asset model
$model = new AssetModel;
if (e(Input::get('depreciation_id')) == '') {
$model->depreciation_id = 0;
} else {
$model->depreciation_id = e(Input::get('depreciation_id'));
}
if (e(Input::get('eol')) == '') {
$model->eol = 0;
} else {
$model->eol = e(Input::get('eol'));
}
// Save the model data
$model->name = e(Input::get('name'));
$model->model_number = e(Input::get('model_number'));
$model->manufacturer_id = e(Input::get('manufacturer_id'));
$model->category_id = e(Input::get('category_id'));
$model->notes = e(Input::get('notes'));
$model->user_id = Auth::user()->id;
$model->eol = $request->input('eol');
$model->depreciation_id = $request->input('depreciation_id');
$model->name = $request->input('name');
$model->model_number = $request->input('model_number');
$model->manufacturer_id = $request->input('manufacturer_id');
$model->category_id = $request->input('category_id');
$model->notes = $request->input('notes');
$model->user_id = Auth::guard('api')->user();
$model->requestable = Input::has('requestable');
if (Input::get('custom_fieldset')!='') {
$model->fieldset_id = e(Input::get('custom_fieldset'));
if ($request->input('custom_fieldset')!='') {
$model->fieldset_id = e($request->input('custom_fieldset'));
}
if (Input::file('image')) {
$image = Input::file('image');
$file_name = str_random(25).".".$image->getClientOriginalExtension();
@@ -117,22 +103,21 @@ class AssetModelsController extends Controller
// Was it created?
if ($model->save()) {
// Redirect to the new model page
return redirect()->to("hardware/models")->with('success', trans('admin/models/message.create.success'));
return redirect()->route("models.index")->with('success', trans('admin/models/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($model->getErrors());
return redirect()->back()->withInput()->withErrors($model->getErrors());
}
/**
* Validates and stores new Asset Model data created from the
* modal form on the Asset Creation view.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return String JSON
*/
public function store()
* Validates and stores new Asset Model data created from the
* modal form on the Asset Creation view.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @param Request $request
* @return String JSON
*/
public function apiStore(Request $request)
{
//COPYPASTA!!!! FIXME
$model = new AssetModel;
@@ -140,18 +125,18 @@ class AssetModelsController extends Controller
$settings=Input::all();
$settings['eol']= null;
$model->name=e(Input::get('name'));
$model->manufacturer_id = e(Input::get('manufacturer_id'));
$model->category_id = e(Input::get('category_id'));
$model->model_number = e(Input::get('model_number'));
$model->user_id = Auth::user()->id;
$model->notes = e(Input::get('notes'));
$model->name=$request->input('name');
$model->manufacturer_id = $request->input('manufacturer_id');
$model->category_id = $request->input('category_id');
$model->model_number = $request->input('model_number');
$model->user_id = Auth::id();
$model->notes = $request->input('notes');
$model->eol= null;
if (Input::get('fieldset_id')=='') {
if ($request->input('fieldset_id')=='') {
$model->fieldset_id = null;
} else {
$model->fieldset_id = e(Input::get('fieldset_id'));
$model->fieldset_id = e($request->input('fieldset_id'));
}
if ($model->save()) {
@@ -170,22 +155,18 @@ class AssetModelsController extends Controller
* @param int $modelId
* @return View
*/
public function getEdit($modelId = null)
public function edit($modelId = null)
{
// Check if the model exists
if (is_null($item = AssetModel::find($modelId))) {
// Redirect to the model management page
return redirect()->to('assets/models')->with('error', trans('admin/models/message.does_not_exist'));
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
}
$depreciation_list = Helper::depreciationList();
$manufacturer_list = Helper::manufacturerList();
$category_list = Helper::categoryList('asset');
$view = View::make('models/edit', compact('item'));
$view->with('category_list', $category_list);
$view->with('depreciation_list', $depreciation_list);
$view->with('manufacturer_list', $manufacturer_list);
$view->with('category_list', Helper::categoryList('asset'));
$view->with('depreciation_list', Helper::depreciationList());
$view->with('manufacturer_list', Helper::manufacturerList());
return $view;
}
@@ -199,39 +180,28 @@ class AssetModelsController extends Controller
* @param int $modelId
* @return Redirect
*/
public function postEdit($modelId = null)
public function update(Request $request, $modelId = null)
{
// Check if the model exists
if (is_null($model = AssetModel::find($modelId))) {
// Redirect to the models management page
return redirect()->to('admin/models')->with('error', trans('admin/models/message.does_not_exist'));
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
}
if (e(Input::get('depreciation_id')) == '') {
$model->depreciation_id = 0;
} else {
$model->depreciation_id = e(Input::get('depreciation_id'));
}
if (e(Input::get('eol')) == '') {
$model->eol = null;
} else {
$model->eol = e(Input::get('eol'));
}
// Update the model data
$model->name = e(Input::get('name'));
$model->model_number = e(Input::get('model_number'));
$model->manufacturer_id = e(Input::get('manufacturer_id'));
$model->category_id = e(Input::get('category_id'));
$model->notes = e(Input::get('notes'));
$model->depreciation_id = $request->input('depreciation_id');
$model->eol = $request->input('eol');
$model->name = $request->input('name');
$model->model_number = $request->input('model_number');
$model->manufacturer_id = $request->input('manufacturer_id');
$model->category_id = $request->input('category_id');
$model->notes = $request->input('notes');
$model->requestable = Input::has('requestable');
if (Input::get('custom_fieldset')=='') {
if ($request->input('custom_fieldset')=='') {
$model->fieldset_id = null;
} else {
$model->fieldset_id = e(Input::get('custom_fieldset'));
$model->fieldset_id = $request->input('custom_fieldset');
}
if (Input::file('image')) {
@@ -245,22 +215,14 @@ class AssetModelsController extends Controller
$model->image = $file_name;
}
if (Input::get('image_delete') == 1 && Input::file('image') == "") {
if ($request->input('image_delete') == 1 && Input::file('image') == "") {
$model->image = null;
}
// Was it created?
if ($model->save()) {
// Redirect to the new model page
return redirect()->to("hardware/models")->with('success', trans('admin/models/message.update.success'));
} else {
return redirect()->back()->withInput()->withErrors($model->getErrors());
return redirect()->route("models.index")->with('success', trans('admin/models/message.update.success'));
}
// Redirect to the model create page
return redirect()->to("hardware/models/$modelId/edit")->with('error', trans('admin/models/message.update.error'));
return redirect()->back()->withInput()->withErrors($model->getErrors());
}
/**
@@ -272,25 +234,22 @@ class AssetModelsController extends Controller
* @param int $modelId
* @return Redirect
*/
public function getDelete($modelId)
public function destroy($modelId)
{
// Check if the model exists
if (is_null($model = AssetModel::find($modelId))) {
// Redirect to the blogs management page
return redirect()->to('hardware/models')->with('error', trans('admin/models/message.not_found'));
return redirect()->route('models.index')->with('error', trans('admin/models/message.not_found'));
}
if ($model->assets->count() > 0) {
if ($model->assets()->count() > 0) {
// Throw an error that this model is associated with assets
return redirect()->to('hardware/models')->with('error', trans('admin/models/message.assoc_users'));
} else {
// Delete the model
$model->delete();
// Redirect to the models management page
return redirect()->to('hardware/models')->with('success', trans('admin/models/message.delete.success'));
return redirect()->route('models.index')->with('error', trans('admin/models/message.assoc_users'));
}
// Delete the model
$model->delete();
// Redirect to the models management page
return redirect()->route('models.index')->with('success', trans('admin/models/message.delete.success'));
}
@@ -317,11 +276,10 @@ class AssetModelsController extends Controller
$success = trans('admin/models/message.restore.success');
// Redirect back
return redirect()->back()->with('success', $success);
return redirect()->route('models.index')->with('success', $success);
} else {
return redirect()->back()->with('error', trans('admin/models/message.not_found'));
}
return redirect()->back()->with('error', trans('admin/models/message.not_found'));
}
@@ -334,21 +292,18 @@ class AssetModelsController extends Controller
* @param int $modelId
* @return View
*/
public function getView($modelId = null)
public function show($modelId = null)
{
$model = AssetModel::withTrashed()->find($modelId);
if (isset($model->id)) {
return View::make('models/view', compact('model'));
} else {
// Prepare the error message
$error = trans('admin/models/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('models')->with('error', $error);
return View::make('models/view', compact('model'));
}
// Prepare the error message
$error = trans('admin/models/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('models.index')->with('error', $error);
}
/**
@@ -363,21 +318,17 @@ class AssetModelsController extends Controller
{
// Check if the model exists
if (is_null($model_to_clone = AssetModel::find($modelId))) {
// Redirect to the model management page
return redirect()->to('assets/models')->with('error', trans('admin/models/message.does_not_exist'));
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
}
$model = clone $model_to_clone;
$model->id = null;
// Show the page
$depreciation_list = Helper::depreciationList();
$manufacturer_list = Helper::manufacturerList();
$category_list = Helper::categoryList('asset');
$view = View::make('models/edit');
$view->with('category_list', $category_list);
$view->with('depreciation_list', $depreciation_list);
$view->with('manufacturer_list', $manufacturer_list);
$view->with('category_list', Helper::categoryList('asset'));
$view->with('depreciation_list', Helper::depreciationList());
$view->with('manufacturer_list', Helper::manufacturerList());
$view->with('item', $model);
$view->with('clone_model', $model_to_clone);
return $view;
@@ -402,115 +353,29 @@ class AssetModelsController extends Controller
/**
* Get the JSON response to populate the data tables on the
* Asset Model listing page.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @param string $status
* @return String JSON
*/
public function getDatatable($status = null)
{
$models = AssetModel::with('category', 'assets', 'depreciation', 'manufacturer');
switch ($status) {
case 'Deleted':
$models->withTrashed()->Deleted();
break;
}
if (Input::has('search')) {
$models = $models->TextSearch(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 = ['id','name','model_number'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
$models = $models->orderBy($sort, $order);
$modelCount = $models->count();
$models = $models->skip($offset)->take($limit)->get();
$rows = array();
foreach ($models as $model) {
if ($model->deleted_at == '') {
$actions = '<div style=" white-space: nowrap;"><a href="'.route('clone/model', $model->id).'" class="btn btn-info btn-sm" title="Clone Model" data-toggle="tooltip"><i class="fa fa-clone"></i></a> <a href="'.route('update/model', $model->id).'" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a><a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/model', $model->id).'" data-content="'.trans('admin/models/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($model->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></div>';
} else {
$actions = '<a href="'.route('restore/model', $model->id).'" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
}
$rows[] = array(
'id' => $model->id,
'manufacturer' => (string)link_to('/admin/settings/manufacturers/'.$model->manufacturer->id.'/view', $model->manufacturer->name),
'name' => (string)link_to('/hardware/models/'.$model->id.'/view', $model->name),
'image' => ($model->image!='') ? '<img src="'.config('app.url').'/uploads/models/'.$model->image.'" height=50 width=50>' : '',
'modelnumber' => $model->model_number,
'numassets' => $model->assets->count(),
'depreciation' => (($model->depreciation) && ($model->depreciation->id > 0)) ? $model->depreciation->name.' ('.$model->depreciation->months.')' : trans('general.no_depreciation'),
'category' => ($model->category) ? (string)link_to('admin/settings/categories/'.$model->category->id.'/view', $model->category->name) : '',
'eol' => ($model->eol) ? $model->eol.' '.trans('general.months') : '',
'note' => $model->getNote(),
'fieldset' => ($model->fieldset) ? (string)link_to('admin/custom_fields/'.$model->fieldset->id, $model->fieldset->name) : '',
'actions' => $actions
);
}
$data = array('total' => $modelCount, 'rows' => $rows);
return $data;
}
/**
* Get the asset information to present to the model view detail page
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @param int $modelId
* @return String JSON
*/
public function getDataView($modelID)
* Get the asset information to present to the model view detail page
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @param Request $request
* @param $modelID
* @return String JSON
* @internal param int $modelId
*/
public function getDataView(Request $request, $modelID)
{
$assets = Asset::where('model_id', '=', $modelID)->with('company', 'assetstatus');
if (Input::has('search')) {
$assets = $assets->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;
$assets = $assets->TextSearch(e($request->input('search')));
}
$offset = request('offset', 0);
$limit = request('limit', 50);
$allowed_columns = ['name', 'serial','asset_tag'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
$assets = $assets->orderBy($sort, $order);
@@ -519,29 +384,10 @@ class AssetModelsController extends Controller
$rows = array();
$all_custom_fields = CustomField::all();
foreach ($assets as $asset) {
$actions = '';
if ($asset->assetstatus) {
if ($asset->assetstatus->deployable != 0) {
if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) {
$actions = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
} else {
$actions = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</a>';
}
}
}
$rows[] = array(
'id' => $asset->id,
'name' => (string)link_to('/hardware/'.$asset->id.'/view', $asset->showAssetName()),
'asset_tag' => (string)link_to('hardware/'.$asset->id.'/view', $asset->asset_tag),
'serial' => $asset->serial,
'assigned_to' => ($asset->assigned_to) ? (string)link_to('/admin/users/'.$asset->assigned_to.'/view', $asset->assigneduser->fullName()) : '',
'actions' => $actions,
'companyName' => Company::getName($asset)
);
$rows[] = $asset->present()->forDataTable($all_custom_fields);
}
$data = array('total' => $assetsCount, 'rows' => $rows);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\Request;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get the e-mail subject line to be used for the reset link email.
* Overriding method "getEmailSubject()" from trait "use ResetsPasswords"
* @return string
*/
public function getEmailSubject()
{
return property_exists($this, 'subject') ? $this->subject : \Lang::get('mail.reset_link');
}
/**
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function sendResetLinkEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$response = $this->broker()->sendResetLink(
$request->only('email')
);
if ($response === \Password::RESET_LINK_SENT) {
return redirect()->route('login')->with('status', trans($response));
}
// If an error was returned by the password broker, we will get this message
// translated so we can notify a user of the problem. We'll redirect back
// to where the users came from so they can attempt this process again.
return back()->withErrors(
['email' => trans($response)]
);
}
}

View File

@@ -5,7 +5,6 @@ namespace App\Http\Controllers\Auth;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use App\Models\Setting;
use App\Models\Ldap;
use App\Models\User;
@@ -18,20 +17,17 @@ use Log;
use View;
use PragmaRX\Google2FA\Google2FA;
/**
* This controller handles authentication for the user, including local
* database users and LDAP users.
*
* @todo Move LDAP methods into user model for better separation of concerns.
* @author [A. Gianotto] [<snipe@snipe.net>]
* @version v1.0
*/
class AuthController extends Controller
class LoginController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
use ThrottlesLogins;
// This tells the auth controller to use username instead of email address
protected $username = 'username';
@@ -67,7 +63,7 @@ class AuthController extends Controller
{
LOG::debug("Binding user to LDAP.");
$ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'));
if(!$ldap_user) {
if (!$ldap_user) {
LOG::debug("LDAP user ".$request->input('username')." not found in LDAP or could not bind");
throw new \Exception("Could not find user in LDAP directory");
} else {
@@ -75,7 +71,7 @@ class AuthController extends Controller
}
// Check if the user already exists in the database and was imported via LDAP
$user = User::where('username', '=', Input::get('username'))->whereNull('deleted_at')->where('ldap_import','=',1)->first();
$user = User::where('username', '=', Input::get('username'))->whereNull('deleted_at')->where('ldap_import', '=', 1)->first();
LOG::debug("Local auth lookup complete");
// The user does not exist in the database. Try to get them from LDAP.
@@ -123,16 +119,11 @@ class AuthController extends Controller
return redirect()->back()->withInput()->withErrors($validator);
}
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
$this->maxLoginAttempts = config('auth.throttle.max_attempts');
$this->lockoutTime = config('auth.throttle.lockout_duration');
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
if ($lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
@@ -142,8 +133,8 @@ class AuthController extends Controller
if (Setting::getSettings()->ldap_enabled=='1') {
LOG::debug("LDAP is enabled.");
try {
$user = $this->login_via_ldap($request);
Auth::login($user, true);
$user = $this->login_via_ldap($request);
Auth::login($user, true);
// If the user was unable to login via LDAP, log the error and let them fall through to
// local authentication.
@@ -153,32 +144,30 @@ class AuthController extends Controller
}
// If the user wasn't authenticated via LDAP, skip to local auth
if(!$user) {
LOG::debug("Authenticating user against database.");
if (!$user) {
LOG::debug("Authenticating user against database.");
// Try to log the user in
if (!Auth::attempt(Input::only('username', 'password'), Input::get('remember-me', 0))) {
if (!Auth::attempt(Input::only('username', 'password'), Input::get('remember-me', 0))) {
if ($throttles && ! $lockedOut) {
$this->incrementLoginAttempts($request);
}
if (!$lockedOut) {
$this->incrementLoginAttempts($request);
}
LOG::debug("Local authentication failed.");
return redirect()->back()->withInput()->with('error', trans('auth/message.account_not_found'));
} else {
LOG::debug("Local authentication failed.");
return redirect()->back()->withInput()->with('error', trans('auth/message.account_not_found'));
} else {
if ($throttles) {
$this->clearLoginAttempts($request);
}
}
}
}
// Get the page we were before
$redirect = \Session::get('loginRedirect', 'home');
// Unset the page we were before from the session
\Session::forget('loginRedirect');
if ($user = Auth::user()) {
$user->last_login = \Carbon::now();
\Log::debug('Last login:'.$user->last_login);
$user->save();
}
// Redirect to the users page
return redirect()->to($redirect)->with('success', trans('auth/message.signin.success'));
return redirect()->intended()->with('success', trans('auth/message.signin.success'));
}
@@ -209,7 +198,7 @@ class AuthController extends Controller
$user->two_factor_secret
);
return View::make('auth.two_factor_enroll')->with('google2fa_url',$google2fa_url);
return View::make('auth.two_factor_enroll')->with('google2fa_url', $google2fa_url);
}
@@ -219,7 +208,8 @@ class AuthController extends Controller
*
* @return Redirect
*/
public function getTwoFactorAuth() {
public function getTwoFactorAuth()
{
return View::make('auth.two_factor');
}
@@ -228,7 +218,8 @@ class AuthController extends Controller
*
* @return Redirect
*/
public function postTwoFactorAuth(Request $request) {
public function postTwoFactorAuth(Request $request)
{
if (!Auth::check()) {
return redirect()->route('login')->with('error', 'You must be logged in.');
@@ -279,18 +270,54 @@ class AuthController extends Controller
]);
}
/**
* Get the login lockout error message.
*
* @param int $seconds
* @return string
*/
protected function getLockoutErrorMessage($seconds)
public function username()
{
return \Lang::has('auth/message.throttle')
? \Lang::get('auth/message.throttle', ['seconds' => $seconds])
: 'Too many login attempts. Please try again in '.$seconds.' seconds.';
return 'username';
}
/**
* Redirect the user after determining they are locked out.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
protected function sendLockoutResponse(Request $request)
{
$seconds = $this->limiter()->availableIn(
$this->throttleKey($request)
);
$minutes = round($seconds / 60);
$message = \Lang::get('auth/message.throttle', ['minutes' => $minutes]);
return redirect()->back()
->withInput($request->only($this->username(), 'remember'))
->withErrors([$this->username() => $message]);
}
/**
* Override the lockout time and duration
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
protected function hasTooManyLoginAttempts(Request $request)
{
$lockoutTime = config('auth.throttle.lockout_duration');
$maxLoginAttempts = config('auth.throttle.max_attempts');
return $this->limiter()->tooManyAttempts(
$this->throttleKey($request),
$maxLoginAttempts,
$lockoutTime
);
}
public function legacyAuthRedirect() {
return redirect()->route('login');
}
}

View File

@@ -1,60 +0,0 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
/**
* This controller handles password resets for the user.
* It uses the built-in Laravel magic of ResetsPasswords, so we
* don't actually do much here.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @version v1.0
*/
class PasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Create a new password controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get the e-mail subject line to be used for the reset link email.
* Overriding method "getEmailSubject()" from trait "use ResetsPasswords"
* @return string
*/
public function getEmailSubject(){
return property_exists($this, 'subject') ? $this->subject : \Lang::get('mail.reset_link');
}
/**
* Get the response for after the reset link has been successfully sent.
*
* @param string $response
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function getSendResetLinkEmailSuccessResponse($response)
{
return redirect()->route('login')->with('status', trans($response));
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Models\Category as Category;
use App\Models\Company;
use App\Models\CustomField;
use App\Models\Setting;
use Auth;
use DB;
@@ -32,9 +33,9 @@ class CategoriesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see CategoriesController::getDatatable() method that generates the JSON response
* @since [v1.0]
* @return View
*/
public function getIndex()
* @return \Illuminate\Contracts\View\View
*/
public function index()
{
// Show the page
return View::make('categories/index');
@@ -45,16 +46,16 @@ class CategoriesController extends Controller
* Returns a form view to create a new category.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see CategoriesController::postCreate() method that stores the data
* @see CategoriesController::store() method that stores the data
* @since [v1.0]
* @return View
*/
public function getCreate()
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
// Show the page
$category_types= Helper::categoryTypeList();
return View::make('categories/edit')->with('item', new Category)
->with('category_types', $category_types);
->with('category_types', $category_types);
}
@@ -62,39 +63,28 @@ class CategoriesController extends Controller
* Validates and stores the new category data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see CategoriesController::getCreate() method that makes the form.
* @see CategoriesController::create() method that makes the form.
* @since [v1.0]
* @return Redirect
*/
public function postCreate()
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request)
{
// create a new model instance
$category = new Category();
// Update the category data
$category->name = e(Input::get('name'));
$category->category_type = e(Input::get('category_type'));
$category->eula_text = e(Input::get('eula_text'));
$category->use_default_eula = e(Input::get('use_default_eula', '0'));
$category->require_acceptance = e(Input::get('require_acceptance', '0'));
$category->checkin_email = e(Input::get('checkin_email', '0'));
$category->user_id = Auth::user()->id;
$category->name = $request->input('name');
$category->category_type = $request->input('category_type');
$category->eula_text = $request->input('eula_text');
$category->use_default_eula = $request->input('use_default_eula', '0');
$category->require_acceptance = $request->input('require_acceptance', '0');
$category->checkin_email = $request->input('checkin_email', '0');
$category->user_id = Auth::id();
if ($category->save()) {
// Redirect to the new category page
return redirect()->to("admin/settings/categories")->with('success', trans('admin/categories/message.create.success'));
} else {
// The given data did not pass validation
return redirect()->back()->withInput()->withErrors($category->getErrors());
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.create.success'));
}
// Redirect to the category create page
return redirect()->to('admin/settings/categories/create')->with('error', trans('admin/categories/message.create.error'));
return redirect()->back()->withInput()->withErrors($category->getErrors());
}
/**
@@ -104,67 +94,56 @@ class CategoriesController extends Controller
* @see CategoriesController::postEdit() method saves the data
* @param int $categoryId
* @since [v1.0]
* @return View
*/
public function getEdit($categoryId = null)
* @return \Illuminate\Contracts\View\View
*/
public function edit($categoryId = null)
{
// Check if the category exists
if (is_null($item = Category::find($categoryId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.does_not_exist'));
}
// Show the page
//$category_options = array('' => 'Top Level') + Category::lists('name', 'id');
$category_options = array('' => 'Top Level') + DB::table('categories')->where('id', '!=', $categoryId)->lists('name', 'id');
$category_types= Helper::categoryTypeList();
return View::make('categories/edit', compact('item'))
->with('category_options', $category_options)
->with('category_types', $category_types);
}
/**
* Validates and stores the updated category data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see CategoriesController::getEdit() method that makes the form.
* @param int $categoryId
* @since [v1.0]
* @return Redirect
*/
public function postEdit(Request $request, $categoryId = null)
* Validates and stores the updated category data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see CategoriesController::getEdit() method that makes the form.
* @param Request $request
* @param int $categoryId
* @return \Illuminate\Http\RedirectResponse
* @since [v1.0]
*/
public function update(Request $request, $categoryId = null)
{
// Check if the blog post exists
if (is_null($category = Category::find($categoryId))) {
// Redirect to the blogs management page
// Redirect to the categories management page
return redirect()->to('admin/categories')->with('error', trans('admin/categories/message.does_not_exist'));
}
// Update the category data
$category->name = e($request->input('name'));
$category->name = $request->input('name');
// If the item count is > 0, we disable the category type in the edit. Disabled items
// don't POST, so if the category_type is blank we just set it to the default.
$category->category_type = e($request->input('category_type', $category->category_type));
$category->eula_text = e($request->input('eula_text'));
$category->use_default_eula = e($request->input('use_default_eula', '0'));
$category->require_acceptance = e($request->input('require_acceptance', '0'));
$category->checkin_email = e($request->input('checkin_email', '0'));
$category->category_type = $request->input('category_type', $category->category_type);
$category->eula_text = $request->input('eula_text');
$category->use_default_eula = $request->input('use_default_eula', '0');
$category->require_acceptance = $request->input('require_acceptance', '0');
$category->checkin_email = $request->input('checkin_email', '0');
if ($category->save()) {
// Redirect to the new category page
return redirect()->to("admin/settings/categories")->with('success', trans('admin/categories/message.update.success'));
} // attempt validation
else {
// The given data did not pass validation
return redirect()->back()->withInput()->withErrors($category->getErrors());
// Redirect to the new category page
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.update.success'));
}
// Redirect to the category management page
return redirect()->back()->with('error', trans('admin/categories/message.update.error'));
// The given data did not pass validation
return redirect()->back()->withInput()->withErrors($category->getErrors());
}
/**
@@ -173,41 +152,31 @@ class CategoriesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @param int $categoryId
* @return Redirect
*/
public function getDelete($categoryId)
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($categoryId)
{
// Check if the category exists
if (is_null($category = Category::find($categoryId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.not_found'));
}
if ($category->has_models() > 0) {
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'model']));
} elseif ($category->accessories()->count() > 0) {
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory']));
} elseif ($category->consumables()->count() > 0) {
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable']));
} elseif ($category->components()->count() > 0) {
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'component']));
} else {
$category->delete();
// Redirect to the locations management page
return redirect()->to('admin/settings/categories')->with('success', trans('admin/categories/message.delete.success'));
}
$category->delete();
// Redirect to the locations management page
return redirect()->to(route('categories.index'))->with('success', trans('admin/categories/message.delete.success'));
}
/**
* Returns a view that invokes the ajax tables which actually contains
* the content for the categories detail view, which is generated in getDataView.
@@ -216,319 +185,32 @@ class CategoriesController extends Controller
* @see CategoriesController::getDataView() method that generates the JSON response
* @param int $categoryId
* @since [v1.8]
* @return View
*/
public function getView($categoryId = null)
* @return \Illuminate\Contracts\View\View
*/
public function show($id)
{
$category = Category::find($categoryId);
if ($category = Category::find($id)) {
if (isset($category->id)) {
return View::make('categories/view', compact('category'));
} else {
// Prepare the error message
$error = trans('admin/categories/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('categories')->with('error', $error);
}
}
/**
* Returns a JSON response with the data to populate the bootstrap table on the
* cateory listing page.
*
* @todo Refactor this nastiness. Assets do not behave the same as accessories, etc.
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see CategoriesController::getIndex() method that generates the view
* @since [v1.8]
* @return String JSON
*/
public function getDatatable()
{
// Grab all the categories
$categories = Category::with('assets', 'accessories', 'consumables', 'components');
if (Input::has('search')) {
$categories = $categories->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 = ['id','name','category_type'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
$categories = $categories->orderBy($sort, $order);
$catCount = $categories->count();
$categories = $categories->skip($offset)->take($limit)->get();
$rows = array();
foreach ($categories as $category) {
$actions = '<a href="'.route('update/category', $category->id).'" class="btn btn-warning btn-sm" style="margin-right:5px;">';
$actions .='<i class="fa fa-pencil icon-white"></i></a>';
$actions .='<a data-html="false" class="btn delete-asset btn-danger btn-sm';
if ($category->itemCount() > 0) {
$actions .=' disabled';
}
$actions .=' data-toggle="modal" href="'.route('delete/category', $category->id).'" data-content="'.trans('admin/categories/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($category->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
$rows[] = array(
'id' => $category->id,
'name' => (string)link_to('/admin/settings/categories/'.$category->id.'/view', $category->name) ,
'category_type' => ucwords($category->category_type),
'count' => $category->itemCount(),
'acceptance' => ($category->require_acceptance=='1') ? '<i class="fa fa-check"></i>' : '',
'eula' => ($category->getEula()) ? '<i class="fa fa-check"></i>' : '',
'actions' => $actions
);
}
$data = array('total' => $catCount, 'rows' => $rows);
return $data;
}
public function getDataViewAssets($categoryID)
{
$category = Category::find($categoryID);
$category = $category->load('assets.company', 'assets.model', 'assets.assetstatus', 'assets.assigneduser');
$category_assets = $category->assets();
if (Input::has('search')) {
$category_assets = $category_assets->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;
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$allowed_columns = ['id','name','serial','asset_tag'];
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$count = $category_assets->count();
$category_assets = $category_assets->skip($offset)->take($limit)->get();
$rows = array();
foreach ($category_assets as $asset) {
$actions = '';
$inout='';
if ($asset->deleted_at=='') {
$actions = '<div style=" white-space: nowrap;"><a href="'.route('clone/hardware', $asset->id).'" class="btn btn-info btn-sm" title="Clone asset"><i class="fa fa-files-o"></i></a> <a href="'.route('update/hardware', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> <a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/hardware', $asset->id).'" data-content="'.trans('admin/hardware/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($asset->asset_tag).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></div>';
} elseif ($asset->deleted_at!='') {
$actions = '<a href="'.route('restore/hardware', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
}
if ($asset->availableForCheckout()) {
if (Gate::allows('assets.checkout')) {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</a>';
}
if ($category->category_type=='asset') {
$category_type = 'hardware';
$category_type_route = 'assets';
} elseif ($category->category_type=='accessory') {
$category_type = 'accessories';
$category_type_route = 'accessories';
} else {
if (Gate::allows('assets.checkin')) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
}
$category_type = $category->category_type;
$category_type_route = $category->category_type.'s';
}
$rows[] = array(
'id' => $asset->id,
'name' => (string)link_to('/hardware/'.$asset->id.'/view', $asset->showAssetName()),
'model' => ($asset->model) ? (string)link_to('hardware/models/'.$asset->model->id.'/view', $asset->model->name) : '',
'asset_tag' => $asset->asset_tag,
'serial' => $asset->serial,
'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', $asset->assigneduser->fullName()): '',
'change' => $inout,
'actions' => $actions,
'companyName' => is_null($asset->company) ? '' : e($asset->company->name)
);
return View::make('categories/view', compact('category'))
->with('category_type',$category_type)
->with('category_type_route',$category_type_route);
}
$data = array('total' => $count, 'rows' => $rows);
return $data;
// Prepare the error message
$error = trans('admin/categories/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('categories.index')->with('error', $error);
}
public function getDataViewAccessories($categoryID)
{
$category = Category::with('accessories.company')->find($categoryID);
$category_assets = $category->accessories;
if (Input::has('search')) {
$category_assets = $category_assets->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;
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$allowed_columns = ['id','name','serial','asset_tag'];
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$count = $category_assets->count();
$rows = array();
foreach ($category_assets as $asset) {
$actions = '';
$inout='';
if ($asset->deleted_at=='') {
$actions = '<div style=" white-space: nowrap;"><a href="'.route('update/accessory', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> <a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/accessory', $asset->id).'" data-content="'.trans('admin/hardware/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($asset->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></div>';
}
$rows[] = array(
'id' => $asset->id,
'name' => (string)link_to_route('view/accessory', $asset->name, [$asset->id]),
'actions' => $actions,
'companyName' => Company::getName($asset),
);
}
$data = array('total' => $count, 'rows' => $rows);
return $data;
}
public function getDataViewConsumables($categoryID)
{
$category = Category::with('accessories.company')->find($categoryID);
$category_assets = $category->consumables;
if (Input::has('search')) {
$category_assets = $category_assets->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;
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$allowed_columns = ['id','name','serial','asset_tag'];
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$count = $category_assets->count();
$rows = array();
foreach ($category_assets as $asset) {
$actions = '';
$inout='';
if ($asset->deleted_at=='') {
$actions = '<div style=" white-space: nowrap;"><a href="'.route('update/consumable', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> <a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/consumable', $asset->id).'" data-content="'.trans('admin/hardware/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($asset->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></div>';
}
$rows[] = array(
'id' => $asset->id,
'name' => (string) link_to_route('view/consumable', $asset->name, [$asset->id]),
'actions' => $actions,
'companyName' => Company::getName($asset),
);
}
$data = array('total' => $count, 'rows' => $rows);
return $data;
}
public function getDataViewComponent($categoryID)
{
$category = Category::with('accessories.company')->find($categoryID);
$category_assets = $category->components;
if (Input::has('search')) {
$category_assets = $category_assets->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;
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$allowed_columns = ['id','name','serial','asset_tag'];
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$count = $category_assets->count();
$rows = array();
foreach ($category_assets as $asset) {
$actions = '';
$inout='';
if ($asset->deleted_at=='') {
$actions = '<div style=" white-space: nowrap;"><a href="'.route('update/component', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> <a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/component', $asset->id).'" data-content="'.trans('admin/hardware/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($asset->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></div>';
}
$rows[] = array(
'id' => $asset->id,
'name' => (string)link_to_route('view/accessory', $asset->name, [$asset->id]),
'actions' => $actions,
'companyName' => Company::getName($asset),
);
}
$data = array('total' => $count, 'rows' => $rows);
return $data;
}
}

View File

@@ -6,6 +6,7 @@ use Input;
use Lang;
use Redirect;
use View;
use Illuminate\Http\Request;
/**
* This controller handles all actions related to Companies for
@@ -22,9 +23,9 @@ final class CompaniesController extends Controller
*
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @return View
*/
public function getIndex()
* @return \Illuminate\Contracts\View\View
*/
public function index()
{
return View::make('companies/index')->with('companies', Company::all());
}
@@ -34,33 +35,31 @@ final class CompaniesController extends Controller
*
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @return View
*/
public function getCreate()
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
return View::make('companies/edit')->with('item', new Company);
}
/**
* Save data from new company form.
*
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @return Redirect
*/
public function postCreate()
* Save data from new company form.
*
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request)
{
$company = new Company;
$company->name = e(Input::get('name'));
$company->name = $request->input('name');
if ($company->save()) {
return redirect()->to('admin/settings/companies')
return redirect()->route('companies.index')
->with('success', trans('admin/companies/message.create.success'));
} else {
return redirect()->back()->withInput()->withErrors($company->getErrors());
}
return redirect()->back()->withInput()->withErrors($company->getErrors());
}
@@ -70,44 +69,40 @@ final class CompaniesController extends Controller
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @param int $companyId
* @return View
*/
public function getEdit($companyId)
* @return \Illuminate\Contracts\View\View
*/
public function edit($companyId)
{
if (is_null($item = Company::find($companyId))) {
return redirect()->to('admin/settings/companies')
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.does_not_exist'));
} else {
return View::make('companies/edit')->with('item', $item);
}
return View::make('companies/edit')->with('item', $item);
}
/**
* Save data from edit company form.
*
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @param int $companyId
* @return Redirect
*/
public function postEdit($companyId)
* Save data from edit company form.
*
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @param Request $request
* @param int $companyId
* @return \Illuminate\Http\RedirectResponse
*/
public function update(Request $request, $companyId)
{
if (is_null($company = Company::find($companyId))) {
return redirect()->to('admin/settings/companies')->with('error', trans('admin/companies/message.does_not_exist'));
} else {
$company->name = e(Input::get('name'));
if ($company->save()) {
return redirect()->to('admin/settings/companies')
->with('success', trans('admin/companies/message.update.success'));
} else {
return redirect()->to("admin/settings/companies/$companyId/edit")
->with('error', trans('admin/companies/message.update.error'));
}
return redirect()->route('companies.index')->with('error', trans('admin/companies/message.does_not_exist'));
}
$company->name = $request->input('name');
if ($company->save()) {
return redirect()->route('companies.index')
->with('success', trans('admin/companies/message.update.success'));
}
return redirect()->route('companies.edit', ['company' => $companyId])
->with('error', trans('admin/companies/message.update.error'));
}
/**
@@ -116,17 +111,17 @@ final class CompaniesController extends Controller
* @author [Abdullah Alansari] [<ahimta@gmail.com>]
* @since [v1.8]
* @param int $companyId
* @return Redirect
*/
public function postDelete($companyId)
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($companyId)
{
if (is_null($company = Company::find($companyId))) {
return redirect()->to('admin/settings/companies')
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.not_found'));
} else {
try {
$company->delete();
return redirect()->to('admin/settings/companies')
return redirect()->route('companies.index')
->with('success', trans('admin/companies/message.delete.success'));
} catch (\Illuminate\Database\QueryException $exception) {
/*
@@ -134,7 +129,7 @@ final class CompaniesController extends Controller
* For example when rows in other tables are referencing this company
*/
if ($exception->getCode() == 23000) {
return redirect()->to('admin/settings/companies')
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.assoc_users'));
} else {
throw $exception;
@@ -142,4 +137,16 @@ final class CompaniesController extends Controller
}
}
}
public function show($id) {
$this->authorize('view', Company::class);
if (is_null($company = Company::find($id))) {
return redirect()->route('companies.index')
->with('error', trans('admin/companies/message.not_found'));
} else {
return View::make('companies/view')->with('company',$company);
}
}
}

View File

@@ -5,12 +5,14 @@ use App\Helpers\Helper;
use App\Models\Actionlog;
use App\Models\Company;
use App\Models\Component;
use App\Models\CustomField;
use App\Models\Setting;
use App\Models\User;
use App\Models\Asset;
use Auth;
use Config;
use DB;
use DeepCopyTest\H;
use Input;
use Lang;
use Mail;
@@ -37,10 +39,11 @@ class ComponentsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ComponentsController::getDatatable() method that generates the JSON response
* @since [v3.0]
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getIndex()
public function index()
{
$this->authorize('view', Component::class);
return View::make('components/index');
}
@@ -51,20 +54,17 @@ class ComponentsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ComponentsController::postCreate() method that stores the data
* @since [v3.0]
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getCreate()
public function create()
{
$this->authorize('create', Component::class);
// Show the page
$category_list = Helper::categoryList('component');
$company_list = Helper::companyList();
$location_list = Helper::locationsList();
return View::make('components/edit')
->with('item', new Component)
->with('category_list', $category_list)
->with('company_list', $company_list)
->with('location_list', $location_list);
->with('category_list', Helper::categoryList('component'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList());
}
@@ -74,48 +74,34 @@ class ComponentsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ComponentsController::getCreate() method that generates the view
* @since [v3.0]
* @return Redirect
*/
public function postCreate()
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
$this->authorize('create', Component::class);
// create a new model instance
$component = new Component();
// Update the component data
$component->name = e(Input::get('name'));
$component->category_id = e(Input::get('category_id'));
$component->location_id = e(Input::get('location_id'));
$component->name = Input::get('name');
$component->category_id = Input::get('category_id');
$component->location_id = Input::get('location_id');
$component->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
$component->order_number = e(Input::get('order_number'));
$component->min_amt = e(Input::get('min_amt'));
$component->serial = e(Input::get('serial'));
if (e(Input::get('purchase_date')) == '') {
$component->purchase_date = null;
} else {
$component->purchase_date = e(Input::get('purchase_date'));
}
if (e(Input::get('purchase_cost')) == '0.00') {
$component->purchase_cost = null;
} else {
$component->purchase_cost = Helper::ParseFloat(e(Input::get('purchase_cost')));
}
$component->qty = e(Input::get('qty'));
$component->user_id = Auth::user()->id;
$component->order_number = Input::get('order_number');
$component->min_amt = Input::get('min_amt');
$component->serial = Input::get('serial');
$component->purchase_date = Input::get('purchase_date');
$component->purchase_cost = request('purchase_cost');
$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()->to("admin/components")->with('success', trans('admin/components/message.create.success'));
return redirect()->route('components.index')->with('success', trans('admin/components/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($component->getErrors());
}
/**
@@ -125,26 +111,22 @@ class ComponentsController extends Controller
* @see ComponentsController::postEdit() method that stores the data.
* @since [v3.0]
* @param int $componentId
* @return View
*/
public function getEdit($componentId = null)
* @return \Illuminate\Contracts\View\View
*/
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()->to('admin/components')->with('error', trans('admin/components/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($item)) {
return redirect()->to('admin/components')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
}
$category_list = Helper::categoryList('component');
$company_list = Helper::companyList();
$location_list = Helper::locationsList();
$this->authorize('update', $item);
return View::make('components/edit', compact('item'))
->with('category_list', $category_list)
->with('company_list', $company_list)
->with('location_list', $location_list);
->with('category_list', Helper::categoryList('component'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList());
}
@@ -155,53 +137,35 @@ class ComponentsController extends Controller
* @see ComponentsController::getEdit() method presents the form.
* @param int $componentId
* @since [v3.0]
* @return Redirect
*/
public function postEdit($componentId = null)
* @return \Illuminate\Http\RedirectResponse
*/
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()->to('admin/components')->with('error', trans('admin/components/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($component)) {
return redirect()->to('admin/components')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
}
$this->authorize('update', $component);
// Update the component data
$component->name = e(Input::get('name'));
$component->category_id = e(Input::get('category_id'));
$component->location_id = e(Input::get('location_id'));
$component->name = Input::get('name');
$component->category_id = Input::get('category_id');
$component->location_id = Input::get('location_id');
$component->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
$component->order_number = e(Input::get('order_number'));
$component->min_amt = e(Input::get('min_amt'));
$component->serial = e(Input::get('serial'));
$component->order_number = Input::get('order_number');
$component->min_amt = Input::get('min_amt');
$component->serial = Input::get('serial');
$component->purchase_date = Input::get('purchase_date');
$component->purchase_cost = request('purchase_cost');
$component->qty = Input::get('qty');
if (e(Input::get('purchase_date')) == '') {
$component->purchase_date = null;
} else {
$component->purchase_date = e(Input::get('purchase_date'));
}
if (e(Input::get('purchase_cost')) == '0.00') {
$component->purchase_cost = null;
} else {
$component->purchase_cost = Helper::ParseFloat(e(Input::get('purchase_cost')));
}
$component->qty = e(Input::get('qty'));
// Was the component created?
if ($component->save()) {
// Redirect to the new component page
return redirect()->to("admin/components")->with('success', trans('admin/components/message.update.success'));
return redirect()->route('components.index')->with('success', trans('admin/components/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($component->getErrors());
}
/**
@@ -210,32 +174,28 @@ class ComponentsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @param int $componentId
* @return Redirect
*/
public function getDelete($componentId)
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($componentId)
{
// Check if the blog post exists
if (is_null($component = Component::find($componentId))) {
// Redirect to the blogs management page
return redirect()->to('admin/components')->with('error', trans('admin/components/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($component)) {
return redirect()->to('admin/components')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
}
$component->delete();
// Redirect to the locations management page
return redirect()->to('admin/components')->with('success', trans('admin/components/message.delete.success'));
$this->authorize('delete', $component);
$component->delete();
return redirect()->route('components.index')->with('success', trans('admin/components/message.delete.success'));
}
public function postBulk($componentId = null)
{
//$this->authorize('checkout', $component)
echo 'Stubbed - not yet complete';
}
public function postBulkSave($componentId = null)
{
//$this->authorize('edit', Component::class);
echo 'Stubbed - not yet complete';
}
@@ -247,29 +207,20 @@ class ComponentsController extends Controller
* @see ComponentsController::getDataView() method that generates the JSON response
* @since [v3.0]
* @param int $componentId
* @return View
*/
public function getView($componentId = null)
* @return \Illuminate\Contracts\View\View
*/
public function show($componentId = null)
{
$component = Component::find($componentId);
if (isset($component->id)) {
if (!Company::isCurrentUserHasAccess($component)) {
return redirect()->to('admin/components')->with('error', trans('general.insufficient_permissions'));
} else {
return View::make('components/view', compact('component'));
}
} else {
// Prepare the error message
$error = trans('admin/components/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('components')->with('error', $error);
$this->authorize('view', $component);
return View::make('components/view', compact('component'));
}
// Prepare the error message
$error = trans('admin/components/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('components.index')->with('error', $error);
}
/**
@@ -279,50 +230,41 @@ class ComponentsController extends Controller
* @see ComponentsController::postCheckout() method that stores the data.
* @since [v3.0]
* @param int $componentId
* @return View
*/
* @return \Illuminate\Contracts\View\View
*/
public function getCheckout($componentId)
{
// Check if the component exists
if (is_null($component = Component::find($componentId))) {
// Redirect to the component management page with error
return redirect()->to('components')->with('error', trans('admin/components/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($component)) {
return redirect()->to('admin/components')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
}
// Get the dropdown of assets and then pass it to the checkout view
$assets_list = Helper::detailedAssetList();
return View::make('components/checkout', compact('component'))->with('assets_list', $assets_list);
$this->authorize('checkout', $component);
return View::make('components/checkout', compact('component'))->with('assets_list', Helper::detailedAssetList());
}
/**
* Validate and store checkout data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ComponentsController::getCheckout() method that returns the form.
* @since [v3.0]
* @param int $componentId
* @return Redirect
*/
* Validate and store checkout data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ComponentsController::getCheckout() method that returns the form.
* @since [v3.0]
* @param Request $request
* @param int $componentId
* @return \Illuminate\Http\RedirectResponse
*/
public function postCheckout(Request $request, $componentId)
{
// Check if the component exists
if (is_null($component = Component::find($componentId))) {
// Redirect to the component management page with error
return redirect()->to('components')->with('error', trans('admin/components/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($component)) {
return redirect()->to('admin/components')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
}
$this->authorize('checkout', $component);
$max_to_checkout = $component->numRemaining();
$validator = Validator::make($request->all(),[
$validator = Validator::make($request->all(), [
"asset_id" => "required",
"assigned_qty" => "required|numeric|between:1,$max_to_checkout"
]);
@@ -339,159 +281,25 @@ class ComponentsController extends Controller
// Check if the user exists
if (is_null($asset = Asset::find($asset_id))) {
// Redirect to the component management page with error
return redirect()->to('admin/components')->with('error', trans('admin/components/message.asset_does_not_exist'));
return redirect()->route('components.index')->with('error', trans('admin/components/message.asset_does_not_exist'));
}
// Update the component data
$component->asset_id = $asset_id;
$component->assets()->attach($component->id, array(
'component_id' => $component->id,
'user_id' => $admin_user->id,
'created_at' => date('Y-m-d H:i:s'),
'assigned_qty' => e(Input::get('assigned_qty')),
'asset_id' => $asset_id));
$logaction = $component->logCheckout(e(Input::get('note')), $asset_id);
$settings = Setting::getSettings();
if ($settings->slack_endpoint) {
$slack_settings = [
'username' => $settings->botname,
'channel' => $settings->slack_channel,
'link_names' => true
];
$client = new \Maknz\Slack\Client($settings->slack_endpoint, $slack_settings);
try {
$client->attach([
'color' => 'good',
'fields' => [
[
'title' => 'Checked Out:',
'value' => class_basename(strtoupper($logaction->item_type)).' <'.config('app.url').'/admin/components/'.$component->id.'/view'.'|'.$component->name.'> checked out to <'.config('app.url').'/hardware/'.$asset->id.'/view|'.$asset->showAssetName().'> by <'.config('app.url').'/admin/users/'.$admin_user->id.'/view'.'|'.$admin_user->fullName().'>.'
],
[
'title' => 'Note:',
'value' => e($logaction->note)
],
]
])->send('Component Checked Out');
} catch (Exception $e) {
}
}
// Redirect to the new component page
return redirect()->to("admin/components")->with('success', trans('admin/components/message.checkout.success'));
$component->assets()->attach($component->id, [
'component_id' => $component->id,
'user_id' => $admin_user->id,
'created_at' => date('Y-m-d H:i:s'),
'assigned_qty' => Input::get('assigned_qty'),
'asset_id' => $asset_id
]);
$component->logCheckout(e(Input::get('note')), $asset_id);
return redirect()->route('components.index')->with('success', trans('admin/components/message.checkout.success'));
}
/**
* Generates the JSON response for accessories listing view.
*
* For debugging, see at /api/accessories/list
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return string JSON
**/
public function getDatatable()
{
$components = Company::scopeCompanyables(Component::select('components.*')->whereNull('components.deleted_at')
->with('company', 'location', 'category'));
if (Input::has('search')) {
$components = $components->TextSearch(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 = ['id','name','min_amt','order_number','serial','purchase_date','purchase_cost','companyName','category','total_qty'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
switch ($sort) {
case 'category':
$components = $components->OrderCategory($order);
break;
case 'location':
$components = $components->OrderLocation($order);
break;
case 'companyName':
$components = $components->OrderCompany($order);
break;
default:
$components = $components->orderBy($sort, $order);
break;
}
$consumCount = $components->count();
$components = $components->skip($offset)->take($limit)->get();
$rows = array();
foreach ($components as $component) {
$actions = '<nobr>';
if (Gate::allows('components.checkout')) {
$actions .= '<a href="' . route('checkout/component',
$component->id) . '" style="margin-right:5px;" class="btn btn-info btn-sm ' . (($component->numRemaining() > 0) ? '' : ' disabled') . '" ' . (($component->numRemaining() > 0) ? '' : ' disabled') . '>' . trans('general.checkout') . '</a>';
}
if (Gate::allows('components.edit')) {
$actions .= '<a href="' . route('update/component',
$component->id) . '" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a>';
}
if (Gate::allows('components.delete')) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/component',
$component->id) . '" data-content="' . trans('admin/components/message.delete.confirm') . '" data-title="' . trans('general.delete') . ' ' . htmlspecialchars($component->name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
}
$actions .='</nobr>';
$company = $component->company;
$rows[] = array(
'checkbox' =>'<div class="text-center"><input type="checkbox" name="component['.$component->id.']" class="one_required"></div>',
'id' => $component->id,
'name' => (string)link_to('admin/components/'.$component->id.'/view', e($component->name)),
'serial_number' => $component->serial,
'location' => ($component->location) ? e($component->location->name) : '',
'qty' => e($component->qty),
'min_amt' => e($component->min_amt),
'category' => ($component->category) ? e($component->category->name) : 'Missing category',
'order_number' => e($component->order_number),
'purchase_date' => e($component->purchase_date),
'purchase_cost' => Helper::formatCurrencyOutput($component->purchase_cost),
'numRemaining' => $component->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name),
);
}
$data = array('total' => $consumCount, 'rows' => $rows);
return $data;
}
/**
* Return JSON data to populate the components view,
*
@@ -503,22 +311,20 @@ class ComponentsController extends Controller
*/
public function getDataView($componentId)
{
//$component = Component::find($componentID);
$component = Component::with('assets')->find($componentId);
if (is_null($component = Component::with('assets')->find($componentId))) {
// Redirect to the component management page with error
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
}
if (!Company::isCurrentUserHasAccess($component)) {
return ['total' => 0, 'rows' => []];
}
$this->authorize('view', $component);
$rows = array();
$all_custom_fields = CustomField::all(); // Cached for table;
foreach ($component->assets as $component_assignment) {
$rows[] = array(
'name' => (string)link_to('/hardware/'.$component_assignment->id.'/view', e($component_assignment->showAssetName())),
'qty' => e($component_assignment->pivot->assigned_qty),
'created_at' => ($component_assignment->created_at->format('Y-m-d H:i:s')=='-0001-11-30 00:00:00') ? '' : $component_assignment->created_at->format('Y-m-d H:i:s'),
);
$rows[] = $component_assignment->present()->forDataTable($all_custom_fields);
}
$componentCount = $component->assets->count();

View File

@@ -8,6 +8,7 @@ use App\Models\Company;
use App\Models\Consumable;
use App\Models\Setting;
use App\Models\User;
use App\Notifications\CheckoutNotification;
use Auth;
use Config;
use DB;
@@ -34,10 +35,11 @@ class ConsumablesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ConsumablesController::getDatatable() method that generates the JSON response
* @since [v1.0]
* @return View
*/
public function getIndex()
* @return \Illuminate\Contracts\View\View
*/
public function index()
{
$this->authorize('index', Consumable::class);
return View::make('consumables/index');
}
@@ -48,22 +50,18 @@ class ConsumablesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ConsumablesController::postCreate() method that stores the form data
* @since [v1.0]
* @return View
*/
public function getCreate()
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
$this->authorize('create', Consumable::class);
// Show the page
$category_list = Helper::categoryList('consumable');
$company_list = Helper::companyList();
$location_list = Helper::locationsList();
$manufacturer_list = Helper::manufacturerList();
return View::make('consumables/edit')
->with('item', new Consumable)
->with('category_list', $category_list)
->with('company_list', $company_list)
->with('location_list', $location_list)
->with('manufacturer_list', $manufacturer_list);
->with('category_list', Helper::categoryList('consumable'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList())
->with('manufacturer_list', Helper::manufacturerList());
}
@@ -73,46 +71,35 @@ class ConsumablesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ConsumablesController::getCreate() method that returns the form view
* @since [v1.0]
* @return Redirect
*/
public function postCreate()
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
$this->authorize('create', Consumable::class);
$consumable = new Consumable();
$consumable->name = e(Input::get('name'));
$consumable->category_id = e(Input::get('category_id'));
$consumable->location_id = e(Input::get('location_id'));
$consumable->name = Input::get('name');
$consumable->category_id = Input::get('category_id');
$consumable->location_id = Input::get('location_id');
$consumable->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
$consumable->order_number = e(Input::get('order_number'));
$consumable->min_amt = e(Input::get('min_amt'));
$consumable->manufacturer_id = e(Input::get('manufacturer_id'));
$consumable->model_number = e(Input::get('model_number'));
$consumable->item_no = e(Input::get('item_no'));
if (e(Input::get('purchase_date')) == '') {
$consumable->purchase_date = null;
} else {
$consumable->purchase_date = e(Input::get('purchase_date'));
}
if (e(Input::get('purchase_cost')) == '0.00') {
$consumable->purchase_cost = null;
} else {
$consumable->purchase_cost = Helper::ParseFloat(e(Input::get('purchase_cost')));
}
$consumable->qty = e(Input::get('qty'));
$consumable->user_id = Auth::user()->id;
$consumable->order_number = Input::get('order_number');
$consumable->min_amt = Input::get('min_amt');
$consumable->manufacturer_id = Input::get('manufacturer_id');
$consumable->model_number = Input::get('model_number');
$consumable->item_no = Input::get('item_no');
$consumable->purchase_date = Input::get('purchase_date');
$consumable->purchase_cost = Helper::ParseFloat(Input::get('purchase_cost'));
$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()->to("admin/consumables")->with('success', trans('admin/consumables/message.create.success'));
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
}
/**
@@ -122,28 +109,23 @@ class ConsumablesController extends Controller
* @param int $consumableId
* @see ConsumablesController::postEdit() method that stores the form data.
* @since [v1.0]
* @return View
*/
public function getEdit($consumableId = null)
* @return \Illuminate\Contracts\View\View
*/
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()->to('admin/consumables')->with('error', trans('admin/consumables/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($item)) {
return redirect()->to('admin/consumables')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
}
$category_list = Helper::categoryList('consumable');
$company_list = Helper::companyList();
$location_list = Helper::locationsList();
$manufacturer_list = Helper::manufacturerList();
$this->authorize($item);
return View::make('consumables/edit', compact('item'))
->with('category_list', $category_list)
->with('company_list', $company_list)
->with('location_list', $location_list)
->with('manufacturer_list', $manufacturer_list);
->with('category_list', Helper::categoryList('consumable'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList())
->with('manufacturer_list', Helper::manufacturerList());
}
@@ -154,46 +136,33 @@ class ConsumablesController extends Controller
* @param int $consumableId
* @see ConsumablesController::getEdit() method that stores the form data.
* @since [v1.0]
* @return Redirect
*/
public function postEdit($consumableId = null)
* @return \Illuminate\Http\RedirectResponse
*/
public function update($consumableId = null)
{
if (is_null($consumable = Consumable::find($consumableId))) {
return redirect()->to('admin/consumables')->with('error', trans('admin/consumables/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($consumable)) {
return redirect()->to('admin/consumables')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
}
$consumable->name = e(Input::get('name'));
$consumable->category_id = e(Input::get('category_id'));
$consumable->location_id = e(Input::get('location_id'));
$this->authorize($consumable);
$consumable->name = Input::get('name');
$consumable->category_id = Input::get('category_id');
$consumable->location_id = Input::get('location_id');
$consumable->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
$consumable->order_number = e(Input::get('order_number'));
$consumable->min_amt = e(Input::get('min_amt'));
$consumable->manufacturer_id = e(Input::get('manufacturer_id'));
$consumable->model_number = e(Input::get('model_number'));
$consumable->item_no = e(Input::get('item_no'));
if (e(Input::get('purchase_date')) == '') {
$consumable->purchase_date = null;
} else {
$consumable->purchase_date = e(Input::get('purchase_date'));
}
if (e(Input::get('purchase_cost')) == '0.00') {
$consumable->purchase_cost = null;
} else {
$consumable->purchase_cost = Helper::ParseFloat(e(Input::get('purchase_cost')));
}
$consumable->qty = Helper::ParseFloat(e(Input::get('qty')));
$consumable->order_number = Input::get('order_number');
$consumable->min_amt = Input::get('min_amt');
$consumable->manufacturer_id = Input::get('manufacturer_id');
$consumable->model_number = Input::get('model_number');
$consumable->item_no = Input::get('item_no');
$consumable->purchase_date = Input::get('purchase_date');
$consumable->purchase_cost = Helper::ParseFloat(Input::get('purchase_cost'));
$consumable->qty = Helper::ParseFloat(Input::get('qty'));
if ($consumable->save()) {
return redirect()->to("admin/consumables")->with('success', trans('admin/consumables/message.update.success'));
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($consumable->getErrors());
}
/**
@@ -202,27 +171,21 @@ class ConsumablesController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $consumableId
* @since [v1.0]
* @return Redirect
*/
public function getDelete($consumableId)
* @return \Illuminate\Http\RedirectResponse
*/
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()->to('admin/consumables')->with('error', trans('admin/consumables/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($consumable)) {
return redirect()->to('admin/consumables')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
}
$consumable->delete();
// Redirect to the locations management page
return redirect()->to('admin/consumables')->with('success', trans('admin/consumables/message.delete.success'));
$this->authorize($consumable);
$consumable->delete();
// Redirect to the locations management page
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.delete.success'));
}
/**
* Return a view to display component information.
*
@@ -230,29 +193,20 @@ class ConsumablesController extends Controller
* @see ConsumablesController::getDataView() method that generates the JSON response
* @since [v1.0]
* @param int $consumableId
* @return View
*/
public function getView($consumableId = null)
* @return \Illuminate\Contracts\View\View
*/
public function show($consumableId = null)
{
$consumable = Consumable::find($consumableId);
$this->authorize($consumable);
if (isset($consumable->id)) {
if (!Company::isCurrentUserHasAccess($consumable)) {
return redirect()->to('admin/consumables')->with('error', trans('general.insufficient_permissions'));
} else {
return View::make('consumables/view', compact('consumable'));
}
} else {
// 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 View::make('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);
}
/**
@@ -262,23 +216,18 @@ class ConsumablesController extends Controller
* @see ConsumablesController::postCheckout() method that stores the data.
* @since [v1.0]
* @param int $consumableId
* @return View
*/
* @return \Illuminate\Contracts\View\View
*/
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()->to('consumables')->with('error', trans('admin/consumables/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($consumable)) {
return redirect()->to('admin/consumables')->with('error', trans('general.insufficient_permissions'));
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
$users_list = Helper::usersList();
return View::make('consumables/checkout', compact('consumable'))->with('users_list', $users_list);
return View::make('consumables/checkout', compact('consumable'))->with('users_list', Helper::usersList());
}
/**
@@ -288,71 +237,37 @@ class ConsumablesController extends Controller
* @see ConsumablesController::getCheckout() method that returns the form.
* @since [v1.0]
* @param int $consumableId
* @return Redirect
*/
* @return \Illuminate\Http\RedirectResponse
*/
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()->to('consumables')->with('error', trans('admin/consumables/message.not_found'));
} elseif (!Company::isCurrentUserHasAccess($consumable)) {
return redirect()->to('admin/consumables')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
}
$this->authorize('checkout', $consumable);
$admin_user = Auth::user();
$assigned_to = e(Input::get('assigned_to'));
// Check if the user exists
if (is_null($user = User::find($assigned_to))) {
// Redirect to the consumable management page with error
return redirect()->to('admin/consumables')->with('error', trans('admin/consumables/message.user_does_not_exist'));
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.user_does_not_exist'));
}
// Update the consumable data
$consumable->assigned_to = e(Input::get('assigned_to'));
$consumable->users()->attach($consumable->id, array(
'consumable_id' => $consumable->id,
'user_id' => $admin_user->id,
'assigned_to' => e(Input::get('assigned_to'))));
$consumable->users()->attach($consumable->id, [
'consumable_id' => $consumable->id,
'user_id' => $admin_user->id,
'assigned_to' => e(Input::get('assigned_to'))
]);
$logaction = $consumable->logCheckout(e(Input::get('note')));
$settings = Setting::getSettings();
if ($settings->slack_endpoint) {
$slack_settings = [
'username' => $settings->botname,
'channel' => $settings->slack_channel,
'link_names' => true
];
$client = new \Maknz\Slack\Client($settings->slack_endpoint, $slack_settings);
try {
$client->attach([
'color' => 'good',
'fields' => [
[
'title' => 'Checked Out:',
'value' => 'Consumable <'.config('app.url').'/admin/consumables/'.$consumable->id.'/view'.'|'.$consumable->name.'> checked out to <'.config('app.url').'/admin/users/'.$user->id.'/view|'.$user->fullName().'> by <'.config('app.url').'/admin/users/'.$admin_user->id.'/view'.'|'.$admin_user->fullName().'>.'
],
[
'title' => 'Note:',
'value' => e($logaction->note)
],
]
])->send('Consumable Checked Out');
} catch (Exception $e) {
}
}
$consumable_user = DB::table('consumables_users')->where('assigned_to', '=', $consumable->assigned_to)->where('consumable_id', '=', $consumable->id)->first();
$data['log_id'] = $logaction->id;
$data['eula'] = $consumable->getEula();
$data['first_name'] = $user->first_name;
@@ -361,7 +276,6 @@ class ConsumablesController extends Controller
$data['note'] = $logaction->note;
$data['require_acceptance'] = $consumable->requireAcceptance();
if (($consumable->requireAcceptance()=='1') || ($consumable->getEula())) {
Mail::send('emails.accept-asset', $data, function ($m) use ($user) {
@@ -372,118 +286,11 @@ class ConsumablesController extends Controller
}
// Redirect to the new consumable page
return redirect()->to("admin/consumables")->with('success', trans('admin/consumables/message.checkout.success'));
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.checkout.success'));
}
/**
* Returns the JSON response containing the the consumables data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ConsumablesController::getIndex() method that returns the view that consumes the JSON.
* @since [v1.0]
* @param int $consumableId
* @return View
*/
public function getDatatable()
{
$consumables = Company::scopeCompanyables(
Consumable::select('consumables.*')
->whereNull('consumables.deleted_at')
->with('company', 'location', 'category', 'users', 'manufacturer')
);
if (Input::has('search')) {
$consumables = $consumables->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 = ['id','name','order_number','min_amt','purchase_date','purchase_cost','companyName','category','model_number', 'item_no', 'manufacturer'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
switch ($sort) {
case 'category':
$consumables = $consumables->OrderCategory($order);
break;
case 'location':
$consumables = $consumables->OrderLocation($order);
break;
case 'manufacturer':
$consumables = $consumables->OrderManufacturer($order);
break;
case 'companyName':
$consumables = $consumables->OrderCompany($order);
break;
default:
$consumables = $consumables->orderBy($sort, $order);
break;
}
$consumCount = $consumables->count();
$consumables = $consumables->skip($offset)->take($limit)->get();
$rows = array();
foreach ($consumables as $consumable) {
$actions = '<nobr>';
if (Gate::allows('consumables.checkout')) {
$actions .= '<a href="' . route('checkout/consumable',
$consumable->id) . '" style="margin-right:5px;" class="btn btn-info btn-sm" ' . (($consumable->numRemaining() > 0) ? '' : ' disabled') . '>' . trans('general.checkout') . '</a>';
}
if (Gate::allows('consumables.edit')) {
$actions .= '<a href="' . route('update/consumable',
$consumable->id) . '" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a>';
}
if (Gate::allows('consumables.delete')) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/consumable',
$consumable->id) . '" data-content="' . trans('admin/consumables/message.delete.confirm') . '" data-title="' . trans('general.delete') . ' ' . htmlspecialchars($consumable->name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
}
$actions .='</nobr>';
$company = $consumable->company;
$rows[] = array(
'id' => $consumable->id,
'name' => (string)link_to('admin/consumables/'.$consumable->id.'/view', e($consumable->name)),
'location' => ($consumable->location) ? e($consumable->location->name) : '',
'min_amt' => e($consumable->min_amt),
'qty' => e($consumable->qty),
'manufacturer' => ($consumable->manufacturer) ? (string) link_to('/admin/settings/manufacturers/'.$consumable->manufacturer_id.'/view', $consumable->manufacturer->name): '',
'model_number' => e($consumable->model_number),
'item_no' => e($consumable->item_no),
'category' => ($consumable->category) ? (string) link_to('/admin/settings/categories/'.$consumable->category_id.'/view', $consumable->category->name) : 'Missing category',
'order_number' => e($consumable->order_number),
'purchase_date' => e($consumable->purchase_date),
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
'numRemaining' => $consumable->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name),
);
}
$data = array('total' => $consumCount, 'rows' => $rows);
return $data;
}
/**
* Returns a JSON response containing details on the users associated with this consumable.
*
@@ -491,8 +298,8 @@ class ConsumablesController extends Controller
* @see ConsumablesController::getView() method that returns the form.
* @since [v1.0]
* @param int $consumableId
* @return View
*/
* @return array
*/
public function getDataView($consumableId)
{
//$consumable = Consumable::find($consumableID);
@@ -511,15 +318,15 @@ class ConsumablesController extends Controller
if (!Company::isCurrentUserHasAccess($consumable)) {
return ['total' => 0, 'rows' => []];
}
$this->authorize('view', Component::class);
$rows = array();
foreach ($consumable->consumableAssigments as $consumable_assignment) {
$rows[] = array(
'name' => (string)link_to('/admin/users/'.$consumable_assignment->user->id.'/view', e($consumable_assignment->user->fullName())),
'created_at' => ($consumable_assignment->created_at->format('Y-m-d H:i:s')=='-0001-11-30 00:00:00') ? '' : $consumable_assignment->created_at->format('Y-m-d H:i:s'),
'admin' => ($consumable_assignment->admin) ? e($consumable_assignment->admin->fullName()) : '',
);
$rows[] = [
'name' => $consumable_assignment->user->present()->nameUrl(),
'created_at' => ($consumable_assignment->created_at->format('Y-m-d H:i:s')=='-0001-11-30 00:00:00') ? '' : $consumable_assignment->created_at->format('Y-m-d H:i:s'),
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : '',
];
}
$consumableCount = $consumable->users->count();

View File

@@ -11,6 +11,7 @@ use App\Models\AssetModel;
use Lang;
use Auth;
use Illuminate\Http\Request;
use App\Helpers\Helper;
use Log;
/**
@@ -35,77 +36,15 @@ class CustomFieldsController extends Controller
*/
public function index()
{
//
$fieldsets=CustomFieldset::with("fields", "models")->get();
//$fieldsets=CustomFieldset::all();
$fields=CustomField::with("fieldset")->get();
//$fields=CustomField::all();
$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);
}
/**
* Returns a view with a form for creating a new custom fieldset.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return View
*/
public function create()
{
//
return View::make("custom_fields.create");
}
/**
* Validates and stores a new custom fieldset.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return Redirect
*/
public function store(Request $request)
{
//
$cfset = new CustomFieldset(
[
"name" => e($request->get("name")),
"user_id" => Auth::user()->id]
);
$validator=Validator::make(Input::all(), $cfset->rules);
if ($validator->passes()) {
$cfset->save();
return redirect()->route("admin.custom_fields.show", [$cfset->id])->with('success', trans('admin/custom_fields/message.fieldset.create.success'));
} else {
return redirect()->back()->withInput()->withErrors($validator);
}
}
/**
* Associate the custom field with a custom fieldset.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return View
*/
public function associate($id)
{
$set = CustomFieldset::find($id);
foreach ($set->fields as $field) {
if ($field->id == Input::get('field_id')) {
return redirect()->route("admin.custom_fields.show", [$id])->withInput()->withErrors(['field_id' => trans('admin/custom_fields/message.field.already_added')]);
}
}
$results=$set->fields()->attach(Input::get('field_id'), ["required" => (Input::get('required') == "on"),"order" => Input::get('order')]);
return redirect()->route("admin.custom_fields.show", [$id])->with("success", trans('admin/custom_fields/message.field.create.assoc_success'));
}
/**
* Returns a view with a form to create a new custom field.
@@ -115,9 +54,10 @@ class CustomFieldsController extends Controller
* @since [v1.8]
* @return View
*/
public function createField()
public function create()
{
return View::make("custom_fields.create_field");
return View::make("custom_fields.fields.edit")->with('field', new CustomField());
}
@@ -129,13 +69,14 @@ class CustomFieldsController extends Controller
* @since [v1.8]
* @return Redirect
*/
public function storeField(Request $request)
public function store(Request $request)
{
$field = new CustomField([
"name" => e($request->get("name")),
"element" => e($request->get("element")),
"field_values" => e($request->get("field_values")),
"field_encrypted" => e($request->get("field_encrypted", 0)),
"name" => $request->get("name"),
"element" => $request->get("element"),
"help_text" => $request->get("help_text"),
"field_values" => $request->get("field_values"),
"field_encrypted" => $request->get("field_encrypted", 0),
"user_id" => Auth::user()->id
]);
@@ -148,12 +89,12 @@ class CustomFieldsController extends Controller
}
$validator = Validator::make(Input::all(), $field->rules);
$validator=Validator::make(Input::all(), $field->rules);
if ($validator->passes()) {
$results = $field->save();
if ($results) {
return redirect()->route("admin.custom_fields.index")->with("success", trans('admin/custom_fields/message.field.create.success'));
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.create.success'));
} else {
dd($field);
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.create.error'));
@@ -176,7 +117,7 @@ class CustomFieldsController extends Controller
$field = CustomField::find($field_id);
if ($field->fieldset()->detach($fieldset_id)) {
return redirect()->route("admin.custom_fields.index")->with("success", trans('admin/custom_fields/message.field.delete.success'));
return redirect()->route('fieldsets.show', ['fieldset' => $fieldset_id])->with("success", trans('admin/custom_fields/message.field.delete.success'));
}
return redirect()->back()->withErrors(['message' => "Field is in-use"]);
@@ -189,7 +130,7 @@ class CustomFieldsController extends Controller
* @since [v1.8]
* @return Redirect
*/
public function deleteField($field_id)
public function destroy($field_id)
{
$field = CustomField::find($field_id);
@@ -197,115 +138,63 @@ class CustomFieldsController extends Controller
return redirect()->back()->withErrors(['message' => "Field is in-use"]);
} else {
$field->delete();
return redirect()->route("admin.custom_fields.index")->with("success", trans('admin/custom_fields/message.field.delete.success'));
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.delete.success'));
}
}
/**
* Validates and stores a new custom field.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v1.8]
* @return View
*/
public function show($id)
{
$cfset = CustomFieldset::with('fields')->where('id','=',$id)->orderBy('id','ASC')->first();
$custom_fields_list = ["" => "Add New Field to Fieldset"] + CustomField::lists("name", "id")->toArray();
$maxid = 0;
foreach ($cfset->fields() as $field) {
if ($field->pivot->order > $maxid) {
$maxid=$field->pivot->order;
}
if (isset($custom_fields_list[$field->id])) {
unset($custom_fields_list[$field->id]);
}
}
return View::make("custom_fields.show")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
}
/**
* What the actual fuck, Brady?
* Return a view to edit a custom field
*
* @todo Uhh, build this?
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @since [v1.8]
* @return Fuckall
* @since [v4.0]
* @return View
*/
public function edit($id)
{
//
$field = CustomField::find($id);
return View::make("custom_fields.fields.edit")->with('field', $field);
}
/**
* GET IN THE SEA BRADY.
* Store the updated field
*
* @todo Uhh, build this too?
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v1.8]
* @return Fuckall
*/
public function update($id)
{
//
}
/**
* Validates a custom fieldset and then deletes if it has no models associated.
* @todo Allow encrypting/decrypting if encryption status changes
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @since [v1.8]
* @return View
* @since [v4.0]
* @return Redirect
*/
public function destroy($id)
public function update(Request $request, $id)
{
//
$fieldset = CustomFieldset::find($id);
$field = CustomField::find($id);
$models = AssetModel::where("fieldset_id", "=", $id);
if ($models->count() == 0) {
$fieldset->delete();
return redirect()->route("admin.custom_fields.index")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
$field->name = e($request->get("name"));
$field->element = e($request->get("element"));
$field->field_values = e($request->get("field_values"));
$field->field_encrypted = e($request->get("field_encrypted", 0));
$field->user_id = Auth::user()->id;
$field->help_text = $request->get("help_text");
if (!in_array(Input::get('format'), array_keys(CustomField::$PredefinedFormats))) {
$field->format = e($request->get("custom_format"));
} else {
return redirect()->route("admin.custom_fields.index")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
$field->format = e($request->get("format"));
}
$validator = Validator::make(Input::all(), $field->rules);
if ($field->save()) {
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.field.update.success'));
}
return redirect()->back()->withInput()->withErrors($validator);
}
/**
* Reorder the custom fields within a fieldset
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v3.0]
* @return Array
*/
public function postReorder(Request $request, $id)
{
$fieldset = CustomFieldset::find($id);
$fields = array();
$order_array = array();
$items = $request->input('item');
foreach ($items as $order => $field_id) {
$order_array[$field_id] = $order;
}
foreach ($fieldset->fields as $field) {
$fields[$field->id] = ['required' => $field->pivot->required, 'order' => $order_array[$field->id]];
}
return $fieldset->fields()->sync($fields);
}
}

View File

@@ -0,0 +1,171 @@
<?php
namespace App\Http\Controllers;
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;
/**
* This controller handles all actions related to Custom Asset Fields 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>]
*/
class CustomFieldsetsController extends Controller
{
/**
* Validates and stores a new custom field.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v1.8]
* @return View
*/
public function show($id)
{
$cfset = CustomFieldset::with('fields')->where('id', '=', $id)->orderBy('id', 'ASC')->first();
$custom_fields_list = ["" => "Add New Field to Fieldset"] + CustomField::pluck("name", "id")->toArray();
$maxid = 0;
foreach ($cfset->fields() as $field) {
if ($field->pivot->order > $maxid) {
$maxid=$field->pivot->order;
}
if (isset($custom_fields_list[$field->id])) {
unset($custom_fields_list[$field->id]);
}
}
return View::make("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
}
/**
* Returns a view with a form for creating a new custom fieldset.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return View
*/
public function create()
{
return View::make("custom_fields.fieldsets.edit");
}
/**
* Validates and stores a new custom fieldset.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return Redirect
*/
public function store(Request $request)
{
$cfset = new CustomFieldset(
[
"name" => e($request->get("name")),
"user_id" => Auth::user()->id]
);
$validator = Validator::make(Input::all(), $cfset->rules);
if ($validator->passes()) {
$cfset->save();
return redirect()->route("fieldsets.show", [$cfset->id])->with('success', trans('admin/custom_fields/message.fieldset.create.success'));
} else {
return redirect()->back()->withInput()->withErrors($validator);
}
}
/**
* What the actual fuck, Brady?
*
* @todo Uhh, build this?
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v1.8]
* @return Fuckall
*/
public function edit($id)
{
//
}
/**
* GET IN THE SEA BRADY.
*
* @todo Uhh, build this too?
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v1.8]
* @return Fuckall
*/
public function update($id)
{
//
}
/**
* Validates a custom fieldset and then deletes if it has no models associated.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @param int $id
* @since [v1.8]
* @return View
*/
public function destroy($id)
{
//
$fieldset = CustomFieldset::find($id);
$models = AssetModel::where("fieldset_id", "=", $id);
if ($models->count() == 0) {
$fieldset->delete();
return redirect()->route("fields.show")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
} else {
return redirect()->route("fields.show")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
}
}
/**
* Associate the custom field with a custom fieldset.
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return View
*/
public function associate($id)
{
$set = CustomFieldset::find($id);
foreach ($set->fields as $field) {
if ($field->id == Input::get('field_id')) {
return redirect()->route("fieldsets.show", [$id])->withInput()->withErrors(['field_id' => trans('admin/custom_fields/message.field.already_added')]);
}
}
$results=$set->fields()->attach(Input::get('field_id'), ["required" => (Input::get('required') == "on"),"order" => Input::get('order')]);
return redirect()->route("fieldsets.show", [$id])->with("success", trans('admin/custom_fields/message.field.create.assoc_success'));
}
}

View File

@@ -1,7 +1,7 @@
<?php
namespace App\Http\Controllers;
use Input;
use App\Helpers\Helper;
use Lang;
use App\Models\Depreciation;
use Redirect;
@@ -10,6 +10,7 @@ use DB;
use Str;
use View;
use Auth;
use Illuminate\Http\Request;
/**
* This controller handles all actions related to Depreciations for
@@ -26,9 +27,9 @@ class DepreciationsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net]
* @see DepreciationsController::getDatatable() method that generates the JSON response
* @since [v1.0]
* @return View
*/
public function getIndex()
* @return \Illuminate\Contracts\View\View
*/
public function index()
{
// Show the page
return View::make('depreciations/index', compact('depreciations'));
@@ -41,9 +42,9 @@ class DepreciationsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net]
* @see DepreciationsController::postCreate()
* @since [v1.0]
* @return View
*/
public function getCreate()
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
// Show the page
return View::make('depreciations/edit')->with('item', new Depreciation);
@@ -51,35 +52,29 @@ class DepreciationsController extends Controller
/**
* Validates and stores the new depreciation data.
*
* @author [A. Gianotto] [<snipe@snipe.net]
* @see DepreciationsController::postCreate()
* @since [v1.0]
* @return Redirect
*/
public function postCreate()
* Validates and stores the new depreciation data.
*
* @author [A. Gianotto] [<snipe@snipe.net]
* @see DepreciationsController::postCreate()
* @since [v1.0]
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request)
{
// get the POST data
$new = Input::all();
// create a new instance
// create a new instance
$depreciation = new Depreciation();
// Depreciation data
$depreciation->name = $request->input('name');
$depreciation->months = $request->input('months');
$depreciation->user_id = Auth::id();
// Depreciation data
$depreciation->name = e(Input::get('name'));
$depreciation->months = e(Input::get('months'));
$depreciation->user_id = Auth::user()->id;
// Was the asset created?
// Was the asset created?
if ($depreciation->save()) {
// Redirect to the new depreciation page
return redirect()->to("admin/settings/depreciations")->with('success', trans('admin/depreciations/message.create.success'));
return redirect()->route('depreciations.index')->with('success', trans('admin/depreciations/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($depreciation->getErrors());
}
/**
@@ -89,14 +84,14 @@ class DepreciationsController extends Controller
* @see DepreciationsController::postEdit()
* @param int $depreciationId
* @since [v1.0]
* @return View
*/
public function getEdit($depreciationId = null)
* @return \Illuminate\Contracts\View\View
*/
public function edit($depreciationId = null)
{
// Check if the depreciation exists
if (is_null($item = Depreciation::find($depreciationId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/depreciations')->with('error', trans('admin/depreciations/message.does_not_exist'));
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.does_not_exist'));
}
return View::make('depreciations/edit', compact('item'));
@@ -104,123 +99,61 @@ class DepreciationsController extends Controller
/**
* Validates and stores the updated depreciation data.
*
* @author [A. Gianotto] [<snipe@snipe.net]
* @see DepreciationsController::getEdit()
* @param int $depreciationId
* @since [v1.0]
* @return Redirect
*/
public function postEdit($depreciationId = null)
* Validates and stores the updated depreciation data.
*
* @author [A. Gianotto] [<snipe@snipe.net]
* @see DepreciationsController::getEdit()
* @param Request $request
* @param int $depreciationId
* @return \Illuminate\Http\RedirectResponse
* @since [v1.0]
*/
public function update(Request $request, $depreciationId = null)
{
// Check if the depreciation exists
if (is_null($depreciation = Depreciation::find($depreciationId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/depreciations')->with('error', trans('admin/depreciations/message.does_not_exist'));
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.does_not_exist'));
}
// Depreciation data
$depreciation->name = e(Input::get('name'));
$depreciation->months = e(Input::get('months'));
$depreciation->name = $request->input('name');
$depreciation->months = $request->input('months');
// Was the asset created?
if ($depreciation->save()) {
// Redirect to the depreciation page
return redirect()->to("admin/settings/depreciations/")->with('success', trans('admin/depreciations/message.update.success'));
return redirect()->route("depreciations.index")->with('success', trans('admin/depreciations/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($depreciation->getErrors());
}
/**
* Validates and deletes a selected depreciation.
*
* This is a hard-delete. We do not currently soft-delete depreciations.
*
* @author [A. Gianotto] [<snipe@snipe.net]
* @since [v1.0]
* @return Redirect
*/
public function getDelete($depreciationId)
* Validates and deletes a selected depreciation.
*
* This is a hard-delete. We do not currently soft-delete depreciations.
*
* @author [A. Gianotto] [<snipe@snipe.net]
* @since [v1.0]
* @param integer $depreciationId
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($depreciationId)
{
// Check if the depreciation exists
if (is_null($depreciation = Depreciation::find($depreciationId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/depreciations')->with('error', trans('admin/depreciations/message.not_found'));
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.not_found'));
}
if ($depreciation->has_models() > 0) {
// Redirect to the asset management page
return redirect()->to('admin/settings/depreciations')->with('error', trans('admin/depreciations/message.assoc_users'));
} else {
$depreciation->delete();
// Redirect to the depreciations management page
return redirect()->to('admin/settings/depreciations')->with('success', trans('admin/depreciations/message.delete.success'));
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.assoc_users'));
}
$depreciation->delete();
// Redirect to the depreciations management page
return redirect()->route('depreciations.index')->with('success', trans('admin/depreciations/message.delete.success'));
}
/**
* Generates the JSON used to display the depreciation listing.
*
* @see DepreciationsController::getIndex()
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param string $status
* @since [v1.2]
* @return String JSON
*/
public function getDatatable()
{
$depreciations = Depreciation::select(array('id','name','months'));
if (Input::has('search')) {
$depreciations = $depreciations->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 = ['id','name','months'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$depreciations->orderBy($sort, $order);
$depreciationsCount = $depreciations->count();
$depreciations = $depreciations->skip($offset)->take($limit)->get();
$rows = array();
foreach ($depreciations as $depreciation) {
$actions = '<a href="'.route('update/depreciations', $depreciation->id).'" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a><a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/depreciations', $depreciation->id).'" data-content="'.trans('admin/depreciations/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($depreciation->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
$rows[] = array(
'id' => $depreciation->id,
'name' => e($depreciation->name),
'months' => e($depreciation->months),
'actions' => $actions
);
}
$data = array('total' => $depreciationsCount, 'rows' => $rows);
return $data;
}
}

View File

@@ -26,8 +26,8 @@ class GroupsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net]
* @see GroupsController::getDatatable() method that generates the JSON response
* @since [v1.0]
* @return View
*/
* @return \Illuminate\Contracts\View\View
*/
public function getIndex()
{
// Show the page
@@ -40,8 +40,8 @@ class GroupsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net]
* @see GroupsController::postCreate()
* @since [v1.0]
* @return View
*/
* @return \Illuminate\Contracts\View\View
*/
public function getCreate()
{
$group = new Group;
@@ -60,8 +60,8 @@ class GroupsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net]
* @see GroupsController::getCreate()
* @since [v1.0]
* @return Redirect
*/
* @return \Illuminate\Http\RedirectResponse
*/
public function postCreate()
{
// create a new group instance
@@ -70,12 +70,9 @@ class GroupsController extends Controller
$group->permissions = json_encode(Input::get('permission'));
if ($group->save()) {
return redirect()->to("admin/groups")->with('success', trans('admin/groups/message.success.create'));
return redirect()->route("groups.index")->with('success', trans('admin/groups/message.success.create'));
}
return redirect()->back()->withInput()->withErrors($group->getErrors());
return redirect(route('groups.create'))->withInput()->withErrors($group->getErrors());
}
/**
@@ -85,8 +82,8 @@ class GroupsController extends Controller
* @see GroupsController::postEdit()
* @param int $id
* @since [v1.0]
* @return View
*/
* @return \Illuminate\Contracts\View\View
*/
public function getEdit($id = null)
{
$group = Group::find($id);
@@ -103,30 +100,24 @@ class GroupsController extends Controller
* @see GroupsController::getEdit()
* @param int $id
* @since [v1.0]
* @return Redirect
*/
* @return \Illuminate\Http\RedirectResponse
*/
public function postEdit($id = null)
{
$permissions = config('permissions');
if (!$group = Group::find($id)) {
return redirect()->route('groups')->with('error', trans('admin/groups/message.group_not_found', compact('id')));
}
$group->name = e(Input::get('name'));
$group->permissions = json_encode(Input::get('permission'));
if (!config('app.lock_passwords')) {
if ($group->save()) {
return redirect()->to("admin/groups")->with('success', trans('admin/groups/message.success.update'));
}
return redirect()->back()->withInput()->withErrors($group->getErrors());
} else {
return redirect()->route('update/group', $id)->withInput()->with('error', 'Denied! Editing groups is not allowed in the demo.');
}
return redirect()->route('groups')->with('error', trans('general.feature_disabled'));
}
/**
@@ -136,103 +127,19 @@ class GroupsController extends Controller
* @see GroupsController::getEdit()
* @param int $id
* @since [v1.0]
* @return Redirect
*/
* @return \Illuminate\Http\RedirectResponse
*/
public function getDelete($id = null)
{
if (!config('app.lock_passwords')) {
try {
// Get group information
$group = Group::find($id);
$group->delete();
// Redirect to the group management page
return redirect()->route('groups')->with('success', trans('admin/groups/message.success.delete'));
} catch (GroupNotFoundException $e) {
// Redirect to the group management page
if (!$group = Group::find($id)) {
return redirect()->route('groups')->with('error', trans('admin/groups/message.group_not_found', compact('id')));
}
} else {
return redirect()->route('groups')->with('error', trans('general.feature_disabled'));
$group->delete();
// Redirect to the group management page
return redirect()->route('groups')->with('success', trans('admin/groups/message.success.delete'));
}
return redirect()->route('groups')->with('error', trans('general.feature_disabled'));
}
/**
* Generates the JSON used to display the User Group listing.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v2.0]
* @return String JSON
*/
public function getDatatable()
{
if (Input::has('offset')) {
$offset = e(Input::get('offset'));
} else {
$offset = 0;
}
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
} else {
$limit = 50;
}
if (Input::get('sort')=='name') {
$sort = 'first_name';
} else {
$sort = e(Input::get('sort'));
}
// Grab all the groups
$groups = Group::with('users')->orderBy('name', 'ASC');
//$users = Company::scopeCompanyables($users);
if (Input::has('search')) {
$groups = $users->TextSearch(e(Input::get('search')));
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$allowed_columns =
[
'name','created_at'
];
$sort = in_array($sort, $allowed_columns) ? $sort : 'name';
$groups = $groups->orderBy($sort, $order);
$groupsCount = $groups->count();
$groups = $groups->skip($offset)->take($limit)->get();
$rows = array();
foreach ($groups as $group) {
$group_names = '';
$inout = '';
$actions = '<nobr>';
$actions .= '<a href="' . route('update/group', $group->id) . '" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> ';
if (!config('app.lock_passwords')) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/group', $group->id) . '" data-content="'.trans('admin/groups/message.delete.confirm').'" data-title="Delete ' . htmlspecialchars($group->name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a> ';
} else {
$actions .= ' <span class="btn delete-asset btn-danger btn-sm disabled"><i class="fa fa-trash icon-white"></i></span>';
}
$actions .= '</nobr>';
$rows[] = array(
'id' => $group->id,
'name' => $group->name,
'users' => $group->users->count(),
'created_at' => $group->created_at->format('Y-m-d'),
'actions' => ($actions) ? $actions : '',
);
}
$data = array('total'=>$groupsCount, 'rows'=>$rows);
return $data;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
<?php
namespace App\Http\Controllers;
use App\Helpers\Helper;
use Input;
use Lang;
use App\Models\Location;
use phpDocumentor\Reflection\Types\Array_;
use Redirect;
use App\Models\Setting;
use App\Models\User;
@@ -31,9 +33,9 @@ class LocationsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LocationsController::getDatatable() method that generates the JSON response
* @since [v1.0]
* @return View
*/
public function getIndex()
* @return \Illuminate\Contracts\View\View
*/
public function index()
{
// Grab all the locations
$locations = Location::orderBy('created_at', 'DESC')->with('parent', 'assets', 'assignedassets')->get();
@@ -49,9 +51,9 @@ class LocationsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LocationsController::postCreate() method that validates and stores the data
* @since [v1.0]
* @return View
*/
public function getCreate()
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
$locations = Location::orderBy('name', 'ASC')->get();
@@ -60,8 +62,8 @@ class LocationsController extends Controller
$location_options = array('' => 'Top Level') + $location_options;
return View::make('locations/edit')
->with('location_options', $location_options)
->with('item', new Location);
->with('location_options', $location_options)
->with('item', new Location);
}
@@ -72,38 +74,26 @@ class LocationsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LocationsController::getCreate() method that makes the form
* @since [v1.0]
* @return Redirect
*/
public function postCreate()
* @return \Illuminate\Http\RedirectResponse
*/
public function store()
{
// create a new location instance
$location = new Location();
// Save the location data
$location->name = e(Input::get('name'));
if (Input::get('parent_id')=='') {
$location->parent_id = null;
} else {
$location->parent_id = e(Input::get('parent_id'));
}
$location->currency = e(Input::get('currency', '$'));
$location->address = e(Input::get('address'));
$location->address2 = e(Input::get('address2'));
$location->city = e(Input::get('city'));
$location->state = e(Input::get('state'));
$location->country = e(Input::get('country'));
$location->zip = e(Input::get('zip'));
$location->user_id = Auth::user()->id;
$location->name = Input::get('name');
$location->parent_id = Input::get('parent_id', null);
$location->currency = Input::get('currency', '$');
$location->address = Input::get('address');
$location->address2 = Input::get('address2');
$location->city = Input::get('city');
$location->state = Input::get('state');
$location->country = Input::get('country');
$location->zip = Input::get('zip');
$location->user_id = Auth::id();
if ($location->save()) {
// Redirect to the new location page
return redirect()->to("admin/settings/locations")->with('success', trans('admin/locations/message.create.success'));
return redirect()->route("locations.index")->with('success', trans('admin/locations/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($location->getErrors());
}
/**
@@ -115,35 +105,30 @@ class LocationsController extends Controller
* @since [v1.0]
* @return String JSON
*/
public function store()
public function apiStore()
{
$new['currency']=Setting::first()->default_currency;
// create a new location instance
$location = new Location();
// Save the location data
$location->name = e(Input::get('name'));
$location->name = Input::get('name');
$location->currency = Setting::first()->default_currency; //e(Input::get('currency'));
$location->address = ''; //e(Input::get('address'));
// $location->address2 = e(Input::get('address2'));
$location->city = e(Input::get('city'));
$location->city = Input::get('city');
$location->state = '';//e(Input::get('state'));
$location->country = e(Input::get('country'));
$location->country = Input::get('country');
// $location->zip = e(Input::get('zip'));
$location->user_id = Auth::user()->id;
$location->user_id = Auth::id();
// Was the location created?
if ($location->save()) {
return JsonResponse::create($location);
}
// failure
$errors = $location->errors();
return JsonResponse::create(["error" => "Failed validation: ".print_r($location->getErrors(), true)], 500);
}
@@ -154,9 +139,9 @@ class LocationsController extends Controller
* @see LocationsController::postCreate() method that validates and stores
* @param int $locationId
* @since [v1.0]
* @return View
*/
public function getEdit($locationId = null)
* @return \Illuminate\Contracts\View\View
*/
public function edit($locationId = null)
{
// Check if the location exists
if (is_null($item = Location::find($locationId))) {
@@ -180,40 +165,34 @@ class LocationsController extends Controller
* @see LocationsController::getEdit() method that makes the form view
* @param int $locationId
* @since [v1.0]
* @return Redirect
*/
public function postEdit($locationId = null)
* @return \Illuminate\Http\RedirectResponse
*/
public function update($locationId = null)
{
// Check if the location exists
if (is_null($location = Location::find($locationId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.does_not_exist'));
}
// Update the location data
$location->name = e(Input::get('name'));
if (Input::get('parent_id')=='') {
$location->parent_id = null;
} else {
$location->parent_id = e(Input::get('parent_id', ''));
}
$location->currency = e(Input::get('currency', '$'));
$location->address = e(Input::get('address'));
$location->address2 = e(Input::get('address2'));
$location->city = e(Input::get('city'));
$location->state = e(Input::get('state'));
$location->country = e(Input::get('country'));
$location->zip = e(Input::get('zip'));
$location->name = Input::get('name');
$location->parent_id = Input::get('parent_id', null);
$location->currency = Input::get('currency', '$');
$location->address = Input::get('address');
$location->address2 = Input::get('address2');
$location->city = Input::get('city');
$location->state = Input::get('state');
$location->country = Input::get('country');
$location->zip = Input::get('zip');
$location->ldap_ou = Input::get('ldap_ou');
// Was the asset created?
// Was the location updated?
if ($location->save()) {
// Redirect to the saved location page
return redirect()->to("admin/settings/locations/")->with('success', trans('admin/locations/message.update.success'));
return redirect()->route("locations.index")->with('success', trans('admin/locations/message.update.success'));
}
// Redirect to the location management page
return redirect()->back()->withInput()->withInput()->withErrors($location->getErrors());
}
/**
@@ -222,32 +201,29 @@ class LocationsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $locationId
* @since [v1.0]
* @return Redirect
*/
public function getDelete($locationId)
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($locationId)
{
// Check if the location exists
if (is_null($location = Location::find($locationId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.not_found'));
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.not_found'));
}
if ($location->users->count() > 0) {
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.assoc_users'));
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_users'));
} elseif ($location->childLocations->count() > 0) {
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.assoc_child_loc'));
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_child_loc'));
} elseif ($location->assets->count() > 0) {
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.assoc_assets'));
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
} elseif ($location->assignedassets->count() > 0) {
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.assoc_assets'));
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
} else {
$location->delete();
return redirect()->to('admin/settings/locations')->with('success', trans('admin/locations/message.delete.success'));
return redirect()->to(route('locations.index'))->with('success', trans('admin/locations/message.delete.success'));
}
}
@@ -260,114 +236,34 @@ class LocationsController extends Controller
* @see LocationsController::getDataViewAssets() method that returns JSON for location assets
* @param int $locationId
* @since [v1.0]
* @return View
*/
public function getView($locationId = null)
* @return \Illuminate\Contracts\View\View
*/
public function show($locationId = null)
{
$location = Location::find($locationId);
if (isset($location->id)) {
return View::make('locations/view', compact('location'));
} else {
// Prepare the error message
$error = trans('admin/locations/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('locations')->with('error', $error);
return View::make('locations/view', compact('location'));
}
// Prepare the error message
$error = trans('admin/locations/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('locations.index')->with('error', $error);
}
/**
* Returns the JSON response to populate the bootstrap tables on the locationa view.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LocationsController::getIndex() method that returns JSON for location index
* @since [v1.0]
* @return View
*/
public function getDatatable()
{
$locations = Location::select(array('locations.id','locations.name','locations.address','locations.address2','locations.city','locations.state','locations.zip','locations.country','locations.parent_id','locations.currency'))->with('assets');
if (Input::has('search')) {
$locations = $locations->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;
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
switch (Input::get('sort')) {
case 'parent':
$locations = $locations->OrderParent($order);
break;
default:
$allowed_columns = ['id','name','address','city','state','country','currency','zip'];
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$locations = $locations->orderBy($sort, $order);
break;
}
$locationsCount = $locations->count();
$locations = $locations->skip($offset)->take($limit)->get();
$rows = array();
foreach ($locations as $location) {
$actions = '<nobr><a href="'.route('update/location', $location->id).'" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a><a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/location', $location->id).'" data-content="'.trans('admin/locations/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($location->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></nobr>';
$rows[] = array(
'id' => $location->id,
'name' => (string)link_to('admin/settings/locations/'.$location->id.'/view', e($location->name)),
'parent' => ($location->parent) ? e($location->parent->name) : '',
// 'assets' => ($location->assets->count() + $location->assignedassets->count()),
'assets_default' => $location->assignedassets->count(),
'assets_checkedout' => $location->assets->count(),
'address' => ($location->address) ? e($location->address): '',
'city' => e($location->city),
'state' => e($location->state),
'zip' => e($location->zip),
'country' => e($location->country),
'currency' => e($location->currency),
'actions' => $actions
);
}
$data = array('total' => $locationsCount, 'rows' => $rows);
return $data;
}
/**
* Returns a JSON response that contains the users association with the
* selected location, to be used by the location detail view.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LocationsController::getView() method that creates the display view
* @param int $locationId
* @since [v1.8]
* @return View
*/
* Returns a JSON response that contains the users association with the
* selected location, to be used by the location detail view.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LocationsController::getView() method that creates the display view
* @param $locationID
* @return array
* @internal param int $locationId
* @since [v1.8]
*/
public function getDataViewUsers($locationID)
{
$location = Location::find($locationID);
@@ -382,7 +278,7 @@ class LocationsController extends Controller
foreach ($users as $user) {
$rows[] = array(
'name' => (string)link_to('/admin/users/'.$user->id.'/view', e($user->fullName()))
'name' => (string)link_to_route('users.show', e($user->present()->fullName()), ['user'=>$user->id])
);
}
@@ -402,8 +298,8 @@ class LocationsController extends Controller
* @see LocationsController::getView() method that creates the display view
* @param int $locationID
* @since [v1.8]
* @return View
*/
* @return array
*/
public function getDataViewAssets($locationID)
{
$location = Location::find($locationID)->load('assignedassets.model');
@@ -418,12 +314,12 @@ class LocationsController extends Controller
$rows = array();
foreach ($assets as $asset) {
$rows[] = array(
'name' => (string)link_to(config('app.url').'/hardware/'.$asset->id.'/view', e($asset->showAssetName())),
'asset_tag' => e($asset->asset_tag),
'serial' => e($asset->serial),
'model' => e($asset->model->name),
);
$rows[] = [
'name' => (string)link_to_route('hardware.show', e($asset->present()->name()), ['hardware' => $asset->id]),
'asset_tag' => e($asset->asset_tag),
'serial' => e($asset->serial),
'model' => e($asset->model->name),
];
}
$data = array('total' => $assets->count(), 'rows' => $rows);

View File

@@ -1,16 +1,18 @@
<?php
namespace App\Http\Controllers;
use App\Models\Company;
use App\Helpers\Helper;
use App\Models\CustomField;
use App\Models\Manufacturer;
use App\Models\Setting;
use Auth;
use Exception;
use Gate;
use Input;
use Lang;
use Redirect;
use Str;
use View;
use Illuminate\Http\Request;
/**
* This controller handles all actions related to Manufacturers for
@@ -25,13 +27,12 @@ class ManufacturersController extends Controller
* the content for the manufacturers listing, which is generated in getDatatable.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::getDatatable() method that generates the JSON response
* @see Api\ManufacturersController::index() method that generates the JSON response
* @since [v1.0]
* @return View
*/
public function getIndex()
* @return \Illuminate\Contracts\View\View
*/
public function index()
{
// Show the page
return View::make('manufacturers/index', compact('manufacturers'));
}
@@ -40,89 +41,93 @@ class ManufacturersController extends Controller
* Returns a view that displays a form to create a new manufacturer.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::postCreate()
* @see ManufacturersController::store()
* @since [v1.0]
* @return View
*/
public function getCreate()
* @return \Illuminate\Contracts\View\View
*/
public function create()
{
return View::make('manufacturers/edit')->with('item', new Manufacturer);
}
/**
* Validates and stores the data for a new manufacturer.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::postCreate()
* @since [v1.0]
* @return Redirect
*/
public function postCreate()
* Validates and stores the data for a new manufacturer.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::create()
* @since [v1.0]
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function store(Request $request)
{
$manufacturer = new Manufacturer;
$manufacturer->name = e(Input::get('name'));
$manufacturer->name = $request->input('name');
$manufacturer->user_id = Auth::user()->id;
$manufacturer->url = $request->input('url');
$manufacturer->support_url = $request->input('support_url');
$manufacturer->support_phone = $request->input('support_phone');
$manufacturer->support_email = $request->input('support_email');
if ($manufacturer->save()) {
return redirect()->to("admin/settings/manufacturers")->with('success', trans('admin/manufacturers/message.create.success'));
return redirect()->route('manufacturers.index')->with('success', trans('admin/manufacturers/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($manufacturer->getErrors());
}
/**
* Returns a view that displays a form to edit a manufacturer.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::postEdit()
* @see ManufacturersController::update()
* @param int $manufacturerId
* @since [v1.0]
* @return View
*/
public function getEdit($manufacturerId = null)
* @return \Illuminate\Contracts\View\View
*/
public function edit($id = null)
{
// Check if the manufacturer exists
if (is_null($item = Manufacturer::find($manufacturerId))) {
// Redirect to the manufacturer page
return redirect()->to('admin/settings/manufacturers')->with('error', trans('admin/manufacturers/message.does_not_exist'));
if (is_null($item = Manufacturer::find($id))) {
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
}
// Show the page
return View::make('manufacturers/edit', compact('item'));
}
/**
* Validates and stores the updated manufacturer data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::getEdit()
* @param int $manufacturerId
* @since [v1.0]
* @return View
*/
public function postEdit($manufacturerId = null)
* Validates and stores the updated manufacturer data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::getEdit()
* @param Request $request
* @param int $manufacturerId
* @return \Illuminate\Http\RedirectResponse
* @since [v1.0]
*/
public function update(Request $request, $manufacturerId = null)
{
// Check if the manufacturer exists
if (is_null($manufacturer = Manufacturer::find($manufacturerId))) {
// Redirect to the manufacturer page
return redirect()->to('admin/settings/manufacturers')->with('error', trans('admin/manufacturers/message.does_not_exist'));
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
}
// Save the data
$manufacturer->name = e(Input::get('name'));
$manufacturer->name = $request->input('name');
$manufacturer->url = $request->input('url');
$manufacturer->support_url = $request->input('support_url');
$manufacturer->support_phone = $request->input('support_phone');
$manufacturer->support_email = $request->input('support_email');
// Was it created?
if ($manufacturer->save()) {
// Redirect to the new manufacturer page
return redirect()->to("admin/settings/manufacturers")->with('success', trans('admin/manufacturers/message.update.success'));
return redirect()->route('manufacturers.index')->with('success', trans('admin/manufacturers/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($manufacturer->getErrors());
}
/**
@@ -131,33 +136,26 @@ class ManufacturersController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $manufacturerId
* @since [v1.0]
* @return View
*/
public function getDelete($manufacturerId)
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy($manufacturerId)
{
// Check if the manufacturer exists
if (is_null($manufacturer = Manufacturer::find($manufacturerId))) {
// Redirect to the manufacturers page
return redirect()->to('admin/settings/manufacturers')->with('error', trans('admin/manufacturers/message.not_found'));
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.not_found'));
}
if ($manufacturer->has_models() > 0) {
// Redirect to the asset management page
return redirect()->to('admin/settings/manufacturers')->with('error', trans('admin/manufacturers/message.assoc_users'));
} else {
// Delete the manufacturer
$manufacturer->delete();
// Redirect to the manufacturers management page
return redirect()->to('admin/settings/manufacturers')->with('success', trans('admin/manufacturers/message.delete.success'));
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.assoc_users'));
}
// Delete the manufacturer
$manufacturer->delete();
// Redirect to the manufacturers management page
return redirect()->route('manufacturers.index')->with('success', trans('admin/manufacturers/message.delete.success'));
}
/**
* Returns a view that invokes the ajax tables which actually contains
* the content for the manufacturers detail listing, which is generated in getDatatable.
@@ -167,189 +165,88 @@ class ManufacturersController extends Controller
* @see ManufacturersController::getDataView()
* @param int $manufacturerId
* @since [v1.0]
* @return View
*/
public function getView($manufacturerId = null)
* @return \Illuminate\Contracts\View\View
*/
public function show($manufacturerId = null)
{
$manufacturer = Manufacturer::find($manufacturerId);
if (isset($manufacturer->id)) {
return View::make('manufacturers/view', compact('manufacturer'));
} else {
// Prepare the error message
$error = trans('admin/manufacturers/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('manufacturers')->with('error', $error);
return View::make('manufacturers/view', compact('manufacturer'));
}
// Prepare the error message
$error = trans('admin/manufacturers/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('manufacturers')->with('error', $error);
}
/**
* Generates the JSON used to display the manufacturer listings.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::getIndex()
* @since [v1.0]
* @return String JSON
*/
public function getDatatable()
{
$manufacturers = Manufacturer::select(array('id','name'))->with('assets')
->whereNull('deleted_at');
if (Input::has('search')) {
$manufacturers = $manufacturers->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 = ['id','name'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$manufacturers->orderBy($sort, $order);
$manufacturersCount = $manufacturers->count();
$manufacturers = $manufacturers->skip($offset)->take($limit)->get();
$rows = array();
foreach ($manufacturers as $manufacturer) {
$actions = '<a href="'.route('update/manufacturer', $manufacturer->id).'" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a><a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/manufacturer', $manufacturer->id).'" data-content="'.trans('admin/manufacturers/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($manufacturer->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
$rows[] = array(
'id' => $manufacturer->id,
'name' => (string)link_to('admin/settings/manufacturers/'.$manufacturer->id.'/view', e($manufacturer->name)),
'assets' => $manufacturer->assets->count(),
'actions' => $actions
);
}
$data = array('total' => $manufacturersCount, 'rows' => $rows);
return $data;
}
/**
* Generates the JSON used to display the manufacturer detail.
* This JSON returns data on all of the assets with the specified
* manufacturer ID number.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::getView()
* @param int $manufacturerId
* @since [v1.0]
* @return String JSON
*/
public function getDataView($manufacturerId, $itemtype = null)
* Generates the JSON used to display the manufacturer detail.
* This JSON returns data on all of the assets with the specified
* manufacturer ID number.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see ManufacturersController::getView()
* @param int $manufacturerId
* @param string $itemType
* @param Request $request
* @return String JSON* @since [v1.0]
*/
public function getDataView($manufacturerId, $itemType = null, Request $request)
{
$manufacturer = Manufacturer::find($manufacturerId);
switch ($itemtype) {
switch ($itemType) {
case "assets":
return $this->getDataAssetsView($manufacturer);
return $this->getDataAssetsView($manufacturer, $request);
case "licenses":
return $this->getDataLicensesView($manufacturer);
return $this->getDataLicensesView($manufacturer, $request);
case "accessories":
return $this->getDataAccessoriesView($manufacturer);
return $this->getDataAccessoriesView($manufacturer, $request);
case "consumables":
return $this->getDataConsumablesView($manufacturer);
return $this->getDataConsumablesView($manufacturer, $request);
}
throw new Exception("We shouldn't be here");
return "We shouldn't be here";
}
protected function getDataAssetsView(Manufacturer $manufacturer)
protected function getDataAssetsView(Manufacturer $manufacturer, Request $request)
{
$manufacturer = $manufacturer->load('assets.model', 'assets.assigneduser', 'assets.assetstatus', 'assets.company');
$manufacturer_assets = $manufacturer->assets;
$manufacturer = $manufacturer->load('assets.model', 'assets.assignedTo', 'assets.assetstatus', 'assets.company');
$manufacturer_assets = $manufacturer->assets();
if (Input::has('search')) {
$manufacturer_assets = $manufacturer_assets->TextSearch(e(Input::get('search')));
if ($request->has('search')) {
$manufacturer_assets = $manufacturer_assets->TextSearch(e($request->input('search')));
}
if (Input::has('offset')) {
$offset = e(Input::get('offset'));
} else {
$offset = 0;
}
$offset = request('offset', 0);
$limit = request('limit', 50);
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
} else {
$limit = 50;
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$allowed_columns = ['id','name','serial','asset_tag'];
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
$count = $manufacturer_assets->count();
$manufacturer_assets = $manufacturer_assets->skip($offset)->take($limit)->get();
$rows = array();
$all_custom_fields = CustomField::all(); // cached;
foreach ($manufacturer_assets as $asset) {
$actions = '';
if ($asset->deleted_at=='') {
$actions = '<div style=" white-space: nowrap;"><a href="'.route('clone/hardware', $asset->id).'" class="btn btn-info btn-sm" title="Clone asset"><i class="fa fa-files-o"></i></a> <a href="'.route('update/hardware', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> <a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/hardware', $asset->id).'" data-content="'.trans('admin/hardware/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($asset->asset_tag).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a></div>';
} elseif ($asset->deleted_at!='') {
$actions = '<a href="'.route('restore/hardware', $asset->id).'" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
}
if ($asset->availableForCheckout()) {
if (Gate::allows('assets.checkout')) {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</a>';
}
} else {
if (Gate::allows('assets.checkin')) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
}
}
$rows[] = array(
'id' => $asset->id,
'name' => (string)link_to('/hardware/'.$asset->id.'/view', e($asset->showAssetName())),
'model' => e($asset->model->name),
'asset_tag' => e($asset->asset_tag),
'serial' => e($asset->serial),
'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', e($asset->assigneduser->fullName())): '',
'actions' => $actions,
// 'companyName' => e(Company::getName($asset)),
'companyName' => is_null($asset->company) ? '' : $asset->company->name
);
if (isset($inout)) {
$row['change'] = $inout;
}
$rows[] = $asset->present()->forDataTable($all_custom_fields);
}
$data = array('total' => $count, 'rows' => $rows);
return $data;
}
protected function getDataLicensesView(Manufacturer $manufacturer)
protected function getDataLicensesView(Manufacturer $manufacturer, Request $request)
{
$manufacturer = $manufacturer->load('licenses.company', 'licenses.manufacturer', 'licenses.licenseSeatsRelation');
$licenses = $manufacturer->licenses;
if (Input::has('search')) {
$licenses = $licenses->TextSearch(Input::get('search'));
if ($request->has('search')) {
$licenses = $licenses->TextSearch($request->input('search'));
}
$licenseCount = $licenses->count();
@@ -357,46 +254,7 @@ class ManufacturersController extends Controller
$rows = array();
foreach ($licenses as $license) {
$actions = '<span style="white-space: nowrap;">';
if (Gate::allows('licenses.checkout')) {
$actions .= '<a href="' . route('freecheckout/license', $license->id)
. '" class="btn btn-primary btn-sm' . (($license->remaincount() > 0) ? '' : ' disabled') . '" style="margin-right:5px;">' . trans('general.checkout') . '</a> ';
}
if (Gate::allows('licenses.create')) {
$actions .= '<a href="' . route('clone/license', $license->id)
. '" class="btn btn-info btn-sm" style="margin-right:5px;" title="Clone asset"><i class="fa fa-files-o"></i></a>';
}
if (Gate::allows('licenses.edit')) {
$actions .= '<a href="' . route('update/license', $license->id)
. '" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a>';
}
if (Gate::allows('licenses.delete')) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'
. route('delete/license', $license->id)
. '" data-content="' . trans('admin/licenses/message.delete.confirm') . '" data-title="' . trans('general.delete') . ' ' . htmlspecialchars($license->name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
}
$actions .='</span>';
$rows[] = array(
'id' => $license->id,
'name' => (string) link_to('/admin/licenses/'.$license->id.'/view', $license->name),
'serial' => (string) link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")),
'totalSeats' => $license->licenseSeatCount,
'remaining' => $license->remaincount(),
'license_name' => e($license->license_name),
'license_email' => e($license->license_email),
'purchase_date' => ($license->purchase_date) ? $license->purchase_date : '',
'expiration_date' => ($license->expiration_date) ? $license->expiration_date : '',
'purchase_cost' => ($license->purchase_cost) ? number_format($license->purchase_cost, 2) : '',
'purchase_order' => ($license->purchase_order) ? e($license->purchase_order) : '',
'order_number' => ($license->order_number) ? e($license->order_number) : '',
'notes' => ($license->notes) ? e($license->notes) : '',
'actions' => $actions,
'companyName' => is_null($license->company) ? '' : e($license->company->name),
'manufacturer' => $license->manufacturer ? (string) link_to('/admin/settings/manufacturers/'.$license->manufacturer_id.'/view', $license->manufacturer->name) : ''
);
$rows[] = $license->present()->forDataTable();
}
$data = array('total' => $licenseCount, 'rows' => $rows);
@@ -404,7 +262,7 @@ class ManufacturersController extends Controller
return $data;
}
public function getDataAccessoriesView(Manufacturer $manufacturer)
public function getDataAccessoriesView(Manufacturer $manufacturer, Request $request)
{
$manufacturer = $manufacturer->load(
'accessories.location',
@@ -412,56 +270,22 @@ class ManufacturersController extends Controller
'accessories.category',
'accessories.manufacturer',
'accessories.users'
);
$accessories = $manufacturer->accessories;
);
$accessories = $manufacturer->accessories();
if (Input::has('search')) {
$accessories = $accessories->TextSearch(e(Input::get('search')));
if ($request->has('search')) {
$accessories = $accessories->TextSearch(e($request->input('search')));
}
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
} else {
$limit = 50;
}
$offset = request('offset', 0);
$limit = request('limit', 50);
$accessCount = $accessories->count();
$accessories = $accessories->skip($offset)->take($limit)->get();
$rows = array();
foreach ($accessories as $accessory) {
$actions = '<nobr>';
if (Gate::allows('accessories.checkout')) {
$actions .= '<a href="' . route('checkout/accessory',
$accessory->id) . '" style="margin-right:5px;" class="btn btn-info btn-sm" ' . (($accessory->numRemaining() > 0) ? '' : ' disabled') . '>' . trans('general.checkout') . '</a>';
}
if (Gate::allows('accessories.edit')) {
$actions .= '<a href="' . route('update/accessory',
$accessory->id) . '" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a>';
}
if (Gate::allows('accessories.delete')) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/accessory',
$accessory->id) . '" data-content="' . trans('admin/accessories/message.delete.confirm') . '" data-title="' . trans('general.delete') . ' ' . htmlspecialchars($accessory->name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
}
$actions .= '</nobr>';
$company = $accessory->company;
$rows[] = array(
'name' => '<a href="'.url('admin/accessories/'.$accessory->id).'/view">'. $accessory->name.'</a>',
'category' => ($accessory->category) ? (string)link_to('admin/settings/categories/'.$accessory->category->id.'/view', $accessory->category->name) : '',
'qty' => e($accessory->qty),
'order_number' => e($accessory->order_number),
'min_amt' => e($accessory->min_amt),
'location' => ($accessory->location) ? e($accessory->location->name): '',
'purchase_date' => e($accessory->purchase_date),
'purchase_cost' => number_format($accessory->purchase_cost, 2),
'numRemaining' => $accessory->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name),
'manufacturer' => $accessory->manufacturer ? (string) link_to('/admin/settings/manufacturers/'.$accessory->manufacturer_id.'/view', $accessory->manufacturer->name) : ''
);
$rows[] = $accessory->present()->forDataTable();
}
$data = array('total'=>$accessCount, 'rows'=>$rows);
@@ -469,7 +293,7 @@ class ManufacturersController extends Controller
return $data;
}
public function getDataConsumablesView($manufacturer)
public function getDataConsumablesView($manufacturer, Request $request)
{
$manufacturer = $manufacturer->load(
'consumables.location',
@@ -478,59 +302,22 @@ class ManufacturersController extends Controller
'consumables.manufacturer',
'consumables.users'
);
$consumables = $manufacturer->consumables;
$consumables = $manufacturer->consumables();
if (Input::has('search')) {
$consumables = $consumables->TextSearch(e(Input::get('search')));
if ($request->has('search')) {
$consumables = $consumables->TextSearch(e($request->input('search')));
}
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
} else {
$limit = 50;
}
$offset = request('offset', 0);
$limit = request('limit', 50);
$consumCount = $consumables->count();
$consumables = $consumables->skip($offset)->take($limit)->get();
$rows = array();
foreach ($consumables as $consumable) {
$actions = '<nobr>';
if (Gate::allows('consumables.checkout')) {
$actions .= '<a href="' . route('checkout/consumable',
$consumable->id) . '" style="margin-right:5px;" class="btn btn-info btn-sm" ' . (($consumable->numRemaining() > 0) ? '' : ' disabled') . '>' . trans('general.checkout') . '</a>';
}
if (Gate::allows('consumables.edit')) {
$actions .= '<a href="' . route('update/consumable',
$consumable->id) . '" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a>';
}
if (Gate::allows('consumables.delete')) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/consumable',
$consumable->id) . '" data-content="' . trans('admin/consumables/message.delete.confirm') . '" data-title="' . trans('general.delete') . ' ' . htmlspecialchars($consumable->name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
}
$actions .='</nobr>';
$company = $consumable->company;
$rows[] = array(
'id' => $consumable->id,
'name' => (string)link_to('admin/consumables/'.$consumable->id.'/view', e($consumable->name)),
'location' => ($consumable->location) ? e($consumable->location->name) : '',
'min_amt' => e($consumable->min_amt),
'qty' => e($consumable->qty),
'manufacturer' => ($consumable->manufacturer) ? (string) link_to('/admin/settings/manufacturers/'.$consumable->manufacturer_id.'/view', $consumable->manufacturer->name): '',
'model_number' => e($consumable->model_number),
'item_no' => e($consumable->item_no),
'category' => ($consumable->category) ? (string) link_to('/admin/settings/categories/'.$consumable->category_id.'/view', $consumable->category->name) : 'Missing category',
'order_number' => e($consumable->order_number),
'purchase_date' => e($consumable->purchase_date),
'purchase_cost' => ($consumable->purchase_cost!='') ? number_format($consumable->purchase_cost, 2): '' ,
'numRemaining' => $consumable->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name),
);
$rows[] = $consumable->present()->forDataTable();
}
$data = array('total' => $consumCount, 'rows' => $rows);

View File

@@ -24,11 +24,10 @@ class ProfileController extends Controller
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
* @return \Illuminate\Contracts\View\View
*/
public function getIndex()
{
// Get the user information
$user = Auth::user();
$location_list = Helper::locationsList();
return View::make('account/profile', compact('user'))->with('location_list', $location_list);
@@ -39,25 +38,21 @@ class ProfileController extends Controller
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return Redirect
*/
* @return \Illuminate\Http\RedirectResponse
*/
public function postIndex()
{
// Grab the user
$user = Auth::user();
// Update the user information
$user->first_name = e(Input::get('first_name'));
$user->last_name = e(Input::get('last_name'));
$user->website = e(Input::get('website'));
$user->location_id = e(Input::get('location_id'));
$user->gravatar = e(Input::get('gravatar'));
$user->locale = e(Input::get('locale'));
$user->first_name = Input::get('first_name');
$user->last_name = Input::get('last_name');
$user->website = Input::get('website');
$user->location_id = Input::get('location_id');
$user->gravatar = Input::get('gravatar');
$user->locale = Input::get('locale');
if ((Gate::allows('self.two_factor')) && ((Setting::getSettings()->two_factor_enabled=='1') && (!config('app.lock_passwords')))) {
$user->two_factor_optin = e(Input::get('two_factor_optin', '0'));
$user->two_factor_optin = Input::get('two_factor_optin', '0');
}
if (Input::file('avatar')) {
@@ -77,4 +72,19 @@ class ProfileController extends Controller
}
return redirect()->back()->withInput()->withErrors($user->getErrors());
}
/**
* Returns a page with the API token generation interface.
*
* We created a controller method for this because closures aren't allowed
* in the routes file if you want to be able to cache the routes.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function api() {
return view('account/api');
}
}

View File

@@ -117,11 +117,11 @@ class ReportsController extends Controller
$customfields = CustomField::get();
$response = new StreamedResponse(function() use ($customfields) {
$response = new StreamedResponse(function () use ($customfields) {
// Open output stream
$handle = fopen('php://output', 'w');
Asset::with('assigneduser', 'assetloc','defaultLoc','assigneduser.userloc','model','supplier','assetstatus','model.manufacturer')->orderBy('created_at', 'DESC')->chunk(500, function($assets) use($handle, $customfields) {
Asset::with('assignedTo', 'assetLoc','defaultLoc','assignedTo','model','supplier','assetstatus','model.manufacturer')->orderBy('created_at', 'DESC')->chunk(500, function($assets) use($handle, $customfields) {
$headers=[
trans('general.company'),
trans('admin/hardware/table.asset_tag'),
@@ -140,7 +140,7 @@ class ReportsController extends Controller
trans('admin/hardware/table.location'),
trans('general.notes'),
];
foreach($customfields as $field) {
foreach ($customfields as $field) {
$headers[]=$field->name;
}
fputcsv($handle, $headers);
@@ -160,13 +160,12 @@ class ReportsController extends Controller
($asset->purchase_cost > 0) ? Helper::formatCurrencyOutput($asset->purchase_cost) : '',
($asset->order_number) ? e($asset->order_number) : '',
($asset->supplier) ? e($asset->supplier->name) : '',
($asset->assigneduser) ? e($asset->assigneduser->fullName()) : '',
($asset->assignedTo) ? e($asset->assignedTo->present()->name()) : '',
($asset->last_checkout!='') ? e($asset->last_checkout) : '',
($asset->assigneduser && $asset->assigneduser->userloc!='') ?
e($asset->assigneduser->userloc->name) : ( ($asset->defaultLoc!='') ? e($asset->defaultLoc->name) : ''),
e($asset->assetLoc->present()->name()),
($asset->notes) ? e($asset->notes) : '',
];
foreach($customfields as $field) {
foreach ($customfields as $field) {
$values[]=$asset->{$field->db_column_name()};
}
fputcsv($handle, $values);
@@ -195,7 +194,7 @@ class ReportsController extends Controller
{
// Grab all the assets
$assets = Asset::with('model', 'assigneduser', 'assetstatus', 'defaultLoc', 'assetlog', 'company')
$assets = Asset::with('model', 'assignedTo', 'assetstatus', 'defaultLoc', 'assetlog', 'company')
->orderBy('created_at', 'DESC')->get();
return View::make('reports/depreciation', compact('assets'));
@@ -213,7 +212,7 @@ class ReportsController extends Controller
{
// Grab all the assets
$assets = Asset::with('model', 'assigneduser', 'assetstatus', 'defaultLoc', 'assetlog')
$assets = Asset::with('model', 'assignedTo', 'assetstatus', 'defaultLoc', 'assetlog')
->orderBy('created_at', 'DESC')->get();
$csv = \League\Csv\Writer::createFromFileObject(new \SplTempFileObject());
@@ -244,15 +243,13 @@ class ReportsController extends Controller
$row[] = e($asset->name);
$row[] = e($asset->serial);
if ($asset->assigned_to > 0) {
$user = User::find($asset->assigned_to);
$row[] = e($user->fullName());
if ($target = $asset->assignedTo) {
$row[] = e($target->present()->name());
} else {
$row[] = ''; // Empty string if unassigned
}
if (( $asset->assigned_to > 0 ) && ( $asset->assigneduser->location_id > 0 )) {
$location = Location::find($asset->assigneduser->location_id);
if (( $asset->assigned_to > 0 ) && ( $location = $asset->assetLoc )) {
if ($location->city) {
$row[] = e($location->city) . ', ' . e($location->state);
} elseif ($location->name) {
@@ -291,12 +288,8 @@ class ReportsController extends Controller
*/
public function getActivityReport()
{
$log_actions = Actionlog::orderBy('created_at', 'DESC')
->with('item')
->orderBy('created_at', 'DESC')
->get();
return View::make('reports/activity', compact('log_actions'));
return View::make('reports/activity');
}
/**
@@ -337,78 +330,7 @@ class ReportsController extends Controller
$rows = array();
foreach ($activitylogs as $activity) {
if ($activity->itemType() == "asset") {
$activity_icons = '<i class="fa fa-barcode"></i>';
} elseif ($activity->itemType() == "accessory") {
$activity_icons = '<i class="fa fa-keyboard-o"></i>';
} elseif ($activity->itemType()=="consumable") {
$activity_icons = '<i class="fa fa-tint"></i>';
} elseif ($activity->itemType()=="license"){
$activity_icons = '<i class="fa fa-floppy-o"></i>';
} elseif ($activity->itemType()=="component") {
$activity_icons = '<i class="fa fa-hdd-o"></i>';
} else {
$activity_icons = '<i class="fa fa-paperclip"></i>';
}
if (($activity->item) && ($activity->itemType()=="asset")) {
$activity_item = '<a href="'.route('view/hardware', $activity->item_id).'">'.e($activity->item->asset_tag).' - '. e($activity->item->showAssetName()).'</a>';
$item_type = 'asset';
} elseif ($activity->item) {
$activity_item = '<a href="' . route('view/' . $activity->itemType(),
$activity->item_id) . '">' . e($activity->item->name) . '</a>';
$item_type = $activity->itemType();
} else {
$activity_item = "unkonwn";
$item_type = "null";
}
if (($activity->user) && ($activity->action_type=="uploaded") && ($activity->itemType()=="user")) {
$activity_target = '<a href="'.route('view/user', $activity->target_id).'">'.$activity->user->fullName().'</a>';
} elseif ($activity->target_type === "App\Models\Asset") {
if($activity->target) {
$activity_target = '<a href="'.route('view/hardware', $activity->target_id).'">'.$activity->target->showAssetName().'</a>';
} else {
$activity_target = "";
}
} elseif ( $activity->target_type === "App\Models\User") {
if($activity->target) {
$activity_target = '<a href="'.route('view/user', $activity->target_id).'">'.$activity->target->fullName().'</a>';
} else {
$activity_target = '';
}
} elseif (($activity->action_type=='accepted') || ($activity->action_type=='declined')) {
$activity_target = '<a href="' . route('view/user', $activity->item->assigneduser->id) . '">' . e($activity->item->assigneduser->fullName()) . '</a>';
} elseif ($activity->action_type=='requested') {
if ($activity->user) {
$activity_target = '<a href="'.route('view/user', $activity->user_id).'">'.$activity->user->fullName().'</a>';
} else {
$activity_target = '';
}
} else {
if($activity->target) {
$activity_target = $activity->target->id;
} else {
$activity_target = "";
}
}
$rows[] = array(
'icon' => $activity_icons,
'created_at' => date("M d, Y g:iA", strtotime($activity->created_at)),
'action_type' => strtolower(trans('general.'.str_replace(' ','_',$activity->action_type))),
'admin' => $activity->user ? (string) link_to('/admin/users/'.$activity->user_id.'/view', $activity->user->fullName()) : '',
'target' => $activity_target,
'item' => $activity_item,
'item_type' => $item_type,
'note' => e($activity->note),
);
$rows[] = $activity->present()->forDataTable();
}
$data = array('total'=>$activityCount, 'rows'=>$rows);
@@ -508,7 +430,7 @@ class ReportsController extends Controller
*/
public function postCustom()
{
$assets = Asset::orderBy('created_at', 'DESC')->with('company','assigneduser', 'assetloc','defaultLoc','assigneduser.userloc','model','supplier','assetstatus','model.manufacturer')->get();
$assets = Asset::orderBy('created_at', 'DESC')->with('company', 'assigneduser', 'assetloc', 'defaultLoc', 'assigneduser.userloc', 'model', 'supplier', 'assetstatus', 'model.manufacturer')->get();
$customfields = CustomField::get();
$rows = [ ];
@@ -580,6 +502,10 @@ class ReportsController extends Controller
$header[] = trans('admin/hardware/form.expected_checkin');
}
if (e(Input::get('notes')) == '1') {
$header[] = 'Notes';
}
foreach ($customfields as $customfield) {
if (e(Input::get($customfield->db_column_name())) == '1') {
@@ -629,7 +555,7 @@ class ReportsController extends Controller
$row[] = '"' . Helper::formatCurrencyOutput($asset->purchase_cost) . '"';
}
if (e(Input::get('eol')) == '1') {
$row[] = '"' .($asset->eol_date()) ? $asset->eol_date() : ''. '"';
$row[] = '"' .($asset->present()->eol_date()) ? $asset->present()->eol_date() : ''. '"';
}
if (e(Input::get('order')) == '1') {
if ($asset->order_number) {
@@ -647,34 +573,25 @@ class ReportsController extends Controller
}
if (e(Input::get('location')) == '1') {
$show_loc = '';
if (($asset->assigned_to > 0) && ($asset->assigneduser) && ($asset->assigneduser->location)) {
$show_loc .= '"' .e($asset->assigneduser->location->name). '"';
} elseif ($asset->rtd_location_id!='') {
$location = Location::find($asset->rtd_location_id);
if ($location) {
$show_loc .= '"' .e($location->name). '"';
} else {
$show_loc .= 'Default location '.$asset->rtd_location_id.' is invalid';
}
if($asset->assetLoc) {
$show_loc = $asset->assetLoc->present()->name();
} else {
$show_loc = 'Default location '.$asset->rtd_location_id.' is invalid';
}
$row[] = $show_loc;
}
if (e(Input::get('assigned_to')) == '1') {
if ($asset->assigneduser) {
$row[] = '"' .e($asset->assigneduser->fullName()). '"';
if ($asset->assignedTo) {
$row[] = '"' .e($asset->assignedTo->present()->name()). '"';
} else {
$row[] = ''; // Empty string if unassigned
}
}
if (e(Input::get('username')) == '1') {
// Only works if we're checked out to a user, not anything else.
if ($asset->assigneduser) {
$row[] = '"' .e($asset->assigneduser->username). '"';
} else {
@@ -683,6 +600,7 @@ class ReportsController extends Controller
}
if (e(Input::get('employee_num')) == '1') {
// Only works if we're checked out to a user, not anything else.
if ($asset->assigneduser) {
$row[] = '"' .e($asset->assigneduser->employee_num). '"';
} else {
@@ -704,7 +622,7 @@ class ReportsController extends Controller
if (e(Input::get('warranty')) == '1') {
if ($asset->warranty_months) {
$row[] = $asset->warranty_months;
$row[] = $asset->warrantee_expires();
$row[] = $asset->present()->warrantee_expires();
} else {
$row[] = '';
$row[] = '';
@@ -724,6 +642,14 @@ class ReportsController extends Controller
}
}
if (e(Input::get('notes')) == '1') {
if ($asset->notes) {
$row[] = '"' .$asset->notes. '"';
} else {
$row[] = ''; // Empty string if unassigned
}
}
foreach ($customfields as $customfield) {
$column_name = $customfield->db_column_name();
if (e(Input::get($customfield->db_column_name())) == '1') {
@@ -748,7 +674,7 @@ class ReportsController extends Controller
->with('error', trans('admin/reports/message.error'));
}
}
/**
* getImprovementsReport
@@ -873,9 +799,9 @@ class ReportsController extends Controller
$row = [ ];
$row[] = str_replace(',', '', e($assetItem->assetlog->model->category->name));
$row[] = str_replace(',', '', e($assetItem->assetlog->model->name));
$row[] = str_replace(',', '', e($assetItem->assetlog->showAssetName()));
$row[] = str_replace(',', '', e($assetItem->assetlog->present()->name()));
$row[] = str_replace(',', '', e($assetItem->assetlog->asset_tag));
$row[] = str_replace(',', '', e($assetItem->assetlog->assigneduser->fullName()));
$row[] = str_replace(',', '', e($assetItem->assetlog->assignedTo->present()->name()));
$rows[] = implode($row, ',');
}

View File

@@ -3,6 +3,7 @@ namespace App\Http\Controllers;
use Input;
use Lang;
use Illuminate\Http\Request;
use App\Models\Setting;
use App\Models\Ldap;
use Redirect;
@@ -18,6 +19,7 @@ use Mail;
use Auth;
use App\Models\User;
use App\Http\Requests\SetupUserRequest;
use App\Http\Requests\ImageUploadRequest;
/**
* This controller handles all actions related to Settings for
@@ -55,13 +57,13 @@ class SettingsController extends Controller
$host = $_SERVER['SERVER_NAME'];
if (($protocol === 'http://' && $_SERVER['SERVER_PORT'] != '80') || ($protocol === 'https://' && $_SERVER['SERVER_PORT'] != '443')) {
$host .= ':' . $_SERVER['SERVER_PORT'];
$host .= ':' . $_SERVER['SERVER_PORT'];
}
$pageURL = $protocol . $host . $_SERVER['REQUEST_URI'];
$start_settings['url_valid'] = (config('app.url').'/setup' === $pageURL);
$start_settings['url_valid'] = (url('/').'/setup' === $pageURL);
$start_settings['url_config'] = config('app.url');
$start_settings['url_config'] = url('/');
$start_settings['real_url'] = $pageURL;
$exposed_env = @file_get_contents($protocol . $host.'/.env');
@@ -292,7 +294,7 @@ class SettingsController extends Controller
* @since [v1.0]
* @return Redirect
*/
public function postEdit()
public function postEdit(ImageUploadRequest $request)
{
// Check if the asset exists
@@ -301,25 +303,9 @@ class SettingsController extends Controller
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
if (Input::get('clear_logo')=='1') {
$setting->logo = null;
} elseif (Input::file('logo_img')) {
if (!config('app.lock_passwords')) {
$image = Input::file('logo_img');
$file_name = "logo.".$image->getClientOriginalExtension();
$path = public_path('uploads/'.$file_name);
Image::make($image->getRealPath())->resize(null, 40, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->save($path);
$setting->logo = $file_name;
}
}
if (!config('app.lock_passwords')) {
$setting->site_name = e(Input::get('site_name'));
$setting->brand = e(Input::get('brand'));
$setting->custom_css = e(Input::get('custom_css'));
if (Input::get('two_factor_enabled')=='') {
@@ -354,8 +340,6 @@ class SettingsController extends Controller
$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'));
@@ -420,6 +404,31 @@ class SettingsController extends Controller
$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 {
@@ -433,7 +442,8 @@ class SettingsController extends Controller
}
public function getLdapTest() {
public function getLdapTest()
{
try {
$connection = Ldap::connectToLdap();
@@ -588,4 +598,18 @@ class SettingsController extends Controller
return redirect()->back()->with('error', trans('general.feature_disabled'));
}
}
/**
* Returns a page with the API token generation interface.
*
* We created a controller method for this because closures aren't allowed
* in the routes file if you want to be able to cache the routes.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v4.0]
* @return View
*/
public function api() {
return view('settings/api');
}
}

View File

@@ -27,64 +27,33 @@ class StatuslabelsController extends Controller
/**
* Show a list of all the statuslabels.
*
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getIndex()
public function index()
{
// Show the page
return View::make('statuslabels/index', compact('statuslabels'));
}
/**
* Show a count of assets by status label
*
* @return View
*/
public function getAssetCountByStatuslabel()
public function show($id)
{
$colors = [];
$statuslabels = Statuslabel::with('assets')->get();
$labels=[];
$points=[];
$colors=[];
foreach ($statuslabels as $statuslabel) {
if ($statuslabel->assets->count() > 0) {
$labels[]=$statuslabel->name;
$points[]=$statuslabel->assets()->whereNull('assigned_to')->count();
if ($statuslabel->color!='') {
$colors[]=$statuslabel->color;
}
}
$statuslabel = Statuslabel::find($id);
if (isset($statuslabel->id)) {
return View::make('statuslabels/view', compact('statuslabel'));
}
$labels[]='Deployed';
$points[]=Asset::whereNotNull('assigned_to')->count();
$colors_array = array_merge($colors, Helper::chartColors());
$result= [
"labels" => $labels,
"datasets" => [ [
"data" => $points,
"backgroundColor" => $colors_array,
"hoverBackgroundColor" => $colors_array
]]
];
return $result;
return redirect()->route('statuslabels.index')->with('error', trans('admin/locations/message.does_not_exist', compact('id')));
}
/**
* Statuslabel create.
*
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getCreate()
public function create()
{
// Show the page
$item = new Statuslabel;
@@ -98,52 +67,53 @@ class StatuslabelsController extends Controller
/**
* Statuslabel create form processing.
*
* @return Redirect
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function postCreate(Request $request)
public function store(Request $request)
{
// create a new model instance
$statuslabel = new Statuslabel();
$statusLabel = new Statuslabel();
if (!$request->has('statuslabel_types')) {
return redirect()->back()->withInput()->withErrors(['statuslabel_types' => trans('validation.statuslabel_type')]);
}
$statustype = Statuslabel::getStatuslabelTypesForDB($request->input('statuslabel_types'));
$statusType = Statuslabel::getStatuslabelTypesForDB($request->input('statuslabel_types'));
// Save the Statuslabel data
$statuslabel->name = e(Input::get('name'));
$statuslabel->user_id = Auth::user()->id;
$statuslabel->notes = e(Input::get('notes'));
$statuslabel->deployable = $statustype['deployable'];
$statuslabel->pending = $statustype['pending'];
$statuslabel->archived = $statustype['archived'];
$statuslabel->color = e(Input::get('color'));
$statuslabel->show_in_nav = e(Input::get('show_in_nav'),0);
$statusLabel->name = Input::get('name');
$statusLabel->user_id = Auth::id();
$statusLabel->notes = Input::get('notes');
$statusLabel->deployable = $statusType['deployable'];
$statusLabel->pending = $statusType['pending'];
$statusLabel->archived = $statusType['archived'];
$statusLabel->color = Input::get('color');
$statusLabel->show_in_nav = Input::get('show_in_nav', 0);
// Was the asset created?
if ($statuslabel->save()) {
if ($statusLabel->save()) {
// Redirect to the new Statuslabel page
return redirect()->to("admin/settings/statuslabels")->with('success', trans('admin/statuslabels/message.create.success'));
return redirect()->route('statuslabels.index')->with('success', trans('admin/statuslabels/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($statuslabel->getErrors());
return redirect()->back()->withInput()->withErrors($statusLabel->getErrors());
}
public function store(Request $request)
/**
* @param Request $request
* @return JsonResponse
*/
public function apiStore(Request $request)
{
$statuslabel = new Statuslabel();
if (!$request->has('statuslabel_types')) {
return JsonResponse::create(["error" => trans('validation.statuslabel_type')], 500);
}
$statustype = Statuslabel::getStatuslabelTypesForDB(Input::get('statuslabel_types'));
$statuslabel->name = e(Input::get('name'));
$statuslabel->user_id = Auth::user()->id;
$statuslabel->name = Input::get('name');
$statuslabel->user_id = Auth::id();
$statuslabel->notes = '';
$statuslabel->deployable = $statustype['deployable'];
$statuslabel->pending = $statustype['pending'];
@@ -164,14 +134,14 @@ class StatuslabelsController extends Controller
* Statuslabel update.
*
* @param int $statuslabelId
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getEdit($statuslabelId = null)
public function edit($statuslabelId = null)
{
// Check if the Statuslabel exists
if (is_null($item = Statuslabel::find($statuslabelId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/statuslabels')->with('error', trans('admin/statuslabels/message.does_not_exist'));
return redirect()->route('statuslabels.index')->with('error', trans('admin/statuslabels/message.does_not_exist'));
}
$use_statuslabel_type = $item->getStatuslabelType();
@@ -186,14 +156,14 @@ class StatuslabelsController extends Controller
* Statuslabel update form processing page.
*
* @param int $statuslabelId
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
*/
public function postEdit(Request $request, $statuslabelId = null)
public function update(Request $request, $statuslabelId = null)
{
// Check if the Statuslabel exists
if (is_null($statuslabel = Statuslabel::find($statuslabelId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/statuslabels')->with('error', trans('admin/statuslabels/message.does_not_exist'));
return redirect()->route('statuslabels.index')->with('error', trans('admin/statuslabels/message.does_not_exist'));
}
if (!$request->has('statuslabel_types')) {
@@ -202,128 +172,46 @@ class StatuslabelsController extends Controller
// Update the Statuslabel data
$statustype = Statuslabel::getStatuslabelTypesForDB(Input::get('statuslabel_types'));
$statuslabel->name = e(Input::get('name'));
$statuslabel->notes = e(Input::get('notes'));
$statustype = Statuslabel::getStatuslabelTypesForDB(Input::get('statuslabel_types'));
$statuslabel->name = Input::get('name');
$statuslabel->notes = Input::get('notes');
$statuslabel->deployable = $statustype['deployable'];
$statuslabel->pending = $statustype['pending'];
$statuslabel->archived = $statustype['archived'];
$statuslabel->color = e(Input::get('color'));
$statuslabel->show_in_nav = e(Input::get('show_in_nav'),0);
$statuslabel->color = Input::get('color');
$statuslabel->show_in_nav = Input::get('show_in_nav', 0);
// Was the asset created?
if ($statuslabel->save()) {
// Redirect to the saved Statuslabel page
return redirect()->to("admin/settings/statuslabels/")->with('success', trans('admin/statuslabels/message.update.success'));
} else {
return redirect()->back()->withInput()->withErrors($statuslabel->getErrors());
return redirect()->route("statuslabels.index")->with('success', trans('admin/statuslabels/message.update.success'));
}
// Redirect to the Statuslabel management page
return redirect()->to("admin/settings/statuslabels/$statuslabelId/edit")->with('error', trans('admin/statuslabels/message.update.error'));
return redirect()->back()->withInput()->withErrors($statuslabel->getErrors());
}
/**
* Delete the given Statuslabel.
*
* @param int $statuslabelId
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
*/
public function getDelete($statuslabelId)
public function destroy($statuslabelId)
{
// Check if the Statuslabel exists
if (is_null($statuslabel = Statuslabel::find($statuslabelId))) {
// Redirect to the blogs management page
return redirect()->to('admin/settings/statuslabels')->with('error', trans('admin/statuslabels/message.not_found'));
return redirect()->route('statuslabels.index')->with('error', trans('admin/statuslabels/message.not_found'));
}
if ($statuslabel->has_assets() > 0) {
// Redirect to the asset management page
return redirect()->to('admin/settings/statuslabels')->with('error', trans('admin/statuslabels/message.assoc_assets'));
} else {
if ($statuslabel->has_assets() == 0) {
$statuslabel->delete();
// Redirect to the statuslabels management page
return redirect()->to('admin/settings/statuslabels')->with('success', trans('admin/statuslabels/message.delete.success'));
return redirect()->route('statuslabels.index')->with('success', trans('admin/statuslabels/message.delete.success'));
}
// Redirect to the asset management page
return redirect()->route('statuslabels.index')->with('error', trans('admin/statuslabels/message.assoc_assets'));
}
public function getDatatable()
{
$statuslabels = Statuslabel::select(array('id','name','deployable','pending','archived','color','show_in_nav'))
->whereNull('deleted_at');
if (Input::has('search')) {
$statuslabels = $statuslabels->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 = ['id','name'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$statuslabels->orderBy($sort, $order);
$statuslabelsCount = $statuslabels->count();
$statuslabels = $statuslabels->skip($offset)->take($limit)->get();
$rows = array();
foreach ($statuslabels as $statuslabel) {
if ($statuslabel->deployable == 1) {
$label_type = trans('admin/statuslabels/table.deployable');
} elseif ($statuslabel->pending == 1) {
$label_type = trans('admin/statuslabels/table.pending');
} elseif ($statuslabel->archived == 1) {
$label_type = trans('admin/statuslabels/table.archived');
} else {
$label_type = trans('admin/statuslabels/table.undeployable');
}
$actions = '<a href="'.route('update/statuslabel', $statuslabel->id).'" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a><a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/statuslabel', $statuslabel->id).'" data-content="'.trans('admin/statuslabels/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($statuslabel->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
if ($statuslabel->color!='') {
$color = '<div class="pull-left" style="margin-right: 5px; height: 20px; width: 20px; background-color: '.e($statuslabel->color).'"></div>'.e($statuslabel->color);
} else {
$color = '';
}
$rows[] = array(
'id' => e($statuslabel->id),
'type' => e($label_type),
'name' => e($statuslabel->name),
'color' => $color,
'show_in_nav' => ($statuslabel->show_in_nav=='1') ? trans('general.yes') : trans('general.no'),
'actions' => $actions
);
}
$data = array('total' => $statuslabelsCount, 'rows' => $rows);
return $data;
}
}

View File

@@ -1,6 +1,7 @@
<?php
namespace App\Http\Controllers;
use App\Helpers\Helper;
use Image;
use App\Models\AssetMaintenance;
use Input;
@@ -26,9 +27,9 @@ class SuppliersController extends Controller
/**
* Show a list of all suppliers
*
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getIndex()
public function index()
{
// Grab all the suppliers
$suppliers = Supplier::orderBy('created_at', 'DESC')->get();
@@ -41,9 +42,9 @@ class SuppliersController extends Controller
/**
* Supplier create.
*
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getCreate()
public function create()
{
return View::make('suppliers/edit')->with('item', new Supplier);
}
@@ -52,37 +53,31 @@ class SuppliersController extends Controller
/**
* Supplier create form processing.
*
* @return Redirect
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function postCreate()
public function store(Request $request)
{
// get the POST data
$new = Input::all();
// Create a new supplier
$supplier = new Supplier;
// Save the location data
$supplier->name = e(Input::get('name'));
$supplier->address = e(Input::get('address'));
$supplier->address2 = e(Input::get('address2'));
$supplier->city = e(Input::get('city'));
$supplier->state = e(Input::get('state'));
$supplier->country = e(Input::get('country'));
$supplier->zip = e(Input::get('zip'));
$supplier->contact = e(Input::get('contact'));
$supplier->phone = e(Input::get('phone'));
$supplier->fax = e(Input::get('fax'));
$supplier->email = e(Input::get('email'));
$supplier->notes = e(Input::get('notes'));
$supplier->url = $supplier->addhttp(e(Input::get('url')));
$supplier->user_id = Auth::user()->id;
$supplier->name = request('name');
$supplier->address = request('address');
$supplier->address2 = request('address2');
$supplier->city = request('city');
$supplier->state = request('state');
$supplier->country = request('country');
$supplier->zip = request('zip');
$supplier->contact = request('contact');
$supplier->phone = request('phone');
$supplier->fax = request('fax');
$supplier->email = request('email');
$supplier->notes = request('notes');
$supplier->url = $supplier->addhttp(request('url'));
$supplier->user_id = Auth::id();
if (Input::file('image')) {
$image = Input::file('image');
$image = $request->file('image');
$file_name = str_random(25).".".$image->getClientOriginalExtension();
$path = public_path('uploads/suppliers/'.$file_name);
Image::make($image->getRealPath())->resize(300, null, function ($constraint) {
@@ -95,39 +90,39 @@ class SuppliersController extends Controller
// Was it created?
if ($supplier->save()) {
// Redirect to the new supplier page
return redirect()->to("admin/settings/suppliers")->with('success', trans('admin/suppliers/message.create.success'));
return redirect()->route('suppliers.index')->with('success', trans('admin/suppliers/message.create.success'));
}
return redirect()->back()->withInput()->withErrors($supplier->getErrors());
}
public function store(Request $request)
/**
* @param Request $request
* @return JsonResponse
*/
public function apiStore(Request $request)
{
$supplier = new Supplier;
$supplier->name = e($request->input('name'));
$supplier->user_id = Auth::user()->id;
$supplier->name = $request->input('name');
$supplier->user_id = Auth::id();
if ($supplier->save()) {
return JsonResponse::create($supplier);
}
return JsonResponse::create(["error" => "Failed validation: ".print_r($supplier->getErrors(), true)], 500);
return JsonResponse::create(["error" => "Couldn't save Supplier"]);
}
/**
* Supplier update.
*
* @param int $supplierId
* @return View
* @return \Illuminate\Contracts\View\View
*/
public function getEdit($supplierId = null)
public function edit($supplierId = null)
{
// Check if the supplier exists
if (is_null($item = Supplier::find($supplierId))) {
// Redirect to the supplier page
return redirect()->to('admin/settings/suppliers')->with('error', trans('admin/suppliers/message.does_not_exist'));
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.does_not_exist'));
}
// Show the page
@@ -139,33 +134,33 @@ class SuppliersController extends Controller
* Supplier update form processing page.
*
* @param int $supplierId
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
*/
public function postEdit($supplierId = null)
public function update($supplierId = null, Request $request)
{
// Check if the supplier exists
if (is_null($supplier = Supplier::find($supplierId))) {
// Redirect to the supplier page
return redirect()->to('admin/settings/suppliers')->with('error', trans('admin/suppliers/message.does_not_exist'));
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.does_not_exist'));
}
// Save the data
$supplier->name = e(Input::get('name'));
$supplier->address = e(Input::get('address'));
$supplier->address2 = e(Input::get('address2'));
$supplier->city = e(Input::get('city'));
$supplier->state = e(Input::get('state'));
$supplier->country = e(Input::get('country'));
$supplier->zip = e(Input::get('zip'));
$supplier->contact = e(Input::get('contact'));
$supplier->phone = e(Input::get('phone'));
$supplier->fax = e(Input::get('fax'));
$supplier->email = e(Input::get('email'));
$supplier->url = $supplier->addhttp(e(Input::get('url')));
$supplier->notes = e(Input::get('notes'));
$supplier->name = request('name');
$supplier->address = request('address');
$supplier->address2 = request('address2');
$supplier->city = request('city');
$supplier->state = request('state');
$supplier->country = request('country');
$supplier->zip = request('zip');
$supplier->contact = request('contact');
$supplier->phone = request('phone');
$supplier->fax = request('fax');
$supplier->email = request('email');
$supplier->url = $supplier->addhttp(request('url'));
$supplier->notes = request('notes');
if (Input::file('image')) {
$image = Input::file('image');
$image = $request->file('image');
$file_name = str_random(25).".".$image->getClientOriginalExtension();
$path = public_path('uploads/suppliers/'.$file_name);
Image::make($image->getRealPath())->resize(300, null, function ($constraint) {
@@ -175,12 +170,12 @@ class SuppliersController extends Controller
$supplier->image = $file_name;
}
if (Input::get('image_delete') == 1 && Input::file('image') == "") {
if (request('image_delete') == 1 && $request->file('image') == "") {
$supplier->image = null;
}
if ($supplier->save()) {
return redirect()->to("admin/settings/suppliers")->with('success', trans('admin/suppliers/message.update.success'));
return redirect()->route('suppliers.index')->with('success', trans('admin/suppliers/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($supplier->getErrors());
@@ -191,107 +186,49 @@ class SuppliersController extends Controller
* Delete the given supplier.
*
* @param int $supplierId
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
*/
public function getDelete($supplierId)
public function destroy($supplierId)
{
// Check if the supplier exists
if (is_null($supplier = Supplier::find($supplierId))) {
// Redirect to the suppliers page
return redirect()->to('admin/settings/suppliers')->with('error', trans('admin/suppliers/message.not_found'));
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.not_found'));
}
if ($supplier->num_assets() > 0) {
// Redirect to the asset management page
return redirect()->to('admin/settings/suppliers')->with('error', trans('admin/suppliers/message.assoc_users'));
} else {
if ($supplier->num_assets() == 0) {
// Delete the supplier
$supplier->delete();
// Redirect to the suppliers management page
return redirect()->to('admin/settings/suppliers')->with('success', trans('admin/suppliers/message.delete.success'));
return redirect()->route('suppliers.index')->with(
'success',
trans('admin/suppliers/message.delete.success')
);
}
// Redirect to the asset management page
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.assoc_users'));
}
/**
* Get the asset information to present to the supplier view page
*
* @param int $assetId
* @return View
**/
public function getView($supplierId = null)
* Get the asset information to present to the supplier view page
*
* @param null $supplierId
* @return \Illuminate\Contracts\View\View
* @internal param int $assetId
*/
public function show($supplierId = null)
{
$supplier = Supplier::find($supplierId);
if (isset($supplier->id)) {
return View::make('suppliers/view', compact('supplier'));
} else {
// Prepare the error message
$error = trans('admin/suppliers/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('suppliers')->with('error', $error);
}
// Prepare the error message
$error = trans('admin/suppliers/message.does_not_exist', compact('id'));
// Redirect to the user management page
return redirect()->route('suppliers')->with('error', $error);
}
public function getDatatable()
{
$suppliers = Supplier::with('assets', 'licenses')->select(array('id','name','address','address2','city','state','country','fax', 'phone','email','contact'))
->whereNull('deleted_at');
if (Input::has('search')) {
$suppliers = $suppliers->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 = ['id','name','address','phone','contact','fax','email'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'created_at';
$suppliers->orderBy($sort, $order);
$suppliersCount = $suppliers->count();
$suppliers = $suppliers->skip($offset)->take($limit)->get();
$rows = array();
foreach ($suppliers as $supplier) {
$actions = '<a href="'.route('update/supplier', $supplier->id).'" class="btn btn-warning btn-sm" style="margin-right:5px;"><i class="fa fa-pencil icon-white"></i></a><a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="'.route('delete/supplier', $supplier->id).'" data-content="'.trans('admin/suppliers/message.delete.confirm').'" data-title="'.trans('general.delete').' '.htmlspecialchars($supplier->name).'?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a>';
$rows[] = array(
'id' => $supplier->id,
'name' => (string)link_to('admin/settings/suppliers/'.$supplier->id.'/view', e($supplier->name)),
'contact' => e($supplier->contact),
'address' => e($supplier->address).' '.e($supplier->address2).' '.e($supplier->city).' '.e($supplier->state).' '.e($supplier->country),
'phone' => e($supplier->phone),
'fax' => e($supplier->fax),
'email' => ($supplier->email!='') ? '<a href="mailto:'.e($supplier->email).'">'.e($supplier->email).'</a>' : '',
'assets' => $supplier->assets->count(),
'licenses' => $supplier->licenses->count(),
'actions' => $actions
);
}
$data = array('total' => $suppliersCount, 'rows' => $rows);
return $data;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,6 @@ class ViewAssetsController extends Controller
{
$user = User::with(
'assets',
'assets.model',
'consumables',
'accessories',
@@ -69,7 +68,7 @@ class ViewAssetsController extends Controller
public function getRequestableIndex()
{
$assets = Asset::with('model', 'defaultLoc', 'assetloc', 'assigneduser')->Hardware()->RequestableAssets()->get();
$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'));
@@ -103,16 +102,16 @@ class ViewAssetsController extends Controller
$logaction->target_id = $data['user_id'] = Auth::user()->id;
$logaction->target_type = User::class;
$data['requested_by'] = $user->fullName();
$data['requested_by'] = $user->present()->fullName();
$data['item_name'] = $item->name;
$data['item_type'] = $itemType;
if ($fullItemType == Asset::class) {
$data['item_url'] = route('view/hardware', $item->id);
$slackMessage = ' Asset <'.config('app.url').'/hardware/'.$item->id.'/view'.'|'.$item->showAssetName().'> requested by <'.config('app.url').'/users/'.$item->user_id.'/view'.'|'.$user->fullName().'>.';
$data['item_url'] = route('hardware.show', $item->id);
$slackMessage = ' Asset <'.url('/').'/hardware/'.$item->id.'/view'.'|'.$item->present()->name().'> requested by <'.url('/').'/users/'.$item->user_id.'/view'.'|'.$user->present()->fullName().'>.';
} else {
$data['item_url'] = route("view/${itemType}", $item->id);
$slackMessage = $quantity. ' ' . class_basename(strtoupper($logaction->item_type)).' <'.$data['item_url'].'|'.$item->name.'> requested by <'.config('app.url').'/user/'.$item->id.'/view'.'|'.$user->fullName().'>.';
$slackMessage = $quantity. ' ' . class_basename(strtoupper($logaction->item_type)).' <'.$data['item_url'].'|'.$item->name.'> requested by <'.url('/').'/user/'.$item->id.'/view'.'|'.$user->present()->fullName().'>.';
}
$settings = Setting::getSettings();
@@ -226,8 +225,8 @@ class ViewAssetsController extends Controller
$logaction->target_type = User::class;
$log = $logaction->logaction('requested');
$data['requested_by'] = $user->fullName();
$data['asset_name'] = $asset->showAssetName();
$data['requested_by'] = $user->present()->fullName();
$data['asset_name'] = $asset->present()->name();
$settings = Setting::getSettings();
@@ -259,7 +258,7 @@ class ViewAssetsController extends Controller
'fields' => [
[
'title' => 'REQUESTED:',
'value' => class_basename(strtoupper($logaction->item_type)).' asset <'.config('app.url').'/hardware/'.$asset->id.'/view'.'|'.$asset->showAssetName().'> requested by <'.config('app.url').'/hardware/'.$asset->id.'/view'.'|'.Auth::user()->fullName().'>.'
'value' => class_basename(strtoupper($logaction->item_type)).' asset <'.url('/').'/hardware/'.$asset->id.'/view'.'|'.$asset->present()->name().'> requested by <'.url('/').'/hardware/'.$asset->id.'/view'.'|'.Auth::user()->present()->fullName().'>.'
]
]
@@ -315,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::make('account/accept-asset', compact('item'))->with('findlog', $findlog)->with('item', $item);
}
}

View File

@@ -14,7 +14,7 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middleware = [
\MisterPhilip\MaintenanceMode\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\FrameGuard::class,
@@ -37,10 +37,12 @@ class Kernel extends HttpKernel
\App\Http\Middleware\VerifyCsrfToken::class,
\App\Http\Middleware\CheckLocale::class,
\App\Http\Middleware\CheckForTwoFactor::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
'throttle:60,1',
'auth:api',
],
];
@@ -52,9 +54,10 @@ class Kernel extends HttpKernel
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'authorize' => \App\Http\Middleware\CheckPermissions::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];

View File

@@ -19,7 +19,7 @@ class CheckForDebug
view()->share('debug_in_production', false);
if (((Auth::check() && (Auth::user()->isSuperUser()))) && (app()->environment()=='production') && (config('app.warn_debug')===true) && (config('app.debug')===true)) {
view()->share('debug_in_production', true);
view()->share('debug_in_production', true);
}
return $next($request);

View File

@@ -22,14 +22,14 @@ class CheckForSetup
if (Setting::setupCompleted()) {
if ($request->is('setup*')) {
return redirect(config('app.url'));
return redirect(url('/'));
} else {
return $next($request);
}
} else {
if (!($request->is('setup*')) && !($request->is('.env'))) {
return redirect(config('app.url').'/setup')->with('Request', $request);
return redirect(url('/').'/setup')->with('Request', $request);
}
return $next($request);

View File

@@ -24,7 +24,9 @@ class AssetCheckoutRequest extends Request
public function rules()
{
return [
"assigned_to" => 'required',
"assigned_user" => 'required_without_all:assigned_asset,assigned_location',
"assigned_asset" => 'required_without_all:assigned_user,assigned_location',
"assigned_location" => 'required_without_all:assigned_user,assigned_asset',
];
}
}

View File

@@ -26,19 +26,21 @@ class AssetRequest extends Request
public function rules()
{
$rules = [
'name' => 'min:2|max:255',
'model_id' => 'required|integer',
'status_id' => 'required|integer',
'company_id' => 'integer',
'warranty_months' => 'integer|min:0|max:240',
'physical' => 'integer',
'checkout_date' => 'date',
'checkin_date' => 'date',
'supplier_id' => 'integer',
'status' => 'integer',
'asset_tag' => 'required',
'purchase_cost' => 'numeric',
'name' => 'max:255|nullable',
'model_id' => 'required|integer|exists:models,id',
'status_id' => 'required|integer|exists:status_labels,id',
'company_id' => 'integer|nullable',
'warranty_months' => 'numeric|nullable',
'physical' => 'integer|nullable',
'checkout_date' => 'date',
'checkin_date' => 'date',
'supplier_id' => 'integer|nullable',
'status' => 'integer|nullable',
'asset_tag' => 'required',
'purchase_cost' => 'numeric|nullable',
"assigned_user" => 'sometimes:required_without_all:assigned_asset,assigned_location',
"assigned_asset" => 'sometimes:required_without_all:assigned_user,assigned_location',
"assigned_location" => 'sometimes:required_without_all:assigned_user,assigned_asset',
];
$model = AssetModel::find($this->request->get('model_id'));

View File

@@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class ImageUploadRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'image' => 'mimes:png,gif,jpg,jpeg,svg|max:2000'
];
}
public function response(array $errors)
{
return $this->redirector->back()->withInput()->withErrors($errors, $this->errorBag);
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace App\Http\Requests;
use App\Models\Import;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class ItemImportRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
public function import(Import $import)
{
$filename = config('app.private_uploads') . '/imports/' . $import->file_path;
$class = title_case($this->input('import-type'));
$classString = "App\\Importer\\{$class}Importer";
$importer = new $classString($filename);
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
->setUserId(Auth::id())
->setUpdating($this->has('import-update'))
->setUsernameFormat('firstname.lastname');
$importer->import();
return $this->errors;
}
public function log($string)
{
return; // FUTURE IMPLEMENTATION
}
public function progress($count)
{
// Open for future
return;
}
public function errorCallback($item, $field, $errorString)
{
$this->errors[$item->name][$field] = $errorString;
// $this->errors[$item->name] = $errorString;
}
private $errors;
}

View File

@@ -1,6 +1,7 @@
<?php
namespace App\Http\Requests;
use App\Helpers\Helper;
use Illuminate\Foundation\Http\FormRequest;
@@ -13,9 +14,15 @@ abstract class Request extends FormRequest
return $this->rules;
}
// public function response(array $errors)
// {
// $this->session->flash('errorMessages', $errors);
// return $this->redirector->back()->withErrors($errors)->withInput();
// }
public function response(array $errors)
{
if ($this->ajax() || $this->wantsJson())
{
return Helper::formatStandardApiResponse('error', null, $errors);
}
return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}
}

View File

@@ -0,0 +1,74 @@
<?php
namespace App\Http\Transformers;
use App\Models\Accessory;
use Gate;
use Illuminate\Database\Eloquent\Collection;
use App\Helpers\Helper;
class AccessoriesTransformer
{
public function transformAccessories (Collection $accessories, $total)
{
$array = array();
foreach ($accessories as $accessory) {
$array[] = self::transformAccessory($accessory);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformAccessory (Accessory $accessory)
{
$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)] : '',
'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)] : '',
'notes' => ($accessory->notes) ? e($accessory->notes) : null,
'qty' => ($accessory->qty) ? e($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,
'remaining_qty' => $accessory->numRemaining(),
'created_at' => Helper::getFormattedDateObject($accessory->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($accessory->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', Accessory::class) ? true : false,
'checkin' => false,
'update' => Gate::allows('update', Accessory::class) ? true : false,
'delete' => Gate::allows('delete', Accessory::class) ? true : false,
];
$permissions_array['user_can_checkout'] = false;
if ($accessory->numRemaining() > 0) {
$permissions_array['user_can_checkout'] = true;
}
$array += $permissions_array;
return $array;
}
public function transformCheckedoutAccessories (Collection $accessories_users, $total)
{
$array = array();
foreach ($accessories_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace App\Http\Transformers;
use App\Models\AssetModel;
use Illuminate\Database\Eloquent\Collection;
use Gate;
class AssetModelsTransformer
{
public function transformAssetModels (Collection $assetmodels, $total)
{
$array = array();
foreach ($assetmodels as $assetmodel) {
$array[] = self::transformAssetModel($assetmodel);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformAssetModel (AssetModel $assetmodel)
{
$array = [
'id' => $assetmodel->id,
'name' => e($assetmodel->name),
'manufacturer' => ($assetmodel->manufacturer_id) ? $assetmodel->manufacturer : null,
'image' => ($assetmodel->image!='') ? url('/').'/uploads/models/'.e($assetmodel->image) : '',
'model_number' => e($assetmodel->model_number),
'depreciation' => ($assetmodel->depreciation) ? $assetmodel->depreciation : 'No',
'assets_count' => $assetmodel->assets_count,
'category' => ($assetmodel->category_id) ? $assetmodel->category : null,
'fieldset' => ($assetmodel->fieldset) ? $assetmodel->fieldset : null,
'eol' => ($assetmodel->eol > 0) ? $assetmodel->eol .' months': 'None',
'notes' => e($assetmodel->notes)
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('admin') ? true : false,
'delete' => Gate::allows('admin') ? true : false,
];
$array += $permissions_array;
return $array;
}
public function transformAssetModelsDatatable($assetmodels) {
return (new DatatablesTransformer)->transformDatatables($assetmodels);
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace App\Http\Transformers;
use App\Models\Asset;
use Illuminate\Database\Eloquent\Collection;
use App\Http\Transformers\UsersTransformer;
use Gate;
use App\Helpers\Helper;
class AssetsTransformer
{
public function transformAssets(Collection $assets, $total)
{
$array = array();
foreach ($assets as $asset) {
$array[] = self::transformAsset($asset);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformAsset(Asset $asset)
{
$array = [
'id' => (int) $asset->id,
'name' => e($asset->name),
'asset_tag' => e($asset->asset_tag),
'serial' => e($asset->serial),
'model' => ($asset->model) ? [
'id' => (int) $asset->model->id,
'name'=> e($asset->model->name)
] : null,
'model_number' => ($asset->model) ? e($asset->model->model_number) : null,
'status_label' => ($asset->assetstatus) ? [
'id' => (int) $asset->assetstatus->id,
'name'=> e($asset->assetstatus->name)
] : null,
'category' => ($asset->model->category) ? [
'id' => (int) $asset->model->category->id,
'name'=> e($asset->model->category->name)
] : null,
'manufacturer' => ($asset->model->manufacturer) ? [
'id' => (int) $asset->model->manufacturer->id,
'name'=> e($asset->model->manufacturer->name)
] : null,
'notes' => e($asset->notes),
'order_number' => e($asset->order_number),
'company' => ($asset->company) ? [
'id' => (int) $asset->company->id,
'name'=> e($asset->company->name)
] : null,
'location' => ($asset->assetLoc) ? [
'id' => (int) $asset->assetLoc->id,
'name'=> e($asset->assetLoc->name)
] : null,
'rtd_location' => ($asset->defaultLoc) ? [
'id' => (int) $asset->defaultLoc->id,
'name'=> e($asset->defaultLoc->name)
] : null,
'image' => ($asset->getImageUrl()) ? $asset->getImageUrl() : null,
'assigned_to' => ($asset->assigneduser) ? [
'id' => (int) $asset->assigneduser->id,
'name' => e($asset->assigneduser->getFullNameAttribute()),
'first_name'=> e($asset->assigneduser->first_name),
'last_name'=> e($asset->assigneduser->last_name)
] : 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,
'created_at' => Helper::getFormattedDateObject($asset->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($asset->updated_at, 'datetime'),
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
'expected_checkin' => Helper::getFormattedDateObject($asset->expected_checkin, 'date'),
'purchase_cost' => Helper::formatCurrencyOutput($asset->purchase_cost),
'user_can_checkout' => (bool) $asset->availableForCheckout(),
];
$permissions_array['available_actions'] = [
'checkout' => (bool) Gate::allows('checkout', Asset::class),
'checkin' => (bool) Gate::allows('checkin', Asset::class),
'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;
}
public function transformAssetsDatatable($assets)
{
return (new DatatablesTransformer)->transformDatatables($assets);
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Http\Transformers;
use App\Models\Category;
use Illuminate\Database\Eloquent\Collection;
use Gate;
class CategoriesTransformer
{
public function transformCategories (Collection $categorys, $total)
{
$array = array();
foreach ($categorys as $category) {
$array[] = self::transformCategory($category);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformCategory (Category $category = null)
{
if ($category) {
$array = [
'id' => e($category->id),
'name' => e($category->name),
'type' => e($category->category_type),
'use_default_eula' => ($category->use_default_eula =='1') ? true : false,
'require_acceptance' => ($category->require_acceptance =='1') ? true : false,
'assets_count' => $category->assets_count,
'accessories_count' => $category->accessories_count,
'consumables_count' => $category->consumables_count,
'components_count' => $category->components_count,
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Category::class) ? true : false,
'delete' => Gate::allows('delete', Category::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace App\Http\Transformers;
use App\Models\Asset;
use Illuminate\Database\Eloquent\Collection;
use App\Http\Transformers\UsersTransformer;
use Gate;
class ComponentsAssetsTransformer
{
public function transformAssets (Collection $assets, $total)
{
$array = array();
foreach ($assets as $asset) {
$array[] = self::transformAsset($asset);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformAsset (Asset $asset)
{
$array = [
'id' => $asset->id,
'name' => e($asset->name),
'created_at' => $asset->created_at->format('Y-m-d'),
'qty' => $asset->components()->count(),
'user_can_checkout' => $asset->availableForCheckout(),
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', Asset::class) ? true : false,
'checkin' => Gate::allows('checkin', Asset::class) ? true : false,
'update' => Gate::allows('update', Asset::class) ? true : false,
'delete' => Gate::allows('delete', Asset::class) ? true : false,
];
$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;
}
public function transformAssetsDatatable ($assets) {
return (new DatatablesTransformer)->transformDatatables($assets);
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace App\Http\Transformers;
use App\Models\Component;
use Illuminate\Database\Eloquent\Collection;
use App\Helpers\Helper;
use Gate;
class ComponentsTransformer
{
public function transformComponents(Collection $components, $total)
{
$array = array();
foreach ($components as $component) {
$array[] = self::transformComponent($component);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformComponent(Component $component)
{
$array = [
'id' => (int) $component->id,
'name' => e($component->name),
'serial_number' => e($component->serial),
'location' => ($component->location) ? [
'id' => (int) $component->location->id,
'name' => e($component->location->name)
] : null,
'qty' => number_format($component->qty),
'min_amt' => e($component->min_amt),
'category' => ($component->category) ? [
'id' => (int) $component->category->id,
'name' => e($component->category->name)
] : null,
'order_number' => e($component->order_number),
'purchase_date' => Helper::getFormattedDateObject($component->purchase_date, 'date'),
'purchase_cost' => Helper::formatCurrencyOutput($component->purchase_cost),
'remaining' => (int) $component->numRemaining(),
'company' => ($component->company) ? [
'id' => (int) $component->company->id,
'name' => e($component->company->name)
] : null,
'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'checkout' => (bool) Gate::allows('checkout', Component::class),
'checkin' => (bool) Gate::allows('checkin', Component::class),
'update' => (bool) Gate::allows('update', Component::class),
'delete' => (bool) Gate::allows('delete', Component::class),
];
$array += $permissions_array;
return $array;
}
public function transformCheckedoutComponents(Collection $components_users, $total)
{
$array = array();
foreach ($components_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace App\Http\Transformers;
use App\Models\Consumable;
use Illuminate\Database\Eloquent\Collection;
use App\Helpers\Helper;
use Gate;
class ConsumablesTransformer
{
public function transformConsumables (Collection $consumables, $total)
{
$array = array();
foreach ($consumables as $consumable) {
$array[] = self::transformConsumable($consumable);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
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,
'remaining' => $consumable->numRemaining(),
'order_number' => $consumable->order_number,
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
'purchase_date' => Helper::getFormattedDateObject($consumable->purchase_date, 'date'),
'qty' => $consumable->qty,
'created_at' => Helper::getFormattedDateObject($consumable->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($consumable->updated_at, 'datetime'),
];
$permissions_array['user_can_checkout'] = false;
if ($consumable->numRemaining() > 0) {
$permissions_array['user_can_checkout'] = true;
}
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', Consumable::class) ? true : false,
'checkin' => Gate::allows('checkin', Consumable::class) ? true : false,
'update' => Gate::allows('update', Consumable::class) ? true : false,
'delete' => Gate::allows('delete', Consumable::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
public function transformCheckedoutConsumables (Collection $consumables_users, $total)
{
$array = array();
foreach ($consumables_users as $user) {
$array[] = (new UsersTransformer)->transformUser($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace App\Http\Transformers;
use App\Models\Location;
class DatatablesTransformer
{
public function transformDatatables($objects, $total = null)
{
(isset($total)) ? $objects_array['total'] = $total : $objects_array['total'] = count($objects);
$objects_array['rows'] = $objects;
return $objects_array;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Http\Transformers;
use App\Models\Depreciation;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class DepreciationsTransformer
{
public function transformDepreciations (Collection $depreciations)
{
$array = array();
foreach ($depreciations as $depreciation) {
$array[] = self::transformDepreciation($depreciation);
}
return (new DatatablesTransformer)->transformDatatables($array);
}
public function transformDepreciation (Depreciation $depreciation)
{
$array = [
'id' => e($depreciation->id),
'name' => e($depreciation->name),
'months' => $depreciation->months . ' '. trans('general.months'),
'created_at' => Helper::getFormattedDateObject($depreciation->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($depreciation->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Depreciation::class) ? true : false,
'delete' => Gate::allows('delete', Depreciation::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Http\Transformers;
use App\Models\Group;
use Illuminate\Database\Eloquent\Collection;
use Gate;
class GroupsTransformer
{
public function transformGroups (Collection $groups)
{
$array = array();
foreach ($groups as $group) {
$array[] = self::transformGroup($group);
}
return (new DatatablesTransformer)->transformDatatables($array);
}
public function transformGroup (Group $group)
{
$array = [
'id' => e($group->id),
'name' => e($group->name),
'permissions' => $group->permissions,
'users_count' => $group->users_count,
'created_at' => Helper::getFormattedDateObject($group->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($group->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('superadmin') ? true : false,
'delete' => Gate::allows('superadmin') ? true : false,
];
$array += $permissions_array;
return $array;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Http\Transformers;
use App\Models\Import;
use App\Models\Setting;
use Illuminate\Database\Eloquent\Collection;
class ImportsTransformer
{
public function transformImports($imports)
{
$array = array();
foreach ($imports as $import) {
$array[] = self::transformImport($import);
}
return $array;
}
public function transformImport(Import $import)
{
$array = [
'id' => $import->id,
'file_path' => $import->file_path,
'filesize' => Setting::fileSizeConvert($import->filesize),
'name' => $import->name,
'import_type' => $import->import_type,
'created_at' => $import->created_at->diffForHumans(),
];
return $array;
}
public function transformImportsDatatable($imports)
{
return (new DatatablesTransformer)->transformDatatables($imports);
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace App\Http\Transformers;
use App\Models\License;
use Gate;
use Illuminate\Database\Eloquent\Collection;
use App\Helpers\Helper;
class LicensesTransformer
{
public function transformLicenses (Collection $licenses, $total)
{
$array = array();
foreach ($licenses as $license) {
$array[] = self::transformLicense($license);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformLicense (License $license)
{
$array = [
'id' => $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,
'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,
'notes' => e($license->notes),
'expiration_date' => Helper::getFormattedDateObject($license->expiration_date, 'date'),
'total_seats' => e($license->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,
'created_at' => Helper::getFormattedDateObject($license->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'checkout' => Gate::allows('checkout', License::class) ? true : false,
'checkin' => Gate::allows('checkin', License::class) ? true : false,
'update' => Gate::allows('update', License::class) ? true : false,
'delete' => Gate::allows('delete', License::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
public function transformAssetsDatatable($licenses) {
return (new DatatablesTransformer)->transformDatatables($licenses);
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace App\Http\Transformers;
use App\Models\Location;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class LocationsTransformer
{
public function transformLocations (Collection $locations, $total)
{
$array = array();
foreach ($locations as $location) {
$array[] = self::transformLocation($location);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformLocation (Location $location = null)
{
if ($location) {
$assets_arr = [];
foreach($location->assets() as $asset) {
$assets_arr = ['id' => $asset->id];
}
$array = [
'id' => e($location->id),
'name' => e($location->name),
'address' => e($location->address),
'city' => e($location->city),
'state' => e($location->state),
'assets_checkedout' => $location->assets()->count(),
'assets_default' => $location->assignedassets()->count(),
'country' => e($location->country),
'assets' => $assets_arr,
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Location::class) ? true : false,
'delete' => Gate::allows('delete', Location::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Http\Transformers;
use App\Models\Manufacturer;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class ManufacturersTransformer
{
public function transformManufacturers (Collection $manufacturers, $total)
{
$array = array();
foreach ($manufacturers as $manufacturer) {
$array[] = self::transformManufacturer($manufacturer);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformManufacturer (Manufacturer $manufacturer = null)
{
if ($manufacturer) {
$array = [
'id' => e($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),
'created_at' => Helper::getFormattedDateObject($manufacturer->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($manufacturer->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Manufacturer::class) ? true : false,
'delete' => Gate::allows('delete', Manufacturer::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Http\Transformers;
use App\Models\Statuslabel;
use Illuminate\Database\Eloquent\Collection;
use Gate;
use App\Helpers\Helper;
class StatuslabelsTransformer
{
public function transformStatuslabels (Collection $statuslabels)
{
$array = array();
foreach ($statuslabels as $statuslabel) {
$array[] = self::transformStatuslabel($statuslabel);
}
return (new DatatablesTransformer)->transformDatatables($array);
}
public function transformStatuslabel (Statuslabel $statuslabel)
{
$array = [
'id' => e($statuslabel->id),
'name' => e($statuslabel->name),
'type' => $statuslabel->getStatuslabelType(),
'color' => ($statuslabel->color) ? e($statuslabel->color) : null,
'show_in_nav' => ($statuslabel->show_in_nav=='1') ? true : false,
'notes' => e($statuslabel->notes),
'created_at' => Helper::getFormattedDateObject($statuslabel->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($statuslabel->updated_at, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Statuslabel::class) ? true : false,
'delete' => Gate::allows('delete', Statuslabel::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace App\Http\Transformers;
use App\Models\User;
use Illuminate\Database\Eloquent\Collection;
use phpDocumentor\Reflection\Types\Integer;
use Gate;
use App\Helpers\Helper;
class UsersTransformer
{
public function transformUsers (Collection $users, $total)
{
$array = array();
foreach ($users as $user) {
$array[] = self::transformUser($user);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformUser (User $user)
{
$array = [
'id' => e($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),
'email' => e($user->email),
'location' => (new LocationsTransformer)->transformLocation($user->userloc),
'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,
'created_at' => Helper::getFormattedDateObject($user->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($user->updated_at, 'datetime'),
'last_login' => Helper::getFormattedDateObject($user->last_login, 'datetime'),
];
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', User::class) ? true : false,
'delete' => Gate::allows('delete', User::class) ? true : false,
];
$array += $permissions_array;
return $array;
}
public function transformUsersDatatable($users) {
return (new DatatablesTransformer)->transformDatatables($users);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Importer;
use App\Helpers\Helper;
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)
{
parent::handle($row); // TODO: Change the autogenerated stub
$this->createAccessoryIfNotExists();
}
/**
* Create an accessory if a duplicate does not exist
*
* @author Daniel Melzter
* @since 3.0
*/
public function createAccessoryIfNotExists()
{
$accessoryId = $this->accessories->search(function ($key) {
return strcasecmp($key->name, $this->item['name']) == 0;
});
if ($accessoryId !== false) {
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();
}
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');
}
$this->jsonError($accessory, 'Accessory');
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace App\Importer;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Category;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
class AssetImporter extends ItemImporter
{
protected $defaultStatusLabelId;
public function __construct($filename)
{
parent::__construct($filename);
$this->defaultStatusLabelId = Statuslabel::first()->id;
}
protected function handle($row)
{
// ItemImporter handles the general fetching.
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));
}
}
$this->createAssetIfNotExists($row);
}
/**
* Create the asset if it does not exist.
*
* @author Daniel Melzter
* @since 3.0
* @param array $row
* @return Asset|mixed|null
*/
public function createAssetIfNotExists(array $row)
{
$editingAsset = false;
$asset = Asset::where(['asset_tag'=> $this->item['asset_tag']])->first();
if ($asset) {
if (!$this->updating) {
$this->log('A matching Asset ' . $this->item['asset_tag'] . ' already exists');
return;
}
$this->log("Updating Asset");
$editingAsset = true;
} else {
$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->log("No status field found, defaulting to first status.");
$this->item['status_id'] = $this->defaultStatusLabelId;
}
// By default we're set this to location_id in the item.
$item = $this->sanitizeItemForStoring($asset, $editingAsset);
if (isset($this->item["location"])) {
$item['rtd_location_id'] = $this->item['location_id'];
unset($item['location_id']);
}
if ($editingAsset) {
$asset->update($item);
} else {
$asset->fill($item);
}
if (array_key_exists('custom_fields', $this->item)) {
foreach ($this->item['custom_fields'] as $custom_field => $val) {
$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'].'"');
}
}
}

View File

@@ -0,0 +1,80 @@
<?php
namespace App\Importer;
use App\Models\Asset;
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)
{
parent::handle($row);
$this->createComponentIfNotExists();
}
/**
* Create a component if a duplicate does not exist
*
* @author Daniel Melzter
* @since 3.0
*/
public function createComponentIfNotExists()
{
$component = null;
$editingComponent = false;
$this->log("Creating Component");
$componentId = $this->components->search(function ($key) {
return strcasecmp($key->name, $this->item['name']) == 0;
});
if ($componentId !== false) {
$editingComponent = true;
$this->log('A matching Component ' . $this->item["name"] . ' already exists. ');
if (!$this->updating) {
$this->log("Skipping Component");
return;
}
$this->log("Updating Component");
$component = $this->components[$componentId];
$component->update($this->sanitizeItemFor($component));
if (!$this->testRun) {
$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');
// If we have an asset tag, checkout to that asset.
if (isset($this->item['asset_tag']) && ($asset = Asset::where('asset_tag', $this->item['asset_tag'])->first())) {
$component->assets()->attach($component->id, [
'component_id' => $component->id,
'user_id' => $this->user_id,
'created_at' => date('Y-m-d H:i:s'),
'assigned_qty' => 1, // Only assign the first one to the asset
'asset_id' => $asset->id
]);
}
return;
}
$this->jsonError($component, 'Component');
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace App\Importer;
use App\Helpers\Helper;
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)
{
parent::handle($row); // TODO: Change the autogenerated stub
$this->createConsumableIfNotExists();
}
/**
* Create a consumable if a duplicate does not exist
*
* @author Daniel Melzter
* @since 3.0
*/
public function createConsumableIfNotExists()
{
$consumableId = $this->consumables->search(function ($key) {
return strcasecmp($key->name, $this->item['name']) == 0;
});
if ($consumableId !== false) {
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();
}
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');
return;
}
}

312
app/Importer/Importer.php Normal file
View File

@@ -0,0 +1,312 @@
<?php
namespace App\Importer;
use App\Models\CustomField;
use App\Models\Setting;
use App\Models\User;
use ForceUTF8\Encoding;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use League\Csv\Reader;
abstract class Importer
{
/**
* @var string
*/
private $filename;
private $csv;
/**
* Should we persist to database?
* @var bool
*/
protected $testRun;
/**
* Id of User performing import
* @var
*/
protected $user_id;
/**
* Are we updating items in the import
* @var bool
*/
protected $updating;
/**
* @var callable
*/
protected $logCallback;
protected $tempPassword;
/**
* @var callable
*/
protected $progressCallback;
/**
* @var null
*/
protected $usernameFormat;
/**
* @var callable
*/
protected $errorCallback;
/**
* ObjectImporter constructor.
* @param string $filename
*/
public function __construct(string $filename)
{
$this->filename = $filename;
$this->csv = Reader::createFromPath($filename);
$this->csv->setNewLine('\r\n');
if (! ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1');
}
$this->tempPassword = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
}
// Cached Values for import lookups
protected $customFields;
public function import()
{
$results = $this->normalizeInputArray($this->csv->fetchAssoc());
$this->customFields = CustomField::All(['name']);
DB::transaction(function () use (&$results) {
Model::unguard();
$resultsCount = sizeof($results);
foreach ($results as $row) {
$this->handle($row);
call_user_func($this->progressCallback, $resultsCount);
$this->log('------------- Action Summary ----------------');
}
});
}
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
*
* @author Daniel Melzter
* @since 3.0
* @param $array array
* @param $key string
* @param $default string
* @return string
*/
public function array_smart_fetch(array $array, $key, $default = '')
{
$val = $default;
if (array_key_exists(trim($key), $array)) {
$val = e(Encoding::toUTF8(trim($array[ $key ])));
}
$key = title_case($key);
// $this->log("${key}: ${val}");
return $val;
}
/**
* Figure out the fieldname of the custom field
*
* @author A. Gianotto <snipe@snipe.net>
* @since 3.0
* @param $array array
* @return string
*/
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])) : '';
}
protected function log($string)
{
call_user_func($this->logCallback, $string);
}
protected function jsonError($item, $field)
{
call_user_func($this->errorCallback, $item, $field, $item->getErrors());
}
/**
* Finds the user matching given data, or creates a new one if there is no match
*
* @author Daniel Melzter
* @since 3.0
* @param $row array
* @return User Model w/ matching name
* @internal param string $user_username Username extracted from CSV
* @internal param string $user_email Email extracted from CSV
* @internal param string $first_name
* @internal param string $last_name
*/
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");
$first_name = '';
$last_name = '';
// A number was given instead of a name
if (is_numeric($user_name)) {
$this->log('User '.$user_name.' is not a name - assume this user already exists');
$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 {
$user_email_array = User::generateFormattedNameFromFullName(Setting::getSettings()->email_format, $user_name);
$first_name = $user_email_array['first_name'];
$last_name = $user_email_array['last_name'];
if ($user_email=='') {
if (Setting::getSettings()->email_domain) {
$user_email = str_slug($user_email_array['username']).'@'.Setting::getSettings()->email_domain;
}
}
if ($user_username=='') {
if ($this->usernameFormat =='email') {
$user_username = $user_email;
} else {
$user_name_array = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format, $user_name);
$user_username = $user_name_array['username'];
}
}
}
$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');
} elseif (( $first_name != '') && ($last_name != '') && ($user_username != '')) {
$user = new User;
$user->first_name = $first_name;
$user->last_name = $last_name;
$user->username = $user_username;
$user->email = $user_email;
$user->activated = 1;
$user->password = $this->tempPassword;
if ($user->save()) {
$this->log('User '.$first_name.' created');
} else {
$this->jsonError($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.
*
* @param mixed $user_id the user id
*
* @return self
*/
public function setUserId($user_id)
{
$this->user_id = $user_id;
return $this;
}
/**
* Sets the Are we updating items in the import.
*
* @param bool $updating the updating
*
* @return self
*/
public function setUpdating($updating)
{
$this->updating = $updating;
return $this;
}
/**
* Sets the callbacks for the import
*
* @param callable $logCallback Function to call when we have data to log
* @param callable $progressCallback Function to call to display progress
* @param callable $errorCallback Function to call when we have errors
*
* @return self
*/
public function setCallbacks(callable $logCallback, callable $progressCallback, callable $errorCallback)
{
$this->logCallback = $logCallback;
$this->progressCallback = $progressCallback;
$this->errorCallback = $errorCallback;
return $this;
}
/**
* Sets the value of usernameFormat.
*
* @param string $usernameFormat the username format
*
* @return self
*/
public function setUsernameFormat($usernameFormat)
{
$this->usernameFormat = $usernameFormat;
return $this;
}
}

View File

@@ -0,0 +1,425 @@
<?php
namespace App\Importer;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
use App\Models\Location;
use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
class ItemImporter extends Importer
{
protected $item;
public function __construct($filename)
{
parent::__construct($filename);
}
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;
}
}
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;
}
}
if ($this->shouldUpdateField($item_company_name)) {
if ($this->item["company"] = $this->createOrFetchCompany($item_company_name)) {
$this->item["company_id"] = $this->item["company"]->id;
}
}
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;
}
}
if ($this->shouldUpdateField($item_supplier)) {
if ($this->item['supplier'] = $this->createOrFetchSupplier($item_supplier)) {
$this->item['supplier_id'] = $this->item['supplier']->id;
}
}
}
/**
* Cleanup the $item array before storing.
* We need to remove any values that are not part of the fillable fields.
* Also, if updating, we remove any fields from the array that are empty.
*
* @author Daniel Melzter
* @since 4.0
* @param $model SnipeModel Model that's being updated.
* @param $updating boolean Should we remove blank values?
* @return array
*/
protected function sanitizeItemForStoring($model, $updating = false)
{
// 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) {
return empty($value);
});
}
return $item->toArray();
}
/**
* Convenience function for updating that strips the empty values.
*
*
*/
protected function sanitizeItemForUpdating($model)
{
return $this->sanitizeItemForStoring($model, true);
}
/**
* Determines if a field needs updating
* Follows the following rules:
* If we are not updating, we should update the field
* If We are updating, we only update the field if it's not empty.
*
* @author Daniel Melzter
* @since 4.0
* @param $field string
* @return boolean
*/
private function shouldUpdateField($field)
{
if (empty($field)) {
return false;
}
return !($this->updating && empty($field));
}
/**
* Select the asset model if it exists, otherwise create it.
*
* @author Daniel Melzter
* @since 3.0
* @param array
* @param $category Category
* @param $manufacturer Manufacturer
* @return AssetModel
* @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");
// 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;
}
if ((empty($asset_model_name)) && (!empty($asset_modelNumber))) {
$asset_model_name = $asset_modelNumber;
} elseif ((empty($asset_model_name)) && (empty($asset_modelNumber))) {
$asset_model_name ='Unknown';
}
$editingModel = $this->updating;
$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;
}
$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;
}
$this->log("No Matching Model, Creating a new one");
$asset_model = new AssetModel();
$item = $this->sanitizeItemForStoring($asset_model, $editingModel);
$item['name'] = $asset_model_name;
$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;
}
if ($asset_model->save()) {
$this->log('Asset Model ' . $asset_model_name . ' with model number ' . $asset_modelNumber . ' was created');
return $asset_model;
}
$this->jsonError($asset_model, 'Asset Model "' . $asset_model_name . '"');
return;
}
/**
* Finds a category with the same name and item type in the database, otherwise creates it
*
* @author Daniel Melzter
* @since 3.0
* @param $asset_category string
* @return Category
* @internal param string $item_type
*/
public function createOrFetchCategory($asset_category)
{
// 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';
}
$category = Category::where(['name' => $asset_category, 'category_type' => $item_type])->first();
if ($category) {
$this->log("A matching category: " . $asset_category . " already exists");
return $category;
}
$category = new Category();
$category->name = $asset_category;
$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;
}
$this->jsonError($category, 'Category "'. $asset_category. '"');
}
/**
* Fetch an existing company, or create new if it doesn't exist
*
* @author Daniel Melzter
* @since 3.0
* @param $asset_company_name string
* @return Company
*/
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;
}
$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;
}
$this->jsonError($company, 'Company');
return;
}
/**
* Fetch the existing status label or create new if it doesn't exist.
*
* @author Daniel Melzter
* @since 3.0
* @param string $asset_statuslabel_name
* @return Statuslabel|null
*/
public function createOrFetchStatusLabel($asset_statuslabel_name)
{
if (empty($asset_statuslabel_name)) {
return null;
}
$status = Statuslabel::where(['name' => $asset_statuslabel_name])->first();
if ($status) {
$this->log('A matching Status ' . $asset_statuslabel_name . ' already exists');
return $status;
}
$this->log("Creating a new status");
$status = new Statuslabel();
$status->name = $asset_statuslabel_name;
$status->deployable = 1;
$status->pending = 0;
$status->archived = 0;
if ($this->testRun) {
return $status;
}
if ($status->save()) {
$this->log('Status ' . $asset_statuslabel_name . ' was created');
return $status;
}
$this->jsonError($status, 'Status "'. $asset_statuslabel_name . '"');
return;
}
/**
* Finds a manufacturer with matching name, otherwise create it.
*
* @author Daniel Melzter
* @since 3.0
* @param $item_manufacturer string
* @return Manufacturer
*/
public function createOrFetchManufacturer($item_manufacturer)
{
if (empty($item_manufacturer)) {
$item_manufacturer='Unknown';
}
$manufacturer = Manufacturer::where(['name'=> $item_manufacturer])->first();
if ($manufacturer) {
$this->log('Manufacturer ' . $item_manufacturer . ' already exists') ;
return $manufacturer;
}
//Otherwise create a manufacturer.
$manufacturer = new Manufacturer();
$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;
}
$this->jsonError($manufacturer, 'Manufacturer "'. $manufacturer->name . '"');
return;
}
/**
* Checks the DB to see if a location with the same name exists, otherwise create it
*
* @author Daniel Melzter
* @since 3.0
* @param $asset_location string
* @return Location|null
*/
public function createOrFetchLocation($asset_location)
{
if (empty($asset_location)) {
$this->log('No location given, so none created.');
return null;
}
$location = Location::where(['name' => $asset_location])->first();
if ($location !== false) {
$this->log('Location ' . $asset_location . ' already exists');
return $location;
}
// No matching locations in the collection, create a new one.
$location = new Location();
$location->name = $asset_location;
$location->address = '';
$location->city = '';
$location->state = '';
$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;
}
$this->jsonError($location, 'Location');
return;
}
/**
* Fetch an existing supplier or create new if it doesn't exist
*
* @author Daniel Melzter
* @since 3.0
* @param $row array
* @return Supplier
*/
public function createOrFetchSupplier($item_supplier)
{
if (empty($item_supplier)) {
$item_supplier='Unknown';
}
$supplier = Supplier::where(['name' => $item_supplier ])->first();
if ($supplier) {
$this->log('Supplier ' . $item_supplier . ' already exists');
return $supplier;
}
$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;
}
$this->jsonError($supplier, 'Supplier');
return;
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace App\Importer;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Category;
use App\Models\License;
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);
}
/**
* Create the license if it does not exist.
*
* @author Daniel Melzter
* @since 4.0
* @param array $row
* @return License|mixed|null
*/
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) {
if (!$this->updating) {
$this->log('A matching License ' . $this->item['name'] . ' already exists');
return;
}
$this->log("Updating License");
$editingLicense = true;
$license = $this->licenses[$license_id];
} else {
$this->log("No Matching License, Creating a new one");
}
$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');
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');
// 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) {
$targetLicense->asset_id = $asset->id;
$targetLicense->save();
}
}
return;
}
$this->jsonError($license, 'License "' . $this->item['name'].'"');
}
}
}

View File

@@ -1,9 +1,7 @@
<?php
namespace App\Models;
use App\Models\Loggable;
use App\Models\SnipeModel;
use Illuminate\Database\Eloquent\Model;
use App\Presenters\Presentable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Watson\Validating\ValidatingTrait;
@@ -14,8 +12,9 @@ use Watson\Validating\ValidatingTrait;
*/
class Accessory extends SnipeModel
{
protected $presenter = 'App\Presenters\AccessoryPresenter';
use CompanyableTrait;
use Loggable;
use Loggable, Presentable;
use SoftDeletes;
protected $dates = ['deleted_at'];
@@ -27,10 +26,10 @@ class Accessory extends SnipeModel
public $rules = array(
'name' => 'required|min:3|max:255',
'qty' => 'required|integer|min:1',
'category_id' => 'required|integer',
'company_id' => 'integer',
'category_id' => 'required|integer|exists:categories,id',
'company_id' => 'integer|nullable',
'min_amt' => 'integer|min:0',
'purchase_cost' => 'numeric',
'purchase_cost' => 'numeric|nullable',
);
@@ -49,7 +48,18 @@ class Accessory extends SnipeModel
*
* @var array
*/
protected $fillable = ['name','qty','category_id'];
protected $fillable = [
'category_id',
'company_id',
'location_id',
'name',
'order_number',
'purchase_cost',
'purchase_date',
'model_number',
'qty',
'requestable'
];
public function company()
{
@@ -109,10 +119,8 @@ class Accessory extends SnipeModel
return $Parsedown->text(e($this->category->eula_text));
} elseif ((Setting::getSettings()->default_eula_text) && ($this->category->use_default_eula=='1')) {
return $Parsedown->text(e(Setting::getSettings()->default_eula_text));
} else {
return null;
}
return null;
}
public function numRemaining()
@@ -126,10 +134,10 @@ class Accessory extends SnipeModel
/**
* Query builder scope to search on text
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $search Search term
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeTextSearch($query, $search)
{
@@ -154,6 +162,7 @@ class Accessory extends SnipeModel
$query->where('locations.name', 'LIKE', '%'.$search.'%');
});
})->orWhere('accessories.name', 'LIKE', '%'.$search.'%')
->orWhere('accessories.model_number', 'LIKE', '%'.$search.'%')
->orWhere('accessories.order_number', 'LIKE', '%'.$search.'%')
->orWhere('accessories.purchase_cost', 'LIKE', '%'.$search.'%')
->orWhere('accessories.purchase_date', 'LIKE', '%'.$search.'%');
@@ -164,39 +173,55 @@ class Accessory extends SnipeModel
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCompany($query, $order)
{
return $query->leftJoin('companies', 'accessories.company_id', '=', 'companies.id')->orderBy('companies.name', $order);
return $query->leftJoin('companies', 'accessories.company_id', '=', 'companies.id')
->orderBy('companies.name', $order);
}
/**
* Query builder scope to order on company
* Query builder scope to order on category
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCategory($query, $order)
{
return $query->leftJoin('categories', 'accessories.category_id', '=', 'categories.id')->orderBy('categories.name', $order);
return $query->leftJoin('categories', 'accessories.category_id', '=', 'categories.id')
->orderBy('categories.name', $order);
}
/**
* Query builder scope to order on company
* Query builder scope to order on location
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderLocation($query, $order)
{
return $query->leftJoin('locations', 'consumables.location_id', '=', 'locations.id')->orderBy('locations.name', $order);
return $query->leftJoin('locations', 'accessories.location_id', '=', 'locations.id')
->orderBy('locations.name', $order);
}
/**
* Query builder scope to order on manufacturer
*
* @param \Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return \Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderManufacturer($query, $order)
{
return $query->leftJoin('manufacturers', 'accessories.manufacturer_id', '=', 'manufacturers.id')->orderBy('manufacturers.name', $order);
}
}

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Models;
use App\Presenters\Presentable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
@@ -12,10 +12,11 @@ use Response;
*
* @version v1.0
*/
class Actionlog extends Model
class Actionlog extends SnipeModel
{
protected $presenter = "App\Presenters\ActionlogPresenter";
use SoftDeletes;
use Presentable;
protected $dates = [ 'deleted_at' ];
protected $table = 'action_logs';
@@ -26,15 +27,15 @@ class Actionlog extends Model
public static function boot()
{
parent::boot();
static::creating( function (Actionlog $actionlog) {
static::creating(function (Actionlog $actionlog) {
// If the admin is a superadmin, let's see if the target instead has a company.
if (Auth::user() && Auth::user()->isSuperUser()) {
if ($actionlog->target) {
$actionlog->company_id = $actionlog->target->company_id;
} else if ($actionlog->item) {
} elseif ($actionlog->item) {
$actionlog->company_id = $actionlog->item->company_id;
}
} else if (Auth::user() && Auth::user()->company) {
} elseif (Auth::user() && Auth::user()->company) {
$actionlog->company_id = Auth::user()->company_id;
}
});
@@ -45,19 +46,59 @@ class Actionlog extends Model
return $this->morphTo('item')->withTrashed();
}
public function company() {
return $this->hasMany('\App\Models\Company', 'id','company_id');
public function company()
{
return $this->hasMany('\App\Models\Company', 'id', 'company_id');
}
public function itemType()
{
if($this->item_type == AssetModel::class) {
if ($this->item_type == AssetModel::class) {
return "model";
}
return camel_case(class_basename($this->item_type));
}
public function parseItemRoute()
{
if ($this->itemType() == "asset") {
$itemroute = 'assets';
} elseif ($this->itemType() == "accessory") {
$itemroute = 'accessories';
} elseif ($this->itemType()=="consumable") {
$itemroute = 'consumables';
} elseif ($this->itemType()=="license") {
$itemroute = 'licenses';
} elseif ($this->itemType()=="component") {
$itemroute = 'components';
} else {
$itemroute = '';
}
return $itemroute;
}
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()
{
return $this->morphTo('item')
@@ -78,7 +119,7 @@ class Actionlog extends Model
public function target()
{
return $this->morphTo('target');
return $this->morphTo('target')->withTrashed();
}
public function childlogs()

File diff suppressed because it is too large Load Diff

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