Compare commits

..

239 Commits

Author SHA1 Message Date
snipe
0d088f3031 Fixes #2491 - show asset tag on dashboard 2016-08-25 21:28:46 -07:00
snipe
a92ed97b4e Definitely not beta ;) 2016-08-25 21:06:43 -07:00
snipe
fcdea4825e Bumped version 2016-08-25 21:04:43 -07:00
snipe
35439f9976 Additional strings 2016-08-25 21:04:36 -07:00
snipe
d473432436 Show encryption in fieldset list 2016-08-25 21:04:25 -07:00
snipe
4dff58ec26 Fix array generation for select 2016-08-25 21:04:10 -07:00
snipe
537ad28a67 Don’t make required encrypted custom fields required if user is not an admin 2016-08-25 21:03:52 -07:00
snipe
96eb832fd3 Only decrypt if the user is an admin 2016-08-25 21:03:24 -07:00
snipe
130c798c90 Only accept a new value for encrypted fields if the user is an admin 2016-08-25 20:59:54 -07:00
snipe
e1229bfb0f Graceful decryption method 2016-08-25 20:58:56 -07:00
snipe
f185c2e0de Hide radio and checkboxes for now 2016-08-25 19:48:11 -07:00
snipe
122f0b9cba Custom fields form in asset edit view 2016-08-25 18:35:28 -07:00
snipe
c49f10c9bb Removed line break 2016-08-25 18:35:16 -07:00
snipe
97a938f119 Method helper to translate piped field_values into a useable array 2016-08-25 18:35:01 -07:00
snipe
308fcf96de Updated language strings 2016-08-25 17:43:07 -07:00
snipe
f1fab8b164 Added Indonesian to dropdown locale list 2016-08-25 17:22:08 -07:00
snipe
0e8502a323 Removed newline 2016-08-25 17:12:50 -07:00
snipe
3171d9230b Better language 2016-08-25 17:12:34 -07:00
snipe
11b9df4b48 Use updated L5 request method 2016-08-25 17:11:52 -07:00
snipe
0c2524954f Removed unusued status_id variable 2016-08-25 17:10:09 -07:00
snipe
b76ad5ea88 Reverted name of form field 2016-08-25 17:08:39 -07:00
snipe
43fbd54a12 Store new fields in the database 2016-08-25 17:08:08 -07:00
snipe
406d270c01 Use L5 Request method for input 2016-08-25 17:07:58 -07:00
snipe
98eb26a2bd Merge branch 'features/cusom_field_types' into develop 2016-08-25 16:36:21 -07:00
snipe
61aa9beddb Added new fields to custom fields views 2016-08-25 16:36:00 -07:00
snipe
e89fd9b3a2 Additional strings 2016-08-25 16:35:45 -07:00
snipe
d72443c335 Use trans() for custom format text 2016-08-25 16:35:31 -07:00
snipe
4cf2d16c7a Temp fix for number import on cost 2016-08-23 19:01:40 -07:00
snipe
f38912a5cf Custom fields additions 2016-08-23 18:52:54 -07:00
snipe
ad22293f4b Added show in nav for status label views and controller 2016-08-23 18:52:42 -07:00
snipe
fb402e138d Smaller dashboard number 2016-08-23 18:52:12 -07:00
snipe
90d2d0c7e1 Fixes #2469 - corrected config app.url 2016-08-23 16:04:22 -07:00
snipe
9d730af50f Added single quotes to env for mail sender 2016-08-23 16:03:57 -07:00
snipe
9407b4e28c Removed console warning 2016-08-23 15:53:18 -07:00
snipe
ec19924bea Custom field types 2016-08-23 15:52:34 -07:00
snipe
7b8403cdb9 Pass status ID to ajax 2016-08-23 15:52:10 -07:00
snipe
85f3e7e3d4 Added filter by status type 2016-08-23 15:51:59 -07:00
snipe
11dc20de61 Show in nav language option 2016-08-23 15:51:45 -07:00
snipe
14fa7ed965 Fixed indenting 2016-08-23 15:51:14 -07:00
snipe
5cf1c8dfa3 Added DB DUMP PATH to docker.env 2016-08-23 15:51:05 -07:00
snipe
f04cfb3e7f Allow admins to show status labels in nav 2016-08-23 15:50:52 -07:00
snipe
d970daa666 Add new fields to custom fields table 2016-08-23 15:50:43 -07:00
snipe
b1324c2e64 Removed beta from version 2016-08-23 11:37:49 -07:00
snipe
3c28be33c5 Bumped version 2016-08-23 11:37:00 -07:00
snipe
e52a0f65bb Update asset report to show deployed if asset is checked out 2016-08-23 11:36:34 -07:00
snipe
b726d131a4 More helpful message for LDAP TLS issue 2016-08-23 11:32:11 -07:00
snipe
014167699d Fixes #2441 - use showAssetName to avoid blank entries in link name which makes Slack do weird things 2016-08-18 13:10:31 -07:00
snipe
d9f2e7bf58 If custom field is type URL, display it as a link 2016-08-18 12:44:55 -07:00
snipe
4c8c58d453 Clean up divs for gates in list view 2016-08-18 12:31:45 -07:00
snipe
923352537c Moved column for in/out 2016-08-18 07:06:55 -07:00
snipe
be8049b41a Include asset maintenances in purge 2016-08-18 07:06:15 -07:00
snipe
4419dc7434 Merge branch 'fix-double-format' of https://github.com/dmeltzer/snipe-it into dmeltzer-fix-double-format
# Conflicts:
#	app/Http/Controllers/ConsumablesController.php
#	app/Http/Controllers/LicensesController.php
#	resources/views/hardware/view.blade.php
2016-08-16 18:53:45 -07:00
Daniel Meltzer
ac63642224 Add manufacturer to licenses (#2436)
* Add manufacturer to licenses.  Shows in table and edit.  Need to improve manufacturer view to show lists beyond assets still.

* Remove extra closing tags, formatting

* Work on making the manufacturer view show more options. Need to figure out how to change the table dynamically.

* Cleanup formatting and fix a few weirdities in hardware/view.blade.php

* Standardize on two-space tabs in this file, as it seems the most
* common.

* Fix a few places where we call number_format without guaranteeing the
* item is a number and not a string.

* Show a "No Results" message on components page if there are no
* components.

* Show table of licenses on manufacturer view page.

This reworks the ManufacturersController::getDataView method to delegate
the view to a sub method (currently assets or licenses, but plan to
extend to consumables/accessories/components as well).  We then put tabs
at the top of the view to show multiple tables.  This just duplicates
the table layout from licenses/index.blade, but I wonder if theres a way
to centralize that code, maybe through partials, over time..

The only known missing part of manufacturers for licenses would be adding it
to the importer, but the license importer should probably migrate to
object importer before doing too much more...

* Add manufacturer to accessory.

* Add consumables to the manufacturer view page.
2016-08-16 18:49:54 -07:00
Daniel Meltzer
5959f83de3 Rename parseCurrencyString to formatCurrencyOutput to clarify what it does better. 2016-08-16 20:47:53 -05:00
Daniel Meltzer
0c912bcf49 Fix more number_format madness.
This does two main things:
1) The importer now imports as numbers, not parsed strings.  This allows
is to format values on output instead of input, which is what was
happening in most places.

2) Add a Helper::parseCurrencyString method and port everything to use
this.  This checks to see if the value is numeric or empty, and returns
the appropriate value in all cases.  Should fix all known occurances of
number_format expections.
2016-08-16 20:41:28 -05:00
snipe
44821b9667 Fixes #2404 Only update name of asset if it isn't null. 2016-08-16 18:23:20 -07:00
snipe
29c4189419 Bumped version 2016-08-16 18:20:42 -07:00
Daniel Meltzer
7ef4f23d0f Validate that purchase_cost is a numeric value. (#2452) 2016-08-16 18:18:50 -07:00
Daniel Meltzer
a852c624d3 Fix 2347 (#2394)
* Prevent multiple checkouts of the same asset.

This adds a new method to the Asset model, availableForCheckout.
Port getDataTable to use availableForCheckout instead of doing the
check manually.

Fixes Issue #2347

* Use availableForCheckout in categories controller.  Also gate the checkin/checkout actions here.

* Use gate and availableForCheckout in manufactuers as well.
2016-08-16 13:02:42 -07:00
snipe
7edf1db101 Small tweaks to history 2016-08-12 19:03:32 -07:00
snipe
5e9740e0b4 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-08-12 17:10:10 -07:00
snipe
41a20d8f66 Tidied up some debugging code, better explanation 2016-08-12 17:10:03 -07:00
snipe
7a0843e954 Import history language file 2016-08-12 16:02:51 -07:00
snipe
4a9f3fd6ff Generate email method 2016-08-12 16:02:39 -07:00
snipe
9ae1841fc4 Make additional fields fillable 2016-08-12 16:02:18 -07:00
snipe
ba5a2edd54 CSV history routes 2016-08-12 16:02:09 -07:00
snipe
c73cbccffc Method to import CSV history 2016-08-12 16:01:59 -07:00
snipe
24d2726c86 Added helper for imports 2016-08-12 16:01:45 -07:00
snipe
06fcf3e07d Import history blade 2016-08-12 16:01:34 -07:00
Daniel Meltzer
cc15a4f018 Use showAssetName instead of asset->name to include the asset tag (#2437) 2016-08-11 23:56:40 -07:00
snipe
18e576e5fd Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-08-11 22:03:25 -07:00
snipe
4c787891e4 Use custom maintenance middleware 2016-08-11 19:22:26 -07:00
Daniel Meltzer
dbd96a4c10 Don't try to format a formatted number string. (#2396)
The importer already formatted/parsed numbers on input into the db
(maybe it shouldn't have?) so running number_format on that string
throws an exception.  Check to make sure the value is numeric before
formatting it.
2016-08-11 19:13:49 -07:00
snipe
d314f85b93 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-08-11 15:58:22 -07:00
snipe
3a81b7e612 Eager load asset query on maintenances to prevent n+1 queries 2016-08-11 15:56:21 -07:00
snipe
7992258b46 Updated UI with new required indicator 2016-08-11 15:44:01 -07:00
snipe
869da1da78 Add maintenance notes to maintenances tab in hardware view 2016-08-11 15:40:41 -07:00
Michael T
a6a6aa78b0 Fixing the script freezing prior to mysql secure install (#2434) 2016-08-11 15:17:55 -07:00
snipe
4ffea7ceaa Fixes #2406 - added missing gate for assets.edit 2016-08-09 16:38:43 -07:00
snipe
1d3255a00b Allow admin to turn LDAP password sync off.
This is added to handle customers/users with a security policy that prohibits third-parties or external databases from storing LDAP passwords.
2016-08-04 14:29:28 -07:00
snipe
29eadb10ae Fixes #2387 2016-08-02 17:03:15 -07:00
snipe
1ca5f8bee5 Removed asterisks, use orange bar for req fields in locations 2016-08-02 16:40:38 -07:00
snipe
8dbc098836 Bumped hash for 3.2.0 2016-08-02 15:25:23 -07:00
snipe
45ea44e172 Bumped hash 2016-08-02 15:16:16 -07:00
snipe
fff2bce9e4 Added missing username in header row 2016-08-02 15:16:01 -07:00
snipe
75e0c5565c Add username and custom fields option to custom report 2016-08-02 15:04:10 -07:00
snipe
098e7e4feb Hide email address if there is no value 2016-08-02 15:03:45 -07:00
snipe
e4355292e4 Bumped hash version 2016-08-02 13:30:00 -07:00
snipe
ca8ca89955 Added custom color to status labels, only show status labels if there are results 2016-08-02 13:25:50 -07:00
snipe
30c45442f9 Merge remote-tracking branch 'origin/develop' 2016-08-02 12:40:06 -07:00
snipe
03c2c267bc Added favicon explicit link 2016-08-02 12:39:49 -07:00
snipe
a76fe98b2d Only show a logo if a logo is uploaded 2016-08-02 12:34:08 -07:00
snipe
9e43a44d20 Better styling for forgotten password screens 2016-08-02 12:30:22 -07:00
snipe
6fe639f490 Skip email if no email domain is given 2016-08-02 12:30:02 -07:00
snipe
a5467ba25d Slug the username to handle spaces, etc. 2016-08-02 11:12:28 -07:00
snipe
1c09479d5f Merge remote-tracking branch 'origin/develop' 2016-08-02 10:34:43 -07:00
snipe
682c75e990 Bumped version 2016-08-02 10:34:30 -07:00
snipe
1612562f41 Create log record and send EULA when creating a new asset that’s checked out 2016-08-02 10:33:44 -07:00
snipe
1b7f28598d Merge remote-tracking branch 'origin/develop' 2016-08-02 09:54:47 -07:00
snipe
17d5e40e02 Fixes #2383 2016-08-02 09:54:31 -07:00
snipe
099a85e26d Merge remote-tracking branch 'origin/develop' 2016-08-02 05:06:29 -07:00
snipe
0e5209e80f Few more dashboard fixes 2016-08-02 05:06:17 -07:00
snipe
95328f0a6a Merge remote-tracking branch 'origin/develop' 2016-08-02 04:46:25 -07:00
snipe
cbc42f3e59 Fix for deleted users display 2016-08-02 04:45:48 -07:00
snipe
846356974d Merge remote-tracking branch 'origin/develop' 2016-08-02 04:26:19 -07:00
snipe
ef6fb69cee Fix translation 2016-08-02 04:26:07 -07:00
snipe
fb1eab0978 Merge remote-tracking branch 'origin/develop' 2016-08-02 04:24:09 -07:00
snipe
39929c7d89 Better handling for deleted users 2016-08-02 04:23:13 -07:00
snipe
d6ba0b67f0 Merge remote-tracking branch 'origin/develop' 2016-08-02 03:50:20 -07:00
snipe
66ad0f1d4c Better fix for location LDAP sync 2016-08-02 03:50:08 -07:00
snipe
bfac25d445 Merge remote-tracking branch 'origin/develop' 2016-08-02 03:45:17 -07:00
snipe
3b247ba31f Ignore location field if no value is passed 2016-08-02 03:45:03 -07:00
snipe
bc3482b281 Merge remote-tracking branch 'origin/develop' 2016-08-02 03:26:53 -07:00
snipe
23e23bab90 Remove display of port number since it’s ignored anyway 2016-08-02 03:26:38 -07:00
snipe
848e3837aa Merge remote-tracking branch 'origin/develop' 2016-08-02 02:36:40 -07:00
Brady Wetherington
1747be4b29 Enable .env file to point to location of CA Cert (#2382) 2016-08-02 02:36:00 -07:00
snipe
565ea95803 Merge remote-tracking branch 'origin/develop' 2016-08-02 02:33:04 -07:00
snipe
e7e8c487c9 Bumped version 2016-08-02 02:32:52 -07:00
snipe
5a242433fb Merge remote-tracking branch 'origin/develop' 2016-08-02 02:12:33 -07:00
snipe
6204969639 Fixed requestable link 2016-08-02 02:12:18 -07:00
snipe
cde5efd698 Merge remote-tracking branch 'origin/develop' 2016-08-02 01:36:32 -07:00
snipe
283bb4ae4b Fixes #2381 2016-08-02 01:36:14 -07:00
snipe
3d1d248bb5 Merge remote-tracking branch 'origin/develop' 2016-08-02 01:26:51 -07:00
snipe
9c31c0edce Ignore uploaded barcodes 2016-08-02 01:26:44 -07:00
snipe
39450c1fe9 Eager load throttle query 2016-08-02 01:23:53 -07:00
snipe
64ffd261fc Bumped version 2016-08-02 01:14:11 -07:00
snipe
de17da099f Fixed tests 2016-08-02 01:12:58 -07:00
snipe
886a31190c Fixed route 2016-08-02 01:08:37 -07:00
snipe
8246a319a2 Fixes #2363 and #1097 2016-08-02 00:54:38 -07:00
snipe
27adeb427e Generate barcodes locally and try to serve them if they exist 2016-08-01 22:56:28 -07:00
snipe
bfc18c758a Removed console message from JS 2016-08-01 21:43:56 -07:00
snipe
735595be07 Typeahead library
(not implemented yet)
2016-08-01 21:43:01 -07:00
snipe
27dee1b793 Removed comment 2016-08-01 20:15:25 -07:00
snipe
cdeccb399f Hide extra options if superadmin is checked 2016-08-01 20:11:54 -07:00
snipe
2f679ccc29 Merge remote-tracking branch 'origin/develop' 2016-08-01 18:44:32 -07:00
snipe
eac6abe60a Fixes #2378 - disallow admins to create/edit superadmins
Also disables admins from being able to edit groups, since that can grant superadmin access.
2016-08-01 18:43:11 -07:00
Daniel Meltzer
c9d3cd724b Fix installer again (#2370)
I hate bash... anyone else want to maintain this? :)
2016-08-01 11:08:46 -07:00
snipe
1fa2fe3c24 Merge remote-tracking branch 'origin/develop' 2016-08-01 10:32:04 -07:00
snipe
b6986ad808 Bumped version 2016-08-01 10:31:46 -07:00
snipe
715c9aa780 Merge remote-tracking branch 'origin/develop' 2016-08-01 10:18:01 -07:00
snipe
139325d8ba Small tweaks for bad data 2016-08-01 10:17:46 -07:00
snipe
d65a9091c8 Merge remote-tracking branch 'origin/develop' 2016-07-30 17:27:29 -07:00
snipe
1f30bdee99 Fixes #2361 2016-07-30 17:27:08 -07:00
snipe
4e4f338680 Merge remote-tracking branch 'origin/develop' 2016-07-29 14:32:49 -07:00
snipe
0f72989953 Updated language strings 2016-07-29 14:32:31 -07:00
snipe
93e038006c Merge remote-tracking branch 'origin/develop' 2016-07-29 14:18:21 -07:00
snipe
b63a3abf70 Bumped hash 2016-07-29 14:18:05 -07:00
snipe
46eca54b44 Moved bulk checkout into assets nav 2016-07-29 14:17:59 -07:00
zjean
fcb1d6ac15 Fixed feedback on #2349 (#2359) 2016-07-29 13:59:50 -07:00
snipe
3f54c034dd Merge remote-tracking branch 'origin/develop' 2016-07-29 12:15:45 -07:00
snipe
a53346be1f Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-07-29 12:15:14 -07:00
snipe
fd94c76874 Fixes asset created_at 2016-07-29 12:15:09 -07:00
zjean
108a3c9dad Updated view for #2324 (#2357) 2016-07-29 11:55:16 -07:00
snipe
85232c47da Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-07-28 21:31:58 -07:00
snipe
47f6635992 A few more permissions tweaks 2016-07-28 21:31:53 -07:00
Daniel Meltzer
eef8d1609e Small fixes (#2350)
* components.view should point to view, not create

* Fix comment

* Rename variable to accurately reflect its responsibility

* Fix line breaks in serial key, remove places where adding line breaks makes no sense.  Fixes #2344
2016-07-28 20:59:42 -07:00
snipe
8a9307f357 Wordwrap license key 2016-07-28 18:56:02 -07:00
snipe
0a73297f24 Merge remote-tracking branch 'origin/develop' 2016-07-28 12:51:01 -07:00
snipe
1f0737cfb7 Allow super admins to override company 2016-07-28 12:40:19 -07:00
snipe
fae9755ffb Merge remote-tracking branch 'origin/develop' 2016-07-28 09:16:46 -07:00
snipe
c07ad03e74 Removed unique from form request 2016-07-28 09:16:30 -07:00
snipe
011cb1120d Merge remote-tracking branch 'origin/develop' 2016-07-28 08:51:15 -07:00
snipe
68b7b8f932 Fixes Carbon date 2016-07-28 08:51:01 -07:00
snipe
f78a577210 Merge remote-tracking branch 'origin/develop' 2016-07-28 08:41:47 -07:00
snipe
c0f4e621ea Bumped version 2016-07-28 08:41:33 -07:00
snipe
c78dbfc21f Merge remote-tracking branch 'origin/develop' 2016-07-28 08:39:59 -07:00
snipe
f31637adb4 Fixes #2346 2016-07-28 08:39:28 -07:00
snipe
3e5d2b5385 Ability to remove field from fieldset 2016-07-28 08:10:15 -07:00
snipe
fbd0059bbb Fixes #2317 2016-07-28 08:07:14 -07:00
snipe
f53c5706f6 Fixes #2341 2016-07-28 07:36:58 -07:00
snipe
214a7d548d Bumped version 2016-07-28 06:44:59 -07:00
snipe
0ee5dea1a1 Fixes #2344 2016-07-28 06:43:31 -07:00
snipe
29c60ee6b5 Merge remote-tracking branch 'origin/develop' 2016-07-28 05:50:22 -07:00
snipe
075f8fd021 Fixed typo 2016-07-28 05:49:55 -07:00
snipe
14b0a6315f Pass users path to get_src 2016-07-28 05:49:41 -07:00
snipe
b99d300ab2 Merge remote-tracking branch 'origin/develop' 2016-07-27 21:47:25 -07:00
snipe
9dda0d02ea Change default zerofill to 5 2016-07-27 21:47:03 -07:00
snipe
8e6c157e7e Merge remote-tracking branch 'origin/develop' 2016-07-27 21:33:00 -07:00
snipe
9fbe6c68ac Fixes #2304 2016-07-27 21:30:38 -07:00
snipe
eb508901c5 Zerofilling for auto-increment 2016-07-27 21:28:00 -07:00
snipe
07b70a8cd0 Merge remote-tracking branch 'origin/develop' 2016-07-27 20:30:25 -07:00
snipe
e9eb5ad372 Bumped version 2016-07-27 20:30:11 -07:00
snipe
3fd5fb836f Restore linebreaks in notes 2016-07-27 20:24:09 -07:00
snipe
3514ae2c0d Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-07-27 20:16:54 -07:00
snipe
1493251794 Gitignore cleanup 2016-07-27 20:16:46 -07:00
Daniel Meltzer
b4e54225a2 Fix exports (#2338)
* Update tableexport.js to the new version.

* Give the export file in each table a useful name.

The name takes the form of tabletype-export-YYYY-MM-DD.extension.
2016-07-27 19:45:45 -07:00
Daniel Meltzer
4c9e75cec9 Install php-zip so backups work. Not needed in 14.04 because it looks like this is part of the php7 split. (#2340)
Issue #2269
2016-07-27 19:44:46 -07:00
Daniel Meltzer
a401986ef5 Only set the category_type in postEdit if the category is empty. (#2337)
Fixes #2333
2016-07-27 16:13:54 -07:00
snipe
288584cb60 Merge branch 'master' of github.com:snipe/snipe-it 2016-07-26 16:33:32 -07:00
Daniel Meltzer
399e70763b Scope requestable assets to company as well. Updates to #2206. (#2326) 2016-07-26 16:22:56 -07:00
Brady Wetherington
f145d6cc8c Change README to point to new documentation site 2016-07-26 13:56:40 -07:00
Daniel Meltzer
9e4ac018ea Don't allow users without a company to change the company of items if full company support is enabled. (#2321) 2016-07-26 13:31:36 -07:00
Daniel Meltzer
0bf5c6978e Make sure the assigned user is actually shown in the dropdown list. Not sure why this wasn't throwing an error for me, but this makes it actually behave. (#2322) 2016-07-26 13:06:38 -07:00
snipe
9a9b214c1d Fixes #2319 2016-07-26 06:07:47 -07:00
snipe
b76dc25ac0 Duh, we don’t soft-delete companies 2016-07-26 02:11:41 -07:00
snipe
b30369f7ce Added table name for trait 2016-07-26 02:04:31 -07:00
snipe
16fe53928c Updated undeleted validation 2016-07-26 01:49:21 -07:00
snipe
2e665e128f Putting uniqueUndeleted into a trait for use across models 2016-07-26 01:39:30 -07:00
snipe
60560e4994 Remove unused Log statement 2016-07-26 00:50:16 -07:00
snipe
a44b90dfc9 Custom validator for multiple deleted items with the same unique field 2016-07-26 00:44:26 -07:00
snipe
987b969e88 Move bcrypt out of loop for object importer 2016-07-25 22:31:33 -07:00
snipe
ad531d6d59 Merge branch 'develop' of github.com:snipe/snipe-it into develop 2016-07-25 22:10:38 -07:00
snipe
261d2f133b Only bcrypt temp passwords once for performance 2016-07-25 22:10:33 -07:00
Daniel Meltzer
e0938cf82d Scope to company when viewing assets (#2315)
* If a user doesn't belong to a company, when scoping to a company we should only show items that don't belong to a company.

* Scope tables/items to the company they belong to when fetching items for the index.

* Fix asset count to also scope to company.  This fixes dashboard view

* Exempt super users from the child company check to be consistent.  Fixes license count on dashboard now that we scope everything
2016-07-25 19:46:29 -07:00
snipe
eec22c5aeb Removed port stuff, since LDAP ignores it anyway :-/ 2016-07-22 16:21:16 -07:00
snipe
b03330aae0 Added TLS option in settings for LDAP 2016-07-22 16:00:37 -07:00
snipe
7f5ea72dc7 Bumped version 2016-07-22 15:11:03 -07:00
snipe
ba25972b49 Add LDAP port number option 2016-07-22 15:09:49 -07:00
snipe
cc6b2a0081 FIxes #2280
This shouldn’t ever happen though. Bad data somwhere, I’m guessing.
2016-07-22 07:48:46 -07:00
snipe
a590cc3dd2 One more fix for MAC address weirdness 2016-07-22 05:56:00 -07:00
snipe
d4138f4364 Fixes #2299 2016-07-22 03:10:25 -07:00
snipe
128290bd82 Cleanup checkin blade 2016-07-22 02:34:25 -07:00
snipe
114540d836 Cleanup checkout form 2016-07-22 02:20:05 -07:00
snipe
0b57f74e36 Check for model name (this should never be blank, but…) 2016-07-22 02:14:12 -07:00
snipe
03d7d01e12 Fixes #2300 2016-07-22 02:12:04 -07:00
snipe
a1640d7fe3 Form cleanup 2016-07-22 02:11:57 -07:00
snipe
1f85f4b337 Clearer demo mode text 2016-07-22 02:11:46 -07:00
snipe
b2d958724b Removed commented code 2016-07-22 02:11:37 -07:00
snipe
297820d347 Newer required style 2016-07-22 01:33:55 -07:00
snipe
094c5ac8df Fixes #2292 2016-07-22 01:16:18 -07:00
snipe
78fda31379 Helper method to introspect into the model level validation to see if the field is required
(This does not yet handle form request validation)
2016-07-22 00:29:23 -07:00
snipe
3a04686ade Nicer demo mode message 2016-07-22 00:28:22 -07:00
snipe
ca5d3e3006 Nicer license form display 2016-07-22 00:25:41 -07:00
snipe
d427dcc8e2 updated version 2016-07-22 00:24:42 -07:00
snipe
f0c00897ca Required class 2016-07-22 00:21:56 -07:00
snipe
e256bdc9f7 Clearer version in footer 2016-07-21 21:39:23 -07:00
snipe
2e6e0e8911 Fixed versioning path 2016-07-21 21:30:49 -07:00
snipe
b0dc5b4183 Fixes #2290 2016-07-21 21:28:17 -07:00
snipe
9385c3e9cf Remove last name requirement from Form Request 2016-07-21 19:46:46 -07:00
snipe
61108102d7 No longer require last name
I may regret this…
2016-07-21 19:44:07 -07:00
snipe
8ba9399de7 Merge branch 'master' into develop 2016-07-21 19:42:11 -07:00
snipe
f6a4d4aaab Better display for some features disabled for demo mode 2016-07-21 19:40:23 -07:00
Daniel Meltzer
df664bdc9d Fix categories acceptance test as it stands. We need to choose a category type to pass validation, and we need to see the elemnt alert-danger, not the text, to make the test fail when it should. (#2289) 2016-07-20 21:36:43 -07:00
Daniel Meltzer
c2f6e0cfd8 Don't escape html in default eula. Fixes #2277 (#2279) 2016-07-20 19:39:48 -07:00
Daniel Meltzer
ba6f26cef9 If a category has items in it, disable changing the category type (#2288) 2016-07-20 19:27:33 -07:00
Daniel Meltzer
68b0bbbec9 Fix tests (#2273)
* Update installer script for v3 now that things have moved around.

* Make Statuslabel attributes fillable and add them to the generated array.  Fixes status label tests.
2016-07-19 15:50:21 -07:00
snipe
52425f62c5 Set default values for status labels in import 2016-07-19 15:49:04 -07:00
Daniel Meltzer
54a0d0de0e Fetch the installer from master instead of v3 branch. (#2266) 2016-07-19 09:41:00 -07:00
Daniel Meltzer
099f5d4cfd Update installer script for v3 now that things have moved around. (#2263) 2016-07-19 08:41:56 -07:00
600 changed files with 9229 additions and 3935 deletions

View File

@@ -30,7 +30,7 @@ MAIL_USERNAME=YOURUSERNAME
MAIL_PASSWORD=YOURPASSWORD
MAIL_ENCRYPTION=null
MAIL_FROM_ADDR=you@example.com
MAIL_FROM_NAME=Snipe-IT
MAIL_FROM_NAME='Snipe-IT'
# --------------------------------------------
@@ -74,4 +74,4 @@ AWS_BUCKET=null
APP_LOG=single
APP_LOCKED=false
FILESYSTEM_DISK=local
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1

68
.gitignore vendored
View File

@@ -1,49 +1,39 @@
/vendor
/node_modules
Homestead.yaml
Homestead.json
.env
tests/_output/*
.couscous
.DS_Store
public/uploads/models/*
public/uploads/avatars/*
public/uploads/suppliers/*
public/uploads/assets/*
public/uploads/users/*
public/uploads/*.gif
public/uploads/*.jpg
public/uploads/*.png
public/uploads/*.tif
public/uploads/*.svg
storage/app/private_uploads/users/*
phpDocumentor.phar
output
tests/_support/_generated/*
.env
.idea
/bin/
/bootstrap/compiled.php
composer.phar
app/config/database.php
app/config/mail.php
/node_modules
/vendor
app/database/*.sqlite
app/storage/meta/services.json
app/config/*/mail.php
app/config/*/session.php
app/config/*/database.php
app/config/*/app.php
app/config/*/ldap.php
public/packages/*
storage/logs/*
storage/debugbar/
/bin/
.idea
composer.phar
crowdin.yaml
Homestead.json
Homestead.yaml
output
phpDocumentor.phar
public/uploads/*.gif
public/uploads/barcodes/*.png
public/uploads/*.jpg
public/uploads/*.png
public/uploads/*.svg
public/uploads/*.tif
public/uploads/assets/*
public/uploads/avatars/*
public/uploads/logo.gif
public/uploads/logo.svg
public/uploads/logo.png
.couscous
public/uploads/logo.svg
public/uploads/models/*
public/uploads/suppliers/*
public/uploads/users/*
storage/app/private_uploads/users/*
storage/debugbar/
storage/dumps/*
tests/_data/scenarios
storage/laravel-backups
storage/logs/*
storage/private_uploads/users/*
tests/_data/scenarios
tests/_output/*
tests/_support/_generated/*

View File

@@ -63,6 +63,9 @@ class ObjectImportCommand extends Command
{
$filename = $this->argument('filename');
$tmp_password = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$password = bcrypt($tmp_password);
if (!$this->option('web-importer')) {
$logFile = $this->option('logfile');
@@ -109,7 +112,7 @@ class ObjectImportCommand extends Command
$bar = $this->output->createProgressBar(count($newarray));
}
// Loop through the records
DB::transaction(function () use (&$newarray, $bar) {
DB::transaction(function () use (&$newarray, $bar, $password) {
Model::unguard();
$item_type = strtolower($this->option('item-type'));
@@ -154,7 +157,8 @@ class ObjectImportCommand extends Command
$this->log('Company Name: ' . $item_company_name);
$this->log('Status: ' . $item_status_name);
$item["user"] = $this->createOrFetchUser($row);
$item["user"] = $this->createOrFetchUser($row, $password);
$item["location"] = $this->createOrFetchLocation($item_location);
$item["category"] = $this->createOrFetchCategory($item_category, $item_type);
@@ -456,6 +460,10 @@ class ObjectImportCommand extends Command
$status = new Statuslabel();
$status->name = $asset_statuslabel_name;
$status->deployable = 1;
$status->pending = 0;
$status->archived = 0;
if (!$this->option('testrun')) {
if ($status->save()) {
@@ -627,7 +635,7 @@ class ObjectImportCommand extends Command
* @internal param string $first_name
* @internal param string $last_name
*/
public function createOrFetchUser($row)
public function createOrFetchUser($row, $password = null)
{
$user_name = $this->array_smart_fetch($row, "name");
$user_email = $this->array_smart_fetch($row, "email");
@@ -652,7 +660,12 @@ class ObjectImportCommand extends Command
$last_name = $user_email_array['last_name'];
if ($user_email=='') {
$user_email = $user_email_array['username'].'@'.Setting::getSettings()->email_domain;
if (Setting::getSettings()->email_domain) {
$user_email = str_slug($user_email_array['username']).'@'.Setting::getSettings()->email_domain;
} else {
$user_email = '';
}
}
if ($user_username=='') {
@@ -685,14 +698,13 @@ class ObjectImportCommand extends Command
$this->log('User '.$user_username.' already exists');
} elseif (( $first_name != '') && ($last_name != '') && ($user_username != '')) {
$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->password = bcrypt($password);
$user->activated = 1;
$user->password = $password;
if ($user->save()) {
$this->log('User '.$first_name.' created');
} else {
@@ -768,7 +780,7 @@ class ObjectImportCommand extends Command
if (!empty($item["purchase_cost"])) {
//TODO How to generalize this for not USD?
$purchase_cost = substr($item["purchase_cost"], 0, 1) === '$' ? substr($item["purchase_cost"], 1) : $item["purchase_cost"];
$asset->purchase_cost = number_format($purchase_cost, 2);
$asset->purchase_cost = number_format($purchase_cost, 2, '.', '');
$this->log("Asset cost parsed: " . $asset->purchase_cost);
} else {
$asset->purchase_cost = 0.00;

View File

@@ -62,15 +62,19 @@ class Purge extends Command
$assetcount = $assets->count();
$this->info($assets->count().' assets purged.');
$asset_assoc = 0;
$asset_maintenances = 0;
foreach ($assets as $asset) {
$this->info('- Asset "'.$asset->showAssetName().'" deleted.');
$asset_assoc += $asset->assetlog()->count();
$asset->assetlog()->forceDelete();
$asset_maintenances += $asset->assetmaintenances()->count();
$asset->assetmaintenances()->forceDelete();
$asset->forceDelete();
}
$this->info($asset_assoc.' corresponding log records purged.');
$this->info($asset_maintenances.' corresponding maintenance records purged.');
$locations = Location::whereNotNull('deleted_at')->withTrashed()->get();
$this->info($locations->count().' locations purged.');

View File

@@ -42,7 +42,7 @@ class Versioning extends Command
{
// Path to the file containing your version
// This will be overwritten everything you commit a message
$versionFile = app_path().'/config/version.php';
$versionFile = 'config/version.php';
// The git's output
// get the argument passed in the git command
@@ -50,7 +50,7 @@ class Versioning extends Command
// discard the commit hash
$version = explode('-', $hash_version);
$realVersion = $version[0] . '-' . $version[1];
$realVersion = $version[0];
// save the version array to a variable
$array = var_export(array('app_version' => $realVersion,'hash_version' => $hash_version), true);

View File

@@ -17,6 +17,8 @@ use App\Models\Component;
use App\Models\Accessory;
use App\Models\Consumable;
use App\Models\Asset;
use Crypt;
use Illuminate\Contracts\Encryption\DecryptException;
/*
* To change this license header, choose License Headers in Project Properties.
@@ -43,6 +45,17 @@ class Helper
return array_walk($emails_array, 'trim_value');
}
public static function formatCurrencyOutput($cost)
{
// The importer has formatted number strings since v3, so the value might be a string, or an integer.
// If it's a number, format it as a string
if (is_numeric($cost)) {
return number_format($cost, 2, '.', '');
}
// It's already been parsed.
return $cost;
}
// This doesn't do anything yet
public static function trim_value(&$value)
{
@@ -226,7 +239,7 @@ class Helper
{
$keys=array_keys(CustomField::$PredefinedFormats);
$stuff=array_combine($keys, $keys);
return $stuff+["" => "Custom Format..."];
return $stuff+["" => trans('admin/custom_fields/general.custom_format')];
}
public static function barcodeDimensions($barcode_type = 'QRCODE')
@@ -403,4 +416,83 @@ class Helper
return $permissions_arr;
}
/**
* Introspects into the model validation to see if the field passed is required.
* This is used by the blades to add a required class onto the HTML element.
* This isn't critical, but is helpful to keep form fields in sync with the actual
* model level validation.
*
* This does not currently handle form request validation requiredness :(
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return boolean
*/
public static function checkIfRequired($class, $field) {
$rules = $class::rules();
foreach ($rules as $rule_name => $rule) {
if ($rule_name == $field) {
if (strpos($rule, 'required') === false) {
return false;
} else {
return true;
}
}
}
}
/**
* 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 static function array_smart_fetch(array $array, $key, $default = '')
{
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>';
}
}
public static function gracefulDecrypt(CustomField $field, $string) {
if ($field->isFieldDecryptable($string)) {
try {
Crypt::decrypt($string);
return Crypt::decrypt($string);
} catch (DecryptException $e) {
return 'Error Decrypting: '.$e->getMessage();
}
}
return $string;
}
}

View File

@@ -19,6 +19,7 @@ use Str;
use View;
use Auth;
use Request;
use Gate;
/** This controller handles all actions related to Accessories for
* the Snipe-IT Asset Management application.
@@ -52,14 +53,12 @@ class AccessoriesController extends Controller
public function getCreate(Request $request)
{
// Show the page
$category_list = Helper::categoryList('accessory');
$company_list = Helper::companyList();
$location_list = Helper::locationsList();
return View::make('accessories/edit')
->with('accessory', new Accessory)
->with('category_list', $category_list)
->with('company_list', $company_list)
->with('location_list', $location_list);
->with('category_list', Helper::categoryList('accessory'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList())
->with('manufacturer_list', Helper::manufacturerList());
}
@@ -76,12 +75,13 @@ class AccessoriesController extends Controller
$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->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'));
if (e(Input::get('purchase_date')) == '') {
$accessory->purchase_date = null;
@@ -95,8 +95,8 @@ class AccessoriesController extends Controller
$accessory->purchase_cost = e(Input::get('purchase_cost'));
}
$accessory->qty = e(Input::get('qty'));
$accessory->user_id = Auth::user()->id;
$accessory->qty = e(Input::get('qty'));
$accessory->user_id = Auth::user()->id;
// Was the accessory created?
if ($accessory->save()) {
@@ -125,14 +125,11 @@ class AccessoriesController extends Controller
return redirect()->to('admin/accessories')->with('error', trans('general.insufficient_permissions'));
}
$category_list = Helper::categoryList('accessory');
$company_list = Helper::companyList();
$location_list = Helper::locationsList();
return View::make('accessories/edit', compact('accessory'))
->with('category_list', $category_list)
->with('company_list', $company_list)
->with('location_list', $location_list);
->with('category_list', Helper::categoryList('accessory'))
->with('company_list', Helper::companyList())
->with('location_list', Helper::locationsList())
->with('manufacturer_list', Helper::manufacturerList());
}
@@ -145,9 +142,9 @@ class AccessoriesController extends Controller
*/
public function postEdit(Request $request, $accessoryId = null)
{
// Check if the blog post exists
// Check if the accessory exists
if (is_null($accessory = Accessory::find($accessoryId))) {
// Redirect to the blogs management page
// 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'));
@@ -159,11 +156,12 @@ class AccessoriesController extends Controller
if (e(Input::get('location_id')) == '') {
$accessory->location_id = null;
} else {
$accessory->location_id = e(Input::get('location_id'));
$accessory->location_id = e(Input::get('location_id'));
}
$accessory->min_amt = e(Input::get('min_amt'));
$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'));
if (e(Input::get('purchase_date')) == '') {
@@ -180,9 +178,9 @@ class AccessoriesController extends Controller
$accessory->qty = e(Input::get('qty'));
// Was the accessory created?
// Was the accessory updated?
if ($accessory->save()) {
// Redirect to the new accessory page
// Redirect to the updated accessory page
return redirect()->to("admin/accessories")->with('success', trans('admin/accessories/message.update.success'));
}
@@ -549,7 +547,7 @@ class AccessoriesController extends Controller
**/
public function getDatatable(Request $request)
{
$accessories = Accessory::select('accessories.*')->with('category', 'company')
$accessories = Company::scopeCompanyables(Accessory::select('accessories.*')->with('category', 'company'))
->whereNull('accessories.deleted_at');
if (Input::has('search')) {
@@ -591,7 +589,21 @@ class AccessoriesController extends Controller
$rows = array();
foreach ($accessories as $accessory) {
$actions = '<nobr><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><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><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></nobr>';
$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(
@@ -602,10 +614,12 @@ class AccessoriesController extends Controller
'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),
'purchase_cost' => Helper::formatCurrencyOutput($accessory->purchase_cost),
'numRemaining' => $accessory->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name)
'companyName' => is_null($company) ? '' : e($company->name),
'manufacturer' => $accessory->manufacturer ? (string) link_to('/admin/settings/manufacturers/'.$accessory->manufacturer_id.'/view', $accessory->manufacturer->name) : ''
);
}
@@ -654,10 +668,20 @@ class AccessoriesController extends Controller
$rows = array();
foreach ($accessory_users as $user) {
$actions = '<a href="'.route('checkin/accessory', $user->pivot->id).'" class="btn btn-info btn-sm">Checkin</a>';
$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('users.view')) {
$name = (string) link_to('/admin/users/'.$user->id.'/view', e($user->fullName()));
} else {
$name = e($user->fullName());
}
$rows[] = array(
'name' =>(string) link_to('/admin/users/'.$user->id.'/view', e($user->fullName())),
'name' => $name,
'actions' => $actions
);
}

View File

@@ -309,7 +309,7 @@ class AssetMaintenancesController extends Controller
'' => 'Select an improvement type',
] + AssetMaintenance::getImprovementOptions();
$assets = Company::scopeCompanyables(Asset::all(), 'assets.company_id')->lists('detailed_name', 'id');
$assets = Company::scopeCompanyables(Asset::with('model','assignedUser')->get(), 'assets.company_id')->lists('detailed_name', 'id');
// Get Supplier List
$supplier_list = Helper::suppliersList();

View File

@@ -23,6 +23,7 @@ use Validator;
use Artisan;
use Auth;
use Config;
use League\Csv\Reader;
use DB;
use Image;
use Input;
@@ -39,6 +40,8 @@ use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\JsonResponse;
use TCPDF;
use View;
use Carbon\Carbon;
use Gate;
/**
* This class controls all actions related to assets for
@@ -237,7 +240,7 @@ class AssetsController extends Controller
$constraint->upsize();
})->save($path);
$asset->image = $file_name;
} catch(\Exception $e) {
} catch (\Exception $e) {
\Input::flash();
$messageBag = new \Illuminate\Support\MessageBag();
$messageBag->add('image', $e->getMessage());
@@ -263,13 +266,8 @@ class AssetsController extends Controller
if ($asset->save()) {
if (Input::get('assigned_to')!='') {
$logaction = new Actionlog();
$logaction->asset_id = $asset->id;
$logaction->checkedout_to = $asset->assigned_to;
$logaction->asset_type = 'hardware';
$logaction->user_id = Auth::user()->id;
$logaction->note = e(Input::get('note'));
$log = $logaction->logaction('checkout');
$user = User::find(e(Input::get('assigned_to')));
$asset->checkOutToUser($user, Auth::user(), date('Y-m-d h:i:s'), '', 'Checked out on asset creation', e(Input::get('name')));
}
// Redirect to the asset listing page
\Session::flash('success', trans('admin/hardware/message.create.success'));
@@ -356,7 +354,7 @@ class AssetsController extends Controller
}
if ($request->has('purchase_cost')) {
$asset->purchase_cost = e($request->input('purchase_cost'));
$asset->purchase_cost = e(Helper::formatCurrencyOutput($request->input('purchase_cost')));
} else {
$asset->purchase_cost = null;
}
@@ -420,7 +418,7 @@ class AssetsController extends Controller
$constraint->upsize();
})->save($path);
$asset->image = $file_name;
} catch(\Exception $e) {
} catch (\Exception $e) {
\Input::flash();
$messageBag = new \Illuminate\Support\MessageBag();
$messageBag->add('image', $e->getMessage());
@@ -438,14 +436,22 @@ class AssetsController extends Controller
$model = AssetModel::find($request->get('model_id'));
if ($model->fieldset) {
foreach ($model->fieldset->fields as $field) {
$asset->{\App\Models\CustomField::name_to_db_name($field->name)} = e($request->input(\App\Models\CustomField::name_to_db_name($field->name)));
// LOG::debug($field->name);
// LOG::debug(\App\Models\CustomField::name_to_db_name($field->name));
// LOG::debug($field->db_column_name());
if ($field->field_encrypted=='1') {
if (Gate::allows('admin')) {
$asset->{\App\Models\CustomField::name_to_db_name($field->name)} = \Crypt::encrypt(e($request->input(\App\Models\CustomField::name_to_db_name($field->name))));
}
} else {
$asset->{\App\Models\CustomField::name_to_db_name($field->name)} = e($request->input(\App\Models\CustomField::name_to_db_name($field->name)));
}
}
}
if ($asset->save()) {
// Redirect to the new asset page
\Session::flash('success', trans('admin/hardware/message.update.success'));
@@ -532,6 +538,8 @@ class AssetsController extends Controller
return redirect()->to('hardware')->with('error', trans('admin/hardware/message.does_not_exist'));
} elseif (!Company::isCurrentUserHasAccess($asset)) {
return redirect()->to('hardware')->with('error', trans('general.insufficient_permissions'));
} elseif (!$asset->availableForCheckout()) {
return redirect()->to('hardware')->with('error', trans('admin/hardware/message.checkout.not_available'));
}
$user = User::find(e(Input::get('assigned_to')));
@@ -624,8 +632,13 @@ class AssetsController extends Controller
// Was the asset updated?
if ($asset->save()) {
$checkout_at = e(Input::get('checkin_at'));
$logaction = $asset->createLogRecord('checkin', $asset, $admin, $user, null, e(Input::get('note')), $checkout_at);
if ($request->input('checkin_at') == Carbon::now()->format('Y-m-d')) {
$checkin_at = Carbon::now();
} else {
$checkin_at = $request->input('checkin_at').' 00:00:00';
}
//$checkin_at = e(Input::get('checkin_at'));
$logaction = $asset->createLogRecord('checkin', $asset, $admin, $user, null, e(Input::get('note')), $checkin_at);
$settings = Setting::getSettings();
@@ -755,14 +768,20 @@ class AssetsController extends Controller
if ($settings->qr_code == '1') {
$asset = Asset::find($assetId);
$size = Helper::barcodeDimensions($settings->barcode_type);
$qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'.png';
if (isset($asset->id,$asset->asset_tag)) {
$barcode = new \Com\Tecnick\Barcode\Barcode();
$barcode_obj = $barcode->getBarcodeObj($settings->barcode_type, route('view/hardware', $asset->id), $size['height'], $size['width'], 'black', array(-2, -2, -2, -2));
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
if (file_exists($qr_file)) {
$header = ['Content-type' => 'image/png'];
return response()->file($qr_file, $header);
} else {
$barcode = new \Com\Tecnick\Barcode\Barcode();
$barcode_obj = $barcode->getBarcodeObj($settings->barcode_type, route('view/hardware', $asset->id), $size['height'], $size['width'], 'black', array(-2, -2, -2, -2));
file_put_contents($qr_file, $barcode_obj->getPngData());
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
}
}
}
@@ -782,12 +801,20 @@ class AssetsController extends Controller
$settings = Setting::getSettings();
$asset = Asset::find($assetId);
$barcode_file = public_path().'/uploads/barcodes/'.str_slug($settings->alt_barcode).'-'.str_slug($asset->asset_tag).'.png';
if (isset($asset->id,$asset->asset_tag)) {
$barcode = new \Com\Tecnick\Barcode\Barcode();
$barcode_obj = $barcode->getBarcodeObj($settings->alt_barcode, $asset->asset_tag, 250, 20);
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
if (file_exists($barcode_file)) {
$header = ['Content-type' => 'image/png'];
return response()->file($barcode_file, $header);
} else {
$barcode = new \Com\Tecnick\Barcode\Barcode();
$barcode_obj = $barcode->getBarcodeObj($settings->alt_barcode, $asset->asset_tag, 250, 20);
file_put_contents($barcode_file, $barcode_obj->getPngData());
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
}
}
}
@@ -873,11 +900,11 @@ class AssetsController extends Controller
try {
$file->move($path, $date.'-'.$fixed_filename);
} catch (\Symfony\Component\HttpFoundation\File\Exception\FileException $exception) {
$results['error']=trans('admin/hardware/message.upload.error');
if( config('app.debug')) {
$results['error'].= ' ' . $exception->getMessage();
}
return $results;
$results['error']=trans('admin/hardware/message.upload.error');
if (config('app.debug')) {
$results['error'].= ' ' . $exception->getMessage();
}
return $results;
}
$name = date('Y-m-d-his').'-'.$fixed_filename;
$filesize = Setting::fileSizeConvert(filesize($path.'/'.$name));
@@ -988,6 +1015,171 @@ class AssetsController extends Controller
}
/**
* Return history import view
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v1.0]
* @return View
*/
public function getImportHistory()
{
return View::make('hardware/history');
}
/**
* Import history
*
* This needs a LOT of love. It's done very inelegantly right now, and there are
* a ton of optimizations that could (and should) be done.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.3]
* @return View
*/
public function postImportHistory(Request $request)
{
if (!ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1');
}
$assets = Asset::all(['asset_tag']);
$csv = Reader::createFromPath(Input::file('user_import_csv'));
$csv->setNewline("\r\n");
//get the first row, usually the CSV header
//$headers = $csv->fetchOne();
$results = $csv->fetchAssoc();
$item = array();
$status = array();
foreach($results as $row) {
if (is_array($row)) {
$row = array_change_key_case($row, CASE_LOWER);
$asset_tag = Helper::array_smart_fetch($row, "asset tag");
if (!array_key_exists($asset_tag, $item)) {
$item[$asset_tag] = array();
}
$batch_counter = count($item[$asset_tag]);
$item[$asset_tag][$batch_counter]['checkout_date'] = Carbon::parse(Helper::array_smart_fetch($row, "date"))->format('Y-m-d H:i:s');
$item[$asset_tag][$batch_counter]['asset_tag'] = Helper::array_smart_fetch($row, "asset tag");
$item[$asset_tag][$batch_counter]['name'] = Helper::array_smart_fetch($row, "name");
$item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email");
$asset = Asset::where('asset_tag','=',$asset_tag)->first();
$item[$asset_tag][$batch_counter]['asset_id'] = $asset->id;
$base_username = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format,$item[$asset_tag][$batch_counter]['name']);
$user = User::where('username','=',$base_username['username']);
$user_query = ' on username '.$base_username['username'];
if ($request->input('match_firstnamelastname')=='1') {
$firstnamedotlastname = User::generateFormattedNameFromFullName('firstname.lastname',$item[$asset_tag][$batch_counter]['name']);
$item[$asset_tag][$batch_counter]['username'][] = $firstnamedotlastname['username'];
$user->orWhere('username','=',$firstnamedotlastname['username']);
$user_query .= ', or on username '.$firstnamedotlastname['username'];
}
if ($request->input('match_flastname')=='1') {
$flastname = User::generateFormattedNameFromFullName('filastname',$item[$asset_tag][$batch_counter]['name']);
$item[$asset_tag][$batch_counter]['username'][] = $flastname['username'];
$user->orWhere('username','=',$flastname['username']);
$user_query .= ', or on username '.$flastname['username'];
}
if ($request->input('match_firstname')=='1') {
$firstname = User::generateFormattedNameFromFullName('firstname',$item[$asset_tag][$batch_counter]['name']);
$item[$asset_tag][$batch_counter]['username'][] = $firstname['username'];
$user->orWhere('username','=',$firstname['username']);
$user_query .= ', or on username '.$firstname['username'];
}
if ($request->input('match_email')=='1') {
if ($item[$asset_tag][$batch_counter]['email']=='') {
$item[$asset_tag][$batch_counter]['username'][] = $user_email = User::generateEmailFromFullName($item[$asset_tag][$batch_counter]['name']);
$user->orWhere('username','=',$user_email);
$user_query .= ', or on username '.$user_email;
}
}
// A matching user was found
if ($user = $user->first()) {
$item[$asset_tag][$batch_counter]['checkedout_to'] = $user->id;
$status['success'][] = 'Found user '.Helper::array_smart_fetch($row, "name").$user_query;
if ($asset) {
$item[$asset_tag][$batch_counter]['user_id'] = $user->id;
Actionlog::firstOrCreate(array(
'asset_id' => $asset->id,
'asset_type' => 'hardware',
'user_id' => Auth::user()->id,
'note' => 'Checkout imported by '.Auth::user()->fullName().' from history importer',
'checkedout_to' => $item[$asset_tag][$batch_counter]['user_id'],
'created_at' => $item[$asset_tag][$batch_counter]['checkout_date'],
'action_type' => 'checkout'
)
);
$asset->assigned_to = $user->id;
$asset->save();
} else {
$status['error'][] = 'Asset does not exist so no checkin log was created.';
}
} else {
$item[$asset_tag][$batch_counter]['checkedout_to'] = null;
$status['error'][] = 'No matching user for '.Helper::array_smart_fetch($row, "name");
}
}
}
// Loop through and backfill the checkins
foreach ($item as $key => $asset_batch) {
$total_in_batch = count($asset_batch);
for($x = 0; $x < $total_in_batch; $x++) {
$next = $x + 1;
// Only do this if a matching user was found
if ($asset_batch[$x]['checkedout_to']!='') {
if (($total_in_batch > 1) && ($x < $total_in_batch) && (array_key_exists($next,$asset_batch))) {
$checkin_date = Carbon::parse($asset_batch[$next]['checkout_date'])->subDay(1)->format('Y-m-d H:i:s');
$asset_batch[$x]['real_checkin'] = $checkin_date;
Actionlog::firstOrCreate(array(
'asset_id' => $asset_batch[$x]['asset_id'],
'asset_type' => 'hardware',
'user_id' => Auth::user()->id,
'note' => 'Checkin imported by ' . Auth::user()->fullName() . ' from history importer',
'checkedout_to' => null,
'created_at' => $checkin_date,
'action_type' => 'checkin'
)
);
}
}
}
}
return View::make('hardware/history')->with('status',$status);
}
/**
* Retore a deleted asset.
*
@@ -1404,31 +1596,31 @@ class AssetsController extends Controller
* @since [v2.0]
* @return String JSON
*/
public function getDatatable($status = null)
public function getDatatable(Request $request, $status = null)
{
$assets = Asset::select('assets.*')->with('model', 'assigneduser', 'assigneduser.userloc', 'assetstatus', 'defaultLoc', 'assetlog', 'model', 'model.category', 'model.manufacturer', 'model.fieldset', 'assetstatus', 'assetloc', 'company')
$assets = Company::scopeCompanyables(Asset::select('assets.*'))->with('model', 'assigneduser', 'assigneduser.userloc', 'assetstatus', 'defaultLoc', 'assetlog', 'model', 'model.category', 'model.manufacturer', 'model.fieldset', 'assetstatus', 'assetloc', 'company')
->Hardware();
if (Input::has('search')) {
$assets = $assets->TextSearch(e(Input::get('search')));
if ($request->has('search')) {
$assets = $assets->TextSearch(e($request->get('search')));
}
if (Input::has('offset')) {
$offset = e(Input::get('offset'));
if ($request->has('offset')) {
$offset = e($request->get('offset'));
} else {
$offset = 0;
}
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
if ($request->has('limit')) {
$limit = e($request->get('limit'));
} else {
$limit = 50;
}
if (Input::has('order_number')) {
$assets->where('order_number', '=', e(Input::get('order_number')));
if ($request->has('order_number')) {
$assets->where('order_number', '=', e($request->get('order_number')));
}
switch ($status) {
@@ -1456,6 +1648,12 @@ class AssetsController extends Controller
}
if ($request->has('status_id')) {
$assets->where('status_id','=', e($request->get('status_id')));
}
$allowed_columns = [
'id',
'name',
@@ -1485,8 +1683,8 @@ class AssetsController extends Controller
$allowed_columns[]=$field->db_column_name();
}
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? Input::get('sort') : 'asset_tag';
$order = $request->get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'asset_tag';
switch ($sort) {
case 'model':
@@ -1525,23 +1723,42 @@ class AssetsController extends Controller
$rows = array();
foreach ($assets as $asset) {
$inout = '';
$actions = '';
$actions = '<div style="white-space: nowrap;">';
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" data-toggle="tooltip"><i class="fa fa-clone"></i></a> <a href="'.route('update/hardware', $asset->id).'" class="btn btn-warning btn-sm" title="Edit asset" data-toggle="tooltip"><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>';
if (Gate::allows('assets.create')) {
$actions .= '<a href="' . route('clone/hardware',
$asset->id) . '" class="btn btn-info btn-sm" title="Clone asset" data-toggle="tooltip"><i class="fa fa-clone"></i></a> ';
}
if (Gate::allows('assets.edit')) {
$actions .= '<a href="' . route('update/hardware',
$asset->id) . '" class="btn btn-warning btn-sm" title="Edit asset" data-toggle="tooltip"><i class="fa fa-pencil icon-white"></i></a> ';
}
if (Gate::allows('assets.delete')) {
$actions .= '<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>';
}
} elseif ($asset->model->deleted_at=='') {
$actions = '<a href="'.route('restore/hardware', $asset->id).'" title="Restore asset" data-toggle="tooltip" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
$actions .= '<a href="'.route('restore/hardware', $asset->id).'" title="Restore asset" data-toggle="tooltip" class="btn btn-warning btn-sm"><i class="fa fa-recycle icon-white"></i></a>';
}
if ($asset->assetstatus) {
if (($asset->assetstatus->deployable != 0) && ($asset->deleted_at=='')) {
if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm" title="Checkin this asset" data-toggle="tooltip">'.trans('general.checkin').'</a>';
} else {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm" title="Checkout this asset to a user" data-toggle="tooltip">'.trans('general.checkout').'</a>';
}
$actions .= '</div>';
if (($asset->availableForCheckout()))
{
if (Gate::allows('assets.checkout')) {
$inout = '<a href="' . route('checkout/hardware',
$asset->id) . '" class="btn btn-info btn-sm" title="Checkout this asset to a user" data-toggle="tooltip">' . trans('general.checkout') . '</a>';
}
} else {
if (Gate::allows('assets.checkin')) {
$inout = '<a href="' . route('checkin/hardware',
$asset->id) . '" class="btn btn-primary btn-sm" title="Checkin this asset" data-toggle="tooltip">' . trans('general.checkin') . '</a>';
}
}
$purchase_cost = Helper::formatCurrencyOutput($asset->purchase_cost);
$row = array(
'checkbox' =>'<div class="text-center"><input type="checkbox" name="edit_asset['.$asset->id.']" class="one_required"></div>',
'id' => $asset->id,
@@ -1557,7 +1774,7 @@ class AssetsController extends Controller
'category' => (($asset->model) && ($asset->model->category)) ?(string)link_to('/admin/settings/categories/'.$asset->model->category->id.'/view', e($asset->model->category->name)) : '',
'manufacturer' => (($asset->model) && ($asset->model->manufacturer)) ? (string)link_to('/admin/settings/manufacturers/'.$asset->model->manufacturer->id.'/view', e($asset->model->manufacturer->name)) : '',
'eol' => ($asset->eol_date()) ? $asset->eol_date() : '',
'purchase_cost' => ($asset->purchase_cost) ? number_format($asset->purchase_cost, 2) : '',
'purchase_cost' => $purchase_cost,
'purchase_date' => ($asset->purchase_date) ? $asset->purchase_date : '',
'notes' => e($asset->notes),
'order_number' => ($asset->order_number!='') ? '<a href="'.config('app.url').'/hardware?order_number='.e($asset->order_number).'">'.e($asset->order_number).'</a>' : '',
@@ -1569,7 +1786,28 @@ class AssetsController extends Controller
'companyName' => is_null($asset->company) ? '' : e($asset->company->name)
);
foreach ($all_custom_fields as $field) {
$row[$field->db_column_name()]=$asset->{$field->db_column_name()};
$column_name = $field->db_column_name();
if ($field->isFieldDecryptable($asset->{$column_name})) {
if (Gate::allows('admin')) {
if (($field->format=='URL') && ($asset->{$column_name}!='')) {
$row[$column_name] = '<a href="'.Helper::gracefulDecrypt($field, $asset->{$column_name}).'" target="_blank">'.Helper::gracefulDecrypt($field, $asset->{$column_name}).'</a>';
} else {
$row[$column_name] = Helper::gracefulDecrypt($field, $asset->{$column_name});
}
} else {
$row[$field->db_column_name()] = strtoupper(trans('admin/custom_fields/general.encrypted'));
}
} else {
if (($field->format=='URL') && ($asset->{$field->db_column_name()}!='')) {
$row[$field->db_column_name()] = '<a href="'.$asset->{$field->db_column_name()}.'" target="_blank">'.$asset->{$field->db_column_name()}.'</a>';
} else {
$row[$field->db_column_name()] = e($asset->{$field->db_column_name()});
}
}
}
$rows[]=$row;
}
@@ -1578,4 +1816,68 @@ class AssetsController extends Controller
return $data;
}
public function getBulkCheckout()
{
// Get the dropdown of users and then pass it to the checkout view
$users_list = Helper::usersList();
// Filter out assets that are not deployable.
$assets = Asset::RTD()->get();
$assets_list = Company::scopeCompanyables($assets, 'assets.company_id')->lists('detailed_name', 'id')->toArray();
return View::make('hardware/bulk-checkout')->with('users_list', $users_list)->with('assets_list', $assets_list);
}
public function postBulkCheckout(Request $request)
{
$this->validate($request, [
"assigned_to" => 'required'
]);
$user = User::find(e(Input::get('assigned_to')));
$admin = Auth::user();
$asset_ids = array_filter(Input::get('selected_assets'));
if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) {
$checkout_at = e(Input::get('checkout_at'));
} else {
$checkout_at = date("Y-m-d H:i:s");
}
if (Input::has('expected_checkin')) {
$expected_checkin = e(Input::get('expected_checkin'));
} else {
$expected_checkin = '';
}
$has_errors = false;
$errors = [];
DB::transaction(function() use ($user, $admin, $checkout_at, $expected_checkin, $errors, $asset_ids)
{
foreach($asset_ids as $asset_id)
{
$asset = Asset::find($asset_id);
$error = $asset->checkOutToUser($user, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), null);
if($error)
{
$has_errors = true;
array_merge_recursive($errors, $asset->getErrors()->toArray());
}
}
});
if (!$errors) {
// Redirect to the new asset page
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.checkout.success'));
}
// Redirect to the asset management page with error
return redirect()->to("hardware/bulk-checkout")->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($errors);
}
}

View File

@@ -108,7 +108,7 @@ class AuthController extends Controller
LOG::debug("Creating local user ".Input::get('username'));
if ($newuser = Ldap::createUserFromLdap($userattr)) {
LOG::debug("Local user created..");
LOG::debug("Local user created.");
} else {
LOG::debug("Could not create local user.");
}
@@ -131,12 +131,21 @@ class AuthController extends Controller
LOG::debug("Valid LDAP login. Updating the local data.");
$user->password = bcrypt($request->input('password'));
if (Setting::getSettings()->ldap_pw_sync=='1') {
$user->password = bcrypt($request->input('password'));
}
$user->email = $ldap_attr['email'];
$user->first_name = $ldap_attr['firstname'];
$user->last_name = $ldap_attr['lastname'];
$user->save();
if (Setting::getSettings()->ldap_pw_sync!='1') {
Auth::login($user, true);
// Redirect to the users page
return redirect()->to('/home')->with('success', trans('auth/message.signin.success'));
}
} else {
LOG::debug("User ".Input::get('username')." did not authenticate correctly against LDAP. Local user was not updated.");
}// End LDAP auth
@@ -146,14 +155,17 @@ class AuthController extends Controller
// NO LDAP enabled - just try to login the user normally
}
LOG::debug("Authenticating user against database.");
// Try to log the user in
if (!Auth::attempt(Input::only('username', 'password'), Input::get('remember-me', 0))) {
LOG::debug("Local authentication failed.");
// throw new Cartalyst\Sentry\Users\UserNotFoundException();
// throw new Cartalyst\Sentry\Users\UserNotFoundException();
return redirect()->back()->withInput()->with('error', trans('auth/message.account_not_found'));
}
// Get the page we were before
$redirect = \Session::get('loginRedirect', 'home');

View File

@@ -7,6 +7,8 @@ use App\Models\Company;
use App\Models\Setting;
use Auth;
use DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Gate;
use Input;
use Lang;
use Redirect;
@@ -133,7 +135,7 @@ class CategoriesController extends Controller
* @since [v1.0]
* @return Redirect
*/
public function postEdit($categoryId = null)
public function postEdit(Request $request, $categoryId = null)
{
// Check if the blog post exists
if (is_null($category = Category::find($categoryId))) {
@@ -142,12 +144,14 @@ class CategoriesController extends Controller
}
// 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->name = e($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'));
if ($category->save()) {
// Redirect to the new category page
@@ -341,13 +345,13 @@ class CategoriesController extends Controller
$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->assetstatus) {
if ($asset->assetstatus->deployable != 0) {
if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
} else {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</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>';
}
}

View File

@@ -20,6 +20,7 @@ use Str;
use View;
use Validator;
use Illuminate\Http\Request;
use Gate;
/**
* This class controls all actions related to Components for
@@ -374,7 +375,7 @@ class ComponentsController extends Controller
'fields' => [
[
'title' => 'Checked Out:',
'value' => strtoupper($logaction->asset_type).' <'.config('app.url').'/admin/components/'.$component->id.'/view'.'|'.$component->name.'> checked out to <'.config('app.url').'/hardware/'.$asset->id.'/view|'.$asset->name.'> by <'.config('app.url').'/admin/users/'.$admin_user->id.'/view'.'|'.$admin_user->fullName().'>.'
'value' => strtoupper($logaction->asset_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:',
@@ -410,8 +411,8 @@ class ComponentsController extends Controller
**/
public function getDatatable()
{
$components = Component::select('components.*')->whereNull('components.deleted_at')
->with('company', 'location', 'category');
$components = Company::scopeCompanyables(Component::select('components.*')->whereNull('components.deleted_at')
->with('company', 'location', 'category'));
if (Input::has('search')) {
$components = $components->TextSearch(Input::get('search'));
@@ -454,7 +455,23 @@ class ComponentsController extends Controller
$rows = array();
foreach ($components as $component) {
$actions = '<nobr><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><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><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></nobr>';
$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(
@@ -467,7 +484,7 @@ class ComponentsController extends Controller
'category' => ($component->category) ? e($component->category->name) : 'Missing category',
'order_number' => e($component->order_number),
'purchase_date' => e($component->purchase_date),
'purchase_cost' => ($component->purchase_cost!='') ? number_format($component->purchase_cost, 2): '' ,
'purchase_cost' => Helper::formatCurrencyOutput($component->purchase_cost),
'numRemaining' => $component->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name),
@@ -503,7 +520,7 @@ class ComponentsController extends Controller
foreach ($component->assets as $component_assignment) {
$rows[] = array(
'name' => (string)link_to('/hardware/'.$component_assignment->id.'/view', e($component_assignment->name)),
'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'),
);

View File

@@ -18,6 +18,7 @@ use Redirect;
use Slack;
use Str;
use View;
use Gate;
/**
* This controller handles all actions related to Consumables for
@@ -397,8 +398,8 @@ class ConsumablesController extends Controller
*/
public function getDatatable()
{
$consumables = Consumable::select('consumables.*')->whereNull('consumables.deleted_at')
->with('company', 'location', 'category', 'users');
$consumables = Company::scopeCompanyables(Consumable::select('consumables.*')->whereNull('consumables.deleted_at')
->with('company', 'location', 'category', 'users'));
if (Input::has('search')) {
$consumables = $consumables->TextSearch(e(Input::get('search')));
@@ -444,7 +445,23 @@ class ConsumablesController extends Controller
$rows = array();
foreach ($consumables as $consumable) {
$actions = '<nobr><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><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><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></nobr>';
$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(
@@ -453,13 +470,13 @@ class ConsumablesController extends Controller
'location' => ($consumable->location) ? e($consumable->location->name) : '',
'min_amt' => e($consumable->min_amt),
'qty' => e($consumable->qty),
'manufacturer' => ($consumable->manufacturer) ? e($consumable->manufacturer->name) : '',
'model_no' => e($consumable->model_no),
'item_no' => e($consumable->item_no),
'category' => ($consumable->category) ? e($consumable->category->name) : 'Missing category',
'manufacturer' => ($consumable->manufacturer) ? (string) link_to('/admin/settings/manufacturers/'.$consumable->manufacturer_id.'/view', $consumable->manufacturer->name): '',
'model_no' => e($consumable->model_no),
'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): '' ,
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
'numRemaining' => $consumable->numRemaining(),
'actions' => $actions,
'companyName' => is_null($company) ? '' : e($company->name),

View File

@@ -10,6 +10,7 @@ use Redirect;
use App\Models\AssetModel;
use Lang;
use Auth;
use Illuminate\Http\Request;
/**
* This controller handles all actions related to Custom Asset Fields for
@@ -63,10 +64,15 @@ class CustomFieldsController extends Controller
* @since [v1.8]
* @return Redirect
*/
public function store()
public function store(Request $request)
{
//
$cfset=new CustomFieldset(["name" => Input::get("name"),"user_id" => Auth::user()->id]);
$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();
@@ -122,24 +128,33 @@ class CustomFieldsController extends Controller
* @since [v1.8]
* @return Redirect
*/
public function storeField()
public function storeField(Request $request)
{
$field=new CustomField(["name" => Input::get("name"),"element" => Input::get("element"),"user_id" => Auth::user()->id]);
$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)),
"user_id" => Auth::user()->id
]);
if (!in_array(Input::get('format'), array_keys(CustomField::$PredefinedFormats))) {
$field->format=Input::get("custom_format");
$field->format = e($request->get("custom_format"));
} else {
$field->format=Input::get('format');
$field->format = e($request->get("format"));
}
$validator=Validator::make(Input::all(), $field->rules);
if ($validator->passes()) {
$results=$field->save();
//return "postCreateField: $results";
$results = $field->save();
if ($results) {
return redirect()->route("admin.custom_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'));
}
} else {
@@ -147,6 +162,25 @@ class CustomFieldsController extends Controller
}
}
/**
* Detach a custom field from a fieldset.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return Redirect
*/
public function deleteFieldFromFieldset($field_id, $fieldset_id)
{
$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()->back()->withErrors(['message' => "Field is in-use"]);
}
/**
* Delete a custom field.
*
@@ -156,7 +190,7 @@ class CustomFieldsController extends Controller
*/
public function deleteField($field_id)
{
$field=CustomField::find($field_id);
$field = CustomField::find($field_id);
if ($field->fieldset->count()>0) {
return redirect()->back()->withErrors(['message' => "Field is in-use"]);

View File

@@ -32,7 +32,7 @@ class DashboardController extends Controller
$recent_activity = Actionlog::orderBy('created_at', 'DESC')
->with('accessorylog', 'consumablelog', 'licenselog', 'assetlog', 'adminlog', 'userlog', 'componentlog')
->take(30)
->take(20)
->get();

View File

@@ -23,6 +23,7 @@ use Config;
use Session;
use App\Helpers\Helper;
use Auth;
use Gate;
/**
* This controller handles all actions related to Licenses for
@@ -60,18 +61,17 @@ class LicensesController extends Controller
public function getCreate()
{
$depreciation_list = Helper::depreciationList();
$supplier_list = Helper::suppliersList();
$maintained_list = array('' => 'Maintained', '1' => 'Yes', '0' => 'No');
$company_list = Helper::companyList();
return View::make('licenses/edit')
//->with('license_options',$license_options)
->with('depreciation_list', $depreciation_list)
->with('supplier_list', $supplier_list)
->with('depreciation_list', Helper::depreciationList())
->with('supplier_list', Helper::suppliersList())
->with('maintained_list', $maintained_list)
->with('company_list', $company_list)
->with('company_list', Helper::companyList())
->with('manufacturer_list', Helper::manufacturerList())
->with('license', new License);
}
@@ -124,6 +124,12 @@ class LicensesController extends Controller
$license->purchase_order = e(Input::get('purchase_order'));
}
if (empty(e(Input::get('manufacturer_id')))) {
$license->manufacturer_id = null;
} else {
$license->manufacturer_id = e(Input::get('manufacturer_id'));
}
// Save the license data
$license->name = e(Input::get('name'));
$license->serial = e(Input::get('serial'));
@@ -205,17 +211,15 @@ class LicensesController extends Controller
// Show the page
$license_options = array('' => 'Top Level') + DB::table('assets')->where('id', '!=', $licenseId)->pluck('name', 'id');
$depreciation_list = array('0' => trans('admin/licenses/form.no_depreciation')) + Depreciation::pluck('name', 'id')->toArray();
$supplier_list = array('' => 'Select Supplier') + Supplier::orderBy('name', 'asc')->pluck('name', 'id')->toArray();
$maintained_list = array('' => 'Maintained', '1' => 'Yes', '0' => 'No');
$company_list = Helper::companyList();
return View::make('licenses/edit', compact('license'))
->with('license_options', $license_options)
->with('depreciation_list', $depreciation_list)
->with('supplier_list', $supplier_list)
->with('company_list', $company_list)
->with('maintained_list', $maintained_list);
->with('depreciation_list', Helper::depreciationList())
->with('supplier_list', Helper::suppliersList())
->with('company_list', Helper::companyList())
->with('maintained_list', $maintained_list)
->with('manufacturer_list', Helper::manufacturerList());
}
@@ -252,6 +256,13 @@ class LicensesController extends Controller
$license->maintained = e(Input::get('maintained'));
$license->reassignable = e(Input::get('reassignable'));
if (empty(e(Input::get('manufacturer_id')))) {
$license->manufacturer_id = null;
} else {
$license->manufacturer_id = e(Input::get('manufacturer_id'));
}
if (e(Input::get('supplier_id')) == '') {
$license->supplier_id = null;
} else {
@@ -501,7 +512,7 @@ class LicensesController extends Controller
}
if (($asset->assigned_to!='') && (($asset->assigned_to!=$assigned_to)) && ($assigned_to!='') ) {
if (($asset->assigned_to!='') && (($asset->assigned_to!=$assigned_to)) && ($assigned_to!='')) {
return redirect()->to('admin/licenses')->with('error', trans('admin/licenses/message.owner_doesnt_match_asset'));
}
@@ -551,7 +562,7 @@ class LicensesController extends Controller
$slack_msg = strtoupper($logaction->asset_type).' license <'.config('app.url').'/admin/licenses/'.$license->id.'/view'.'|'.$license->name.'> checked out to <'.config('app.url').'/hardware/'.$asset->id.'/view|'.$asset->showAssetName().'> by <'.config('app.url').'/admin/users/'.$user->id.'/view'.'|'.$user->fullName().'>.';
} else {
$logaction->checkedout_to = e(Input::get('assigned_to'));
$slack_msg = strtoupper($logaction->asset_type).' license <'.config('app.url').'/admin/licenses/'.$license->id.'/view'.'|'.$license->name.'> checked out to <'.config('app.url').'/admin/users/'.$asset->id.'/view|'.$is_assigned_to->fullName().'> by <'.config('app.url').'/admin/users/'.$user->id.'/view'.'|'.$user->fullName().'>.';
$slack_msg = strtoupper($logaction->asset_type).' license <'.config('app.url').'/admin/licenses/'.$license->id.'/view'.'|'.$license->name.'> checked out to <'.config('app.url').'/admin/users/'.$user->id.'/view|'.$is_assigned_to->fullName().'> by <'.config('app.url').'/admin/users/'.$user->id.'/view'.'|'.$user->fullName().'>.';
}
@@ -965,7 +976,7 @@ class LicensesController extends Controller
*/
public function getDatatable()
{
$licenses = License::with('company');
$licenses = Company::scopeCompanyables(License::with('company'));
if (Input::has('search')) {
$licenses = $licenses->TextSearch(Input::get('search'));
@@ -983,7 +994,27 @@ class LicensesController extends Controller
$rows = array();
foreach ($licenses as $license) {
$actions = '<span style="white-space: nowrap;"><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> <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><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><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></span>';
$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,
@@ -992,15 +1023,16 @@ class LicensesController extends Controller
'totalSeats' => $license->totalSeatsByLicenseID(),
'remaining' => $license->remaincount(),
'license_name' => e($license->license_name),
'license_email' => e($license->license_email),
'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_cost' => Helper::formatCurrencyOutput($license->purchase_cost),
'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)
'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) : ''
);
}

View File

@@ -2,14 +2,15 @@
namespace App\Http\Controllers;
use App\Models\Company;
use App\Models\Manufacturer;
use App\Models\Setting;
use Auth;
use Gate;
use Input;
use Lang;
use App\Models\Manufacturer;
use Redirect;
use App\Models\Setting;
use Str;
use View;
use Auth;
/**
* This controller handles all actions related to Manufacturers for
@@ -254,10 +255,27 @@ class ManufacturersController extends Controller
* @since [v1.0]
* @return String JSON
*/
public function getDataView($manufacturerId)
public function getDataView($manufacturerId, $itemtype = null)
{
$manufacturer = Manufacturer::with('assets.company')->find($manufacturerId);
switch ($itemtype) {
case "assets":
return $this->getDataAssetsView($manufacturer);
case "licenses":
return $this->getDataLicensesView($manufacturer);
case "accessories":
return $this->getDataAccessoriesView($manufacturer);
case "consumables":
return $this->getDataConsumablesView($manufacturer);
}
throw new Exception("We shouldn't be here");
}
protected function getDataAssetsView(Manufacturer $manufacturer)
{
$manufacturer_assets = $manufacturer->assets;
if (Input::has('search')) {
@@ -293,35 +311,213 @@ class ManufacturersController extends Controller
$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->assetstatus) {
if ($asset->assetstatus->deployable != 0) {
if (($asset->assigned_to !='') && ($asset->assigned_to > 0)) {
$inout = '<a href="'.route('checkin/hardware', $asset->id).'" class="btn btn-primary btn-sm">'.trans('general.checkin').'</a>';
} else {
$inout = '<a href="'.route('checkout/hardware', $asset->id).'" class="btn btn-info btn-sm">'.trans('general.checkout').'</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>';
}
}
$row = 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)),
);
$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)),
);
if (isset($inout)) {
$row['change'] = $inout;
if (isset($inout)) {
$row['change'] = $inout;
}
}
$rows[] = $row;
}
$data = array('total' => $count, 'rows' => $rows);
return $data;
}
protected function getDataLicensesView(Manufacturer $manufacturer)
{
$licenses = $manufacturer->licenses;
if (Input::has('search')) {
$licenses = $licenses->TextSearch(Input::get('search'));
}
$licenseCount = $licenses->count();
$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->totalSeatsByLicenseID(),
'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) : ''
);
}
$data = array('total' => $licenseCount, 'rows' => $rows);
return $data;
}
public function getDataAccessoriesView(Manufacturer $manufacturer)
{
$accessories = $manufacturer->accessories;
if (Input::has('search')) {
$accessories = $accessories->TextSearch(e(Input::get('search')));
}
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
} else {
$limit = 50;
}
$accessCount = $accessories->count();
$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) : ''
);
}
$data = array('total'=>$accessCount, 'rows'=>$rows);
return $data;
}
public function getDataConsumablesView($manufacturer)
{
$consumables = $manufacturer->consumables;
if (Input::has('search')) {
$consumables = $consumables->TextSearch(e(Input::get('search')));
}
if (Input::has('limit')) {
$limit = e(Input::get('limit'));
} else {
$limit = 50;
}
$consumCount = $consumables->count();
$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_no' => e($consumable->model_no),
'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),
);
}
$data = array('total' => $consumCount, 'rows' => $rows);
return $data;
}
}

View File

@@ -1,25 +1,26 @@
<?php
namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Models\Accessory;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\AssetMaintenance;
use Carbon\Carbon;
use Category;
use App\Models\AssetModel;
use App\Models\Company;
use App\Models\CustomField;
use App\Models\License;
use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\View;
use Input;
use League\Csv\Reader;
use App\Models\License;
use App\Models\Location;
use App\Models\AssetModel;
use Redirect;
use App\Models\Setting;
use App\Models\User;
/**
* This controller handles all actions related to Reports for
@@ -166,7 +167,7 @@ class ReportsController extends Controller
$row[] = '';
}
$row[] = $asset->purchase_date;
$row[] = '"' . number_format($asset->purchase_cost, 2) . '"';
$row[] = '"' . Helper::parsePurchasedCost($asset->purchase_cost) . '"';
if ($asset->order_number) {
$row[] = e($asset->order_number);
} else {
@@ -308,9 +309,9 @@ class ReportsController extends Controller
}
$row[] = $asset->purchase_date;
$row[] = $currency . number_format($asset->purchase_cost, 2);
$row[] = $currency . number_format($asset->getDepreciatedValue(), 2);
$row[] = $currency . number_format(( $asset->purchase_cost - $asset->getDepreciatedValue() ), 2);
$row[] = $currency . Helper::formatCurrencyOutput($asset->purchase_cost);
$row[] = $currency . Helper::formatCurrencyOutput($asset->getDepreciatedValue());
$row[] = $currency . Helper::formatCurrencyOutput(( $asset->purchase_cost - $asset->getDepreciatedValue() ));
$csv->insertOne($row);
}
@@ -392,7 +393,7 @@ class ReportsController extends Controller
$row[] = $license->remaincount();
$row[] = $license->expiration_date;
$row[] = $license->purchase_date;
$row[] = '"' . number_format($license->purchase_cost, 2) . '"';
$row[] = '"' . Helper::formatCurrencyOutput($license->purchase_cost) . '"';
$rows[] = implode($row, ',');
}
@@ -415,8 +416,8 @@ class ReportsController extends Controller
*/
public function getCustomReport()
{
return View::make('reports/custom');
$customfields = CustomField::get();
return View::make('reports/custom')->with('customfields', $customfields);
}
/**
@@ -430,6 +431,7 @@ class ReportsController extends Controller
public function postCustom()
{
$assets = Asset::orderBy('created_at', 'DESC')->get();
$customfields = CustomField::get();
$rows = [ ];
$header = [ ];
@@ -471,6 +473,9 @@ class ReportsController extends Controller
if (e(Input::get('assigned_to')) == '1') {
$header[] = 'Assigned To';
}
if (e(Input::get('username')) == '1') {
$header[] = 'Username';
}
if (e(Input::get('status')) == '1') {
$header[] = 'Status';
}
@@ -484,6 +489,13 @@ class ReportsController extends Controller
$header[] = 'Diff';
}
foreach ($customfields as $customfield) {
if (e(Input::get($customfield->db_column_name())) == '1') {
$header[] = $customfield->name;
}
}
$header = array_map('trim', $header);
$rows[] = implode($header, ',');
@@ -517,7 +529,7 @@ class ReportsController extends Controller
$row[] = e($asset->purchase_date);
}
if (e(Input::get('purchase_cost')) == '1' && ( e(Input::get('depreciation')) != '1' )) {
$row[] = '"' . number_format($asset->purchase_cost, 2) . '"';
$row[] = '"' . Helper::formatCurrencyOutput($asset->purchase_cost) . '"';
}
if (e(Input::get('order')) == '1') {
if ($asset->order_number) {
@@ -562,6 +574,16 @@ class ReportsController extends Controller
$row[] = ''; // Empty string if unassigned
}
}
if (e(Input::get('username')) == '1') {
if ($asset->assigned_to > 0) {
$user = User::find($asset->assigned_to);
$row[] = '"' .e($user->username). '"';
} else {
$row[] = ''; // Empty string if unassigned
}
}
if (e(Input::get('status')) == '1') {
if (( $asset->status_id == '0' ) && ( $asset->assigned_to == '0' )) {
$row[] = trans('general.ready_to_deploy');
@@ -584,10 +606,19 @@ class ReportsController extends Controller
}
if (e(Input::get('depreciation')) == '1') {
$depreciation = $asset->getDepreciatedValue();
$row[] = '"' . number_format($asset->purchase_cost, 2) . '"';
$row[] = '"' . number_format($depreciation, 2) . '"';
$row[] = '"' . number_format($asset->purchase_cost - $depreciation, 2) . '"';
$row[] = '"' . Helper::formatCurrencyOutput($asset->purchase_cost) . '"';
$row[] = '"' . Helper::formatCurrencyOutput($depreciation) . '"';
$row[] = '"' . Helper::formatCurrencyOutput($asset->purchase_cost) . '"';
}
foreach ($customfields as $customfield) {
$column_name = $customfield->db_column_name();
if (e(Input::get($customfield->db_column_name())) == '1') {
$row[] = $asset->$column_name;
}
}
$rows[] = implode($row, ',');
}
@@ -668,7 +699,7 @@ class ReportsController extends Controller
$improvementTime = intval($assetMaintenance->asset_maintenance_time);
}
$row[] = $improvementTime;
$row[] = trans('general.currency') . number_format($assetMaintenance->cost, 2);
$row[] = trans('general.currency') . Helper::formatCurrencyOutput($assetMaintenance->cost);
$rows[] = implode($row, ',');
}

View File

@@ -348,6 +348,7 @@ class SettingsController extends Controller
$setting->qr_text = e(Input::get('qr_text'));
$setting->auto_increment_prefix = e(Input::get('auto_increment_prefix'));
$setting->auto_increment_assets = e(Input::get('auto_increment_assets', '0'));
$setting->zerofill_count = e(Input::get('zerofill_count'));
$setting->alert_interval = e(Input::get('alert_interval'));
$setting->alert_threshold = e(Input::get('alert_threshold'));
$setting->email_domain = e(Input::get('email_domain'));
@@ -415,6 +416,8 @@ class SettingsController extends Controller
$setting->ldap_email = e(Input::get('ldap_email'));
$setting->ad_domain = e(Input::get('ad_domain'));
$setting->is_ad = e(Input::get('is_ad', '0'));
$setting->ldap_tls = e(Input::get('ldap_tls', '0'));
$setting->ldap_pw_sync = e(Input::get('ldap_pw_sync', '0'));
// If validation fails, we'll exit the operation now.
if ($setting->save()) {

View File

@@ -47,23 +47,32 @@ class StatuslabelsController extends Controller
{
$colors = [];
$statuslabels = Statuslabel::get();
$statuslabels = Statuslabel::with('assets')->get();
$labels=[];
$points=[];
$colors=[];
foreach ($statuslabels as $statuslabel) {
$labels[]=$statuslabel->name;
$points[]=$statuslabel->assets()->whereNull('assigned_to')->count();
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" => Helper::chartColors(),
"hoverBackgroundColor" => Helper::chartColors()
"backgroundColor" => $colors_array,
"hoverBackgroundColor" => $colors_array
]]
];
return $result;
@@ -110,6 +119,8 @@ class StatuslabelsController extends Controller
$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);
// Was the asset created?
@@ -197,6 +208,8 @@ class StatuslabelsController extends Controller
$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);
// Was the asset created?
@@ -247,7 +260,7 @@ class StatuslabelsController extends Controller
public function getDatatable()
{
$statuslabels = Statuslabel::select(array('id','name','deployable','pending','archived'))
$statuslabels = Statuslabel::select(array('id','name','deployable','pending','archived','color','show_in_nav'))
->whereNull('deleted_at');
if (Input::has('search')) {
@@ -291,10 +304,19 @@ class StatuslabelsController extends Controller
$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
);
}

View File

@@ -33,6 +33,7 @@ use Symfony\Component\HttpFoundation\JsonResponse;
use URL;
use View;
use Illuminate\Http\Request;
use Gate;
/**
* This controller handles all actions related to Users for
@@ -145,7 +146,7 @@ class UsersController extends Controller
} else {
$user->groups()->sync(array());
}
if (($request->input('email_user') == 1) && ($request->has('email'))) {
// Send the credentials through email
$data = array();
@@ -853,7 +854,7 @@ class UsersController extends Controller
* @see UsersController::getIndex() method that consumed this JSON response
* @return string JSON
*/
public function getDatatable($status = null)
public function getDatatable(Request $request, $status = null)
{
if (Input::has('offset')) {
@@ -875,7 +876,7 @@ class UsersController extends Controller
}
$users = User::select(array('users.id','users.employee_num','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.deleted_at','users.activated'))
->with('assets', 'accessories', 'consumables', 'licenses', 'manager', 'groups', 'userloc', 'company');
->with('assets', 'accessories', 'consumables', 'licenses', 'manager', 'groups', 'userloc', 'company','throttle');
$users = Company::scopeCompanyables($users);
switch ($status) {
@@ -923,25 +924,38 @@ class UsersController extends Controller
}
if (!is_null($user->deleted_at)) {
$actions .= '<a href="' . route('restore/user', $user->id) . '" class="btn btn-warning btn-sm"><i class="fa fa-share icon-white"></i></a> ';
} else {
if ($user->accountStatus() == 'suspended') {
$actions .= '<a href="' . route('unsuspend/user', $user->id) . '" class="btn btn-default btn-sm"><span class="fa fa-clock-o"></span></a> ';
}
$actions .= '<a href="' . route('update/user', $user->id) . '" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> ';
$actions .= '<a href="' . route('clone/user', $user->id) . '" class="btn btn-info btn-sm"><i class="fa fa-clone"></i></a>';
if ((Auth::user()->id !== $user->id) && (!config('app.lock_passwords'))) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/user', $user->id) . '" data-content="Are you sure you wish to delete this user?" data-title="Delete ' . htmlspecialchars($user->first_name) . '?" onClick="return false;"><i class="fa fa-trash icon-white"></i></a> ';
if (!is_null($user->deleted_at)) {
if (Gate::allows('users.delete')) {
$actions .= '<a href="' . route('restore/user',
$user->id) . '" class="btn btn-warning btn-sm"><i class="fa fa-share 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>';
if (Gate::allows('users.delete')) {
if ($user->accountStatus() == 'suspended') {
$actions .= '<a href="' . route('unsuspend/user',
$user->id) . '" class="btn btn-default btn-sm"><span class="fa fa-clock-o"></span></a> ';
}
}
if (Gate::allows('users.edit')) {
$actions .= '<a href="' . route('update/user',
$user->id) . '" class="btn btn-warning btn-sm"><i class="fa fa-pencil icon-white"></i></a> ';
$actions .= '<a href="' . route('clone/user',
$user->id) . '" class="btn btn-info btn-sm"><i class="fa fa-clone"></i></a>';
}
if (Gate::allows('users.delete')) {
if ((Auth::user()->id !== $user->id) && (!config('app.lock_passwords'))) {
$actions .= '<a data-html="false" class="btn delete-asset btn-danger btn-sm" data-toggle="modal" href="' . route('delete/user',
$user->id) . '" data-content="Are you sure you wish to delete this user?" data-title="Delete ' . htmlspecialchars($user->first_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>';
}
} else {
$actions.='foo';
}
}
}
$actions .= '</nobr>';
$rows[] = array(
@@ -1079,7 +1093,7 @@ class UsersController extends Controller
return redirect()->route('users')->with('error', trans('general.insufficient_permissions'));
} else {
$log = Actionlog::find($fileId);
$file = $log->get_src();
$file = $log->get_src('users');
return Response::download($file);
}
} else {
@@ -1135,7 +1149,6 @@ class UsersController extends Controller
protected $ldapValidationRules = array(
'firstname' => 'required|string|min:2',
'lastname' => 'required|string|min:2',
'employee_number' => 'string',
'username' => 'required|min:2|unique:users,username',
'email' => 'email|unique:users,email',
@@ -1148,7 +1161,7 @@ class UsersController extends Controller
* @since [v1.8]
* @return Redirect
*/
public function postLDAP()
public function postLDAP(Request $request)
{
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
ini_set('memory_limit', '500M');
@@ -1161,9 +1174,6 @@ class UsersController extends Controller
$ldap_result_emp_num = Setting::getSettings()->ldap_emp_num;
$ldap_result_email = Setting::getSettings()->ldap_email;
$location_id = e(Input::get('location_id'));
try {
$ldapconn = Ldap::connectToLdap();
} catch (\Exception $e) {
@@ -1180,6 +1190,10 @@ class UsersController extends Controller
$results = Ldap::findLdapUsers();
$tmp_pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$pass = bcrypt($tmp_pass);
for ($i = 0; $i < $results["count"]; $i++) {
if (empty($ldap_result_active_flag) || $results[$i][$ldap_result_active_flag][0] == "TRUE") {
@@ -1194,21 +1208,22 @@ class UsersController extends Controller
$item["createorupdate"] = 'updated';
if (!$user = User::where('username', $item["username"])->first()) {
$user = new User;
$user->password = $pass;
$item["createorupdate"] = 'created';
}
// Create the user if they don't exist.
$pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$user->first_name = e($item["firstname"]);
$user->last_name = e($item["lastname"]);
$user->username = e($item["username"]);
$user->email = e($item["email"]);
$user->employee_num = e($item["employee_number"]);
$user->password = bcrypt($pass);
$user->activated = 1;
$user->location_id = e($location_id);
if ($request->input('location_id')!='') {
$user->location_id = e($request->input('location_id'));
}
$user->notes = 'Imported from LDAP';
$user->ldap_import = 1;
@@ -1218,9 +1233,7 @@ class UsersController extends Controller
$item["note"] = $item["createorupdate"];
$item["status"]='success';
} else {
//$errors_array = array($user->getErrors());
foreach ($user->getErrors()->getMessages() as $key => $err) {
//echo $user->getErrors();
$errors .='<li>'.$err[0];
}
$item["note"] = $errors;
@@ -1234,7 +1247,7 @@ class UsersController extends Controller
return redirect()->route('ldap/user')->with('success', "OK")->with('summary', $summary);
return redirect()->route('ldap/user')->with('success', "LDAP Import successful.")->with('summary', $summary);
}
/**
@@ -1246,9 +1259,7 @@ class UsersController extends Controller
*/
public function getAssetList($userId)
{
$assets = Asset::where('assigned_to', '=', $userId)->get();
$assets = Asset::where('assigned_to', '=', $userId)->with('model')->get();
return response()->json($assets);
//$foo = Asset::where('assigned_to','=',$userId)->get();
//print_r($foo);
}
}

View File

@@ -14,7 +14,7 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\MisterPhilip\MaintenanceMode\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\FrameGuard::class,

View File

@@ -37,6 +37,7 @@ class AssetRequest extends Request
'supplier_id' => 'integer',
'status' => 'integer',
'asset_tag' => 'required',
'purchase_cost' => 'numeric',
];

View File

@@ -26,7 +26,6 @@ class SaveUserRequest extends Request
return [
'first_name' => 'required|string|min:1',
'last_name' => 'required|string|min:1',
'username' => 'required|string|min:2|unique:users,username,NULL,deleted_at',
'email' => 'email',
'password' => 'required|min:6',
'password_confirm' => 'sometimes|required_with:password',

View File

@@ -25,7 +25,6 @@ class UpdateUserRequest extends Request
{
return [
'first_name' => 'required|string|min:1',
'last_name' => 'required|string|min:1',
'email' => 'email',
'password_confirm' => 'sometimes|required_with:password',
];

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Http\Traits;
trait UniqueUndeletedTrait
{
/**
* Prepare a unique_ids rule, adding a model identifier if required.
*
* @param array $parameters
* @param string $field
* @return string
*/
protected function prepareUniqueUndeletedRule($parameters, $field)
{
// Only perform a replacement if the model has been persisted.
if ($this->exists) {
return 'unique_undeleted:'.$this->table.','. $this->getKey();
}
return 'unique_undeleted:'.$this->table.',0';
}
}

View File

@@ -78,7 +78,7 @@ Route::group([ 'prefix' => 'api', 'middleware' => 'auth' ], function () {
/*---Manufacturers API---*/
Route::group(array('prefix'=>'manufacturers'), function () {
Route::get('list', array('as'=>'api.manufacturers.list', 'uses'=>'ManufacturersController@getDatatable'));
Route::get('{manufacturerID}/view', array('as'=>'api.manufacturers.view', 'uses'=>'ManufacturersController@getDataView'));
Route::get('{manufacturerID}/view/{itemtype}', array('as'=>'api.manufacturers.view', 'uses'=>'ManufacturersController@getDataView'));
});
/*---Suppliers API---*/
@@ -184,79 +184,138 @@ Route::group([ 'prefix' => 'api', 'middleware' => 'auth' ], function () {
Route::group(
[ 'prefix' => 'hardware',
'middleware' => ['web',
'auth',
'authorize:assets.view']],
'auth']],
function () {
Route::get('history', [
'as' => 'asset.import-history',
'middleware' => 'authorize:assets.checkout',
'uses' => 'AssetsController@getImportHistory'
]);
Route::post('history', [
'as' => 'asset.process-import-history',
'middleware' => 'authorize:assets.checkout',
'uses' => 'AssetsController@postImportHistory'
]);
Route::get('create/{model?}', [
'as' => 'create/hardware',
'middleware' => 'authorize:assets.create',
'uses' => 'AssetsController@getCreate'
]);
Route::post('create', [
'as' => 'savenew/hardware',
'middleware' => 'authorize:assets.create',
'uses' => 'AssetsController@postCreate'
]);
Route::get('{assetId}/edit', [
'as' => 'update/hardware',
'middleware' => 'authorize:assets.edit',
'uses' => 'AssetsController@getEdit'
]);
Route::get('/bytag', [
'as' => 'findbytag/hardware',
'middleware' => 'authorize:assets.view',
'uses' => 'AssetsController@getAssetByTag'
]);
Route::get('{assetId}/clone', [ 'as' => 'clone/hardware', 'uses' => 'AssetsController@getClone' ]);
Route::get('{assetId}/clone', [
'as' => 'clone/hardware',
'middleware' => 'authorize:assets.create',
'uses' => 'AssetsController@getClone'
]);
Route::post('{assetId}/clone', 'AssetsController@postCreate');
Route::get('{assetId}/delete', [ 'as' => 'delete/hardware', 'uses' => 'AssetsController@getDelete' ]);
Route::get(
'{assetId}/checkout',
[ 'as' => 'checkout/hardware', 'uses' => 'AssetsController@getCheckout' ]
);
Route::post('{assetId}/checkout', 'AssetsController@postCheckout');
Route::get(
'{assetId}/checkin/{backto?}',
[ 'as' => 'checkin/hardware', 'uses' => 'AssetsController@getCheckin' ]
);
Route::post('{assetId}/checkin/{backto?}', 'AssetsController@postCheckin');
Route::get('{assetId}/view', [ 'as' => 'view/hardware', 'uses' => 'AssetsController@getView' ]);
Route::get('{assetId}/delete', [
'as' => 'delete/hardware',
'middleware' => 'authorize:assets.delete',
'uses' => 'AssetsController@getDelete'
]);
Route::get('{assetId}/checkout', [
'as' => 'checkout/hardware',
'middleware' => 'authorize:assets.checkout',
'uses' => 'AssetsController@getCheckout'
]);
Route::post('{assetId}/checkout', [
'as' => 'checkout/hardware',
'middleware' => 'authorize:assets.checkout',
'uses' => 'AssetsController@postCheckout'
]);
Route::get('{assetId}/checkin/{backto?}', [
'as' => 'checkin/hardware',
'middleware' => 'authorize:assets.checkin',
'uses' => 'AssetsController@getCheckin'
]);
Route::post('{assetId}/checkin/{backto?}', [
'as' => 'checkin/hardware',
'middleware' => 'authorize:assets.checkin',
'uses' => 'AssetsController@postCheckin'
]);
Route::get('{assetId}/view', [
'as' => 'view/hardware',
'middleware' => ['authorize:assets.view'],
'uses' => 'AssetsController@getView'
]);
Route::get('{assetId}/qr-view', [ 'as' => 'qr-view/hardware', 'uses' => 'AssetsController@getView' ]);
Route::get('{assetId}/qr_code', [ 'as' => 'qr_code/hardware', 'uses' => 'AssetsController@getQrCode' ]);
Route::get('{assetId}/barcode', [ 'as' => 'barcode/hardware', 'uses' => 'AssetsController@getBarCode' ]);
Route::get('{assetId}/restore', [ 'as' => 'restore/hardware', 'uses' => 'AssetsController@getRestore' ]);
Route::post('{assetId}/upload', [ 'as' => 'upload/asset', 'uses' => 'AssetsController@postUpload' ]);
Route::get(
'{assetId}/deletefile/{fileId}',
[ 'as' => 'delete/assetfile', 'uses' => 'AssetsController@getDeleteFile' ]
);
Route::get(
'{assetId}/showfile/{fileId}',
[ 'as' => 'show/assetfile', 'uses' => 'AssetsController@displayFile' ]
);
Route::get('{assetId}/restore', [
'as' => 'restore/hardware',
'middleware' => 'authorize:assets.delete',
'uses' => 'AssetsController@getRestore'
]);
Route::post('{assetId}/upload', [
'as' => 'upload/asset',
'middleware' => 'authorize:assets.edit',
'uses' => 'AssetsController@postUpload'
]);
Route::get(
'import/delete-import/{filename}',
[ 'as' => 'assets/import/delete-file', 'uses' => 'AssetsController@getDeleteImportFile' ]
);
Route::get('{assetId}/deletefile/{fileId}', [
'as' => 'delete/assetfile',
'middleware' => 'authorize:assets.edit',
'uses' => 'AssetsController@getDeleteFile'
]);
Route::get(
'import/process/{filename}',
[ 'as' => 'assets/import/process-file', 'uses' => 'AssetsController@getProcessImportFile' ]
);
Route::get('{assetId}/showfile/{fileId}', [
'as' => 'show/assetfile',
'middleware' => 'authorize:assets.view',
'uses' => 'AssetsController@displayFile'
]);
Route::get(
'import',
[ 'as' => 'assets/import', 'uses' => 'AssetsController@getImportUpload' ]
);
Route::get('import/delete-import/{filename}', [
'as' => 'assets/import/delete-file',
'middleware' => 'authorize:assets.create',
'uses' => 'AssetsController@getDeleteImportFile'
]);
Route::get( 'import/process/{filename}', [ 'as' => 'assets/import/process-file',
'middleware' => 'authorize:assets.create',
'uses' => 'AssetsController@getProcessImportFile'
]);
Route::get('import',[
'as' => 'assets/import',
'middleware' => 'authorize:assets.create',
'uses' => 'AssetsController@getImportUpload'
]);
Route::post('{assetId}/edit', 'AssetsController@postEdit');
Route::post('{assetId}/edit',[
'as' => 'assets/import',
'middleware' => 'authorize:assets.edit',
'uses' => 'AssetsController@postEdit'
]);
Route::post(
'bulkedit',
[
'as' => 'hardware/bulkedit',
'middleware' => 'authorize:assets.edit',
'uses' => 'AssetsController@postBulkEdit'
]
);
@@ -264,6 +323,7 @@ Route::group(
'bulkdelete',
[
'as' => 'hardware/bulkdelete',
'middleware' => 'authorize:assets.delete',
'uses' => 'AssetsController@postBulkDelete'
]
);
@@ -271,10 +331,23 @@ Route::group(
'bulksave',
[
'as' => 'hardware/bulksave',
'middleware' => 'authorize:assets.edit',
'uses' => 'AssetsController@postBulkSave'
]
);
# Bulk checkout / checkin
Route::get( 'bulkcheckout', [
'as' => 'hardware/bulkcheckout',
'middleware' => 'authorize:assets.checkout',
'uses' => 'AssetsController@getBulkCheckout'
]);
Route::post( 'bulkcheckout', [
'as' => 'hardware/bulkcheckout',
'middleware' => 'authorize:assets.checkout',
'uses' => 'AssetsController@postBulkCheckout'
]);
# Asset Model Management
Route::group([ 'prefix' => 'models', 'middleware' => 'auth' ], function () {
@@ -293,6 +366,7 @@ Route::group(
Route::get('/', [
'as' => 'hardware',
'middleware' => 'authorize:assets.view',
'uses' => 'AssetsController@getIndex'
]);
@@ -313,41 +387,57 @@ Route::group([ 'prefix' => 'admin','middleware' => ['web','auth']], function ()
# Licenses
Route::group([ 'prefix' => 'licenses', 'middleware'=>'authorize:licenses.view' ], function () {
Route::get('create', [ 'as' => 'create/licenses', 'uses' => 'LicensesController@getCreate' ]);
Route::post('create', 'LicensesController@postCreate');
Route::get('{licenseId}/edit', [ 'as' => 'update/license', 'uses' => 'LicensesController@getEdit' ]);
Route::post('{licenseId}/edit', 'LicensesController@postEdit');
Route::get('{licenseId}/clone', [ 'as' => 'clone/license', 'uses' => 'LicensesController@getClone' ]);
Route::post('{licenseId}/clone', 'LicensesController@postCreate');
Route::get('{licenseId}/delete', [ 'as' => 'delete/license', 'uses' => 'LicensesController@getDelete' ]);
Route::get(
'{licenseId}/freecheckout',
[ 'as' => 'freecheckout/license', 'uses' => 'LicensesController@getFreeLicense' ]
);
Route::get('create', [ 'as' => 'create/licenses', 'middleware' => 'authorize:licenses.create','uses' => 'LicensesController@getCreate' ]);
Route::post('create', [ 'as' => 'create/licenses', 'middleware' => 'authorize:licenses.create','uses' => 'LicensesController@postCreate' ]);
Route::get('{licenseId}/edit', [ 'as' => 'update/license', 'middleware' => 'authorize:licenses.edit', 'uses' => 'LicensesController@getEdit' ]);
Route::post('{licenseId}/edit', [ 'as' => 'update/license', 'middleware' => 'authorize:licenses.edit', 'uses' => 'LicensesController@postEdit' ]);
Route::get('{licenseId}/clone', [ 'as' => 'clone/license', 'middleware' => 'authorize:licenses.create', 'uses' => 'LicensesController@getClone' ]);
Route::post('{licenseId}/clone', [ 'as' => 'clone/license', 'middleware' => 'authorize:licenses.create', 'uses' => 'LicensesController@postCreate' ]);
Route::get('{licenseId}/delete', [ 'as' => 'delete/license', 'middleware' => 'authorize:licenses.delete', 'uses' => 'LicensesController@getDelete' ]);
Route::get('{licenseId}/freecheckout', [
'as' => 'freecheckout/license',
'middleware' => 'authorize:licenses.checkout',
'uses' => 'LicensesController@getFreeLicense'
]);
Route::get(
'{licenseId}/checkout',
[ 'as' => 'checkout/license', 'uses' => 'LicensesController@getCheckout' ]
[ 'as' => 'checkout/license', 'middleware' => 'authorize:licenses.checkout','uses' => 'LicensesController@getCheckout' ]
);
Route::post('{licenseId}/checkout', 'LicensesController@postCheckout');
Route::get(
'{licenseId}/checkin/{backto?}',
[ 'as' => 'checkin/license', 'uses' => 'LicensesController@getCheckin' ]
Route::post(
'{licenseId}/checkout',
[ 'as' => 'checkout/license', 'middleware' => 'authorize:licenses.checkout','uses' => 'LicensesController@postCheckout' ]
);
Route::post('{licenseId}/checkin/{backto?}', 'LicensesController@postCheckin');
Route::get('{licenseId}/view', [ 'as' => 'view/license', 'uses' => 'LicensesController@getView' ]);
Route::get('{licenseId}/checkin/{backto?}', [
'as' => 'checkin/license',
'middleware' => 'authorize:licenses.checkin',
'uses' => 'LicensesController@getCheckin'
]);
Route::post('{licenseId}/checkin/{backto?}', [
'as' => 'checkin/license',
'middleware' => 'authorize:licenses.checkin',
'uses' => 'LicensesController@postCheckin'
]);
Route::get('{licenseId}/view', [
'as' => 'view/license',
'middleware' => 'authorize:licenses.view',
'uses' => 'LicensesController@getView'
]);
Route::post(
'{licenseId}/upload',
[ 'as' => 'upload/license', 'uses' => 'LicensesController@postUpload' ]
[ 'as' => 'upload/license', 'middleware' => 'authorize:licenses.edit','uses' => 'LicensesController@postUpload' ]
);
Route::get(
'{licenseId}/deletefile/{fileId}',
[ 'as' => 'delete/licensefile', 'uses' => 'LicensesController@getDeleteFile' ]
[ 'as' => 'delete/licensefile', 'middleware' => 'authorize:licenses.edit', 'uses' => 'LicensesController@getDeleteFile' ]
);
Route::get(
'{licenseId}/showfile/{fileId}',
[ 'as' => 'show/licensefile', 'uses' => 'LicensesController@displayFile' ]
[ 'as' => 'show/licensefile', 'middleware' => 'authorize:licenses.view','uses' => 'LicensesController@displayFile' ]
);
Route::get('/', [ 'as' => 'licenses', 'uses' => 'LicensesController@getIndex' ]);
Route::get('/', [ 'as' => 'licenses', 'middleware' => 'authorize:licenses.view','uses' => 'LicensesController@getIndex' ]);
});
# Asset Maintenances
@@ -377,84 +467,103 @@ Route::group([ 'prefix' => 'admin','middleware' => ['web','auth']], function ()
# Accessories
Route::group([ 'prefix' => 'accessories', 'middleware'=>'authorize:accessories.view' ], function () {
Route::get('create', [ 'as' => 'create/accessory', 'uses' => 'AccessoriesController@getCreate' ]);
Route::get('create', [ 'as' => 'create/accessory', 'middleware' => 'authorize:accessories.create','uses' => 'AccessoriesController@getCreate' ]);
Route::post('create', 'AccessoriesController@postCreate');
Route::get(
'{accessoryID}/edit',
[ 'as' => 'update/accessory', 'uses' => 'AccessoriesController@getEdit' ]
[ 'as' => 'update/accessory', 'middleware' => 'authorize:accessories.edit','uses' => 'AccessoriesController@getEdit' ]
);
Route::post('{accessoryID}/edit', 'AccessoriesController@postEdit');
Route::get(
'{accessoryID}/delete',
[ 'as' => 'delete/accessory', 'uses' => 'AccessoriesController@getDelete' ]
[ 'as' => 'delete/accessory', 'middleware' => 'authorize:accessories.delete','uses' => 'AccessoriesController@getDelete' ]
);
Route::get('{accessoryID}/view', [ 'as' => 'view/accessory', 'uses' => 'AccessoriesController@getView' ]);
Route::get('{accessoryID}/view', [ 'as' => 'view/accessory', 'middleware' => 'authorize:accessories.view','uses' => 'AccessoriesController@getView' ]);
Route::get(
'{accessoryID}/checkout',
[ 'as' => 'checkout/accessory', 'uses' => 'AccessoriesController@getCheckout' ]
[ 'as' => 'checkout/accessory', 'middleware' => 'authorize:accessories.checkout','uses' => 'AccessoriesController@getCheckout' ]
);
Route::post('{accessoryID}/checkout', 'AccessoriesController@postCheckout');
Route::post(
'{accessoryID}/checkout',
[ 'as' => 'checkout/accessory', 'middleware' => 'authorize:accessories.checkout','uses' => 'AccessoriesController@postCheckout' ]
);
Route::get(
'{accessoryID}/checkin/{backto?}',
[ 'as' => 'checkin/accessory', 'uses' => 'AccessoriesController@getCheckin' ]
[ 'as' => 'checkin/accessory', 'middleware' => 'authorize:accessories.checkin','uses' => 'AccessoriesController@getCheckin' ]
);
Route::post(
'{accessoryID}/checkin/{backto?}',
[ 'as' => 'checkin/accessory', 'middleware' => 'authorize:accessories.checkin','uses' => 'AccessoriesController@postCheckin' ]
);
Route::post('{accessoryID}/checkin/{backto?}', 'AccessoriesController@postCheckin');
Route::get('/', [ 'as' => 'accessories', 'uses' => 'AccessoriesController@getIndex' ]);
Route::get('/', [ 'as' => 'accessories', 'middleware'=>'authorize:accessories.view', 'uses' => 'AccessoriesController@getIndex' ]);
});
# Consumables
Route::group([ 'prefix' => 'consumables', 'middleware'=>'authorize:consumables.view' ], function () {
Route::get('create', [ 'as' => 'create/consumable', 'uses' => 'ConsumablesController@getCreate' ]);
Route::post('create', 'ConsumablesController@postCreate');
Route::get('create', [ 'as' => 'create/consumable','middleware'=>'authorize:consumables.create', 'uses' => 'ConsumablesController@getCreate' ]);
Route::post('create', [ 'as' => 'create/consumable','middleware'=>'authorize:consumables.create', 'uses' => 'ConsumablesController@postCreate' ]);
Route::get(
'{consumableID}/edit',
[ 'as' => 'update/consumable', 'uses' => 'ConsumablesController@getEdit' ]
[ 'as' => 'update/consumable', 'middleware'=>'authorize:consumables.edit', 'uses' => 'ConsumablesController@getEdit' ]
);
Route::post(
'{consumableID}/edit',
[ 'as' => 'update/consumable', 'middleware'=>'authorize:consumables.edit', 'uses' => 'ConsumablesController@postEdit' ]
);
Route::post('{consumableID}/edit', 'ConsumablesController@postEdit');
Route::get(
'{consumableID}/delete',
[ 'as' => 'delete/consumable', 'uses' => 'ConsumablesController@getDelete' ]
[ 'as' => 'delete/consumable', 'middleware'=>'authorize:consumables.delete','uses' => 'ConsumablesController@getDelete' ]
);
Route::get(
'{consumableID}/view',
[ 'as' => 'view/consumable', 'uses' => 'ConsumablesController@getView' ]
[ 'as' => 'view/consumable', 'middleware'=>'authorize:consumables.view','uses' => 'ConsumablesController@getView' ]
);
Route::get(
'{consumableID}/checkout',
[ 'as' => 'checkout/consumable', 'uses' => 'ConsumablesController@getCheckout' ]
[ 'as' => 'checkout/consumable', 'middleware'=>'authorize:consumables.checkout','uses' => 'ConsumablesController@getCheckout' ]
);
Route::post('{consumableID}/checkout', 'ConsumablesController@postCheckout');
Route::get('/', [ 'as' => 'consumables', 'uses' => 'ConsumablesController@getIndex' ]);
Route::post(
'{consumableID}/checkout',
[ 'as' => 'checkout/consumable', 'middleware'=>'authorize:consumables.checkout','uses' => 'ConsumablesController@postCheckout' ]
);
Route::get('/', [ 'as' => 'consumables', 'middleware'=>'authorize:consumables.view','uses' => 'ConsumablesController@getIndex' ]);
});
# Components
Route::group([ 'prefix' => 'components', 'middleware'=>'authorize:components.view' ], function () {
Route::get('create', [ 'as' => 'create/component', 'uses' => 'ComponentsController@getCreate' ]);
Route::post('create', 'ComponentsController@postCreate');
Route::get('create', [ 'as' => 'create/component', 'middleware'=>'authorize:components.create','uses' => 'ComponentsController@getCreate' ]);
Route::post('create', [ 'as' => 'create/component', 'middleware'=>'authorize:components.create','uses' => 'ComponentsController@postCreate' ]);
Route::get(
'{componentID}/edit',
[ 'as' => 'update/component', 'uses' => 'ComponentsController@getEdit' ]
[ 'as' => 'update/component', 'middleware'=>'authorize:components.edit','uses' => 'ComponentsController@getEdit' ]
);
Route::post(
'{componentID}/edit',
[ 'as' => 'update/component', 'middleware'=>'authorize:components.edit','uses' => 'ComponentsController@postEdit' ]
);
Route::post('{componentID}/edit', 'ComponentsController@postEdit');
Route::get(
'{componentID}/delete',
[ 'as' => 'delete/component', 'uses' => 'ComponentsController@getDelete' ]
[ 'as' => 'delete/component', 'middleware'=>'authorize:components.delete','uses' => 'ComponentsController@getDelete' ]
);
Route::get(
'{componentID}/view',
[ 'as' => 'view/component', 'uses' => 'ComponentsController@getView' ]
[ 'as' => 'view/component', 'middleware'=>'authorize:components.view','uses' => 'ComponentsController@getView' ]
);
Route::get(
'{componentID}/checkout',
[ 'as' => 'checkout/component', 'uses' => 'ComponentsController@getCheckout' ]
[ 'as' => 'checkout/component', 'middleware'=>'authorize:components.checkout','uses' => 'ComponentsController@getCheckout' ]
);
Route::post('{componentID}/checkout', 'ComponentsController@postCheckout');
Route::post('bulk', [ 'as' => 'component/bulk-form', 'uses' => 'ComponentsController@postBulk' ]);
Route::post('bulksave', [ 'as' => 'component/bulk-save', 'uses' => 'ComponentsController@postBulkSave' ]);
Route::get('/', [ 'as' => 'components', 'uses' => 'ComponentsController@getIndex' ]);
Route::post(
'{componentID}/checkout',
[ 'as' => 'checkout/component', 'middleware'=>'authorize:components.checkout','uses' => 'ComponentsController@postCheckout' ]
);
Route::post('bulk', [ 'as' => 'component/bulk-form', 'middleware'=>'authorize:components.checkout','uses' => 'ComponentsController@postBulk' ]);
Route::post('bulksave', [ 'as' => 'component/bulk-save', 'middleware'=>'authorize:components.edit','uses' => 'ComponentsController@postBulkSave' ]);
Route::get('/', [ 'as' => 'components', 'middleware'=>'authorize:components.view','uses' => 'ComponentsController@getIndex' ]);
});
# Admin Settings Routes (for categories, maufactureres, etc)
@@ -638,27 +747,28 @@ Route::group([ 'prefix' => 'admin','middleware' => ['web','auth']], function ()
Route::get('custom_fields/create-field', ['uses' =>'CustomFieldsController@createField','as' => 'admin.custom_fields.create-field']);
Route::post('custom_fields/create-field', ['uses' => 'CustomFieldsController@storeField','as' => 'admin.custom_fields.store-field']);
Route::post('custom_fields/{id}/associate', ['uses' => 'CustomFieldsController@associate','as' => 'admin.custom_fields.associate']);
Route::get('custom_fields/{field_id}/{fieldset_id}/disassociate', ['uses' => 'CustomFieldsController@deleteFieldFromFieldset','as' => 'admin.custom_fields.disassociate']);
Route::match(['DELETE'], 'custom_fields/delete-field/{id}', ['uses' => 'CustomFieldsController@deleteField','as' => 'admin.custom_fields.delete-field']);
Route::resource('custom_fields', 'CustomFieldsController');
# User Management
Route::group([ 'prefix' => 'users', 'middleware' => ['web','auth','authorize:users.view']], function () {
Route::get('ldap', ['as' => 'ldap/user', 'uses' => 'UsersController@getLDAP' ]);
Route::get('ldap', ['as' => 'ldap/user', 'uses' => 'UsersController@getLDAP', 'middleware' => ['authorize:users.edit'] ]);
Route::post('ldap', 'UsersController@postLDAP');
Route::get('create', [ 'as' => 'create/user', 'uses' => 'UsersController@getCreate' ]);
Route::post('create', 'UsersController@postCreate');
Route::get('import', [ 'as' => 'import/user', 'uses' => 'UsersController@getImport' ]);
Route::post('import', 'UsersController@postImport');
Route::get('{userId}/edit', [ 'as' => 'update/user', 'uses' => 'UsersController@getEdit' ]);
Route::post('{userId}/edit', 'UsersController@postEdit');
Route::get('{userId}/clone', [ 'as' => 'clone/user', 'uses' => 'UsersController@getClone' ]);
Route::post('{userId}/clone', 'UsersController@postCreate');
Route::get('{userId}/delete', [ 'as' => 'delete/user', 'uses' => 'UsersController@getDelete' ]);
Route::get('{userId}/restore', [ 'as' => 'restore/user', 'uses' => 'UsersController@getRestore' ]);
Route::get('{userId}/view', [ 'as' => 'view/user', 'uses' => 'UsersController@getView' ]);
Route::get('{userId}/unsuspend', [ 'as' => 'unsuspend/user', 'uses' => 'UsersController@getUnsuspend' ]);
Route::get('create', [ 'as' => 'create/user', 'uses' => 'UsersController@getCreate', 'middleware' => ['authorize:users.edit'] ]);
Route::post('create', [ 'uses' => 'UsersController@postCreate', 'middleware' => ['authorize:users.edit'] ]);
Route::get('import', [ 'as' => 'import/user', 'uses' => 'UsersController@getImport', 'middleware' => ['authorize:users.edit'] ]);
Route::post('import', [ 'uses' => 'UsersController@postImport', 'middleware' => ['authorize:users.edit'] ]);
Route::get('{userId}/edit', [ 'as' => 'update/user', 'uses' => 'UsersController@getEdit', 'middleware' => ['authorize:users.edit'] ]);
Route::post('{userId}/edit', [ 'uses' => 'UsersController@postEdit', 'middleware' => ['authorize:users.edit'] ]);
Route::get('{userId}/clone', [ 'as' => 'clone/user', 'uses' => 'UsersController@getClone', 'middleware' => ['authorize:users.edit'] ]);
Route::post('{userId}/clone', [ 'uses' => 'UsersController@postCreate', 'middleware' => ['authorize:users.edit'] ]);
Route::get('{userId}/delete', [ 'as' => 'delete/user', 'uses' => 'UsersController@getDelete', 'middleware' => ['authorize:users.edit'] ]);
Route::get('{userId}/restore', [ 'as' => 'restore/user', 'uses' => 'UsersController@getRestore', 'middleware' => ['authorize:users.edit'] ]);
Route::get('{userId}/view', [ 'as' => 'view/user', 'uses' => 'UsersController@getView' , 'middleware' => ['authorize:users.view'] ]);
Route::get('{userId}/unsuspend', [ 'as' => 'unsuspend/user', 'uses' => 'UsersController@getUnsuspend', 'middleware' => ['authorize:users.edit'] ]);
Route::get(
'{userId}/deletefile/{fileId}',
[ 'as' => 'delete/userfile', 'uses' => 'UsersController@getDeleteFile' ]
@@ -672,14 +782,16 @@ Route::group([ 'prefix' => 'admin','middleware' => ['web','auth']], function ()
'bulkedit',
[
'as' => 'users/bulkedit',
'uses' => 'UsersController@postBulkEdit'
'uses' => 'UsersController@postBulkEdit',
'middleware' => ['authorize:users.edit'],
]
);
Route::post(
'bulksave',
[
'as' => 'users/bulksave',
'uses' => 'UsersController@postBulkSave'
'uses' => 'UsersController@postBulkSave',
'middleware' => ['authorize:users.edit'],
]
);

View File

@@ -22,11 +22,12 @@ class Accessory extends Model
* Accessory validation rules
*/
public $rules = array(
'name' => 'required|min:3|max:255',
'qty' => 'required|integer|min:1',
'category_id' => 'required|integer',
'company_id' => 'integer',
'min_amt' => 'integer|min:1',
'name' => 'required|min:3|max:255',
'qty' => 'required|integer|min:1',
'category_id' => 'required|integer',
'company_id' => 'integer',
'min_amt' => 'integer|min:1',
'purchase_cost' => 'numeric',
);
@@ -81,6 +82,11 @@ class Accessory extends Model
return $this->belongsToMany('\App\Models\User', 'accessories_users', 'accessory_id', 'assigned_to')->count();
}
public function manufacturer()
{
return $this->belongsTo('\App\Models\Manufacturer', 'manufacturer_id');
}
public function checkin_email()
{
return $this->category->checkin_email;

View File

@@ -21,7 +21,7 @@ class Actionlog extends Model implements ICompanyableChild
protected $table = 'asset_logs';
public $timestamps = true;
protected $fillable = [ 'created_at', 'asset_type' ];
protected $fillable = [ 'created_at', 'asset_type','user_id','asset_id','action_type','note','checkedout_to' ];
public function getCompanyableParents()
{
@@ -85,6 +85,13 @@ class Actionlog extends Model implements ICompanyableChild
->withTrashed();
}
public function userasassetlog()
{
return $this->belongsTo('\App\Models\User', 'asset_id')
->withTrashed();
}
public function childlogs()
{

View File

@@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
use Log;
use Parsedown;
use Watson\Validating\ValidatingTrait;
use App\Http\Traits\UniqueUndeletedTrait;
use DateTime;
use App\Models\Setting;
use App\Helpers\Helper;
@@ -40,6 +41,7 @@ class Asset extends Depreciable
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;
use UniqueUndeletedTrait;
protected $rules = [
'name' => 'min:2|max:255',
@@ -51,8 +53,9 @@ class Asset extends Depreciable
'checkout_date' => 'date|max:10|min:10',
'checkin_date' => 'date|max:10|min:10',
'supplier_id' => 'integer',
'asset_tag' => 'required|min:1|max:255|unique:assets,asset_tag,NULL,deleted_at',
'asset_tag' => 'required|min:1|max:255|unique_undeleted',
'status' => 'integer',
'purchase_cost' => 'numeric',
];
@@ -70,20 +73,36 @@ class Asset extends Depreciable
}
public function availableForCheckout()
{
return (
empty($this->assigned_to) &&
$this->assetstatus->deployable == 1 &&
empty($this->deleted_at)
);
}
/**
* Checkout asset
*/
public function checkOutToUser($user, $admin, $checkout_at = null, $expected_checkin = null, $note = null, $name = null)
{
if (!$user) {
return false;
}
if ($expected_checkin) {
$this->expected_checkin = $expected_checkin ;
$this->expected_checkin = $expected_checkin;
}
$this->last_checkout = $checkout_at;
$this->assigneduser()->associate($user);
$this->name = $name;
if($name != null)
{
$this->name = $name;
}
$settings = Setting::getSettings();
@@ -91,9 +110,7 @@ class Asset extends Depreciable
$this->accepted="pending";
}
if (!$user) {
return false;
}
if ($this->save()) {
@@ -175,8 +192,8 @@ class Asset extends Depreciable
public function getDetailedNameAttribute()
{
if ($this->assigned_user) {
$user_name = $user->fullName();
if ($this->assignedUser) {
$user_name = $this->assignedUser->fullName();
} else {
$user_name = "Unassigned";
}
@@ -328,7 +345,7 @@ class Asset extends Depreciable
public static function assetcount()
{
return Asset::where('physical', '=', '1')
return Company::scopeCompanyables(Asset::where('physical', '=', '1'))
->whereNull('deleted_at', 'and')
->count();
}
@@ -372,7 +389,10 @@ class Asset extends Depreciable
{
if ($this->name == '') {
return $this->model->name;
if ($this->model) {
return $this->model->name.' ('.$this->asset_tag.')';
}
return $this->asset_tag;
} else {
return $this->name;
}
@@ -462,13 +482,24 @@ class Asset extends Depreciable
$asset_tag = \DB::table('assets')
->where('physical', '=', '1')
->max('id');
if ($settings->zerofill_count > 0) {
return $settings->auto_increment_prefix.Asset::zerofill(($asset_tag + 1),$settings->zerofill_count);
}
return $settings->auto_increment_prefix.($asset_tag + 1);
} else {
return false;
}
}
public function checkin_email()
public static function zerofill ($num, $zerofill = 3)
{
return str_pad($num, $zerofill, '0', STR_PAD_LEFT);
}
public function checkin_email()
{
return $this->model->category->checkin_email;
}
@@ -641,7 +672,7 @@ class Asset extends Depreciable
public function scopeRequestableAssets($query)
{
return $query->where('requestable', '=', 1)
return Company::scopeCompanyables($query->where('requestable', '=', 1))
->whereHas('assetstatus', function ($query) {
$query->where('deployable', '=', 1)

View File

@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Watson\Validating\ValidatingTrait;
use App\Http\Traits\UniqueUndeletedTrait;
/**
* Model for Categories. Categories are a higher-level group
@@ -25,7 +26,7 @@ class Category extends Model
*/
public $rules = array(
'user_id' => 'numeric',
'name' => 'required|min:1|max:255|unique:categories,name,NULL,deleted_at',
'name' => 'required|min:1|max:255|unique_undeleted',
'category_type' => 'required',
);
@@ -38,6 +39,7 @@ class Category extends Model
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;
use UniqueUndeletedTrait;
/**

View File

@@ -16,7 +16,11 @@ final class Company extends Model
protected $table = 'companies';
// Declare the rules for the model validation
protected $rules = ['name' => 'required|min:1|max:255|unique:companies,name'];
protected $rules = [
'name' => 'required|min:1|max:255|unique:companies,name'
];
/**
* Whether the model should inject it's identifier to the unique
* validation rules before attempting validation. If this property
@@ -55,11 +59,7 @@ final class Company extends Model
$company_id = null;
}
if ($company_id == null) {
return $query;
} else {
return $query->where($column, '=', $company_id);
}
return $query->where($column, '=', $company_id);
}
public static function getSelectList()
@@ -86,11 +86,17 @@ final class Company extends Model
} else {
$current_user = Auth::user();
if ($current_user->company_id != null) {
return $current_user->company_id;
} else {
// Super users should be able to set a company to whatever they need
if ($current_user->isSuperUser()) {
return static::getIdFromInput($unescaped_input);
} else {
if ($current_user->company_id != null) {
return $current_user->company_id;
} else {
return static::getIdFromInput($unescaped_input);
}
}
}
}
@@ -110,7 +116,7 @@ final class Company extends Model
public static function isCurrentUserAuthorized()
{
return ((!static::isFullMultipleCompanySupportEnabled()) || (Auth::user()->company_id == null) || (Auth::user()->isSuperUser()));
return ((!static::isFullMultipleCompanySupportEnabled()) || (Auth::user()->isSuperUser()));
}
public static function canManageUsersCompanies()
@@ -141,7 +147,7 @@ final class Company extends Model
{
if (count($companyable_names) == 0) {
throw new Exception('No Companyable Children to scope');
} elseif (!static::isFullMultipleCompanySupportEnabled()) {
} elseif (!static::isFullMultipleCompanySupportEnabled() || (Auth::check() && Auth::user()->isSuperUser())) {
return $query;
} else {
$f = function ($q) {

View File

@@ -34,6 +34,7 @@ class Component extends Model
'category_id' => 'required|integer',
'company_id' => 'integer',
'purchase_date' => 'date',
'purchase_cost' => 'numeric',
);
/**

View File

@@ -29,6 +29,7 @@ class Consumable extends Model
'category_id' => 'required|integer',
'company_id' => 'integer',
'min_amt' => 'integer|min:1',
'purchase_cost' => 'numeric',
);
/**

View File

@@ -11,14 +11,14 @@ class CustomField extends Model
*/
public static $PredefinedFormats=[
"ANY" => "",
"ALPHA" => "alpha",
"EMAIL" => "email",
"DATE" => "date",
"URL" => "url",
"NUMERIC" => "numeric",
"MAC" => "regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/",
"IP" => "ip"
"ANY" => "",
"ALPHA" => "alpha",
"EMAIL" => "email",
"DATE" => "date",
"URL" => "url",
"NUMERIC" => "numeric",
"MAC" => "regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/",
"IP" => "ip",
];
public $rules=[
@@ -109,4 +109,43 @@ class CustomField extends Model
$this->attributes['format']=$value;
}
}
/**
* Format a value string as an array for select boxes and checkboxes.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.4]
* @return Array
*/
public function formatFieldValuesAsArray() {
$arr = preg_split("/\\r\\n|\\r|\\n/", $this->field_values);
$result[''] = 'Select '.strtolower($this->format);
for ($x = 0; $x < count($arr); $x++) {
$arr_parts = explode('|', $arr[$x]);
if ($arr_parts[0]!='') {
if (key_exists('1',$arr_parts)) {
$result[$arr_parts[0]] = $arr_parts[1];
} else {
$result[$arr_parts[0]] = $arr_parts[0];
}
}
}
return $result;
}
public function isFieldDecryptable($string) {
if (($this->field_encrypted=='1') && ($string!='')) {
return true;
}
return false;
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Gate;
class CustomFieldset extends Model
{
@@ -30,16 +31,21 @@ class CustomFieldset extends Model
{
$rules=[];
foreach ($this->fields as $field) {
$rule=[];
if ($field->pivot->required) {
$rule[]="required";
$rule = [];
if (($field->field_encrypted!='1') ||
(($field->field_encrypted =='1') && (Gate::allows('admin')) ))
{
if ($field->pivot->required) {
$rule[]="required";
}
}
array_push($rule, $field->attributes['format']);
$rules[$field->db_column_name()]=$rule;
}
return $rules;
}
//requiredness goes *here*
//sequence goes here?
}

View File

@@ -26,25 +26,34 @@ class Ldap extends Model
$ldap_host = Setting::getSettings()->ldap_server;
$ldap_version = Setting::getSettings()->ldap_version;
$ldap_server_cert_ignore = Setting::getSettings()->ldap_server_cert_ignore;
$ldap_use_tls = Setting::getSettings()->ldap_tls;
// If we are ignoring the SSL cert we need to setup the environment variable
// before we create the connection
if ($ldap_server_cert_ignore) {
if ($ldap_server_cert_ignore=='1') {
putenv('LDAPTLS_REQCERT=never');
}
// Connecting to LDAP
$connection = @ldap_connect($ldap_host) or die("Could not connect to {$ldap_host}");
// If the user specifies where CA Certs are, make sure to use them
if(env("LDAPTLS_CACERT")) {
putenv("LDAPTLS_CACERT=".env("LDAPTLS_CACERT"));
}
$connection = @ldap_connect($ldap_host);
if (!$connection) {
throw new Exception('Could not connect to LDAP server at '.$ldap_host.': '.ldap_error($connection));
throw new Exception('Could not connect to LDAP server at '.$ldap_host.'. Please check your LDAP server name and port number in your settings.');
}
// Needed for AD
ldap_set_option($connection, LDAP_OPT_REFERRALS, 0);
ldap_set_option($connection, LDAP_OPT_PROTOCOL_VERSION, $ldap_version);
if ($ldap_use_tls=='1') {
ldap_start_tls($connection);
}
return $connection;
}
@@ -182,6 +191,7 @@ class Ldap extends Model
{
$item = Ldap::parseAndMapLdapAttributes($ldapatttibutes);
// Create user from LDAP data
if (!empty($item["username"])) {
$user = new User;
@@ -189,7 +199,14 @@ class Ldap extends Model
$user->last_name = $item["lastname"];
$user->username = $item["username"];
$user->email = $item["email"];
$user->password = bcrypt(Input::get("password"));
if (Setting::getSettings()->ldap_pw_sync=='1') {
$user->password = bcrypt(Input::get("password"));
} else {
$pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 25);
$user->password = bcrypt($pass);
}
$user->activated = 1;
$user->ldap_import = 1;
$user->notes = 'Imported on first login from LDAP';
@@ -230,8 +247,12 @@ class Ldap extends Model
// Perform the search
do {
// Paginate (non-critical, if not supported by server)
ldap_control_paged_result($ldapconn, $page_size, false, $cookie);
if (!$ldap_paging = @ldap_control_paged_result($ldapconn, $page_size, false, $cookie)) {
throw new Exception('Problem with your LDAP connection. Try checking the Use TLS setting in Admin > Settings. ');
}
$search_results = ldap_search($ldapconn, $base_dn, '('.$filter.')');

View File

@@ -36,6 +36,11 @@ class License extends Depreciable
return $this->belongsTo('\App\Models\Company', 'company_id');
}
public function manufacturer()
{
return $this->belongsTo('\App\Models\Manufacturer', 'manufacturer_id');
}
/**
* Get the assigned user
*/

View File

@@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\User;
use App\Models\Asset;
use Watson\Validating\ValidatingTrait;
use App\Http\Traits\UniqueUndeletedTrait;
class Location extends Model
{
@@ -13,7 +14,7 @@ class Location extends Model
protected $dates = ['deleted_at'];
protected $table = 'locations';
protected $rules = array(
'name' => 'required|min:3|max:255|unique:locations,name,NULL,deleted_at',
'name' => 'required|min:3|max:255|unique_undeleted',
'city' => 'min:3|max:255',
'state' => 'min:2|max:32',
'country' => 'min:2|max:2|max:2',
@@ -31,6 +32,7 @@ class Location extends Model
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;
use UniqueUndeletedTrait;
/**

View File

@@ -46,6 +46,21 @@ class Manufacturer extends Model
return $this->hasManyThrough('\App\Models\Asset', '\App\Models\AssetModel', 'manufacturer_id', 'model_id');
}
public function licenses()
{
return $this->hasMany('\App\Models\License', 'manufacturer_id');
}
public function accessories()
{
return $this->hasMany('\App\Models\Accessory', 'manufacturer_id');
}
public function consumables()
{
return $this->hasMany('\App\Models\Consumable', 'manufacturer_id');
}
/**
* Query builder scope to search on text
*

View File

@@ -4,11 +4,13 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Watson\Validating\ValidatingTrait;
use App\Http\Traits\UniqueUndeletedTrait;
class Statuslabel extends Model
{
use SoftDeletes;
use ValidatingTrait;
use UniqueUndeletedTrait;
protected $injectUniqueIdentifier = true;
protected $dates = ['deleted_at'];
@@ -16,14 +18,14 @@ class Statuslabel extends Model
protected $rules = array(
'name' => 'required|string|unique:status_labels,name,NULL,deleted_at',
'name' => 'required|string|unique_undeleted',
'notes' => 'string',
'deployable' => 'required',
'pending' => 'required',
'archived' => 'required',
);
protected $fillable = ['name'];
protected $fillable = ['name', 'deployable', 'pending', 'archived'];
/**
* Show count of assets with status label

View File

@@ -4,14 +4,16 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Watson\Validating\ValidatingTrait;
use App\Http\Traits\UniqueUndeletedTrait;
class Supplier extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $table = 'suppliers';
protected $rules = array(
'name' => 'required|min:3|max:255|unique:suppliers,name,NULL,deleted_at',
'name' => 'required|min:3|max:255|unique_undeleted',
'address' => 'min:3|max:255',
'address2' => 'min:2|max:255',
'city' => 'min:3|max:255',
@@ -35,6 +37,7 @@ class Supplier extends Model
*/
protected $injectUniqueIdentifier = true;
use ValidatingTrait;
use UniqueUndeletedTrait;
/**
* The attributes that are mass assignable.

View File

@@ -7,8 +7,8 @@ use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Watson\Validating\ValidatingTrait;
use App\Models\Company;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Http\Traits\UniqueUndeletedTrait;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
@@ -17,6 +17,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
use ValidatingTrait;
use Authenticatable;
use CanResetPassword;
use UniqueUndeletedTrait;
protected $dates = ['deleted_at'];
protected $table = 'users';
@@ -32,8 +33,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
protected $rules = [
'first_name' => 'required|string|min:1',
'last_name' => 'required|string|min:1',
'username' => 'required|string|min:2|unique:users,username,NULL,deleted_at',
'username' => 'required|string|min:2|unique_undeleted',
'email' => 'email',
'password' => 'required|min:6',
];
@@ -55,7 +55,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
$user_permissions = json_decode($this->permissions, true);
//If the user is explicitly granted, return false
//If the user is explicitly granted, return true
if (($user_permissions!='') && ((array_key_exists($section, $user_permissions)) && ($user_permissions[$section]=='1'))) {
return true;
}
@@ -232,10 +232,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
public function accountStatus()
{
if ($this->sentryThrottle) {
if ($this->sentryThrottle->suspended==1) {
if ($this->throttle) {
if ($this->throttle->suspended==1) {
return 'suspended';
} elseif ($this->sentryThrottle->banned==1) {
} elseif ($this->throttle->banned==1) {
return 'banned';
} else {
return false;
@@ -262,7 +262,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
->orderBy('created_at', 'desc');
}
public function sentryThrottle()
public function throttle()
{
return $this->hasOne('\App\Models\Throttle');
}
@@ -302,6 +302,10 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
->orWhere('username', '=', $user_email);
}
public static function generateEmailFromFullName($name) {
$username = User::generateFormattedNameFromFullName(Setting::getSettings()->email_format, $name);
return $username['username'].'@'.Setting::getSettings()->email_domain;
}
public static function generateFormattedNameFromFullName($format = 'filastname', $users_name)
{
@@ -333,8 +337,9 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
} elseif ($format=='firstname') {
$email_last_name.=str_replace(' ', '', $last_name);
$email_prefix = $first_name;
}
}
$user_username = $email_prefix;

View File

@@ -3,6 +3,8 @@ namespace App\Providers;
use Validator;
use Illuminate\Support\ServiceProvider;
use DB;
/**
* This service provider handles a few custom validation rules.
@@ -47,6 +49,21 @@ class AppServiceProvider extends ServiceProvider
}
});
// Unique only if undeleted
// This works around the use case where multiple deleted items have the same unique attribute.
// (I think this is a bug in Laravel's validator?)
Validator::extend('unique_undeleted', function($attribute, $value, $parameters, $validator) {
$count = DB::table($parameters[0])->select('id')->where($attribute,'=',$value)->whereNull('deleted_at')->where('id','!=',$parameters[1])->count();
if ($count < 1) {
return true;
} else {
return false;
}
});
}
/**

View File

@@ -91,6 +91,19 @@ class AuthServiceProvider extends ServiceProvider
}
});
$gate->define('assets.edit', function ($user) {
if (($user->hasAccess('assets.edit')) || ($user->hasAccess('admin'))) {
return true;
}
});
// Checks for some level of management
$gate->define('assets.manage', function ($user) {
if (($user->hasAccess('assets.checkin')) || ($user->hasAccess('assets.edit')) || ($user->hasAccess('assets.delete')) || ($user->hasAccess('assets.checkout')) || ($user->hasAccess('admin'))) {
return true;
}
});
# -----------------------------------------
# Accessories
@@ -131,6 +144,13 @@ class AuthServiceProvider extends ServiceProvider
}
});
// Checks for some level of management
$gate->define('accessories.manage', function ($user) {
if (($user->hasAccess('accessories.checkin')) || ($user->hasAccess('accessories.edit')) || ($user->hasAccess('accessories.checkout')) || ($user->hasAccess('admin'))) {
return true;
}
});
# -----------------------------------------
# Consumables
# -----------------------------------------
@@ -170,6 +190,13 @@ class AuthServiceProvider extends ServiceProvider
}
});
// Checks for some level of management
$gate->define('consumables.manage', function ($user) {
if (($user->hasAccess('consumables.checkin')) || ($user->hasAccess('consumables.edit')) || ($user->hasAccess('consumables.delete')) || ($user->hasAccess('consumables.checkout')) || ($user->hasAccess('admin'))) {
return true;
}
});
# -----------------------------------------
@@ -205,7 +232,7 @@ class AuthServiceProvider extends ServiceProvider
# Components
# -----------------------------------------
$gate->define('components.view', function ($user) {
if (($user->hasAccess('components.create')) || ($user->hasAccess('admin'))) {
if (($user->hasAccess('components.view')) || ($user->hasAccess('admin'))) {
return true;
}
});
@@ -228,6 +255,13 @@ class AuthServiceProvider extends ServiceProvider
}
});
// Checks for some level of management
$gate->define('components.manage', function ($user) {
if (($user->hasAccess('components.edit')) || ($user->hasAccess('components.delete')) || ($user->hasAccess('components.checkout')) || ($user->hasAccess('admin'))) {
return true;
}
});
# -----------------------------------------
# Licenses
@@ -268,6 +302,19 @@ class AuthServiceProvider extends ServiceProvider
}
});
$gate->define('licenses.keys', function ($user) {
if (($user->hasAccess('licenses.keys')) || ($user->hasAccess('admin'))) {
return true;
}
});
// Checks for some level of management
$gate->define('licenses.manage', function ($user) {
if (($user->hasAccess('licenses.checkin')) || ($user->hasAccess('licenses.edit')) || ($user->hasAccess('licenses.delete')) || ($user->hasAccess('licenses.checkout')) || ($user->hasAccess('admin'))) {
return true;
}
});
}
}

View File

@@ -21,7 +21,8 @@
"doctrine/common": "v2.5.3",
"doctrine/dbal": "v2.4.2",
"barryvdh/laravel-debugbar": "^2.1",
"spatie/laravel-backup": "3.8.1"
"spatie/laravel-backup": "3.8.1",
"misterphilip/maintenance-mode": "1.0.*"
},
"require-dev": {
"fzaninotto/faker": "~1.4",

266
composer.lock generated
View File

@@ -4,21 +4,21 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "bf63c53f99a010e882f5c4b797e9f098",
"content-hash": "47c6ecb6331ff36a3e58ca8ddac195f8",
"hash": "a770010d0ebb93a2e1b5f4acadd5a7f3",
"content-hash": "59772418a4612685eea10dde38ca77b7",
"packages": [
{
"name": "aws/aws-sdk-php",
"version": "3.18.30",
"version": "3.18.39",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "fbce85229b913a9e1aded54e464a9bbff0787bf1"
"reference": "85f1fddaeb40b95106b2a2764268e9c89fc258ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/fbce85229b913a9e1aded54e464a9bbff0787bf1",
"reference": "fbce85229b913a9e1aded54e464a9bbff0787bf1",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/85f1fddaeb40b95106b2a2764268e9c89fc258ce",
"reference": "85f1fddaeb40b95106b2a2764268e9c89fc258ce",
"shasum": ""
},
"require": {
@@ -85,7 +85,7 @@
"s3",
"sdk"
],
"time": "2016-07-18 16:15:53"
"time": "2016-08-11 16:40:35"
},
{
"name": "aws/aws-sdk-php-laravel",
@@ -754,12 +754,12 @@
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "490a8f35a4163f59230f53c34f1fbb22a864c01e"
"reference": "f671ae73647b6666c1442cbaac98e5d60208e409"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/490a8f35a4163f59230f53c34f1fbb22a864c01e",
"reference": "490a8f35a4163f59230f53c34f1fbb22a864c01e",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/f671ae73647b6666c1442cbaac98e5d60208e409",
"reference": "f671ae73647b6666c1442cbaac98e5d60208e409",
"shasum": ""
},
"require": {
@@ -788,7 +788,7 @@
"markdown",
"parser"
],
"time": "2016-03-09 17:02:39"
"time": "2016-07-27 08:05:24"
},
{
"name": "fideloper/proxy",
@@ -1221,16 +1221,16 @@
},
{
"name": "laravel/framework",
"version": "v5.2.39",
"version": "v5.2.43",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "c2a77050269b4e03bd9a735a9f24e573a7598b8a"
"reference": "5490b8f00564bb60839002f86828e27edd1e5610"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/c2a77050269b4e03bd9a735a9f24e573a7598b8a",
"reference": "c2a77050269b4e03bd9a735a9f24e573a7598b8a",
"url": "https://api.github.com/repos/laravel/framework/zipball/5490b8f00564bb60839002f86828e27edd1e5610",
"reference": "5490b8f00564bb60839002f86828e27edd1e5610",
"shasum": ""
},
"require": {
@@ -1287,7 +1287,8 @@
"illuminate/support": "self.version",
"illuminate/translation": "self.version",
"illuminate/validation": "self.version",
"illuminate/view": "self.version"
"illuminate/view": "self.version",
"tightenco/collect": "self.version"
},
"require-dev": {
"aws/aws-sdk-php": "~3.0",
@@ -1346,7 +1347,7 @@
"framework",
"laravel"
],
"time": "2016-06-17 19:25:12"
"time": "2016-08-10 12:23:59"
},
{
"name": "laravelcollective/html",
@@ -1461,16 +1462,16 @@
},
{
"name": "league/flysystem",
"version": "1.0.25",
"version": "1.0.27",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "a76afa4035931be0c78ca8efc6abf3902362f437"
"reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a76afa4035931be0c78ca8efc6abf3902362f437",
"reference": "a76afa4035931be0c78ca8efc6abf3902362f437",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/50e2045ed70a7e75a5e30bc3662904f3b67af8a9",
"reference": "50e2045ed70a7e75a5e30bc3662904f3b67af8a9",
"shasum": ""
},
"require": {
@@ -1540,7 +1541,7 @@
"sftp",
"storage"
],
"time": "2016-07-18 12:22:57"
"time": "2016-08-10 08:55:11"
},
{
"name": "maknz/slack",
@@ -1548,12 +1549,12 @@
"source": {
"type": "git",
"url": "https://github.com/maknz/slack.git",
"reference": "e44a4685743c2286466ce5f0dbc025cf23248333"
"reference": "e9bab77eb7344f4697756ca55386576b05dc8e5a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maknz/slack/zipball/e44a4685743c2286466ce5f0dbc025cf23248333",
"reference": "e44a4685743c2286466ce5f0dbc025cf23248333",
"url": "https://api.github.com/repos/maknz/slack/zipball/e9bab77eb7344f4697756ca55386576b05dc8e5a",
"reference": "e9bab77eb7344f4697756ca55386576b05dc8e5a",
"shasum": ""
},
"require": {
@@ -1590,7 +1591,7 @@
"laravel",
"slack"
],
"time": "2016-06-26 05:15:48"
"time": "2016-07-27 23:17:40"
},
{
"name": "maximebf/debugbar",
@@ -1654,17 +1655,62 @@
"time": "2016-01-22 12:22:23"
},
{
"name": "monolog/monolog",
"version": "1.20.0",
"name": "misterphilip/maintenance-mode",
"version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "55841909e2bcde01b5318c35f2b74f8ecc86e037"
"url": "https://github.com/MisterPhilip/maintenance-mode.git",
"reference": "35e061703edb3c0703baea677335c03085f2b179"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/55841909e2bcde01b5318c35f2b74f8ecc86e037",
"reference": "55841909e2bcde01b5318c35f2b74f8ecc86e037",
"url": "https://api.github.com/repos/MisterPhilip/maintenance-mode/zipball/35e061703edb3c0703baea677335c03085f2b179",
"reference": "35e061703edb3c0703baea677335c03085f2b179",
"shasum": ""
},
"require": {
"illuminate/support": "5.0 - 5.2",
"nesbot/carbon": "~1.19",
"php": ">=5.4.0"
},
"type": "library",
"autoload": {
"psr-0": {
"MisterPhilip\\MaintenanceMode": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Philip Lawrence",
"email": "philip@misterphilip.com",
"homepage": "http://misterphilip.com"
}
],
"description": "An enhanced drop-in replacement for Laravel 5's maintenance mode",
"keywords": [
"l5",
"laravel",
"laravel5",
"maintenance"
],
"time": "2015-12-23 07:24:42"
},
{
"name": "monolog/monolog",
"version": "1.21.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/f42fbdfd53e306bda545845e4dbfd3e72edb4952",
"reference": "f42fbdfd53e306bda545845e4dbfd3e72edb4952",
"shasum": ""
},
"require": {
@@ -1729,7 +1775,7 @@
"logging",
"psr-3"
],
"time": "2016-07-02 14:02:10"
"time": "2016-07-29 03:23:52"
},
{
"name": "mtdowling/cron-expression",
@@ -1978,16 +2024,16 @@
},
{
"name": "psr/http-message",
"version": "1.0",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298"
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"reference": "85d63699f0dbedb190bbd4b0d2b9dc707ea4c298",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
@@ -2015,6 +2061,7 @@
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
@@ -2023,7 +2070,7 @@
"request",
"response"
],
"time": "2015-05-04 20:22:00"
"time": "2016-08-06 14:39:51"
},
{
"name": "psr/log",
@@ -2302,16 +2349,16 @@
},
{
"name": "symfony/console",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "a7abb7153f6d1da47f87ec50274844e246b09d9f"
"reference": "926061e74229e935d3c5b4e9ba87237316c6693f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/a7abb7153f6d1da47f87ec50274844e246b09d9f",
"reference": "a7abb7153f6d1da47f87ec50274844e246b09d9f",
"url": "https://api.github.com/repos/symfony/console/zipball/926061e74229e935d3c5b4e9ba87237316c6693f",
"reference": "926061e74229e935d3c5b4e9ba87237316c6693f",
"shasum": ""
},
"require": {
@@ -2358,20 +2405,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 07:02:21"
"time": "2016-07-30 07:22:48"
},
{
"name": "symfony/debug",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "c54bc3539c3b87e86799533801e8ae0e971d78c2"
"reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/c54bc3539c3b87e86799533801e8ae0e971d78c2",
"reference": "c54bc3539c3b87e86799533801e8ae0e971d78c2",
"url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a",
"reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a",
"shasum": ""
},
"require": {
@@ -2415,20 +2462,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:40:00"
"time": "2016-07-30 07:22:48"
},
{
"name": "symfony/event-dispatcher",
"version": "v3.1.2",
"version": "v3.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "7f9839ede2070f53e7e2f0849b9bd14748c434c5"
"reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/7f9839ede2070f53e7e2f0849b9bd14748c434c5",
"reference": "7f9839ede2070f53e7e2f0849b9bd14748c434c5",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c0c00c80b3a69132c4e55c3e7db32b4a387615e5",
"reference": "c0c00c80b3a69132c4e55c3e7db32b4a387615e5",
"shasum": ""
},
"require": {
@@ -2475,11 +2522,11 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:41:56"
"time": "2016-07-19 10:45:57"
},
{
"name": "symfony/finder",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
@@ -2528,16 +2575,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "1341139f906d295baa4f4abd55293d07e25a065a"
"reference": "49ba00f8ede742169cb6b70abe33243f4d673f82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/1341139f906d295baa4f4abd55293d07e25a065a",
"reference": "1341139f906d295baa4f4abd55293d07e25a065a",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/49ba00f8ede742169cb6b70abe33243f4d673f82",
"reference": "49ba00f8ede742169cb6b70abe33243f4d673f82",
"shasum": ""
},
"require": {
@@ -2577,20 +2624,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 07:02:21"
"time": "2016-07-17 13:54:30"
},
{
"name": "symfony/http-kernel",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "177b63b2d50b63fa6d82ea41359ed9928cc7a1fb"
"reference": "d97ba4425e36e79c794e7d14ff36f00f081b37b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/177b63b2d50b63fa6d82ea41359ed9928cc7a1fb",
"reference": "177b63b2d50b63fa6d82ea41359ed9928cc7a1fb",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/d97ba4425e36e79c794e7d14ff36f00f081b37b3",
"reference": "d97ba4425e36e79c794e7d14ff36f00f081b37b3",
"shasum": ""
},
"require": {
@@ -2659,7 +2706,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2016-06-30 16:30:17"
"time": "2016-07-30 09:10:37"
},
{
"name": "symfony/polyfill-mbstring",
@@ -2830,16 +2877,16 @@
},
{
"name": "symfony/process",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "d7cde1f9d94d87060204f863779389b61c382eeb"
"reference": "768debc5996f599c4372b322d9061dba2a4bf505"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/d7cde1f9d94d87060204f863779389b61c382eeb",
"reference": "d7cde1f9d94d87060204f863779389b61c382eeb",
"url": "https://api.github.com/repos/symfony/process/zipball/768debc5996f599c4372b322d9061dba2a4bf505",
"reference": "768debc5996f599c4372b322d9061dba2a4bf505",
"shasum": ""
},
"require": {
@@ -2875,11 +2922,11 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:40:00"
"time": "2016-07-28 11:13:34"
},
{
"name": "symfony/routing",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
@@ -2954,16 +3001,16 @@
},
{
"name": "symfony/translation",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "6bf844e1ee3c820c012386c10427a5c67bbefec8"
"reference": "eee6c664853fd0576f21ae25725cfffeafe83f26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/6bf844e1ee3c820c012386c10427a5c67bbefec8",
"reference": "6bf844e1ee3c820c012386c10427a5c67bbefec8",
"url": "https://api.github.com/repos/symfony/translation/zipball/eee6c664853fd0576f21ae25725cfffeafe83f26",
"reference": "eee6c664853fd0576f21ae25725cfffeafe83f26",
"shasum": ""
},
"require": {
@@ -3014,20 +3061,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:40:00"
"time": "2016-07-30 07:22:48"
},
{
"name": "symfony/var-dumper",
"version": "v3.0.8",
"version": "v3.0.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "2f046e9a9d571f22cc8b26783564876713b06579"
"reference": "1f7e071aafc6676fcb6e3f0497f87c2397247377"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/2f046e9a9d571f22cc8b26783564876713b06579",
"reference": "2f046e9a9d571f22cc8b26783564876713b06579",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/1f7e071aafc6676fcb6e3f0497f87c2397247377",
"reference": "1f7e071aafc6676fcb6e3f0497f87c2397247377",
"shasum": ""
},
"require": {
@@ -3077,7 +3124,7 @@
"debug",
"dump"
],
"time": "2016-06-29 05:40:00"
"time": "2016-07-26 08:03:56"
},
{
"name": "tecnickcom/tc-lib-barcode",
@@ -4289,16 +4336,16 @@
},
{
"name": "phpunit/phpunit",
"version": "4.8.26",
"version": "4.8.27",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "fc1d8cd5b5de11625979125c5639347896ac2c74"
"reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc1d8cd5b5de11625979125c5639347896ac2c74",
"reference": "fc1d8cd5b5de11625979125c5639347896ac2c74",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c062dddcb68e44b563f66ee319ddae2b5a322a90",
"reference": "c062dddcb68e44b563f66ee319ddae2b5a322a90",
"shasum": ""
},
"require": {
@@ -4357,7 +4404,7 @@
"testing",
"xunit"
],
"time": "2016-05-17 03:09:28"
"time": "2016-07-21 06:48:14"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -4867,16 +4914,16 @@
},
{
"name": "symfony/browser-kit",
"version": "v3.1.2",
"version": "v3.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
"reference": "dcf41ed026b0499254385b5c88f03247b2ba010b"
"reference": "d2a07cc11c5fa94820240b1e67592ffb18e347b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/dcf41ed026b0499254385b5c88f03247b2ba010b",
"reference": "dcf41ed026b0499254385b5c88f03247b2ba010b",
"url": "https://api.github.com/repos/symfony/browser-kit/zipball/d2a07cc11c5fa94820240b1e67592ffb18e347b9",
"reference": "d2a07cc11c5fa94820240b1e67592ffb18e347b9",
"shasum": ""
},
"require": {
@@ -4920,11 +4967,11 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:41:56"
"time": "2016-07-26 08:04:17"
},
{
"name": "symfony/css-selector",
"version": "v3.1.2",
"version": "v3.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
@@ -4977,16 +5024,16 @@
},
{
"name": "symfony/dom-crawler",
"version": "v3.1.2",
"version": "v3.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "99ec4a23330fcd0c8667095f3ef7aa204ffd9dc0"
"reference": "c7b9b8db3a6f2bac76dcd9a9db5446f2591897f9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/99ec4a23330fcd0c8667095f3ef7aa204ffd9dc0",
"reference": "99ec4a23330fcd0c8667095f3ef7aa204ffd9dc0",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/c7b9b8db3a6f2bac76dcd9a9db5446f2591897f9",
"reference": "c7b9b8db3a6f2bac76dcd9a9db5446f2591897f9",
"shasum": ""
},
"require": {
@@ -5029,20 +5076,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:41:56"
"time": "2016-07-26 08:04:17"
},
{
"name": "symfony/yaml",
"version": "v3.1.2",
"version": "v3.1.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de"
"reference": "1819adf2066880c7967df7180f4f662b6f0567ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/2884c26ce4c1d61aebf423a8b912950fe7c764de",
"reference": "2884c26ce4c1d61aebf423a8b912950fe7c764de",
"url": "https://api.github.com/repos/symfony/yaml/zipball/1819adf2066880c7967df7180f4f662b6f0567ac",
"reference": "1819adf2066880c7967df7180f4f662b6f0567ac",
"shasum": ""
},
"require": {
@@ -5078,32 +5125,33 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:41:56"
"time": "2016-07-17 14:02:08"
},
{
"name": "webmozart/assert",
"version": "1.0.2",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
"reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde"
"reference": "bb2d123231c095735130cc8f6d31385a44c7b308"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
"reference": "30eed06dd6bc88410a4ff7f77b6d22f3ce13dbde",
"url": "https://api.github.com/repos/webmozart/assert/zipball/bb2d123231c095735130cc8f6d31385a44c7b308",
"reference": "bb2d123231c095735130cc8f6d31385a44c7b308",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": "^5.3.3|^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.6"
"phpunit/phpunit": "^4.6",
"sebastian/version": "^1.0.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
"dev-master": "1.2-dev"
}
},
"autoload": {
@@ -5127,7 +5175,7 @@
"check",
"validate"
],
"time": "2015-08-24 13:29:44"
"time": "2016-08-09 15:02:57"
}
],
"aliases": [],

View File

@@ -117,7 +117,7 @@ return [
|--------------------------------------------------------------------------
| This is the path for any uploaded files that have to be run through the
| auth system to ensure they are not visible to the public. These should be
| stored somewhere outside of the web root so that an unautenticated user
| stored somewhere outside of the web root so that an unauthenticated user
| cannot access them.
|
| For example: license keys, contracts, etc.
@@ -197,6 +197,8 @@ return [
Collective\Html\HtmlServiceProvider::class,
Spatie\Backup\BackupServiceProvider::class,
Fideloper\Proxy\TrustedProxyServiceProvider::class,
MisterPhilip\MaintenanceMode\MaintenanceModeServiceProvider::class,
MisterPhilip\MaintenanceMode\MaintenanceCommandServiceProvider::class,
/*
* Custom service provider

View File

@@ -46,19 +46,19 @@ return array(
'permission' => 'assets.create',
'label' => 'Create ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'assets.edit',
'label' => 'Edit ',
'label' => 'Edit ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'assets.delete',
'label' => 'Delete ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'assets.checkout',
@@ -71,7 +71,14 @@ return array(
'permission' => 'assets.checkin',
'label' => 'Checkin ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'assets.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => true,
),
array(
@@ -88,6 +95,7 @@ return array(
'note' => '',
'display' => true,
),
),
'Accessories' => array(
@@ -101,31 +109,31 @@ return array(
'permission' => 'accessory.create',
'label' => 'Create ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'accessories.edit',
'label' => 'Edit ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'accessories.delete',
'label' => 'Delete ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'accessories.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'accessories.checkin',
'label' => 'Checkin ',
'note' => '',
'display' => false,
'display' => true,
),
),
@@ -140,25 +148,25 @@ return array(
'permission' => 'consumables.create',
'label' => 'Create ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'consumables.edit',
'label' => 'Edit ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'consumables.delete',
'label' => 'Delete ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'consumables.checkout',
'label' => 'Checkout ',
'note' => '',
'display' => false,
'display' => true,
),
),
@@ -172,27 +180,27 @@ return array(
),
array(
'permission' => 'licenses.create',
'label' => 'Create Licenses',
'label' => 'Create ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'licenses.edit',
'label' => 'Edit Licenses',
'label' => 'Edit ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'licenses.delete',
'label' => 'Delete Licenses',
'label' => 'Delete ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'licenses.checkout',
'label' => 'Checkout Licenses',
'label' => 'Checkout ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'licenses.keys',
@@ -212,33 +220,33 @@ return array(
),
array(
'permission' => 'components.create',
'label' => 'Create Components',
'label' => 'Create ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'components.edit',
'label' => 'Edit Components',
'label' => 'Edit ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'components.delete',
'label' => 'Delete Components',
'label' => 'Delete ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'components.checkout',
'label' => 'Checkout Components',
'label' => 'Checkout ',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'components.checkin',
'label' => 'Checkin Components',
'label' => 'Checkin ',
'note' => '',
'display' => false,
'display' => true,
),
),
@@ -254,19 +262,19 @@ return array(
'permission' => 'users.create',
'label' => 'Create Users',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'users.edit',
'label' => 'Edit Users',
'note' => '',
'display' => false,
'display' => true,
),
array(
'permission' => 'users.delete',
'label' => 'Delete Users',
'note' => '',
'display' => false,
'display' => true,
),
),

View File

@@ -1,5 +1,5 @@
<?php
return array (
'app_version' => 'v3.0',
'hash_version' => 'v3.0-ebc74a65',
'app_version' => 'v3.4.0-alpha',
'hash_version' => 'v3.4.0-alpha-49-g122f0b9',
);

View File

@@ -18,9 +18,9 @@ class UpdateGroupFieldForReporting extends Migration {
// //
// });
DB::update('update groups set permissions = ? where id = ?', ['{"admin":1,"users":1,"reports":1}', 1]);
DB::update('update '.DB::getTablePrefix().'groups set permissions = ? where id = ?', ['{"admin":1,"users":1,"reports":1}', 1]);
DB::update('update groups set permissions = ? where id = ?', ['{"users":1,"reports":1}', 2]);
DB::update('update '.DB::getTablePrefix().'groups set permissions = ? where id = ?', ['{"users":1,"reports":1}', 2]);
// DB::statement('UPDATE '.$prefix.'groups SET permissions="{\"admin\":1,\"users\":1,\"reports\":1}" where id=1');
// DB::statement('UPDATE '.$prefix.'groups SET permissions="{\"users\":1,\"reports\":1}" where id=2');

View File

@@ -0,0 +1,78 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class FixCustomFieldsRegexStuff extends Migration
{
/**
* Run the migrations.
* "ANY" => "",
* "ALPHA" => "alpha",
* "EMAIL" => "email",
* "DATE" => "date",
* "URL" => "url",
* "NUMERIC" => "numeric",
* "MAC" => "regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/",
* "IP" => "ip"
*
* @return void
*/
public function up()
{
foreach(\App\Models\CustomField::all() as $custom_field) {
// Handle alphanumeric
if (stripos($custom_field->format, 'ALPHA') !== false) {
$custom_field->format='alpha';
// Numeric
} elseif (stripos($custom_field->format, 'NUMERIC') !== false) {
$custom_field->format='numeric';
// IP
} elseif (stripos($custom_field->format, 'IP') !== false) {
$custom_field->format='ip';
// Email
} elseif (stripos($custom_field->format, 'EMAIL') !== false) {
$custom_field->format='email';
// MAC
} elseif (stripos($custom_field->format, 'regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/') !== false) {
$custom_field->format='regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/';
// Date
} elseif (stripos($custom_field->format, 'DATE') !== false) {
$custom_field->format='date';
// URL
} elseif (stripos($custom_field->format, 'URL') !== false) {
$custom_field->format='url';
// ANY
} elseif (stripos($custom_field->format, 'ANY') !== false) {
$custom_field->format='';
// Fix any custom regexes
} else {
$tmp_custom = str_replace('regex:/^', '', $custom_field->format);
$tmp_custom = str_replace('$/', '', $tmp_custom);
$custom_field->format = 'regex:/^'.$tmp_custom.'$/';
}
$custom_field->save();
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class OneMoreMacAddrFix extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
foreach(\App\Models\CustomField::all() as $custom_field) {
if ($custom_field->format=='regex:/^MAC$/') {
$custom_field->format = 'regex:/^[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}:[a-fA-F0-9]{2}$/';
}
$custom_field->save();
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
//
}
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddPortToLdapSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('ldap_port', 5)->default('389');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function ($table) {
$table->dropColumn('ldap_port');
});
}
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddTlsToLdapSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->boolean('ldap_tls')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function ($table) {
$table->dropColumn('ldap_tls');
});
}
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddZerofillToSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->integer('zerofill_count')->default(5);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function ($table) {
$table->dropColumn('zerofill_count');
});
}
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddColorToStatuslabel extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('status_labels', function (Blueprint $table) {
$table->string('color', 10)->nullable()->default(NULL);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('status_labels', function ($table) {
$table->dropColumn('color');
});
}
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddDisallowLdapPwSyncToSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->boolean('ldap_pw_sync')->default(1);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function ($table) {
$table->dropColumn('ldap_pw_sync');
});
}
}

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddManufacturerToLicenses extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('licenses', function (Blueprint $table) {
//
$table->integer('manufacturer_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('licenses', function (Blueprint $table) {
//
});
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddManufacturerToAccessoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('accessories', function (Blueprint $table) {
//
$table->integer('manufacturer_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('accessories', function (Blueprint $table) {
//
$table->dropColumn('manufacturer_id');
});
}
}

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddNewFieldsToCustomFields extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('custom_fields', function (Blueprint $table) {
//
$table->string('field_values')->nullable()->default(null);
$table->boolean('field_encrypted')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('custom_fields', function (Blueprint $table) {
//
$table->dropColumn('field_values', 'field_encrypted');
});
}
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddShowInNavToStatusLabels extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('status_labels', function (Blueprint $table) {
$table->boolean('show_in_nav')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('status_labels', function (Blueprint $table) {
$table->dropColumn('show_in_nav', 'field_encrypted');
});
}
}

View File

@@ -1 +1 @@
See http://docs.snipeitapp.com/installation/server/docker.html for Docker information
See https://snipe-it.readme.io/docs/docker for Docker information

View File

@@ -18,6 +18,7 @@ DB_DATABASE=${MYSQL_DATABASE}
DB_USERNAME=${MYSQL_USER}
DB_PASSWORD=${MYSQL_PASSWORD}
DB_PREFIX=null
DB_DUMP_PATH='/usr/bin'
# --------------------------------------------

View File

@@ -38,7 +38,7 @@ elixir(function(mix) {
mix.version(['assets/css/app.css','assets/js/all.js']);
// mix.codeception();
mix.codeception();

View File

@@ -2,6 +2,6 @@
if [ "$(id -u)" != "0" ]; then
exec sudo "$0" "$@"
fi
wget https://raw.githubusercontent.com/snipe/snipe-it/v3/snipeit.sh
wget https://raw.githubusercontent.com/snipe/snipe-it/master/snipeit.sh
chmod 744 snipeit.sh
sudo ./snipeit.sh 2>&1 | sudo tee -a /var/log/snipeit-install.log

View File

@@ -57,6 +57,7 @@ body {
.content-wrapper,
.right-side,
.main-footer {
transition: -webkit-transform 0.3s ease-in-out, margin 0.3s ease-in-out;
transition: transform 0.3s ease-in-out, margin 0.3s ease-in-out;
margin-left: 230px;
z-index: 820;
@@ -84,6 +85,7 @@ body {
.sidebar-open .content-wrapper,
.sidebar-open .right-side,
.sidebar-open .main-footer {
-webkit-transform: translate(230px, 0);
transform: translate(230px, 0);
}
}
@@ -425,6 +427,7 @@ a:focus {
min-height: 100%;
width: 230px;
z-index: 810;
transition: -webkit-transform 0.3s ease-in-out, width 0.3s ease-in-out;
transition: transform 0.3s ease-in-out, width 0.3s ease-in-out;
}
@media (max-width: 767px) {
@@ -436,18 +439,21 @@ a:focus {
@media (max-width: 767px) {
.main-sidebar,
.left-side {
-webkit-transform: translate(-230px, 0);
transform: translate(-230px, 0);
}
}
@media (min-width: 768px) {
.sidebar-collapse .main-sidebar,
.sidebar-collapse .left-side {
-webkit-transform: translate(-230px, 0);
transform: translate(-230px, 0);
}
}
@media (max-width: 767px) {
.sidebar-open .main-sidebar,
.sidebar-open .left-side {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
}
@@ -533,6 +539,7 @@ a:focus {
margin-top: 3px;
}
.sidebar-menu li.active > a > .fa-angle-left {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.sidebar-menu li.active > .treeview-menu {
@@ -576,6 +583,7 @@ a:focus {
z-index: 840;
}
.sidebar-mini.sidebar-collapse .main-sidebar {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
width: 50px!important;
z-index: 850;
@@ -1142,30 +1150,58 @@ a:focus {
/* Add fade animation to dropdown menus by appending
the class .animated-dropdown-menu to the .dropdown-menu ul (or ol)*/
.open:not(.dropup) > .animated-dropdown-menu {
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
-webkit-animation: flipInX 0.7s both;
animation: flipInX 0.7s both;
}
@keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transition-timing-function: ease-in;
opacity: 0;
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transition-timing-function: ease-in;
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
100% {
-webkit-transform: perspective(400px);
transform: perspective(400px);
}
}
@-webkit-keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-transition-timing-function: ease-in;
opacity: 0;
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-transition-timing-function: ease-in;
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
100% {
-webkit-transform: perspective(400px);
}
}
/* Fix dropdown menu in navbars */
.navbar-custom-menu > .navbar-nav > li {
position: relative;
@@ -2459,9 +2495,11 @@ table.text-center th {
padding: 0;
}
.direct-chat.chat-pane-open .direct-chat-contacts {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
.direct-chat-messages {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
padding: 10px;
height: 250px;
@@ -2484,6 +2522,7 @@ table.text-center th {
}
.direct-chat-messages,
.direct-chat-contacts {
transition: -webkit-transform 0.5s ease-in-out;
transition: transform 0.5s ease-in-out;
}
.direct-chat-text {
@@ -2547,9 +2586,11 @@ table.text-center th {
color: #999;
}
.direct-chat-contacts-open .direct-chat-contacts {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
.direct-chat-contacts {
-webkit-transform: translate(101%, 0);
transform: translate(101%, 0);
position: absolute;
top: 0;
@@ -3902,9 +3943,11 @@ fieldset[disabled] .btn-yahoo.active {
line-height: 30px;
}
.fc-color-picker > li .fa {
transition: -webkit-transform linear 0.3s;
transition: transform linear 0.3s;
}
.fc-color-picker > li .fa:hover {
-webkit-transform: rotate(30deg);
transform: rotate(30deg);
}
#add-new-event {
@@ -4599,6 +4642,7 @@ fieldset[disabled] .btn-yahoo.active {
.main-footer {
margin-left: 0!important;
min-height: 0!important;
-webkit-transform: translate(0, 0) !important;
transform: translate(0, 0) !important;
}
.fixed .content-wrapper,
@@ -5114,52 +5158,117 @@ a.accordion-header {
a.logo.no-hover a:hover {
background-color: transparent;
}
.required {
border-right: 6px solid orange;
}
/* WRENCHING */
@-webkit-keyframes wrench {
0% {
-webkit-transform: rotate(-12deg);
}
8% {
-webkit-transform: rotate(12deg);
}
10% {
-webkit-transform: rotate(24deg);
}
18% {
-webkit-transform: rotate(-24deg);
}
20% {
-webkit-transform: rotate(-24deg);
}
28% {
-webkit-transform: rotate(24deg);
}
30% {
-webkit-transform: rotate(24deg);
}
38% {
-webkit-transform: rotate(-24deg);
}
40% {
-webkit-transform: rotate(-24deg);
}
48% {
-webkit-transform: rotate(24deg);
}
50% {
-webkit-transform: rotate(24deg);
}
58% {
-webkit-transform: rotate(-24deg);
}
60% {
-webkit-transform: rotate(-24deg);
}
68% {
-webkit-transform: rotate(24deg);
}
75% {
-webkit-transform: rotate(0deg);
}
}
@keyframes wrench {
0% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg);
}
8% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg);
}
10% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
18% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
20% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
28% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
30% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
38% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
40% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
48% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
50% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
58% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
60% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
68% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
75% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
@@ -5177,44 +5286,91 @@ a.logo.no-hover a:hover {
-ms-transform-origin-x: 90%;
-ms-transform-origin-y: 35%;
-ms-transform-origin-z: initial;
-webkit-animation: wrench 2.5s ease infinite;
animation: wrench 2.5s ease infinite;
transform-origin-x: 90%;
transform-origin-y: 35%;
transform-origin-z: initial;
}
/* BELL */
@-webkit-keyframes ring {
0% {
-webkit-transform: rotate(-15deg);
}
2% {
-webkit-transform: rotate(15deg);
}
4% {
-webkit-transform: rotate(-18deg);
}
6% {
-webkit-transform: rotate(18deg);
}
8% {
-webkit-transform: rotate(-22deg);
}
10% {
-webkit-transform: rotate(22deg);
}
12% {
-webkit-transform: rotate(-18deg);
}
14% {
-webkit-transform: rotate(18deg);
}
16% {
-webkit-transform: rotate(-12deg);
}
18% {
-webkit-transform: rotate(12deg);
}
20% {
-webkit-transform: rotate(0deg);
}
}
@keyframes ring {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg);
}
2% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg);
}
4% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg);
}
6% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg);
}
8% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg);
}
10% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg);
}
12% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg);
}
14% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg);
}
16% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg);
}
18% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg);
}
20% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
@@ -5232,68 +5388,142 @@ a.logo.no-hover a:hover {
-ms-transform-origin-x: 50%;
-ms-transform-origin-y: 0px;
-ms-transform-origin-z: initial;
-webkit-animation: ring 2s ease infinite;
animation: ring 2s ease infinite;
transform-origin-x: 50%;
transform-origin-y: 0px;
transform-origin-z: initial;
}
/* VERTICAL */
@-webkit-keyframes vertical {
0% {
-webkit-transform: translate(0, -3px);
}
4% {
-webkit-transform: translate(0, 3px);
}
8% {
-webkit-transform: translate(0, -3px);
}
12% {
-webkit-transform: translate(0, 3px);
}
16% {
-webkit-transform: translate(0, -3px);
}
20% {
-webkit-transform: translate(0, 3px);
}
22% {
-webkit-transform: translate(0, 0);
}
}
@keyframes vertical {
0% {
-webkit-transform: translate(0, -3px);
transform: translate(0, -3px);
}
4% {
-webkit-transform: translate(0, 3px);
transform: translate(0, 3px);
}
8% {
-webkit-transform: translate(0, -3px);
transform: translate(0, -3px);
}
12% {
-webkit-transform: translate(0, 3px);
transform: translate(0, 3px);
}
16% {
-webkit-transform: translate(0, -3px);
transform: translate(0, -3px);
}
20% {
-webkit-transform: translate(0, 3px);
transform: translate(0, 3px);
}
22% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
}
.faa-vertical.animated,
.faa-vertical.animated-hover:hover {
-webkit-animation: vertical 2s ease infinite;
animation: vertical 2s ease infinite;
}
/* HORIZONTAL */
@-webkit-keyframes horizontal {
0% {
-webkit-transform: translate(0, 0);
}
6% {
-webkit-transform: translate(5px, 0);
}
12% {
-webkit-transform: translate(0, 0);
}
18% {
-webkit-transform: translate(5px, 0);
}
24% {
-webkit-transform: translate(0, 0);
}
30% {
-webkit-transform: translate(5px, 0);
}
36% {
-webkit-transform: translate(0, 0);
}
}
@keyframes horizontal {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
6% {
-webkit-transform: translate(5px, 0);
transform: translate(5px, 0);
}
12% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
18% {
-webkit-transform: translate(5px, 0);
transform: translate(5px, 0);
}
24% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
30% {
-webkit-transform: translate(5px, 0);
transform: translate(5px, 0);
}
36% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
}
.faa-horizontal.animated,
.faa-horizontal.animated-hover:hover {
-webkit-animation: horizontal 2s ease infinite;
animation: horizontal 2s ease infinite;
}
/* FLASHING */
@-webkit-keyframes flash {
0%,
100%,
50% {
opacity: 1;
}
25%,
75% {
opacity: 0;
}
}
@keyframes flash {
0%,
100%,
@@ -5307,71 +5537,132 @@ a.logo.no-hover a:hover {
}
.faa-flash.animated,
.faa-flash.animated-hover:hover {
-webkit-animation: flash 2s ease infinite;
animation: flash 2s ease infinite;
}
/* BOUNCE */
@-webkit-keyframes bounce {
0%,
100%,
20%,
50%,
80% {
-webkit-transform: translateY(0);
}
40% {
-webkit-transform: translateY(-15px);
}
60% {
-webkit-transform: translateY(-15px);
}
}
@keyframes bounce {
0%,
10%,
20%,
50%,
80% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
40% {
-webkit-transform: translateY(-15px);
transform: translateY(-15px);
}
60% {
-webkit-transform: translateY(-15px);
transform: translateY(-15px);
}
}
.faa-bounce.animated,
.faa-bounce.animated-hover:hover {
-webkit-animation: bounce 2s ease infinite;
animation: bounce 2s ease infinite;
}
/* SPIN */
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.faa-spin.animated,
.faa-spin.animated-hover:hover {
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}
/* FLOAT */
@-webkit-keyframes float {
0% {
-webkit-transform: translateY(0);
}
50% {
-webkit-transform: translateY(-6px);
}
100% {
-webkit-transform: translateY(0);
}
}
@keyframes float {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
50% {
-webkit-transform: translateY(-6px);
transform: translateY(-6px);
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
.faa-float.animated,
.faa-float.animated-hover:hover {
-webkit-animation: float 2s linear infinite;
animation: float 2s linear infinite;
}
/* PULSE */
@-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1);
}
50% {
-webkit-transform: scale(0.8);
}
100% {
-webkit-transform: scale(1);
}
}
@keyframes pulse {
0% {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
50% {
-webkit-transform: scale(0.8);
transform: scale(0.8);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
.faa-pulse.animated,
.faa-pulse.animated-hover:hover {
-webkit-animation: pulse 2s linear infinite;
animation: pulse 2s linear infinite;
}
/* SHAKE */

File diff suppressed because one or more lines are too long

1
public/assets/css/jquery.typeahead.min.css vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -34248,7 +34248,7 @@ var pieOptions = {
//String - A tooltip template
tooltipTemplate: "<%=value %> <%=label%> "
};
console.dir(pieOptions);
//console.dir(pieOptions);
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
//pieChart.Doughnut(PieData, pieOptions);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

11
public/assets/js/jquery.typeahead.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@@ -57,6 +57,7 @@ body {
.content-wrapper,
.right-side,
.main-footer {
transition: -webkit-transform 0.3s ease-in-out, margin 0.3s ease-in-out;
transition: transform 0.3s ease-in-out, margin 0.3s ease-in-out;
margin-left: 230px;
z-index: 820;
@@ -84,6 +85,7 @@ body {
.sidebar-open .content-wrapper,
.sidebar-open .right-side,
.sidebar-open .main-footer {
-webkit-transform: translate(230px, 0);
transform: translate(230px, 0);
}
}
@@ -425,6 +427,7 @@ a:focus {
min-height: 100%;
width: 230px;
z-index: 810;
transition: -webkit-transform 0.3s ease-in-out, width 0.3s ease-in-out;
transition: transform 0.3s ease-in-out, width 0.3s ease-in-out;
}
@media (max-width: 767px) {
@@ -436,18 +439,21 @@ a:focus {
@media (max-width: 767px) {
.main-sidebar,
.left-side {
-webkit-transform: translate(-230px, 0);
transform: translate(-230px, 0);
}
}
@media (min-width: 768px) {
.sidebar-collapse .main-sidebar,
.sidebar-collapse .left-side {
-webkit-transform: translate(-230px, 0);
transform: translate(-230px, 0);
}
}
@media (max-width: 767px) {
.sidebar-open .main-sidebar,
.sidebar-open .left-side {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
}
@@ -533,6 +539,7 @@ a:focus {
margin-top: 3px;
}
.sidebar-menu li.active > a > .fa-angle-left {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.sidebar-menu li.active > .treeview-menu {
@@ -576,6 +583,7 @@ a:focus {
z-index: 840;
}
.sidebar-mini.sidebar-collapse .main-sidebar {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
width: 50px!important;
z-index: 850;
@@ -1142,30 +1150,58 @@ a:focus {
/* Add fade animation to dropdown menus by appending
the class .animated-dropdown-menu to the .dropdown-menu ul (or ol)*/
.open:not(.dropup) > .animated-dropdown-menu {
-webkit-backface-visibility: visible !important;
backface-visibility: visible !important;
-webkit-animation: flipInX 0.7s both;
animation: flipInX 0.7s both;
}
@keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
transition-timing-function: ease-in;
opacity: 0;
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
transition-timing-function: ease-in;
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
100% {
-webkit-transform: perspective(400px);
transform: perspective(400px);
}
}
@-webkit-keyframes flipInX {
0% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
-webkit-transition-timing-function: ease-in;
opacity: 0;
}
40% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
-webkit-transition-timing-function: ease-in;
}
60% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
opacity: 1;
}
80% {
-webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
100% {
-webkit-transform: perspective(400px);
}
}
/* Fix dropdown menu in navbars */
.navbar-custom-menu > .navbar-nav > li {
position: relative;
@@ -2459,9 +2495,11 @@ table.text-center th {
padding: 0;
}
.direct-chat.chat-pane-open .direct-chat-contacts {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
.direct-chat-messages {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
padding: 10px;
height: 250px;
@@ -2484,6 +2522,7 @@ table.text-center th {
}
.direct-chat-messages,
.direct-chat-contacts {
transition: -webkit-transform 0.5s ease-in-out;
transition: transform 0.5s ease-in-out;
}
.direct-chat-text {
@@ -2547,9 +2586,11 @@ table.text-center th {
color: #999;
}
.direct-chat-contacts-open .direct-chat-contacts {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
.direct-chat-contacts {
-webkit-transform: translate(101%, 0);
transform: translate(101%, 0);
position: absolute;
top: 0;
@@ -3902,9 +3943,11 @@ fieldset[disabled] .btn-yahoo.active {
line-height: 30px;
}
.fc-color-picker > li .fa {
transition: -webkit-transform linear 0.3s;
transition: transform linear 0.3s;
}
.fc-color-picker > li .fa:hover {
-webkit-transform: rotate(30deg);
transform: rotate(30deg);
}
#add-new-event {
@@ -4599,6 +4642,7 @@ fieldset[disabled] .btn-yahoo.active {
.main-footer {
margin-left: 0!important;
min-height: 0!important;
-webkit-transform: translate(0, 0) !important;
transform: translate(0, 0) !important;
}
.fixed .content-wrapper,
@@ -5114,52 +5158,117 @@ a.accordion-header {
a.logo.no-hover a:hover {
background-color: transparent;
}
.required {
border-right: 6px solid orange;
}
/* WRENCHING */
@-webkit-keyframes wrench {
0% {
-webkit-transform: rotate(-12deg);
}
8% {
-webkit-transform: rotate(12deg);
}
10% {
-webkit-transform: rotate(24deg);
}
18% {
-webkit-transform: rotate(-24deg);
}
20% {
-webkit-transform: rotate(-24deg);
}
28% {
-webkit-transform: rotate(24deg);
}
30% {
-webkit-transform: rotate(24deg);
}
38% {
-webkit-transform: rotate(-24deg);
}
40% {
-webkit-transform: rotate(-24deg);
}
48% {
-webkit-transform: rotate(24deg);
}
50% {
-webkit-transform: rotate(24deg);
}
58% {
-webkit-transform: rotate(-24deg);
}
60% {
-webkit-transform: rotate(-24deg);
}
68% {
-webkit-transform: rotate(24deg);
}
75% {
-webkit-transform: rotate(0deg);
}
}
@keyframes wrench {
0% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg);
}
8% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg);
}
10% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
18% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
20% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
28% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
30% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
38% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
40% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
48% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
50% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
58% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
60% {
-webkit-transform: rotate(-24deg);
transform: rotate(-24deg);
}
68% {
-webkit-transform: rotate(24deg);
transform: rotate(24deg);
}
75% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
@@ -5177,44 +5286,91 @@ a.logo.no-hover a:hover {
-ms-transform-origin-x: 90%;
-ms-transform-origin-y: 35%;
-ms-transform-origin-z: initial;
-webkit-animation: wrench 2.5s ease infinite;
animation: wrench 2.5s ease infinite;
transform-origin-x: 90%;
transform-origin-y: 35%;
transform-origin-z: initial;
}
/* BELL */
@-webkit-keyframes ring {
0% {
-webkit-transform: rotate(-15deg);
}
2% {
-webkit-transform: rotate(15deg);
}
4% {
-webkit-transform: rotate(-18deg);
}
6% {
-webkit-transform: rotate(18deg);
}
8% {
-webkit-transform: rotate(-22deg);
}
10% {
-webkit-transform: rotate(22deg);
}
12% {
-webkit-transform: rotate(-18deg);
}
14% {
-webkit-transform: rotate(18deg);
}
16% {
-webkit-transform: rotate(-12deg);
}
18% {
-webkit-transform: rotate(12deg);
}
20% {
-webkit-transform: rotate(0deg);
}
}
@keyframes ring {
0% {
-webkit-transform: rotate(-15deg);
transform: rotate(-15deg);
}
2% {
-webkit-transform: rotate(15deg);
transform: rotate(15deg);
}
4% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg);
}
6% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg);
}
8% {
-webkit-transform: rotate(-22deg);
transform: rotate(-22deg);
}
10% {
-webkit-transform: rotate(22deg);
transform: rotate(22deg);
}
12% {
-webkit-transform: rotate(-18deg);
transform: rotate(-18deg);
}
14% {
-webkit-transform: rotate(18deg);
transform: rotate(18deg);
}
16% {
-webkit-transform: rotate(-12deg);
transform: rotate(-12deg);
}
18% {
-webkit-transform: rotate(12deg);
transform: rotate(12deg);
}
20% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
}
@@ -5232,68 +5388,142 @@ a.logo.no-hover a:hover {
-ms-transform-origin-x: 50%;
-ms-transform-origin-y: 0px;
-ms-transform-origin-z: initial;
-webkit-animation: ring 2s ease infinite;
animation: ring 2s ease infinite;
transform-origin-x: 50%;
transform-origin-y: 0px;
transform-origin-z: initial;
}
/* VERTICAL */
@-webkit-keyframes vertical {
0% {
-webkit-transform: translate(0, -3px);
}
4% {
-webkit-transform: translate(0, 3px);
}
8% {
-webkit-transform: translate(0, -3px);
}
12% {
-webkit-transform: translate(0, 3px);
}
16% {
-webkit-transform: translate(0, -3px);
}
20% {
-webkit-transform: translate(0, 3px);
}
22% {
-webkit-transform: translate(0, 0);
}
}
@keyframes vertical {
0% {
-webkit-transform: translate(0, -3px);
transform: translate(0, -3px);
}
4% {
-webkit-transform: translate(0, 3px);
transform: translate(0, 3px);
}
8% {
-webkit-transform: translate(0, -3px);
transform: translate(0, -3px);
}
12% {
-webkit-transform: translate(0, 3px);
transform: translate(0, 3px);
}
16% {
-webkit-transform: translate(0, -3px);
transform: translate(0, -3px);
}
20% {
-webkit-transform: translate(0, 3px);
transform: translate(0, 3px);
}
22% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
}
.faa-vertical.animated,
.faa-vertical.animated-hover:hover {
-webkit-animation: vertical 2s ease infinite;
animation: vertical 2s ease infinite;
}
/* HORIZONTAL */
@-webkit-keyframes horizontal {
0% {
-webkit-transform: translate(0, 0);
}
6% {
-webkit-transform: translate(5px, 0);
}
12% {
-webkit-transform: translate(0, 0);
}
18% {
-webkit-transform: translate(5px, 0);
}
24% {
-webkit-transform: translate(0, 0);
}
30% {
-webkit-transform: translate(5px, 0);
}
36% {
-webkit-transform: translate(0, 0);
}
}
@keyframes horizontal {
0% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
6% {
-webkit-transform: translate(5px, 0);
transform: translate(5px, 0);
}
12% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
18% {
-webkit-transform: translate(5px, 0);
transform: translate(5px, 0);
}
24% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
30% {
-webkit-transform: translate(5px, 0);
transform: translate(5px, 0);
}
36% {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}
}
.faa-horizontal.animated,
.faa-horizontal.animated-hover:hover {
-webkit-animation: horizontal 2s ease infinite;
animation: horizontal 2s ease infinite;
}
/* FLASHING */
@-webkit-keyframes flash {
0%,
100%,
50% {
opacity: 1;
}
25%,
75% {
opacity: 0;
}
}
@keyframes flash {
0%,
100%,
@@ -5307,71 +5537,132 @@ a.logo.no-hover a:hover {
}
.faa-flash.animated,
.faa-flash.animated-hover:hover {
-webkit-animation: flash 2s ease infinite;
animation: flash 2s ease infinite;
}
/* BOUNCE */
@-webkit-keyframes bounce {
0%,
100%,
20%,
50%,
80% {
-webkit-transform: translateY(0);
}
40% {
-webkit-transform: translateY(-15px);
}
60% {
-webkit-transform: translateY(-15px);
}
}
@keyframes bounce {
0%,
10%,
20%,
50%,
80% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
40% {
-webkit-transform: translateY(-15px);
transform: translateY(-15px);
}
60% {
-webkit-transform: translateY(-15px);
transform: translateY(-15px);
}
}
.faa-bounce.animated,
.faa-bounce.animated-hover:hover {
-webkit-animation: bounce 2s ease infinite;
animation: bounce 2s ease infinite;
}
/* SPIN */
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
}
}
@keyframes spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.faa-spin.animated,
.faa-spin.animated-hover:hover {
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}
/* FLOAT */
@-webkit-keyframes float {
0% {
-webkit-transform: translateY(0);
}
50% {
-webkit-transform: translateY(-6px);
}
100% {
-webkit-transform: translateY(0);
}
}
@keyframes float {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
50% {
-webkit-transform: translateY(-6px);
transform: translateY(-6px);
}
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
.faa-float.animated,
.faa-float.animated-hover:hover {
-webkit-animation: float 2s linear infinite;
animation: float 2s linear infinite;
}
/* PULSE */
@-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1);
}
50% {
-webkit-transform: scale(0.8);
}
100% {
-webkit-transform: scale(1);
}
}
@keyframes pulse {
0% {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
50% {
-webkit-transform: scale(0.8);
transform: scale(0.8);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
}
}
.faa-pulse.animated,
.faa-pulse.animated-hover:hover {
-webkit-animation: pulse 2s linear infinite;
animation: pulse 2s linear infinite;
}
/* SHAKE */

File diff suppressed because one or more lines are too long

View File

@@ -34248,7 +34248,7 @@ var pieOptions = {
//String - A tooltip template
tooltipTemplate: "<%=value %> <%=label%> "
};
console.dir(pieOptions);
//console.dir(pieOptions);
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
//pieChart.Doughnut(PieData, pieOptions);

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
{
"assets/css/app.css": "assets/css/app-ec8e97e7ca.css",
"assets/js/all.js": "assets/js/all-edd914620a.js"
"assets/css/app.css": "assets/css/app-de75b6d10a.css",
"assets/js/all.js": "assets/js/all-5ba6978224.js"
}

1
public/uploads/.gitignore vendored Executable file
View File

@@ -0,0 +1 @@
!.gitignore

1
public/uploads/assets/.gitignore vendored Executable file
View File

@@ -0,0 +1 @@
!.gitignore

1
public/uploads/avatars/.gitignore vendored Executable file
View File

@@ -0,0 +1 @@
!.gitignore

View File

1
public/uploads/models/.gitignore vendored Executable file
View File

@@ -0,0 +1 @@
!.gitignore

1
public/uploads/suppliers/.gitignore vendored Executable file
View File

@@ -0,0 +1 @@
!.gitignore

View File

@@ -35,7 +35,7 @@ var pieOptions = {
//String - A tooltip template
tooltipTemplate: "<%=value %> <%=label%> "
};
console.dir(pieOptions);
//console.dir(pieOptions);
//Create pie or douhnut chart
// You can switch between pie and douhnut using the method below.
//pieChart.Doughnut(PieData, pieOptions);

View File

@@ -283,3 +283,7 @@ a.logo.no-hover a:hover {
}
.required {
border-right: 6px solid orange;
}

View File

@@ -12,12 +12,12 @@ return array(
'update' => array(
'error' => 'لم يتم تحديث الملحق، الرجاء المحاولة مرة أخرى',
'success' => 'تم بنجاح تحديث الملحق.'
'success' => 'تم تحديث الملحق بنجاح.'
),
'delete' => array(
'confirm' => 'هل أنت متأكد من رغبتك في حذف هذا الملحق؟',
'error' => 'حدث خطأ أثناء محاولة حذف الملحق. الرجاء حاول مرة أخرى.',
'error' => 'حدث خطأ أثناء محاولة حذف الملحق. الرجاء المحاولة مرة أخرى.',
'success' => 'تم حذف الملحق بنجاح.'
),
@@ -30,7 +30,7 @@ return array(
'checkin' => array(
'error' => 'لم يتم إيداع الملحق، الرجاء المحاولة مرة أخرى',
'success' => 'تم إيداع الملحق بنجاح.',
'user_does_not_exist' => 'هذا المستخدم خاطئ، الرجاء المحاولة مرة أخرى.'
'user_does_not_exist' => 'هذا المستخدم غير صحيح. الرجاء المحاولة مرة أخرى.'
)

View File

@@ -1,7 +1,7 @@
<?php
return [
'asset_maintenances' => 'صيانة الاُصول',
'asset_maintenances' => 'صيانة الاُصل',
'edit' => 'تعديل صيانة الأصل',
'delete' => 'حذف صيانة الأصل',
'view' => 'عرض تفاصيل صيانة الأصل',

View File

@@ -1,15 +1,15 @@
<?php
return [
'not_found' => 'لم يتم العثور على صيانة الأصل!',
'not_found' => 'لم يتم العثور على سند صيانة الأصل المطلوب!',
'delete' => [
'confirm' => 'هل أنت متأكد من رغبتك في حذف صيانة الأصل؟',
'error' => 'حدثت مشكلة في عملية الحذف لصيانة الأصل. الرجاء المحاولة مرة اُخرى.',
'success' => 'تم حذف صيانة الأصل بنجاح.'
'confirm' => 'هل أنت متأكد من رغبتك في حذف سند صيانة الأصل؟',
'error' => 'حدثت مشكلة في عملية الحذف لسند صيانة الأصل. الرجاء المحاولة مرة اُخرى.',
'success' => 'تم حذف سند صيانة الأصل بنجاح.'
],
'create' => [
'error' => 'لم يتم إنشاء صيانة الأصل، الرجاء المحاولة مرة أخرى.',
'success' => 'تم إنشاء صيانة الأصل بنجاح.'
'error' => 'لم يتم إنشاء سند صيانة الأصل، الرجاء المحاولة مرة أخرى.',
'success' => 'تم إنشاء سند صيانة الأصل بنجاح.'
],
'asset_maintenance_incomplete' => 'لم يكتمل بعد',
'warranty' => 'الضمان',

View File

@@ -3,7 +3,7 @@
return [
'title' => 'صيانة الاُصل',
'asset_name' => 'الأصل',
'supplier_name' => 'المزود',
'supplier_name' => 'المورد',
'is_warranty' => 'الضمان',
'dl_csv' => 'التنزيل كملف CSV'
];

View File

@@ -3,8 +3,8 @@
return array(
'does_not_exist' => 'التصنيف غير موجود.',
'assoc_models' => 'This category is currently associated with at least one model and cannot be deleted. Please update your models to no longer reference this category and try again. ',
'assoc_items' => 'This category is currently associated with at least one :asset_type and cannot be deleted. Please update your :asset_type to no longer reference this category and try again. ',
'assoc_models' => 'هذا التصنيف حاليا مرتبط مع نموذج ولا يمكن حذفه. الرجاء القيام بتحديث النماذج بحيث لا تكون مرتبطة بهذا التصنيف، ثم حاول مرة اخرى. ',
'assoc_items' => 'هذه التصنيف مرتبط حاليا مع واحد على الأقل من أنواع الاصول asset_type: ولا يمكن حذفه. الرجاء تحديث نوع الاصل الخاص بك asset_type: حيث لا يكون مرتبط بهذا التصنيف، ثم حاول مرة أخرى. ',
'create' => array(
'error' => 'فشل إنشاء التصنيف، فضلاً حاول مرة أخرى.',

View File

@@ -3,16 +3,16 @@ return array(
'does_not_exist' => 'الشركة غير موجودة.',
'assoc_users' => 'هذه الشركة مرتبطة حاليا مع نموذج ولا يمكن حذفها. رجاءً قم بتحديث النماذج بحيث لا تكون مرتبطة بهذه الشركة ثم حاول مرة اُخرى. ',
'create' => array(
'error' => 'لم يتم انشاء الشركة، رجاءً حاول مرة اُخرى.',
'error' => 'لم يتم انشاء الشركة، الرجاء المحاولة مرة اُخرى.',
'success' => 'تم إنشاء الشركة بنجاح.'
),
'update' => array(
'error' => 'لم يتم تحديث الشركة، رجاءً حاول مرة اُخرى',
'error' => 'لم يتم انشاء الشركة، الرجاء المحاولة مرة اُخرى',
'success' => 'تم تحديث الشركة بنجاح.'
),
'delete' => array(
'confirm' => 'هل أنت متأكد من رغبتك في حذف هذه الشركة؟',
'error' => 'حدثت مشكلة اثناء عملية حذف الشركة. رجاءً المحاولة مرة اُخرى.',
'error' => 'حدثت مشكلة اثناء عملية حذف الشركة. الرجاء المحاولة مرة اُخرى.',
'success' => 'تم حذف الشركة بنجاح.'
)
);

View File

@@ -16,7 +16,7 @@ return array(
'delete' => array(
'confirm' => 'هل أنت متأكد من رغبتك في حذف هذا المكون؟',
'error' => 'حدثت مشكلة اثناء عملية حذف المكون. رجاءً المحاولة مرة اُخرى.',
'error' => 'حدثت مشكلة اثناء عملية حذف المكون. الرجاء المحاولة مرة اُخرى.',
'success' => 'تم حذف المكون بنجاح.'
),

View File

@@ -7,7 +7,7 @@ return array(
'cost' => 'تكلفة الشراء',
'create' => 'إنشاء مادة إستهلاكية',
'date' => 'تاريخ الشراء',
'item_no' => 'Item No.',
'item_no' => 'رقم القطعة.',
'order' => 'رقم طلب الشراء',
'remaining' => 'المتبقية',
'total' => 'المجموع',

View File

@@ -2,34 +2,34 @@
return array(
'does_not_exist' => 'Consumable does not exist.',
'does_not_exist' => 'المادة الإستهلاكية غير موجودة.',
'create' => array(
'error' => 'Consumable was not created, please try again.',
'success' => 'Consumable created successfully.'
'error' => 'لم يتم انشاء المادة الإستهلاكية، الرجاء المحاولة مرة اخرى.',
'success' => 'تم إنشاء المادة الإستهلاكية بنجاح.'
),
'update' => array(
'error' => 'Consumable was not updated, please try again',
'success' => 'Consumable updated successfully.'
'error' => 'لم يتم تحديث المادة الإستهلاكية، الرجاء المحاولة مرة اخرى',
'success' => 'تم تحديث المادة الإستهلاكية بنجاح.'
),
'delete' => array(
'confirm' => 'Are you sure you wish to delete this consumable?',
'error' => 'There was an issue deleting the consumable. Please try again.',
'success' => 'The consumable was deleted successfully.'
'confirm' => 'هل أنت متأكد من رغبتك في حذف هذه المادة الإستهلاكية؟',
'error' => 'لقد حدثت مشكلة لعملية حذف المادة الإستهلاكية، الرجاء المحاولة مرة اخرى.',
'success' => 'تم حذف المادة الإستهلاكية بنجاح.'
),
'checkout' => array(
'error' => 'Consumable was not checked out, please try again',
'success' => 'Consumable checked out successfully.',
'user_does_not_exist' => 'That user is invalid. Please try again.'
'error' => 'لم يتم إخراج المادة الإستهلاكية، الرجاء المحاولة مرة اخرى',
'success' => 'تم إخراج المادة الإستهلاكية بنجاح.',
'user_does_not_exist' => 'هذا المستخدم غير صحيح. الرجاء المحاولة مرة أخرى.'
),
'checkin' => array(
'error' => 'Consumable was not checked in, please try again',
'success' => 'Consumable checked in successfully.',
'user_does_not_exist' => 'That user is invalid. Please try again.'
'error' => 'لم يتم إيداع المادة الإستهلاكية، الرجاء المحاولة مرة اخرى',
'success' => 'تم إخراج المادة الإستهلاكية بنجاح.',
'user_does_not_exist' => 'هذا المستخدم غير صحيح. الرجاء المحاولة مرة أخرى.'
)

View File

@@ -1,5 +1,5 @@
<?php
return array(
'title' => 'Consumable Name',
'title' => 'إسم المادة الإستهلاكية',
);

View File

@@ -1,23 +1,28 @@
<?php
return array(
'custom_fields' => 'Custom Fields',
'field' => 'Field',
'about_fieldsets_title' => 'About Fieldsets',
'about_fieldsets_text' => 'Fieldsets allow you to create groups of custom fields that are frequently re-used used for specific asset model types.',
'fieldset' => 'Fieldset',
'qty_fields' => 'Qty Fields',
'fieldsets' => 'Fieldsets',
'fieldset_name' => 'Fieldset Name',
'field_name' => 'Field Name',
'field_element' => 'Form Element',
'field_element_short' => 'Element',
'field_format' => 'Format',
'field_custom_format' => 'Custom Format',
'required' => 'Required',
'req' => 'Req.',
'used_by_models' => 'Used By Models',
'custom_fields' => 'حقول مخصصة',
'field' => 'حقل',
'about_fieldsets_title' => 'حول مجموعة الحقول',
'about_fieldsets_text' => 'مجموعات-الحقول تسمح لك بإنشاء مجموعات من الحقول اللتي يمكن إعادة إستخدامها مع أنواع موديل محدد.',
'custom_format' => 'Custom format...',
'encrypt_field' => 'Encrypt the value of this field in the database',
'encrypt_field_help' => 'WARNING: Encrypting a field makes it unsearchable.',
'fieldset' => 'مجموعة-حقول',
'qty_fields' => 'الحقول الكمية',
'fieldsets' => 'مجموعات-الحقول',
'fieldset_name' => 'إسم مجموعة-الحقل',
'field_name' => 'إسم الحقل',
'field_values' => 'Field Values',
'field_values_help' => 'Add selectable options, one per line. Blank lines other than the first line will be ignored.',
'field_element' => 'عنصر النموذج',
'field_element_short' => 'عنصر',
'field_format' => 'صيغة',
'field_custom_format' => 'صيغة مخصصة',
'required' => 'مطلوب',
'req' => 'مطلوب',
'used_by_models' => 'مستخدم في الموديلات',
'order' => 'Order',
'create_fieldset' => 'New Fieldset',
'create_field' => 'New Custom Field',
'create_fieldset' => 'مجموعة-حقول جديدة',
'create_field' => 'حقل جديد مخصص',
);

View File

@@ -3,25 +3,25 @@
return array(
'field' => array(
'invalid' => 'That field does not exist.',
'already_added' => 'Field already added',
'invalid' => 'هذا الحقل غير موجود.',
'already_added' => 'تم إضافة الحقل سابقا',
'create' => array(
'error' => 'Field was not created, please try again.',
'success' => 'Field created successfully.',
'assoc_success' => 'Field successfully added to fieldset.'
'error' => 'لم يتم إنشاء الحقل، الرجاء المحاولة مرة اخرى.',
'success' => 'تم إنشاء الحقل بنجاح.',
'assoc_success' => 'تم اضافة الحقل الى مجموعة-الحقول بنجاح.'
),
'update' => array(
'error' => 'Field was not updated, please try again',
'success' => 'Field updated successfully.'
'error' => 'لم يتم تحديث الحقل، الرجاء المحاولة مرة اخرى',
'success' => 'تم تحديث الحقل بنجاح.'
),
'delete' => array(
'confirm' => 'Are you sure you wish to delete this field?',
'error' => 'There was an issue deleting the field. Please try again.',
'success' => 'The field was deleted successfully.',
'in_use' => 'Field is still in use.',
'confirm' => 'هل أنت متأكد من رغبتك في حذف هذا الحقل؟',
'error' => 'لقد حدثت مشكلة أثناء عملية حذف الحقل، الرجاء المحاولة مرة اخرى.',
'success' => 'تم حذف الحقل بنجاح.',
'in_use' => 'لا يزال الحقل قيد الإستخدام.',
)
),
@@ -31,20 +31,20 @@ return array(
'create' => array(
'error' => 'Fieldset was not created, please try again.',
'success' => 'Fieldset created successfully.'
'error' => 'لم يتم إنشاء مجموعة-الحقول، الرجاء المحاولة مرة اخرى.',
'success' => 'تم إنشاء مجموعة-الحقول بنجاح.'
),
'update' => array(
'error' => 'Fieldset was not updated, please try again',
'success' => 'Fieldset updated successfully.'
'error' => 'لم يتم تحديث مجموعة-الحقول، الرجاء المحاولة مرة اخرى',
'success' => 'تم تحديث مجموعة-الحقول بنجاح.'
),
'delete' => array(
'confirm' => 'Are you sure you wish to delete this fieldset?',
'error' => 'There was an issue deleting the fieldset. Please try again.',
'success' => 'The fieldset was deleted successfully.',
'in_use' => 'Fieldset is still in use.',
'confirm' => 'هل أنت متأكد من رغبتك في حذف مجموعة-الحقول هذه؟',
'error' => 'لقد حدثت مشكلة أثناء عملية حذف مجموعة-الحقول هذه، الرجاء المحاولة مرة اخرى.',
'success' => 'تم حذف مجموعة-الحقول بنجاح.',
'in_use' => 'لا تزال مجموعة-الحقول هذه قيد الإستخدام.',
)
),

View File

@@ -2,24 +2,24 @@
return array(
'does_not_exist' => 'Depreciation class does not exist.',
'assoc_users' => 'This depreciation is currently associated with one or more models and cannot be deleted. Please delete the models, and then try deleting again. ',
'does_not_exist' => 'فئة الإستهلاك غير موجود.',
'assoc_users' => 'لا يزال سند هذا الإستهلاك مرتبط مع أحد الموديلات ولا يمكن حذفه، الرجاء حذف الموديلات، وثم حاول حذف سند الإستهلاك مرة اخرى. ',
'create' => array(
'error' => 'Depreciation class was not created, please try again. :(',
'success' => 'Depreciation class created successfully. :)'
'error' => 'لم يتم إنشاء فئة الإستهلاك، الرجاء المحاولة مرة اخرى',
'success' => 'تم إنشاء فئة الإستهلاك بنجاح.'
),
'update' => array(
'error' => 'Depreciation class was not updated, please try again',
'success' => 'Depreciation class updated successfully.'
'error' => 'لم يتم تحديث فئة الإستهلاك، الرجاء المحاولة مرة اخرى',
'success' => 'تم تحديث فئة الإستهلاك بنجاح.'
),
'delete' => array(
'confirm' => 'Are you sure you wish to delete this depreciation class?',
'error' => 'There was an issue deleting the depreciation class. Please try again.',
'success' => 'The depreciation class was deleted successfully.'
'confirm' => 'هل أنت متأكد من رغبتك في حذف فئة الإستهلاك هذه؟',
'error' => 'لقد حدثت مشكلة أثناء عملية حذف فئة الإستهلاك، الرجاء المحاولة مرة اخرى.',
'success' => 'تم إنشاء فئة الإستهلاك بنجاح.'
)
);

View File

@@ -1,7 +1,7 @@
<?php
return array(
'bulk_delete' => 'Confrm Bulk Delete Assets',
'bulk_delete' => 'إجراء حذف متعدد للاُصول',
'bulk_delete_help' => 'Review the assets for bulk deletion below. Once deleted, these assets can be restored, but they will no longer be associated with any users they are currently assigned to.',
'bulk_delete_warn' => 'You are about to delete :asset_count assets.',
'bulk_update' => 'Bulk Update Assets',

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