Compare commits

...

505 Commits

Author SHA1 Message Date
snipe d9a1dab827 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2023-10-06 20:17:59 +01:00
snipe 5277f7cc5c Dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-10-06 20:14:44 +01:00
snipe 25a5507d9d Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2023-10-06 20:07:35 +01:00
snipe a95fae0e94 Merge remote-tracking branch 'origin/develop' 2023-10-06 20:00:12 +01:00
snipe 890efb18d8 Merge pull request #13720 from snipe/security/huntr_dev_d6ed5ac1-2ad6-45fd-9492-979820bf60c8
Fixed missing escaping asset history old/new values
2023-10-06 19:59:42 +01:00
snipe eea2eabaee Escaping asset history old/new values
Signed-off-by: snipe <snipe@snipe.net>
2023-10-06 19:45:23 +01:00
snipe 9596826259 Merge branch 'master' of https://github.com/snipe/snipe-it 2023-10-06 19:04:44 +01:00
snipe cd3b4754e8 Merge pull request #13704 from Godmartinz/feature/sc-23571_v2
Added a check-in button on components tab of Asset view
2023-10-05 14:28:37 +01:00
snipe 1dab4b59e9 Merge pull request #13693 from Godmartinz/bug/sc-9955
added proper margin-top to sidebar menu on bigger resolutions
2023-10-05 14:27:25 +01:00
snipe 05dd2b4008 Merge pull request #13709 from spencerrlongg/eol-migration
Speed up EOL Migration
2023-10-05 14:26:47 +01:00
snipe b809625856 Merge pull request #13713 from snipe/security/13685
[Snyk] Security upgrade css-loader from 4.3.0 to 5.0.0 #13685
2023-10-05 14:13:35 +01:00
snipe 8d921359ca [Snyk] Security upgrade css-loader from 4.3.0 to 5.0.0 #13685
Signed-off-by: snipe <snipe@snipe.net>
2023-10-05 14:12:36 +01:00
spencerrlongg c07c0c0f74 cleanup 2023-10-04 16:55:35 -05:00
spencerrlongg cc82e86eeb one more check 2023-10-04 16:54:56 -05:00
spencerrlongg 8c9961aba8 refactor 2023-10-04 15:40:42 -05:00
spencerrlongg 46af40bd02 ????? 2023-10-04 15:20:16 -05:00
spencerrlongg 6cda9056b8 oops 2023-10-04 14:56:18 -05:00
spencerrlongg 101bd9c404 kill transaction, try update array 2023-10-04 14:47:14 -05:00
spencerrlongg ad6b502005 comments 2023-10-04 14:37:18 -05:00
spencerrlongg cb10c7af27 oops 2023-10-04 14:33:35 -05:00
spencerrlongg 99d409c0a5 transaction 2023-10-04 14:32:28 -05:00
Godfrey M 37c1d6fc04 removed unnecessary changes 2023-10-03 12:45:13 -07:00
Godfrey M c69958d95d removed dead space 2023-10-03 12:32:24 -07:00
Godfrey M 92776adb93 remove unnecessary changes 2023-10-03 12:31:58 -07:00
Godfrey M dee36fc294 adds component checkin to asset tab 2023-10-03 12:30:08 -07:00
snipe a2773aa895 Merge pull request #13696 from marcusmoore/bug/sc-23796
Fixed potential call to a member function toArray() on null
2023-10-03 11:01:40 +01:00
Marcus Moore e82fec2a5f Grammar fix 2023-10-02 16:19:20 -07:00
Marcus Moore db4c86a4f4 Filter null field options before attempting to process them 2023-10-02 16:14:20 -07:00
snipe 8384786e8b Merge pull request #13695 from marcusmoore/bug/sc-23795-to-master
Log non-compliant barcode error as debug message
2023-10-02 22:22:26 +01:00
Marcus Moore a5fd218c23 Log non-compliant barcode error as debug message 2023-10-02 14:19:52 -07:00
snipe d2435c6f86 Merge remote-tracking branch 'origin/develop' 2023-10-02 22:14:08 +01:00
snipe 1abcc8b802 Merge pull request #13694 from marcusmoore/bug/sc-23795
Logs non-compliant barcode error as debug message
2023-10-02 22:13:19 +01:00
Marcus Moore 724c054838 Log non-compliant barcode error as debug message 2023-10-02 12:06:24 -07:00
Godfrey M 1e8f90bcf0 gives proper margin-top to sidebar menu on bigger resolutions 2023-10-02 11:46:08 -07:00
snipe 129e9b90dc Merge pull request #13585 from spencerrlongg/eol_2
Standardize Asset EOL Date
2023-10-02 16:09:22 +01:00
snipe 4e6764428e Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2023-10-02 14:29:59 +01:00
snipe c7b8880d69 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2023-10-02 14:28:59 +01:00
snipe 228f21ed91 Merge pull request #13690 from snipe/localization/all
Updated language strings
2023-10-02 14:24:52 +01:00
snipe b7c390a257 Updated language strings
Signed-off-by: snipe <snipe@snipe.net>
2023-10-02 14:23:22 +01:00
snipe c45ede2d17 Merge remote-tracking branch 'origin/develop' 2023-09-29 19:00:27 +01:00
snipe 758d808772 Merge pull request #13683 from snipe/bug/sc-17602
Fixed consumable user view route name
2023-09-29 15:17:23 +01:00
snipe 754ec7563a Fixed consumable user view route name
Signed-off-by: snipe <snipe@snipe.net>
2023-09-29 15:15:03 +01:00
snipe 352e53a036 Merge remote-tracking branch 'origin/develop' 2023-09-29 01:51:40 +01:00
snipe 0184d25a95 Merge pull request #13681 from marcusmoore/bug/sc-23778
Fixed uncaught type error when attempting to render barcodes with invalid characters
2023-09-29 01:50:07 +01:00
Marcus Moore bed1055c4e Catch TypeError when rendering 1d barcode 2023-09-28 17:32:16 -07:00
Marcus Moore 41eccaeae0 Set dummy asset tag to value that is valid for EAN13 2023-09-28 17:31:45 -07:00
snipe c1f545a523 Merge pull request #13679 from Godmartinz/bug/sc-23688
Fixed General Webhooks error messaging and validation
2023-09-28 20:24:09 +01:00
Godfrey M 8792d654b6 added translations for messages 2023-09-28 12:15:17 -07:00
Godfrey M f8730adb11 removed unnecessary changes 2023-09-28 11:41:43 -07:00
Godfrey M c21586dee5 adds better error messaging 2023-09-28 11:29:46 -07:00
snipe 581e56198c Merge remote-tracking branch 'origin/develop' 2023-09-28 19:24:48 +01:00
snipe f16e81e0e8 Merge pull request #13678 from spencerrlongg/bug/sc-23596
Fieldset Properly Sortable in Asset Models Table
2023-09-28 19:24:04 +01:00
snipe 3de656f5c6 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/js/build/app.js
#	public/js/dist/all.js
#	public/mix-manifest.json
2023-09-28 19:20:27 +01:00
snipe 3b4004ac18 Merge pull request #13677 from snipe/feature/sc-14880
Set modal focus to modal-name field
2023-09-28 19:18:16 +01:00
snipe 0bf423cda9 Set modal focus to modal-name field
Signed-off-by: snipe <snipe@snipe.net>
2023-09-28 19:16:40 +01:00
spencerrlongg a54fab5c33 add fieldset to allowed_columns 2023-09-28 13:02:12 -05:00
snipe 96c6c93197 Merge pull request #13674 from snipe/bug/sc-23774
Fixed bug where license checkout/checkin notes were not being saved
2023-09-28 18:37:47 +01:00
spencerrlongg 4d67c72eea scope and switch case in api 2023-09-28 12:26:23 -05:00
snipe 6fa0d42bc2 Fixed bug where license checkout/checkin notes were not being saved
Signed-off-by: snipe <snipe@snipe.net>
2023-09-28 15:40:18 +01:00
snipe cfe6b07b3a Updated prod assets
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/all.css
#	public/css/dist/bootstrap-table.css
#	public/js/build/vendor.js
#	public/js/dist/all.js
#	public/mix-manifest.json
2023-09-28 15:15:50 +01:00
snipe 7512400b56 Merge pull request #13672 from snipe/feature/sc-23772
Fixed #13662 - added clipboard.js
2023-09-28 15:13:42 +01:00
snipe 1acb14a39f Moved dragtable css
Signed-off-by: snipe <snipe@snipe.net>
2023-09-28 15:12:44 +01:00
snipe bb7a41628a Fixed #13662 - added clipboard.js
Signed-off-by: snipe <snipe@snipe.net>
2023-09-28 15:06:55 +01:00
snipe 68c9fac971 Merge remote-tracking branch 'origin/develop' 2023-09-28 14:25:31 +01:00
snipe 402ff58628 Merge pull request #13671 from snipe/bug/sc-23773
Fixed #13670 - order number missing from license import
2023-09-28 14:24:49 +01:00
snipe 492fb15036 Fixed #13670 - order number missing from license import
Signed-off-by: snipe <snipe@snipe.net>
2023-09-28 14:24:07 +01:00
snipe ac7f85fea9 Merge remote-tracking branch 'origin/develop' 2023-09-28 03:32:57 +01:00
snipe cc4cb14e9d Merge pull request #13667 from snipe/bug/sc-23771
Fixed #13658 for asset history with encrypted fields
2023-09-28 03:29:06 +01:00
snipe ee72c92d4f Fix for asset history with enfrypted fields
Signed-off-by: snipe <snipe@snipe.net>
2023-09-28 03:00:49 +01:00
snipe 3aeea007b2 Merge remote-tracking branch 'origin/develop' 2023-09-26 15:26:21 +01:00
snipe 048ad57418 Merge pull request #13657 from snipe/fixes/revert_column_sorting_temp
Commented out sortable columns
2023-09-26 15:25:58 +01:00
snipe 7bcb28d8fd Commented out sortable columns
Signed-off-by: snipe <snipe@snipe.net>
2023-09-26 15:24:20 +01:00
snipe 660abeca9e Merge pull request #13638 from marcusmoore/bug/sc-20704
Fixed exception being thrown when selected import was deleted
2023-09-26 15:00:35 +01:00
snipe 0c31d5749c Merge remote-tracking branch 'origin/develop' 2023-09-26 14:47:25 +01:00
snipe 1509339b68 Merge pull request #13655 from snipe/bug/sc-23759
Fixed bug where checkout to location would throw an error if FMCS was enabled
2023-09-26 14:37:36 +01:00
snipe 81ae32d3f9 Fixed typo
Signed-off-by: snipe <snipe@snipe.net>
2023-09-26 14:33:51 +01:00
snipe 279e6c7e4f Check for null company ID
Signed-off-by: snipe <snipe@snipe.net>
2023-09-26 14:33:42 +01:00
snipe 16498fdcf8 Merge remote-tracking branch 'origin/develop' 2023-09-25 13:46:33 +01:00
snipe 81a982fd77 Merge pull request #13650 from snipe/features/more_info_in_settings
Features/more info in settings
2023-09-25 13:46:00 +01:00
snipe 619712b927 Fixed table
Signed-off-by: snipe <snipe@snipe.net>
2023-09-25 13:45:46 +01:00
snipe 359cd2a267 A few more config options
Signed-off-by: snipe <snipe@snipe.net>
2023-09-25 13:28:13 +01:00
snipe 13bee63fe9 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2023-09-25 10:59:09 +01:00
snipe f6317695f9 Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2023-09-25 10:58:14 +01:00
snipe e4696138ba Merge pull request #13647 from snipe/localization/new_translations
Localization/new translations
2023-09-25 10:57:02 +01:00
snipe bd0863d9c7 Added new translations
Signed-off-by: snipe <snipe@snipe.net>
2023-09-25 10:54:46 +01:00
snipe 28cd0085b7 Added Khmer as an available language
Signed-off-by: snipe <snipe@snipe.net>
2023-09-25 10:54:32 +01:00
snipe 456d55c3bd Added some mail settings to /settings for easier reference
Signed-off-by: snipe <snipe@snipe.net>
2023-09-21 16:14:47 +01:00
Marcus Moore 5a88a64ebd Remove unnecessary redirect 2023-09-20 17:35:34 -07:00
Marcus Moore b1199100a0 Display error message if import file deleted before it can be selected 2023-09-20 17:22:12 -07:00
Godfrey M b7901ae2d8 dont allow redirects, messaging applied, general webhook validation applied 2023-09-20 12:54:34 -07:00
spencerrlongg 4660a2e5b7 rm more duplicate 2023-09-20 14:37:32 -05:00
spencerrlongg a9123754f5 remove unnecessary code 2023-09-20 14:34:42 -05:00
spencerrlongg cbef531811 parse purchase date even though it's cast 2023-09-20 14:26:49 -05:00
spencerrlongg 7dab59c98d fix for no eol, fix for optional in view 2023-09-20 14:17:30 -05:00
spencerrlongg c48a47936c add validation back in 2023-09-20 14:00:59 -05:00
snipe 7c908fecd9 Merge pull request #12992 from spencerrlongg/features/12853
Adds tag for docker builds
2023-09-20 19:36:22 +01:00
snipe cdd0de15b5 Merge pull request #13634 from marcusmoore/chore/add-factories-to-autolabeler
Added factories to autolabeler action
2023-09-20 17:51:34 +01:00
snipe 46981da400 Merge pull request #13635 from marcusmoore/bug/sc-23715
Added unique() to some factory properties
2023-09-20 17:51:22 +01:00
Godfrey M 66abf8d5c0 redoing logic 2023-09-19 17:46:29 -07:00
spencerrlongg 2ace24b176 csv header 2023-09-19 19:38:59 -05:00
spencerrlongg d65d1930e4 asset models 2023-09-19 19:24:53 -05:00
Marcus Moore 90e75a3e2c Add unique() to some factory properties 2023-09-19 17:02:18 -07:00
spencerrlongg 2d59517c35 rm !empty 2023-09-19 18:40:23 -05:00
spencerrlongg 3cb906a05f pushing to switch branches and test 2023-09-19 18:23:06 -05:00
Marcus Moore cd538a4ad8 Add factories to autolabeler action 2023-09-19 16:07:26 -07:00
spencerrlongg 6b4f8f1813 rm duplicate fillable 2023-09-19 18:07:15 -05:00
spencerrlongg 929e107a20 rm byod from casts 2023-09-19 18:04:16 -05:00
snipe 5a5b07f5a5 Merge remote-tracking branch 'origin/develop' 2023-09-19 10:22:59 +01:00
snipe 439c2e095d Merge pull request #13629 from snipe/bug/sc-23745
Fixed #13628 - removed duplicate favicon tag
2023-09-19 10:22:36 +01:00
snipe 14c0517927 Fixed #13628 - removed duplicate favicon tag
Signed-off-by: snipe <snipe@snipe.net>
2023-09-19 10:21:38 +01:00
snipe d84d26febf Merge remote-tracking branch 'origin/develop' 2023-09-18 22:31:41 +01:00
snipe 753a5f789e Merge pull request #13623 from snipe/fixes/dependabot_target
Made develop the target branch for dependabot
2023-09-18 22:31:11 +01:00
snipe d7790cd16b Updated assets
Signed-off-by: snipe <snipe@snipe.net>
2023-09-18 22:24:15 +01:00
snipe 8ecc0651ed Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/all.css
#	public/css/dist/bootstrap-table.css
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2023-09-18 22:23:58 +01:00
snipe a8b2089275 Merge pull request #13627 from snipe/fixes/dependabot_13616
Replaces #13616 - Bump docker/metadata-action from 4 to 5
2023-09-18 22:20:06 +01:00
snipe a46a11d554 Replaces #13616 - Bump docker/metadata-action from 4 to 5
Signed-off-by: snipe <snipe@snipe.net>
2023-09-18 22:19:31 +01:00
snipe d444b620c5 Merge pull request #13626 from snipe/fixes/dependabot_13617
Replaces #13617 - Bump docker/setup-buildx-action from 2 to 3
2023-09-18 22:18:04 +01:00
snipe 10dcd8166b Replaces #13617 - Bump docker/setup-buildx-action from 2 to 3
Signed-off-by: snipe <snipe@snipe.net>
2023-09-18 22:17:24 +01:00
snipe 00df449e0b Merge pull request #13625 from snipe/fixes/dependabot_13618
Replaces #13618 - Bump docker/build-push-action from 4 to 5
2023-09-18 22:16:08 +01:00
snipe 0cb4427a19 Bump docker/build-push-action from 4 to 5
Signed-off-by: snipe <snipe@snipe.net>
2023-09-18 22:15:18 +01:00
snipe 17fe915d2f Merge pull request #13624 from snipe/fixes/dependabot_13619
Bump docker/login-action from 2 to 3 (#13619)
2023-09-18 22:14:01 +01:00
snipe 9ad73ed09a Bump docker/login-action from 2 to 3 (#13619)
Signed-off-by: snipe <snipe@snipe.net>
2023-09-18 22:13:09 +01:00
snipe 68fa6d57ca Merge pull request #13613 from snipe/features/reorder_columns
Added column re-ordering
2023-09-18 22:10:09 +01:00
snipe f14e3422b4 Made develop the target branch
Signed-off-by: snipe <snipe@snipe.net>
2023-09-18 22:09:43 +01:00
snipe 2a638e66f0 Added column re-ordering
Signed-off-by: snipe <snipe@snipe.net>
2023-09-15 21:53:34 +01:00
snipe 8bdecb1da9 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/js/build/app.js
#	public/js/dist/all.js
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2023-09-15 20:32:05 +01:00
snipe 52f9c786be Merge pull request #13612 from snipe/fixes/re_add_sticky_header
Fixed regression that disabled sticky headers
2023-09-15 20:29:24 +01:00
snipe 3ba8b60f54 Fixed regression that disabled sticky headers
Signed-off-by: snipe <snipe@snipe.net>
2023-09-15 20:28:28 +01:00
snipe 341f711385 Merge remote-tracking branch 'origin/develop' 2023-09-15 15:43:48 +01:00
snipe eb406547c4 Merge pull request #13610 from snipe/fixes/disallow_sorting_on_age
Fixes #13609 - disallow sorting on age
2023-09-15 15:26:55 +01:00
snipe 0b562d2f55 Fixes #13609 - disallow sorting on age
Signed-off-by: snipe <snipe@snipe.net>
2023-09-15 15:25:52 +01:00
snipe 131ccaa5b9 Merge pull request #12869 from Godmartinz/bug/sc-23134
Fixed footer sizing issue
2023-09-15 14:31:07 +01:00
snipe 9bd357e2d4 Merge remote-tracking branch 'origin/develop' 2023-09-15 12:52:59 +01:00
snipe 054d8763fb Merge pull request #13608 from snipe/bug/sc-15287
Use relative path in backups for cleaner directory structure
2023-09-15 12:51:49 +01:00
snipe 52a77f4c31 Use relative path in backups for cleaner directory structure
Signed-off-by: snipe <snipe@snipe.net>
2023-09-15 12:50:00 +01:00
snipe cce90c6ce0 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2023-09-15 09:43:25 +01:00
snipe 4e0e1a2c85 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2023-09-15 09:42:27 +01:00
snipe 8a8afef81b Merge pull request #13606 from snipe/feature/sc-23705
Fixed #13592 - unable to delete model from view page
2023-09-15 01:11:49 +01:00
snipe 860e7791ff Fixed #13592 - unable to delete model from view page
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 23:35:44 +01:00
snipe 20da6cccbc Merge remote-tracking branch 'origin/develop' 2023-09-14 22:57:04 +01:00
snipe a013ddf541 Merge pull request #13605 from snipe/bug/sc-23183
Simplify upload messaging, handle -1% error
2023-09-14 22:52:31 +01:00
spencerrlongg 1cfd7673e0 change Importer.php back 2023-09-14 16:11:24 -05:00
snipe bbe7d9dde2 Removed stray space
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 22:08:53 +01:00
snipe 932c02cc54 Typo
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 22:08:30 +01:00
snipe 84b0ff76ed Revert large warning size
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 22:06:19 +01:00
snipe 273740b8f5 Fixed import error warning
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 22:04:23 +01:00
spencerrlongg afe9d43139 chunk by id? 2023-09-14 16:00:35 -05:00
snipe 34c3174531 Merge pull request #13604 from marcusmoore/feature/sc-23714
Removed ChipperCI integration
2023-09-14 21:48:49 +01:00
spencerrlongg aac627592b move logic inside of try 2023-09-14 15:43:00 -05:00
spencerrlongg f35f9f922e safety & catch & log 2023-09-14 15:32:17 -05:00
snipe 8f4ca9da57 Simplify upload messaging
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 21:20:21 +01:00
Marcus Moore b113411891 Remove ChipperCI 2023-09-14 13:00:38 -07:00
spencerrlongg 44441ec703 up chunk size 2023-09-14 14:25:02 -05:00
snipe 15c71439b6 Merge pull request #13602 from snipe/bug/sc-23685
Fixed checkbox formatting on quickstart
2023-09-14 18:48:50 +01:00
snipe 8e41fb7b36 Removed stray text
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 18:48:20 +01:00
snipe d0c4910a51 Fixed checkbox formatting on quickstart
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 18:44:02 +01:00
snipe 467609e561 Merge remote-tracking branch 'origin/develop' 2023-09-14 14:32:06 +01:00
snipe 2166d6649d Merge pull request #13343 from snipe/fixes/re-scramble_password_if_ldap_pw_sync_not_enabled
Fixed #13336 - Save unhashed password if no password provided
2023-09-14 14:15:53 +01:00
snipe dcae5503c8 Use $attributes array
Signed-off-by: snipe <snipe@snipe.net>
2023-09-14 13:52:57 +01:00
snipe d916e20c10 Merge pull request #13415 from marcusmoore/feature/department-scoping
Added `CompanyableTrait` to `Department` model
2023-09-14 12:52:53 +01:00
snipe b92327eb40 Merge pull request #13520 from inietov/fixes/licenses_reassignable_feature
Fixed Not reassignable Licenses shouldn't show 'Checkin All Seats' button [sc-23506]
2023-09-14 12:52:13 +01:00
snipe c7b24821b3 Merge pull request #13549 from inietov/fixes/attempt_to_read_property_id_on_null
Fixed ErrorException: Attempt to read property "id" on null (rollbar #3541)
2023-09-14 12:50:54 +01:00
snipe a37df8ce9d Merge pull request #13581 from snipe/updates/upgrade_checkout_actions
Upgraded actions/checkout to v4 (via #13580)
2023-09-14 12:40:34 +01:00
snipe 104219ed76 Merge pull request #13597 from marcusmoore/bug/sc-23681
Reset checkout to value when navigating away from type
2023-09-14 12:39:04 +01:00
snipe 56c7da7b06 Merge pull request #13595 from Godmartinz/correct-nullable_on_asset_model_min_qty
Fixed nullability on asset model `min qty` column
2023-09-14 08:52:33 +01:00
spencerrlongg 7c9a4ac161 immutable 2023-09-13 18:15:13 -05:00
spencerrlongg 64a9859efd cleanup 2023-09-13 17:58:33 -05:00
spencerrlongg ef64843d2f chunk migration, needs to be tested 2023-09-13 17:41:45 -05:00
Ivan Nieto Vivanco 439e031911 Evaluate if the event properties exists before run the CheckoutAcceptance query 2023-09-13 16:35:10 -06:00
spencerrlongg 0368b9df43 viola 2023-09-13 17:16:17 -05:00
Marcus Moore 74c7f106ce Reset assigned_x values when changing check out to type 2023-09-13 13:43:35 -07:00
Godfrey M f283a5f755 changed the down method change 2023-09-13 13:24:26 -07:00
spencerrlongg 951521dc81 push 2023-09-13 15:20:55 -05:00
Godfrey M 0c504fed49 fixed nullability of on Asset Models 2023-09-13 13:13:41 -07:00
Marcus Moore 11208ee064 Guard against attempting to send notification to model that isn't notifiable 2023-09-13 12:56:27 -07:00
spencerrlongg 70a251de55 fix up gui edit 2023-09-13 13:51:14 -05:00
spencerrlongg e21a8b6717 fix up this file 2023-09-12 18:11:36 -05:00
spencerrlongg 7047869367 cleanup 2023-09-12 18:03:13 -05:00
spencerrlongg 53d4fd1d0b purchase_date 2023-09-12 18:01:33 -05:00
snipe f6a11ac0ed Merge pull request #13586 from inietov/fixes/call_to_member_function_checkedOutToUser
Fixed Call to a member function checkedOutToUser() on null [rollbar-3598]
2023-09-12 08:35:30 +01:00
Ivan Nieto Vivanco 9cbd2d032c Add a boolean variable and condition to handle the call to checkedOutToUser() method 2023-09-11 17:40:59 -06:00
spencerrlongg ccf3fe40ec rm additional row 2023-09-11 17:35:13 -05:00
spencerrlongg 3a63bcab73 temporarily show on its own line 2023-09-11 17:35:13 -05:00
spencerrlongg 30dade1fba cleanup 2023-09-11 17:35:12 -05:00
spencerrlongg 97d6a34b8c some changes to sample csv 2023-09-11 17:34:05 -05:00
spencerrlongg 431af5f530 this works!!!! 2023-09-11 17:34:05 -05:00
spencerrlongg 3e3bb594ea some import stuff 2023-09-11 17:34:04 -05:00
spencerrlongg fb001caee4 fix conflicts 2023-09-11 17:33:31 -05:00
spencerrlongg b73f20cadf immutable when things are looping, just in case 2023-09-11 17:22:46 -05:00
spencerrlongg 3fb62874f0 quick push to check something else 2023-09-11 17:22:46 -05:00
spencerrlongg c66804bcee a little cleanup 2023-09-11 17:22:46 -05:00
spencerrlongg e1af69f6ae typo 2023-09-11 17:22:46 -05:00
slong753 27bea2abb9 just some more wip on the importer 2023-09-11 17:21:51 -05:00
slong753 1b18cd7fe6 added asset_eol_date and explicit to factory 2023-09-11 17:21:51 -05:00
slong753 78c400e948 fix conflicts 2023-09-11 17:21:50 -05:00
slong753 75d7e3e1a0 fix conflicts 2023-09-11 17:20:21 -05:00
slong753 5948679a4a fix purchase date update 2023-09-11 17:17:59 -05:00
slong753 774f21bb7f some more cleanup 2023-09-11 17:17:59 -05:00
slong753 20367eecc9 fix conflicts 2023-09-11 17:17:59 -05:00
slong753 cda9dd57dd asset update logic 2023-09-11 17:15:25 -05:00
slong753 41b65bd9a2 small changes 2023-09-11 17:15:25 -05:00
slong753 17a83129b9 this all needs to be tested tediously 2023-09-11 17:15:25 -05:00
slong753 0e60184e95 i think this migration makes sense 2023-09-11 17:15:25 -05:00
slong753 1ea0de8bca prevent injection, fix asset update 2023-09-11 17:15:25 -05:00
slong753 17ccfa9ada resolve some conflicts 2023-09-11 17:15:24 -05:00
slong753 c1daabef08 progress 2023-09-11 17:10:41 -05:00
slong753 dc39d2c567 notes 2023-09-11 17:10:41 -05:00
slong753 321e7c93ec carbon thing 2023-09-11 16:51:40 -05:00
slong753 8456b3ec0c wip stuff 2023-09-11 16:51:40 -05:00
snipe a49d3fe131 Merge pull request #13526 from Godmartinz/asset-model-notifs
Added threshold notifications and min qty for Asset models
2023-09-11 17:55:34 +01:00
Godfrey Martinez a26b96185b Merge branch 'develop' into asset-model-notifs 2023-09-11 09:37:22 -07:00
Godfrey M 0eb50ceb3d removes commented code 2023-09-11 09:36:38 -07:00
snipe c2fe9d490b Upgraded actions/checkout to v4 (via #13580)
Signed-off-by: snipe <snipe@snipe.net>
2023-09-11 13:25:44 +01:00
snipe dc74fb133f Merge pull request #13577 from marcusmoore/fixes/improve-testcase
Fixed failing test
2023-09-08 07:08:21 +01:00
Marcus Moore 093bf57448 Update assertion and add failure messages 2023-09-07 16:42:49 -07:00
snipe 9c608dd6ff Merge remote-tracking branch 'origin/develop' 2023-09-07 21:36:39 +01:00
snipe 06836663c8 Merge pull request #13575 from marcusmoore/fixes/improve-api-messaging
Added validation around department_id in API patch request
2023-09-07 21:36:20 +01:00
Marcus Moore c6c1c64c1e Remove todo 2023-09-07 13:30:05 -07:00
Marcus Moore 4caa501996 Relax property type check 2023-09-07 13:28:32 -07:00
Marcus Moore a7a70f6981 Test permissions update 2023-09-07 13:21:27 -07:00
Marcus Moore 39ff575ac1 Remove unused test cases 2023-09-07 13:16:08 -07:00
snipe 5b88089ffc Merge remote-tracking branch 'origin/develop' 2023-09-07 20:50:35 +01:00
snipe 02c187b0a0 Merge pull request #13566 from snipe/features/13562_add_inline_file_link
Fixed #13562 - Added inline file link
2023-09-07 20:50:13 +01:00
snipe 7f892bf5ef Merge pull request #13574 from inietov/fixes/unaccepted_assets_report_incorrect
Fixed Unaccepted Assets report has incorrect people [freshdesk-37808]
2023-09-07 20:49:40 +01:00
Marcus Moore 56e6205667 Formatting 2023-09-07 12:45:03 -07:00
Ivan Nieto Vivanco abd2ed3b81 Filter unaccepted assets that are not assigned to users 2023-09-07 13:39:16 -06:00
Marcus Moore 899c2eb19b Implement test case 2023-09-07 12:34:50 -07:00
snipe cf36c31eac Merge remote-tracking branch 'origin/develop' 2023-09-07 20:22:33 +01:00
snipe 894c34ff4f Update to only use relative paths
Signed-off-by: snipe <snipe@snipe.net>
2023-09-07 20:22:14 +01:00
snipe b7c2b9374c Merge pull request #13573 from snipe/upgrade_scim_server
Upgrade to new branch for our fork of laravel-scim-server
2023-09-07 20:07:59 +01:00
Brady Wetherington 3184f795c2 Upgrade to new branch for our fork of laravel-scim-server 2023-09-07 18:29:23 +01:00
snipe 67cad9c751 Merge pull request #13571 from inietov/fixes/require_acceptance_on_null
Fixed Attempt to read property require_acceptance on null [rollbar-3557]
2023-09-07 18:11:42 +01:00
snipe ec5238ff06 Merge pull request #13548 from marcusmoore/update-testing-documentation
Updated testing documentation
2023-09-07 11:25:53 +01:00
Marcus Moore 1c3c36f2a0 Begin to implement patch test 2023-09-06 16:14:14 -07:00
Ivan Nieto Vivanco 1509c512a5 Add guard clauses around some License and LicenseSeat models functions 2023-09-06 11:54:11 -06:00
snipe 2a94fd17ee Merge remote-tracking branch 'origin/develop' 2023-09-06 09:37:35 +01:00
snipe e920199626 Merge pull request #13567 from johnson-yi/fixes/add_default_location_to_checkin_actionlog
Add default location to tracked changes on checkin actionlog
2023-09-06 09:37:04 +01:00
johnson-yi 5897f4d6d9 Add rtd_location_id to tracked changes on checkin actionlog 2023-09-06 00:36:48 +00:00
snipe a67888f3d3 Merge pull request #13547 from inietov/fixes/Attempt_to_read_property_asset_tag
Fixed ErrorException: Attempt to read property "asset_tag" on null (rollbar #3541)
2023-09-05 20:26:21 +01:00
Ivan Nieto Vivanco 91b1cc7121 Move the early return to the controller instead of the Label model 2023-09-05 13:23:51 -06:00
snipe d6dd332b09 Merge pull request #13557 from johnson-yi/fixes/add_changes_to_checkinout_actionlog
Added/Fixed: track changes on asset checkin/out
2023-09-05 19:08:49 +01:00
snipe 65a76c599c Added inline=true to image preview modal
Signed-off-by: snipe <snipe@snipe.net>
2023-09-05 18:35:07 +01:00
snipe f53db8ba75 Fixed #13562 - allow inline view for uploaded files
Signed-off-by: snipe <snipe@snipe.net>
2023-09-05 18:28:01 +01:00
snipe 32407b531b Merge remote-tracking branch 'origin/develop' 2023-09-05 16:10:30 +01:00
snipe e486fe2794 Removed soft-delete query
Signed-off-by: snipe <snipe@snipe.net>
2023-09-05 16:10:20 +01:00
snipe 521fcd45b0 Merge remote-tracking branch 'origin/develop' 2023-09-05 16:08:17 +01:00
snipe 26452a8a29 Merge pull request #13565 from snipe/fixes/asset_history_500_on_hard_deleted_models
Account for hard-deleted models, suppliers
2023-09-05 16:06:40 +01:00
snipe f85df6bb8c Use same method of accessing companies as others
Signed-off-by: snipe <snipe@snipe.net>
2023-09-05 16:02:28 +01:00
snipe 2acf2b880e Account for hard-deleted models, suppliers
Signed-off-by: snipe <snipe@snipe.net>
2023-09-05 15:58:21 +01:00
snipe b17af38d8e Merge pull request #12901 from Godmartinz/user_total_cost
Added users total cost of assets to user profile
2023-09-05 13:52:34 +01:00
snipe a62e2f092b Merge pull request #13498 from marcusmoore/feature/add-checkin-date-range-filter-to-custom-asset-report
Added last check in column and filter to custom asset report
2023-09-05 13:22:15 +01:00
Johnson Yi 09f7b3debe Track changes on asset checkin/out 2023-09-01 13:12:07 +10:00
Marcus Moore da7d6f6f77 Merge branch 'develop' into update-testing-documentation 2023-08-31 10:36:06 -07:00
snipe faa865fd48 Merge remote-tracking branch 'origin/develop' 2023-08-31 18:24:29 +01:00
snipe f08cef8664 Merge pull request #13556 from snipe/feature/sc-23684
Added model name and number to dynamic url
2023-08-31 18:23:33 +01:00
snipe e192cbbbe1 Merge pull request #13550 from marcusmoore/remove-dusk
Removed Dusk
2023-08-31 18:06:04 +01:00
snipe 83b178f5b2 Added model name and number to dynamic url
Signed-off-by: snipe <snipe@snipe.net>
2023-08-31 18:03:32 +01:00
snipe 2a1aa53ba6 Merge remote-tracking branch 'origin/develop' 2023-08-31 13:04:56 +01:00
snipe c51574099f Merge pull request #13507 from Godmartinz/ignore_encrypt_and_other_changes
Added eager loading for `changedinfo` and removed encrypted values from Asset history
2023-08-31 13:04:39 +01:00
snipe 821c3085f0 Merge remote-tracking branch 'origin/develop' 2023-08-31 12:01:58 +01:00
snipe 9a0f691f05 Merge pull request #13546 from snipe/fixes/make_boolean_user_fields_more_consistant
Don’t cast as boolean, do validate as boolean for User validation
2023-08-31 12:01:20 +01:00
Marcus Moore a799659610 Scaffold tests and add context 2023-08-30 17:33:23 -07:00
Marcus Moore 999605f832 Add failing test 2023-08-30 17:10:50 -07:00
Marcus Moore 5828d29952 Remove Dusk 2023-08-30 16:43:18 -07:00
Marcus Moore 417b2c8331 Update testing documentation 2023-08-30 11:27:26 -07:00
snipe 663faffcc1 Un-cast byod, validate as boolean
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 19:13:55 +01:00
snipe fb455be406 Added tests
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 19:13:38 +01:00
Ivan Nieto Vivanco 3cf9c1fea5 Adds a null coalescing operator to the license seat checkin notification 2023-08-30 11:57:29 -06:00
Ivan Nieto Vivanco 085a993340 Early return if no asset is found 2023-08-30 11:05:58 -06:00
Marcus Moore 07c3fe1fce Update assertions to account for type change 2023-08-30 09:42:53 -07:00
snipe 2a93c38830 Don’t cast as boolean, validate as boolean
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 16:40:28 +01:00
snipe 587a787b5d Fixed bug introduced in #13528
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 15:50:28 +01:00
snipe 305804f260 Updated assets
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
#	package-lock.json
#	public/css/dist/all.css
#	public/js/dist/all-defer.js
#	public/mix-manifest.json
2023-08-30 15:50:09 +01:00
snipe c0cbdb1fc4 Fixed bug introduced in #13528
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 15:48:35 +01:00
snipe 5cf8c36698 Updated assets
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 15:43:06 +01:00
snipe 1bcc74f156 Upgrade @fortawesome/fontawesome-free from 6.4.0 to 6.4.2 #13527
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 15:41:11 +01:00
snipe 9ebcde4472 Upgrade less from 4.1.2 to 4.2.0 #13534
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 15:40:56 +01:00
snipe fbc04cfd47 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2023-08-30 15:07:38 +01:00
snipe 319cb2305d Merge remote-tracking branch 'origin/develop' 2023-08-30 15:05:46 +01:00
snipe b109ee281a Merge pull request #13544 from marcusmoore/bug/sc-23675
Fixed user search not adhering to company scoping
2023-08-30 08:54:41 +01:00
Marcus Moore 806ab2cb9d Ensure users are scoped by company in index method 2023-08-29 16:17:29 -07:00
Marcus Moore aafa1ab70e Add failing test 2023-08-29 16:15:13 -07:00
snipe 22d136df46 Merge pull request #13528 from inietov/fixes/cloning_model_blanks_fieldset
Fixed #12548 Cloning a model blanks fieldset of new one
2023-08-29 19:14:38 +01:00
Godfrey Martinez 0ac5d4d582 Merge pull request #8 from Godmartinz/fix-companyable
Fix companyable
2023-08-28 19:38:27 -07:00
Godfrey Martinez d86c63cf23 Merge branch 'ignore_encrypt_and_other_changes' into fix-companyable 2023-08-28 19:38:16 -07:00
Godfrey M 74f45a4473 reworks company queries for asset history 2023-08-28 19:35:46 -07:00
Ivan Nieto Vivanco 4e4ba38038 Pass the model_id variable in the controller and get it only if we are cloning the asset model 2023-08-28 16:23:26 -06:00
snipe 18ff810d7e Reverse orderof parent
Signed-off-by: snipe <snipe@snipe.net>
2023-08-28 20:51:52 +01:00
snipe baffcbad71 Set password property properly
Signed-off-by: snipe <snipe@snipe.net>
2023-08-28 20:47:56 +01:00
snipe 611db4c0d2 Removed stray line
Signed-off-by: snipe <snipe@snipe.net>
2023-08-28 20:46:45 +01:00
snipe 367484a766 Merge pull request #13537 from snipe/fixes/13500_prevent_autocomplete_on_ldap_password
Fixed #13500 - Try to prevent the browser from pre-filling the LDAP password
2023-08-28 20:42:58 +01:00
snipe 0f43388a2b Merge remote-tracking branch 'origin/develop' 2023-08-28 20:40:12 +01:00
snipe 81365ef911 Merge pull request #13518 from marcusmoore/chore/tests-via-github-actions
Run tests for PHP 7.4, 8.0, and 8.1.1 via GitHub Actions
2023-08-28 20:28:42 +01:00
snipe 6020927e24 Merge pull request #13538 from snipe/fixes/13516_use_int_not_string_for_port_default
Fixed #13516 - Use int not string if no DB_PORT specified
2023-08-28 19:38:41 +01:00
snipe 82981290d4 Use int not string if no DB_PORT specified
Signed-off-by: snipe <snipe@snipe.net>
2023-08-28 19:34:08 +01:00
snipe 7787ca328c Try to prevent the browser from pre-filling the LDAP password
Signed-off-by: snipe <snipe@snipe.net>
2023-08-28 18:36:06 +01:00
Godfrey Martinez 92e88a0ae2 Merge branch 'develop' into ignore_encrypt_and_other_changes 2023-08-28 10:14:41 -07:00
snipe b93adf44c8 Merge remote-tracking branch 'origin/develop' 2023-08-28 12:41:45 +01:00
snipe 535ca0e3c0 Merge pull request #13535 from snipe/fixes/13521_make_modal_upload_button_wider
Fixed #13521 - make modal “select files” button wider
2023-08-28 12:41:27 +01:00
snipe 582cad2dc5 Fixed #13521 - make modal “select files” button wider
Signed-off-by: snipe <snipe@snipe.net>
2023-08-28 12:37:42 +01:00
snipe a1897298dc Merge remote-tracking branch 'origin/develop' 2023-08-27 13:56:54 +01:00
snipe e3a9c34818 Merge pull request #13533 from snipe/improvements/labels_clearer_barcode_text
Clearer labels barcode text
2023-08-26 18:08:10 +01:00
snipe 20e9f05a64 Tighter layout
Signed-off-by: snipe <snipe@snipe.net>
2023-08-26 17:43:02 +01:00
snipe 844fe0938c Added link to the help docs
Signed-off-by: snipe <snipe@snipe.net>
2023-08-26 17:42:56 +01:00
snipe 0a47706e46 Merge remote-tracking branch 'origin/develop' 2023-08-25 15:47:47 +01:00
Ivan Nieto Vivanco a12a68e4e9 Add a variable so I dont ended rewriting the original model 2023-08-24 15:28:12 -06:00
Ivan Nieto Vivanco 950536f59f Added a condition to send correct model id when cloning one 2023-08-24 15:18:51 -06:00
Godfrey M e56628499c fixed lost changes 2023-08-24 11:45:23 -07:00
Godfrey M 2b7a899ef8 removed unnecessary code 2023-08-24 11:43:44 -07:00
Godfrey M 0b956b2a46 revert changes of composer.lock 2023-08-24 10:45:59 -07:00
Godfrey M 18cb514a53 revert unwanted changes 2023-08-24 10:40:44 -07:00
Godfrey M a3b6e0fbe6 adds some spacing 2023-08-24 10:36:09 -07:00
Godfrey M 34ba0c4440 adds id to history info 2023-08-24 10:36:08 -07:00
Godfrey M 739fc152c2 Adds readable asset history in the action log transformer 2023-08-24 10:36:08 -07:00
Godfrey M 011c09a3dd working on getting notifications 2023-08-24 10:35:40 -07:00
Godfrey M 38d5691b88 fix conflicts 2023-08-24 10:35:40 -07:00
Godfrey M c26ef224f4 fixing my mess 2023-08-24 10:31:01 -07:00
Godfrey M 8ebb9afedd adds min_amt to asset model edit, index, and table 2023-08-24 10:30:07 -07:00
snipe 26dd992d3c Merge pull request #13525 from marcusmoore/bug/sc-23660
Fixed undeclared variable in ActionlogsTransformer
2023-08-24 17:09:30 +01:00
Marcus Moore e32c07be02 Clear commented log statements 2023-08-24 08:15:40 -07:00
Marcus Moore 5a0b0522b0 Explicitly declare $clean_meta variable 2023-08-24 08:15:07 -07:00
Marcus Moore 20457bd89e Run tests for PHP 7.4, 8.0, and 8.1.1 2023-08-23 15:53:34 -07:00
Ivan Nieto Vivanco 7bfb5a0667 Disable the Checkin All Seats button if License is not reassignable 2023-08-23 16:36:06 -06:00
Ivan Nieto Vivanco 6161a0d76d Add condition in LicenseCheckinController:bulkCheckin method to evaluate if the license is reassignable 2023-08-23 16:22:40 -06:00
Godfrey Martinez 28cf533d19 Merge branch 'develop' into ignore_encrypt_and_other_changes 2023-08-23 00:42:59 -07:00
Godfrey M 0fc79ec936 fixes conflicts 2023-08-23 00:40:59 -07:00
Godfrey M ffe1b11419 merged develop 2023-08-23 00:38:58 -07:00
Godfrey M 27488c1009 adds soft deletes to eager loading 2023-08-23 00:34:09 -07:00
Godfrey M ce60db009c adds soft deletes to eager loading 2023-08-23 00:32:43 -07:00
snipe 9f291d7e4b Merge remote-tracking branch 'origin/develop' 2023-08-23 08:21:53 +01:00
snipe d393bd5c97 Merge pull request #13511 from snipe/fixes/13510_no_translations_in_migrations
Fixed #13510 - do not use translations in migrations
2023-08-23 08:21:18 +01:00
snipe ea37325806 Remove trans() from default values
Signed-off-by: snipe <snipe@snipe.net>
2023-08-23 08:19:05 +01:00
snipe 31a7758ab1 Merge pull request #13509 from marcusmoore/bug/sc-23636
Fixed asset model query in action log transformer
2023-08-23 06:58:41 +01:00
Marcus Moore bee680683d Add withTrashed to asset model query 2023-08-22 17:05:06 -07:00
Godfrey M 92ddf8fc67 removed dead space 2023-08-22 12:38:50 -07:00
Godfrey M 1019287c76 retarget key 2023-08-22 12:36:43 -07:00
Godfrey M 9e438c3ed0 eager loaded changedInfo queries, reworked encrypted data change log changes 2023-08-22 12:34:45 -07:00
Godfrey M c7f2acf2c6 removes encrypted info from change log, renames asset_eol_date in the change log 2023-08-22 11:39:38 -07:00
snipe 79b330f492 Merge pull request #13400 from inietov/fixes/asset_acceptance_user_error
Fixed Asset acceptance error when user company and asset company don't match
2023-08-22 15:49:56 +01:00
snipe 3da21e73e2 Merge pull request #13501 from snipe/fixes/checkbox_layout_in_settings
Small fixes to checkbox layout in general settings blade
2023-08-22 14:12:15 +01:00
snipe da38945a53 Small fixes to checkbox layout in general settings blade
Signed-off-by: snipe <snipe@snipe.net>
2023-08-22 14:10:39 +01:00
snipe a48762c64d Merge pull request #13496 from snipe/features/setting_for_name_order
Fixed #13495 added setting for name order
2023-08-22 12:50:58 +01:00
snipe 23237e5cd3 Removed unused translation
Signed-off-by: snipe <snipe@snipe.net>
2023-08-22 12:50:32 +01:00
snipe aafb7668f5 Merge pull request #13453 from inietov/fixes/accessories_declined_issue
Fixed #13317 Accessories declined by user remain assigned
2023-08-22 12:42:55 +01:00
snipe bb61134dd5 Merge remote-tracking branch 'origin/develop' 2023-08-22 12:41:27 +01:00
snipe fea11ec7f1 Merge pull request #12761 from spencerrlongg/bulk_edit_custom_fields
Bulk Editing Custom Fields
2023-08-22 12:40:18 +01:00
snipe 303b45c9e9 Merge pull request #13485 from Godmartinz/history_info_clean_up
Added better handling of information of asset history
2023-08-22 12:25:17 +01:00
snipe 8c7925e703 Merge pull request #13436 from marcusmoore/chore/dependency-updates
Bumped dependencies
2023-08-21 22:58:52 +01:00
Marcus Moore 191c4f959f Bump guzzlehttp/psr7 to 2.4.5 2023-08-21 14:46:08 -07:00
Marcus Moore 1e10a7ee23 Bump nyholm/psr7 to 1.6.1 2023-08-21 14:45:21 -07:00
Marcus Moore 4e8537a1c7 Merge branch 'develop' into chore/dependency-updates
# Conflicts:
#	composer.lock
2023-08-21 14:44:15 -07:00
snipe 24a9deb735 Merge remote-tracking branch 'origin/develop' 2023-08-21 22:35:45 +01:00
Marcus Moore 4e2ef4f056 Default to using the current date if last check in end date is not provided 2023-08-21 14:35:15 -07:00
snipe 79a4d915db Merge pull request #13456 from marcusmoore/fixes/auto-incrementing-on-74
Fixed passing invalid argument to `strpos()`
2023-08-21 22:25:52 +01:00
Marcus Moore c332b98456 Add last checkin options to report front end 2023-08-21 13:44:49 -07:00
Godfrey M b54aaefefb adds some spacing 2023-08-21 13:43:06 -07:00
Godfrey M 5076b45a0d adds id to history info 2023-08-21 13:40:39 -07:00
Marcus Moore 6fc06f2ee1 Add simple tests around asset check in 2023-08-21 12:31:51 -07:00
snipe 36a343365e Switched from fullName() to getFullNameAttribute()
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:14:07 +01:00
snipe c617bf89b6 Tweak layout
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:13:45 +01:00
snipe ba0643f6a4 Added name display format, tweaked some
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:13:28 +01:00
snipe bfd674b622 Switched to getFullNameAttribute() from fullName() in User Presenter
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:12:25 +01:00
snipe d73d15b8a2 Added form macro for name format
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:11:59 +01:00
snipe 8660d41aa3 Changed width of locale field
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:11:45 +01:00
snipe c39579b170 New strings
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:11:25 +01:00
snipe 354550b52e Removed getCompleteNameAttribute(), modified getFullNameAttribute()
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:11:17 +01:00
snipe f3460b5a4f Switch to getFullNameAttribute() in user transformer
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:10:48 +01:00
snipe 474c03e3fc Added name order to settings save controller method
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:10:03 +01:00
snipe 749002b768 Added migration to add name order to settings
Signed-off-by: snipe <snipe@snipe.net>
2023-08-21 20:09:48 +01:00
Marcus Moore 489d30c685 Set last_checkin in ui and api controllers 2023-08-21 11:57:33 -07:00
snipe 2346bab8ed Merge pull request #13492 from snipe/features/add_dymo_labelwriter
Added Dymo labelwriter
2023-08-18 23:27:37 +01:00
snipe 45898deb1a Don’t 500 if the 1D barcode doesn’t match the format requested - log an error instead
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 22:18:38 +01:00
snipe ffc7c4e99a use number format to constrain large number displays
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 22:18:09 +01:00
snipe 1e82c2bfad Changed example asset name
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 22:17:54 +01:00
snipe d12f4564e1 Added Dymo Labelwriter template
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 21:44:12 +01:00
snipe 1dcca14c37 Values are not sortable, so don’t show them as sortable
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 21:21:54 +01:00
snipe cb3db51fe0 Merge remote-tracking branch 'origin/develop' 2023-08-18 18:42:11 +01:00
snipe 63f847f125 Merge pull request #13491 from snipe/fixes/remove_border_from_default_label
Removed the black label from around the default labels
2023-08-18 18:40:45 +01:00
snipe d56c671410 Removed the black label from around the default labels
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 18:39:00 +01:00
snipe 8e9fa613e3 Merge remote-tracking branch 'origin/develop' 2023-08-18 18:14:40 +01:00
snipe 802651a1b4 Merge pull request #13489 from snipe/fixes/override_0_cols_rows_in_default_for_new_engine
Make sure the columns and rows can never be 0
2023-08-18 18:14:01 +01:00
snipe 0cb76a049a Make sure the columns and rows can never be 0
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 18:13:16 +01:00
snipe 384428148b Merge remote-tracking branch 'origin/develop' 2023-08-18 15:32:33 +01:00
Marcus Moore 8b2716d2b7 Fix update statement 2023-08-17 18:33:01 -07:00
Marcus Moore 56fb45f1ea WIP: Add last_checkin to assets table 2023-08-17 18:01:26 -07:00
Godfrey M a62876d4bc Adds readable asset history in the action log transformer 2023-08-17 16:14:01 -07:00
snipe 8810059427 Merge remote-tracking branch 'origin/develop' 2023-08-16 01:40:06 +01:00
Ivan Nieto Vivanco 25c58a8486 Fix typo in language variable name 2023-08-15 14:17:39 -06:00
snipe 2848465dd2 Merge remote-tracking branch 'origin/develop' 2023-08-15 20:42:36 +01:00
snipe 06ed8b2f2d Merge remote-tracking branch 'origin/develop' 2023-08-15 20:31:00 +01:00
snipe 2ddf5c9a0b Merge pull request #13463 from uberbrady/fix_api_accessory_checkin
Accessory checkin via API reported wrong target user
2023-08-15 19:24:45 +01:00
snipe 949a88e560 Merge remote-tracking branch 'origin/develop' 2023-08-15 18:55:39 +01:00
snipe 28b1461cb4 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/mix-manifest.json
2023-08-15 18:21:51 +01:00
Brady Wetherington 7504c0df13 Accessory checkin via API reported wrong target user 2023-08-15 14:19:36 +01:00
snipe 1c02a7d590 Merge remote-tracking branch 'origin/develop' 2023-08-15 13:26:40 +01:00
snipe 8e0b7bee41 Merge remote-tracking branch 'origin/develop' 2023-08-15 13:23:23 +01:00
Ivan Nieto Vivanco 71cb16118d Change error string for a better (?) one 2023-08-14 20:52:00 -06:00
Ivan Nieto Vivanco d365565b6d Add message in the acceptance assets view to indicate when the user can\'t accept nor deny the asset 2023-08-14 20:51:04 -06:00
Marcus Moore dc1a8840f1 Ensure empty string is not passed to strpos() 2023-08-14 16:40:34 -07:00
Ivan Nieto Vivanco 96440834bd Move the declinedCheckout function so it don/'t separate the class properties 2023-08-14 16:16:28 -06:00
snipe 642a09f139 Merge remote-tracking branch 'origin/develop' 2023-08-14 23:12:07 +01:00
snipe 716e13e5b1 Merge remote-tracking branch 'origin/develop' 2023-08-14 22:23:06 +01:00
Ivan Nieto Vivanco 8da2a8a79c Allows to save signature for declined items 2023-08-14 14:58:10 -06:00
Ivan Nieto Vivanco 4796598bb6 Add declinedCheckout method to Accessory model 2023-08-14 14:35:31 -06:00
snipe ec2556f991 Merge remote-tracking branch 'origin/develop' 2023-08-14 13:02:45 +01:00
snipe 6134dfa8f2 Merge remote-tracking branch 'origin/develop' 2023-08-11 09:42:30 +01:00
Marcus Moore 3a2b15313c Bump guzzlehttp/psr7 to 2.4.5 2023-08-10 11:53:20 -07:00
Marcus Moore 6b6bb61400 Bump nyholm/psr7 to 1.6.1 2023-08-10 11:52:42 -07:00
snipe 7df3be3a54 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/all.css
#	public/css/dist/bootstrap-table.css
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2023-08-09 10:54:49 +01:00
snipe 70903f068c Merge remote-tracking branch 'origin/develop' 2023-08-08 19:01:40 +01:00
snipe 5a43c5906f Merge remote-tracking branch 'origin/develop' 2023-08-08 17:54:17 +01:00
snipe 4b2bf057c7 Merge remote-tracking branch 'origin/develop' 2023-08-08 12:57:27 +01:00
snipe 3091d2cdf0 Merge remote-tracking branch 'origin/develop' 2023-08-08 08:19:15 +01:00
Marcus Moore 42055bb69d Add authentication and authorization tests for department index method 2023-08-07 17:42:28 -07:00
Marcus Moore 7c5a1b376e Remove redundant Company::scopeCompanyables wrapper 2023-08-07 16:54:23 -07:00
Marcus Moore f7b2075e9e Add CompanyableTrait to Department 2023-08-07 16:54:02 -07:00
Marcus Moore cdfe8e459d Add simple test cases for api department index 2023-08-07 16:36:01 -07:00
Ivan Nieto Vivanco 053d3fc9ed Prevent asset to be checked out if full company support is enabled and companies not match 2023-08-02 19:23:28 -06:00
Ivan Nieto Vivanco 9ca163e8cf Stop asset acceptances from shown to user if full company support is enabled and companies not match 2023-08-02 19:22:35 -06:00
snipe c52a1f94dc Merge remote-tracking branch 'origin/develop' 2023-08-02 15:19:23 +01:00
snipe ff3bdebb9a Merge remote-tracking branch 'origin/develop' 2023-07-24 13:27:35 +01:00
snipe f699d9680b Merge remote-tracking branch 'origin/develop' 2023-07-21 15:00:23 +01:00
snipe d26bc19e3f Merge remote-tracking branch 'origin/develop' 2023-07-20 16:34:16 +01:00
snipe 19df0b82b1 Merge remote-tracking branch 'origin/develop' 2023-07-20 14:06:45 +01:00
snipe b54e7dc3ee Fixed #13336 - Save unhashed password if no password provided
Signed-off-by: snipe <snipe@snipe.net>
2023-07-19 17:44:40 +01:00
snipe 74a5bcd490 Merge remote-tracking branch 'origin/develop' 2023-07-19 09:01:19 +01:00
snipe bc91181917 Merge remote-tracking branch 'origin/develop' 2023-07-18 13:27:05 +01:00
snipe 92e7e79faf Merge remote-tracking branch 'origin/develop' 2023-07-18 13:25:34 +01:00
snipe 1fa703387a Merge remote-tracking branch 'origin/develop' 2023-07-18 11:30:53 +01:00
snipe 3203f8f97c Merge remote-tracking branch 'origin/develop' 2023-07-15 10:48:09 +01:00
snipe 8bc8ecfc67 Merge remote-tracking branch 'origin/develop' 2023-07-14 09:39:26 +01:00
snipe db8c37cd5b Merge remote-tracking branch 'origin/develop' 2023-07-14 08:26:12 +01:00
snipe 43d419f051 Merge remote-tracking branch 'origin/develop' 2023-07-13 13:18:52 +01:00
snipe 66875ff0dc Merge remote-tracking branch 'origin/develop' 2023-07-13 12:59:30 +01:00
snipe 8c74e906ef Merge remote-tracking branch 'origin/develop' 2023-07-12 19:22:49 +01:00
snipe 3a6d8ef684 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/all.css
#	public/css/dist/bootstrap-table.css
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2023-07-12 19:22:34 +01:00
snipe a56b040143 Merge remote-tracking branch 'origin/develop' 2023-07-05 17:30:19 +01:00
snipe 61fd427678 Bumped version
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2023-07-05 14:41:34 +01:00
snipe 32747cafde Merge remote-tracking branch 'origin/develop' 2023-07-05 14:37:53 +01:00
snipe e18c3e08be Merge remote-tracking branch 'origin/develop' 2023-06-29 21:23:53 +01:00
snipe 33b1a31ed3 Merge remote-tracking branch 'origin/develop' 2023-06-29 21:19:25 +01:00
snipe 1b71ab6d86 Updated prod assets
Signed-off-by: snipe <snipe@snipe.net>
2023-06-29 20:41:16 +01:00
snipe af26ec471f Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/mix-manifest.json
2023-06-29 20:41:05 +01:00
slong753 8cee3a8218 ok, @marcusmoore was right all along
i just didn't get it
2023-06-29 14:06:52 -05:00
snipe 4dd71e0332 Merge remote-tracking branch 'origin/develop' 2023-06-29 17:14:15 +01:00
slong753 826ea0ded8 move colon to blade based on a comment 2023-06-29 10:40:04 -05:00
snipe 4908082240 Merge remote-tracking branch 'origin/develop' 2023-06-29 16:23:35 +01:00
snipe ead5f039b4 Merge remote-tracking branch 'origin/develop' 2023-06-29 15:33:12 +01:00
slong753 ea61f634fb get rid of nice nullsafe 2023-06-28 16:48:52 -05:00
slong753 afe6fe207a resolved, missed adding errors in a case 2023-06-28 16:45:18 -05:00
slong753 8923206ac8 translation string 2023-06-28 13:08:34 -05:00
slong753 3b8ab2d682 clean formatting a little 2023-06-28 13:00:59 -05:00
slong753 2d27941105 added to textarea too 2023-06-28 12:59:54 -05:00
slong753 50a518e5f3 disable input when field is unique 2023-06-28 12:57:23 -05:00
snipe 2c23c71823 Merge remote-tracking branch 'origin/develop' 2023-06-28 16:41:49 +01:00
slong753 8b8e7cb5ee couple translation strings 2023-06-28 10:17:28 -05:00
slong753 e8988bf51e add list 2023-06-26 20:22:27 -05:00
slong753 2736161909 oops, fixed translation 2023-06-26 16:37:06 -05:00
slong753 8cbff0179c translation strings 2023-06-26 16:35:53 -05:00
slong753 2a352619f7 clean up 2023-06-26 16:25:48 -05:00
slong753 691faf6340 ok, this kind of works - pr needs some clean up 2023-06-26 14:56:07 -05:00
snipe 4cb9c25e83 Merge remote-tracking branch 'origin/develop' 2023-06-26 08:30:35 +01:00
Spencer Long f646623a5e Merge branch 'develop' into bulk_edit_custom_fields 2023-06-22 18:00:31 -05:00
snipe c377e0617c Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
2023-06-21 19:07:07 +01:00
snipe 2ac4449ea3 Merge remote-tracking branch 'origin/develop' 2023-06-15 20:30:07 +01:00
snipe 83708e1be9 Merge remote-tracking branch 'origin/develop' 2023-06-13 18:36:22 +01:00
snipe f552bcef78 Merge pull request #13143 from qay21/patch-1
Fixed #13129: Add missing LDAP lib required for LDAPS support
2023-06-12 14:04:05 +01:00
Quentin Aymard fc6c5eadd7 Fix missing ldap packages
This should provide LDAPS support out of the box, and fix #13129
2023-06-09 11:14:41 +02:00
snipe 924d0b25e8 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	config/version.php
#	public/css/dist/all.css
#	public/js/build/app.js
#	public/js/build/vendor.js
#	public/js/dist/all.js
#	public/mix-manifest.json
2023-06-08 08:53:22 +01:00
snipe fc5b02e392 Merge remote-tracking branch 'origin/develop' 2023-06-01 19:51:49 +01:00
snipe 18eda15ec1 Merge remote-tracking branch 'origin/develop' 2023-05-31 16:19:34 +01:00
snipe c05a4452bc Merge + update assets
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2023-05-29 18:20:12 -04:00
snipe a3a64be19b Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/build/app.css
#	public/css/build/overrides.css
#	public/css/dist/all.css
#	public/mix-manifest.json
2023-05-24 16:06:26 -07:00
snipe f1b4bba3ae Merge remote-tracking branch 'origin/develop' 2023-05-16 23:12:41 -07:00
snipe dbae01f545 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/mix-manifest.json
2023-05-16 17:41:39 -07:00
snipe 5be993df8d Merge remote-tracking branch 'origin/develop' 2023-05-16 16:42:17 -07:00
snipe 37f75c5001 Merge remote-tracking branch 'origin/develop' 2023-05-16 16:29:36 -07:00
slong753 5e34ffa2b0 wip 2023-05-10 14:08:12 -05:00
snipe b1fda46e11 Production assets
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 11:25:28 -07:00
snipe 6b7a7b8aee Merge remote-tracking branch 'origin/develop' 2023-05-10 11:23:29 -07:00
snipe 63c660f306 Merge pull request #12999 from snipe/develop
Google Oauth Recap
2023-05-10 10:01:23 -07:00
slong753 9a4ba78c19 oops, pattern 2023-05-09 23:41:21 -05:00
slong753 491f670215 I think this is what they're looking for 2023-05-09 22:52:00 -05:00
slong753 1d2596fc54 wip 2023-05-09 14:58:59 -05:00
slong753 815c77f943 wip 2023-05-03 14:49:31 -05:00
slong753 cdda4a56d8 aha, ok thisd kind of works 2023-05-02 19:11:43 -05:00
slong753 b2c2097e8b just more troubleshooting stuff, still no solution 2023-05-02 18:54:20 -05:00
slong753 52c9fefbe0 ok, this works except error display 2023-04-26 15:06:50 -05:00
slong753 6bec9cf880 fix a couple things 2023-04-25 23:26:16 -05:00
Godfrey M c9eb1410d7 swaps version and open source text in the footer 2023-04-25 11:03:05 -07:00
Godfrey M b8c424fca0 adds users total cost to user profile 2023-04-24 09:17:42 -07:00
Godfrey M 97df39001d adds optional breakdowns for total cost 2023-04-19 17:51:37 -07:00
Godfrey M 6872f8da7b adding total cost to user view 2023-04-19 17:31:09 -07:00
Godfrey M 0ab400f5bc removed deadspace and pull 2023-04-18 15:23:11 -07:00
Godfrey M f15b0d8591 fix for footer 2023-04-18 15:20:38 -07:00
slong753 52dc99588e pushing for now, needs validation work 2023-04-17 13:57:48 -05:00
slong753 8b9aea8874 very much WIP, but dupe queries reduced
but i think this can be cleaned up a bit more
2023-04-12 14:46:48 -05:00
slong753 830e3e5594 cleanup 2023-04-05 15:27:28 -05:00
slong753 d56a4e7173 cleanup+formatting 2023-04-05 15:16:46 -05:00
slong753 3929526a57 ok, this works but needs to be tested more 2023-04-04 18:57:51 -05:00
slong753 29e3d202fe checking something, quick push 2023-04-03 17:54:31 -05:00
slong753 b0fa298d8f delete a couple things 2023-03-29 15:14:48 -05:00
slong753 65bbecd145 this all works - could use some eyes 2023-03-29 14:46:31 -05:00
slong753 032ae4348e custom fields display, need to get saving
+some clean up
2023-03-28 21:45:31 -05:00
slong753 804a788a27 initial fetch working 2023-03-28 20:31:24 -05:00
1330 changed files with 14587 additions and 282842 deletions
-61
View File
@@ -1,61 +0,0 @@
version: 1
environment:
php: 8.0
node: 12
services:
- mysql: 5.7
- dusk:
on:
push:
branches:
- master
- develop
pull_request:
branches: .*
pipeline:
- name: Setup
cmd: |
cp -v .env.testing.example .env
cp -v .env.testing.example .env.testing
composer install --no-interaction --prefer-dist --optimize-autoloader
- name: Generate Key
cmd: |
php artisan key:generate --force
- name: Passport Keys
cmd: |
php artisan passport:keys
- name: Run Migrations
cmd: |
php artisan migrate --force
- name: PHPUnit Unit Tests
cmd: |
php artisan test --testsuite Unit
- name: PHPUnit Feature Tests
cmd: |
php artisan test --testsuite Feature
# - name: Browser Tests
# cmd: |
# cp -v .env.dusk.example .env.dusk.ci
# sed -i "s@APP_ENV=.*@APP_ENV=ci@g" .env.dusk.ci
# sed -i "s@APP_URL=.*@APP_URL=http://$BUILD_HOST:8000@g" .env.dusk.ci
# #sed -i "s@DB_HOST=.*@DB_HOST=mysql@g" .env.dusk.ci
# sed -i "s@DB_HOST=.*@DB_HOST=$DB_HOST@g" .env.dusk.ci
# sed -i "s@DB_USERNAME=.*@DB_USERNAME=chipperci@g" .env.dusk.ci
# sed -i "s@DB_DATABASE=.*@DB_DATABASE=chipperci@g" .env.dusk.ci
# sed -i "s@DB_PASSWORD=.*@DB_PASSWORD=secret@g" .env.dusk.ci
#
# php -S [::0]:8000 -t public 2>server.log &
# sleep 2
# php artisan dusk:chrome-driver $CHROME_DRIVER
# php artisan dusk --env=ci
+1 -1
View File
@@ -18,5 +18,5 @@ importer: ["/app/Importer/*","/app/Http/Livewire/Importer.php", "resources/views
cli / artisan: ["/app/Console/*"]
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php"]
docker: ["*docker/*", "Dockerfile", "Dockerfile.alpine", "Dockerfile.fpm-alpine", ".dockerignore", ".env.docker"]
tests: ["/tests/*", "/stubs"]
tests: ["/tests/*", "/database/factories/*", "/stubs"]
config: .github
+1
View File
@@ -2,5 +2,6 @@ version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "develop"
schedule:
interval: "weekly"
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
language: [ 'javascript' ]
steps:
- name: Checkout repository
uses: actions/checkout@v3.3.0
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout code
uses: actions/checkout@v3.3.0
uses: actions/checkout@v4
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
- name: Run Codacy Analysis CLI
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Crowdin push
uses: crowdin/github-action@v1
+6 -5
View File
@@ -32,6 +32,7 @@ jobs:
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }},suffix=-alpine
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }},suffix=-alpine
type=ref,event=tag,suffix=-alpine
type=semver,pattern=v{{major}}-latest-alpine
# Define default tag "flavor" for docker/metadata-action per
# https://github.com/docker/metadata-action#flavor-input
# We turn off 'latest' tag by default.
@@ -41,17 +42,17 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v3.3.0
uses: actions/checkout@v4
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
# https://github.com/docker/login-action
- name: Login to DockerHub
# Only login if not a PR, as PRs only trigger a Docker build and not a push
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
@@ -63,7 +64,7 @@ jobs:
# Get Metadata for docker_build step below
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
id: meta_build
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: snipe/snipe-it
tags: ${{ env.IMAGE_TAGS }}
@@ -72,7 +73,7 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push 'snipe-it' image
id: docker_build
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile.alpine
+6 -5
View File
@@ -32,6 +32,7 @@ jobs:
type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=branch,enable=${{ !endsWith(github.ref, github.event.repository.default_branch) }}
type=ref,event=tag
type=semver,pattern=v{{major}}-latest
# Define default tag "flavor" for docker/metadata-action per
# https://github.com/docker/metadata-action#flavor-input
# We turn off 'latest' tag by default.
@@ -41,17 +42,17 @@ jobs:
steps:
# https://github.com/actions/checkout
- name: Checkout codebase
uses: actions/checkout@v3.3.0
uses: actions/checkout@v4
# https://github.com/docker/setup-buildx-action
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
# https://github.com/docker/login-action
- name: Login to DockerHub
# Only login if not a PR, as PRs only trigger a Docker build and not a push
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
@@ -63,7 +64,7 @@ jobs:
# Get Metadata for docker_build step below
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
id: meta_build
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: snipe/snipe-it
tags: ${{ env.IMAGE_TAGS }}
@@ -72,7 +73,7 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push 'snipe-it' image
id: docker_build
uses: docker/build-push-action@v4
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
+73
View File
@@ -0,0 +1,73 @@
name: Tests
on:
push:
branches:
- master
- develop
pull_request:
jobs:
tests:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:5.7
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: snipeit
ports:
- 33306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
strategy:
fail-fast: false
matrix:
php-version:
- "7.4"
- "8.0"
- "8.1.1"
name: PHP ${{ matrix.php-version }}
steps:
- uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php-version }}"
coverage: none
- uses: actions/checkout@v4
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-
- name: Copy .env
run: |
cp -v .env.testing.example .env
cp -v .env.testing.example .env.testing
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
- name: Directory Permissions
run: chmod -R 777 storage bootstrap/cache
- name: Execute tests (Unit and Feature tests) via PHPUnit
env:
DB_CONNECTION: mysql
DB_DATABASE: snipeit
DB_PORT: ${{ job.services.mysql.ports[3306] }}
DB_USERNAME: root
run: php artisan test --parallel
-2
View File
@@ -1,8 +1,6 @@
.couscous
.DS_Store
.env
.env.dusk.*
!.env.dusk.example
.env.testing
phpstan.neon
.idea
+1 -1
View File
@@ -1,4 +1,4 @@
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=snipe/snipe-it&amp;utm_campaign=Badge_Grade)
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=snipe/snipe-it&amp;utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-326-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev)
## Snipe-IT - Open Source Asset Management System
+33 -32
View File
@@ -9,7 +9,39 @@ Before starting, follow the [instructions](README.md#installation) for installin
Before attempting to run the test suite copy the example environment file for tests and update the values to match your environment:
`cp .env.testing.example .env.testing`
> Since the data in the database is flushed after each test it is recommended you create a separate mysql database for specifically for tests
The following should work for running tests in memory with sqlite:
```
# --------------------------------------------
# REQUIRED: BASIC APP SETTINGS
# --------------------------------------------
APP_ENV=testing
APP_DEBUG=true
APP_KEY=base64:glJpcM7BYwWiBggp3SQ/+NlRkqsBQMaGEOjemXqJzOU=
APP_URL=http://localhost:8000
APP_TIMEZONE='UTC'
APP_LOCALE=en
# --------------------------------------------
# REQUIRED: DATABASE SETTINGS
# --------------------------------------------
DB_CONNECTION=sqlite_testing
#DB_HOST=127.0.0.1
#DB_PORT=3306
#DB_DATABASE=null
#DB_USERNAME=null
#DB_PASSWORD=null
```
To use MySQL you should update the `DB_` variables to match your local test database:
```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE={}
DB_USERNAME={}
DB_PASSWORD={}
```
Now you are ready to run the entire test suite from your terminal:
@@ -18,34 +50,3 @@ Now you are ready to run the entire test suite from your terminal:
To run individual test files, you can pass the path to the test that you want to run:
`php artisan test tests/Unit/AccessoryTest.php`
## Browser Tests
Browser tests are run via [Laravel Dusk](https://laravel.com/docs/8.x/dusk) and require Google Chrome to be installed.
Before attempting to run Dusk tests copy the example environment file for Dusk and update the values to match your environment:
`cp .env.dusk.example .env.dusk.local`
> `local` refers to the value of `APP_ENV` in your `.env` so if you have it set to `dev` then the file should be named `.env.dusk.dev`.
**Important**: Dusk tests cannot be run using an in-memory SQLite database. Additionally, the Dusk test suite uses the `DatabaseMigrations` trait which will leave the database in a fresh state after running. Therefore, it is recommended that you create a test database and point `DB_DATABASE` in `.env.dusk.local` to it.
### Running Browser Tests
Your application needs to be configured and up and running in order for the browser tests to actually run. When running the tests locally, you can start the application using the following command:
`php artisan serve`
Now you are ready to run the test suite. Use the following command from another terminal tab or window:
`php artisan dusk`
To run individual test files, you can pass the path to the test that you want to run:
`php artisan dusk tests/Browser/LoginTest.php`
If you get an error when attempting to run Dusk tests that says `Couldn't connect to server` run:
`php artisan dusk:chrome-driver --detect`
This command will install the specific ChromeDriver Dusk needs for your operating system and Chrome version.
+1 -5
View File
@@ -180,10 +180,6 @@ class LdapSync extends Command
}
}
/* Create user account entries in Snipe-IT */
$tmp_pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 20);
$pass = bcrypt($tmp_pass);
$manager_cache = [];
if($ldap_default_group != null) {
@@ -229,7 +225,7 @@ class LdapSync extends Command
} else {
// Creating a new user.
$user = new User;
$user->password = $pass;
$user->password = $user->noPassword();
$user->activated = 1; // newly created users can log in by default, unless AD's UAC is in use, or an active flag is set (below)
$item['createorupdate'] = 'created';
}
+3 -1
View File
@@ -15,18 +15,20 @@ class CheckoutableCheckedIn
public $checkedInBy;
public $note;
public $action_date; // Date setted in the hardware.checkin view at the checkin_at input, for the action log
public $originalValues;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($checkoutable, $checkedOutTo, User $checkedInBy, $note, $action_date = null)
public function __construct($checkoutable, $checkedOutTo, User $checkedInBy, $note, $action_date = null, $originalValues = [])
{
$this->checkoutable = $checkoutable;
$this->checkedOutTo = $checkedOutTo;
$this->checkedInBy = $checkedInBy;
$this->note = $note;
$this->action_date = $action_date ?? date('Y-m-d');
$this->originalValues = $originalValues;
}
}
+3 -1
View File
@@ -14,17 +14,19 @@ class CheckoutableCheckedOut
public $checkedOutTo;
public $checkedOutBy;
public $note;
public $originalValues;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note)
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [])
{
$this->checkoutable = $checkoutable;
$this->checkedOutTo = $checkedOutTo;
$this->checkedOutBy = $checkedOutBy;
$this->note = $note;
$this->originalValues = $originalValues;
}
}
+25
View File
@@ -2,6 +2,8 @@
namespace App\Helpers;
use App\Models\Accessory;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Component;
use App\Models\Consumable;
use App\Models\CustomField;
@@ -643,6 +645,7 @@ class Helper
$consumables = Consumable::withCount('consumableAssignments as consumable_assignments_count')->whereNotNull('min_amt')->get();
$accessories = Accessory::withCount('users as users_count')->whereNotNull('min_amt')->get();
$components = Component::whereNotNull('min_amt')->get();
$asset_models = AssetModel::where('min_amt', '>', 0)->get();
$avail_consumables = 0;
$items_array = [];
@@ -705,6 +708,28 @@ class Helper
}
}
foreach ($asset_models as $asset_model){
$asset = new Asset();
$total_owned = $asset->where('model_id', '=', $asset_model->id)->count();
$avail = $asset->where('model_id', '=', $asset_model->id)->whereNull('assigned_to')->count();
if ($avail < ($asset_model->min_amt)+ \App\Models\Setting::getSettings()->alert_threshold) {
if ($avail > 0) {
$percent = number_format((($avail / $total_owned) * 100), 0);
} else {
$percent = 100;
}
$items_array[$all_count]['id'] = $asset_model->id;
$items_array[$all_count]['name'] = $asset_model->name;
$items_array[$all_count]['type'] = 'models';
$items_array[$all_count]['percent'] = $percent;
$items_array[$all_count]['remaining'] = $avail;
$items_array[$all_count]['min_amt'] = $asset_model->min_amt;
$all_count++;
}
}
return $items_array;
}
@@ -161,22 +161,19 @@ class AccessoriesFilesController extends Controller
->header('Content-Type', 'text/plain');
} else {
// Display the file inline
if (request('inline') == 'true') {
$headers = [
'Content-Disposition' => 'inline',
];
return Storage::download($file, $log->filename, $headers);
}
// We have to override the URL stuff here, since local defaults in Laravel's Flysystem
// won't work, as they're not accessible via the web
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(['error' => 'Failed validation: '], 500);
}
return StorageHelper::downloader($file);
}
}
}
@@ -69,7 +69,7 @@ class AcceptanceController extends Controller
}
if (! Company::isCurrentUserHasAccess($acceptance->checkoutable)) {
return redirect()->route('account.accept')->with('error', trans('general.insufficient_permissions'));
return redirect()->route('account.accept')->with('error', trans('general.error_user_company'));
}
return view('account/accept.create', compact('acceptance'));
@@ -245,6 +245,36 @@ class AcceptanceController extends Controller
$return_msg = trans('admin/users/message.accepted');
} else {
/**
* Check for the eula-pdfs directory
*/
if (! Storage::exists('private_uploads/eula-pdfs')) {
Storage::makeDirectory('private_uploads/eula-pdfs', 775);
}
if (Setting::getSettings()->require_accept_signature == '1') {
// Check if the signature directory exists, if not create it
if (!Storage::exists('private_uploads/signatures')) {
Storage::makeDirectory('private_uploads/signatures', 775);
}
// The item was accepted, check for a signature
if ($request->filled('signature_output')) {
$sig_filename = 'siglog-' . Str::uuid() . '-' . date('Y-m-d-his') . '.png';
$data_uri = $request->input('signature_output');
$encoded_image = explode(',', $data_uri);
$decoded_image = base64_decode($encoded_image[1]);
Storage::put('private_uploads/signatures/' . $sig_filename, (string)$decoded_image);
// No image data is present, kick them back.
// This mostly only applies to users on super-duper crapola browsers *cough* IE *cough*
} else {
return redirect()->back()->with('error', trans('general.shitty_browser'));
}
}
// Format the data to send the declined notification
$branding_settings = SettingsController::getPDFBranding();
@@ -281,11 +311,18 @@ class AcceptanceController extends Controller
'item_model' => $display_model,
'item_serial' => $item->serial,
'declined_date' => Carbon::parse($acceptance->declined_at)->format('Y-m-d'),
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
'assigned_to' => $assigned_to,
'company_name' => $branding_settings->site_name,
'date_settings' => $branding_settings->date_display_format,
];
if ($pdf_view_route!='') {
\Log::debug($pdf_filename.' is the filename, and the route was specified.');
$pdf = Pdf::loadView($pdf_view_route, $data);
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf->output());
}
$acceptance->decline($sig_filename);
$acceptance->notify(new AcceptanceAssetDeclinedNotification($data));
event(new CheckoutDeclined($acceptance));
@@ -38,6 +38,7 @@ class AssetModelsController extends Controller
'image',
'name',
'model_number',
'min_amt',
'eol',
'notes',
'created_at',
@@ -45,6 +46,7 @@ class AssetModelsController extends Controller
'requestable',
'assets_count',
'category',
'fieldset',
];
$assetmodels = AssetModel::select([
@@ -52,6 +54,7 @@ class AssetModelsController extends Controller
'models.image',
'models.name',
'model_number',
'min_amt',
'eol',
'requestable',
'models.notes',
@@ -92,6 +95,9 @@ class AssetModelsController extends Controller
case 'category':
$assetmodels->OrderCategory($order);
break;
case 'fieldset':
$assetmodels->OrderFieldset($order);
break;
default:
$assetmodels->orderBy($sort, $order);
break;
@@ -905,6 +905,7 @@ class AssetsController extends Controller
$asset->expected_checkin = null;
$asset->last_checkout = null;
$asset->last_checkin = now();
$asset->assigned_to = null;
$asset->assignedTo()->disassociate($asset);
$asset->accepted = null;
@@ -924,10 +925,14 @@ class AssetsController extends Controller
}
$checkin_at = $request->filled('checkin_at') ? $request->input('checkin_at').' '. date('H:i:s') : date('Y-m-d H:i:s');
$originalValues = $asset->getRawOriginal();
if (($request->filled('checkin_at')) && ($request->get('checkin_at') != date('Y-m-d'))) {
$originalValues['action_date'] = $checkin_at;
}
if ($asset->save()) {
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at));
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at, $originalValues));
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.success')));
}
@@ -27,7 +27,7 @@ class DepartmentsController extends Controller
$this->authorize('view', Department::class);
$allowed_columns = ['id', 'name', 'image', 'users_count'];
$departments = Company::scopeCompanyables(Department::select(
$departments = Department::select(
'departments.id',
'departments.name',
'departments.phone',
@@ -37,8 +37,8 @@ class DepartmentsController extends Controller
'departments.manager_id',
'departments.created_at',
'departments.updated_at',
'departments.image'),
"company_id", "departments")->with('users')->with('location')->with('manager')->with('company')->withCount('users as users_count');
'departments.image'
)->with('users')->with('location')->with('manager')->with('company')->withCount('users as users_count');
if ($request->filled('search')) {
$departments = $departments->TextSearch($request->input('search'));
+8 -3
View File
@@ -75,7 +75,6 @@ class UsersController extends Controller
])->with('manager', 'groups', 'userloc', 'company', 'department', 'assets', 'licenses', 'accessories', 'consumables', 'createdBy',)
->withCount('assets as assets_count', 'licenses as licenses_count', 'accessories as accessories_count', 'consumables as consumables_count');
$users = Company::scopeCompanyables($users);
if ($request->filled('activated')) {
@@ -271,6 +270,8 @@ class UsersController extends Controller
} elseif (($request->filled('all')) && ($request->input('all') == 'true')) {
$users = $users->withTrashed();
}
$users = Company::scopeCompanyables($users);
$total = $users->count();
$users = $users->skip($offset)->take($limit)->get();
@@ -362,8 +363,12 @@ class UsersController extends Controller
$user->permissions = $permissions_array;
}
$tmp_pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 40);
$user->password = bcrypt($request->get('password', $tmp_pass));
//
if ($request->filled('password')) {
$user->password = bcrypt($request->get('password'));
} else {
$user->password = $user->noPassword();
}
app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');
+12 -1
View File
@@ -6,6 +6,7 @@ use App\Helpers\Helper;
use App\Http\Requests\ImageUploadRequest;
use App\Models\AssetModel;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Validator;
@@ -76,6 +77,7 @@ class AssetModelsController extends Controller
$model->depreciation_id = $request->input('depreciation_id');
$model->name = $request->input('name');
$model->model_number = $request->input('model_number');
$model->min_amt = $request->input('min_amt');
$model->manufacturer_id = $request->input('manufacturer_id');
$model->category_id = $request->input('category_id');
$model->notes = $request->input('notes');
@@ -153,6 +155,7 @@ class AssetModelsController extends Controller
$model->eol = $request->input('eol');
$model->name = $request->input('name');
$model->model_number = $request->input('model_number');
$model->min_amt = $request->input('min_amt');
$model->manufacturer_id = $request->input('manufacturer_id');
$model->category_id = $request->input('category_id');
$model->notes = $request->input('notes');
@@ -171,8 +174,15 @@ class AssetModelsController extends Controller
}
}
}
if ($model->save()) {
if ($model->wasChanged('eol')) {
$newEol = $model->eol;
$model->assets()->whereNotNull('purchase_date')->where('eol_explicit', false)
->update(['asset_eol_date' => DB::raw('DATE_ADD(purchase_date, INTERVAL ' . $newEol . ' MONTH)')]);
}
return redirect()->route('models.index')->with('success', trans('admin/models/message.update.success'));
}
@@ -286,6 +296,7 @@ class AssetModelsController extends Controller
return view('models/edit')
->with('depreciation_list', Helper::depreciationList())
->with('item', $model)
->with('model_id', $model_to_clone->id)
->with('clone_model', $model_to_clone);
}
@@ -78,7 +78,7 @@ class AssetModelsFilesController extends Controller
* @return View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($modelId = null, $fileId = null, $download = true)
public function show($modelId = null, $fileId = null)
{
$model = AssetModel::find($modelId);
// the asset is valid
@@ -99,12 +99,13 @@ class AssetModelsFilesController extends Controller
->header('Content-Type', 'text/plain');
}
if ($download != 'true') {
if ($contents = file_get_contents(Storage::url($file))) {
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
if (request('inline') == 'true') {
return JsonResponse::create(['error' => 'Failed validation: '], 500);
$headers = [
'Content-Disposition' => 'inline',
];
return Storage::download($file, $log->filename, $headers);
}
return StorageHelper::downloader($file);
@@ -68,6 +68,7 @@ class AssetCheckinController extends Controller
$asset->expected_checkin = null;
$asset->last_checkout = null;
$asset->last_checkin = now();
$asset->assigned_to = null;
$asset->assignedTo()->disassociate($asset);
$asset->assigned_type = null;
@@ -108,8 +109,11 @@ class AssetCheckinController extends Controller
}
}
$originalValues = $asset->getRawOriginal();
$checkin_at = date('Y-m-d H:i:s');
if (($request->filled('checkin_at')) && ($request->get('checkin_at') != date('Y-m-d'))) {
$originalValues['action_date'] = $checkin_at;
$checkin_at = $request->get('checkin_at');
}
@@ -132,7 +136,7 @@ class AssetCheckinController extends Controller
// Was the asset updated?
if ($asset->save()) {
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at));
event(new CheckoutableCheckedIn($asset, $target, Auth::user(), $request->input('note'), $checkin_at, $originalValues));
if ((isset($user)) && ($backto == 'user')) {
return redirect()->route('users.show', $user->id)->with('success', trans('admin/hardware/message.checkin.success'));
@@ -89,6 +89,15 @@ class AssetCheckoutController extends Controller
}
}
$settings = \App\Models\Setting::getSettings();
// We have to check whether $target->company_id is null here since locations don't have a company yet
if (($settings->full_multiple_companies_support) && ((!is_null($target->company_id)) && (!is_null($asset->company_id)))) {
if ($target->company_id != $asset->company_id){
return redirect()->to("hardware/$assetId/checkout")->with('error', trans('general.error_user_company'));
}
}
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $request->get('name'))) {
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.checkout.success'));
}
@@ -79,7 +79,7 @@ class AssetFilesController extends Controller
* @return View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($assetId = null, $fileId = null, $download = true)
public function show($assetId = null, $fileId = null)
{
$asset = Asset::find($assetId);
// the asset is valid
@@ -103,12 +103,13 @@ class AssetFilesController extends Controller
->header('Content-Type', 'text/plain');
}
if ($download != 'true') {
if ($contents = file_get_contents(Storage::url($file))) {
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
if (request('inline') == 'true') {
return JsonResponse::create(['error' => 'Failed validation: '], 500);
$headers = [
'Content-Disposition' => 'inline',
];
return Storage::download($file, $log->filename, $headers);
}
return StorageHelper::downloader($file);
@@ -6,6 +6,7 @@ use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Requests\ImageUploadRequest;
use App\Models\Actionlog;
use Illuminate\Support\Facades\Log;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\CheckoutRequest;
@@ -14,26 +15,18 @@ use App\Models\Location;
use App\Models\Setting;
use App\Models\Statuslabel;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\View\Label;
use Auth;
use Carbon\Carbon;
use DB;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Gate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Cookie;
use Input;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Validator;
use League\Csv\Reader;
use League\Csv\Statement;
use Paginator;
use Redirect;
use Response;
use Slack;
use Str;
use TCPDF;
use View;
use Illuminate\Support\Facades\Redirect;
/**
* This class controls all actions related to assets for
@@ -173,9 +166,9 @@ class AssetsController extends Controller
if ($field->field_encrypted == '1') {
if (Gate::allows('admin')) {
if (is_array($request->input($field->db_column))) {
$asset->{$field->db_column} = \Crypt::encrypt(implode(', ', $request->input($field->db_column)));
$asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column)));
} else {
$asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column));
$asset->{$field->db_column} = Crypt::encrypt($request->input($field->db_column));
}
}
} else {
@@ -298,10 +291,10 @@ class AssetsController extends Controller
/**
* Validate and process asset edit form.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $assetId
* @since [v1.0]
* @return Redirect
* @return \Illuminate\Http\RedirectResponse|Redirect
*@since [v1.0]
* @author [A. Gianotto] [<snipe@snipe.net>]
*/
public function update(ImageUploadRequest $request, $assetId = null)
{
@@ -315,9 +308,23 @@ class AssetsController extends Controller
$asset->status_id = $request->input('status_id', null);
$asset->warranty_months = $request->input('warranty_months', null);
$asset->purchase_cost = $request->input('purchase_cost', null);
$asset->asset_eol_date = request('asset_eol_date', null);
$asset->purchase_date = $request->input('purchase_date', null);
$asset->purchase_date = $request->input('purchase_date', null);
if ($request->filled('purchase_date') && !$request->filled('asset_eol_date') && $asset->model->eol) {
$asset->purchase_date = $request->input('purchase_date', null);
$asset->asset_eol_date = Carbon::parse($request->input('purchase_date'))->addMonths($asset->model->eol)->format('Y-m-d');
} elseif ($request->filled('asset_eol_date')) {
$asset->asset_eol_date = $request->input('asset_eol_date', null);
$months = Carbon::parse($asset->asset_eol_date)->diffInMonths($asset->purchase_date);
if($asset->model->eol) {
if($months != $asset->model->eol) {
$asset->eol_explicit = true;
} else {
$asset->eol_explicit = false;
}
} else {
$asset->eol_explicit = true;
}
}
$asset->supplier_id = $request->input('supplier_id', null);
$asset->expected_checkin = $request->input('expected_checkin', null);
@@ -342,7 +349,7 @@ class AssetsController extends Controller
unlink(public_path().'/uploads/assets/'.$asset->image);
$asset->image = '';
} catch (\Exception $e) {
\Log::info($e);
Log::info($e);
}
}
@@ -370,9 +377,9 @@ class AssetsController extends Controller
if ($field->field_encrypted == '1') {
if (Gate::allows('admin')) {
if (is_array($request->input($field->db_column))) {
$asset->{$field->db_column} = \Crypt::encrypt(implode(', ', $request->input($field->db_column)));
$asset->{$field->db_column} = Crypt::encrypt(implode(', ', $request->input($field->db_column)));
} else {
$asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column));
$asset->{$field->db_column} = Crypt::encrypt($request->input($field->db_column));
}
}
} else {
@@ -420,7 +427,7 @@ class AssetsController extends Controller
try {
Storage::disk('public')->delete('assets'.'/'.$asset->image);
} catch (\Exception $e) {
\Log::debug($e);
Log::debug($e);
}
}
@@ -535,7 +542,7 @@ class AssetsController extends Controller
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
} catch (\Exception $e) {
\Log::debug('The barcode format is invalid.');
Log::debug('The barcode format is invalid.');
return response(file_get_contents(public_path('uploads/barcodes/invalid_barcode.gif')))->header('Content-type', 'image/gif');
}
@@ -856,7 +863,7 @@ class AssetsController extends Controller
'next_audit_date' => 'date|nullable',
];
$validator = \Validator::make($request->all(), $rules);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()->all()));
@@ -873,7 +880,7 @@ class AssetsController extends Controller
// Check to see if they checked the box to update the physical location,
// not just note it in the audit notes
if ($request->input('update_location') == '1') {
\Log::debug('update location in audit');
Log::debug('update location in audit');
$asset->location_id = $request->input('location_id');
}
@@ -14,6 +14,7 @@ use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use App\Http\Requests\AssetCheckoutRequest;
use App\Models\CustomField;
class BulkAssetsController extends Controller
{
@@ -31,7 +32,7 @@ class BulkAssetsController extends Controller
public function edit(Request $request)
{
$this->authorize('view', Asset::class);
if (! $request->filled('ids')) {
return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected'));
}
@@ -41,13 +42,30 @@ class BulkAssetsController extends Controller
session(['bulk_back_url' => $bulk_back_url]);
$asset_ids = array_values(array_unique($request->input('ids')));
//custom fields logic
$asset_custom_field = Asset::with(['model.fieldset.fields', 'model'])->whereIn('id', $asset_ids)->whereHas('model', function ($query) {
return $query->where('fieldset_id', '!=', null);
})->get();
$models = $asset_custom_field->unique('model_id');
$modelNames = [];
foreach($models as $model) {
$modelNames[] = $model->model->name;
}
if ($request->filled('bulk_actions')) {
switch ($request->input('bulk_actions')) {
case 'labels':
$this->authorize('view', Asset::class);
$assets_found = Asset::find($asset_ids);
if ($assets_found->isEmpty()){
return redirect()->back();
}
return (new Label)
->with('assets', Asset::find($asset_ids))
->with('assets', $assets_found)
->with('settings', Setting::getSettings())
->with('bulkedit', true)
->with('count', 0);
@@ -74,7 +92,9 @@ class BulkAssetsController extends Controller
$this->authorize('update', Asset::class);
return view('hardware/bulk')
->with('assets', $asset_ids)
->with('statuslabel_list', Helper::statusLabelList());
->with('statuslabel_list', Helper::statusLabelList())
->with('models', $models->pluck(['model']))
->with('modelNames', $modelNames);
}
}
@@ -92,6 +112,7 @@ class BulkAssetsController extends Controller
public function update(Request $request)
{
$this->authorize('update', Asset::class);
$error_bag = [];
// Get the back url from the session and then destroy the session
$bulk_back_url = route('hardware.index');
@@ -100,12 +121,21 @@ class BulkAssetsController extends Controller
}
if (! $request->filled('ids') || count($request->input('ids')) <= 0) {
$custom_field_columns = CustomField::all()->pluck('db_column')->toArray();
if(Session::exists('ids')) {
$assets = Session::get('ids');
} elseif (! $request->filled('ids') || count($request->input('ids')) <= 0) {
return redirect($bulk_back_url)->with('error', trans('admin/hardware/message.update.no_assets_selected'));
}
$assets = array_keys($request->input('ids'));
if ($request->anyFilled($custom_field_columns)) {
$custom_fields_present = true;
} else {
$custom_fields_present = false;
}
if (($request->filled('purchase_date'))
|| ($request->filled('expected_checkin'))
|| ($request->filled('purchase_cost'))
@@ -121,6 +151,7 @@ class BulkAssetsController extends Controller
|| ($request->filled('null_purchase_date'))
|| ($request->filled('null_expected_checkin_date'))
|| ($request->filled('null_next_audit_date'))
|| ($request->anyFilled($custom_field_columns))
) {
foreach ($assets as $assetId) {
@@ -136,6 +167,9 @@ class BulkAssetsController extends Controller
->conditionallyAddItem('supplier_id')
->conditionallyAddItem('warranty_months')
->conditionallyAddItem('next_audit_date');
foreach ($custom_field_columns as $key => $custom_field_column) {
$this->conditionallyAddItem($custom_field_column);
}
if ($request->input('null_purchase_date')=='1') {
$this->update_array['purchase_date'] = null;
@@ -168,11 +202,11 @@ class BulkAssetsController extends Controller
}
$changed = [];
$asset = Asset::where('id' ,$assetId)->get();
$assetCollection = Asset::where('id' ,$assetId)->get();
foreach ($this->update_array as $key => $value) {
if ($this->update_array[$key] != $asset->toArray()[0][$key]) {
$changed[$key]['old'] = $asset->toArray()[0][$key];
if ($this->update_array[$key] != $assetCollection->toArray()[0][$key]) {
$changed[$key]['old'] = $assetCollection->toArray()[0][$key];
$changed[$key]['new'] = $this->update_array[$key];
}
}
@@ -184,17 +218,47 @@ class BulkAssetsController extends Controller
$logAction->user_id = Auth::id();
$logAction->log_meta = json_encode($changed);
$logAction->logaction('update');
DB::table('assets')
->where('id', $assetId)
->update($this->update_array);
} // endforeach
if($custom_fields_present) {
$asset = Asset::find($assetId);
$assetCustomFields = $asset->model()->first()->fieldset;
if($assetCustomFields && $assetCustomFields->fields) {
foreach ($assetCustomFields->fields as $field) {
if (array_key_exists($field->db_column, $this->update_array)) {
$asset->{$field->db_column} = $this->update_array[$field->db_column];
$saved = $asset->save();
if(!$saved) {
$error_bag[] = $asset->getErrors();
}
continue;
} else {
$array = $this->update_array;
array_except($array, $field->db_column);
$asset->save($array);
}
if (!$asset->save()) {
$error_bag[] = $asset->getErrors();
}
}
}
} else {
Asset::find($assetId)->update($this->update_array);
}
}
if(!empty($error_bag)) {
$errors = [];
//find the customfield name from the name of the messagebag items
foreach ($error_bag as $key => $bag) {
foreach($bag->keys() as $key => $value) {
CustomField::where('db_column', $value)->get()->map(function($item) use (&$errors) {
$errors[] = $item->name;
});
}
}
return redirect($bulk_back_url)->with('bulk_errors', array_unique($errors));
}
return redirect($bulk_back_url)->with('success', trans('admin/hardware/message.update.success'));
}
// no values given, nothing to update
return redirect($bulk_back_url)->with('warning', trans('admin/hardware/message.update.nothing_updated'));
}
@@ -191,9 +191,11 @@ class LoginController extends Controller
$ldap_attr = Ldap::parseAndMapLdapAttributes($ldap_user);
$user->password = $user->noPassword();
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']; //FIXME (or TODO?) - do we need to map additional fields that we now support? E.g. country, phone, etc.
@@ -56,10 +56,11 @@ class ComponentCheckinController extends Controller
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(Request $request, $component_asset_id)
public function store(Request $request, $component_asset_id, $backto = null)
{
if ($component_assets = DB::table('components_assets')->find($component_asset_id)) {
if (is_null($component = Component::find($component_assets->component_id))) {
return redirect()->route('components.index')->with('error',
trans('admin/components/message.not_found'));
}
@@ -95,6 +96,10 @@ class ComponentCheckinController extends Controller
$asset = Asset::find($component_assets->asset_id);
event(new CheckoutableCheckedIn($component, $asset, Auth::user(), $request->input('note'), Carbon::now()));
if($backto == 'asset'){
return redirect()->route('hardware.view', $asset->id)->with('success',
trans('admin/components/message.checkin.success'));
}
return redirect()->route('components.index')->with('success',
trans('admin/components/message.checkin.success'));
@@ -132,7 +132,7 @@ class ComponentsFilesController extends Controller
* @return \Symfony\Component\HttpFoundation\Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($componentId = null, $fileId = null, $download = true)
public function show($componentId = null, $fileId = null)
{
\Log::debug('Private filesystem is: '.config('filesystems.default'));
$component = Component::find($componentId);
@@ -157,21 +157,17 @@ class ComponentsFilesController extends Controller
->header('Content-Type', 'text/plain');
} else {
// Display the file inline
if (request('inline') == 'true') {
$headers = [
'Content-Disposition' => 'inline',
];
return Storage::download($file, $log->filename, $headers);
}
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(['error' => 'Failed validation: '], 500);
}
return StorageHelper::downloader($file);
}
}
}
}
@@ -131,7 +131,7 @@ class ConsumablesFilesController extends Controller
* @return \Symfony\Consumable\HttpFoundation\Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show($consumableId = null, $fileId = null, $download = true)
public function show($consumableId = null, $fileId = null)
{
$consumable = Consumable::find($consumableId);
@@ -155,22 +155,19 @@ class ConsumablesFilesController extends Controller
->header('Content-Type', 'text/plain');
} else {
// Display the file inline
if (request('inline') == 'true') {
$headers = [
'Content-Disposition' => 'inline',
];
return Storage::download($file, $log->filename, $headers);
}
// We have to override the URL stuff here, since local defaults in Laravel's Flysystem
// won't work, as they're not accessible via the web
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(['error' => 'Failed validation: '], 500);
}
return StorageHelper::downloader($file);
}
}
}
+2 -2
View File
@@ -30,8 +30,8 @@ class LabelsController extends Controller
$exampleAsset = new Asset();
$exampleAsset->id = 999999;
$exampleAsset->name = 'AST-AB-CD-1234';
$exampleAsset->asset_tag = 'TCA-00001';
$exampleAsset->name = 'JEN-867-5309';
$exampleAsset->asset_tag = '100001';
$exampleAsset->serial = 'SN9876543210';
$exampleAsset->company = new Company();
@@ -76,7 +76,7 @@ class LicenseCheckinController extends Controller
// Declare the rules for the form validation
$rules = [
'note' => 'string|nullable',
'notes' => 'string|nullable',
];
// Create a new validator instance from our validation rules
@@ -97,6 +97,7 @@ class LicenseCheckinController extends Controller
// Update the asset data
$licenseSeat->assigned_to = null;
$licenseSeat->asset_id = null;
$licenseSeat->notes = $request->input('notes');
// Was the asset updated?
if ($licenseSeat->save()) {
@@ -128,6 +129,13 @@ class LicenseCheckinController extends Controller
$license = License::findOrFail($licenseId);
$this->authorize('checkin', $license);
if (! $license->reassignable) {
// Not allowed to checkin
Session::flash('error', 'License not reassignable.');
return redirect()->back()->withInput();
}
$licenseSeatsByUser = LicenseSeat::where('license_id', '=', $licenseId)
->whereNotNull('assigned_to')
->with('user')
@@ -63,6 +63,7 @@ class LicenseCheckoutController extends Controller
$licenseSeat = $this->findLicenseSeatToCheckout($license, $seatId);
$licenseSeat->user_id = Auth::id();
$licenseSeat->notes = $request->input('notes');
$checkoutMethod = 'checkoutTo'.ucwords(request('checkout_to_type'));
@@ -152,21 +152,19 @@ class LicenseFilesController extends Controller
->header('Content-Type', 'text/plain');
} else {
if (request('inline') == 'true') {
$headers = [
'Content-Disposition' => 'inline',
];
return Storage::download($file, $log->filename, $headers);
}
// We have to override the URL stuff here, since local defaults in Laravel's Flysystem
// won't work, as they're not accessible via the web
if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer?
return StorageHelper::downloader($file);
} else {
if ($download != 'true') {
\Log::debug('display the file');
if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones
return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file)));
}
return JsonResponse::create(['error' => 'Failed validation: '], 500);
}
return StorageHelper::downloader($file);
}
}
+24 -1
View File
@@ -545,6 +545,10 @@ class ReportsController extends Controller
$header[] = trans('admin/hardware/table.checkout_date');
}
if ($request->filled('checkin_date')) {
$header[] = trans('admin/hardware/table.last_checkin_date');
}
if ($request->filled('expected_checkin')) {
$header[] = trans('admin/hardware/form.expected_checkin');
}
@@ -651,6 +655,14 @@ class ReportsController extends Controller
$assets->whereBetween('assets.last_checkout', [$checkout_start, $checkout_end]);
}
if (($request->filled('checkin_date_start'))) {
$assets->whereBetween('last_checkin', [
Carbon::parse($request->input('checkin_date_start'))->startOfDay(),
// use today's date is `checkin_date_end` is not provided
Carbon::parse($request->input('checkin_date_end', now()))->endOfDay(),
]);
}
if (($request->filled('expected_checkin_start')) && ($request->filled('expected_checkin_end'))) {
$assets->whereBetween('assets.expected_checkin', [$request->input('expected_checkin_start'), $request->input('expected_checkin_end')]);
}
@@ -835,6 +847,12 @@ class ReportsController extends Controller
$row[] = ($asset->last_checkout) ? $asset->last_checkout : '';
}
if ($request->filled('checkin_date')) {
$row[] = ($asset->last_checkin)
? Carbon::parse($asset->last_checkin)->format('Y-m-d')
: '';
}
if ($request->filled('expected_checkin')) {
$row[] = ($asset->expected_checkin) ? $asset->expected_checkin : '';
}
@@ -1003,7 +1021,12 @@ class ReportsController extends Controller
$assetsForReport = $acceptances
->filter(function ($acceptance) {
return $acceptance->checkoutable_type == 'App\Models\Asset';
$acceptance_checkoutable_flag = false;
if ($acceptance->checkoutable){
$acceptance_checkoutable_flag = $acceptance->checkoutable->checkedOutToUser();
}
return $acceptance->checkoutable_type == 'App\Models\Asset' && $acceptance_checkoutable_flag;
})
->map(function($acceptance) {
return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];
@@ -590,6 +590,7 @@ class SettingsController extends Controller
$setting->date_display_format = $request->input('date_display_format');
$setting->time_display_format = $request->input('time_display_format');
$setting->digit_separator = $request->input('digit_separator');
$setting->name_display_format = $request->input('name_display_format');
if ($setting->save()) {
return redirect()->route('settings.index')
@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Users;
use App\Helpers\StorageHelper;
use App\Http\Controllers\Controller;
use App\Http\Requests\AssetFileRequest;
use App\Models\Actionlog;
@@ -139,18 +140,25 @@ class UserFilesController extends Controller
// the license is valid
if (isset($user->id)) {
$this->authorize('view', $user);
$log = Actionlog::find($fileId);
$file = $log->get_src('users');
return Response::download($file); //FIXME this doesn't use the new StorageHelper yet, but it's complicated...
// Display the file inline
if (request('inline') == 'true') {
$headers = [
'Content-Disposition' => 'inline',
];
return Storage::download('private_uploads/users/'.$log->filename, $log->filename, $headers);
}
return Storage::download('private_uploads/users/'.$log->filename);
}
// Prepare the error message
$error = trans('admin/users/message.user_not_found', ['id' => $userId]);
// Redirect to the licence management page
return redirect()->route('users.index')->with('error', $error);
// Redirect to the user management page if the user doesn't exist
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', ['id' => $userId]));
}
}
+16
View File
@@ -275,6 +275,7 @@ class Importer extends Component
'license_email' => trans('admin/licenses/form.to_email'),
'license_name' => trans('admin/licenses/form.to_name'),
'purchase_order' => trans('admin/licenses/form.purchase_order'),
'order_number' => trans('general.order_number'),
'reassignable' => trans('admin/licenses/form.reassignable'),
'seats' => trans('admin/licenses/form.seats'),
'notes' => trans('general.notes'),
@@ -484,8 +485,17 @@ class Importer extends Component
public function selectFile($id)
{
$this->clearMessage();
$this->activeFile = Import::find($id);
if (!$this->activeFile) {
$this->message = trans('admin/hardware/message.import.file_missing');
$this->message_type = 'danger';
return;
}
$this->field_map = null;
foreach($this->activeFile->header_row as $element) {
if(isset($this->activeFile->field_map[$element])) {
@@ -520,6 +530,12 @@ class Importer extends Component
}
}
public function clearMessage()
{
$this->message = null;
$this->message_type = null;
}
public function render()
{
$this->files = Import::orderBy('id','desc')->get(); //HACK - slows down renders.
+20 -16
View File
@@ -12,7 +12,7 @@ class SlackSettingsForm extends Component
public $webhook_endpoint;
public $webhook_channel;
public $webhook_botname;
public $isDisabled ='' ;
public $isDisabled ='disabled' ;
public $webhook_name;
public $webhook_link;
public $webhook_placeholder;
@@ -22,11 +22,17 @@ class SlackSettingsForm extends Component
public Setting $setting;
public $webhook_endpoint_rules;
protected $rules = [
'webhook_endpoint' => 'url|required_with:webhook_channel|starts_with:https://hooks.slack.com/services|nullable',
'webhook_endpoint' => 'required_with:webhook_channel|starts_with:http://,https://,ftp://,irc://,https://hooks.slack.com/services/|url|nullable',
'webhook_channel' => 'required_with:webhook_endpoint|starts_with:#|nullable',
'webhook_botname' => 'string|nullable',
];
public $messages = [
'webhook_endpoint.starts_with' => 'your webhook endpoint should begin with http://, https:// or other protocol.',
];
public function mount() {
$this->webhook_text= [
@@ -55,9 +61,7 @@ class SlackSettingsForm extends Component
$this->webhook_botname = $this->setting->webhook_botname;
$this->webhook_options = $this->setting->webhook_selected;
if($this->setting->webhook_selected == 'general'){
$this->isDisabled='';
}
if($this->setting->webhook_endpoint != null && $this->setting->webhook_channel != null){
$this->isDisabled= '';
}
@@ -65,9 +69,8 @@ class SlackSettingsForm extends Component
}
public function updated($field) {
if($this->webhook_selected != 'general') {
$this->validateOnly($field, $this->rules);
}
}
public function updatedWebhookSelected() {
@@ -82,7 +85,6 @@ class SlackSettingsForm extends Component
}
private function isButtonDisabled() {
if($this->webhook_selected == 'slack') {
if (empty($this->webhook_endpoint)) {
$this->isDisabled = 'disabled';
$this->save_button = trans('admin/settings/general.webhook_presave');
@@ -91,8 +93,6 @@ class SlackSettingsForm extends Component
$this->isDisabled = 'disabled';
$this->save_button = trans('admin/settings/general.webhook_presave');
}
}
}
public function render()
@@ -108,6 +108,7 @@ class SlackSettingsForm extends Component
'defaults' => [
'exceptions' => false,
],
'allow_redirects' => false,
]);
$payload = json_encode(
@@ -116,18 +117,23 @@ class SlackSettingsForm extends Component
'text' => trans('general.webhook_test_msg', ['app' => $this->webhook_name]),
'username' => e($this->webhook_botname),
'icon_emoji' => ':heart:',
]);
try {
$test = $webhook->post($this->webhook_endpoint, ['body' => $payload]);
$webhook->post($this->webhook_endpoint, ['body' => $payload]);
if(($test->getStatusCode() == 302)||($test->getStatusCode() == 301)){
return session()->flash('error' , trans('admin/settings/message.webhook.error_redirect', ['endpoint' => $this->webhook_endpoint]));
}
$this->isDisabled='';
$this->save_button = trans('general.save');
return session()->flash('success' , 'Your '.$this->webhook_name.' Integration works!');
return session()->flash('success' , trans('admin/settings/message.webhook.success', ['webhook_name' => $this->webhook_name]));
} catch (\Exception $e) {
$this->isDisabled= 'disabled';
$this->isDisabled='disabled';
$this->save_button = trans('admin/settings/general.webhook_presave');
return session()->flash('error' , trans('admin/settings/message.webhook.error', ['error_message' => $e->getMessage(), 'app' => $this->webhook_name]));
}
@@ -158,9 +164,7 @@ class SlackSettingsForm extends Component
if (Helper::isDemoMode()) {
session()->flash('error',trans('general.feature_disabled'));
} else {
if ($this->webhook_selected != 'general') {
$this->validate($this->rules);
}
$this->validate($this->rules);
$this->setting->webhook_selected = $this->webhook_selected;
$this->setting->webhook_endpoint = $this->webhook_endpoint;
+1
View File
@@ -32,6 +32,7 @@ class SaveUserRequest extends FormRequest
public function rules()
{
$rules = [
'department_id' => 'nullable|exists:departments,id',
'manager_id' => 'nullable|exists:users,id',
];
+109 -2
View File
@@ -3,7 +3,12 @@ namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Actionlog;
use App\Models\CustomField;
use App\Models\Setting;
use App\Models\Company;
use App\Models\Supplier;
use App\Models\Location;
use App\Models\AssetModel;
use Illuminate\Database\Eloquent\Collection;
class ActionlogsTransformer
@@ -38,21 +43,46 @@ class ActionlogsTransformer
public function transformActionlog (Actionlog $actionlog, $settings = null)
{
$icon = $actionlog->present()->icon();
$custom_fields = CustomField::all();
if ($actionlog->filename!='') {
$icon = e(\App\Helpers\Helper::filetype_icon($actionlog->filename));
$icon = Helper::filetype_icon($actionlog->filename);
}
// This is necessary since we can't escape special characters within a JSON object
if (($actionlog->log_meta) && ($actionlog->log_meta!='')) {
$meta_array = json_decode($actionlog->log_meta);
$clean_meta = [];
if ($meta_array) {
foreach ($meta_array as $fieldname => $fieldata) {
$clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old);
$clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new);
// this is a custom field
if (str_starts_with($fieldname, '_snipeit_')) {
foreach ($custom_fields as $custom_field) {
if ($custom_field->db_column == $fieldname) {
if ($custom_field->field_encrypted == '1') {
$clean_meta[$fieldname]['old'] = "************";
$clean_meta[$fieldname]['new'] = "************";
}
}
}
}
}
}
$clean_meta= $this->changedInfo($clean_meta);
}
$file_url = '';
@@ -115,9 +145,10 @@ class ActionlogsTransformer
'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null,
'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
];
//\Log::info("Clean Meta is: ".print_r($clean_meta,true));
// \Log::info("Clean Meta is: ".print_r($clean_meta,true));
//dd($array);
return $array;
}
@@ -132,6 +163,82 @@ class ActionlogsTransformer
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
/**
* This takes the ids of the changed attributes and returns the names instead for the history view of an Asset
*
* @param array $clean_meta
* @return array
*/
public function changedInfo(array $clean_meta)
{ $location = Location::withTrashed()->get();
$supplier = Supplier::withTrashed()->get();
$model = AssetModel::withTrashed()->get();
$company = Company::get();
if(array_key_exists('rtd_location_id',$clean_meta)) {
$clean_meta['rtd_location_id']['old'] = $clean_meta['rtd_location_id']['old'] ? "[id: ".$clean_meta['rtd_location_id']['old']."] ". e($location->find($clean_meta['rtd_location_id']['old'])->name) : trans('general.unassigned');
$clean_meta['rtd_location_id']['new'] = $clean_meta['rtd_location_id']['new'] ? "[id: ".$clean_meta['rtd_location_id']['new']."] ". e($location->find($clean_meta['rtd_location_id']['new'])->name) : trans('general.unassigned');
$clean_meta['Default Location'] = $clean_meta['rtd_location_id'];
unset($clean_meta['rtd_location_id']);
}
if (array_key_exists('location_id', $clean_meta)) {
$clean_meta['location_id']['old'] = $clean_meta['location_id']['old'] ? "[id: ".$clean_meta['location_id']['old']."] ".e($location->find($clean_meta['location_id']['old'])->name): trans('general.unassigned');
$clean_meta['location_id']['new'] = $clean_meta['location_id']['new'] ? "[id: ".$clean_meta['location_id']['new']."] ".e($location->find($clean_meta['location_id']['new'])->name) : trans('general.unassigned');
$clean_meta['Current Location'] = $clean_meta['location_id'];
unset($clean_meta['location_id']);
}
if(array_key_exists('model_id', $clean_meta)) {
$oldModel = $model->find($clean_meta['model_id']['old']);
$oldModelName = $oldModel ? e($oldModel->name) : trans('admin/models/message.deleted');
$newModel = $model->find($clean_meta['model_id']['new']);
$newModelName = $newModel ? e($newModel->name) : trans('admin/models/message.deleted');
$clean_meta['model_id']['old'] = "[id: ".$clean_meta['model_id']['old']."] ".$oldModelName;
$clean_meta['model_id']['new'] = "[id: ".$clean_meta['model_id']['new']."] ".$newModelName; /** model is required at asset creation */
$clean_meta['Model'] = $clean_meta['model_id'];
unset($clean_meta['model_id']);
}
if(array_key_exists('company_id', $clean_meta)) {
$oldCompany = $company->find($clean_meta['company_id']['old']);
$oldCompanyName = $oldCompany ? e($oldCompany->name) : trans('admin/company/message.deleted');
$newCompany = $company->find($clean_meta['company_id']['new']);
$newCompanyName = $newCompany ? e($newCompany->name) : trans('admin/company/message.deleted');
$clean_meta['company_id']['old'] = $clean_meta['company_id']['old'] ? "[id: ".$clean_meta['company_id']['old']."] ". $oldCompanyName : trans('general.unassigned');
$clean_meta['company_id']['new'] = $clean_meta['company_id']['new'] ? "[id: ".$clean_meta['company_id']['new']."] ". $newCompanyName : trans('general.unassigned');
$clean_meta['Company'] = $clean_meta['company_id'];
unset($clean_meta['company_id']);
}
if(array_key_exists('supplier_id', $clean_meta)) {
$oldSupplier = $supplier->find($clean_meta['supplier_id']['old']);
$oldSupplierName = $oldSupplier ? e($oldSupplier->name) : trans('admin/suppliers/message.deleted');
$newSupplier = $supplier->find($clean_meta['supplier_id']['new']);
$newSupplierName = $newSupplier ? e($newSupplier->name) : trans('admin/suppliers/message.deleted');
$clean_meta['supplier_id']['old'] = $clean_meta['supplier_id']['old'] ? "[id: ".$clean_meta['supplier_id']['old']."] ". $oldSupplierName : trans('general.unassigned');
$clean_meta['supplier_id']['new'] = $clean_meta['supplier_id']['new'] ? "[id: ".$clean_meta['supplier_id']['new']."] ". $newSupplierName : trans('general.unassigned');
$clean_meta['Supplier'] = $clean_meta['supplier_id'];
unset($clean_meta['supplier_id']);
}
if(array_key_exists('asset_eol_date', $clean_meta)) {
$clean_meta['EOL date'] = $clean_meta['asset_eol_date'];
unset($clean_meta['asset_eol_date']);
}
return $clean_meta;
}
@@ -47,6 +47,7 @@ class AssetModelsTransformer
] : null,
'image' => ($assetmodel->image != '') ? Storage::disk('public')->url('models/'.e($assetmodel->image)) : null,
'model_number' => e($assetmodel->model_number),
'min_amt' => ($assetmodel->min_amt) ? (int) $assetmodel->min_amt : null,
'depreciation' => ($assetmodel->depreciation) ? [
'id' => (int) $assetmodel->depreciation->id,
'name'=> e($assetmodel->depreciation->name),
+2 -2
View File
@@ -26,8 +26,8 @@ class LabelsTransformer
'name' => $label->getName(),
'unit' => $label->getUnit(),
'width' => $label->getWidth(),
'height' => $label->getHeight(),
'width' => number_format($label->getWidth(), 2),
'height' => number_format($label->getHeight(), 2),
'margin_top' => $label->getMarginTop(),
'margin_bottom' => $label->getMarginBottom(),
@@ -45,6 +45,7 @@ class LicenseSeatsTransformer
'name'=> e($seat->location()->name),
] : null,
'reassignable' => (bool) $seat->license->reassignable,
'notes' => e($seat->notes),
'user_can_checkout' => (($seat->assigned_to == '') && ($seat->asset_id == '')),
];
+1 -1
View File
@@ -24,7 +24,7 @@ class UsersTransformer
$array = [
'id' => (int) $user->id,
'avatar' => e($user->present()->gravatar),
'name' => e($user->first_name).' '.e($user->last_name),
'name' => e($user->getFullNameAttribute()),
'first_name' => e($user->first_name),
'last_name' => e($user->last_name),
'username' => e($user->username),
+6 -8
View File
@@ -3,7 +3,9 @@
namespace App\Importer;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Statuslabel;
use Carbon\Carbon;
class AssetImporter extends ItemImporter
{
@@ -63,6 +65,7 @@ class AssetImporter extends ItemImporter
$asset_tag = Asset::autoincrement_asset();
}
$asset = Asset::where(['asset_tag'=> (string) $asset_tag])->first();
if ($asset) {
if (! $this->updating) {
@@ -116,12 +119,7 @@ class AssetImporter extends ItemImporter
if (isset($this->item['next_audit_date'])) {
$item['next_audit_date'] = $this->item['next_audit_date'];
}
$item['asset_eol_date'] = null;
if (isset($this->item['asset_eol_date'])) {
$item['asset_eol_date'] = $this->item['asset_eol_date'];
}
if ($editingAsset) {
$asset->update($item);
} else {
@@ -134,9 +132,9 @@ class AssetImporter extends ItemImporter
$asset->{$custom_field} = $val;
}
}
if ($asset->save()) {
$asset->logCreate(trans('general.importer.import_note'));
$this->log('Asset '.$this->item['name'].' with serial number '.$this->item['serial'].' was created');
+1 -1
View File
@@ -28,7 +28,7 @@ abstract class Importer
/**
* Default Map of item fields->csv names
*
* This has been moved into Livewire/Importer.php to be more granular.
* This has been moved into app/Http/Livewire/Importer.php to be more granular.
* @todo - remove references to this property since we don't use it anymore.
*
* @var array
+10 -2
View File
@@ -10,6 +10,8 @@ use App\Models\Manufacturer;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\User;
use Carbon\CarbonImmutable;
use Illuminate\Support\Facades\Log;
class ItemImporter extends Importer
{
@@ -88,8 +90,14 @@ class ItemImporter extends Importer
}
$this->item['asset_eol_date'] = null;
if ($this->findCsvMatch($row, 'asset_eol_date') != '') {
$this->item['asset_eol_date'] = date('Y-m-d', strtotime($this->findCsvMatch($row, 'asset_eol_date')));
if($this->findCsvMatch($row, 'asset_eol_date') != '') {
$csvMatch = $this->findCsvMatch($row, 'asset_eol_date');
try {
$this->item['asset_eol_date'] = CarbonImmutable::parse($csvMatch)->format('Y-m-d');
} catch (\Exception $e) {
Log::info($e->getMessage());
$this->log('Unable to parse date: '.$csvMatch);
}
}
$this->item['qty'] = $this->findCsvMatch($row, 'quantity');
+1
View File
@@ -65,6 +65,7 @@ class LicenseImporter extends ItemImporter
$this->item['license_name'] = $this->findCsvMatch($row, 'license_name');
$this->item['maintained'] = $this->findCsvMatch($row, 'maintained');
$this->item['purchase_order'] = $this->findCsvMatch($row, 'purchase_order');
$this->item['order_number'] = $this->findCsvMatch($row, 'order_number');
$this->item['reassignable'] = $this->findCsvMatch($row, 'reassignable');
$this->item['manufacturer'] = $this->createOrFetchManufacturer($this->findCsvMatch($row, 'manufacturer'));
+12 -8
View File
@@ -79,13 +79,15 @@ class CheckoutableListener
/**
* Send the appropriate notification
*/
$acceptances = CheckoutAcceptance::where('checkoutable_id', $event->checkoutable->id)
->where('assigned_to_id', $event->checkedOutTo->id)
->get();
if ($event->checkedOutTo && $event->checkoutable){
$acceptances = CheckoutAcceptance::where('checkoutable_id', $event->checkoutable->id)
->where('assigned_to_id', $event->checkedOutTo->id)
->get();
foreach($acceptances as $acceptance){
if($acceptance->isPending()){
$acceptance->delete();
foreach($acceptances as $acceptance){
if($acceptance->isPending()){
$acceptance->delete();
}
}
}
@@ -142,9 +144,11 @@ class CheckoutableListener
$notifiables = collect();
/**
* Notify the user who checked out the item
* Notify who checked out the item as long as the model can route notifications
*/
$notifiables->push($event->checkedOutTo);
if (method_exists($event->checkedOutTo, 'routeNotificationFor')) {
$notifiables->push($event->checkedOutTo);
}
/**
* Notify Admin users if the settings is activated
+2 -2
View File
@@ -33,7 +33,7 @@ class LogListener
*/
public function onCheckoutableCheckedIn(CheckoutableCheckedIn $event)
{
$event->checkoutable->logCheckin($event->checkedOutTo, $event->note, $event->action_date);
$event->checkoutable->logCheckin($event->checkedOutTo, $event->note, $event->action_date, $event->originalValues);
}
/**
@@ -46,7 +46,7 @@ class LogListener
*/
public function onCheckoutableCheckedOut(CheckoutableCheckedOut $event)
{
$event->checkoutable->logCheckout($event->note, $event->checkedOutTo, $event->checkoutable->last_checkout);
$event->checkoutable->logCheckout($event->note, $event->checkedOutTo, $event->checkoutable->last_checkout, $event->originalValues);
}
/**
+16
View File
@@ -349,6 +349,22 @@ class Accessory extends SnipeModel
return (int) $remaining;
}
/**
* Run after the checkout acceptance was declined by the user
*
* @param User $acceptedBy
* @param string $signature
*/
public function declinedCheckout(User $declinedBy, $signature)
{
if (is_null($accessory_user = \DB::table('accessories_users')->where('assigned_to', $declinedBy->id)->where('accessory_id', $this->id)->latest('created_at'))) {
// Redirect to the accessory management page with error
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
}
$accessory_user->limit(1)->delete();
}
/**
* Query builder scope to order on company
*
+16 -3
View File
@@ -72,7 +72,10 @@ class Asset extends Depreciable
protected $casts = [
'purchase_date' => 'date',
'asset_eol_date' => 'date',
'eol_explicit' => 'boolean',
'last_checkout' => 'datetime',
'last_checkin' => 'datetime',
'expected_checkin' => 'date',
'last_audit_date' => 'datetime',
'next_audit_date' => 'date',
@@ -82,7 +85,6 @@ class Asset extends Depreciable
'location_id' => 'integer',
'rtd_company_id' => 'integer',
'supplier_id' => 'integer',
'byod' => 'boolean',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
@@ -104,7 +106,9 @@ class Asset extends Depreciable
'serial' => 'unique_serial|nullable',
'purchase_cost' => 'numeric|nullable|gte:0',
'supplier_id' => 'exists:suppliers,id|nullable',
'asset_eol_date' => 'date|max:10|min:10|nullable',
'asset_eol_date' => 'date|nullable',
'eol_explicit' => 'boolean|nullable',
'byod' => 'boolean',
];
/**
@@ -135,8 +139,10 @@ class Asset extends Depreciable
'expected_checkin',
'byod',
'asset_eol_date',
'eol_explicit',
'last_audit_date',
'next_audit_date',
'asset_eol_date',
];
use Searchable;
@@ -332,6 +338,13 @@ class Asset extends Depreciable
}
}
$originalValues = $this->getRawOriginal();
// attempt to detect change in value if different from today's date
if ($checkout_at && strpos($checkout_at, date('Y-m-d')) === false) {
$originalValues['action_date'] = date('Y-m-d H:i:s');
}
if ($this->save()) {
if (is_int($admin)) {
$checkedOutBy = User::findOrFail($admin);
@@ -340,7 +353,7 @@ class Asset extends Depreciable
} else {
$checkedOutBy = Auth::user();
}
event(new CheckoutableCheckedOut($this, $target, $checkedOutBy, $note));
event(new CheckoutableCheckedOut($this, $target, $checkedOutBy, $note, $originalValues));
$this->increment('checkout_counter', 1);
+12
View File
@@ -29,6 +29,7 @@ class AssetModel extends SnipeModel
protected $rules = [
'name' => 'required|min:1|max:255',
'model_number' => 'max:255|nullable',
'min_amt' => 'integer|min:0|nullable',
'category_id' => 'required|integer|exists:categories,id',
'manufacturer_id' => 'integer|exists:manufacturers,id|nullable',
'eol' => 'integer:min:0|max:240|nullable',
@@ -65,6 +66,7 @@ class AssetModel extends SnipeModel
'fieldset_id',
'image',
'manufacturer_id',
'min_amt',
'model_number',
'name',
'notes',
@@ -150,6 +152,11 @@ class AssetModel extends SnipeModel
{
return $this->belongsTo(\App\Models\CustomFieldset::class, 'fieldset_id');
}
public function customFields()
{
return $this->fieldset()->first()->fields();
}
/**
* Establishes the model -> custom field default values relationship
@@ -284,4 +291,9 @@ class AssetModel extends SnipeModel
{
return $query->leftJoin('categories', 'models.category_id', '=', 'categories.id')->orderBy('categories.name', $order);
}
public function scopeOrderFieldset($query, $order)
{
return $query->leftJoin('custom_fieldsets', 'models.fieldset_id', '=', 'custom_fieldsets.id')->orderBy('custom_fieldsets.name', $order);
}
}
+5 -1
View File
@@ -9,7 +9,6 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Validation\Rule;
use Schema;
use Watson\Validating\ValidatingTrait;
class CustomField extends Model
{
use HasFactory;
@@ -182,6 +181,11 @@ class CustomField extends Model
{
return $this->belongsToMany(\App\Models\CustomFieldset::class);
}
public function assetModels()
{
return $this->fieldset()->with('models')->get()->pluck('models')->flatten()->unique('id');
}
/**
* Establishes the customfield -> admin user relationship
+1
View File
@@ -9,6 +9,7 @@ use Watson\Validating\ValidatingTrait;
class Department extends SnipeModel
{
use CompanyableTrait;
use HasFactory;
/**
+15 -5
View File
@@ -37,7 +37,7 @@ class DefaultLabel extends RectangleSheet
private int $columns;
private int $rows;
public function __construct() {
$settings = Setting::getSettings();
@@ -62,6 +62,16 @@ class DefaultLabel extends RectangleSheet
$this->columns = ($usableWidth + $this->labelSpacingH) / ($this->labelWidth + $this->labelSpacingH);
$this->rows = ($usableHeight + $this->labelSpacingV) / ($this->labelHeight + $this->labelSpacingV);
// Make sure the columns and rows are never zero, since that scenario should never happen
if ($this->columns == 0) {
$this->columns = 1;
}
if ($this->rows == 0) {
$this->rows = 1;
}
}
public function getUnit() { return 'in'; }
@@ -76,7 +86,7 @@ class DefaultLabel extends RectangleSheet
public function getColumns() { return $this->columns; }
public function getRows() { return $this->rows; }
public function getLabelBorder() { return 0.01; }
public function getLabelBorder() { return 0; }
public function getLabelWidth() { return $this->labelWidth; }
public function getLabelHeight() { return $this->labelHeight; }
@@ -85,7 +95,7 @@ class DefaultLabel extends RectangleSheet
public function getLabelMarginBottom() { return 0; }
public function getLabelMarginLeft() { return 0; }
public function getLabelMarginRight() { return 0; }
public function getLabelColumnSpacing() { return $this->labelSpacingH; }
public function getLabelRowSpacing() { return $this->labelSpacingV; }
@@ -106,7 +116,7 @@ class DefaultLabel extends RectangleSheet
$textY = 0;
$textX1 = 0;
$textX2 = $this->getLabelWidth();
// 1D Barcode
if ($record->get('barcode1d')) {
static::write1DBarcode(
@@ -115,7 +125,7 @@ class DefaultLabel extends RectangleSheet
$this->getLabelWidth() - 0.1, self::BARCODE1D_SIZE
);
}
// 2D Barcode
if ($record->get('barcode2d')) {
static::write2DBarcode(
+3 -1
View File
@@ -21,6 +21,8 @@ class Field {
public static function makeArray(Field $field, Asset $asset) {
return $field->getOptions()
// filter out any FieldOptions that are accidentally null
->filter()
->map(fn($option) => $option->toArray($asset))
->filter(fn($result) => $result['value'] != null);
}
@@ -36,4 +38,4 @@ class Field {
->map(fn($optionString) => FieldOption::fromString($optionString));
return $field;
}
}
}
+6 -1
View File
@@ -7,6 +7,7 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\File;
use TCPDF;
use TCPDF_STATIC;
use TypeError;
/**
* Model for Labels.
@@ -370,7 +371,11 @@ abstract class Label
*/
public final function write1DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height) {
if (empty($value)) return;
$pdf->write1DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]);
try {
$pdf->write1DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]);
} catch (\Exception|TypeError $e) {
\Log::debug('The 1D barcode ' . $value . ' is not compliant with the barcode type '. $type);
}
}
/**
@@ -0,0 +1,19 @@
<?php
namespace App\Models\Labels\Tapes\Dymo;
use App\Helpers\Helper;
use App\Models\Labels\Label;
abstract class LabelWriter extends Label
{
private const HEIGHT = 1.15;
private const MARGIN_SIDES = 0.1;
private const MARGIN_ENDS = 0.1;
public function getHeight() { return Helper::convertUnit(self::HEIGHT, 'in', $this->getUnit()); }
public function getMarginTop() { return Helper::convertUnit(self::MARGIN_SIDES, 'in', $this->getUnit()); }
public function getMarginBottom() { return Helper::convertUnit(self::MARGIN_SIDES, 'in', $this->getUnit());}
public function getMarginLeft() { return Helper::convertUnit(self::MARGIN_ENDS, 'in', $this->getUnit()); }
public function getMarginRight() { return Helper::convertUnit(self::MARGIN_ENDS, 'in', $this->getUnit()); }
}
@@ -0,0 +1,90 @@
<?php
namespace App\Models\Labels\Tapes\Dymo;
class LabelWriter_30252 extends LabelWriter
{
private const BARCODE_MARGIN = 1.80;
private const TAG_SIZE = 2.80;
private const TITLE_SIZE = 2.80;
private const TITLE_MARGIN = 0.50;
private const LABEL_SIZE = 2.00;
private const LABEL_MARGIN = - 0.35;
private const FIELD_SIZE = 3.20;
private const FIELD_MARGIN = 0.15;
public function getUnit() { return 'mm'; }
public function getWidth() { return 96.52; }
public function getSupportAssetTag() { return true; }
public function getSupport1DBarcode() { return true; }
public function getSupport2DBarcode() { return true; }
public function getSupportFields() { return 3; }
public function getSupportLogo() { return false; }
public function getSupportTitle() { return true; }
public function preparePDF($pdf) {}
public function write($pdf, $record) {
$pa = $this->getPrintableArea();
$currentX = $pa->x1;
$currentY = $pa->y1;
$usableWidth = $pa->w;
$barcodeSize = $pa->h - self::TAG_SIZE;
if ($record->has('barcode2d')) {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freemono', 'b', self::TAG_SIZE, 'C',
$barcodeSize, self::TAG_SIZE, true, 0
);
static::write2DBarcode(
$pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type,
$currentX, $currentY,
$barcodeSize, $barcodeSize
);
$currentX += $barcodeSize + self::BARCODE_MARGIN;
$usableWidth -= $barcodeSize + self::BARCODE_MARGIN;
} else {
static::writeText(
$pdf, $record->get('tag'),
$pa->x1, $pa->y2 - self::TAG_SIZE,
'freemono', 'b', self::TAG_SIZE, 'R',
$usableWidth, self::TAG_SIZE, true, 0
);
}
if ($record->has('title')) {
static::writeText(
$pdf, $record->get('title'),
$currentX, $currentY,
'freesans', '', self::TITLE_SIZE, 'L',
$usableWidth, self::TITLE_SIZE, true, 0
);
$currentY += self::TITLE_SIZE + self::TITLE_MARGIN;
}
foreach ($record->get('fields') as $field) {
static::writeText(
$pdf, $field['label'],
$currentX, $currentY,
'freesans', '', self::LABEL_SIZE, 'L',
$usableWidth, self::LABEL_SIZE, true, 0, 0
);
$currentY += self::LABEL_SIZE + self::LABEL_MARGIN;
static::writeText(
$pdf, $field['value'],
$currentX, $currentY,
'freemono', 'B', self::FIELD_SIZE, 'L',
$usableWidth, self::FIELD_SIZE, true, 0, 0.3
);
$currentY += self::FIELD_SIZE + self::FIELD_MARGIN;
}
}
}
+2 -5
View File
@@ -252,13 +252,10 @@ class Ldap extends Model
$user->last_name = $item['lastname'];
$user->username = $item['username'];
$user->email = $item['email'];
$user->password = $user->noPassword();
if (Setting::getSettings()->ldap_pw_sync == '1') {
$user->password = bcrypt($password);
} else {
$pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 25);
$user->password = bcrypt($pass);
}
$user->activated = 1;
@@ -268,7 +265,7 @@ class Ldap extends Model
if ($user->save()) {
return $user;
} else {
LOG::debug('Could not create user.'.$user->getErrors());
\Log::debug('Could not create user.'.$user->getErrors());
throw new Exception('Could not create user: '.$user->getErrors());
}
}
+18 -9
View File
@@ -323,7 +323,10 @@ class License extends Depreciable
*/
public function checkin_email()
{
return $this->category->checkin_email;
if ($this->category) {
return $this->category->checkin_email;
}
return false;
}
/**
@@ -335,7 +338,11 @@ class License extends Depreciable
*/
public function requireAcceptance()
{
return $this->category->require_acceptance;
if ($this->category) {
return $this->category->require_acceptance;
}
return false;
}
/**
@@ -348,14 +355,16 @@ class License extends Depreciable
*/
public function getEula()
{
if ($this->category->eula_text) {
return Helper::parseEscapedMarkedown($this->category->eula_text);
} elseif ($this->category->use_default_eula == '1') {
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
} else {
return false;
if ($this->category){
if ($this->category->eula_text) {
return Helper::parseEscapedMarkedown($this->category->eula_text);
} elseif ($this->category->use_default_eula == '1') {
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
}
}
return false;
}
/**
+4 -1
View File
@@ -48,7 +48,10 @@ class LicenseSeat extends SnipeModel implements ICompanyableChild
*/
public function requireAcceptance()
{
return $this->license->category->require_acceptance;
if ($this->license && $this->license->category) {
return $this->license->category->require_acceptance;
}
return false;
}
public function getEula()
+36 -6
View File
@@ -23,7 +23,7 @@ trait Loggable
* @since [v3.4]
* @return \App\Models\Actionlog
*/
public function logCheckout($note, $target, $action_date = null)
public function logCheckout($note, $target, $action_date = null, $originalValues = [])
{
$log = new Actionlog;
$log = $this->determineLogItemType($log);
@@ -62,6 +62,23 @@ trait Loggable
$log->action_date = date('Y-m-d H:i:s');
}
$changed = [];
$originalValues = array_intersect_key($originalValues, array_flip(['action_date','name','status_id','location_id','expected_checkin']));
foreach ($originalValues as $key => $value) {
if ($key == 'action_date' && $value != $action_date) {
$changed[$key]['old'] = $value;
$changed[$key]['new'] = is_string($action_date) ? $action_date : $action_date->format('Y-m-d H:i:s');
} elseif ($value != $this->getAttributes()[$key]) {
$changed[$key]['old'] = $value;
$changed[$key]['new'] = $this->getAttributes()[$key];
}
}
if (!empty($changed)){
$log->log_meta = json_encode($changed);
}
$log->logaction('checkout');
return $log;
@@ -89,7 +106,7 @@ trait Loggable
* @since [v3.4]
* @return \App\Models\Actionlog
*/
public function logCheckin($target, $note, $action_date = null)
public function logCheckin($target, $note, $action_date = null, $originalValues = [])
{
$settings = Setting::getSettings();
$log = new Actionlog;
@@ -114,13 +131,9 @@ trait Loggable
}
}
$log->location_id = null;
$log->note = $note;
$log->action_date = $action_date;
if (! $log->action_date) {
$log->action_date = date('Y-m-d H:i:s');
}
if (! $log->action_date) {
$log->action_date = date('Y-m-d H:i:s');
@@ -130,6 +143,23 @@ trait Loggable
$log->user_id = Auth::user()->id;
}
$changed = [];
$originalValues = array_intersect_key($originalValues, array_flip(['action_date','name','status_id','location_id','rtd_location_id','expected_checkin']));
foreach ($originalValues as $key => $value) {
if ($key == 'action_date' && $value != $action_date) {
$changed[$key]['old'] = $value;
$changed[$key]['new'] = is_string($action_date) ? $action_date : $action_date->format('Y-m-d H:i:s');
} elseif ($value != $this->getAttributes()[$key]) {
$changed[$key]['old'] = $value;
$changed[$key]['new'] = $this->getAttributes()[$key];
}
}
if (!empty($changed)){
$log->log_meta = json_encode($changed);
}
$log->logaction('checkin from');
// $params = [
+1 -2
View File
@@ -9,8 +9,7 @@ class SCIMUser extends User
protected $throwValidationExceptions = true; // we want model-level validation to fully THROW, not just return false
public function __construct(array $attributes = []) {
$attributes['password'] = "*NO PASSWORD*";
// $attributes['activated'] = 1;
$attributes['password'] = $this->noPassword();
parent::__construct($attributes);
}
}
+46 -17
View File
@@ -69,15 +69,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
];
protected $casts = [
'activated' => 'boolean',
'manager_id' => 'integer',
'location_id' => 'integer',
'company_id' => 'integer',
'vip' => 'boolean',
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
'autoassign_licenses' => 'boolean',
];
/**
@@ -103,6 +100,9 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
'state' => 'min:2|max:191|nullable',
'country' => 'min:2|max:191|nullable',
'zip' => 'max:10|nullable',
'vip' => 'boolean',
'remote' => 'boolean',
'activated' => 'boolean',
];
/**
@@ -247,21 +247,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
*/
public function getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
}
$setting = Setting::getSettings();
/**
* Returns the complete name attribute with username
*
* @todo refactor this so it's less repetitive and dumb
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v2.0]
* @return string
*/
public function getCompleteNameAttribute()
{
return $this->last_name.', '.$this->first_name.' ('.$this->username.')';
if ($setting->name_display_format=='last_first') {
return ($this->last_name) ? $this->last_name.' '.$this->first_name : $this->first_name;
}
return $this->last_name ? $this->first_name.' '.$this->last_name : $this->first_name;
}
@@ -465,6 +456,22 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
return $this->belongsToMany(Asset::class, 'checkout_requests', 'user_id', 'requestable_id')->whereNull('canceled_at');
}
/**
* Set a common string when the user has been imported/synced from:
*
* - LDAP without password syncing
* - SCIM
* - CSV import where no password was provided
*
* @author A. Gianotto <snipe@snipe.net>
* @since [v6.2.0]
* @return string
*/
public function noPassword()
{
return "*** NO PASSWORD ***";
}
/**
* Query builder scope to return NOT-deleted users
@@ -759,4 +766,26 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
{
return $this->locale;
}
public function getUserTotalCost(){
$asset_cost= 0;
$license_cost= 0;
$accessory_cost= 0;
foreach ($this->assets as $asset){
$asset_cost += $asset->purchase_cost;
$this->asset_cost = $asset_cost;
}
foreach ($this->licenses as $license){
$license_cost += $license->purchase_cost;
$this->license_cost = $license_cost;
}
foreach ($this->accessories as $accessory){
$accessory_cost += $accessory->purchase_cost;
$this->accessory_cost = $accessory_cost;
}
$this->total_user_cost = ($asset_cost + $accessory_cost + $license_cost);
return $this;
}
}
+28 -2
View File
@@ -6,6 +6,7 @@ use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\Setting;
use Auth;
use Carbon\Carbon;
class AssetObserver
{
@@ -74,9 +75,9 @@ class AssetObserver
$tag = $asset->asset_tag;
$prefix = $settings->auto_increment_prefix;
$number = substr($tag, strlen($prefix));
// IF - auto_increment_assets is on, AND (the prefix matches the start of the tag OR there is no prefix)
// IF - auto_increment_assets is on, AND (there is no prefix OR the prefix matches the start of the tag)
// AND the rest of the string after the prefix is all digits, THEN...
if ($settings->auto_increment_assets && (strpos($tag, $prefix) === 0 || $prefix=='') && preg_match('/\d+/',$number) === 1) {
if ($settings->auto_increment_assets && ($prefix=='' || strpos($tag, $prefix) === 0) && preg_match('/\d+/',$number) === 1) {
// new way of auto-trueing-up auto_increment ID's
$next_asset_tag = intval($number, 10) + 1;
// we had to use 'intval' because the $number could be '01234' and
@@ -119,4 +120,29 @@ class AssetObserver
$logAction->user_id = Auth::id();
$logAction->logaction('delete');
}
public function saving(Asset $asset)
{
//determine if calculated eol and then calculate it - this should only happen on a new asset
if(is_null($asset->asset_eol_date) && !is_null($asset->purchase_date) && !is_null($asset->model->eol)){
$asset->asset_eol_date = $asset->purchase_date->addMonths($asset->model->eol)->format('Y-m-d');
$asset->eol_explicit = false;
}
//determine if explicit and set eol_explit to true
if(!is_null($asset->asset_eol_date) && !is_null($asset->purchase_date)) {
if($asset->model->eol) {
$months = Carbon::parse($asset->asset_eol_date)->diffInMonths($asset->purchase_date);
if($months != $asset->model->eol) {
$asset->eol_explicit = true;
}
}
} elseif (!is_null($asset->asset_eol_date) && is_null($asset->purchase_date)) {
$asset->eol_explicit = true;
}
if ((!is_null($asset->asset_eol_date)) && (!is_null($asset->purchase_date)) && (is_null($asset->model->eol))) {
$asset->eol_explicit = true;
}
}
}
+8
View File
@@ -65,6 +65,14 @@ class AssetModelPresenter extends Presenter
'title' => trans('admin/models/table.modelnumber'),
'visible' => true,
],
[
'field' => 'min_amt',
'searchable' => false,
'sortable' => true,
'switchable' => true,
'title' => trans('mail.min_QTY'),
'visible' => true,
],
[
'field' => 'assets_count',
'searchable' => false,
+8 -8
View File
@@ -3,6 +3,7 @@
namespace App\Presenters;
use App\Models\CustomField;
use Carbon\CarbonImmutable;
use DateTime;
/**
@@ -142,8 +143,8 @@ class AssetPresenter extends Presenter
'formatter' => 'dateDisplayFormatter',
], [
'field' => 'age',
'searchable' => true,
'sortable' => true,
'searchable' => false,
'sortable' => false,
'visible' => false,
'title' => trans('general.age'),
], [
@@ -429,10 +430,7 @@ class AssetPresenter extends Presenter
public function eol_date()
{
if (($this->purchase_date) && ($this->model->model) && ($this->model->model->eol)) {
$date = date_create($this->purchase_date);
date_add($date, date_interval_create_from_date_string($this->model->model->eol.' months'));
return date_format($date, 'Y-m-d');
return CarbonImmutable::parse($this->purchase_date)->addMonths($this->model->model->eol)->format('Y-m-d');
}
}
@@ -548,8 +546,10 @@ class AssetPresenter extends Presenter
public function dynamicWarrantyUrl()
{
$warranty_lookup_url = $this->model->model->manufacturer->warranty_lookup_url;
$url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale,$warranty_lookup_url));
$url = (str_replace('{SERIAL}',$this->model->serial,$url));
$url = (str_replace('{LOCALE}',\App\Models\Setting::getSettings()->locale, $warranty_lookup_url));
$url = (str_replace('{SERIAL}', urlencode($this->model->serial), $url));
$url = (str_replace('{MODEL_NAME}', urlencode($this->model->model->name), $url));
$url = (str_replace('{MODEL_NUMBER}', urlencode($this->model->model->model_number), $url));
return $url;
}
+7 -7
View File
@@ -21,7 +21,7 @@ class LabelPresenter extends Presenter
], [
'field' => 'name',
'searchable' => true,
'sortable' => true,
'sortable' => false,
'switchable' => true,
'title' => trans('general.name'),
'visible' => true,
@@ -44,14 +44,14 @@ class LabelPresenter extends Presenter
], [
'field' => 'support_fields',
'searchable' => false,
'sortable' => true,
'sortable' => false,
'switchable' => true,
'title' => trans('admin/labels/table.support_fields'),
'visible' => true
], [
'field' => 'support_asset_tag',
'searchable' => false,
'sortable' => true,
'sortable' => false,
'switchable' => true,
'title' => trans('admin/labels/table.support_asset_tag'),
'visible' => true,
@@ -59,7 +59,7 @@ class LabelPresenter extends Presenter
], [
'field' => 'support_1d_barcode',
'searchable' => false,
'sortable' => true,
'sortable' => false,
'switchable' => true,
'title' => trans('admin/labels/table.support_1d_barcode'),
'visible' => true,
@@ -67,7 +67,7 @@ class LabelPresenter extends Presenter
], [
'field' => 'support_2d_barcode',
'searchable' => false,
'sortable' => true,
'sortable' => false,
'switchable' => true,
'title' => trans('admin/labels/table.support_2d_barcode'),
'visible' => true,
@@ -75,7 +75,7 @@ class LabelPresenter extends Presenter
], [
'field' => 'support_logo',
'searchable' => false,
'sortable' => true,
'sortable' => false,
'switchable' => true,
'title' => trans('admin/labels/table.support_logo'),
'visible' => true,
@@ -83,7 +83,7 @@ class LabelPresenter extends Presenter
], [
'field' => 'support_title',
'searchable' => false,
'sortable' => true,
'sortable' => false,
'switchable' => true,
'title' => trans('admin/labels/table.support_title'),
'visible' => true,
+8
View File
@@ -254,6 +254,14 @@ class LicensePresenter extends Presenter
'visible' => true,
'formatter' => 'locationsLinkObjFormatter',
],
[
'field' => 'notes',
'searchable' => false,
'sortable' => false,
'visible' => false,
'title' => trans('general.notes'),
'formatter' => 'notesFormatter'
],
[
'field' => 'checkincheckout',
'searchable' => false,
+1 -1
View File
@@ -433,7 +433,7 @@ class UserPresenter extends Presenter
*/
public function nameUrl()
{
return (string) link_to_route('users.show', $this->fullName(), $this->id);
return (string) link_to_route('users.show', $this->getFullNameAttribute(), $this->id);
}
/**
+1 -6
View File
@@ -75,12 +75,7 @@ class AppServiceProvider extends ServiceProvider
// Only load rollbar if there is a rollbar key and the app is in production
if (($this->app->environment('production')) && (config('logging.channels.rollbar.access_token'))) {
$this->app->register(\Rollbar\Laravel\RollbarServiceProvider::class);
}
// Only load dusk's service provider if the app is in local or develop mode
if ($this->app->environment(['local', 'develop'])) {
$this->app->register(\Laravel\Dusk\DuskServiceProvider::class);
}
}
$this->app->singleton('ArieTimmerman\Laravel\SCIMServer\SCIMConfig', SnipeSCIMConfig::class); // this overrides the default SCIM configuration with our own
-2
View File
@@ -77,7 +77,6 @@
"require-dev": {
"brianium/paratest": "^6.6",
"fakerphp/faker": "^1.16",
"laravel/dusk": "^6.25",
"mockery/mockery": "^1.4",
"nunomaduro/larastan": "^1.0",
"nunomaduro/phpinsights": "^2.7",
@@ -107,7 +106,6 @@
},
"autoload-dev": {
"classmap": [
"tests/DuskTestCase.php",
"tests/TestCase.php"
],
"psr-4": {
Generated
+29 -165
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "f30d1bebf56af36eb55a56d093b54650",
"content-hash": "348f96db24a0f8dfb595ee38b38b34eb",
"packages": [
{
"name": "alek13/slack",
@@ -78,25 +78,25 @@
"source": {
"type": "git",
"url": "https://github.com/grokability/laravel-scim-server.git",
"reference": "9e8dd2d3958d3c3c05d0a99fe6475361ad9e9419"
"reference": "dda6dfb60d70fb6cca4b8d4ce1c5f4c19deaab2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/grokability/laravel-scim-server/zipball/9e8dd2d3958d3c3c05d0a99fe6475361ad9e9419",
"reference": "9e8dd2d3958d3c3c05d0a99fe6475361ad9e9419",
"url": "https://api.github.com/repos/grokability/laravel-scim-server/zipball/dda6dfb60d70fb6cca4b8d4ce1c5f4c19deaab2d",
"reference": "dda6dfb60d70fb6cca4b8d4ce1c5f4c19deaab2d",
"shasum": ""
},
"require": {
"illuminate/console": "^6.0|^7.0|^8.0|^9.0",
"illuminate/database": "^6.0|^7.0|^8.0|^9.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0",
"illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0",
"illuminate/database": "^6.0|^7.0|^8.0|^9.0|^10.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0",
"php": "^7.0|^8.0",
"tmilos/scim-filter-parser": "^1.3",
"tmilos/scim-schema": "^0.1.0"
},
"require-dev": {
"laravel/legacy-factories": "*",
"orchestra/testbench": "^5.0|^6.0"
"orchestra/testbench": "^4.0|^5.0|^6.0|^7.0|^8.0"
},
"default-branch": true,
"type": "library",
@@ -133,7 +133,7 @@
"support": {
"source": "https://github.com/grokability/laravel-scim-server/tree/master"
},
"time": "2023-01-12T00:32:07+00:00"
"time": "2023-09-07T16:45:26+00:00"
},
{
"name": "asm89/stack-cors",
@@ -2948,16 +2948,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "2.4.0",
"version": "2.4.5",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "13388f00956b1503577598873fffb5ae994b5737"
"reference": "0454e12ef0cd597ccd2adb036f7bda4e7fface66"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737",
"reference": "13388f00956b1503577598873fffb5ae994b5737",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/0454e12ef0cd597ccd2adb036f7bda4e7fface66",
"reference": "0454e12ef0cd597ccd2adb036f7bda4e7fface66",
"shasum": ""
},
"require": {
@@ -2971,17 +2971,18 @@
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"bamarni/composer-bin-plugin": "^1.8.1",
"http-interop/http-factory-tests": "^0.9",
"phpunit/phpunit": "^8.5.8 || ^9.3.10"
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
@@ -3043,7 +3044,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.4.0"
"source": "https://github.com/guzzle/psr7/tree/2.4.5"
},
"funding": [
{
@@ -3059,7 +3060,7 @@
"type": "tidelift"
}
],
"time": "2022-06-20T21:43:11+00:00"
"time": "2023-04-17T16:00:45+00:00"
},
{
"name": "intervention/image",
@@ -6130,16 +6131,16 @@
},
{
"name": "nyholm/psr7",
"version": "1.5.1",
"version": "1.6.1",
"source": {
"type": "git",
"url": "https://github.com/Nyholm/psr7.git",
"reference": "f734364e38a876a23be4d906a2a089e1315be18a"
"reference": "e874c8c4286a1e010fb4f385f3a55ac56a05cc93"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Nyholm/psr7/zipball/f734364e38a876a23be4d906a2a089e1315be18a",
"reference": "f734364e38a876a23be4d906a2a089e1315be18a",
"url": "https://api.github.com/repos/Nyholm/psr7/zipball/e874c8c4286a1e010fb4f385f3a55ac56a05cc93",
"reference": "e874c8c4286a1e010fb4f385f3a55ac56a05cc93",
"shasum": ""
},
"require": {
@@ -6149,6 +6150,7 @@
"psr/http-message": "^1.0"
},
"provide": {
"php-http/message-factory-implementation": "1.0",
"psr/http-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0"
},
@@ -6161,7 +6163,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "1.6-dev"
}
},
"autoload": {
@@ -6191,7 +6193,7 @@
],
"support": {
"issues": "https://github.com/Nyholm/psr7/issues",
"source": "https://github.com/Nyholm/psr7/tree/1.5.1"
"source": "https://github.com/Nyholm/psr7/tree/1.6.1"
},
"funding": [
{
@@ -6203,7 +6205,7 @@
"type": "github"
}
],
"time": "2022-06-22T07:13:36+00:00"
"time": "2023-04-17T16:03:48+00:00"
},
{
"name": "onelogin/php-saml",
@@ -13519,79 +13521,6 @@
},
"time": "2022-04-13T08:02:27+00:00"
},
{
"name": "laravel/dusk",
"version": "v6.25.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/dusk.git",
"reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/dusk/zipball/25a595ac3dc82089a91af10dd23b0d58fd3f6d0b",
"reference": "25a595ac3dc82089a91af10dd23b0d58fd3f6d0b",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-zip": "*",
"illuminate/console": "^6.0|^7.0|^8.0|^9.0",
"illuminate/support": "^6.0|^7.0|^8.0|^9.0",
"nesbot/carbon": "^2.0",
"php": "^7.2|^8.0",
"php-webdriver/webdriver": "^1.9.0",
"symfony/console": "^4.3|^5.0|^6.0",
"symfony/finder": "^4.3|^5.0|^6.0",
"symfony/process": "^4.3|^5.0|^6.0",
"vlucas/phpdotenv": "^3.0|^4.0|^5.2"
},
"require-dev": {
"mockery/mockery": "^1.0",
"orchestra/testbench": "^4.16|^5.17.1|^6.12.1|^7.0",
"phpunit/phpunit": "^7.5.15|^8.4|^9.0"
},
"suggest": {
"ext-pcntl": "Used to gracefully terminate Dusk when tests are running."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.x-dev"
},
"laravel": {
"providers": [
"Laravel\\Dusk\\DuskServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Laravel\\Dusk\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel Dusk provides simple end-to-end testing and browser automation.",
"keywords": [
"laravel",
"testing",
"webdriver"
],
"support": {
"issues": "https://github.com/laravel/dusk/issues",
"source": "https://github.com/laravel/dusk/tree/v6.25.2"
},
"time": "2022-09-29T09:37:07+00:00"
},
{
"name": "league/container",
"version": "4.2.0",
@@ -14228,71 +14157,6 @@
},
"time": "2022-02-21T12:50:22+00:00"
},
{
"name": "php-webdriver/webdriver",
"version": "1.12.1",
"source": {
"type": "git",
"url": "https://github.com/php-webdriver/php-webdriver.git",
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
"reference": "b27ddf458d273c7d4602106fcaf978aa0b7fe15a",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-zip": "*",
"php": "^5.6 || ~7.0 || ^8.0",
"symfony/polyfill-mbstring": "^1.12",
"symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0 || ^6.0"
},
"replace": {
"facebook/webdriver": "*"
},
"require-dev": {
"ondram/ci-detector": "^2.1 || ^3.5 || ^4.0",
"php-coveralls/php-coveralls": "^2.4",
"php-mock/php-mock-phpunit": "^1.1 || ^2.0",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpunit/phpunit": "^5.7 || ^7 || ^8 || ^9",
"squizlabs/php_codesniffer": "^3.5",
"symfony/var-dumper": "^3.3 || ^4.0 || ^5.0 || ^6.0"
},
"suggest": {
"ext-SimpleXML": "For Firefox profile creation"
},
"type": "library",
"autoload": {
"files": [
"lib/Exception/TimeoutException.php"
],
"psr-4": {
"Facebook\\WebDriver\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.",
"homepage": "https://github.com/php-webdriver/php-webdriver",
"keywords": [
"Chromedriver",
"geckodriver",
"php",
"selenium",
"webdriver"
],
"support": {
"issues": "https://github.com/php-webdriver/php-webdriver/issues",
"source": "https://github.com/php-webdriver/php-webdriver/tree/1.12.1"
},
"time": "2022-05-03T12:16:34+00:00"
},
{
"name": "phpstan/phpdoc-parser",
"version": "1.22.1",
@@ -16736,5 +16600,5 @@
"ext-pdo": "*"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"
"plugin-api-version": "2.3.0"
}
+1 -1
View File
@@ -239,7 +239,7 @@ return [
|
*/
'min_php' => '7.2.5',
'min_php' => '7.4.0',
/*
+7
View File
@@ -35,6 +35,13 @@ return [
'files' => [
/*
* This path is used to make directories in resulting zip-file relative
* Set to false to include complete absolute path
* Example: base_path()
*/
'relative_path' => base_path(),
/*
* The list of directories and files that will be included in the backup.
*/
+1 -1
View File
@@ -69,7 +69,7 @@ return [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
+6 -6
View File
@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v6.1.2',
'full_app_version' => 'v6.1.2 - build 10938-g32747cafd',
'build_version' => '10938',
'app_version' => 'v6.2.2',
'full_app_version' => 'v6.2.2 - build 11714-ga95fae0e9',
'build_version' => '11714',
'prerelease_version' => '',
'hash_version' => 'g32747cafd',
'full_hash' => 'v6.1.2-89-g32747cafd',
'branch' => 'develop',
'hash_version' => 'ga95fae0e9',
'full_hash' => 'v6.2.2-85-ga95fae0e9',
'branch' => 'master',
);
+14
View File
@@ -8,6 +8,8 @@ use App\Models\Location;
use App\Models\Statuslabel;
use App\Models\Supplier;
use App\Models\User;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Factories\Factory;
class AssetFactory extends Factory
@@ -48,6 +50,18 @@ class AssetFactory extends Factory
'last_checkout' => null,
];
}
public function configure()
{
return $this->afterMaking(function (Asset $asset) {
// calculates the EOL date most of the time, but sometimes sets a random date so we have some explicits
// the explicit boolean gets set in the saving() method on the observer
$asset->asset_eol_date = $this->faker->boolean(5)
? CarbonImmutable::parse($asset->purchase_date)->addMonths(rand(0, 20))->format('Y-m-d')
: CarbonImmutable::parse($asset->purchase_date)->addMonths($asset->model->eol)->format('Y-m-d');
});
}
public function laptopMbp()
{
+1 -1
View File
@@ -22,7 +22,7 @@ class CompanyFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->company(),
'name' => $this->faker->unique()->company(),
];
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ class CustomFieldFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->catchPhrase(),
'name' => $this->faker->unique()->catchPhrase(),
'format' => '',
'element' => 'text',
'auto_add_to_fieldsets' => '0',
+1 -1
View File
@@ -22,7 +22,7 @@ class CustomFieldsetFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->catchPhrase(),
'name' => $this->faker->unique()->catchPhrase(),
];
}
+1 -1
View File
@@ -23,7 +23,7 @@ class DepreciationFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->catchPhrase(),
'name' => $this->faker->unique()->catchPhrase(),
'user_id' => User::factory()->superuser(),
'months' => 36,
];
+1 -1
View File
@@ -23,7 +23,7 @@ class ManufacturerFactory extends Factory
public function definition()
{
return [
'name' => $this->faker->company(),
'name' => $this->faker->unique()->company(),
'user_id' => User::factory()->superuser(),
'support_phone' => $this->faker->phoneNumber(),
'url' => $this->faker->url(),
+2 -2
View File
@@ -33,11 +33,11 @@ class UserFactory extends Factory
'permissions' => '{}',
'phone' => $this->faker->phoneNumber(),
'state' => $this->faker->stateAbbr(),
'username' => $this->faker->username(),
'username' => $this->faker->unique()->username(),
'zip' => $this->faker->postcode(),
];
}
public function firstAdmin()
{
return $this->state(function () {
@@ -21,11 +21,7 @@ class AddLabel2Settings extends Migration
$table->string('label2_1d_type')->default('default');
$table->string('label2_2d_type')->default('default');
$table->string('label2_2d_target')->default('hardware_id');
$table->string('label2_fields')->default(
trans('admin/hardware/form.name').'=name;'.
trans('admin/hardware/form.serial').'=serial;'.
trans('admin/hardware/form.model').'=model.name;'
);
$table->string('label2_fields')->default('name=name;serial=serial;model=model.name;');
});
}
@@ -0,0 +1,67 @@
<?php
use App\Models\Asset;
use Carbon\CarbonImmutable;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Log;
class DenormalizedEolAndAddColumnForExplicitDateToAssets extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('assets', function (Blueprint $table) {
$table->boolean('eol_explicit')->default(false)->after('asset_eol_date');
});
// Update the eol_explicit column with the value from asset_eol_date if it exists and is different from the calculated value
Asset::whereNotNull('asset_eol_date')->with('model')->chunkById(500, function ($assetsWithEolDates) {
foreach ($assetsWithEolDates as $asset) {
if ($asset->asset_eol_date && $asset->purchase_date) {
try {
$months = CarbonImmutable::parse($asset->asset_eol_date)->diffInMonths($asset->purchase_date);
} catch (\Exception $e) {
Log::info('asset_eol_date invalid for asset ' . $asset->id);
}
if ($asset->model->eol) {
if ($months != $asset->model->eol) {
$asset->update(['eol_explicit' => true]);
}
} else {
$asset->update(['eol_explicit' => true]);
}
}
}
});
DB::table('assets')
->whereNull('asset_eol_date')
->whereNotNull('purchase_date')
->whereNotNull('model_id')
->join('models', 'assets.model_id', '=', 'models.id')
->update([
'asset_eol_date' => DB::raw('DATE_ADD(purchase_date, INTERVAL models.eol MONTH)')
]);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('assets', function (Blueprint $table) {
$table->dropColumn('eol_explicit');
});
}
}
@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddLastCheckinToAssets extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('assets', function (Blueprint $table) {
$table->dateTime('last_checkin')->after('last_checkout')->nullable();
});
DB::statement(
"UPDATE " . DB::getTablePrefix() . "assets SET last_checkin=(SELECT MAX(" . DB::getTablePrefix() . "action_logs.action_date) FROM " . DB::getTablePrefix() . "action_logs WHERE item_type='App\\\Models\\\Asset' AND " . DB::getTablePrefix() . "action_logs.item_id=" . DB::getTablePrefix() . "assets.id AND " . DB::getTablePrefix() . "action_logs.action_type='checkin from')"
);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('assets', function (Blueprint $table) {
$table->dropColumn('last_checkin');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNameOrderingToSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('name_display_format', 10)->after('alert_threshold')->nullable()->default('first_last');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('name_display_format');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddMinAmtToModelsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('models', function (Blueprint $table) {
$table->integer('min_amt')->after('model_number')->default(null);;
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('models', function (Blueprint $table) {
$table->dropColumn('min_amt');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class FixAssetModelMinQtyNullability extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('models', function (Blueprint $table) {
$table->integer('min_amt')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('models', function (Blueprint $table) {
$table->integer('min_amt')->nullable(false)->change();
});
}
}
+101 -174
View File
@@ -1883,6 +1883,19 @@
}
}
},
"@vue/reactivity": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz",
"integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==",
"requires": {
"@vue/shared": "3.1.5"
}
},
"@vue/shared": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz",
"integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA=="
},
"@webassemblyjs/ast": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@@ -2187,6 +2200,14 @@
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
},
"alpinejs": {
"version": "3.12.3",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.12.3.tgz",
"integrity": "sha512-fLz2dfYQ3xCk7Ip8LiIpV2W+9brUyex2TAE7Z0BCvZdUDklJE+n+a8gCgLWzfZ0GzZNZu7HUP8Z0z6Xbm6fsSA==",
"requires": {
"@vue/reactivity": "~3.1.1"
}
},
"ansi-html-community": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
@@ -3525,11 +3546,6 @@
"tslib": "^2.0.3"
}
},
"camelcase": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="
},
"caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -3703,6 +3719,16 @@
"string-width": "^4.2.0"
}
},
"clipboard": {
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz",
"integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
"requires": {
"good-listener": "^1.2.2",
"select": "^1.1.2",
"tiny-emitter": "^2.0.0"
}
},
"cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -4144,24 +4170,27 @@
}
},
"css-loader": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-4.3.0.tgz",
"integrity": "sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==",
"version": "5.2.7",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz",
"integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==",
"requires": {
"camelcase": "^6.0.0",
"cssesc": "^3.0.0",
"icss-utils": "^4.1.1",
"icss-utils": "^5.1.0",
"loader-utils": "^2.0.0",
"postcss": "^7.0.32",
"postcss-modules-extract-imports": "^2.0.0",
"postcss-modules-local-by-default": "^3.0.3",
"postcss-modules-scope": "^2.2.0",
"postcss-modules-values": "^3.0.0",
"postcss": "^8.2.15",
"postcss-modules-extract-imports": "^3.0.0",
"postcss-modules-local-by-default": "^4.0.0",
"postcss-modules-scope": "^3.0.0",
"postcss-modules-values": "^4.0.0",
"postcss-value-parser": "^4.1.0",
"schema-utils": "^2.7.1",
"semver": "^7.3.2"
"schema-utils": "^3.0.0",
"semver": "^7.3.5"
},
"dependencies": {
"@types/json-schema": {
"version": "7.0.13",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz",
"integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ=="
},
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
@@ -4172,32 +4201,23 @@
"json5": "^2.1.2"
}
},
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"requires": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
},
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
@@ -4508,6 +4528,11 @@
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
},
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -14858,6 +14883,14 @@
}
}
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
"requires": {
"delegate": "^3.1.2"
}
},
"gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
@@ -15283,33 +15316,9 @@
}
},
"icss-utils": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
"integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
"requires": {
"postcss": "^7.0.14"
},
"dependencies": {
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA=="
},
"ieee754": {
"version": "1.2.1",
@@ -16795,8 +16804,7 @@
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"dev": true
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
},
"needle": {
"version": "2.9.1",
@@ -17423,7 +17431,6 @@
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
"integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
"dev": true,
"requires": {
"nanoid": "^3.1.30",
"picocolors": "^1.0.0",
@@ -17701,124 +17708,34 @@
}
},
"postcss-modules-extract-imports": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
"integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
"requires": {
"postcss": "^7.0.5"
},
"dependencies": {
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw=="
},
"postcss-modules-local-by-default": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz",
"integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz",
"integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==",
"requires": {
"icss-utils": "^4.1.1",
"postcss": "^7.0.32",
"icss-utils": "^5.0.0",
"postcss-selector-parser": "^6.0.2",
"postcss-value-parser": "^4.1.0"
},
"dependencies": {
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"postcss-modules-scope": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz",
"integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
"integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
"requires": {
"postcss": "^7.0.6",
"postcss-selector-parser": "^6.0.0"
},
"dependencies": {
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
"postcss-selector-parser": "^6.0.4"
}
},
"postcss-modules-values": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz",
"integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
"integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
"requires": {
"icss-utils": "^4.0.0",
"postcss": "^7.0.6"
},
"dependencies": {
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"postcss": {
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
"icss-utils": "^5.0.0"
}
},
"postcss-normalize-charset": {
@@ -18548,12 +18465,18 @@
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
"integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.5",
"ajv": "^6.12.4",
"ajv-keywords": "^3.5.2"
}
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -18814,8 +18737,7 @@
"source-map-js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
"dev": true
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA=="
},
"source-map-support": {
"version": "0.5.21",
@@ -19380,6 +19302,11 @@
"process": "~0.11.0"
}
},
"tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"tiny-inflate": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+4 -3
View File
@@ -24,7 +24,7 @@
"vue-template-compiler": "2.4.4"
},
"dependencies": {
"@fortawesome/fontawesome-free": "^6.4.0",
"@fortawesome/fontawesome-free": "^6.4.2",
"acorn": "^8.9.0",
"acorn-import-assertions": "^1.9.0",
"admin-lte": "^2.4.18",
@@ -37,7 +37,8 @@
"bootstrap-less": "^3.3.8",
"bootstrap-table": "1.22.1",
"chart.js": "^2.9.4",
"css-loader": "^4.0.0",
"clipboard": "^2.0.11",
"css-loader": "^5.0.0",
"ekko-lightbox": "^5.1.1",
"imagemin": "^8.0.1",
"jquery-form-validator": "^2.3.79",
@@ -46,7 +47,7 @@
"jquery-ui-bundle": "^1.12.1",
"jquery.iframe-transport": "^1.0.0",
"jspdf-autotable": "^3.5.30",
"less": "^4.1.2",
"less": "^4.2.0",
"less-loader": "^5.0",
"list.js": "^1.5.0",
"papaparse": "^4.3.3",
File diff suppressed because one or more lines are too long
+1 -1122
View File
File diff suppressed because one or more lines are too long

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