Compare commits

..

1200 Commits

Author SHA1 Message Date
Brady Wetherington
bf6c48d695 Clean up the fieldset experience for custom fields for users 2023-09-21 14:56:29 +01:00
Brady Wetherington
8428b2a04a Merge branch 'has_custom_fields_trait_rebase' into custom_fields_on_user 2023-09-18 13:45:35 +01:00
Brady Wetherington
71e745d966 Clean up this migration so it runs forwards and backwards OK 2023-09-14 21:14:26 +01:00
Brady Wetherington
a3a786f2af Merge branch 'develop' into has_custom_fields_trait_rebase 2023-09-14 20:27:06 +01: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
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
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
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
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
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
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
Brady Wetherington
0086adab86 Refactor out common code for 'custom fields view' partial 2023-09-05 20:45:43 +01: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
Brady Wetherington
0f91e898fd Remove some code duplication 2023-09-05 19:18:04 +01: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
e486fe2794 Removed soft-delete query
Signed-off-by: snipe <snipe@snipe.net>
2023-09-05 16:10:20 +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
Brady Wetherington
636da2ab5e Wiring up custom fields for users - still some big UI challenges tho 2023-09-05 16:01:53 +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
Brady Wetherington
4f182c0a50 Got a chunk of Custom Fields for Users worked out, still needs cleanup 2023-08-31 19:34:25 +01:00
Marcus Moore
da7d6f6f77 Merge branch 'develop' into update-testing-documentation 2023-08-31 10:36:06 -07: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
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
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
Brady Wetherington
a384d0173a Merge branch 'snipeit_v7_laravel10' into has_custom_fields_trait_rebase 2023-08-30 18:33:17 +01: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
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
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
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
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
Brady Wetherington
427f8b1522 Merge branch 'develop' into snipeit_v7_laravel10
Upgraded composer due to lockfile conflicts
2023-08-28 16:04:21 +01:00
Brady Wetherington
8902145288 This is a squashed branch of all of the various commits that make up the new HasCustomFields trait.
This should allow us to add custom fields to just about anything we want to within Snipe-IT.

Below are the commits that have been squashed together:

Initial decoupling of custom field behavior from Assets for re-use

Add new DB columns to Custom Fields and fieldsets for 'type'

WIP: trying to figure out UI for custom fields for things other than Assets, find problematic places

Real progress towards getting to where this stuff might actually work...

Fix the table-name determining code for Custom Fields

Getting it closer to where Assets at least work

Rename the trait to it's new, even better name

Solid progress on the new Trait!

WIP: HasCustomFields, still working some stuff out

Got some basics working; creating custom fields and stuff

HasCustomFields now validates and saves

Starting to yank the other boilerplate code as things start to work (!)

Got the start of defaultValuesForCustomField() working

More progress (squash me!)

Add migrations for default_values_for_custom_fields table

WIP: more towards hasCustomFields trait

Progress cleaning up the PR, fixing FIXME's

New, passing HasCustomFieldsTrait test!

Fix date formatter helper for custom fields

Fixed more FIXME's
2023-08-28 13:07:33 +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
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
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
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
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
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
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
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
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
5645141f93 Merge pull request #13488 from snipe/fixes/13487_supplier_url_in_listing
Fixed #13487 - include supplier url in listing
2023-08-18 15:32:14 +01:00
snipe
da2f22d504 Fixed #13487 - include supplier url in listing
Signed-off-by: snipe <snipe@snipe.net>
2023-08-18 15:31:15 +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
0ee032a10d Merge pull request #13391 from Godmartinz/ldap_sync_field_clear_bug
Fixed Ldap sync field clear bug
2023-08-17 17:45:03 +01:00
snipe
03a01c02c4 Merge pull request #13483 from inietov/fixes/default_locations_advanced_search
Fixed #13359 Advanced search by Default Location does not work
2023-08-17 15:15:21 +01:00
Ivan Nieto Vivanco
b607a59875 Add query to search default locations in advanced search 2023-08-16 15:04:17 -06:00
snipe
34f2221b02 Merge pull request #13471 from inietov/fixes/components_search
Fixed #13409 Search in component detail view not working
2023-08-16 21:59:40 +01:00
snipe
b81c6825cf Merge pull request #13476 from uberbrady/accessry_checkin_fix_develop
Accessory checkin via API reported wrong target user
2023-08-16 13:05:54 +01:00
Brady Wetherington
852e9ff311 Accessory checkin via API reported wrong target user 2023-08-16 13:03:37 +01:00
Ivan Nieto Vivanco
92df32dfaa Move a couple assignation of variables inside an else to only execute once 2023-08-15 21:10:48 -06:00
snipe
eacbde37e2 Merge pull request #13473 from snipe/fixes/check_for_company_on_labels
Check that there is a company before trying to get name property
2023-08-16 01:27:48 +01:00
snipe
74384f14e4 Use clearer translation (from original PR)
Signed-off-by: snipe <snipe@snipe.net>
2023-08-16 01:25:13 +01:00
snipe
027afa71f1 Check that there is a company before trying to get name property
Signed-off-by: snipe <snipe@snipe.net>
2023-08-16 01:09:22 +01:00
Ivan Nieto Vivanco
993918f47c Add query to search into the per-component view 2023-08-15 15:31:36 -06:00
Brady Wetherington
8b52bad16f Merge branch 'develop' into snipeit_v7_laravel10 2023-08-15 21:25:16 +01:00
Ivan Nieto Vivanco
25c58a8486 Fix typo in language variable name 2023-08-15 14:17:39 -06:00
snipe
7eaf3174ab Merge pull request #13457 from snipe/fixes/remove_autocomplete_off_on_login
Fixed #13365 - Added LOGIN_AUTOCOMPLETE as env var
2023-08-15 20:55:05 +01:00
snipe
297390ae63 Merge pull request #13470 from snipe/fixes/13464_typo_in_accessories_clone
Fixed #13464 typo in accessories clone
2023-08-15 20:41:54 +01:00
snipe
01ab360ef3 Fixed accessory clone typo
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:39:09 +01:00
snipe
1c2f3cd552 Fixed translation typo
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:39:00 +01:00
snipe
bc4a47421a Merge pull request #13469 from snipe/fixes/missed_one_checkbox_in_label
Fixed checkboxes for accessibility
2023-08-15 20:30:39 +01:00
snipe
0763b5135d Fixed checkboxes
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:28:16 +01:00
snipe
253975ce72 Updated translation
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:27:55 +01:00
snipe
9af850dbaa Re-apply a change that was dropped
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:27:47 +01:00
snipe
96b616be89 Downgraded TCPDF
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:11:56 +01:00
snipe
2b9f8ce4a6 Merge pull request #13467 from snipe/fixes/more_label_html_tweaks
Fixes more label html tweaks
2023-08-15 20:05:03 +01:00
snipe
fa6c8d864e Restore label engine checkbox
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:04:19 +01:00
snipe
c957f136aa More label tweaks
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:03:40 +01:00
snipe
697dc10d76 More label tweaks
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 20:03:32 +01:00
snipe
d47b502d86 Merge pull request #13466 from snipe/fixes/weird_label_engine_layout
Fixes weird label engine layout
2023-08-15 18:52:54 +01:00
snipe
6b02184e99 Fixed weird layout with checkbox
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 18:48:20 +01:00
snipe
64342838fd Return the user to the labels page on save
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 18:48:12 +01:00
snipe
346f243bc0 Merge pull request #13465 from snipe/fixes/parse_error_in_helper
Fixed unclosed brace
2023-08-15 18:14:55 +01:00
snipe
443adc50da Fixed unclosed brace
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 18:12:25 +01:00
snipe
cebf0e0de1 Add @cram42 as a contributor 2023-08-15 18:07:56 +01:00
snipe
e41368daac Merge pull request #12050 from cram42/develop
New Label Engine
2023-08-15 17:58:57 +01:00
Godfrey M
d1efca2ae1 fixes conflicts 2023-08-15 09:28:42 -07:00
snipe
c56f664811 Merge pull request #13442 from Robert-Azelis/Robert-Azelis-patch-add_email_to_companies
Add email to companies
2023-08-15 13:26:20 +01:00
snipe
6f373aed33 Merge pull request #13461 from snipe/localization/new_translations
Updated language strings from CrowdIn
2023-08-15 13:22:14 +01:00
snipe
d1ce1b6f18 Updated language strings from CrowdIn
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 13:21:35 +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
snipe
24a3e0ee83 Added LOGIN_AUTOCOMPLETE as env var
Signed-off-by: snipe <snipe@snipe.net>
2023-08-15 01:56:01 +01: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
d3fbbec92c Merge pull request #13455 from snipe/fixes/confusion_around_localization_date
Fixed #13382 - confusion around localization date
2023-08-14 22:50:30 +01:00
snipe
9820ab34d7 Use today’s date for date format selectlist
Signed-off-by: snipe <snipe@snipe.net>
2023-08-14 22:44:29 +01:00
snipe
aa333bcf0b Merge pull request #13448 from Godmartinz/status-label-translations_fix
Fixed #13446 - added translations to status label type column
2023-08-14 22:25:46 +01:00
snipe
ba56746f57 Merge pull request #13437 from marcusmoore/feature/improve-user-factory
Allowed permissions in the user factory to be chained
2023-08-14 22:23:55 +01:00
snipe
dcec4ba5e2 Merge pull request #13454 from snipe/fixes/13450_removed_escaping_custom_fieldsets
Fixed #13450 - remove escaping on saveing new custom fields
2023-08-14 22:22:35 +01:00
snipe
12e9d2adeb Fixed #13450 - remove escaping on saveing new custom fields
Signed-off-by: snipe <snipe@snipe.net>
2023-08-14 22:21:41 +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
Godfrey M
c3356ab765 fixed translation choice and color choice 2023-08-14 12:20:46 -07:00
Godfrey M
4446b2311d remove unnecessary changes 2023-08-14 12:14:15 -07:00
Godfrey M
6b94ef6adc fixes the statuslabeltypeforatter instead of the model 2023-08-14 12:13:01 -07:00
Godfrey M
a0d5774635 adds translations to status label type column 2023-08-14 10:42:17 -07:00
snipe
291fa1cd29 Merge pull request #13445 from snipe/fixes/typo_in_formatter_for_asset_maintenances
Fixed case in BS table formatter for boolean
2023-08-14 13:02:27 +01:00
snipe
58286c9cab Fixed case in BS table formatter for boolean
Signed-off-by: snipe <snipe@snipe.net>
2023-08-14 13:01:32 +01:00
Robert-Azelis
1e43d88e06 Create 2023_08_13_172600_add_email_to_companies.php 2023-08-13 17:25:33 +02:00
Robert-Azelis
da701677c7 Update edit.blade.php 2023-08-13 17:24:17 +02:00
Robert-Azelis
30d33310ae Update CompanyPresenter.php 2023-08-13 17:23:33 +02:00
Robert-Azelis
bbb8ecfee4 Update Company.php 2023-08-13 17:21:55 +02:00
Robert-Azelis
8988a5dfc3 Update CompaniesTransformer.php 2023-08-13 17:20:15 +02:00
Robert-Azelis
ed5b4ca0a2 Update CompaniesController.php 2023-08-13 17:18:25 +02:00
Robert-Azelis
07bafa9508 Update CompaniesController.php 2023-08-13 17:15:20 +02:00
snipe
a1cfa45344 Merge pull request #13439 from snipe/fixes/500_error_when_cloning_invalid_accessory
Fixed route for accessory index
2023-08-11 09:42:00 +01:00
snipe
df8f6a8d2b Correctly call the route for accessory index
Signed-off-by: snipe <snipe@snipe.net>
2023-08-11 09:40:49 +01:00
Marcus Moore
5b86c02366 Set permissions to empty object in user factory 2023-08-10 16:55:44 -07:00
Marcus Moore
41479b1ec7 Allow permissions in the user factory to be chained 2023-08-10 16:35:10 -07: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
6adaa32286 Merge pull request #13431 from marcusmoore/feature/custom-report-scoping
Removed unneeded `Company::scopeCompanyables` from `ReportsController`
2023-08-10 09:57:53 +01:00
snipe
a599f0c923 Merge pull request #13434 from marcusmoore/chore/improve-test-stability
Improved test stability and messaging
2023-08-10 09:57:26 +01:00
snipe
4db4bf7be4 Merge pull request #13432 from marcusmoore/chore/remove-old-testing-code
Removed unused Codeception test code
2023-08-10 09:57:11 +01:00
Marcus Moore
04661d5441 Add help text to response assertion helpers 2023-08-09 17:09:31 -07:00
Marcus Moore
3a5ed031bf Escape values in response assertion helpers 2023-08-09 17:08:49 -07:00
Marcus Moore
60baaae192 Remove unused test bootstrap file 2023-08-09 16:22:58 -07:00
Marcus Moore
8508594a2f Remove old and unused Codeception test code 2023-08-09 13:32:15 -07:00
Marcus Moore
e0b464dcec Merge branch 'develop' into feature/custom-report-scoping 2023-08-09 13:03:05 -07:00
snipe
bd3ba9a5f7 Merge pull request #13428 from snipe/security/update_autotable
Updated autotable
2023-08-09 10:49:01 +01:00
snipe
a65ac1ccdf Updated autotable
Signed-off-by: snipe <snipe@snipe.net>
2023-08-09 10:47:45 +01:00
snipe
ffabc9c331 Merge pull request #13414 from marcusmoore/fixes/chipperci-config
Fixes ChipperCi Pipeline
2023-08-09 10:37:21 +01:00
snipe
a6a742d8d8 Merge pull request #13407 from marcusmoore/feature/sc-23465
Added messaging to category edit page to improve clarity around when users will be emailed
2023-08-09 10:36:19 +01:00
Marcus Moore
2e632a3d2d Improve test readability 2023-08-08 17:40:02 -07:00
Marcus Moore
c32f099053 Remove unneeded call to Company::scopeCompanyables 2023-08-08 17:22:15 -07:00
Marcus Moore
c752e1670c Add test around company scoping in custom report 2023-08-08 17:21:39 -07:00
Marcus Moore
1405e17251 Add simple test around custom asset report response 2023-08-08 17:10:36 -07:00
snipe
15122bbb55 Merge pull request #13425 from snipe/security/upgrade_webpack_snyk_13416
Updated webpack
2023-08-08 22:24:59 +01:00
snipe
c18349d75f Updated webpack
Signed-off-by: snipe <snipe@snipe.net>
2023-08-08 22:07:49 +01:00
snipe
521961457d Merge pull request #13424 from snipe/bug/sc-23552
Fixed tooltip not loading on encrypted field lock icon on asset detail view
2023-08-08 19:00:56 +01:00
snipe
6a3a38b6f6 Call tooltip again on custom fields jquery
Signed-off-by: snipe <snipe@snipe.net>
2023-08-08 18:53:57 +01:00
snipe
40aca9709a Added container to the tooltip invocation
Signed-off-by: snipe <snipe@snipe.net>
2023-08-08 18:52:26 +01:00
snipe
9e6f23c8c7 Merge pull request #13421 from uberbrady/re_add_asset_eol_date
Re-add the option for asset_eol_date as an import field
2023-08-08 17:52:05 +01:00
Brady Wetherington
6afbf1b152 Re-add the option for asset_eol_date as an import field 2023-08-08 17:45:33 +01:00
snipe
af91ffb2da Merge pull request #13418 from snipe/fixes/add_mailgun_endpoint
Added mailgun endpoint option, defaulting to the US
2023-08-08 12:56:37 +01:00
snipe
94bef046b8 Added mailgun endpoint option, defaulting to the US
Signed-off-by: snipe <snipe@snipe.net>
2023-08-08 12:50:38 +01:00
snipe
bd4061e023 Change text on dropdown
Signed-off-by: snipe <snipe@snipe.net>
2023-08-08 08:18:56 +01:00
snipe
5bda73f151 Ugh - messing with the blade layout
Signed-off-by: snipe <snipe@snipe.net>
2023-08-08 08:18:40 +01:00
Marcus Moore
b56bcd3596 Troubleshooting pipeline: create both .env and .env.testing 2023-08-07 11:59:58 -07:00
Marcus Moore
999605b591 Troubleshooting pipeline: create .env.testing in place of .env 2023-08-07 11:57:34 -07:00
Marcus Moore
d3a45f73cf Troubleshooting pipeline: re-add creating .env.testing 2023-08-07 11:48:09 -07:00
Marcus Moore
0d40979724 Troubleshooting pipeline: Remove commented commands 2023-08-07 11:36:51 -07:00
Marcus Moore
81efa7d84e Revert "Troubleshooting pipeline: use phpunit in place of artisan test"
This reverts commit a7d1657111.
2023-08-07 11:35:18 -07:00
Marcus Moore
a7d1657111 Troubleshooting pipeline: use phpunit in place of artisan test 2023-08-07 11:31:00 -07:00
Marcus Moore
8ea8ff05e5 Troubleshooting pipeline: fix filename 2023-08-07 11:26:04 -07:00
Marcus Moore
6398805fc3 Troubleshooting pipeline: use .env.testing in place of .env.example 2023-08-07 11:24:38 -07:00
Marcus Moore
119ed9c882 Troubleshooting pipeline: remove comment to trigger build 2023-08-07 11:09:10 -07:00
snipe
32d8d8c50e Merge pull request #13397 from uberbrady/fix_locationless_ldap_sync
Fixed #13372: Put guard around assigning location via LDAP
2023-08-07 17:06:58 +01:00
Marcus Moore
ae9cf1e5b6 Formatting 2023-08-02 18:24:32 -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
Marcus Moore
d019e62d39 Remove lazy from eula field to avoid race condition 2023-08-02 18:22:40 -07: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
Marcus Moore
b70a5280f9 Remove unneed jquery 2023-08-02 18:04:21 -07:00
Marcus Moore
cbe5a9bc8a Persist eula text even when field is disabled 2023-08-02 18:03:09 -07:00
Marcus Moore
3fd0853fd0 Ensure eula field enabled when not using default eula 2023-08-02 18:02:56 -07:00
Marcus Moore
2e7aa01abe Pass checkin_email value to backend even when unchecked 2023-08-02 17:45:39 -07:00
Marcus Moore
896f038054 Set send email back to original value when eulas cleared 2023-08-02 17:03:56 -07:00
Marcus Moore
48979ce177 Disable send email when it should not be modified 2023-08-02 16:52:56 -07:00
Marcus Moore
e12935f7fa Disable eula textarea when using global eula 2023-08-02 16:18:57 -07:00
Marcus Moore
6400034435 Improve variable name 2023-08-02 16:06:59 -07:00
Marcus Moore
269414e4f2 Automatically check the send email to user checkbox in certain conditions 2023-08-02 16:04:01 -07:00
Marcus Moore
dee6ebf8e0 Scaffold component test 2023-08-02 12:58:07 -07:00
Marcus Moore
105c94aea9 Implement toggling message when email will be sent 2023-08-02 11:36:20 -07:00
Brady Wetherington
0af205dade Put guard around assigning location via LDAP 2023-08-02 15:01:14 +01:00
Marcus Moore
6349d52803 WIP: migrate to livewire 2023-08-01 17:29:23 -07:00
Marcus Moore
65de9c5e07 Extract translation strings 2023-08-01 15:21:49 -07:00
Marcus Moore
ebfc395e78 Improve messaging 2023-08-01 14:39:30 -07:00
Marcus Moore
5c8c2ca027 Improve variable names 2023-08-01 14:26:21 -07:00
snipe
924f5287f7 Merge pull request #13392 from Godmartinz/change_webhook_variable_type
Fixed `webhook_endpoint` data type from varchar to a text
2023-08-01 20:28:39 +01:00
Godfrey M
7560afb8c4 changes webhook_endpoint var to a text 2023-08-01 10:45:39 -07:00
Godfrey M
8a24a47475 removed unnecessary code 2023-08-01 09:45:48 -07:00
Godfrey M
fb52038e7c applies a check if a sync field is designated 2023-08-01 09:39:58 -07:00
Brady Wetherington
daed0b60bc Merge branch 'develop' into snipeit_v7_laravel10 2023-07-31 19:40:56 +01:00
snipe
ffb605a37c Merge pull request #13309 from inietov/fixes/checkout_range_doesnt_include_today
Fixed #13300 Custom Asset Report, Checkout date range never includes current day
2023-07-31 15:04:22 +01:00
Brady Wetherington
4654f7aa37 Porting Snipe-IT v7 to Laravel v10 2023-07-31 14:07:12 +01:00
snipe
343aacab85 Merge pull request #13386 from snipe/security/dep_updates
Updated BS table and table export plugins
2023-07-31 13:46:41 +01:00
snipe
96d69b654d Updated BS table and table export plugins
Signed-off-by: snipe <snipe@snipe.net>
2023-07-31 13:45:15 +01:00
snipe
2e1c3fb51b Merge pull request #13295 from inietov/fixes/admins_cannot_view_encrypted_fields
Fixed #11794 Admins Cannot View Encrypted Field
2023-07-31 13:08:28 +01:00
snipe
3e4b371bf4 Merge pull request #13379 from inietov/fixes/component_checkout_via_api_returns_error
Fixed #13376 Component checkout via API returns error
2023-07-31 13:07:38 +01:00
Grant Le Roux
b1464e028c Merge branch 'develop' into develop 2023-07-31 07:57:29 +08:00
Ivan Nieto Vivanco
0a841ddbb8 Change component validator to the correct asset id we're passing in the API call 2023-07-27 20:22:13 -06:00
Brady Wetherington
70e87dad1c Merge branch 'develop' into snipeit_v7 2023-07-27 16:21:31 +01:00
snipe
af86c6138d Merge pull request #13361 from Godmartinz/bug/sc-19126
Fixed custom fieldset order
2023-07-26 08:55:18 +01:00
snipe
f6545be410 Merge pull request #13363 from inietov/fixes/no_records_found_multipage_license_seats
Fixed #13298 "No records Found" when Switching between Single and Multi-Page Licenses
2023-07-26 08:48:44 +01:00
Ivan Nieto Vivanco
c015264181 Adjust the license offset if it exceeds the total of license seats 2023-07-25 16:23:33 -06:00
Godfrey M
9c6e8d57aa removes typos 2023-07-25 11:44:16 -07:00
Godfrey M
11e3487263 custom field set order starts at 1 now 2023-07-25 11:41:08 -07:00
snipe
a01cb26aac Merge pull request #12940 from akemidx/delete_asset_from_view_page
Delete button on asset view page
2023-07-25 12:11:35 +01:00
akemidx
e289e95721 no ? needed 2023-07-24 17:22:10 -04:00
akemidx
b082d27c42 removing :item 2023-07-24 17:12:12 -04:00
snipe
39ea15a27a Merge pull request #13347 from snipe/fixes/custom_report_error_on_bad_model
Possible alternative to fixing #13296 - custom report failing when th…
2023-07-21 15:18:16 +01:00
snipe
4fe6632167 Merge pull request #13349 from snipe/fixes/check_for_valid_model
Fixed: tighter check for valid model
2023-07-21 14:52:00 +01:00
snipe
1a771e6ab9 Check that the model is valid before trying to chain the relationship
Signed-off-by: snipe <snipe@snipe.net>
2023-07-21 14:46:58 +01:00
snipe
7f761000b4 Use slightly less terrifying and more accurate language
Signed-off-by: snipe <snipe@snipe.net>
2023-07-21 14:46:39 +01:00
Ivan Nieto Vivanco
cb4ed92639 Use Carbon date objects instead of casting using DB::raw() 2023-07-20 16:17:06 -06:00
snipe
540b09c506 Possible alternative to fixing #13296 - custom report failing when the model is busted
Related: https://github.com/snipe/snipe-it/pull/13297
Signed-off-by: snipe <snipe@snipe.net>
2023-07-20 17:45:45 +01:00
Brady Wetherington
ba8d8a6f05 Merge branch 'develop' into snipeit_v7 2023-07-20 17:16:04 +01:00
snipe
0b8a3ee9a5 Merge pull request #13346 from snipe/fixes/depreciable
Check that $this->get_depreciation() returns
2023-07-20 16:33:15 +01:00
snipe
1e09320ebe Check that $this->get_depreciation() returns
Signed-off-by: snipe <snipe@snipe.net>
2023-07-20 16:30:07 +01:00
snipe
ee36497acf Merge pull request #13344 from snipe/fixes/added_manufacturer_to_licenses
Fixes bug/sc-23509: Added manufacturer back into license importer
2023-07-20 14:05:19 +01:00
snipe
d7ac8ef618 Added manufacturer to licenses
Signed-off-by: snipe <snipe@snipe.net>
2023-07-20 14:02:54 +01:00
snipe
244e4ec11f Added manufacturer back into license importer
Signed-off-by: snipe <snipe@snipe.net>
2023-07-20 13:48:51 +01:00
snipe
917005ceb4 Merge pull request #13342 from Loemnk/develop
Fixes #13341: Clean up correct seats on license delete
2023-07-20 13:05:31 +01:00
Tobias Franzius
90a344af0b Fixes #13341 Clean up correct seats on license delete
Before this, we checked for the `id` collumn in the `license_seats` table, insteasd of
using `license_id` for this.

This way, we ensure that we only alter seats belonging to the correct license.
2023-07-20 13:48:57 +02:00
Ivan Nieto Vivanco
ecf522243b Add the new rule to proper views and also in the Asset Transformer 2023-07-19 19:52:03 -06:00
Ivan Nieto Vivanco
705411eb4d Create the Gate that goes with the permission 2023-07-19 19:44:59 -06:00
Ivan Nieto Vivanco
3b4a2b0f5b Add permission to view and modify encrypted custom fields 2023-07-19 14:57:57 -06:00
snipe
a19a508a80 Merge pull request #13197 from akemidx/current_value_for_assets
Current value added to asset index page
2023-07-19 19:06:15 +01:00
akemidx
9e2987e680 changing book value to be NOT searchable or sortable 2023-07-19 13:44:31 -04:00
snipe
1e1aea2eb0 Merge pull request #13299 from ubc-cpsc/bugfix/CVE-2023-37260
Update league/oauth2-server for CVE-2023-3726
2023-07-19 13:14:35 +01:00
Brady Wetherington
605d267fe8 Merge branch 'develop' into snipeit_v7 2023-07-19 11:47:51 +01:00
snipe
33fd904c18 Merge pull request #13330 from akemidx/merge_users_typo
merge users page typo fix
2023-07-19 10:26:57 +01:00
snipe
dc20305db6 Merge pull request #13333 from snipe/fixes/strtolower_on_catgories
Added strtolower for category type
2023-07-19 09:00:55 +01:00
snipe
a0a5ca1f40 Added strtolower for category type
Signed-off-by: snipe <snipe@snipe.net>
2023-07-19 08:56:17 +01:00
akemidx
064e696521 merge users page typo fix 2023-07-18 15:33:33 -04:00
snipe
c1949ffb0d Merge pull request #13319 from marcusmoore/chore/user-search-test-cases
Added test cases around user search
2023-07-18 13:27:22 +01:00
snipe
18e2ec4dad Merge pull request #13310 from marcusmoore/bug/sc-23478
Fixed the inability to load location select when editing profile
2023-07-18 13:26:30 +01:00
snipe
6f8c3ca167 Merge pull request #13322 from uberbrady/fix_ldap_location_3
Fix to ldap_location attribute
2023-07-18 13:24:59 +01:00
snipe
cbdce994b8 Merge pull request #13318 from inietov/fixes/employee_id_not_importing
Fixed Employee Number no longer importing [sc-23497]
2023-07-18 11:08:43 +01:00
Brady Wetherington
051830dff4 Fix to ldap_location attribute 2023-07-17 20:42:02 +01:00
Marcus Moore
2eaab6d9fb Change message to a callout 2023-07-17 12:23:31 -07:00
Marcus Moore
fa0a88289a Add tests around user search
Follow up to #13311
2023-07-17 11:29:22 -07:00
Ivan Nieto Vivanco
88c40c9c14 Change the field name to the same the model uses 2023-07-17 12:08:10 -06:00
snipe
f15e14f905 Merge pull request #13315 from snipe/features/add_warranty_link_even_if_no_warranty_set
Moved warranty into manufactuer’s section
2023-07-15 10:47:44 +01:00
snipe
c21a7db3c1 Moved warranty into manufactuer’s section
Signed-off-by: snipe <snipe@snipe.net>
2023-07-15 10:45:36 +01:00
snipe
bb0eaf8b8d Merge pull request #13312 from snipe/features/add_show_hide_option_on_custom_fields
Added ability to show/hide custom fields in list views by default
2023-07-14 09:38:35 +01:00
snipe
3078cab7ee Added ability to show/hide custom fields in list views by default
Signed-off-by: snipe <snipe@snipe.net>
2023-07-14 09:09:43 +01:00
snipe
15bb943210 Merge pull request #13311 from snipe/fixes/deleted_users_showing_in_current_users
Fixed: deleted users showing in current users
2023-07-14 07:47:36 +01:00
snipe
f51dd15893 Moved deleted scope down
Signed-off-by: snipe <snipe@snipe.net>
2023-07-14 07:44:19 +01:00
Marcus Moore
346ace9444 Allow users that have permission to edit their own location to see locations in select list 2023-07-13 17:37:46 -07:00
Ivan Nieto Vivanco
ecac4718fe Add date casting to the SQL query, so the BETWEEN range doesn't care about time of day in custom report datetimes 2023-07-13 16:02:47 -06:00
snipe
4027acee46 Merge pull request #13184 from akemidx/department_in_side_bar
User department now visible in side pane of asset view page
2023-07-13 21:01:48 +01:00
snipe
5aa99a15d8 Merge pull request #13288 from snipe/fixes/line_based_markdown
Added Inline markdown method
2023-07-13 13:16:50 +01:00
snipe
016502f637 Added notesFormatter
Signed-off-by: snipe <snipe@snipe.net>
2023-07-13 13:14:10 +01:00
snipe
5d1f294f0e Added parseEscapedMarkedownInline to accessories API
Signed-off-by: snipe <snipe@snipe.net>
2023-07-13 12:03:01 +01:00
snipe
981c3a430d Merge pull request #13301 from uberbrady/better_auto_increment_tags
Better auto increment asset-tags [FD-32892]
2023-07-13 09:49:44 +01:00
Joël Pittet
24adcdb586 Revert lock file changes for PHP 7 support 2023-07-12 17:58:52 -07:00
akemidx
1163af3c10 change to make sure department actually exists 2023-07-12 15:57:44 -04:00
snipe
232e84acf7 Merge pull request #13302 from snipe/features/env_setting_for_bs_tables
Fixed #13256 - Added option to switch to localStorage instead of cookies
2023-07-12 20:10:33 +01:00
snipe
5d60a38a0e Added comment with link
Signed-off-by: snipe <snipe@snipe.net>
2023-07-12 20:08:20 +01:00
snipe
c1c2c38995 Fixed #13256 - Added option to switch to localStorage instead of cookies
Signed-off-by: snipe <snipe@snipe.net>
2023-07-12 20:06:17 +01:00
snipe
44231fa52c Merge pull request #13225 from inietov/fixes/change_default_location_at_checkin
Fixed #13167 Default location not being set/updated upon check-in
2023-07-12 19:14:53 +01:00
snipe
44b8558e38 Merge pull request #13233 from Godmartinz/barcode_adjusts_if_qr_code_
fixed margin if qr_code present
2023-07-12 17:11:58 +01:00
snipe
d3c44a462e Merge pull request #13268 from inietov/fixes/license_importer_missing_dropdown_items
Fixed License importer missing Checkout to: Username and Checkout to: Email in dropdown [sc-23456]
2023-07-12 17:11:27 +01:00
snipe
a569a99e61 Used inline markdown in views
Signed-off-by: snipe <snipe@snipe.net>
2023-07-12 16:57:04 +01:00
Brady Wetherington
e648da9dc5 Also do a sanity-check that the normal asset autoincrementing works 2023-07-12 16:51:23 +01:00
Brady Wetherington
76191a09ed Improvements to asset_tag auto-incrementing, with auto-fixups for gaps 2023-07-12 16:39:45 +01:00
snipe
1b8b117f4e Merge pull request #13292 from marcusmoore/guard-against-wiping-local-db
Avoid accidentally wiping local database when running tests
2023-07-12 15:23:11 +01:00
Marcus Moore
3df175fb3e Improve variable name 2023-07-11 16:36:38 -07:00
Marcus Moore
44d8b2fd5e Handle default eula checkbox 2023-07-11 16:36:03 -07:00
Ivan Nieto Vivanco
e0df8cc4aa Add admin role to show encrypted customfield values 2023-07-11 17:21:32 -06:00
Marcus Moore
af681d8190 Display message and update checkbox depending on EULA status 2023-07-11 16:12:43 -07:00
snipe
2bc4235368 Merge pull request #13293 from marcusmoore/run-chipper-on-all-prs
Run ChipperCI on all PRs (take three)
2023-07-11 20:36:49 +01:00
Marcus Moore
5b33c00e9f Run ChipperCI on all PRs 2023-07-11 12:34:39 -07:00
Marcus Moore
48e4ec8cf5 Guard against wiping database when running tests and test specific envs are not created 2023-07-11 12:16:37 -07:00
snipe
b5695c9ab7 Test parsedown in notes
Signed-off-by: snipe <snipe@snipe.net>
2023-07-11 12:20:47 +01:00
snipe
6d3bf1e5f5 Added additional method for inline
Signed-off-by: snipe <snipe@snipe.net>
2023-07-11 11:41:58 +01:00
snipe
9b5a67e31f Use $Parsedown->line instead of $Parsedown->text
Signed-off-by: snipe <snipe@snipe.net>
2023-07-11 11:33:29 +01:00
snipe
ba37a9db8c Merge pull request #13277 from snipe/features/added_phone_fax_to_locations
Added phone, fax to departments, locations, companies
2023-07-11 11:15:13 +01:00
snipe
9dc7fc93fb Small fixes
Signed-off-by: snipe <snipe@snipe.net>
2023-07-11 11:14:19 +01:00
snipe
a5555a1c67 Merge pull request #13281 from inietov/fixes/error_showing_requested_assets
Fixed #13276 Error Showing Requested Assets
2023-07-11 11:11:33 +01:00
snipe
d76f420f4e Merge pull request #13282 from marcusmoore/fixes/allow-installing-on-74-v2
Fixes dev dependency on PHP 7.4
2023-07-11 11:10:52 +01:00
Marcus Moore
d8f22880d6 Allow installing on PHP 7.4 2023-07-10 17:35:21 -07:00
Ivan Nieto Vivanco
ec8cb1b09e Add the withTrashed() method to requestingUser() method in CheckoutRequest model, so the view of requestable assets doesn't crash 2023-07-10 16:34:00 -06:00
snipe
4845a88c68 Merge pull request #13280 from snipe/security/webpack-upgade
[Snyk] Upgrade webpack from 5.86.0 to 5.87.0 #13267
2023-07-10 20:17:44 +01:00
snipe
73c2202d94 [Snyk] Upgrade webpack from 5.86.0 to 5.87.0 #13267
Signed-off-by: snipe <snipe@snipe.net>
2023-07-10 20:16:09 +01:00
snipe
0d37d1a905 Merge pull request #13279 from snipe/security/acorn-upgrade
Upgraded acorn
2023-07-10 20:08:46 +01:00
snipe
83cf106ce5 Upgraded acorn
Signed-off-by: snipe <snipe@snipe.net>
2023-07-10 20:06:57 +01:00
snipe
7debf126d6 Dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-07-10 20:03:12 +01:00
snipe
c5c87ea0ca Merge pull request #13278 from snipe/security/bs-tables-update
Applied Snyk #13272
2023-07-10 20:01:41 +01:00
snipe
8169206943 Applied Snyk #13272
Signed-off-by: snipe <snipe@snipe.net>
2023-07-10 19:59:08 +01:00
snipe
22d9df304b Merge pull request #13265 from marcusmoore/chore/chipperci-on-prs
Have ChipperCi run on each PR
2023-07-10 19:48:40 +01:00
snipe
14c61e4c17 Added phone, fax to departments, locations, companies
Signed-off-by: snipe <snipe@snipe.net>
2023-07-10 19:44:21 +01:00
Joël Pittet
a4a676ef0b Update league/oauth2-server for CVE-2023-3726 and lcobucci/clock to semver to allow dependencies to update 2023-07-10 11:19:54 -07:00
Brady Wetherington
8f2a17585e Merge branch 'develop' into snipeit_v7
Had to do a lot of conflict work here, so this could get ugly :(
2023-07-10 16:53:35 +01:00
Ivan Nieto Vivanco
299e546021 Adds the Username and Email to License Importer dropdown 2023-07-06 18:36:13 -06:00
snipe
5a9c2925c3 Merge pull request #13264 from marcusmoore/bug/sc-23451
Fix label wrapping on category edit page
2023-07-06 19:01:36 +01:00
Marcus Moore
149184dc3c Have ChipperCI on on each PR
Following up on #13218
2023-07-06 11:00:03 -07:00
Marcus Moore
ef160b0e15 Add span tag so label is displayed properly 2023-07-06 10:49:57 -07:00
Ivan Nieto Vivanco
f4ca29b4a8 Only show radio inputs for location in checkin view 2023-07-06 11:36:55 -06:00
Ivan Nieto Vivanco
9591442f1e Evaluate the radio input to update location only or default location too 2023-07-06 10:46:21 -06:00
Ivan Nieto Vivanco
743e852998 Add radio buttons to alter asset checkin location behavior 2023-07-06 10:38:48 -06:00
snipe
2faa73f983 Merge pull request #13169 from akemidx/license_sn_check1
Making Serial Number the logic checked against for new imports
2023-07-06 16:40:27 +01:00
snipe
d37aaee4c8 Merge pull request #13257 from snipe/fixes/check_for_ceiling_in_upgrader
Check for max PHP version in upgrader
2023-07-06 16:07:10 +01:00
snipe
a9d175a396 Check for max PHP version
Signed-off-by: snipe <snipe@snipe.net>
2023-07-05 18:47:48 +01:00
snipe
35039cd590 Merge pull request #13255 from snipe/fixes/larger_field_for_idp_meta
Change settings table `saml_idp_metadata` to MEDIUMTEXT
2023-07-05 17:30:02 +01:00
snipe
c85a33be6a Change settings table saml_idp_metadata to MEDIUMTEXT
Signed-off-by: snipe <snipe@snipe.net>
2023-07-05 17:28:08 +01:00
snipe
d890d923ff Bumped version
Signed-off-by: snipe <snipe@snipe.net>
2023-07-05 14:40:54 +01:00
snipe
4b4983e550 Merge pull request #13253 from uberbrady/improve_scim_404s
Properly return SCIM Exceptions
2023-07-05 14:37:32 +01:00
Brady Wetherington
a6a89ddd6c Also log(debug) the error - could be useful for troubleshooting 2023-07-05 14:31:08 +01:00
Brady Wetherington
1f4d2f1e4a Properly return SCIM Exceptions 2023-07-05 14:27:10 +01:00
Godfrey M
d44e667697 fixed margin if qr_code present 2023-06-29 13:37:38 -07:00
snipe
bbbeaaee2b Merge pull request #13232 from Godmartinz/labels_overlapping_issue
fixed barcode and info from overlapping
2023-06-29 21:23:31 +01:00
Godfrey M
df90e924b4 prevent labels from overlapping 2023-06-29 13:18:17 -07:00
snipe
630b6496ec Merge pull request #13231 from snipe/fixes/small_fix_for_error_during_seeding
Redirect if the license can’t be found
2023-06-29 21:18:02 +01:00
snipe
7937542dcb Redirect if the license can’t be found
Signed-off-by: snipe <snipe@snipe.net>
2023-06-29 21:15:50 +01:00
akemidx
d0212d4bda formatting fix 2023-06-29 15:39:19 -04:00
snipe
e236bf412c Merge pull request #13230 from snipe/fixes/windows_backup_filename_colon_wtf_issue
Fixed windows backup filename - swapped colon in timestamp to hyphen to handle windows filesystems
2023-06-29 20:37:09 +01:00
snipe
fb9b3a5453 Switched from a colon to a hyphen to handle windows filesystems
Signed-off-by: snipe <snipe@snipe.net>
2023-06-29 20:32:20 +01:00
snipe
faf2a235fb Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-06-29 20:31:13 +01:00
snipe
9f99f8275c Merge pull request #13229 from Godmartinz/status_label_color
fixed custom fields labels being unreadable
2023-06-29 20:21:46 +01:00
slong753
8cee3a8218 ok, @marcusmoore was right all along
i just didn't get it
2023-06-29 14:06:52 -05:00
Godfrey M
f83effbb85 removed unnecessary css rule 2023-06-29 11:25:40 -07:00
Godfrey M
d4cddebba5 fixes custom fields labels being unreadable 2023-06-29 11:21:21 -07:00
snipe
825e988dfa Merge pull request #13228 from snipe/bug/sc-23434
Use proper alias for table scope
2023-06-29 17:11:50 +01:00
snipe
bcefe73c9c Use proper alias for table scope
Signed-off-by: snipe <snipe@snipe.net>
2023-06-29 16:52:09 +01:00
slong753
826ea0ded8 move colon to blade based on a comment 2023-06-29 10:40:04 -05:00
snipe
a3096e1b47 Merge pull request #13219 from inietov/features/cancel_request_asset
Cancel requested assets without checkin/out [ch-17606]
2023-06-29 16:18:13 +01:00
snipe
16ce06a3cc Merge pull request #13222 from snipe/feature/sc-23427
Fixed #13213 - Use the Helper::parseEscapedMarkedown in notes
2023-06-29 16:16:25 +01:00
snipe
8be3a6985b Merge pull request #13227 from snipe/bug/sc-23433
More reshuffling of scopes in assets API
2023-06-29 16:10:26 +01:00
snipe
4c3a306a6e More shuffling of scopes
Signed-off-by: snipe <snipe@snipe.net>
2023-06-29 13:35:41 +01:00
Ivan Nieto Vivanco
011726154c Set rtd_location if a location is given at checkin 2023-06-29 03:16:59 -06: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
akemidx
af03b9f140 user department clarification & translation for that phrase. will be used in a later PR 2023-06-28 17:45:13 -04:00
snipe
f7f2d799f2 Merge pull request #13223 from inietov/fixes/delete_notes_map_from_asset_importer
Delete notes column map from assets importer
2023-06-28 20:06:33 +01: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
Ivan Nieto Vivanco
a4b8723dcb Delete notes column map from assets importer 2023-06-28 11:38:51 -06:00
Ivan Nieto Vivanco
e2c2736a9c Delete (gulp) Form for bulk edit since is not used in this view 2023-06-28 11:23:37 -06:00
Ivan Nieto Vivanco
85e717bc4e Fix cancel button style and translate title 2023-06-28 10:38:44 -06:00
snipe
161f4c8d83 Merge pull request #13045 from akemidx/feature/sc-23261
Checkin/out info on side bar
2023-06-28 16:41:21 +01:00
slong753
8b8e7cb5ee couple translation strings 2023-06-28 10:17:28 -05:00
snipe
e1fdfd01f6 Merge pull request #13211 from marcusmoore/company-scoping
Improve testing around company scoping
2023-06-28 16:17:07 +01:00
snipe
4278471d81 Merge pull request #13207 from Godmartinz/half_year_dep_fix
adds half_year fix from jdickerson71388
2023-06-28 15:12:30 +01:00
snipe
e3f381a1e1 Merge pull request #13212 from marcusmoore/feature/sc-23419
Allow running tests in parallel
2023-06-28 15:12:13 +01:00
snipe
8d8adc1639 Use the Helper::parseEscapedMarkedown in notes
Signed-off-by: snipe <snipe@snipe.net>
2023-06-28 15:02:32 +01:00
Brady Wetherington
51424d01a9 Merge branch 'develop' into snipeit_v7 2023-06-28 14:25:33 +01:00
snipe
a455f67d62 Merge pull request #13216 from marcusmoore/bug/sc-23420
Fix translation string in user importer
2023-06-28 07:03:11 +01:00
snipe
b6a11cde65 Merge pull request #13218 from marcusmoore/chore/sc-23424
Have ChipperCI run on each PR
2023-06-28 07:01:14 +01:00
snipe
a8d4494e68 Merge pull request #13220 from marcusmoore/bug/sc-23425
Add missing relationship check in Asset Transformer
2023-06-28 06:59:33 +01:00
Marcus Moore
ab51857854 Check to see if model relationship exists before using it 2023-06-27 19:35:55 -07:00
Ivan Nieto Vivanco
8496e64e16 Adds ternary to set a quantity when needed 2023-06-27 18:37:22 -06:00
Ivan Nieto Vivanco
b4b84f91d0 Redirect to correct page after cancel action 2023-06-27 18:25:38 -06:00
Ivan Nieto Vivanco
1c29bd37a6 Added feature to cancel requests from the Requested Assets view 2023-06-27 18:11:10 -06:00
Marcus Moore
6df7be8c13 Have ChipperCI run on each PR 2023-06-27 16:55:20 -07:00
Ivan Nieto Vivanco
eb4d764601 Refactor Requestable@cancelRequest() firm to admit a user_id so we can cancel a request of whatever user we want 2023-06-27 17:13:11 -06:00
Ivan Nieto Vivanco
b647a8fcd2 Change the inline form HTML label to the Form:: facade 2023-06-27 17:02:25 -06:00
Ivan Nieto Vivanco
62347a56ba Add button with cancel action in requested assets view 2023-06-27 16:41:30 -06:00
Marcus Moore
b0177d513a Fix translation 2023-06-27 12:37:19 -07:00
slong753
e8988bf51e add list 2023-06-26 20:22:27 -05:00
Marcus Moore
3f09e6017b Install paratest to allow for parallel test running 2023-06-26 16:22:28 -07: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
Marcus Moore
2abdb8a5fd Revert unneeded changes 2023-06-26 14:01:09 -07:00
Marcus Moore
7cb22d3d49 Remove incomplete tests 2023-06-26 14:00:53 -07:00
slong753
691faf6340 ok, this kind of works - pr needs some clean up 2023-06-26 14:56:07 -05:00
Marcus Moore
3cb0920411 Merge branch 'develop' into company-scoping 2023-06-26 12:32:10 -07:00
Godfrey M
114d946437 adds half_year fix from jdickerson71388 2023-06-26 11:26:46 -07:00
snipe
49b50d81ee Merge pull request #13200 from snipe/bug/sc-23417
Set table alias for model number sort scope
2023-06-26 08:29:16 +01:00
snipe
4f7b2836b5 Set table alias for model number sort scope
Signed-off-by: snipe <snipe@snipe.net>
2023-06-26 08:27:17 +01:00
Marcus Moore
acd06927ac Add helper method for authenticating with passport 2023-06-22 17:37:30 -07:00
Spencer Long
f646623a5e Merge branch 'develop' into bulk_edit_custom_fields 2023-06-22 18:00:31 -05:00
Marcus Moore
a35d83d14a Migrate to response macros for readability 2023-06-22 14:41:56 -07:00
akemidx
8df9db76bc column ordering fix 2023-06-22 17:12:40 -04:00
akemidx
8725d40f8d current value added to asset index page. translations for this in reports 2023-06-22 17:00:42 -04:00
snipe
8c6bde335e Merge pull request #13196 from inietov/fixes/default_status_labels_when_import
Fixed issue when importing Assets and no status labels exists [sc-23359]
2023-06-22 21:34:25 +01:00
snipe
b2d74f7e95 Merge pull request #13186 from snipe/bug/sc-23386
Moved logic for tighter constraints when ids are passed
2023-06-22 21:32:36 +01:00
snipe
78d8e32a22 Fixed weird order number thing
Signed-off-by: snipe <snipe@snipe.net>
2023-06-22 21:16:24 +01:00
snipe
4029efebfd Merge pull request #13159 from Godmartinz/audit_image_bug
fixed audit log image not appearing
2023-06-22 21:11:39 +01:00
Marcus Moore
8aae5beaba Add explicit select back to query 2023-06-22 13:09:08 -07:00
Marcus Moore
a8133f62e8 Add explicit select back to query 2023-06-22 13:07:49 -07:00
Ivan Nieto Vivanco
67e47a7d8b Add guard clause to obtain the default ID of imported asset's status label 2023-06-22 13:53:58 -06:00
Marcus Moore
a333d7b72f Add context to incomplete tests 2023-06-22 12:48:09 -07:00
Marcus Moore
ab5fed09db Remove scopeCompanyables call from AssetsController@requestable 2023-06-22 12:36:43 -07:00
Marcus Moore
74b072f1b5 Improve messaging in testing helper 2023-06-22 12:36:30 -07:00
Marcus Moore
0a5e1e3190 Remove scopeCompanyables call from AssetsController@selectlist 2023-06-21 17:21:36 -07:00
Marcus Moore
effd969284 Scaffold test before removing scopeCompanyables call from AssetsController@selectlist 2023-06-21 17:15:02 -07:00
Marcus Moore
fd55c99b87 Remove scopeCompanyables call from AssetsController@index 2023-06-21 16:29:44 -07:00
Marcus Moore
af77fefc61 Scaffold test before removing scopeCompanyables call from AssetsController 2023-06-21 16:19:56 -07:00
Marcus Moore
65e8e4e163 Guard against attempting to use invalid property 2023-06-21 16:18:09 -07:00
snipe
17a10a4342 Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2023-06-21 19:06:21 +01:00
snipe
5d4e704fac Added a comment
Signed-off-by: snipe <snipe@snipe.net>
2023-06-21 09:26:54 +01:00
snipe
2d9ddab3f0 Moved logic for tighter constraints when ids are passed
Signed-off-by: snipe <snipe@snipe.net>
2023-06-21 09:24:17 +01:00
akemidx
4b8a08edc1 typo 2023-06-20 19:32:16 -04:00
akemidx
1a407dc05b user department now in side view of asset view page 2023-06-20 19:17:14 -04:00
akemidx
00fd541963 improve logging clarity 2023-06-15 15:09:14 -04:00
snipe
f890e1f8b1 Merge pull request #13171 from snipe/features/importer/allow_update_by_user_id
Accept user ID as authoratative field for updates
2023-06-15 20:08:20 +01:00
akemidx
eda5bbf305 fix to allow empty SN 2023-06-15 14:42:34 -04:00
snipe
7a425f8a49 Merge pull request #13093 from NojoudAlshehri/features/added_asset_tag_colum_in_requestable_assets
feature: Added asset_tag column in requestable assets page
2023-06-15 19:37:18 +01:00
snipe
21a27f43a9 Merge pull request #13158 from Godmartinz/asset_maint_warranty_bug
Added warranty confirmation to asset maintenance table
2023-06-15 19:34:16 +01:00
snipe
09d65f810e Merge pull request #13124 from m4us1ne/fix_dompdf_chroot
Fixed #12434: Include Docker Specific Paths for dompdf chroot
2023-06-15 19:32:34 +01:00
snipe
004992086e Merge pull request #13098 from ak-piracha/feature/snipe-13049-status-label-chart-color
Fixed #13098: Status Label Chart Color, resets to default when editing a Status Label
2023-06-15 16:55:32 +01:00
snipe
6c684bccd0 Accept user ID as authoratative field for updates
Signed-off-by: snipe <snipe@snipe.net>
2023-06-15 10:02:05 +01:00
akemidx
df6b4ff349 tagging code 2023-06-14 15:51:14 -04:00
akemidx
efaed3d02c making serial number logic checked against for new imports 2023-06-14 15:32:47 -04:00
Godfrey M
ee50906e44 attempt to add warranty to api controller 2023-06-13 11:20:55 -07:00
snipe
157a4341ea Merge pull request #13041 from snipe/features/refactor_importer_for_localization
Refactor importer for localization
2023-06-13 18:12:07 +01:00
snipe
f1bf7267f7 Merge pull request #13164 from snipe/localizations/updated_strings
Updated translation strings
2023-06-13 17:24:01 +01:00
snipe
0bb8cc63c5 Updated translation strings
Signed-off-by: snipe <snipe@snipe.net>
2023-06-13 17:12:01 +01:00
Godfrey M
fc86530c94 uses the trueFalseFormatter now 2023-06-13 09:10:42 -07:00
Godfrey M
6dd7181d09 fixed audit log image not appearing 2023-06-12 12:10:19 -07:00
Godfrey M
69325beddb adds warranty confirmation to asset maintenance table 2023-06-12 11:03:32 -07:00
Brady Wetherington
f5ff9b2208 Merge branch 'develop' into snipeit_v7 - 2023-06-12 2023-06-12 16:56:23 +01:00
snipe
d1ab139b0f Add @qay21 as a contributor 2023-06-12 14:05:43 +01:00
snipe
dc43985884 Applied #13143 to develop
Signed-off-by: snipe <snipe@snipe.net>
2023-06-12 14:05:26 +01:00
Lukas Jung
9fca8c2438 Fixed #12434: Include Docker Specific Paths for dompdf chroot 2023-06-09 11:00:46 +02:00
snipe
c78c69700f Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2023-06-08 08:49:55 +01:00
snipe
4775eef392 Merge pull request #13140 from snipe/security/misc_libraries
Updated libraries and dev assets
2023-06-08 08:48:55 +01:00
snipe
14727700ab Updated libraries and dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-06-08 08:48:18 +01:00
snipe
a6b1320b39 Add @stefanstidlffg as a contributor 2023-06-08 08:11:34 +01:00
snipe
4672f6a699 Merge pull request #13139 from snipe/security/updated_webpack
Updated webpack, added new dev assets
2023-06-08 08:11:07 +01:00
snipe
03233465c7 Updated webpack, added new dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-06-08 08:10:12 +01:00
snipe
8a72056bfd Merge pull request #13123 from osterr-forschungsforderungsges-mbh/fix-slack-notifications
fix slack channel notifications
2023-06-08 05:51:08 +01:00
Marcus Moore
7672861b96 Scaffold test before removing scopeCompanyables call from DashboardController 2023-06-07 17:38:23 -07:00
Marcus Moore
6f5252449e Scaffold test before removing scopeCompanyables call from UsersController 2023-06-07 16:25:18 -07:00
Marcus Moore
0f6051bbe5 Inline method call 2023-06-07 16:18:02 -07:00
Marcus Moore
abaf59c990 Extract and use helper methods 2023-06-07 16:16:30 -07:00
Marcus Moore
27d4d107bb Scaffold test before removing scopeCompanyables call from DepartmentsController 2023-06-07 16:10:29 -07:00
Marcus Moore
8e6e525b47 Remove scopeCompanyables call from LicensesController 2023-06-07 16:09:45 -07:00
Marcus Moore
a18f5e7fc0 Remove scopeCompanyables call from ConsumablesController 2023-06-07 14:22:22 -07:00
snipe
adb2757532 Add @NojoudAlshehri as a contributor 2023-06-07 16:52:22 +01:00
snipe
b57730ee9d Added missing assets_fields declaration
Signed-off-by: snipe <snipe@snipe.net>
2023-06-07 15:52:18 +01:00
snipe
9335bf7033 Merge pull request #13122 from marcusmoore/fixes/increase-consumable-factory-name-length
Fixes potentially invalid name in consumable factory
2023-06-07 11:43:13 +01:00
snipe
45b76c4c75 Merge pull request #13127 from NojoudAlshehri/fixes/typo-in-a-html-tag
Fix of typo in an HTML tag
2023-06-07 09:21:51 +01:00
NojoudAlshehri
d06bdc2db4 Fix of typo in an HTML tag 2023-06-07 13:46:17 +07:00
Marcus Moore
48850f3597 Remove scopeCompanyables call from ComponentsController 2023-06-06 18:02:18 -07:00
Marcus Moore
4fb86ad2fb Get name as a string and not an array 2023-06-06 16:31:26 -07:00
Marcus Moore
42a4941ad2 Ensure consumable name is valid in factory 2023-06-06 16:31:26 -07:00
Marcus Moore
6585aa0cf0 Add unit tests for company scoping 2023-06-06 16:31:14 -07:00
Stefan Stidl
ad8c36a51a fix: slack channel 2023-06-06 10:30:01 +02:00
Marcus Moore
d3a0bacb98 Get name as a string and not an array 2023-06-05 12:57:09 -07:00
Marcus Moore
371d11305b Ensure consumable name is valid in factory 2023-06-05 12:17:44 -07:00
snipe
7ae260b489 More license translations
Signed-off-by: snipe <snipe@snipe.net>
2023-06-01 19:51:06 +01:00
snipe
ff480a7247 Merge pull request #13114 from inietov/fixes/broken_sorting_manufacturers
Fixed Broken order by manufacturer in Assets table [sc-23313]
2023-06-01 19:40:16 +01:00
Ivan Nieto Vivanco
f9a20bc917 Replace join with left join in pertinent eloquent query 2023-06-01 12:08:51 -06:00
ak-piracha
daf6bcb6d5 follow best practices when working with blade and javascript 2023-06-01 11:07:21 +09:30
snipe
e431cd5146 Merge pull request #13085 from inietov/fixes/checkboxes_not_holding_value
Fixed #12978 Custom Field Checkboxes not holding assigned values
2023-05-31 10:55:37 -04:00
snipe
35942361b6 Add @ak-piracha as a contributor 2023-05-31 15:51:39 +01:00
snipe
596b510a25 Merge pull request #13108 from ak-piracha/fixes/component_delete_showing_in_assest
Fixes: issue #13073: deleted component addearing in asset component t…
2023-05-31 10:50:34 -04:00
ak-piracha
1cdf089306 Fixes: issue #13073: deleted component addearing in asset component tab fixed 2023-05-31 00:11:11 +09:30
snipe
13e8f91a59 Fixed typo
Signed-off-by: snipe <snipe@snipe.net>
2023-05-29 18:18:46 -04:00
ak-piracha
825a9a384d Fixed 2023-05-29 14:07:53 +09:30
NojoudAlshehri
980cb53efa Added asset_tag column in requestable assets page 2023-05-27 07:05:59 +07:00
snipe
60d2046b6d Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-05-24 16:13:33 -07:00
snipe
67e0eb3193 Merge pull request #13046 from Godmartinz/asset_info_overflow
Added Asset info overflow-wrap
2023-05-24 16:13:01 -07:00
snipe
44cbb0c2e9 Merge branch 'develop' into asset_info_overflow 2023-05-24 16:11:34 -07:00
snipe
fb5e33c50f Updated hash
Signed-off-by: snipe <snipe@snipe.net>
2023-05-24 16:03:15 -07:00
snipe
d7f4fa146b Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-05-24 16:02:28 -07:00
snipe
064dbdd3d4 Fixed missing brace from conflict
Signed-off-by: snipe <snipe@snipe.net>
2023-05-24 16:02:23 -07:00
snipe
cc07921608 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-05-24 15:59:52 -07:00
snipe
267a0ffc59 Merge pull request #13077 from Godmartinz/fix_unclickable_nav_bar_and_notifcation_block
fixes mobile nav bar and notification position
2023-05-24 15:58:27 -07:00
snipe
9086cb5310 Merge branch 'develop' into fix_unclickable_nav_bar_and_notifcation_block 2023-05-24 15:56:01 -07:00
Ivan Nieto Vivanco
f4947bfa93 Use trim() function when format the custom field values as array 2023-05-24 04:06:31 -06:00
snipe
5e96fd200f Refactor to remove general_fields
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 20:31:53 -07:00
snipe
d020825a17 Renamed import samples
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:31:42 -07:00
snipe
3ef081e739 Indenting
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:28:42 -07:00
snipe
47fa490e8a More translations
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:28:23 -07:00
snipe
01768bf649 Renamed sample csv
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:23:29 -07:00
snipe
52cf54d211 New assets CSV
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:22:08 -07:00
snipe
55683c29dc Removed method that does the same return
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:22:00 -07:00
snipe
f355a6e9e1 Added first name and last name
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:21:31 -07:00
snipe
3e4426c68c Clearer comments
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 19:20:52 -07:00
snipe
2e5486a62e Merge pull request #13076 from marcusmoore/fixes/allow-multi-column-search-in-sqlite
Dynamically adapt concatenation searches for MySQL and sqlite
2023-05-23 16:27:12 -07:00
Marcus Moore
0a3d46824e Automatically add table prefixes when building multi-column search string 2023-05-23 15:58:58 -07:00
snipe
f69caf77e5 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 14:57:57 -07:00
snipe
61d5bd8567 Removed comment
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 14:57:15 -07:00
snipe
80e8022c76 Merge pull request #13044 from Godmartinz/bug/sc-23260_multi_select_example_text
Bug/sc 23260 multi select example text
2023-05-23 14:45:55 -07:00
Marcus Moore
6300909fee Add test for searching for user's first and last name 2023-05-23 13:39:01 -07:00
Marcus Moore
b2b6f0cf96 Use new dynamic scope where possible 2023-05-23 13:38:50 -07:00
Marcus Moore
054d71aedc Add docblock 2023-05-23 13:37:04 -07:00
Marcus Moore
9078d4c71c Add dynamic scope for prettier multiple column search 2023-05-23 13:35:19 -07:00
snipe
d4c5a4eb2e More aliases
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 13:18:32 -07:00
snipe
35794c8ba2 More translations
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 12:57:48 -07:00
snipe
62384260bc Clarifying comment
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 12:57:40 -07:00
snipe
f2e9b41199 More user fields in asset importer
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 12:57:34 -07:00
snipe
479350ed7b Removed unneeded mapping file
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 12:57:24 -07:00
Godfrey M
68a43cb590 fixes mobile nav bar and notification position 2023-05-23 12:43:32 -07:00
snipe
809dcdc50c Updated CSVs
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 12:13:17 -07:00
snipe
d0f5a044ba More refactoring
Signed-off-by: snipe <snipe@snipe.net>
2023-05-23 12:13:06 -07:00
Marcus Moore
05a2e568d7 Add comment 2023-05-23 11:37:09 -07:00
snipe
fbed18a984 Merge pull request #13075 from inietov/fixes/api_incorrect_remaining_accessories
Fixed #13074 [API] Remaining accessories quantity not correct
2023-05-23 11:08:37 -07:00
Ivan Nieto Vivanco
086265455d Pass user count to the eloquent query 2023-05-23 11:53:09 -06:00
Marcus Moore
f40e722397 Add docblock 2023-05-22 17:44:17 -07:00
Marcus Moore
50234bc9a5 Formatting 2023-05-22 17:40:06 -07:00
Marcus Moore
9b512648a3 Update searchRelations in Searchable trait 2023-05-22 17:33:19 -07:00
Marcus Moore
64e83ed9f5 Update scopeAssignedSearch in Asset 2023-05-22 16:54:54 -07:00
snipe
0c7acd6a3b Merge pull request #13070 from inietov/fixes/accessory_image_shown_when_disabled
Fixed #12947 Accessory image in checkin email when Show images in emails is disabled
2023-05-22 15:30:14 -07:00
Ivan Nieto Vivanco
6df9a33eab Add a condition to check if images should be shown in notification 2023-05-22 16:24:16 -06:00
snipe
f9449aa81f Merge pull request #13069 from marcusmoore/fixes/add-eager-load-to-asset-model-endpoint
Add eager loading to Asset Models controller
2023-05-22 14:39:32 -07:00
Marcus Moore
a6eeae6541 Eager load fieldset default values in asset model endpoint 2023-05-22 14:19:03 -07:00
snipe
b2d922f127 New user import sample CSV
Signed-off-by: snipe <snipe@snipe.net>
2023-05-22 13:20:20 -07:00
snipe
96e86501ad Additional alias fields
Signed-off-by: snipe <snipe@snipe.net>
2023-05-22 13:20:08 -07:00
snipe
4dfe6f0a28 Added gravatar, avatar, start_date and end_date to user importer
Signed-off-by: snipe <snipe@snipe.net>
2023-05-22 13:19:57 -07:00
snipe
511d83cc47 Added/fixed a few more translations
Signed-off-by: snipe <snipe@snipe.net>
2023-05-20 14:52:42 -07:00
snipe
2171d8c83c Removed requestable field in sample consumable CSV
Signed-off-by: snipe <snipe@snipe.net>
2023-05-20 14:52:28 -07:00
snipe
0ea29a0224 Updated translations
Signed-off-by: snipe <snipe@snipe.net>
2023-05-20 14:21:36 -07:00
snipe
18bedb736e Removed item number, since not everything will have it
Signed-off-by: snipe <snipe@snipe.net>
2023-05-20 14:21:29 -07:00
snipe
1396e314c4 Updated arrays with translations
Signed-off-by: snipe <snipe@snipe.net>
2023-05-20 14:21:13 -07:00
snipe
b75109dcac Added component mapping switch
Signed-off-by: snipe <snipe@snipe.net>
2023-05-20 14:20:49 -07:00
snipe
b7149d8339 Added translation
Signed-off-by: snipe <snipe@snipe.net>
2023-05-20 14:20:38 -07:00
Marcus Moore
2d86c8f030 Update advancedTextSearch methods in Asset and User models 2023-05-18 17:06:41 -07:00
Marcus Moore
3a9670930d Define required fields in Custom Field seeder so sqlite can be seeded 2023-05-18 13:17:35 -07:00
Marcus Moore
85974c7f65 Apply formatting 2023-05-18 13:16:52 -07:00
Marcus Moore
ffbde46180 Simplify sqlite query 2023-05-18 13:06:50 -07:00
Marcus Moore
d8d672c4c1 Move multiple column search function to Searchable trait 2023-05-18 13:05:40 -07:00
Marcus Moore
9cb0decf35 Adapt multiple column search based on database driver 2023-05-18 12:54:00 -07:00
Brady Wetherington
a9c7dbd17a Shift PHP version requiremeents for Snipe-IT v7 to be php 8.0-8.2 2023-05-17 17:51:02 -07:00
Brady Wetherington
09fdc946a0 Merge branch 'develop' into snipeit_v7
Had to do some asset rebuilds, and a composer update
2023-05-17 17:37:10 -07:00
Godfrey M
608d07d03c adds overflow-wrap to asset info table 2023-05-17 13:08:53 -07:00
Godfrey M
addd806653 testing overflow solutions 2023-05-17 10:47:50 -07:00
Godfrey M
fe60309dfd adds padding to multi select2 inputs 2023-05-17 10:19:25 -07:00
akemidx
deca80ba71 checkin/out info on side bar 2023-05-17 13:17:48 -04:00
Godfrey M
448472b6d3 testing input paddings 2023-05-17 09:45:45 -07:00
snipe
2c4c9a16c9 Refactored the static arrays into mount arrays for translations
Signed-off-by: snipe <snipe@snipe.net>
2023-05-16 22:31:58 -07:00
snipe
d228b7f347 Remove 99% of the defaultMap stuff (might pull all of this later)
Signed-off-by: snipe <snipe@snipe.net>
2023-05-16 22:31:01 -07:00
snipe
7012018e22 Removed todo
Signed-off-by: snipe <snipe@snipe.net>
2023-05-16 22:30:17 -07:00
snipe
13c6a7f89b Merge pull request #13039 from snipe/features/add_eol_date_to_importer
Added EOL date to importer
2023-05-16 20:12:10 -07:00
snipe
3296716dfa Added EOL date to importer
Signed-off-by: snipe <snipe@snipe.net>
2023-05-16 19:06:35 -07:00
snipe
c4876865cf Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-05-16 17:36:58 -07:00
snipe
3cbb4620c3 Merge pull request #13008 from Godmartinz/importer_happy_changes
Added standardized colors to the importer
2023-05-16 17:26:32 -07:00
snipe
5a1e6c8e29 Merge pull request #13003 from marcusmoore/chipper-config-updates
Disable browser tests in ChipperCI
2023-05-16 17:26:09 -07:00
snipe
f1575d2020 Merge pull request #13024 from Godmartinz/adds_localization_to_checkout_notif
adds translation to checkout notification
2023-05-16 17:25:50 -07:00
snipe
71234228b4 Merge pull request #13025 from Godmartinz/archived_clears_assigned_to
removes assigned_to if archived
2023-05-16 17:25:24 -07:00
snipe
4ca914d773 Merge pull request #13038 from uberbrady/fix_asset_checkout_on_update
Importer fix for non-Location imports
2023-05-16 16:41:27 -07:00
Brady Wetherington
2eb34d423f Importer fix for non-Location imports 2023-05-16 16:33:07 -07:00
snipe
b9b9eb86d9 Merge pull request #13036 from snipe/features/multiselect_locations_custom_report
Added multi-select option for location, more to custom report
2023-05-16 16:29:13 -07:00
snipe
9e4e9cc708 Merge pull request #13037 from snipe/fixes/actions_text
Uses actions text in backups table
2023-05-16 16:06:05 -07:00
snipe
fe92667812 Use actions text in backups table
Signed-off-by: snipe <snipe@snipe.net>
2023-05-16 16:02:48 -07:00
snipe
02cacf76c6 Additional multi-select options for custom report
Signed-off-by: snipe <snipe@snipe.net>
2023-05-16 13:58:21 -07:00
Godfrey M
8e3cbdad90 removes assigned_to if archived 2023-05-15 11:52:57 -07:00
Godfrey M
46d6783fc5 adds translation to checkout notification 2023-05-15 09:01:30 -07:00
akemidx
ba4fc146e2 Merge branch 'delete_asset_from_view_page' of https://github.com/akemidx/snipe-it into delete_asset_from_view_page 2023-05-10 19:30:11 -04:00
akemidx
1916594d27 fixing translation 2023-05-10 19:16:11 -04:00
Godfrey M
763176c86b standardizes the importer colors no matter the theme 2023-05-10 14:52:08 -07:00
snipe
0f3b77ee2d Added multi-select option to custom report
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 14:45:31 -07:00
snipe
869d195b35 Merge pull request #13007 from snipe/fixes/multiselect_company
Fixed multiselect for companies
2023-05-10 13:17:36 -07:00
snipe
a49257ad4b Wrong eval
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 13:16:59 -07:00
snipe
c6eef86661 Fixed multiselect for companies
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 13:15:22 -07:00
snipe
71c7c82398 Merge pull request #13006 from snipe/fixes/12831_array_for_company_id
Fixes PR #12831 use array bracket for multi select company
2023-05-10 12:36:59 -07:00
snipe
23e3d18931 Used brackets for multiselect company
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 12:35:30 -07:00
slong753
5e34ffa2b0 wip 2023-05-10 14:08:12 -05:00
snipe
5f6e528560 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2023-05-10 11:36:28 -07:00
snipe
9f39d71f16 Merge pull request #12831 from Godmartinz/adds_multi_select_to_custom_report
Added Multiselect of companies for custom reports
2023-05-10 11:36:21 -07:00
snipe
4c78b49b97 Add @vikaas-cyper as a contributor 2023-05-10 11:31:26 -07:00
snipe
aca287d28c Merge pull request #13004 from snipe/security/upgrade_webpack
Updated webpack, new asset files
2023-05-10 11:23:02 -07:00
snipe
1f5e4309fa Updated webpack, new asset files
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 11:20:06 -07:00
Marcus Moore
a1a11d788f Disable browser tests in ChipperCI 2023-05-10 11:06:05 -07:00
snipe
b8a59cc2d8 Merge branch 'master' into develop 2023-05-10 09:32:26 -07:00
snipe
04aedce47e Bumped hash
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 09:29:42 -07:00
snipe
d648e9a01c Added Google test user
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 09:13:34 -07:00
snipe
7c77f4a697 Extra debugging
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 09:10:53 -07:00
akemidx
537aa04c9a Merge branch 'develop' into delete_asset_from_view_page 2023-05-10 09:30:54 -04:00
snipe
27e0484072 I lied. Missed one
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 03:12:22 -07:00
snipe
ec76de607b Final google login tweaks
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 03:08:29 -07:00
snipe
14da8934c5 Few more login page tweaks
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:53:11 -07:00
snipe
ed370a0104 Added translations
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:47:28 -07:00
snipe
b99640ecb2 Added ends_with validation message
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:40:55 -07:00
snipe
8bad72a80f Added validation on google client ID
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:40:45 -07:00
snipe
f3c977aa9d Nicer button
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:37:01 -07:00
snipe
788c03ef57 Hide client secret if app is locked
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:22:49 -07:00
snipe
3c00f68bda Added translation string for google auth failure
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:18:50 -07:00
snipe
7062583710 Check for http or https in avatar value
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:18:38 -07:00
snipe
2dd32d8785 Re-add the image update
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:18:27 -07:00
snipe
ff66a938c1 Clearer comments
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:18:15 -07:00
snipe
7f0e677908 Use normal translation style
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 02:18:05 -07:00
snipe
e8a0c7f2ce Remove avatar update, since we don’t take URLs for that
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:59:33 -07:00
snipe
e950cf4279 Switch to using username as match for google login
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:58:36 -07:00
snipe
567a800c51 Added debugging
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:47:52 -07:00
snipe
e5eb5932ca Create constructor to override expected config variables
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:37:03 -07:00
snipe
a90fc1ab59 Merge pull request #12994 from snipe/features/google_socialite
Google OAuth login
2023-05-10 01:23:37 -07:00
snipe
3612526632 Disallow saving data if app is locked
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:14:54 -07:00
snipe
1ef4ea6381 Very ugly login shim just to test functionality
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:14:31 -07:00
snipe
37bc47290c Disabled fields in demo mode
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:12:55 -07:00
snipe
4da40792ea Use google logo
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 01:08:28 -07:00
snipe
63bf93b786 Pulled redirect from settings
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:56:04 -07:00
snipe
f57e39191d Added google settings blade
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:55:16 -07:00
snipe
6ab214d3a6 Added google option to settings index
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:55:04 -07:00
snipe
3fb5188037 Removed redirect option
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:54:46 -07:00
snipe
aefd330e4e Added methods for google settings
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:54:28 -07:00
snipe
b7e8ce3064 Changed redirect
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:54:14 -07:00
snipe
b183e53c45 Added settings routes for google auth
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:34:48 -07:00
snipe
054a2ab9d4 Add validation and fillable fields
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:34:31 -07:00
snipe
bc9b47c46d Removed env dependency, switched to DB
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:27:47 -07:00
snipe
72d1c08fbc Added migration
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:21:17 -07:00
snipe
c52b48c383 Google oauth login
Signed-off-by: snipe <snipe@snipe.net>
2023-05-10 00:14:28 -07:00
snipe
11cd875c6d Merge remote-tracking branch 'origin/develop' 2023-05-09 22:42:45 -07:00
snipe
a1ec8cf490 Merge pull request #12993 from snipe/fixes/checkbox_layout_in_ldap
Tightened up some layout issues, checkbox issues in LDAP settings
2023-05-09 22:37:49 -07:00
snipe
0680405f4d Tightened up some layout issues, checkbox issues in LDAP settings
Signed-off-by: snipe <snipe@snipe.net>
2023-05-09 22:34:46 -07:00
snipe
cbe70c9cc1 Merge remote-tracking branch 'origin/develop' 2023-05-09 20:14:44 -07:00
snipe
6a7bab453f Made spacing more compact
Signed-off-by: snipe <snipe@snipe.net>
2023-05-09 20:14:00 -07:00
snipe
7412bc32e2 Merge pull request #12991 from snipe/fixes/accessories_view
Fixed width of columns in details
2023-05-09 20:11:36 -07:00
snipe
ec4697fd3e Merge remote-tracking branch 'origin/develop' 2023-05-09 19:45:10 -07:00
snipe
5a461d62bc Merge pull request #12990 from snipe/fixes/12881_missing_icon
Added icon field back into assets page
2023-05-09 19:44:30 -07:00
snipe
999dc3c358 Added icon field back into assets page
Signed-off-by: snipe <snipe@snipe.net>
2023-05-09 19:43:37 -07:00
snipe
a10652797f Fixed width of columns in details
Signed-off-by: snipe <snipe@snipe.net>
2023-05-09 19:42:32 -07:00
snipe
090cbab60e Merge pull request #12989 from marcusmoore/chipper-ci
Add ChipperCI configuration
2023-05-09 18:09:23 -07:00
Marcus Moore
1e7986d75b Limit ChipperCI to running on push to master or develop 2023-05-09 16:39:56 -07:00
snipe
a43dea3c04 Merge remote-tracking branch 'origin/develop' 2023-05-09 16:29:53 -07:00
Marcus Moore
1f11a8a2c1 Configure Dusk for ChipperCI 2023-05-09 14:45:18 -07:00
Marcus Moore
8d205e80e5 Add ejected pipeline configuration for ChipperCI 2023-05-09 14:44:43 -07:00
snipe
2d5da67b1e Merge pull request #12982 from akemidx/feature/sc-23214
Buttons on the Accessory View Page
2023-05-09 14:26:28 -07:00
slong753
1d2596fc54 wip 2023-05-09 14:58:59 -05:00
snipe
7dd41aa574 Removed whitespace
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 15:49:12 -07:00
snipe
c4d40cdbd4 Merge remote-tracking branch 'origin/develop' 2023-05-08 15:11:25 -07:00
snipe
b76c5206ff Merge pull request #12986 from snipe/features/import_backup_filename
Pass filename to pre-import backup
2023-05-08 15:08:59 -07:00
snipe
17efc78816 Merge pull request #12985 from snipe/fixes/increase_state_from_3_chars
Increase state from 3 chars
2023-05-08 15:08:44 -07:00
snipe
332b017dcc Pass filename for manual backups
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 15:00:02 -07:00
snipe
5960a5425d Pass filename to pre-import backup
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 14:48:26 -07:00
snipe
277618bf16 Added maxlenth to form fields
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 14:13:24 -07:00
snipe
f84f4ffe99 Migration to embiggen state fields
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 14:13:06 -07:00
snipe
f1d85c67f1 Make validation match database fields
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 14:12:54 -07:00
snipe
6cb6beb6c7 Merge remote-tracking branch 'origin/develop' 2023-05-08 13:21:43 -07:00
snipe
6486ea4fb7 Merge pull request #12976 from inietov/fixes/validate_soft-deleted_models_in_asset_model
Refactor of #12955
2023-05-08 13:14:02 -07:00
snipe
d685335aea Merge pull request #12975 from inietov/fixes/import_asset_notes
Fixed Notes field doesn't get populate when creating/updating assets via Importer [sc-23222]
2023-05-08 13:11:50 -07:00
snipe
d70e14de61 Merge pull request #12972 from marcusmoore/bug/sc-23177
Fixes user name missing in accessory acceptance notifications
2023-05-08 13:04:37 -07:00
snipe
480ef23505 Merge remote-tracking branch 'origin/develop' 2023-05-08 12:44:01 -07:00
snipe
4503815ad7 Merge pull request #12984 from snipe/features/check_for_zip_in_backup_filename
Check that the filename we pass ends in zip, add it if not
2023-05-08 12:43:34 -07:00
snipe
ba462d1e93 Check that the filename we pass ends in zip, add it if not
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 12:41:32 -07:00
snipe
3429d1f4b4 Merge remote-tracking branch 'origin/develop' 2023-05-08 12:22:22 -07:00
snipe
0f76eda4af Merge pull request #12983 from snipe/features/add_optional_filename_to_backup_artisan
Add optional filename to backup
2023-05-08 12:21:55 -07:00
snipe
85243423cf Add optional filename to backup
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 12:20:43 -07:00
snipe
a73205f228 Merge remote-tracking branch 'origin/develop' 2023-05-08 11:24:03 -07:00
snipe
06ffe64f62 Merge pull request #12981 from snipe/fixes/wonky_div_when_saml_disabled
Fixed misplaced div when saml is disabled
2023-05-08 11:22:54 -07:00
snipe
223ff5e97e Fixed misplaced div when saml is disabled
Signed-off-by: snipe <snipe@snipe.net>
2023-05-08 11:20:26 -07:00
snipe
fe40902765 Merge remote-tracking branch 'origin/develop' 2023-05-06 06:37:29 -07:00
snipe
689ef433b3 Merge pull request #12979 from snipe/fixes/added_use_for_fieldsets_controller
Added missing use statement
2023-05-06 06:37:01 -07:00
snipe
8b73fa0053 Added missing use statement
Signed-off-by: snipe <snipe@snipe.net>
2023-05-06 06:36:09 -07:00
snipe
3d345d15ac Merge remote-tracking branch 'origin/develop' 2023-05-04 11:01:15 -07:00
snipe
4efa84270a Merge pull request #12974 from snipe/fixes/show_sig_column_regardless_of_sig_status
Show signature column in asset history regardless of “require sig” state
2023-05-04 11:00:51 -07:00
snipe
60515f1262 Show signature column regardless of “require sig” state
Signed-off-by: snipe <snipe@snipe.net>
2023-05-04 10:56:35 -07:00
Ivan Nieto Vivanco
fbb7c55450 Tweak 'exist' rule in Asset->model_id field so it ignores soft-deleted models 2023-05-04 03:12:36 -06:00
Ivan Nieto Vivanco
89fbd60d97 Restore the 'Asset Notes' and 'Model Notes' in the Map Asset Import Fields form 2023-05-04 02:00:04 -06:00
Marcus Moore
96c6d8896f Add additional information to acceptance notifications for assets, accessories, and consumables 2023-05-03 17:04:01 -07:00
Marcus Moore
9efe13bb5e Capitalize "declined" in acceptance in notification 2023-05-03 17:03:22 -07:00
Marcus Moore
4a0b3efd1f Include user's name in Acceptance result notifications for accessories 2023-05-03 14:22:05 -07:00
Marcus Moore
f96d8fe674 Add CheckoutAcceptance factory 2023-05-03 14:21:13 -07:00
snipe
5950ec27ab 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/css/dist/skins/skin-black-dark.css
#	public/css/dist/skins/skin-black-dark.min.css
#	public/css/dist/skins/skin-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/mix-manifest.json
2023-05-03 13:49:36 -07:00
snipe
cd6f6ee8ff Bumped version to 6.1.1-pre
Signed-off-by: snipe <snipe@snipe.net>
2023-05-03 13:47:46 -07:00
akemidx
526c089424 Buttons on the accessory view page 2023-05-03 16:40:06 -04:00
akemidx
67105528d1 Buttons on the accessory view page 2023-05-03 16:31:56 -04:00
akemidx
12f0c42545 buttons added 2023-05-03 16:31:56 -04:00
slong753
815c77f943 wip 2023-05-03 14:49:31 -05:00
snipe
fe710efb40 Merge pull request #12874 from Godmartinz/feature/sc-23130
Adds a checkout range for custom asset reports
2023-05-03 11:43:44 -07:00
snipe
fc53b56481 Merge pull request #12955 from inietov/fixes/error_500_after_sign_and_accept_asset
Fixed Error 500 after sign and accept asset
2023-05-03 11:43:14 -07:00
akemidx
889be83762 replacing route. sorry! 2023-05-03 14:14:18 -04:00
snipe
b716f9f55e Merge pull request #12916 from snipe/features/auto_add_to_fieldset
Added ability to auto-add fields to new fieldsets
2023-05-03 11:04:33 -07:00
snipe
ea17fdeba5 Merge pull request #12846 from snipe/features/livewire_location_import
Location importer via Livewire Importer
2023-05-03 11:02:06 -07:00
snipe
f5cd58e9b7 Unmix return type variables
Signed-off-by: snipe <snipe@snipe.net>
2023-05-03 10:57:02 -07:00
snipe
da4841987e Use translation string
Signed-off-by: snipe <snipe@snipe.net>
2023-05-03 10:55:30 -07:00
snipe
4a643c1252 Merge pull request #12880 from Godmartinz/asset_total_cost
Added component costs to asset view
2023-05-03 10:49:03 -07:00
snipe
cdbd68012f Merge pull request #12878 from joelpittet/patch-2
Use environment variable and default to PHP's sendmail_path
2023-05-03 10:48:39 -07:00
snipe
577fff7d65 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-05-03 10:45:36 -07:00
snipe
79a27085c9 Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2023-05-03 10:43:45 -07:00
snipe
27600e1553 Snyk webpack upgrade
Signed-off-by: snipe <snipe@snipe.net>
2023-05-03 10:43:05 -07:00
snipe
914b2658cc Merge pull request #12943 from marcusmoore/fixes/avoid-loading-unused-models-for-report
Remove the loading of asset maintenances that are not used by view
2023-05-03 10:41:52 -07:00
snipe
6a12d5d9a0 Merge pull request #12964 from marcusmoore/fixes/restrict-php-version
Restrict PHP version to <8.2
2023-05-03 10:40:52 -07:00
snipe
31f1bce16b Merge pull request #12958 from uberbrady/snipeit_v7_merge_develop_05_01_2022
Snipeit v7 merge develop 05 01 2022
2023-05-03 10:40:18 -07:00
snipe
466c2fd47c Merge pull request #12966 from Godmartinz/bug/sc-23161
fixed color differences in dark themes
2023-05-03 10:38:54 -07: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
Godfrey M
87d1a82e35 moar changes to red 2023-05-02 15:15:02 -07:00
Godfrey M
1d494252ef corrections for dark red 2023-05-02 14:05:29 -07:00
Godfrey M
786e8deb91 removed dead space 2023-05-02 13:54:14 -07:00
Godfrey M
0a3cb5286d fixes dark red 2023-05-02 12:37:05 -07:00
Godfrey M
f91e76e0f2 fixes dark blue and btn-warning bg 2023-05-02 12:33:40 -07:00
Godfrey M
af2f288286 fixes dark orange theme 2023-05-02 12:17:22 -07:00
Godfrey M
5de30db0a9 fixes dark green theme 2023-05-02 12:10:55 -07:00
Marcus Moore
48ef8443f5 Restrict PHP to >=7.4.3 <8.2 2023-05-02 12:01:09 -07:00
Godfrey M
47370da924 adds fixes to dark black theme 2023-05-02 11:08:37 -07:00
Brady Wetherington
2f3ddaec20 Merge branch 'develop' into snipeit_v7 2023-05-01 18:09:12 -07:00
snipe
7cd37e6e95 Merge pull request #12957 from uberbrady/fix_webpack_for_v7
Fix webpack for v7
2023-05-01 18:08:46 -07:00
Brady Wetherington
a938009074 Rebuilt assets with new Node and node_modules and package.json 2023-05-01 18:06:51 -07:00
Brady Wetherington
21d08ff742 Whoops! Forgot to commit this before 2023-05-01 18:05:06 -07:00
snipe
da8b41b12a Merge pull request #12956 from uberbrady/upgrade_node_and_packages_for_v7
Updated Node version, and various packages to more recent
2023-05-01 17:33:20 -07:00
Brady Wetherington
6e031727fa Updated Node version, and various packages to more recent 2023-05-01 17:05:10 -07:00
akemidx
2cb1545b83 removing route 2023-05-01 19:51:52 -04:00
snipe
63af17da74 Merge pull request #12954 from marcusmoore/fixes/test-suite-fixes
Clear the settings cache on app destruction
2023-05-01 16:28:47 -07:00
Godfrey M
7711938f4b fixes dark yellow 2023-05-01 16:27:21 -07:00
Marcus Moore
f7d2b62d87 Improve method name 2023-05-01 16:06:28 -07:00
Marcus Moore
da08f6ef8c Add InteractsWithSettings trait to required tests 2023-05-01 16:05:26 -07:00
Marcus Moore
6d594faae7 Clear the settings cache on app destruction 2023-05-01 16:04:43 -07:00
Ivan Nieto Vivanco
6936d76661 Prevent hard fail when retrieving acceptance data 2023-05-01 16:50:18 -06:00
Ivan Nieto Vivanco
1b2d830380 Check if model exists before create asset via API 2023-05-01 16:05:03 -06:00
akemidx
ad7a1d6c3b edits from Github comments 2023-05-01 15:50:48 -04:00
snipe
609b1646e9 Merge remote-tracking branch 'origin/develop' 2023-04-30 18:40:52 -07:00
snipe
031c9c1204 Added nobr tag to prevent external link icon and link from breaking
Signed-off-by: snipe <snipe@snipe.net>
2023-04-30 18:40:40 -07:00
snipe
77b51136cf Merge remote-tracking branch 'origin/develop' 2023-04-30 18:38:19 -07:00
snipe
0222a922a1 Added tooltip
Signed-off-by: snipe <snipe@snipe.net>
2023-04-30 18:20:23 -07:00
snipe
8ad600085a Moved external link icon into link
Signed-off-by: snipe <snipe@snipe.net>
2023-04-30 18:17:56 -07:00
snipe
7fdbc10122 Merge remote-tracking branch 'origin/develop' 2023-04-29 13:49:14 -07:00
snipe
4c27b65d45 Merge pull request #12950 from snipe/fixes/warranty_lookup_validation
Fixed  #12946 - warranty lookup url was not nullable
2023-04-29 13:48:54 -07:00
snipe
aa814cf761 Fixed #12946 - warranty lookup url was not nullable
Signed-off-by: snipe <snipe@snipe.net>
2023-04-29 13:47:52 -07:00
Marcus Moore
3cae32b236 Eager load default locations 2023-04-27 17:13:09 -07:00
Marcus Moore
429c4cb99f Remove the loading of asset maintenances that are not used by view 2023-04-27 17:12:53 -07:00
snipe
e250d4c884 Merge remote-tracking branch 'origin/develop' 2023-04-27 17:00:29 -07:00
snipe
8b476e55b6 Merge pull request #12941 from akemidx/feature/sc-23153
Created At and Updated At fields on License table view
2023-04-27 16:59:30 -07:00
snipe
b76d2973f7 Merge pull request #12928 from snipe/features/make_hashing_work_rounds_an_env
Env-ify hashing variables, setting the normal defaults
2023-04-27 16:57:45 -07:00
snipe
b001f6771d Merge remote-tracking branch 'origin/develop' 2023-04-27 16:28:42 -07:00
snipe
956bc41e48 Merge pull request #12942 from snipe/bug/sc-23197
Added missing case for licenses for item_count
2023-04-27 16:28:12 -07:00
snipe
567e19bcc0 Added missing case for licenses for item_count
Signed-off-by: snipe <snipe@snipe.net>
2023-04-27 16:26:50 -07:00
akemidx
67a2b796a4 requested edits 2023-04-27 19:19:53 -04:00
akemidx
1c60d686bd Merge remote-tracking branch 'origin/delete_asset_from_view_page' into delete_asset_from_view_page
# Conflicts:
#	resources/views/hardware/view.blade.php
2023-04-27 19:08:51 -04:00
akemidx
cd389368f7 adding in script 2023-04-27 19:00:17 -04:00
akemidx
d3675831bb snippet rewrite 2023-04-27 18:58:59 -04:00
akemidx
84134b45e6 form work 2023-04-27 18:58:59 -04:00
akemidx
b1e68be545 delete button progress 2023-04-27 18:58:59 -04:00
akemidx
d94bed3f57 push for testing 2023-04-27 18:58:59 -04:00
akemidx
aabcf22b40 commiting 2023-04-27 18:58:59 -04:00
akemidx
af549a0be9 Mock Up of the Buttons 2023-04-27 18:58:59 -04:00
Brady Wetherington
381890b578 Merge branch 'develop' into laravel_v9 2023-04-27 13:56:04 -07:00
snipe
1384ca658a Merge remote-tracking branch 'origin/develop' 2023-04-26 18:42:58 -07:00
snipe
e25dc42121 Switch to externalLinkFormatter
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 18:42:34 -07:00
snipe
dcb7eadfc7 Merge pull request #12933 from snipe/features/unlink_dynamic_urls_if_variables_used
Remove auto-link from from manufacturer warranty
2023-04-26 18:40:33 -07:00
snipe
99ef435d40 Fixed translation
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 18:32:38 -07:00
snipe
e853f8b7fd Removed SR text for exporting
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 18:23:21 -07:00
snipe
deff312381 Remove auto-link from from manufacturer warranty
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 18:16:23 -07:00
snipe
7bffe30fae Merge remote-tracking branch 'origin/develop' 2023-04-26 17:55:48 -07:00
snipe
73d45bb587 Merge pull request #12932 from snipe/features/add_warranty_url_to_mfgs
Added dynamic warranty URL to manufacturers
2023-04-26 17:55:03 -07:00
snipe
7974c172fd Switch back to “normal” url for support
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 16:48:38 -07:00
snipe
54a766c4f9 Added dynamic warranty URL to manufacturers
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 16:39:15 -07:00
snipe
27de5c62c5 Merge remote-tracking branch 'origin/develop' 2023-04-26 15:15:43 -07:00
snipe
ef69df2cdf Merge pull request #12930 from snipe/fixes/added_help_text_to_support_url
Added help text to the now-dynamic manufacturer URLS
2023-04-26 15:15:19 -07:00
snipe
7c0ef581c5 Added help text to the now-dynamic manufacturer URLS
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 15:12:36 -07:00
snipe
0c5837e4a0 Merge pull request #12929 from snipe/fixes/use_asset_tag_if_no_asset_name_given
Use the asset tag instead of asset name if no name is given
2023-04-26 14:49:38 -07:00
snipe
5eac314f4d Merge pull request #12906 from akemidx/feature/sc-20622
Dynamic warranty link for manufacturers' support urls
2023-04-26 14:49:22 -07:00
snipe
b5b335a2ca Use the asset tag instead of asset name if no name is given
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 14:41:19 -07:00
akemidx
497d17835f requested edits 2023-04-26 17:06:08 -04:00
slong753
52c9fefbe0 ok, this works except error display 2023-04-26 15:06:50 -05:00
snipe
68417a4c15 Env-ify hashing variables, setting the normal defaults
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 13:01:42 -07:00
akemidx
aab53cf683 remove regex, add in starts_with 2023-04-26 15:18:13 -04:00
snipe
75fdd0ac96 Merge remote-tracking branch 'origin/develop' 2023-04-26 09:54:44 -07:00
snipe
4c16dcf5d0 Merge pull request #12922 from snipe/fixes/12918_route_name_for_clone_locations
Fixed #12918 - wrong route for clone location
2023-04-26 09:54:18 -07:00
snipe
b6889ff399 Fixed #12918 - wrong toite for clone location
Signed-off-by: snipe <snipe@snipe.net>
2023-04-26 09:52:13 -07:00
snipe
12cc576b52 Merge remote-tracking branch 'origin/develop' 2023-04-25 23:41:45 -07:00
snipe
19554a7dc2 Merge pull request #12917 from snipe/fixes/applies_pr_12868
Applies #12868 - fixes EOL date on asset creation
2023-04-25 23:40:43 -07:00
snipe
8f0b823fb3 Applies #12868
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 23:39:32 -07:00
snipe
2299771e10 Add @zacharyfleck as a contributor 2023-04-25 22:37:17 -07:00
snipe
37b881b906 Add @dboth as a contributor 2023-04-25 22:32:45 -07:00
snipe
22d73f503a Merge pull request #12756 from dboth/develop
Fixed #8208, #8896, #8985 and #9789:  Currency issues when using non-english locales (resubmission)
2023-04-25 22:32:13 -07:00
snipe
970b5e556c Merge pull request #12903 from marcusmoore/bug/sc-15034
Fixes sending webhook notifications for checkout and checkin
2023-04-25 22:22:58 -07:00
snipe
17275cbeb8 Merge pull request #12905 from marcusmoore/fixes/checkout-via-artisan
Fixes where clause operator in artisan checkout command
2023-04-25 22:21:59 -07:00
snipe
d6ea5de5b8 Merge remote-tracking branch 'origin/develop' into features/auto_add_to_fieldset 2023-04-25 22:20:50 -07:00
snipe
42f0975414 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-04-25 22:19:27 -07:00
snipe
470a36a7c9 Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 22:12:56 -07:00
snipe
b7632cdbb7 Updated js packages
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 22:12:47 -07:00
snipe
9529cd8235 Merge pull request #12891 from snipe/snyk-upgrade-38ca074c3dd0aada16ad8b85f20ebaa8
[Snyk] Upgrade bootstrap-table from 1.21.3 to 1.21.4
2023-04-25 22:04:40 -07:00
snipe
fcddd0827c Merge pull request #12888 from snipe/snyk-upgrade-4c8ffc584b299eb1e71d6be555624f4e
[Snyk] Upgrade webpack from 5.76.2 to 5.77.0
2023-04-25 22:03:49 -07:00
snipe
c8c6f879d4 Merge pull request #12912 from Godmartinz/ldap_location_sync
added ldap_location to settings
2023-04-25 21:54:28 -07:00
snipe
31a3be4c6a Small refactor of HTML, added top submit button
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 21:51:59 -07:00
snipe
27477085fe Merge branch 'develop' into features/auto_add_to_fieldset 2023-04-25 21:31:50 -07:00
snipe
45f22e7561 Updated the sync to disassociate if all boxed are unchecked
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 21:31:23 -07:00
snipe
5759d2c948 Added a check to fail validation if the associated fieldsets are not value
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 21:30:47 -07:00
snipe
15dc4e4779 Added fieldset sync
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 21:29:57 -07:00
slong753
6bec9cf880 fix a couple things 2023-04-25 23:26:16 -05:00
snipe
5eeca937cb Added logic for syncing fieldset info
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 21:08:26 -07:00
snipe
662b7787a1 Updated redirect return
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 21:07:50 -07:00
snipe
28d9cec1e3 Added auto_add_to_fieldsets to API response
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 20:59:48 -07:00
snipe
67212f9d57 Changed layout, added fieldsets
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 20:59:29 -07:00
snipe
6cd3cfe1ea Added new field to factory
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 20:57:03 -07:00
snipe
4a063d23b9 We don’t actually use this test?
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 19:36:52 -07:00
snipe
705bb7375a Merge pull request #12914 from marcusmoore/fixes/fix-test-cases
Fixes state leak between tests
2023-04-25 17:22:56 -07:00
snipe
4e3ccb74bc Fixed slightly weird padding
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 15:59:19 -07:00
snipe
4954b50280 Added new strings
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 15:57:46 -07:00
snipe
07336bbc6a Added auto_add_to_fieldsets field
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 15:51:36 -07:00
snipe
0e73923c24 Merge pull request #12913 from uberbrady/fix_scim_id_string
Change from a standard Eloquent mapping for ID to a custom setRead
2023-04-25 12:02:36 -07:00
Marcus Moore
a528ebeab0 Use superuser instead of admin state 2023-04-25 11:53:47 -07:00
Brady Wetherington
3da5df0127 Change from a standard Eloquent mapping for ID to a custom setRead 2023-04-25 11:50:55 -07:00
Godfrey M
20d8ff2a4f removed a typo 2023-04-25 11:49:33 -07:00
snipe
a7e2182ec9 Merge pull request #12904 from zacharyfleck/develop
Fixed #8342: Add ARM64 architecture to Docker Builds
2023-04-25 11:45:27 -07:00
Godfrey M
cb68f41d9c added ldap_location to settings 2023-04-25 11:44:04 -07:00
Zachary Fleck
af0a0276e0 Merge branch 'snipe:develop' into develop 2023-04-25 14:43:41 -04:00
Zachary Fleck
ef07f39ccf remove space 2023-04-25 14:43:34 -04:00
Zachary Fleck
aa223359d4 remove space 2023-04-25 14:42:09 -04:00
snipe
b0e342508f Merge remote-tracking branch 'origin/develop' 2023-04-25 08:09:59 -07:00
snipe
efc0929bbc Merge pull request #12910 from snipe/fixes/finer_permissions_for_bulk_assets
Added more granular permissions on bulk actions for assets
2023-04-25 08:09:30 -07:00
snipe
66ce02fc48 Added permission on restore
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 08:09:16 -07:00
snipe
6e7f0728fd Added more granular permissions on bulk actions for assets
Signed-off-by: snipe <snipe@snipe.net>
2023-04-25 08:06:45 -07:00
Marcus Moore
b4f162f316 Fix operator in where clause 2023-04-24 17:26:06 -07:00
akemidx
9cd2783185 Regex added for link instead 2023-04-24 20:07:21 -04:00
zacharyfleck
63ade327a5 add ARM64 architecture 2023-04-24 16:24:44 -04:00
Godfrey M
b8c424fca0 adds users total cost to user profile 2023-04-24 09:17:42 -07:00
snyk-bot
056790e9cd fix: upgrade bootstrap-table from 1.21.3 to 1.21.4
Snyk has created this PR to upgrade bootstrap-table from 1.21.3 to 1.21.4.

See this package in npm:
https://www.npmjs.com/package/bootstrap-table

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-04-22 14:47:28 +00:00
snipe
0c425ed0e7 Merge remote-tracking branch 'origin/develop' 2023-04-21 05:19:19 -07:00
snipe
7d9062c065 Merge pull request #12877 from joelpittet/patch-1
Allow an environment variable to set the session cookie path
2023-04-21 04:45:17 -07:00
snipe
fc721a9388 Merge pull request #12887 from marcusmoore/bug/sc-23158
Fix: Ensure users editing themselves do not deactivate their account
2023-04-21 04:42:04 -07:00
snyk-bot
6af3ab8954 fix: upgrade webpack from 5.76.2 to 5.77.0
Snyk has created this PR to upgrade webpack from 5.76.2 to 5.77.0.

See this package in npm:
https://www.npmjs.com/package/webpack

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-04-21 06:57:42 +00:00
Marcus Moore
2aba8252f3 Ensure users editing themselves do not deactivate their account 2023-04-20 21:59:55 -07:00
akemidx
16a5a883e5 new request, preparing support_url for validation 2023-04-20 16:34:25 -04:00
snipe
c3c22fae3c Merge pull request #12885 from inietov/fixes/error_call_member_function_totalSeatsByLicenseID
Fixed Call to a member function totalSeatsByLicenseID() on null
2023-04-20 10:43:28 -07:00
Ivan Nieto Vivanco
747d6cfdb4 Change the flow of the condition using an early return 2023-04-20 10:37:26 -06:00
Ivan Nieto Vivanco
ae53609b1b Declare variables only if license is found 2023-04-20 10:16:11 -06:00
Marcus Moore
c357d9f01e Update data provider name 2023-04-19 18:10:23 -07:00
Marcus Moore
645f6ed692 Remove unneeded doc block 2023-04-19 17:52:44 -07:00
Godfrey M
97df39001d adds optional breakdowns for total cost 2023-04-19 17:51:37 -07:00
Marcus Moore
dd40798c43 Remove unneeded comments 2023-04-19 17:49:31 -07:00
Godfrey M
6872f8da7b adding total cost to user view 2023-04-19 17:31:09 -07:00
Marcus Moore
e92c1e7bea Minor docblock update 2023-04-19 17:22:56 -07:00
Godfrey M
bd212b3108 adds component costs to asset view 2023-04-19 16:35:06 -07:00
Joel Pittet
608c5d037f Use environment variable and default to PHP's sendmail_path
Use sendmail_path in PHP instead of hardcoded path and options
2023-04-19 15:25:48 -07:00
Joel Pittet
351928adff Allow an environment variable to set the session cookie path 2023-04-19 15:18:50 -07:00
Marcus Moore
144382e57a Update docblock types 2023-04-19 12:31:12 -07:00
Marcus Moore
835f8876c4 Move notification sending into try catch block 2023-04-19 12:26:48 -07:00
snipe
4a5426f959 Merge pull request #12875 from Godmartinz/sidebar_undeployable_runaway_parenthesis
Fixed space from un deployable total in sidebar
2023-04-19 11:49:42 -07:00
Marcus Moore
15280c435e Merge branch 'develop' into bug/sc-15034 2023-04-19 11:45:16 -07:00
Godfrey M
0e1f50c226 adds checkout-range to jquery 2023-04-19 10:11:26 -07:00
Godfrey M
d2118ba230 removed space from un deployable total in sidebar 2023-04-19 09:46:15 -07:00
Godfrey M
8a5612d1c9 fixes comment 2023-04-19 09:13:43 -07:00
Godfrey M
bdd1045272 adds a checkout range for custom asset reports 2023-04-19 09:11:44 -07:00
snipe
fd5cb32dd9 Honor the “update” flag
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 16:34:47 -07:00
snipe
345662c5c2 Rearrange some of the user creation logic
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 16:34:10 -07:00
snipe
003cd372dd New location same CSV
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 16:23:07 -07:00
snipe
aedfef78d3 Update app/Importer/LocationImporter.php
Co-authored-by: Marcus Moore <contact@marcusmoore.io>
2023-04-18 13:26:23 -07:00
Marcus Moore
bad2eead4c Remove test method 2023-04-18 13:13:57 -07:00
Marcus Moore
508660b1df Skip notifications for component checkouts and checkins 2023-04-18 13:07:55 -07:00
snipe
c68563ae08 Merge remote-tracking branch 'origin/develop' 2023-04-18 13:01:37 -07:00
snipe
a84a9a8dec Merge pull request #12867 from snipe/fixes/clearer_tooltip_text_for_non_assets_undeployable
Small tooltip improvements for undeployable items in table view
2023-04-18 13:00:11 -07:00
snipe
d3bdaf7cd3 Fixed destination name
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 12:59:46 -07:00
snipe
92f516484e Small tooltip improvements for undeployable items
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 12:54:06 -07:00
snipe
b626e5a3bf Merge remote-tracking branch 'origin/develop' 2023-04-18 12:33:32 -07:00
snipe
bfda46276a Merge pull request #12849 from snipe/features/adds_license_checkin_checkout_to_all_in_gui
Added license checkin/checkout to all in license GUI
2023-04-18 12:32:30 -07:00
snipe
031586495a Small cosmetic tweaks to 2FA reset class, fixed weird layout on 2FA reset button
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 12:09:41 -07:00
snipe
d871a14687 Added fa-fw for nicer display
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 11:49:40 -07:00
snipe
00a9591c4c Added autoassign_licenses in view, added fa-fw
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 11:49:29 -07:00
snipe
4d9d75379f Improved translation string
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 11:39:16 -07:00
snipe
41358eba85 Updated label
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 11:29:28 -07:00
snipe
59f4fe67d6 Removed duplicate tooltip
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 11:28:35 -07:00
Brady Wetherington
71fa6d765f Update to Latest Livewire files 2023-04-18 11:05:35 -07:00
Brady Wetherington
9793130f6c Merge branch 'develop' into laravel_v9 2023-04-18 11:01:00 -07:00
snipe
2c5c4ab974 Nicer layout
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 04:40:06 -07:00
snipe
95767c46ac Fixed delete modal
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 04:37:13 -07:00
snipe
0eadc00f4d Removed unneeded css class
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 04:37:04 -07:00
snipe
df7b19bc1e Removed unused validations
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 04:35:06 -07:00
snipe
7aab4290c7 Updated tooltips with data-tooltip=true from old method
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:44:50 -07:00
snipe
3a808aa806 Updated method for available seat count
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:44:33 -07:00
snipe
4d09021e9c Compact tooltip for un-deletable
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:44:19 -07:00
snipe
beba31afbf Added tooltip for disabled delete buttons
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:44:09 -07:00
snipe
41490f1e3a Use “name” instead of “license” for consistency
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:43:59 -07:00
snipe
9da36833be Removed unused method
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:43:44 -07:00
snipe
dc6eb6f104 Throw a warning if there were no users affected
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:07:17 -07:00
snipe
a8a3ca3624 Use count on availSeats
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:06:42 -07:00
snipe
e84ba0c7a0 Revert back to old method name
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:06:32 -07:00
snipe
3e53870b37 Updated language
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:00:13 -07:00
snipe
8a41f37054 Persists buttons through tabs
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 02:00:06 -07:00
snipe
9f7058a128 Revert "Renamed/refactorered licenses method"
This reverts commit de78f8d41f.

Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:36:34 -07:00
snipe
ec0413254e Removed action menu
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:09:40 -07:00
snipe
f21d9c27e6 Use new translations for logs
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:07:26 -07:00
snipe
725adebffe Translate log message
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:07:12 -07:00
snipe
bfcbd9628a Refactored license controller with new counts
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:02:58 -07:00
snipe
220e20d208 Changed tooltip invocation
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:02:36 -07:00
snipe
d3b087b5da Clearer padding between buttons, added tooltips
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:02:19 -07:00
snipe
25a83c2915 Removed moved translations
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:02:01 -07:00
snipe
3f4159f058 Added translations
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:01:52 -07:00
snipe
de78f8d41f Renamed/refactorered licenses method
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:01:44 -07:00
snipe
6ab4314221 Removed unused method
Signed-off-by: snipe <snipe@snipe.net>
2023-04-18 01:01:13 -07:00
snipe
087f0e596a Fixed has to where
Signed-off-by: snipe <snipe@snipe.net>
2023-04-17 22:44:05 -07:00
snipe
0dd967cf2b Merge remote-tracking branch 'origin/develop' 2023-04-17 21:05:09 -07:00
snipe
912f6c45ee Reverted #12832
Signed-off-by: snipe <snipe@snipe.net>
2023-04-17 21:04:47 -07:00
snipe
9a73f5eca3 Updated production 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/css/dist/skins/skin-black-dark.css
#	public/css/dist/skins/skin-black-dark.min.css
#	public/css/dist/skins/skin-blue-dark.css
#	public/css/dist/skins/skin-blue-dark.min.css
#	public/css/dist/skins/skin-green-dark.css
#	public/css/dist/skins/skin-green-dark.min.css
#	public/css/dist/skins/skin-orange-dark.css
#	public/css/dist/skins/skin-orange-dark.min.css
#	public/css/dist/skins/skin-purple-dark.css
#	public/css/dist/skins/skin-purple-dark.min.css
#	public/css/dist/skins/skin-red-dark.css
#	public/css/dist/skins/skin-red-dark.min.css
#	public/css/dist/skins/skin-yellow-dark.css
#	public/css/dist/skins/skin-yellow-dark.min.css
#	public/mix-manifest.json
2023-04-17 20:27:49 -07:00
snipe
9698c3b07b Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-04-17 20:14:50 -07:00
snipe
3153013715 Fixed semicolon parse error from #12832
Signed-off-by: snipe <snipe@snipe.net>
2023-04-17 20:14:45 -07:00
snipe
c12ac9912c Merge pull request #12832 from Godmartinz/fix_footer_space
Fixed footer space when customized
2023-04-17 20:11:15 -07:00
snipe
2b10357c4e Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-04-17 19:06:27 -07:00
Marcus Moore
f6cff90829 Migrate to new test settings interface 2023-04-17 17:31:12 -07:00
Marcus Moore
2d56675ade Merge branch 'develop' into bug/sc-15034
# Conflicts:
#	database/factories/SettingFactory.php
2023-04-17 17:22:55 -07:00
snipe
c70cb36c80 Merge pull request #12828 from Godmartinz/bug/sc-20783
Fixed dark themes pagination and notification drop menu
2023-04-17 16:26:36 -07:00
Godfrey M
247f47ce69 adjusts button color 2023-04-17 15:29:53 -07:00
snipe
99cecee4b5 Merge branch 'develop' into features/adds_license_checkin_checkout_to_all_in_gui 2023-04-17 14:54:30 -07:00
Godfrey M
aabd5e92a8 surrounding text aligns correctly 2023-04-17 12:44:06 -07:00
Godfrey M
247c881d87 add back casts 2023-04-17 12:10:54 -07:00
Godfrey M
1001b52c4f removes unncessary files 2023-04-17 12:01:09 -07:00
slong753
52dc99588e pushing for now, needs validation work 2023-04-17 13:57:48 -05:00
Godfrey M
0cca45d858 footer now uses flex 2023-04-17 11:57:35 -07:00
snipe
b22cad9ced Merge pull request #12855 from koelle25/fixes/last_component_checkout
Allow checkout of available components down to zero stock (fixes #12854)
2023-04-17 09:49:14 -07:00
snipe
071a620144 Merge remote-tracking branch 'origin/develop' 2023-04-17 09:36:07 -07:00
snipe
920711dd16 Merge pull request #12857 from snipe/fixes/wtf_datetime_stuff
Remove start/end dates form casts array
2023-04-17 09:35:03 -07:00
snipe
e0c53d8d09 Remove start/end dates form casts array
Signed-off-by: snipe <snipe@snipe.net>
2023-04-17 09:33:31 -07:00
Kevin Köllmann
04f3c4bf69 Fixed #12854: Allow checkout of available components down to zero stock 2023-04-17 11:45:11 +02:00
snipe
a83991041a Better placement for errors
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 16:08:06 -07:00
snipe
0afaaa4a6b Added autoassign_licenses option to create admin
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:28:08 -07:00
snipe
16ab2bec06 Added sorting and searching on autoassign_licenses via user API
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:27:39 -07:00
snipe
4b66ca6ac5 Added method to bulk checkin (much simpler than checking out)
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:27:15 -07:00
snipe
844ad83431 Added method to bulk checkout license seats
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:26:59 -07:00
snipe
9833d861d4 Added autoassign_licenses tp bulk users conditional
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:26:33 -07:00
snipe
03cc55cb6a Set autoassign_licenses to false if unchecked
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:25:52 -07:00
snipe
6a94a2f515 Return true/false for autoassign_licenses in the API
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:25:26 -07:00
snipe
f40bef8f9b Added autoassign_licenses to user importer
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:25:08 -07:00
snipe
6acce098c9 Added autoassign_licenses on user model
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:24:56 -07:00
snipe
73cf62e060 Added autoassign_licenses to presenter
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:24:00 -07:00
snipe
dd78d2fc66 Added language strings
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:23:51 -07:00
snipe
add9e561f9 Added buttons on license page, greyed out where appriate
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:23:42 -07:00
snipe
ff9af7ea74 Added genetic modal partial
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:23:15 -07:00
snipe
bc7c0aa80d Fixed clone tooltip
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:23:00 -07:00
snipe
73188df090 Added autoassign_licenses to bulk user edit
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:22:37 -07:00
snipe
cf7f244942 Added (clarified?) edit autoassign_licenses in user edit
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:19:37 -07:00
snipe
06d46a4523 Indenting change for clarity
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 15:17:55 -07:00
snipe
8e5042418a Added buttons
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 12:30:32 -07:00
snipe
79ff6a8fc2 Disallow deleting in the API view if there are things checked out
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 12:30:23 -07:00
snipe
8183b8deba Added stub method
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 12:30:02 -07:00
snipe
0210ecde88 Include confirm modal
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 12:29:55 -07:00
snipe
b2940f9915 Added confirm modal
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 12:29:48 -07:00
snipe
b093e428b3 Merge remote-tracking branch 'origin/develop' 2023-04-16 08:54:38 -07:00
snipe
144a6f28ec Added intval
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 08:54:23 -07:00
snipe
65ac877918 Merge remote-tracking branch 'origin/develop' 2023-04-16 08:50:20 -07:00
snipe
f50b958b63 Merge pull request #12848 from snipe/fixes/make_limit_into_singletons
Used a singleton to filter API limit value
2023-04-16 08:48:28 -07:00
snipe
64256351d8 Used a singleton to filter API limit value
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 08:46:39 -07:00
snipe
62edc0ab7d Merge remote-tracking branch 'origin/develop' 2023-04-16 08:02:44 -07:00
snipe
2c6d4d6b7f Merge pull request #12847 from snipe/features/moar_labels
Adds a few more auto-labels
2023-04-16 08:01:06 -07:00
snipe
2b11c96ce0 Adds a few more auto-labels
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 08:00:25 -07:00
snipe
78ec21acc4 Added location case
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:47:49 -07:00
snipe
5a1d03c1dc Added alias maps
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:47:42 -07:00
snipe
a831a34594 New field mapping
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:47:26 -07:00
snipe
bcf9188dcd Made default password longer
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:47:19 -07:00
snipe
c149885ceb Skip the magical user creation if it’s a location
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:47:04 -07:00
snipe
1509672463 Added location importer
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:46:36 -07:00
snipe
bceb0b8a47 Allowed slightly longer zip codes
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:46:29 -07:00
snipe
7534d27a03 Added CSV sample
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 07:46:18 -07:00
snipe
46cce0115e 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-04-16 05:46:26 -07:00
snipe
485f5f3a45 Merge pull request #12845 from snipe/security/update_bs_tables
Upgrade bootstrap-table from 1.20.2 to 1.21.3 (Formerly #12733)
2023-04-16 05:44:52 -07:00
snipe
21f5d39fa1 Upgrade bootstrap-table from 1.20.2 to 1.21.3 (Formerly #12733)
Signed-off-by: snipe <snipe@snipe.net>
2023-04-16 05:43:42 -07:00
snipe
21e78bee71 Merge remote-tracking branch 'origin/develop'
Signed-off-by: snipe <snipe@snipe.net>

# Conflicts:
#	package-lock.json
#	public/js/dist/bootstrap-table.js
#	public/mix-manifest.json
2023-04-15 21:05:18 -07:00
snipe
2eeb7ddf58 Merge pull request #12844 from snipe/fixes/small_blade_parial_fixes
Small blade parial fixes
2023-04-15 21:04:35 -07:00
snipe
589f7fa183 Larger qty box
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 21:03:09 -07:00
snipe
9ff62c966e Check for $item (matters mostly in custom report blade)
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 21:03:00 -07:00
snipe
86b04c7294 Updated prod assets
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 20:50:36 -07:00
snipe
2d03ea943b Applied webpack change from master to develop
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 20:49:34 -07:00
snipe
20ab412e1e Updated dev assets
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 20:45:35 -07:00
snipe
513b95e8d7 Merge pull request #12768 from snipe/snyk-upgrade-291b556667d6ffe966495405775b3255
[Snyk] Upgrade tableexport.jquery.plugin from 1.26.0 to 1.27.0
2023-04-15 20:44:57 -07:00
snipe
50153717f6 Merge pull request #12798 from snipe/snyk-upgrade-cec198178187b64d2348f74ddc10c797
[Snyk] Upgrade webpack from 5.76.1 to 5.76.2
2023-04-15 20:36:48 -07:00
snipe
32030c4f71 Merge remote-tracking branch 'origin/develop' 2023-04-15 18:44:25 -07:00
snipe
955539807c Merge pull request #12830 from snipe/features/adds_supplier_id_to_components
Added supplier to components and consumables
2023-04-15 18:42:23 -07:00
snipe
8c09226b76 Merge pull request #12834 from marcusmoore/mxm/improve-test-setup
Introduced improved way to interact with settings in tests
2023-04-15 18:37:34 -07:00
snipe
b73aed2b69 Merge remote-tracking branch 'origin/develop' 2023-04-15 18:30:21 -07:00
snipe
b9a5a8a500 Merge pull request #12843 from snipe/fixes/temp_fix_seeder
Temp fix for the seeders
2023-04-15 18:30:00 -07:00
snipe
8ae14c43f3 This is a temp fix for the seeders
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 18:27:53 -07:00
snipe
fc7f1f907d Fixed variable name
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 17:37:25 -07:00
snipe
f6cfec1e49 Merge pull request #12842 from snipe/fixes/take_two_better_handling_limits
Use abs() instead of max
2023-04-15 17:33:12 -07:00
snipe
4cbb9c2409 Use abs() instead of max
Signed-off-by: snipe <snipe@snipe.net>
2023-04-15 17:28:25 -07:00
snipe
a97b2d141d Merge pull request #12827 from snipe/fixes/tighter_handling_of_offset_and_limit
Better handling for weird data passed to the API via limit and offset
2023-04-15 16:52:33 -07:00
snipe
f407a551da Merge branch 'develop' of https://github.com/snipe/snipe-it into develop 2023-04-15 16:48:07 -07:00
snipe
36665fde31 Merge pull request #12833 from svpernova09/bump-dockerfile-22-04-php81
Update Dockerfile to Ubuntu 22.04 and PHP 8.1
2023-04-14 17:16:42 -07:00
Joe Ferguson
785d2f3558 Update alpine Dockerfiles to PHP 8.1 and Snipe-IT v6.1.0 2023-04-14 13:35:36 -05:00
Joe Ferguson
1d8a4ca090 Update Dockerfile to Ubuntu 22.04 and PHP 8.1 2023-04-14 07:59:16 -05:00
Marcus Moore
473241edca Move initialization of settings to trait 2023-04-13 16:52:20 -07:00
Godfrey M
42f198ffed fixes footer space when customized 2023-04-13 12:24:59 -07:00
Godfrey M
b16c062485 fixes partial 2023-04-13 12:05:59 -07:00
snipe
b690ed97d5 Fixed unclosed parens in translation file
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 12:05:06 -07:00
Godfrey M
ab67d903b5 adds multi select to custom report for companies 2023-04-13 12:02:11 -07:00
snipe
2fe7fcecdb Added case switch for sorting on suppliers
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:13:45 -07:00
snipe
d2b3e251ad Added counters to API controllers
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:12:16 -07:00
snipe
07c0a1927b Added supplier id to controllers
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:12:01 -07:00
snipe
ab7c75232b Added supplier to transformers
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:10:51 -07:00
snipe
6e183f2ced Added counters for consumables and components
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:10:32 -07:00
snipe
6097d534e9 Added eloquent model relationships
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:10:16 -07:00
snipe
3aac8bccd2 Added presenters for suppliers
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:09:59 -07:00
snipe
e7c6771e73 Added supplier to components and consumables factories for seeding
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:07:22 -07:00
snipe
45142c6888 Migration to add supplier ID to components and consumables
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:06:49 -07:00
snipe
607ab3988a Added supplier to edit/creatre blade
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:06:07 -07:00
snipe
b6d3f2827b Switched to standardized require check
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:05:52 -07:00
snipe
65bb0486d4 Changed blade to use standard required check
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:04:29 -07:00
snipe
a40bad0972 Added consumables and components columns to supplier list
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:04:13 -07:00
snipe
6eed89df91 Added components and consumables tab to suppliers
Signed-off-by: snipe <snipe@snipe.net>
2023-04-13 11:03:26 -07:00
Godfrey M
d476f0de3a forgot dark blue 2023-04-13 10:34:17 -07:00
Godfrey M
bbb4032050 fixes rest of dark mode themes 2023-04-13 10:32:42 -07:00
Godfrey M
b83daea265 fixes dark orange 2023-04-13 10:27:38 -07:00
Marcus Moore
7c95e45178 Introduce trait to conditionally interact with settings 2023-04-12 17:28:47 -07:00
Godfrey M
46ff738494 fixes the notification dropdown menu 2023-04-12 16:12:48 -07:00
akemidx
0a993b2aa1 added external link icon to warranty link 2023-04-12 18:52:21 -04:00
Godfrey M
cbb25025d5 fixes pagination for rest of skins 2023-04-12 15:41:04 -07:00
Godfrey M
f3d12351a6 fixes paginiation for black-dark 2023-04-12 15:23:56 -07:00
Godfrey M
2d27f0155a targeting paginiation 2023-04-12 15:06:06 -07: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
snipe
112a04b108 Better handle weird data passed to the API via limit and offset
Signed-off-by: snipe <snipe@snipe.net>
2023-04-12 11:28:46 -07:00
snipe
9a37273750 Merge remote-tracking branch 'origin/develop' 2023-04-12 08:28:50 -07:00
snipe
1a7201d3d9 Merge pull request #12826 from snipe/fixes/added_invalid_parse_to_dont_report
Added invalid parse to dontReport
2023-04-12 08:28:26 -07:00
snipe
74babfa081 Added maxlength="10"
Signed-off-by: snipe <snipe@snipe.net>
2023-04-12 08:26:36 -07:00
snipe
04f83d34ff Added withInput to carry over older fields
Signed-off-by: snipe <snipe@snipe.net>
2023-04-12 08:25:03 -07:00
snipe
aac76d40fe Merge remote-tracking branch 'origin/develop' 2023-04-12 06:37:01 -07:00
snipe
14ec96cf45 Merge pull request #12825 from snipe/fixes/wrong_button_string_on_bulk_user_edit
Fixed #12822 - Missing translation on bulk edit user submit button
2023-04-12 06:36:39 -07:00
snipe
0f3702b0fc Fixed incorrect translation string for bulk user edit
Signed-off-by: snipe <snipe@snipe.net>
2023-04-12 06:35:28 -07:00
snipe
0e93a9229d Merge remote-tracking branch 'origin/develop' 2023-04-12 06:32:06 -07:00
snipe
a119484277 Merge pull request #12824 from snipe/fixes/radio_button_submit_on_merge_users
Removed iCheck code from merge users script
2023-04-12 06:31:43 -07:00
snipe
89b031d64d Removed iCheck code from merge users script
Signed-off-by: snipe <snipe@snipe.net>
2023-04-12 06:30:52 -07:00
snipe
9ae9ea7f68 Merge remote-tracking branch 'origin/develop' 2023-04-12 04:36:30 -07:00
snipe
d3d464e179 Improved commenting
Signed-off-by: snipe <snipe@snipe.net>
2023-04-12 04:36:05 -07:00
snipe
28e0891645 Merge remote-tracking branch 'origin/develop' 2023-04-11 23:36:59 -07:00
snipe
c02bd54826 Merge pull request #12818 from snipe/fixes/better_error_handling_on_dates
Check for Carbon exception
2023-04-11 23:36:42 -07:00
snipe
afd01869a5 Check for Carbon exception
Signed-off-by: snipe <snipe@snipe.net>
2023-04-11 23:35:41 -07:00
akemidx
2453913080 dynamic link w/ dynamic image 2023-04-11 14:53:44 -04:00
akemidx
71ff987e3c dynamic link w/ dynamic image 2023-04-11 14:32:11 -04:00
akemidx
a65b8025b6 push for testing 2023-04-11 13:53:56 -04:00
akemidx
968701b971 starting to implant the str lower solution 2023-04-10 17:28:19 -04:00
snipe
22336da362 Merge remote-tracking branch 'origin/develop' 2023-04-09 14:08:03 -07:00
snipe
79a8effa25 Merge pull request #12810 from snipe/fixes/maintain_checkbox_state_on_user
Maintain activated state on editing a user
2023-04-09 14:07:41 -07:00
snipe
70ce0d9ee6 Maintain activated state on editing a user
Signed-off-by: snipe <snipe@snipe.net>
2023-04-09 14:06:29 -07:00
Marcus Moore
cd0796ddda Allow Settings to be chainable 2023-04-06 18:46:29 -07:00
Marcus Moore
9561b66613 Add return types and docblock 2023-04-06 17:58:53 -07:00
Marcus Moore
95f195046d Move cache flush to testing helper 2023-04-06 17:50:24 -07:00
Marcus Moore
52c733b31d Add ability to set provided settings 2023-04-06 17:48:23 -07:00
Marcus Moore
8ac4d3aeea Move to a static constructor 2023-04-06 17:42:15 -07:00
Marcus Moore
bbfb6c338a Remove unused method 2023-04-06 17:28:16 -07:00
Marcus Moore
f767cc082f Introduce improved way to interact with settings in tests 2023-04-06 17:27:18 -07:00
akemidx
cc88a361ca commiting 2023-04-06 15:01:01 -04:00
snyk-bot
4c05da37c1 fix: upgrade webpack from 5.76.1 to 5.76.2
Snyk has created this PR to upgrade webpack from 5.76.1 to 5.76.2.

See this package in npm:
https://www.npmjs.com/package/webpack

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-04-06 14:48:49 +00:00
slong753
830e3e5594 cleanup 2023-04-05 15:27:28 -05:00
slong753
d56a4e7173 cleanup+formatting 2023-04-05 15:16:46 -05:00
Marcus Moore
5b4d5cadf4 Add tests for sending webhooks on asset and license seat checkin 2023-04-05 12:57:53 -07:00
Marcus Moore
3054d633b0 Improve comments and remove unused imports 2023-04-05 12:39:41 -07:00
Marcus Moore
3cc3662992 Send webhook notifications for accessory checkins when enabled 2023-04-05 12:36:24 -07:00
Marcus Moore
2187310abb Simplify test case names 2023-04-05 12:27:18 -07:00
Marcus Moore
b41902976b Improve test class names 2023-04-05 12:23:11 -07:00
Marcus Moore
6df8f0f35c Merge branch 'develop' into bug/sc-15034 2023-04-05 11:49:53 -07:00
slong753
3929526a57 ok, this works but needs to be tested more 2023-04-04 18:57:51 -05:00
akemidx
f5122b01b1 Mock Up of the Buttons 2023-04-04 15:51:04 -04:00
slong753
29e3d202fe checking something, quick push 2023-04-03 17:54:31 -05:00
Marcus Moore
524249d4d7 Implement tests for webhook notifications on accessory checkout 2023-03-30 16:58:16 -07:00
Marcus Moore
b2292db3c8 Implement tests for webhook notifications on consumable checkout 2023-03-30 16:40:53 -07:00
Marcus Moore
aefc53cfcf Explicitly disable webhook settings in tests 2023-03-30 16:40:21 -07:00
Marcus Moore
621d8500eb Merge branch 'develop' into bug/sc-15034 2023-03-30 16:17:42 -07:00
snyk-bot
91c67c3116 fix: upgrade tableexport.jquery.plugin from 1.26.0 to 1.27.0
Snyk has created this PR to upgrade tableexport.jquery.plugin from 1.26.0 to 1.27.0.

See this package in npm:
https://www.npmjs.com/package/tableexport.jquery.plugin

See this project in Snyk:
https://app.snyk.io/org/snipe/project/3d53e1dd-b8bf-46b5-ba61-18ce26933166?utm_source=github&utm_medium=referral&page=upgrade-pr
2023-03-30 22:55:38 +00:00
Marcus Moore
134ab631d4 Add test to ensure notification is not sent for license checkouts if not enabled 2023-03-30 15:38:22 -07:00
Marcus Moore
158e1544cd Test the event instead of the checkout 2023-03-30 15:38:00 -07: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
Dominik Both
3271c9dc9f Fix #8208, #8896, #8985, #9789 2023-03-29 09:56:34 +02: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
Marcus Moore
2cbc6276f7 Implement test for license checkout notification 2023-03-27 14:09:31 -07:00
Marcus Moore
362d5b9fd4 Merge branch 'develop' into bug/sc-15034 2023-03-27 11:46:30 -07:00
Marcus Moore
fa69a580ab Start to scaffold license checkout notification test 2023-03-23 17:18:33 -07:00
Marcus Moore
fc043a35d9 Fix checkouts for licenses 2023-03-23 17:03:48 -07:00
Marcus Moore
25e859c866 Simplify test case 2023-03-23 16:42:21 -07:00
Marcus Moore
2dcf4e3d16 Standardize on sending anonymous notifications for asset checkouts 2023-03-23 16:31:40 -07:00
Marcus Moore
1f664709ba Merge branch 'develop' into bug/sc-15034
# Conflicts:
#	app/Notifications/CheckoutAssetNotification.php
2023-03-23 13:04:40 -07:00
Marcus Moore
b396f2bed3 Update test case names 2023-03-22 12:41:30 -07:00
Marcus Moore
28ced46b9d Clean up test code 2023-03-22 12:38:14 -07:00
Marcus Moore
66224765ea Use factory state for webhook settings 2023-03-22 12:31:47 -07:00
Marcus Moore
9c4a3ce56a Update slack_endpoint to webhook_endpoint in test and notification 2023-03-22 12:27:36 -07:00
Marcus Moore
f6d0dd0f93 Merge branch 'develop' into bug/sc-15034 2023-03-22 11:58:47 -07:00
Marcus Moore
e303aeadd1 Fix test name 2023-03-22 11:56:54 -07:00
Marcus Moore
315f5231cd Send slack notification for check outs to assets and locations 2023-03-21 17:03:51 -07:00
Marcus Moore
2813b7ea58 Scaffold tests for slack notification on checkout 2023-03-13 15:47:50 -07:00
Brady Wetherington
aadfa9aa9c Back out Laravel Vite stuff - we're so far away from that right now 2023-02-21 19:54:14 -08:00
Brady Wetherington
645bba96cd WIP: First stabs at getting Laravel Vite to work; no luck so far :(
Probably going to back out all the 'vite' stuff anyways :/
2023-02-21 19:35:37 -08:00
cram42
0f3c5d10ba Merge branch 'feature-label2' into develop 2023-02-01 18:01:46 +11:00
cram42
73fd0a24ca Clarify example asset variable 2023-02-01 17:58:58 +11:00
cram42
4b4c228f1a Correct parameter order 2023-02-01 17:56:23 +11:00
cram42
b72c6b7afc Fix 2D barcode defaults 2023-02-01 17:48:39 +11:00
cram42
c2c009a018 Merge branch 'develop' into develop 2023-01-24 09:53:42 +08:00
Cram42
17e81af4cd Add more Avery label sheets 2022-11-12 20:29:50 +08:00
Cram42
ffce6ec327 Need uppercase 2022-11-12 20:29:34 +08:00
Cram42
60ef5686ab Add "Pop Out" button for preview 2022-11-12 19:02:38 +08:00
Cram42
af0872dc23 Fix form refresh after bootstrap-table 2022-11-11 14:23:38 +08:00
Cram42
30a7a31724 Move label preview to alpine component 2022-11-11 14:23:02 +08:00
Cram42
67d021e457 Add alpinejs to deferred scripts 2022-11-11 11:25:41 +08:00
Cram42
7108156072 Fix button disabling 2022-11-10 19:24:02 +08:00
Cram42
a4b93d4bbd Create Field Definitions helper control 2022-11-10 19:20:18 +08:00
Cram42
f849fcca89 Change the way fields are passed 2022-11-10 18:54:02 +08:00
Cram42
fd9616683c Label preview auto-refresh 2022-11-03 10:20:12 +08:00
Cram42
3d470d6f2f Drop asset tag from default field def. 2022-11-02 22:39:08 +08:00
Cram42
53513d93fa Rework TZe labels for Asset Tag support 2022-11-02 22:38:00 +08:00
Cram42
f5fac50e91 Add preview pane 2022-11-02 19:31:34 +08:00
Cram42
36210f1c6a Allow settings to be overridden in request 2022-11-02 19:30:45 +08:00
Cram42
48fb4f2439 Add labels route for testing layouts 2022-11-02 17:23:52 +08:00
Cram42
fb467d9078 Include Asset for advanced users 2022-11-02 17:20:01 +08:00
Cram42
4fee5ece43 Support Avery L7163 2022-11-02 16:08:10 +08:00
Cram42
4bb40adfce Add Asset Tag as separate supported feature 2022-11-02 16:07:50 +08:00
Cram42
06ce40ac08 Don't add data if it's not there 2022-11-02 16:05:52 +08:00
Cram42
a8b6a4a259 Allow passing "template" param 2022-11-02 16:04:40 +08:00
Cram42
a60ee7736b Add P-touch TZe 12mm Tape Example 2022-11-02 12:22:55 +08:00
Cram42
d0eb3cfc9b Merge branch 'feature-label2' into develop 2022-11-02 10:09:46 +08:00
Cram42
19150aeb44 Add P-touch TZe 24mm Tape Example 2022-11-02 10:09:11 +08:00
Cram42
cde2ba7720 Fix: Oops 2022-11-02 09:51:02 +08:00
Cram42
6b2fe582ca Merge branch 'feature-label2' into develop 2022-11-01 20:12:28 +08:00
cram42
7e2546b31f Merge branch 'snipe:develop' into develop 2022-11-01 20:04:59 +08:00
Cram42
7b29ddd283 Tie into tag generation 2022-11-01 20:02:12 +08:00
Cram42
d37605ff18 Add localization strings 2022-11-01 20:01:18 +08:00
Cram42
6de48b4dc8 Implement settings for labels 2022-11-01 20:00:53 +08:00
Cram42
5558a005b9 Implement API for labels 2022-11-01 19:57:51 +08:00
Cram42
bb09f0168f Create Label View/Generator 2022-11-01 19:56:53 +08:00
Cram42
4ed728d954 Add template to simulate legacy label 2022-11-01 19:54:00 +08:00
Cram42
bbecdb6768 Add QR example 2022-11-01 19:53:11 +08:00
Cram42
df89406987 Create Label model and example 2022-11-01 19:52:34 +08:00
Cram42
7c355cef2d Add helper to convert between units of measurement 2022-11-01 19:49:57 +08:00
Cram42
35536b5dbd Require tecnickcom/tcpdf 2022-11-01 19:47:59 +08:00
Cram42
0e69e4248c Fix: Multiple outputs at hardware/{id}/label 2022-10-27 08:12:42 +08:00
1775 changed files with 33960 additions and 33354 deletions

View File

@@ -2889,6 +2889,78 @@
"avatar_url": "https://avatars.githubusercontent.com/u/570639?v=4",
"profile": "https://github.com/Mezzle",
"contributions": []
},
{
"login": "dboth",
"name": "dboth",
"avatar_url": "https://avatars.githubusercontent.com/u/5731963?v=4",
"profile": "http://dboth.de",
"contributions": [
"code"
]
},
{
"login": "zacharyfleck",
"name": "Zachary Fleck",
"avatar_url": "https://avatars.githubusercontent.com/u/87536651?v=4",
"profile": "https://github.com/zacharyfleck",
"contributions": [
"code"
]
},
{
"login": "vikaas-cyper",
"name": "VIKAAS-A",
"avatar_url": "https://avatars.githubusercontent.com/u/74609912?v=4",
"profile": "https://github.com/vikaas-cyper",
"contributions": [
"code"
]
},
{
"login": "ak-piracha",
"name": "Abdul Kareem",
"avatar_url": "https://avatars.githubusercontent.com/u/88882041?v=4",
"profile": "https://github.com/ak-piracha",
"contributions": [
"code"
]
},
{
"login": "NojoudAlshehri",
"name": "NojoudAlshehri",
"avatar_url": "https://avatars.githubusercontent.com/u/111287779?v=4",
"profile": "https://github.com/NojoudAlshehri",
"contributions": [
"code"
]
},
{
"login": "stefanstidlffg",
"name": "Stefan Stidl",
"avatar_url": "https://avatars.githubusercontent.com/u/54367449?v=4",
"profile": "https://github.com/stefanstidlffg",
"contributions": [
"code"
]
},
{
"login": "qay21",
"name": "Quentin Aymard",
"avatar_url": "https://avatars.githubusercontent.com/u/87803479?v=4",
"profile": "https://github.com/qay21",
"contributions": [
"code"
]
},
{
"login": "cram42",
"name": "Grant Le Roux",
"avatar_url": "https://avatars.githubusercontent.com/u/5396871?v=4",
"profile": "https://github.com/cram42",
"contributions": [
"code"
]
}
]
}

44
.chipperci.yml Normal file
View File

@@ -0,0 +1,44 @@
version: 1
environment:
php: 8.0
node: 12
services:
- mysql: 5.7
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

View File

@@ -85,6 +85,7 @@ COOKIE_NAME=snipeit_session
COOKIE_DOMAIN=null
SECURE_COOKIES=false
API_TOKEN_EXPIRATION_YEARS=15
BS_TABLE_STORAGE=cookieStorage
# --------------------------------------------
# OPTIONAL: SECURITY HEADER SETTINGS
@@ -148,6 +149,7 @@ AWS_DEFAULT_REGION=null
# --------------------------------------------
LOGIN_MAX_ATTEMPTS=5
LOGIN_LOCKOUT_DURATION=60
LOGIN_AUTOCOMPLETE=false
# --------------------------------------------
# OPTIONAL: FORGOTTEN PASSWORD SETTINGS
@@ -175,6 +177,15 @@ REQUIRE_SAML=false
API_THROTTLE_PER_MINUTE=120
CSV_ESCAPE_FORMULAS=true
# --------------------------------------------
# OPTIONAL: HASHING
# --------------------------------------------
HASHING_DRIVER='bcrypt'
BCRYPT_ROUNDS=10
ARGON_MEMORY=1024
ARGON_THREADS=2
ARGON_TIME=2
# --------------------------------------------
# OPTIONAL: SCIM
# --------------------------------------------

View File

@@ -1,18 +1,22 @@
frontend: ["*.js", "*.css", "*.vue", "*.scss", "*.less", "*.blade.*", "*livewire*"]
frontend: ["*.js", "*.css", "*.vue", "*.scss", "*.less", "*.blade.*", "resources/views/livewire/*"]
skins: ["*.js", "*.css", "*.scss", "*.less"]
css: ["*.css","*.scss", "*.less"]
backend: ["/app/*", "*.php"]
javascript: ["*.js", "package.json", "package.lock"]
backend: ["/app/*", "composer.json", "composer.lock"]
translations: ["/resources/lang"]
livewire: ["/app/Http/Livewire/*", "resources/views/livewire/*"]
backups: ["*backup*"]
restore: ["*restore*"]
saml: ["*saml*"]
scim: ["*scim*"]
custom fields: ["*fields*", "*fieldsets*"]
dependencies: ["composer.json"]
dependencies: ["composer.json", "composer.lock", "package.json", "package.lock"]
consumables: ["*consumables*"]
api: ["/app/Http/Controllers/api/*"]
api: ["/app/Http/Controllers/Api/*"]
notifications: ["/app/Notifications/*"]
importer: ["/app/Importer/*"]
importer: ["/app/Importer/*","/app/Http/Livewire/Importer.php", "resources/views/livewire/importer.php"]
cli / artisan: ["/app/Console/*"]
LDAP: ["*LDAP*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php"]
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php"]
docker: ["*docker/*", "Dockerfile", "Dockerfile.alpine", "Dockerfile.fpm-alpine", ".dockerignore", ".env.docker"]
tests: ["/tests/*", "/stubs"]
config: .github

View File

@@ -76,7 +76,7 @@ jobs:
with:
context: .
file: ./Dockerfile.alpine
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
# but we ONLY do an image push to DockerHub if it's NOT a PR
push: ${{ github.event_name != 'pull_request' }}

View File

@@ -76,7 +76,7 @@ jobs:
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
platforms: linux/amd64,linux/arm64
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
# but we ONLY do an image push to DockerHub if it's NOT a PR
push: ${{ github.event_name != 'pull_request' }}

73
.github/workflows/tests.yml vendored Normal file
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@v3
- 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
.gitignore vendored
View File

@@ -1,8 +1,6 @@
.couscous
.DS_Store
.env
.env.dusk.*
!.env.dusk.example
.env.testing
phpstan.neon
.idea

2
.nvmrc
View File

@@ -1 +1 @@
v12.22.1
v18.16.0

View File

@@ -1,4 +1,4 @@
FROM ubuntu:20.04
FROM ubuntu:22.04
LABEL maintainer="Brady Wetherington <bwetherington@grokability.com>"
# No need to add `apt-get clean` here, reference:
@@ -14,16 +14,16 @@ RUN export DEBIAN_FRONTEND=noninteractive; \
apt-utils \
apache2 \
apache2-bin \
libapache2-mod-php7.4 \
php7.4-curl \
php7.4-ldap \
php7.4-mysql \
php7.4-gd \
php7.4-xml \
php7.4-mbstring \
php7.4-zip \
php7.4-bcmath \
php7.4-redis \
libapache2-mod-php8.1 \
php8.1-curl \
php8.1-ldap \
php8.1-mysql \
php8.1-gd \
php8.1-xml \
php8.1-mbstring \
php8.1-zip \
php8.1-bcmath \
php8.1-redis \
php-memcached \
patch \
curl \
@@ -38,9 +38,10 @@ gcc \
make \
autoconf \
libc-dev \
libldap-common \
pkg-config \
libmcrypt-dev \
php7.4-dev \
php8.1-dev \
ca-certificates \
unzip \
dnsutils \
@@ -50,16 +51,16 @@ dnsutils \
RUN curl -L -O https://github.com/pear/pearweb_phars/raw/master/go-pear.phar
RUN php go-pear.phar
RUN pecl install mcrypt-1.0.3
RUN pecl install mcrypt
RUN bash -c "echo extension=/usr/lib/php/20190902/mcrypt.so > /etc/php/7.4/mods-available/mcrypt.ini"
RUN bash -c "echo extension=/usr/lib/php/20210902/mcrypt.so > /etc/php/8.1/mods-available/mcrypt.ini"
RUN phpenmod mcrypt
RUN phpenmod gd
RUN phpenmod bcmath
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.4/apache2/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.4/cli/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/8.1/apache2/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/8.1/cli/php.ini
RUN useradd -m --uid 1000 --gid 50 docker

View File

@@ -1,34 +1,34 @@
FROM alpine:3.14.2
FROM alpine:3.17.3
# Apache + PHP
RUN apk add --no-cache \
apache2 \
php7 \
php7-common \
php7-apache2 \
php7-curl \
php7-ldap \
php7-mysqli \
php7-gd \
php7-xml \
php7-mbstring \
php7-zip \
php7-ctype \
php7-tokenizer \
php7-pdo_mysql \
php7-openssl \
php7-bcmath \
php7-phar \
php7-json \
php7-iconv \
php7-fileinfo \
php7-simplexml \
php7-session \
php7-dom \
php7-xmlwriter \
php7-xmlreader \
php7-sodium \
php7-redis \
php7-pecl-memcached \
php81 \
php81-common \
php81-apache2 \
php81-curl \
php81-ldap \
php81-mysqli \
php81-gd \
php81-xml \
php81-mbstring \
php81-zip \
php81-ctype \
php81-tokenizer \
php81-pdo_mysql \
php81-openssl \
php81-bcmath \
php81-phar \
php81-json \
php81-iconv \
php81-fileinfo \
php81-simplexml \
php81-session \
php81-dom \
php81-xmlwriter \
php81-xmlreader \
php81-sodium \
php81-redis \
php81-pecl-memcached \
curl \
wget \
vim \
@@ -41,7 +41,7 @@ COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
# Where apache's PID lives
RUN mkdir -p /run/apache2 && chown apache:apache /run/apache2
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php7/php.ini
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php81/php.ini
COPY docker/000-default-2.4.conf /etc/apache2/conf.d/default.conf
# Enable mod_rewrite

View File

@@ -1,8 +1,8 @@
ARG ENVIRONMENT=production
ARG SNIPEIT_RELEASE=5.1.3
ARG PHP_VERSION=7.4.16
ARG PHP_ALPINE_VERSION=3.13
ARG COMPOSER_VERSION=2.0.11
ARG SNIPEIT_RELEASE=6.1.0
ARG PHP_VERSION=8.2
ARG PHP_ALPINE_VERSION=3.17
ARG COMPOSER_VERSION=2
# Cannot use arguments with 'COPY --from' workaround
# https://github.com/moby/moby/issues/34482#issuecomment-454716952
@@ -52,7 +52,7 @@ RUN { \
# Install php extensions inside docker containers easily
# https://github.com/mlocati/docker-php-extension-installer
COPY --from=mlocati/php-extension-installer:1.2.19 /usr/bin/install-php-extensions /usr/local/bin/
COPY --from=mlocati/php-extension-installer:2.1.15 /usr/bin/install-php-extensions /usr/local/bin/
RUN set -eux; \
install-php-extensions \
bcmath \

View File

@@ -1,5 +1,5 @@
![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)
[![All Contributors](https://img.shields.io/badge/all_contributors-318-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)
[![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
@@ -144,7 +144,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars.githubusercontent.com/u/32363424?v=4" width="110px;"/><br /><sub>Peace</sub>](https://github.com/julian-piehl)<br />[💻](https://github.com/snipe/snipe-it/commits?author=julian-piehl "Code") | [<img src="https://avatars.githubusercontent.com/u/231528?v=4" width="110px;"/><br /><sub>Kyle Gordon</sub>](https://github.com/kylegordon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kylegordon "Code") | [<img src="https://avatars.githubusercontent.com/u/53009155?v=4" width="110px;"/><br /><sub>Katharina Drexel</sub>](http://www.bfh.ch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sunflowerbofh "Code") | [<img src="https://avatars.githubusercontent.com/u/1931963?v=4" width="110px;"/><br /><sub>David Sferruzza</sub>](https://david.sferruzza.fr/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dsferruzza "Code") | [<img src="https://avatars.githubusercontent.com/u/19511639?v=4" width="110px;"/><br /><sub>Rick Nelson</sub>](https://github.com/rnelsonee)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rnelsonee "Code") | [<img src="https://avatars.githubusercontent.com/u/94169344?v=4" width="110px;"/><br /><sub>BasO12</sub>](https://github.com/BasO12)<br />[💻](https://github.com/snipe/snipe-it/commits?author=BasO12 "Code") | [<img src="https://avatars.githubusercontent.com/u/111710123?v=4" width="110px;"/><br /><sub>Vautia</sub>](https://github.com/Vautia)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Vautia "Code") |
| [<img src="https://avatars.githubusercontent.com/u/28321?v=4" width="110px;"/><br /><sub>Chris Hartjes</sub>](http://www.littlehart.net/atthekeyboard)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [<img src="https://avatars.githubusercontent.com/u/2404584?v=4" width="110px;"/><br /><sub>geo-chen</sub>](https://github.com/geo-chen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [<img src="https://avatars.githubusercontent.com/u/6006620?v=4" width="110px;"/><br /><sub>Phan Nguyen</sub>](https://github.com/nh314)<br />[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [<img src="https://avatars.githubusercontent.com/u/115993812?v=4" width="110px;"/><br /><sub>Iisakki Jaakkola</sub>](https://github.com/StarlessNights)<br />[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="110px;"/><br /><sub>Ikko Ashimine</sub>](https://bandism.net/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [<img src="https://avatars.githubusercontent.com/u/56871540?v=4" width="110px;"/><br /><sub>Lukas Fehling</sub>](https://github.com/lukasfehling)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [<img src="https://avatars.githubusercontent.com/u/1975990?v=4" width="110px;"/><br /><sub>Fernando Almeida</sub>](https://github.com/fernando-almeida)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") |
| [<img src="https://avatars.githubusercontent.com/u/116301219?v=4" width="110px;"/><br /><sub>akemidx</sub>](https://github.com/akemidx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [<img src="https://avatars.githubusercontent.com/u/144778?v=4" width="110px;"/><br /><sub>Oguz Bilgic</sub>](http://oguz.site)<br />[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [<img src="https://avatars.githubusercontent.com/u/9262438?v=4" width="110px;"/><br /><sub>Scooter Crawford</sub>](https://github.com/scoo73r)<br />[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [<img src="https://avatars.githubusercontent.com/u/5957345?v=4" width="110px;"/><br /><sub>subdriven</sub>](https://github.com/subdriven)<br />[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [<img src="https://avatars.githubusercontent.com/u/658865?v=4" width="110px;"/><br /><sub>Andrew Savinykh</sub>](https://github.com/AndrewSav)<br />[💻](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") | [<img src="https://avatars.githubusercontent.com/u/1155067?v=4" width="110px;"/><br /><sub>Tadayuki Onishi</sub>](https://kenchan0130.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kenchan0130 "Code") | [<img src="https://avatars.githubusercontent.com/u/112496896?v=4" width="110px;"/><br /><sub>Florian</sub>](https://github.com/floschoepfer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=floschoepfer "Code") |
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [<img src="https://avatars.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://github.com/Mezzle)<br /> |
| [<img src="https://avatars.githubusercontent.com/u/7305753?v=4" width="110px;"/><br /><sub>Spencer Long</sub>](http://spencerlong.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [<img src="https://avatars.githubusercontent.com/u/1141514?v=4" width="110px;"/><br /><sub>Marcus Moore</sub>](https://github.com/marcusmoore)<br />[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [<img src="https://avatars.githubusercontent.com/u/570639?v=4" width="110px;"/><br /><sub>Martin Meredith</sub>](https://github.com/Mezzle)<br /> | [<img src="https://avatars.githubusercontent.com/u/5731963?v=4" width="110px;"/><br /><sub>dboth</sub>](http://dboth.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dboth "Code") | [<img src="https://avatars.githubusercontent.com/u/87536651?v=4" width="110px;"/><br /><sub>Zachary Fleck</sub>](https://github.com/zacharyfleck)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zacharyfleck "Code") | [<img src="https://avatars.githubusercontent.com/u/74609912?v=4" width="110px;"/><br /><sub>VIKAAS-A</sub>](https://github.com/vikaas-cyper)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vikaas-cyper "Code") | [<img src="https://avatars.githubusercontent.com/u/88882041?v=4" width="110px;"/><br /><sub>Abdul Kareem</sub>](https://github.com/ak-piracha)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ak-piracha "Code") |
| [<img src="https://avatars.githubusercontent.com/u/111287779?v=4" width="110px;"/><br /><sub>NojoudAlshehri</sub>](https://github.com/NojoudAlshehri)<br />[💻](https://github.com/snipe/snipe-it/commits?author=NojoudAlshehri "Code") | [<img src="https://avatars.githubusercontent.com/u/54367449?v=4" width="110px;"/><br /><sub>Stefan Stidl</sub>](https://github.com/stefanstidlffg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=stefanstidlffg "Code") | [<img src="https://avatars.githubusercontent.com/u/87803479?v=4" width="110px;"/><br /><sub>Quentin Aymard</sub>](https://github.com/qay21)<br />[💻](https://github.com/snipe/snipe-it/commits?author=qay21 "Code") | [<img src="https://avatars.githubusercontent.com/u/5396871?v=4" width="110px;"/><br /><sub>Grant Le Roux</sub>](https://github.com/cram42)<br />[💻](https://github.com/snipe/snipe-it/commits?author=cram42 "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!

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.

View File

@@ -56,7 +56,7 @@ class CheckoutLicenseToAllUsers extends Command
return false;
}
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '==', 1)->with('licenses')->get();
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '=', 1)->with('licenses')->get();
if ($users->count() > $license->getAvailSeatsCountAttribute()) {
$this->info('You do not have enough free seats to complete this task, so we will check out as many as we can. ');

View File

@@ -20,13 +20,14 @@ class CreateAdmin extends Command
* @property string $password
* @property boolean $activated
* @property boolean $show_in_list
* @property boolean $autoassign_licenses
* @property \Illuminate\Support\Carbon|null $created_at
* @property mixed $created_by
*/
protected $signature = 'snipeit:create-admin {--first_name=} {--last_name=} {--email=} {--username=} {--password=} {show_in_list?}';
protected $signature = 'snipeit:create-admin {--first_name=} {--last_name=} {--email=} {--username=} {--password=} {show_in_list?} {autoassign_licenses?}';
/**
* The console command description.
@@ -54,6 +55,9 @@ class CreateAdmin extends Command
$email = $this->option('email');
$password = $this->option('password');
$show_in_list = $this->argument('show_in_list');
$autoassign_licenses = $this->argument('autoassign_licenses');
if (($first_name == '') || ($last_name == '') || ($username == '') || ($email == '') || ($password == '')) {
$this->info('ERROR: All fields are required.');
@@ -70,6 +74,11 @@ class CreateAdmin extends Command
if ($show_in_list == 'false') {
$user->show_in_list = 0;
}
if ($autoassign_licenses == 'false') {
$user->autoassign_licenses = 0;
}
if ($user->save()) {
$this->info('New user created');
$user->groups()->attach(1);

View File

@@ -62,6 +62,7 @@ class LdapSync extends Command
$ldap_result_phone = Setting::getSettings()->ldap_phone_field;
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
$ldap_result_country = Setting::getSettings()->ldap_country;
$ldap_result_location = Setting::getSettings()->ldap_location;
$ldap_result_dept = Setting::getSettings()->ldap_dept;
$ldap_result_manager = Setting::getSettings()->ldap_manager;
$ldap_default_group = Setting::getSettings()->ldap_default_group;
@@ -209,8 +210,14 @@ class LdapSync extends Command
$item['country'] = $results[$i][$ldap_result_country][0] ?? '';
$item['department'] = $results[$i][$ldap_result_dept][0] ?? '';
$item['manager'] = $results[$i][$ldap_result_manager][0] ?? '';
$item['location'] = $results[$i][$ldap_result_location][0] ?? '';
// ONLY if you are using the "ldap_location" option *AND* you have an actual result
if ($ldap_result_location && $item['location']) {
$location = Location::firstOrCreate([
'name' => $item['location'],
]);
}
$department = Department::firstOrCreate([
'name' => $item['department'],
]);
@@ -227,16 +234,39 @@ class LdapSync extends Command
$item['createorupdate'] = 'created';
}
$user->first_name = $item['firstname'];
$user->last_name = $item['lastname'];
//If a sync option is not filled in on the LDAP settings don't populate the user field
if($ldap_result_username != null){
$user->username = $item['username'];
$user->email = $item['email'];
}
if($ldap_result_last_name != null){
$user->last_name = $item['lastname'];
}
if($ldap_result_first_name != null){
$user->first_name = $item['firstname'];
}
if($ldap_result_emp_num != null){
$user->employee_num = e($item['employee_number']);
}
if($ldap_result_email != null){
$user->email = $item['email'];
}
if($ldap_result_phone != null){
$user->phone = $item['telephone'];
}
if($ldap_result_jobtitle != null){
$user->jobtitle = $item['jobtitle'];
}
if($ldap_result_country != null){
$user->country = $item['country'];
}
if($ldap_result_dept != null){
$user->department_id = $department->id;
}
if($ldap_result_location != null){
$user->location_id = $location ? $location->id : null;
}
if($ldap_result_manager != null){
if($item['manager'] != null) {
// Check Cache first
if (isset($manager_cache[$item['manager']])) {
@@ -276,6 +306,7 @@ class LdapSync extends Command
}
}
}
// Sync activated state for Active Directory.
if ( !empty($ldap_result_active_flag)) { // IF we have an 'active' flag set....

View File

@@ -11,7 +11,7 @@ class SystemBackup extends Command
*
* @var string
*/
protected $name = 'snipeit:backup';
protected $signature = 'snipeit:backup {--filename=}';
/**
* The console command description.
@@ -37,7 +37,18 @@ class SystemBackup extends Command
*/
public function handle()
{
//
$this->call('backup:run');
if ($this->option('filename')) {
$filename = $this->option('filename');
// Make sure the filename ends in .zip
if (!ends_with($filename, '.zip')) {
$filename = $filename.'.zip';
}
$this->call('backup:run', ['--filename' => $filename]);
} else {
$this->call('backup:run');
}
}
}

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;
}
}

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;
}
}

View File

@@ -10,7 +10,7 @@ use ArieTimmerman\Laravel\SCIMServer\Exceptions\SCIMException;
use Log;
use Throwable;
use JsonException;
use Carbon\Exceptions\InvalidFormatException;
class Handler extends ExceptionHandler
{
@@ -30,6 +30,7 @@ class Handler extends ExceptionHandler
\League\OAuth2\Server\Exception\OAuthServerException::class,
JsonException::class,
SCIMException::class, //these generally don't need to be reported
InvalidFormatException::class,
];
/**
@@ -69,21 +70,39 @@ class Handler extends ExceptionHandler
// Invalid JSON exception
// TODO: don't understand why we have to do this when we have the invalidJson() method, below, but, well, whatever
if ($e instanceof JsonException) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'invalid JSON'), 422);
return response()->json(Helper::formatStandardApiResponse('error', null, 'Invalid JSON'), 422);
}
// Handle SCIM exceptions
if ($e instanceof SCIMException) {
return response()->json(Helper::formatStandardApiResponse('error', null, 'invalid SCIM Request'), 400);
try {
$e->report(); // logs as 'debug', so shouldn't get too noisy
} catch(\Exception $reportException) {
//do nothing
}
return $e->render($request); // ALL SCIMExceptions have the 'render()' method
}
// Handle Ajax requests that fail because the model doesn't exist
// Handle standard requests that fail because Carbon cannot parse the date on validation (when a submitted date value is definitely not a date)
if ($e instanceof InvalidFormatException) {
return redirect()->back()->withInput()->with('error', trans('validation.date', ['attribute' => 'date']));
}
// Handle API requests that fail
if ($request->ajax() || $request->wantsJson()) {
// Handle API requests that fail because Carbon cannot parse the date on validation (when a submitted date value is definitely not a date)
if ($e instanceof InvalidFormatException) {
return response()->json(Helper::formatStandardApiResponse('error', null, trans('validation.date', ['attribute' => 'date'])), 200);
}
// Handle API requests that fail because the model doesn't exist
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
$className = last(explode('\\', $e->getModel()));
return response()->json(Helper::formatStandardApiResponse('error', null, $className . ' not found'), 200);
}
// Handle API requests that fail because of an HTTP status code and return a useful error message
if ($this->isHttpException($e)) {
$statusCode = $e->getStatusCode();
@@ -103,6 +122,8 @@ class Handler extends ExceptionHandler
}
if ($this->isHttpException($e) && (isset($statusCode)) && ($statusCode == '404' )) {
return response()->view('layouts/basic', [
'content' => view('errors/404')

View File

@@ -0,0 +1,77 @@
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\Gate;
/*********************
* These two helper methods are more designed for being re-used with the new HasCustomFields Trait
*
* The 'transform' method is designed for BlahTransformer things that need to return custom field values.
*
* The 'present' method is designed for when you're trying to generate fieldlists for use in Bootstrap tables
* - typically the 'dataTableLayout' method
*
*********************/
class CustomFieldHelper {
static function transform($fieldset, $item) {
if ($fieldset && ($fieldset->fields->count() > 0)) {
$fields_array = [];
foreach ($fieldset->fields as $field) {
if ($field->isFieldDecryptable($item->{$field->db_column})) {
$decrypted = Helper::gracefulDecrypt($field, $item->{$field->db_column});
$value = (Gate::allows('assets.view.encrypted_custom_fields')) ? $decrypted : strtoupper(trans('admin/custom_fields/general.encrypted'));
if ($field->format == 'DATE'){
if (Gate::allows('assets.view.encrypted_custom_fields')){
$value = Helper::getFormattedDateObject($value, 'date', false);
} else {
$value = strtoupper(trans('admin/custom_fields/general.encrypted'));
}
}
$fields_array[$field->name] = [
'field' => e($field->db_column),
'value' => e($value),
'field_format' => $field->format,
'element' => $field->element,
];
} else {
$value = $item->{$field->db_column};
if (($field->format == 'DATE') && (!is_null($value)) && ($value!='')){
$value = Helper::getFormattedDateObject($value, 'date', false);
}
$fields_array[$field->name] = [
'field' => e($field->db_column),
'value' => e($value),
'field_format' => $field->format,
'element' => $field->element,
];
}
return $fields_array;
}
} else {
return new \stdClass; // HACK to force generation of empty object instead of empty list
}
}
static function present($field) {
return [
'field' => 'custom_fields.'.$field->db_column,
'searchable' => true,
'sortable' => true,
'switchable' => true,
'title' => $field->name,
'formatter'=> 'customFieldsFormatter',
'escape' => true,
'class' => ($field->field_encrypted == '1') ? 'css-padlock' : '',
'visible' => ($field->show_in_listview == '1') ? true : false,
];
}
}

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;
@@ -33,6 +35,16 @@ class Helper
}
}
public static function parseEscapedMarkedownInline($str = null)
{
$Parsedown = new \Parsedown();
$Parsedown->setSafeMode(true);
if ($str) {
return $Parsedown->line($str);
}
}
/**
* The importer has formatted number strings since v3,
* so the value might be a string, or an integer.
@@ -543,8 +555,8 @@ class Helper
'license' => trans('general.license'),
];
if($selection != null){
return $category_types[$selection];
if ($selection != null){
return $category_types[strtolower($selection)];
}
else
return $category_types;
@@ -563,6 +575,17 @@ class Helper
return $customfields;
}
/**
* Get all of the different types of custom fields there are
* TODO - how to make this more general? Or more useful? or more dynamic?
* idea - key of classname, *value* of trans? (thus having to make this a method, which is fine)
*/
static $itemtypes_having_custom_fields = [
0 => \App\Models\Asset::class,
1 => \App\Models\User::class,
// 2 => \App\Models\Accessory::class
];
/**
* Get the list of custom field formats in an array to make a dropdown menu
*
@@ -633,6 +656,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 = [];
@@ -695,6 +719,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;
}
@@ -1210,10 +1256,60 @@ class Helper
return true;
\Log::debug('app locked!');
}
return false;
}
/**
* Conversion between units of measurement
*
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
* @since 5.0
* @param float $value Measurement value to convert
* @param string $srcUnit Source unit of measurement
* @param string $dstUnit Destination unit of measurement
* @param int $round Round the result to decimals (Default false - No rounding)
* @return float
*/
public static function convertUnit($value, $srcUnit, $dstUnit, $round=false) {
$srcFactor = static::getUnitConversionFactor($srcUnit);
$dstFactor = static::getUnitConversionFactor($dstUnit);
$output = $value * $srcFactor / $dstFactor;
return ($round !== false) ? round($output, $round) : $output;
}
/**
* Get conversion factor from unit of measurement to mm
*
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
* @since 5.0
* @param string $unit Unit of measurement
* @return float
*/
public static function getUnitConversionFactor($unit) {
switch (strtolower($unit)) {
case 'mm':
return 1.0;
case 'cm':
return 10.0;
case 'm':
return 1000.0;
case 'in':
return 25.4;
case 'ft':
return 12 * static::getUnitConversionFactor('in');
case 'yd':
return 3 * static::getUnitConversionFactor('ft');
case 'pt':
return (1 / 72) * static::getUnitConversionFactor('in');
default:
throw new \InvalidArgumentException('Unit: \'' . $unit . '\' is not supported');
return false;
}
}
/*
* I know it's gauche to return a shitty HTML string, but this is just a helper and since it will be the same every single time,

View File

@@ -77,7 +77,7 @@ class AccessoriesController extends Controller
$accessory->manufacturer_id = request('manufacturer_id');
$accessory->model_number = request('model_number');
$accessory->purchase_date = request('purchase_date');
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
$accessory->purchase_cost = request('purchase_cost');
$accessory->qty = request('qty');
$accessory->user_id = Auth::user()->id;
$accessory->supplier_id = request('supplier_id');
@@ -126,12 +126,13 @@ class AccessoriesController extends Controller
public function getClone($accessoryId = null)
{
$this->authorize('create', Accesory::class);
$this->authorize('create', Accessory::class);
// Check if the asset exists
if (is_null($accessory_to_clone = Accessory::find($accessoryId))) {
// Redirect to the asset management page
return redirect()->route('accessory.index')->with('error', trans('admin/accessories/message.does_not_exist'));
return redirect()->route('accessories.index')
->with('error', trans('admin/accessories/message.does_not_exist', ['id' => $accessoryId]));
}
$accessory = clone $accessory_to_clone;
@@ -180,7 +181,7 @@ class AccessoriesController extends Controller
$accessory->order_number = request('order_number');
$accessory->model_number = request('model_number');
$accessory->purchase_date = request('purchase_date');
$accessory->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
$accessory->purchase_cost = request('purchase_cost');
$accessory->qty = request('qty');
$accessory->supplier_id = request('supplier_id');
$accessory->notes = request('notes');

View File

@@ -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);
}
}
}

View 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'));
@@ -121,7 +121,6 @@ class AcceptanceController extends Controller
$pdf_filename = 'accepted-eula-'.date('Y-m-d-h-i-s').'.pdf';
$sig_filename='';
if ($request->input('asset_acceptance') == 'accepted') {
/**
@@ -153,12 +152,14 @@ class AcceptanceController extends Controller
}
}
// this is horrible
switch($acceptance->checkoutable_type){
case 'App\Models\Asset':
$pdf_view_route ='account.accept.accept-asset-eula';
$asset_model = AssetModel::find($item->model_id);
if (!$asset_model) {
return redirect()->back()->with('error', trans('admin/models/message.does_not_exist'));
}
$display_model = $asset_model->name;
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
@@ -167,7 +168,7 @@ class AcceptanceController extends Controller
$pdf_view_route ='account.accept.accept-accessory-eula';
$accessory = Accessory::find($item->id);
$display_model = $accessory->name;
$assigned_to = User::find($item->assignedTo);
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
case 'App\Models\LicenseSeat':
@@ -244,17 +245,51 @@ 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();
// This is the most horriblest
switch($acceptance->checkoutable_type){
case 'App\Models\Asset':
$asset_model = AssetModel::find($item->model_id);
$display_model = $asset_model->name;
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
case 'App\Models\Accessory':
$assigned_to = User::find($item->assignedTo);
$accessory = Accessory::find($item->id);
$display_model = $accessory->name;
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
case 'App\Models\LicenseSeat':
@@ -266,6 +301,8 @@ class AcceptanceController extends Controller
break;
case 'App\Models\Consumable':
$consumable = Consumable::find($item->id);
$display_model = $consumable->name;
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
}
@@ -274,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));
@@ -289,4 +333,4 @@ class AcceptanceController extends Controller
return redirect()->to('account/accept')->with('success', $return_msg);
}
}
}

View File

@@ -80,12 +80,9 @@ class AccessoriesController extends Controller
$accessories->where('notes','=',$request->input('notes'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($accessories) && ($request->get('offset') > $accessories->count())) ? $accessories->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $accessories->count()) ? $accessories->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort_override = $request->input('sort');
@@ -153,7 +150,7 @@ class AccessoriesController extends Controller
public function show($id)
{
$this->authorize('view', Accessory::class);
$accessory = Accessory::findOrFail($id);
$accessory = Accessory::withCount('users as users_count')->findOrFail($id);
return (new AccessoriesTransformer)->transformAccessory($accessory);
}
@@ -334,7 +331,7 @@ class AccessoriesController extends Controller
$accessory = Accessory::find($accessory_user->accessory_id);
$this->authorize('checkin', $accessory);
$logaction = $accessory->logCheckin(User::find($accessory_user->user_id), $request->input('note'));
$logaction = $accessory->logCheckin(User::find($accessory_user->assigned_to), $request->input('note'));
// Was the accessory updated?
if (DB::table('accessories_users')->where('id', '=', $accessory_user->id)->delete()) {

View File

@@ -36,7 +36,7 @@ class AssetMaintenancesController extends Controller
{
$this->authorize('view', Asset::class);
$maintenances = AssetMaintenance::select('asset_maintenances.*')->with('asset', 'asset.model', 'asset.location', 'supplier', 'asset.company', 'admin');
$maintenances = AssetMaintenance::select('asset_maintenances.*')->with('asset', 'asset.model', 'asset.location', 'asset.defaultLoc', 'supplier', 'asset.company', 'admin');
if ($request->filled('search')) {
$maintenances = $maintenances->TextSearch($request->input('search'));
@@ -55,12 +55,9 @@ class AssetMaintenancesController extends Controller
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($maintenances) && ($request->get('offset') > $maintenances->count())) ? $maintenances->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $maintenances->count()) ? $maintenances->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$allowed_columns = [
'id',
@@ -74,7 +71,8 @@ class AssetMaintenancesController extends Controller
'asset_tag',
'asset_name',
'user_id',
'supplier'
'supplier',
'is_warranty',
];
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
@@ -121,7 +119,7 @@ class AssetMaintenancesController extends Controller
$assetMaintenance = new AssetMaintenance();
$assetMaintenance->supplier_id = $request->input('supplier_id');
$assetMaintenance->is_warranty = $request->input('is_warranty');
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
$assetMaintenance->cost = $request->input('cost');
$assetMaintenance->notes = e($request->input('notes'));
$asset = Asset::find(e($request->input('asset_id')));
@@ -178,7 +176,7 @@ class AssetMaintenancesController extends Controller
$assetMaintenance->supplier_id = e($request->input('supplier_id'));
$assetMaintenance->is_warranty = e($request->input('is_warranty'));
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
$assetMaintenance->cost = $request->input('cost');
$assetMaintenance->notes = e($request->input('notes'));
$asset = Asset::find(request('asset_id'));

View File

@@ -38,6 +38,7 @@ class AssetModelsController extends Controller
'image',
'name',
'model_number',
'min_amt',
'eol',
'notes',
'created_at',
@@ -52,6 +53,7 @@ class AssetModelsController extends Controller
'models.image',
'models.name',
'model_number',
'min_amt',
'eol',
'requestable',
'models.notes',
@@ -63,7 +65,7 @@ class AssetModelsController extends Controller
'models.deleted_at',
'models.updated_at',
])
->with('category', 'depreciation', 'manufacturer', 'fieldset')
->with('category', 'depreciation', 'manufacturer')
->withCount('assets as assets_count');
if ($request->input('status')=='deleted') {
@@ -78,12 +80,9 @@ class AssetModelsController extends Controller
$assetmodels->TextSearch($request->input('search'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($assetmodels) && ($request->get('offset') > $assetmodels->count())) ? $assetmodels->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $assetmodels->count()) ? $assetmodels->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'models.created_at';

View File

@@ -110,12 +110,12 @@ class AssetsController extends Controller
$filter = json_decode($request->input('filter'), true);
}
$all_custom_fields = CustomField::all(); //used as a 'cache' of custom fields throughout this page load
$all_custom_fields = CustomField::where('type', Asset::class); //used as a 'cache' of custom fields throughout this page load
foreach ($all_custom_fields as $field) {
$allowed_columns[] = $field->db_column_name();
}
$assets = Company::scopeCompanyables(Asset::select('assets.*'), 'company_id', 'assets')
$assets = Asset::select('assets.*')
->with('location', 'assetstatus', 'company', 'defaultLoc','assignedTo',
'model.category', 'model.manufacturer', 'model.fieldset','supplier'); //it might be tempting to add 'assetlog' here, but don't. It blows up update-heavy users.
@@ -125,6 +125,8 @@ class AssetsController extends Controller
$assets->InModelList($non_deprecable_models->toArray());
}
// These are used by the API to query against specific ID numbers.
// They are also used by the individual searches on detail pages like
// locations, etc.
@@ -136,6 +138,101 @@ class AssetsController extends Controller
}
}
if ((! is_null($filter)) && (count($filter)) > 0) {
$assets->ByFilter($filter);
} elseif ($request->filled('search')) {
$assets->TextSearch($request->input('search'));
}
// This is used by the audit reporting routes
if (Gate::allows('audit', Asset::class)) {
switch ($audit) {
case 'due':
$assets->DueOrOverdueForAudit($settings);
break;
case 'overdue':
$assets->overdueForAudit($settings);
break;
}
}
// This is used by the sidenav, mostly
// We switched from using query scopes here because of a Laravel bug
// related to fulltext searches on complex queries.
// I am sad. :(
switch ($request->input('status')) {
case 'Deleted':
$assets->onlyTrashed();
break;
case 'Pending':
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 0)
->where('status_alias.pending', '=', 1)
->where('status_alias.archived', '=', 0);
});
break;
case 'RTD':
$assets->whereNull('assets.assigned_to')
->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 1)
->where('status_alias.pending', '=', 0)
->where('status_alias.archived', '=', 0);
});
break;
case 'Undeployable':
$assets->Undeployable();
break;
case 'Archived':
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 0)
->where('status_alias.pending', '=', 0)
->where('status_alias.archived', '=', 1);
});
break;
case 'Requestable':
$assets->where('assets.requestable', '=', 1)
->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 1)
->where('status_alias.pending', '=', 0)
->where('status_alias.archived', '=', 0);
});
break;
case 'Deployed':
// more sad, horrible workarounds for laravel bugs when doing full text searches
$assets->whereNotNull('assets.assigned_to');
break;
case 'byod':
// This is kind of redundant, since we already check for byod=1 above, but this keeps the
// sidebar nav links a little less chaotic
$assets->where('assets.byod', '=', '1');
break;
default:
if ((! $request->filled('status_id')) && ($settings->show_archived_in_list != '1')) {
// terrible workaround for complex-query Laravel bug in fulltext
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.archived', '=', 0);
});
// If there is a status ID, don't take show_archived_in_list into consideration
} else {
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id');
});
}
}
// Leave these under the TextSearch scope, else the fuzziness will override the specific ID (status ID, etc) requested
if ($request->filled('status_id')) {
$assets->where('assets.status_id', '=', $request->input('status_id'));
}
@@ -197,114 +294,10 @@ class AssetsController extends Controller
$assets->where('assets.byod', '=', $request->input('byod'));
}
$request->filled('order_number') ? $assets = $assets->where('assets.order_number', '=', e($request->get('order_number'))) : '';
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($assets) && ($request->get('offset') > $assets->count())) ? $assets->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
// This is used by the audit reporting routes
if (Gate::allows('audit', Asset::class)) {
switch ($audit) {
case 'due':
$assets->DueOrOverdueForAudit($settings);
break;
case 'overdue':
$assets->overdueForAudit($settings);
break;
}
if ($request->filled('order_number')) {
$assets->where('assets.order_number', '=', $request->get('order_number'));
}
// This is used by the sidenav, mostly
// We switched from using query scopes here because of a Laravel bug
// related to fulltext searches on complex queries.
// I am sad. :(
switch ($request->input('status')) {
case 'Deleted':
$assets->onlyTrashed();
break;
case 'Pending':
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 0)
->where('status_alias.pending', '=', 1)
->where('status_alias.archived', '=', 0);
});
break;
case 'RTD':
$assets->whereNull('assets.assigned_to')
->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 1)
->where('status_alias.pending', '=', 0)
->where('status_alias.archived', '=', 0);
});
break;
case 'Undeployable':
$assets->Undeployable();
break;
case 'Archived':
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 0)
->where('status_alias.pending', '=', 0)
->where('status_alias.archived', '=', 1);
});
break;
case 'Requestable':
$assets->where('assets.requestable', '=', 1)
->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.deployable', '=', 1)
->where('status_alias.pending', '=', 0)
->where('status_alias.archived', '=', 0);
});
break;
case 'Deployed':
// more sad, horrible workarounds for laravel bugs when doing full text searches
$assets->where('assets.assigned_to', '>', '0');
break;
case 'byod':
// This is kind of redundant, since we already check for byod=1 above, but this keeps the
// sidebar nav links a little less chaotic
$assets->where('assets.byod', '=', '1');
break;
default:
if ((! $request->filled('status_id')) && ($settings->show_archived_in_list != '1')) {
// terrible workaround for complex-query Laravel bug in fulltext
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id')
->where('status_alias.archived', '=', 0);
});
// If there is a status ID, don't take show_archived_in_list into consideration
} else {
$assets->join('status_labels AS status_alias', function ($join) {
$join->on('status_alias.id', '=', 'assets.status_id');
});
}
}
if ((! is_null($filter)) && (count($filter)) > 0) {
$assets->ByFilter($filter);
} elseif ($request->filled('search')) {
$assets->TextSearch($request->input('search'));
}
// This is kinda gross, but we need to do this because the Bootstrap Tables
// API passes custom field ordering as custom_fields.fieldname, and we have to strip
// that out to let the default sorter below order them correctly on the assets table.
@@ -314,7 +307,8 @@ class AssetsController extends Controller
// in the allowed_columns array)
$column_sort = in_array($sort_override, $allowed_columns) ? $sort_override : 'assets.created_at';
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
switch ($sort_override) {
case 'model':
$assets->OrderModels($order);
@@ -351,6 +345,10 @@ class AssetsController extends Controller
}
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $assets->count()) ? $assets->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
@@ -481,7 +479,7 @@ class AssetsController extends Controller
public function selectlist(Request $request)
{
$assets = Company::scopeCompanyables(Asset::select([
$assets = Asset::select([
'assets.id',
'assets.name',
'assets.asset_tag',
@@ -489,7 +487,7 @@ class AssetsController extends Controller
'assets.assigned_to',
'assets.assigned_type',
'assets.status_id',
])->with('model', 'assetstatus', 'assignedTo')->NotArchived(), 'company_id', 'assets');
])->with('model', 'assetstatus', 'assignedTo')->NotArchived();
if ($request->filled('assetStatusType') && $request->input('assetStatusType') === 'RTD') {
$assets = $assets->RTD();
@@ -547,14 +545,16 @@ class AssetsController extends Controller
$asset->model_id = $request->get('model_id');
$asset->order_number = $request->get('order_number');
$asset->notes = $request->get('notes');
$asset->asset_tag = $request->get('asset_tag', Asset::autoincrement_asset());
$asset->asset_tag = $request->get('asset_tag', Asset::autoincrement_asset()); //yup, problem :/
// NO IT IS NOT!!! This is never firing; we SHOW the asset_tag you're going to get, so it *will* be filled in!
$asset->user_id = Auth::id();
$asset->archived = '0';
$asset->physical = '1';
$asset->depreciate = '0';
$asset->status_id = $request->get('status_id', 0);
$asset->warranty_months = $request->get('warranty_months', null);
$asset->purchase_cost = Helper::ParseCurrency($request->get('purchase_cost')); // this is the API's store method, so I don't know that I want to do this? Confusing. FIXME (or not?!)
$asset->purchase_cost = $request->get('purchase_cost');
$asset->asset_eol_date = $request->get('asset_eol_date', $asset->present()->eol_date());
$asset->purchase_date = $request->get('purchase_date', null);
$asset->assigned_to = $request->get('assigned_to', null);
$asset->supplier_id = $request->get('supplier_id');
@@ -562,6 +562,7 @@ class AssetsController extends Controller
$asset->rtd_location_id = $request->get('rtd_location_id', null);
$asset->location_id = $request->get('rtd_location_id', null);
/**
* this is here just legacy reasons. Api\AssetController
* used image_source once to allow encoded image uploads.
@@ -572,41 +573,8 @@ class AssetsController extends Controller
$asset = $request->handleImages($asset);
// Update custom fields in the database.
// Validation for these fields is handled through the AssetRequest form request
$model = AssetModel::find($request->get('model_id'));
if (($model) && ($model->fieldset)) {
foreach ($model->fieldset->fields as $field) {
$asset->customFill($request, Auth::user(), true);
// Set the field value based on what was sent in the request
$field_val = $request->input($field->db_column, null);
// If input value is null, use custom field's default value
if ($field_val == null) {
\Log::debug('Field value for '.$field->db_column.' is null');
$field_val = $field->defaultValue($request->get('model_id'));
\Log::debug('Use the default fieldset value of '.$field->defaultValue($request->get('model_id')));
}
// if the field is set to encrypted, make sure we encrypt the value
if ($field->field_encrypted == '1') {
\Log::debug('This model field is encrypted in this fieldset.');
if (Gate::allows('admin')) {
// If input value is null, use custom field's default value
if (($field_val == null) && ($request->has('model_id') != '')) {
$field_val = \Crypt::encrypt($field->defaultValue($request->get('model_id')));
} else {
$field_val = \Crypt::encrypt($request->input($field->db_column));
}
}
}
$asset->{$field->db_column} = $field_val;
}
}
if ($asset->save()) {
if ($request->get('assigned_user')) {
@@ -666,21 +634,7 @@ class AssetsController extends Controller
$asset = $request->handleImages($asset);
// Update custom fields
if (($model = AssetModel::find($asset->model_id)) && (isset($model->fieldset))) {
foreach ($model->fieldset->fields as $field) {
if ($request->has($field->db_column)) {
if ($field->field_encrypted == '1') {
if (Gate::allows('admin')) {
$asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column));
}
} else {
$asset->{$field->db_column} = $request->input($field->db_column);
}
}
}
}
$asset->customFill($request,Auth::user());
if ($asset->save()) {
if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) {
@@ -903,6 +857,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;
@@ -922,10 +877,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')));
}
@@ -1031,9 +990,10 @@ class AssetsController extends Controller
{
$this->authorize('viewRequestable', Asset::class);
$assets = Company::scopeCompanyables(Asset::select('assets.*'), 'company_id', 'assets')
$assets = Asset::select('assets.*')
->with('location', 'assetstatus', 'assetlog', 'company', 'defaultLoc','assignedTo',
'model.category', 'model.manufacturer', 'model.fieldset', 'supplier')->requestableAssets();
'model.category', 'model.manufacturer', 'model.fieldset', 'supplier')
->requestableAssets();
$offset = request('offset', 0);
$limit = $request->input('limit', 50);

View File

@@ -67,8 +67,6 @@ class CategoriesController extends Controller
$categories = $categories->withCount('showableAssets as assets_count');
}
if ($request->filled('search')) {
$categories = $categories->TextSearch($request->input('search'));
}
@@ -93,14 +91,9 @@ class CategoriesController extends Controller
$categories->where('checkin_email', '=', $request->input('checkin_email'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($categories) && ($request->get('offset') > $categories->count())) ? $categories->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $categories->count()) ? $categories->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets_count';

View File

@@ -27,6 +27,9 @@ class CompaniesController extends Controller
$allowed_columns = [
'id',
'name',
'phone',
'fax',
'email',
'created_at',
'updated_at',
'users_count',
@@ -47,13 +50,15 @@ class CompaniesController extends Controller
$companies->where('name', '=', $request->input('name'));
}
if ($request->filled('email')) {
$companies->where('email', '=', $request->input('email'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($companies) && ($request->get('offset') > $companies->count())) ? $companies->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $companies->count()) ? $companies->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
@@ -168,6 +173,7 @@ class CompaniesController extends Controller
$companies = Company::select([
'companies.id',
'companies.name',
'companies.email',
'companies.image',
]);

View File

@@ -13,6 +13,7 @@ use App\Events\CheckoutableCheckedIn;
use App\Events\ComponentCheckedIn;
use App\Models\Asset;
use Illuminate\Support\Facades\Validator;
use Illuminate\Database\Query\Builder;
class ComponentsController extends Controller
{
@@ -44,9 +45,8 @@ class ComponentsController extends Controller
'notes',
];
$components = Company::scopeCompanyables(Component::select('components.*')
->with('company', 'location', 'category', 'assets'));
$components = Component::select('components.*')
->with('company', 'location', 'category', 'assets', 'supplier');
if ($request->filled('search')) {
$components = $components->TextSearch($request->input('search'));
@@ -64,6 +64,10 @@ class ComponentsController extends Controller
$components->where('category_id', '=', $request->input('category_id'));
}
if ($request->filled('supplier_id')) {
$components->where('supplier_id', '=', $request->input('supplier_id'));
}
if ($request->filled('location_id')) {
$components->where('location_id', '=', $request->input('location_id'));
}
@@ -72,14 +76,10 @@ class ComponentsController extends Controller
$components->where('notes','=',$request->input('notes'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($components) && ($request->get('offset') > $components->count())) ? $components->count() : $request->get('offset', 0);
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $components->count()) ? $components->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort_override = $request->input('sort');
$column_sort = in_array($sort_override, $allowed_columns) ? $sort_override : 'created_at';
@@ -94,6 +94,9 @@ class ComponentsController extends Controller
case 'company':
$components = $components->OrderCompany($order);
break;
case 'supplier':
$components = $components->OrderSupplier($order);
break;
default:
$components = $components->orderBy($column_sort, $order);
break;
@@ -201,12 +204,29 @@ class ComponentsController extends Controller
$this->authorize('view', \App\Models\Asset::class);
$component = Component::findOrFail($id);
$assets = $component->assets();
$offset = request('offset', 0);
$limit = $request->input('limit', 50);
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
if ($request->filled('search')) {
$assets = $component->assets()
->where(function ($query) use ($request) {
$search_str = '%' . $request->input('search') . '%';
$query->where('name', 'like', $search_str)
->orWhereIn('model_id', function (Builder $query) use ($request) {
$search_str = '%' . $request->input('search') . '%';
$query->selectRaw('id')->from('models')->where('name', 'like', $search_str);
})
->orWhere('asset_tag', 'like', $search_str);
})
->get();
$total = $assets->count();
} else {
$assets = $component->assets();
$total = $assets->count();
$assets = $assets->skip($offset)->take($limit)->get();
}
return (new ComponentsTransformer)->transformCheckedoutComponents($assets, $total);
}
@@ -233,7 +253,7 @@ class ComponentsController extends Controller
$this->authorize('checkout', $component);
$validator = Validator::make($request->all(), [
'asset_id' => 'required|exists:assets,id',
'assigned_to' => 'required|exists:assets,id',
'assigned_qty' => "required|numeric|min:1|digits_between:1,".$component->numRemaining(),
]);

View File

@@ -45,11 +45,8 @@ class ConsumablesController extends Controller
'notes',
];
$consumables = Company::scopeCompanyables(
Consumable::select('consumables.*')
->with('company', 'location', 'category', 'users', 'manufacturer')
);
$consumables = Consumable::select('consumables.*')
->with('company', 'location', 'category', 'users', 'manufacturer');
if ($request->filled('search')) {
$consumables = $consumables->TextSearch(e($request->input('search')));
@@ -75,6 +72,10 @@ class ConsumablesController extends Controller
$consumables->where('manufacturer_id', '=', $request->input('manufacturer_id'));
}
if ($request->filled('supplier_id')) {
$consumables->where('supplier_id', '=', $request->input('supplier_id'));
}
if ($request->filled('location_id')) {
$consumables->where('location_id','=',$request->input('location_id'));
}
@@ -84,12 +85,9 @@ class ConsumablesController extends Controller
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($consumables) && ($request->get('offset') > $consumables->count())) ? $consumables->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $consumables->count()) ? $consumables->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$allowed_columns = ['id', 'name', 'order_number', 'min_amt', 'purchase_date', 'purchase_cost', 'company', 'category', 'model_number', 'item_no', 'manufacturer', 'location', 'qty', 'image'];
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
@@ -111,6 +109,9 @@ class ConsumablesController extends Controller
case 'company':
$consumables = $consumables->OrderCompany($order);
break;
case 'supplier':
$components = $consumables->OrderSupplier($order);
break;
default:
$consumables = $consumables->orderBy($column_sort, $order);
break;

View File

@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
use App\Http\Transformers\CustomFieldsetsTransformer;
use App\Http\Transformers\CustomFieldsTransformer;
use App\Models\CustomFieldset;
use App\Models\CustomField;
use Illuminate\Http\Request;
use Redirect;
use View;
@@ -34,7 +35,7 @@ class CustomFieldsetsController extends Controller
public function index()
{
$this->authorize('index', CustomField::class);
$fieldsets = CustomFieldset::withCount('fields as fields_count', 'models as models_count')->get();
$fieldsets = CustomFieldset::withCount('fields as fields_count')->get();
return (new CustomFieldsetsTransformer)->transformCustomFieldsets($fieldsets, $fieldsets->count());
}
@@ -94,6 +95,18 @@ class CustomFieldsetsController extends Controller
$fieldset->fill($request->all());
if ($fieldset->save()) {
// Sync fieldset with auto_add_to_fieldsets
$fields = CustomField::select('id')->where('auto_add_to_fieldsets', '=', '1')->get();
if ($fields->count() > 0) {
foreach ($fields as $field) {
$field_ids[] = $field->id;
}
$fieldset->fields()->sync($field_ids);
}
return response()->json(Helper::formatStandardApiResponse('success', $fieldset, trans('admin/custom_fields/message.fieldset.create.success')));
}
@@ -112,7 +125,7 @@ class CustomFieldsetsController extends Controller
$this->authorize('delete', CustomField::class);
$fieldset = CustomFieldset::findOrFail($id);
$modelsCount = $fieldset->models->count();
$modelsCount = $fieldset->customizables()->count();
$fieldsCount = $fieldset->fields->count();
if (($modelsCount > 0) || ($fieldsCount > 0)) {

View File

@@ -30,6 +30,8 @@ class DepartmentsController extends Controller
$departments = Company::scopeCompanyables(Department::select(
'departments.id',
'departments.name',
'departments.phone',
'departments.fax',
'departments.location_id',
'departments.company_id',
'departments.manager_id',
@@ -58,12 +60,9 @@ class DepartmentsController extends Controller
$departments->where('location_id', '=', $request->input('location_id'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($departments) && ($request->get('offset') > $departments->count())) ? $departments->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $departments->count()) ? $departments->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';

View File

@@ -28,12 +28,9 @@ class DepreciationsController extends Controller
$depreciations = $depreciations->TextSearch($request->input('search'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($depreciations) && ($request->get('offset') > $depreciations->count())) ? $depreciations->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $depreciations->count()) ? $depreciations->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';

View File

@@ -35,12 +35,9 @@ class GroupsController extends Controller
$groups->where('name', '=', $request->input('name'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($groups) && ($request->get('offset') > $groups->count())) ? $groups->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $groups->count()) ? $groups->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';

View File

@@ -160,7 +160,7 @@ class ImportController extends Controller
// Run a backup immediately before processing
if ($request->get('run-backup')) {
\Log::debug('Backup manually requested via importer');
Artisan::call('backup:run');
Artisan::call('snipeit:backup', ['--filename' => 'pre-import-backup-'.date('Y-m-d-H:i:s')]);
} else {
\Log::debug('NO BACKUP requested via importer');
}
@@ -193,6 +193,9 @@ class ImportController extends Controller
case 'user':
$redirectTo = 'users.index';
break;
case 'location':
$redirectTo = 'locations.index';
break;
}
if ($errors) { //Failure

View File

@@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Transformers\LabelsTransformer;
use App\Models\Labels\Label;
use Illuminate\Http\Request;
use Illuminate\Support\ItemNotFoundException;
use Auth;
class LabelsController extends Controller
{
/**
* Returns JSON listing of all labels.
*
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
* @return JsonResponse
*/
public function index(Request $request)
{
$this->authorize('view', Label::class);
$labels = Label::find();
if ($request->filled('search')) {
$search = $request->get('search');
$labels = $labels->filter(function ($label, $index) use ($search) {
return stripos($label->getName(), $search) !== false;
});
}
$total = $labels->count();
$offset = $request->get('offset', 0);
$offset = ($offset > $total) ? $total : $offset;
$maxLimit = config('app.max_results');
$limit = $request->get('limit', $maxLimit);
$limit = ($limit > $maxLimit) ? $maxLimit : $limit;
$labels = $labels->skip($offset)->take($limit);
return (new LabelsTransformer)->transformLabels($labels, $total, $request);
}
/**
* Returns JSON with information about a label for detail view.
*
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
* @param string $labelName
* @return JsonResponse
*/
public function show(string $labelName)
{
$labelName = str_replace('/', '\\', $labelName);
try {
$label = Label::find($labelName);
} catch(ItemNotFoundException $e) {
return response()
->json(
Helper::formatStandardApiResponse('error', null, trans('admin/labels/message.does_not_exist')),
404
);
}
$this->authorize('view', $label);
return (new LabelsTransformer)->transformLabel($label);
}
}

View File

@@ -39,8 +39,15 @@ class LicenseSeatsController extends Controller
}
$total = $seats->count();
$offset = (($seats) && (request('offset') >= $total)) ? 0 : request('offset', 0);
$limit = request('limit', 50);
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $seats->count()) ? $seats->count() : abs($request->input('offset'));
if ($offset >= $total ){
$offset = 0;
}
$limit = app('api_limit_value');
$seats = $seats->skip($offset)->take($limit)->get();

View File

@@ -26,8 +26,8 @@ class LicensesController extends Controller
public function index(Request $request)
{
$this->authorize('view', License::class);
$licenses = Company::scopeCompanyables(License::with('company', 'manufacturer', 'supplier','category')->withCount('freeSeats as free_seats_count'));
$licenses = License::with('company', 'manufacturer', 'supplier','category')->withCount('freeSeats as free_seats_count');
if ($request->filled('company_id')) {
$licenses->where('company_id', '=', $request->input('company_id'));
@@ -94,12 +94,9 @@ class LicensesController extends Controller
$licenses->onlyTrashed();
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($licenses) && ($request->get('offset') > $licenses->count())) ? $licenses->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $licenses->count()) ? $licenses->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';

View File

@@ -37,6 +37,8 @@ class LocationsController extends Controller
'locations.city',
'locations.state',
'locations.zip',
'locations.phone',
'locations.fax',
'locations.country',
'locations.parent_id',
'locations.manager_id',
@@ -78,14 +80,15 @@ class LocationsController extends Controller
$locations->where('locations.country', '=', $request->input('country'));
}
$offset = (($locations) && (request('offset') > $locations->count())) ? $locations->count() : request('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $locations->count()) ? $locations->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
switch ($request->input('sort')) {
case 'parent':
$locations->OrderParent($order);
@@ -250,8 +253,12 @@ class LocationsController extends Controller
*/
public function selectlist(Request $request)
{
$this->authorize('view.selectlists');
// If a user is in the process of editing their profile, as determined by the referrer,
// then we check that they have permission to edit their own location.
// Otherwise, we do our normal check that they can view select lists.
$request->headers->get('referer') === route('profile')
? $this->authorize('self.edit_location')
: $this->authorize('view.selectlists');
$locations = Location::select([
'locations.id',

View File

@@ -23,10 +23,10 @@ class ManufacturersController extends Controller
public function index(Request $request)
{
$this->authorize('view', Manufacturer::class);
$allowed_columns = ['id', 'name', 'url', 'support_url', 'support_email', 'support_phone', 'created_at', 'updated_at', 'image', 'assets_count', 'consumables_count', 'components_count', 'licenses_count'];
$allowed_columns = ['id', 'name', 'url', 'support_url', 'support_email', 'warranty_lookup_url', 'support_phone', 'created_at', 'updated_at', 'image', 'assets_count', 'consumables_count', 'components_count', 'licenses_count'];
$manufacturers = Manufacturer::select(
['id', 'name', 'url', 'support_url', 'support_email', 'support_phone', 'created_at', 'updated_at', 'image', 'deleted_at']
['id', 'name', 'url', 'support_url', 'warranty_lookup_url', 'support_email', 'support_phone', 'created_at', 'updated_at', 'image', 'deleted_at']
)->withCount('assets as assets_count')->withCount('licenses as licenses_count')->withCount('consumables as consumables_count')->withCount('accessories as accessories_count');
if ($request->input('deleted') == 'true') {
@@ -49,6 +49,10 @@ class ManufacturersController extends Controller
$manufacturers->where('support_url', '=', $request->input('support_url'));
}
if ($request->filled('warranty_lookup_url')) {
$manufacturers->where('warranty_lookup_url', '=', $request->input('warranty_lookup_url'));
}
if ($request->filled('support_phone')) {
$manufacturers->where('support_phone', '=', $request->input('support_phone'));
}
@@ -57,12 +61,9 @@ class ManufacturersController extends Controller
$manufacturers->where('support_email', '=', $request->input('support_email'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($manufacturers) && ($request->get('offset') > $manufacturers->count())) ? $manufacturers->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $manufacturers->count()) ? $manufacturers->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';

View File

@@ -29,8 +29,10 @@ class PredefinedKitsController extends Controller
$kits = $kits->TextSearch($request->input('search'));
}
$offset = $request->input('offset', 0);
$limit = $request->input('limit', 50);
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $kits->count()) ? $kits->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'desc' ? 'desc' : 'asc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'name';
$kits->orderBy($sort, $order);

View File

@@ -54,15 +54,15 @@ class ReportsController extends Controller
'note',
];
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $actionlogs->count()) ? $actionlogs->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
$order = ($request->input('order') == 'asc') ? 'asc' : 'desc';
$offset = request('offset', 0);
$total = $actionlogs->count();
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
$actionlogs = $actionlogs->orderBy($sort, $order)->skip($offset)->take($limit)->get();
return response()->json((new ActionlogsTransformer)->transformActionlogs($actionlogs, $total), 200, ['Content-Type' => 'application/json;charset=utf8'], JSON_UNESCAPED_UNICODE);

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api;
use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Transformers\AssetsTransformer;
use App\Http\Transformers\SelectlistTransformer;
use App\Http\Transformers\StatuslabelsTransformer;
use App\Models\Asset;
use App\Models\Statuslabel;
@@ -50,12 +51,9 @@ class StatuslabelsController extends Controller
}
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($statuslabels) && ($request->get('offset') > $statuslabels->count())) ? $statuslabels->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $statuslabels->count()) ? $statuslabels->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
@@ -294,4 +292,45 @@ class StatuslabelsController extends Controller
return '0';
}
/**
* Gets a paginated collection for the select2 menus
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.1.1]
* @see \App\Http\Transformers\SelectlistTransformer
*/
public function selectlist(Request $request)
{
$this->authorize('view.selectlists');
$statuslabels = Statuslabel::orderBy('default_label', 'desc')->orderBy('name', 'asc')->orderBy('deployable', 'desc');
if ($request->filled('search')) {
$statuslabels = $statuslabels->where('name', 'LIKE', '%'.$request->get('search').'%');
}
if ($request->filled('deployable')) {
$statuslabels = $statuslabels->where('deployable', '=', '1');
}
if ($request->filled('pending')) {
$statuslabels = $statuslabels->where('pending', '=', '1');
}
if ($request->filled('archived')) {
$statuslabels = $statuslabels->where('archived', '=', '1');
}
$statuslabels = $statuslabels->orderBy('name', 'ASC')->paginate(50);
// Loop through and set some custom properties for the transformer to use.
// This lets us have more flexibility in special cases like assets, where
// they may not have a ->name value but we want to display something anyway
foreach ($statuslabels as $statuslabel) {
$statuslabels->use_text = $statuslabel->name;
}
return (new SelectlistTransformer)->transformSelectlist($statuslabels);
}
}

View File

@@ -23,11 +23,30 @@ class SuppliersController extends Controller
public function index(Request $request)
{
$this->authorize('view', Supplier::class);
$allowed_columns = ['id', 'name', 'address', 'phone', 'contact', 'fax', 'email', 'image', 'assets_count', 'licenses_count', 'accessories_count', 'url'];
$allowed_columns = ['
id',
'name',
'address',
'phone',
'contact',
'fax',
'email',
'image',
'assets_count',
'licenses_count',
'accessories_count',
'components_count',
'consumables_count',
'url',
];
$suppliers = Supplier::select(
['id', 'name', 'address', 'address2', 'city', 'state', 'country', 'fax', 'phone', 'email', 'contact', 'created_at', 'updated_at', 'deleted_at', 'image', 'notes']
)->withCount('assets as assets_count')->withCount('licenses as licenses_count')->withCount('accessories as accessories_count');
['id', 'name', 'address', 'address2', 'city', 'state', 'country', 'fax', 'phone', 'email', 'contact', 'created_at', 'updated_at', 'deleted_at', 'image', 'notes', 'url'])
->withCount('assets as assets_count')
->withCount('licenses as licenses_count')
->withCount('accessories as accessories_count')
->withCount('components as components_count')
->withCount('consumables as consumables_count');
if ($request->filled('search')) {
@@ -74,12 +93,9 @@ class SuppliersController extends Controller
$suppliers->where('notes', '=', $request->input('notes'));
}
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($suppliers) && ($request->get('offset') > $suppliers->count())) ? $suppliers->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $suppliers->count()) ? $suppliers->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';

View File

@@ -13,6 +13,7 @@ use App\Http\Transformers\SelectlistTransformer;
use App\Http\Transformers\UsersTransformer;
use App\Models\Asset;
use App\Models\Company;
use App\Models\CustomField;
use App\Models\License;
use App\Models\User;
use App\Notifications\CurrentInventory;
@@ -36,7 +37,7 @@ class UsersController extends Controller
{
$this->authorize('view', User::class);
$users = User::select([
$allowed_columns = [
'users.activated',
'users.created_by',
'users.address',
@@ -71,17 +72,16 @@ class UsersController extends Controller
'users.start_date',
'users.end_date',
'users.vip',
'users.autoassign_licenses',
])->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('deleted')) && ($request->input('deleted') == 'true')) {
$users = $users->onlyTrashed();
} elseif (($request->filled('all')) && ($request->input('all') == 'true')) {
$users = $users->withTrashed();
foreach(CustomField::where('type', User::class)->get() as $field) {
$allowed_columns[] = $field->db_column_name();
}
$users = User::select()->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');
if ($request->filled('activated')) {
$users = $users->where('users.activated', '=', $request->input('activated'));
@@ -187,18 +187,19 @@ class UsersController extends Controller
$users->has('accessories', '=', $request->input('accessories_count'));
}
if ($request->filled('autoassign_licenses')) {
$users->where('autoassign_licenses', '=', $request->input('autoassign_licenses'));
}
if ($request->filled('search')) {
$users = $users->TextSearch($request->input('search'));
}
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
// Set the offset to the API call's offset, unless the offset is higher than the actual count of items in which
// case we override with the actual count, so we should return 0 items.
$offset = (($users) && ($request->get('offset') > $users->count())) ? $users->count() : $request->get('offset', 0);
// Check to make sure the limit is not higher than the max allowed
((config('app.max_results') >= $request->input('limit')) && ($request->filled('limit'))) ? $limit = $request->input('limit') : $limit = config('app.max_results');
// Make sure the offset and limit are actually integers and do not exceed system limits
$offset = ($request->input('offset') > $users->count()) ? $users->count() : abs($request->input('offset'));
$limit = app('api_limit_value');
switch ($request->input('sort')) {
@@ -262,6 +263,7 @@ class UsersController extends Controller
'vip',
'start_date',
'end_date',
'autoassign_licenses',
];
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
@@ -269,6 +271,14 @@ class UsersController extends Controller
break;
}
if (($request->filled('deleted')) && ($request->input('deleted') == 'true')) {
$users = $users->onlyTrashed();
} 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();
@@ -359,11 +369,13 @@ class UsersController extends Controller
$user->permissions = $permissions_array;
}
$tmp_pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 20);
$tmp_pass = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 40);
$user->password = bcrypt($request->get('password', $tmp_pass));
app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');
$user->customFill($request,Auth::user());
if ($user->save()) {
if ($request->filled('groups')) {
$user->groups()->sync($request->input('groups'));
@@ -454,7 +466,9 @@ class UsersController extends Controller
app('App\Http\Requests\ImageUploadRequest')->handleImages($user, 600, 'image', 'avatars', 'avatar');
$user->customFill($request,Auth::user());
if ($user->save()) {
// Sync group memberships:

View File

@@ -101,7 +101,7 @@ class AssetMaintenancesController extends Controller
$assetMaintenance = new AssetMaintenance();
$assetMaintenance->supplier_id = $request->input('supplier_id');
$assetMaintenance->is_warranty = $request->input('is_warranty');
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
$assetMaintenance->cost = $request->input('cost');
$assetMaintenance->notes = $request->input('notes');
$asset = Asset::find($request->input('asset_id'));
@@ -211,7 +211,7 @@ class AssetMaintenancesController extends Controller
$assetMaintenance->supplier_id = $request->input('supplier_id');
$assetMaintenance->is_warranty = $request->input('is_warranty');
$assetMaintenance->cost = Helper::ParseCurrency($request->input('cost'));
$assetMaintenance->cost = $request->input('cost');
$assetMaintenance->notes = $request->input('notes');
$asset = Asset::find(request('asset_id'));

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Http\Requests\ImageUploadRequest;
use App\Models\AssetModel;
use App\Models\DefaultValuesForCustomFields;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\View;
@@ -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,12 +155,13 @@ 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');
$model->requestable = $request->input('requestable', '0');
$this->removeCustomFieldsDefaultValues($model);
DefaultValuesForCustomFields::forPivot($model, Asset::class)->delete();
if ($request->input('fieldset_id') == '') {
$model->fieldset_id = null;
@@ -286,6 +289,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);
}
@@ -448,7 +452,7 @@ class AssetModelsController extends Controller
}
/**
* Adds default values to a model (as long as they are truthy)
* Adds default values to a model (as long as they are truthy) (does this mean I cannot set a default value of 0?)
*
* @param AssetModel $model
* @param array $defaultValues
@@ -483,22 +487,12 @@ class AssetModelsController extends Controller
}
foreach ($defaultValues as $customFieldId => $defaultValue) {
if(is_array($defaultValue)){
$model->defaultValues()->attach($customFieldId, ['default_value' => implode(', ', $defaultValue)]);
}elseif ($defaultValue) {
$model->defaultValues()->attach($customFieldId, ['default_value' => $defaultValue]);
if(is_array($defaultValue)) {
$defaultValue = implode(', ', $defaultValue);
}
DefaultValuesForCustomFields::updateOrCreate(['custom_field_id' => $customFieldId,'item_pivot_id' => $model->id], ['default_value' => $defaultValue]);
}
return true;
}
/**
* Removes all default values
*
* @return void
*/
private function removeCustomFieldsDefaultValues(AssetModel $model)
{
$model->defaultValues()->detach();
}
}

View File

@@ -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);

View 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;
@@ -94,18 +95,25 @@ class AssetCheckinController extends Controller
\Log::debug('Manually override the location IDs');
\Log::debug('Original Location ID: '.$asset->location_id);
$asset->location_id = '';
\Log::debug('New RTD Location ID: '.$asset->location_id);
\Log::debug('New Location ID: '.$asset->location_id);
}
$asset->location_id = $asset->rtd_location_id;
if ($request->filled('location_id')) {
\Log::debug('NEW Location ID: '.$request->get('location_id'));
$asset->location_id = e($request->get('location_id'));
$asset->location_id = $request->get('location_id');
if ($request->get('update_default_location') == 0){
$asset->rtd_location_id = $request->get('location_id');
}
}
$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');
}
@@ -128,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'));

View File

@@ -89,6 +89,14 @@ class AssetCheckoutController extends Controller
}
}
$settings = \App\Models\Setting::getSettings();
if ($settings->full_multiple_companies_support){
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'));
}

View File

@@ -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);

View File

@@ -12,7 +12,9 @@ use App\Models\CheckoutRequest;
use App\Models\Company;
use App\Models\Location;
use App\Models\Setting;
use App\Models\Statuslabel;
use App\Models\User;
use App\View\Label;
use Auth;
use Carbon\Carbon;
use DB;
@@ -140,9 +142,9 @@ class AssetsController extends Controller
$asset->depreciate = '0';
$asset->status_id = request('status_id');
$asset->warranty_months = request('warranty_months', null);
$asset->purchase_cost = Helper::ParseCurrency($request->get('purchase_cost'));
$asset->purchase_cost = request('purchase_cost');
$asset->purchase_date = request('purchase_date', null);
$asset->asset_eol_date = request('asset_eol_date', null);
$asset->asset_eol_date = request('asset_eol_date', $asset->present()->eol_date());
$asset->assigned_to = request('assigned_to', null);
$asset->supplier_id = request('supplier_id', null);
$asset->requestable = request('requestable', 0);
@@ -162,29 +164,7 @@ class AssetsController extends Controller
$asset = $request->handleImages($asset);
}
// Update custom fields in the database.
// Validation for these fields is handled through the AssetRequest form request
$model = AssetModel::find($request->get('model_id'));
if (($model) && ($model->fieldset)) {
foreach ($model->fieldset->fields as $field) {
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)));
} else {
$asset->{$field->db_column} = \Crypt::encrypt($request->input($field->db_column));
}
}
} else {
if (is_array($request->input($field->db_column))) {
$asset->{$field->db_column} = implode(', ', $request->input($field->db_column));
} else {
$asset->{$field->db_column} = $request->input($field->db_column);
}
}
}
}
$asset->customFill($request, Auth::user()); // Update custom fields in the database.
// Validate the asset before saving
if ($asset->isValid() && $asset->save()) {
@@ -312,7 +292,7 @@ class AssetsController extends Controller
$asset->status_id = $request->input('status_id', null);
$asset->warranty_months = $request->input('warranty_months', null);
$asset->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', 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);
@@ -324,6 +304,12 @@ class AssetsController extends Controller
$asset->rtd_location_id = $request->input('rtd_location_id', null);
$asset->byod = $request->input('byod', 0);
$status = Statuslabel::find($asset->status_id);
if($status->archived){
$asset->assigned_to = null;
}
if ($asset->assigned_to == '') {
$asset->location_id = $request->input('rtd_location_id', null);
}
@@ -446,11 +432,12 @@ class AssetsController extends Controller
* @since [v3.0]
* @return Redirect
*/
public function getAssetByTag(Request $request)
public function getAssetByTag(Request $request, $tag=null)
{
$tag = $tag ? $tag : $request->get('assetTag');
$topsearch = ($request->get('topsearch') == 'true');
if (! $asset = Asset::where('asset_tag', '=', $request->get('assetTag'))->first()) {
if (! $asset = Asset::where('asset_tag', '=', $tag)->first()) {
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
}
$this->authorize('view', $asset);
@@ -547,9 +534,11 @@ class AssetsController extends Controller
$asset = Asset::find($assetId);
$this->authorize('view', $asset);
return view('hardware/labels')
->with('assets', Asset::find($asset))
return (new Label())
->with('assets', collect([ $asset ]))
->with('settings', Setting::getSettings())
->with('template', request()->get('template'))
->with('offset', request()->get('offset'))
->with('bulkedit', false)
->with('count', 0);
}
@@ -767,7 +756,7 @@ class AssetsController extends Controller
}
/**
* Retore a deleted asset.
* Restore a deleted asset.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $assetId

View File

@@ -8,11 +8,13 @@ use App\Http\Controllers\CheckInOutRequest;
use App\Http\Controllers\Controller;
use App\Models\Asset;
use App\Models\Setting;
use App\View\Label;
use Illuminate\Http\Request;
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
{
@@ -29,8 +31,8 @@ class BulkAssetsController extends Controller
*/
public function edit(Request $request)
{
$this->authorize('update', Asset::class);
$this->authorize('view', Asset::class);
if (! $request->filled('ids')) {
return redirect()->back()->with('error', trans('admin/hardware/message.update.no_assets_selected'));
}
@@ -40,17 +42,36 @@ 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':
return view('hardware/labels')
->with('assets', Asset::find($asset_ids))
$this->authorize('view', Asset::class);
$assets_found = Asset::find($asset_ids);
if ($assets_found->isEmpty()){
return redirect()->back();
}
return (new Label)
->with('assets', $assets_found)
->with('settings', Setting::getSettings())
->with('bulkedit', true)
->with('count', 0);
case 'delete':
$this->authorize('delete', Asset::class);
$assets = Asset::with('assignedTo', 'location')->find($asset_ids);
$assets->each(function ($asset) {
$this->authorize('delete', $asset);
@@ -58,7 +79,8 @@ class BulkAssetsController extends Controller
return view('hardware/bulk-delete')->with('assets', $assets);
case 'restore':
case 'restore':
$this->authorize('update', Asset::class);
$assets = Asset::withTrashed()->find($asset_ids);
$assets->each(function ($asset) {
$this->authorize('delete', $asset);
@@ -67,9 +89,12 @@ class BulkAssetsController extends Controller
return view('hardware/bulk-restore')->with('assets', $assets);
case 'edit':
$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);
}
}
@@ -87,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');
@@ -95,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'))
@@ -116,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) {
@@ -131,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;
@@ -145,7 +184,7 @@ class BulkAssetsController extends Controller
}
if ($request->filled('purchase_cost')) {
$this->update_array['purchase_cost'] = Helper::ParseCurrency($request->input('purchase_cost'));
$this->update_array['purchase_cost'] = $request->input('purchase_cost');
}
if ($request->filled('company_id')) {
@@ -163,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];
}
}
@@ -179,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'));
}
@@ -333,6 +402,7 @@ class BulkAssetsController extends Controller
}
public function restore(Request $request) {
$this->authorize('update', Asset::class);
$assetIds = $request->get('ids');
if (empty($assetIds)) {
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.restore.nothing_updated'));

View File

@@ -60,6 +60,9 @@ final class CompaniesController extends Controller
$company = new Company;
$company->name = $request->input('name');
$company->phone = $request->input('phone');
$company->fax = $request->input('fax');
$company->email = $request->input('email');
$company = $request->handleImages($company);
@@ -111,6 +114,9 @@ final class CompaniesController extends Controller
$this->authorize('update', $company);
$company->name = $request->input('name');
$company->phone = $request->input('phone');
$company->fax = $request->input('fax');
$company->email = $request->input('email');
$company = $request->handleImages($company);
@@ -119,8 +125,7 @@ final class CompaniesController extends Controller
->with('success', trans('admin/companies/message.update.success'));
}
return redirect()->route('companies.edit', ['company' => $companyId])
->with('error', trans('admin/companies/message.update.error'));
return redirect()->back()->withInput()->withErrors($company->getErrors());
}
/**

View File

@@ -64,8 +64,8 @@ class ComponentCheckoutController extends Controller
$max_to_checkout = $component->numRemaining();
// Make sure there is at least one available to checkout
if ($max_to_checkout <= $request->get('assigned_qty')) {
// Make sure there are at least the requested number of components available to checkout
if ($max_to_checkout < $request->get('assigned_qty')) {
return redirect()->back()->withInput()->with('error', trans('admin/components/message.checkout.unavailable', ['remaining' => $max_to_checkout, 'requested' => $request->get('assigned_qty')]));
}

View File

@@ -71,13 +71,14 @@ class ComponentsController extends Controller
$component = new Component();
$component->name = $request->input('name');
$component->category_id = $request->input('category_id');
$component->supplier_id = $request->input('supplier_id');
$component->location_id = $request->input('location_id');
$component->company_id = Company::getIdForCurrentUser($request->input('company_id'));
$component->order_number = $request->input('order_number', null);
$component->min_amt = $request->input('min_amt', null);
$component->serial = $request->input('serial', null);
$component->purchase_date = $request->input('purchase_date', null);
$component->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost', null));
$component->purchase_cost = $request->input('purchase_cost', null);
$component->qty = $request->input('qty');
$component->user_id = Auth::id();
$component->notes = $request->input('notes');
@@ -145,13 +146,14 @@ class ComponentsController extends Controller
// Update the component data
$component->name = $request->input('name');
$component->category_id = $request->input('category_id');
$component->supplier_id = $request->input('supplier_id');
$component->location_id = $request->input('location_id');
$component->company_id = Company::getIdForCurrentUser($request->input('company_id'));
$component->order_number = $request->input('order_number');
$component->min_amt = $request->input('min_amt');
$component->serial = $request->input('serial');
$component->purchase_date = $request->input('purchase_date');
$component->purchase_cost = Helper::ParseCurrency(request('purchase_cost'));
$component->purchase_cost = request('purchase_cost');
$component->qty = $request->input('qty');
$component->notes = $request->input('notes');

View File

@@ -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);
}
}
}
}

View File

@@ -68,6 +68,7 @@ class ConsumablesController extends Controller
$consumable = new Consumable();
$consumable->name = $request->input('name');
$consumable->category_id = $request->input('category_id');
$consumable->supplier_id = $request->input('supplier_id');
$consumable->location_id = $request->input('location_id');
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
$consumable->order_number = $request->input('order_number');
@@ -76,7 +77,7 @@ class ConsumablesController extends Controller
$consumable->model_number = $request->input('model_number');
$consumable->item_no = $request->input('item_no');
$consumable->purchase_date = $request->input('purchase_date');
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
$consumable->purchase_cost = $request->input('purchase_cost');
$consumable->qty = $request->input('qty');
$consumable->user_id = Auth::id();
$consumable->notes = $request->input('notes');
@@ -144,6 +145,7 @@ class ConsumablesController extends Controller
$consumable->name = $request->input('name');
$consumable->category_id = $request->input('category_id');
$consumable->supplier_id = $request->input('supplier_id');
$consumable->location_id = $request->input('location_id');
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
$consumable->order_number = $request->input('order_number');
@@ -152,7 +154,7 @@ class ConsumablesController extends Controller
$consumable->model_number = $request->input('model_number');
$consumable->item_no = $request->input('item_no');
$consumable->purchase_date = $request->input('purchase_date');
$consumable->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
$consumable->purchase_cost = $request->input('purchase_cost');
$consumable->qty = Helper::ParseFloat($request->input('qty'));
$consumable->notes = $request->input('notes');

View 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);
}
}
}

View File

@@ -6,9 +6,12 @@ use App\Helpers\Helper;
use App\Http\Requests\CustomFieldRequest;
use App\Models\CustomField;
use App\Models\CustomFieldset;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Redirect;
/**
* This controller handles all actions related to Custom Asset Fields for
* the Snipe-IT Asset Management application.
@@ -20,6 +23,7 @@ use Redirect;
*/
class CustomFieldsController extends Controller
{
/**
* Returns a view with a listing of custom fields.
*
@@ -28,12 +32,16 @@ class CustomFieldsController extends Controller
* @return \Illuminate\Support\Facades\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function index()
public function index(Request $request)
{
$this->authorize('view', CustomField::class);
if ( $request->input('tab') == 1 ) {
// Users section, make sure to auto-create the first fieldset if so
CustomFieldset::firstOrCreate(['type' => Helper::$itemtypes_having_custom_fields[1]], ['name' => 'default']);
}
$fieldsets = CustomFieldset::with('fields', 'models')->get();
$fields = CustomField::with('fieldset')->get();
$fieldsets = CustomFieldset::with('fields')->where("type", Helper::$itemtypes_having_custom_fields[$request->get('tab',0)])->get(); //cannot eager-load 'customizable' because it's not a relation
$fields = CustomField::with('fieldset')->where("type", Helper::$itemtypes_having_custom_fields[$request->get('tab',0)])->get();
return view('custom_fields.index')->with('custom_fieldsets', $fieldsets)->with('custom_fields', $fields);
}
@@ -45,7 +53,7 @@ class CustomFieldsController extends Controller
* @see CustomFieldsController::storeField()
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v5.1.5]
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function show()
@@ -63,14 +71,17 @@ class CustomFieldsController extends Controller
* @return \Illuminate\Support\Facades\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function create()
public function create(Request $request)
{
$this->authorize('create', CustomField::class);
$fieldsets = CustomFieldset::where('type', Helper::$itemtypes_having_custom_fields[$request->get('tab')])->get();
return view('custom_fields.fields.edit', [
'predefinedFormats' => Helper::predefined_formats(),
'customFormat' => '',
])->with('field', new CustomField());
'customFormat' => '',
'fieldsets' => $fieldsets,
'field' => new CustomField(),
]);
}
/**
@@ -79,7 +90,7 @@ class CustomFieldsController extends Controller
* @see CustomFieldsController::createField()
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function store(CustomFieldRequest $request)
@@ -104,8 +115,12 @@ class CustomFieldsController extends Controller
"show_in_email" => $show_in_email,
"is_unique" => $request->get("is_unique", 0),
"display_in_user_view" => $display_in_user_view,
"user_id" => Auth::id()
"auto_add_to_fieldsets" => $request->get("auto_add_to_fieldsets", 0),
"show_in_listview" => $request->get("show_in_listview", 0),
"user_id" => Auth::id(),
]);
// not mass-assignable; must be manual
$field->type = Helper::$itemtypes_having_custom_fields[$request->get('tab')];
if ($request->filled('custom_format')) {
@@ -115,10 +130,23 @@ class CustomFieldsController extends Controller
}
if ($field->save()) {
return redirect()->route('fields.index')->with('success', trans('admin/custom_fields/message.field.create.success'));
// Sync fields with fieldsets
$fieldset_array = $request->input('associate_fieldsets');
if ($request->get('tab') == 1 ) {
$fieldset_array = [CustomFieldset::firstOrCreate(['type' => User::class],['name' => 'default'])->id => true];
}
if (($request->has('associate_fieldsets') || $request->get('tab') == 1) && (is_array($fieldset_array))) {
$field->fieldset()->sync(array_keys($fieldset_array));
} else {
$field->fieldset()->sync([]);
}
return redirect()->route('fields.index',['tab' => $request->get('tab',0)])->with('success', trans('admin/custom_fields/message.field.create.success'));
}
return redirect()->back()->withInput()
return redirect()->back()->with('selected_fieldsets', $request->input('associate_fieldsets'))->withInput()
->with('error', trans('admin/custom_fields/message.field.create.error'));
}
@@ -128,7 +156,7 @@ class CustomFieldsController extends Controller
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function deleteFieldFromFieldset($field_id, $fieldset_id)
@@ -147,8 +175,7 @@ class CustomFieldsController extends Controller
->with('success', trans('admin/custom_fields/message.field.delete.success'));
} else {
return redirect()->back()->withErrors(['message' => "Field is in use and cannot be deleted."]);
}
}
}
return redirect()->back()->withErrors(['message' => "Error deleting field from fieldset"]);
@@ -161,7 +188,7 @@ class CustomFieldsController extends Controller
*
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
* @since [v1.8]
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function destroy($field_id)
@@ -169,12 +196,17 @@ class CustomFieldsController extends Controller
if ($field = CustomField::find($field_id)) {
$this->authorize('delete', $field);
if ($field->type == User::class) {
$field->fieldset()->detach(); // remove from 'default' group (and others, if they exist in the future!)
}
if (($field->fieldset) && ($field->fieldset->count() > 0)) {
return redirect()->back()->withErrors(['message' => 'Field is in-use']);
}
$type = $field->type;
$field->delete();
return redirect()->route("fields.index")
->with("success", trans('admin/custom_fields/message.field.delete.success'));
return redirect()->route('fields.index',['tab' => array_search($type, Helper::$itemtypes_having_custom_fields)])
->with('success', trans('admin/custom_fields/message.field.delete.success'));
}
return redirect()->back()->withErrors(['message' => 'Field does not exist']);
@@ -190,12 +222,12 @@ class CustomFieldsController extends Controller
* @return \Illuminate\Support\Facades\View
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function edit($id)
public function edit(Request $request, $id)
{
if ($field = CustomField::find($id)) {
$this->authorize('update', $field);
$fieldsets = CustomFieldset::get();
$customFormat = '';
if ((stripos($field->format, 'regex') === 0) && ($field->format !== CustomField::PREDEFINED_FORMATS['MAC'])) {
$customFormat = $field->format;
@@ -204,6 +236,7 @@ class CustomFieldsController extends Controller
return view('custom_fields.fields.edit', [
'field' => $field,
'customFormat' => $customFormat,
'fieldsets' => $fieldsets,
'predefinedFormats' => Helper::predefined_formats(),
]);
}
@@ -222,7 +255,7 @@ class CustomFieldsController extends Controller
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $id
* @since [v4.0]
* @return Redirect
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function update(CustomFieldRequest $request, $id)
@@ -249,6 +282,8 @@ class CustomFieldsController extends Controller
$field->show_in_email = $show_in_email;
$field->is_unique = $request->get("is_unique", 0);
$field->display_in_user_view = $display_in_user_view;
$field->auto_add_to_fieldsets = $request->get("auto_add_to_fieldsets", 0);
$field->show_in_listview = $request->get("show_in_listview", 0);
if ($request->get('format') == 'CUSTOM REGEX') {
$field->format = e($request->get('custom_format'));
@@ -256,12 +291,22 @@ class CustomFieldsController extends Controller
$field->format = e($request->get('format'));
}
if($field->element == 'checkbox' || $field->element == 'radio'){
if ($field->element == 'checkbox' || $field->element == 'radio'){
$field->format = 'ANY';
}
if ($field->save()) {
return redirect()->route('fields.index')->with('success', trans('admin/custom_fields/message.field.update.success'));
// Sync fields with fieldsets
$fieldset_array = $request->input('associate_fieldsets');
if ($request->has('associate_fieldsets') && (is_array($fieldset_array))) {
$field->fieldset()->sync(array_keys($fieldset_array));
} else {
$field->fieldset()->sync([]);
}
return redirect()->route('fields.index',['tab' => $request->get('tab',0)])->with('success', trans('admin/custom_fields/message.field.update.success'));
}
return redirect()->back()->withInput()->with('error', trans('admin/custom_fields/message.field.update.error'));

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Helpers\Helper;
use App\Models\AssetModel;
use App\Models\CustomField;
use App\Models\CustomFieldset;
@@ -38,7 +39,7 @@ class CustomFieldsetsController extends Controller
* @throws \Illuminate\Auth\Access\AuthorizationException
* @since [v1.8]
*/
public function show($id)
public function show( $id)
{
$cfset = CustomFieldset::with('fields')
->where('id', '=', $id)->orderBy('id', 'ASC')->first();
@@ -46,7 +47,7 @@ class CustomFieldsetsController extends Controller
$this->authorize('view', $cfset);
if ($cfset) {
$custom_fields_list = ['' => 'Add New Field to Fieldset'] + CustomField::pluck('name', 'id')->toArray();
$custom_fields_list = ['' => 'Add New Field to Fieldset'] + CustomField::where('type', $cfset->type)->pluck('name', 'id')->toArray();
$maxid = 0;
foreach ($cfset->fields as $field) {
@@ -93,16 +94,29 @@ class CustomFieldsetsController extends Controller
{
$this->authorize('create', CustomField::class);
$cfset = new CustomFieldset([
'name' => e($request->get('name')),
$fieldset = new CustomFieldset([
'name' => $request->get('name'),
'user_id' => Auth::user()->id,
'type' => Helper::$itemtypes_having_custom_fields[$request->get('tab')]
// 'sub' =>
]);
$validator = Validator::make($request->all(), $cfset->rules);
if ($validator->passes()) {
$cfset->save();
$validator = Validator::make($request->all(), $fieldset->rules);
return redirect()->route('fieldsets.show', [$cfset->id])
if ($validator->passes()) {
$fieldset->save();
// Sync fieldset with auto_add_to_fieldsets
$fields = CustomField::select('id')->where('auto_add_to_fieldsets', '=', '1')->get();
if ($fields->count() > 0) {
foreach ($fields as $field) {
$field_ids[] = $field->id;
}
$fieldset->fields()->sync($field_ids);
}
return redirect()->route('fieldsets.show', [$fieldset->id])
->with('success', trans('admin/custom_fields/message.fieldset.create.success'));
}

View File

@@ -170,6 +170,8 @@ class DepartmentsController extends Controller
$department->manager_id = ($request->filled('manager_id') ? $request->input('manager_id') : null);
$department->location_id = ($request->filled('location_id') ? $request->input('location_id') : null);
$department->company_id = ($request->filled('company_id') ? $request->input('company_id') : null);
$department->phone = $request->input('phone');
$department->fax = $request->input('fax');
$department = $request->handleImages($department);

View File

@@ -0,0 +1,74 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use Laravel\Socialite\Two\InvalidStateException;
use App\Models\Setting;
class GoogleAuthController extends Controller
{
/**
* We need this constructor so that we override the socialite expected config variables,
* since we want to allow this to be changed via database fields
*/
public function __construct()
{
parent::__construct();
$setting = Setting::getSettings();
config(['services.google.redirect' => config('app.url').'/google/callback']);
config(['services.google.client_id' => $setting->google_client_id]);
config(['services.google.client_secret' => $setting->google_client_secret]);
}
public function redirectToGoogle()
{
return Socialite::driver('google')->redirect();
}
public function handleGoogleCallback()
{
try {
$socialUser = Socialite::driver('google')->user();
\Log::debug('Google user found in Google Workspace');
} catch (InvalidStateException $exception) {
\Log::debug('Google user NOT found in Google Workspace');
return redirect()->route('login')
->withErrors(
[
'username' => [
trans('auth/general.google_login_failed')
],
]
);
}
$user = User::where('username', $socialUser->getEmail())->first();
if ($user) {
\Log::debug('Google user '.$socialUser->getEmail().' found in Snipe-IT');
$user->update([
'avatar' => $socialUser->avatar,
]);
Auth::login($user, true);
return redirect()->route('home');
}
\Log::debug('Google user '.$socialUser->getEmail().' NOT found in Snipe-IT');
return redirect()->route('login')
->withErrors(
[
'username' => [
trans('auth/general.google_login_failed'),
],
]
);
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace App\Http\Controllers;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
use App\Models\Labels\Label;
use App\Models\Manufacturer;
use App\Models\Setting;
use App\Models\User;
use App\View\Label as LabelView;
use Illuminate\Support\Facades\Storage;
class LabelsController extends Controller
{
/**
* Returns the Label view with test data
*
* @author Grant Le Roux <grant.leroux+snipe-it@gmail.com>
* @param string $labelName
* @return \Illuminate\Contracts\View\View
*/
public function show(string $labelName)
{
$labelName = str_replace('/', '\\', $labelName);
$template = Label::find($labelName);
$exampleAsset = new Asset();
$exampleAsset->id = 999999;
$exampleAsset->name = 'JEN-867-5309';
$exampleAsset->asset_tag = 'TCA-00001';
$exampleAsset->serial = 'SN9876543210';
$exampleAsset->company = new Company();
$exampleAsset->company->id = 999999;
$exampleAsset->company->name = 'Test Company Limited';
$exampleAsset->company->image = 'company-image-test.png';
$exampleAsset->assignedto = new User();
$exampleAsset->assignedto->id = 999999;
$exampleAsset->assignedto->first_name = 'Test';
$exampleAsset->assignedto->last_name = 'Person';
$exampleAsset->assignedto->username = 'Test.Person';
$exampleAsset->assignedto->employee_num = '0123456789';
$exampleAsset->model = new AssetModel();
$exampleAsset->model->id = 999999;
$exampleAsset->model->name = 'Test Model';
$exampleAsset->model->model_number = 'MDL5678';
$exampleAsset->model->manufacturer = new Manufacturer();
$exampleAsset->model->manufacturer->id = 999999;
$exampleAsset->model->manufacturer->name = 'Test Manufacturing Inc.';
$exampleAsset->model->category = new Category();
$exampleAsset->model->category->id = 999999;
$exampleAsset->model->category->name = 'Test Category';
$settings = Setting::getSettings();
if (request()->has('settings')) {
$overrides = request()->get('settings');
foreach ($overrides as $key => $value) {
$settings->$key = $value;
}
}
return (new LabelView())
->with('assets', collect([$exampleAsset]))
->with('settings', $settings)
->with('template', $template)
->with('bulkedit', false)
->with('count', 0);
return redirect()->route('home')->with('error', trans('admin/labels/message.does_not_exist'));
}
}

View File

@@ -112,4 +112,54 @@ class LicenseCheckinController extends Controller
// Redirect to the license page with error
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.checkin.error'));
}
/**
* Bulk checkin all license seats
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LicenseCheckinController::create() method that provides the form view
* @since [v6.1.1]
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function bulkCheckin(Request $request, $licenseId) {
$license = License::findOrFail($licenseId);
$this->authorize('checkin', $license);
$licenseSeatsByUser = LicenseSeat::where('license_id', '=', $licenseId)
->whereNotNull('assigned_to')
->with('user')
->get();
foreach ($licenseSeatsByUser as $user_seat) {
$user_seat->assigned_to = null;
if ($user_seat->save()) {
\Log::debug('Checking in '.$license->name.' from user '.$user_seat->username);
$user_seat->logCheckin($user_seat->user, trans('admin/licenses/general.bulk.checkin_all.log_msg'));
}
}
$licenseSeatsByAsset = LicenseSeat::where('license_id', '=', $licenseId)
->whereNotNull('asset_id')
->with('asset')
->get();
$count = 0;
foreach ($licenseSeatsByAsset as $asset_seat) {
$asset_seat->asset_id = null;
if ($asset_seat->save()) {
\Log::debug('Checking in '.$license->name.' from asset '.$asset_seat->asset_tag);
$asset_seat->logCheckin($asset_seat->asset, trans('admin/licenses/general.bulk.checkin_all.log_msg'));
$count++;
}
}
return redirect()->back()->with('success', trans_choice('admin/licenses/general.bulk.checkin_all.success', 2, ['count' => $count] ));
}
}

View File

@@ -30,15 +30,17 @@ class LicenseCheckoutController extends Controller
// Check that the license is valid
if ($license = License::find($licenseId)) {
$this->authorize('checkout', $license);
// If the license is valid, check that there is an available seat
if ($license->avail_seats_count < 1) {
return redirect()->route('licenses.index')->with('error', 'There are no available seats for this license');
}
return view('licenses/checkout', compact('license'));
}
$this->authorize('checkout', $license);
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
return view('licenses/checkout', compact('license'));
}
/**
@@ -126,4 +128,70 @@ class LicenseCheckoutController extends Controller
return false;
}
/**
* Bulk checkin all license seats
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @see LicenseCheckinController::create() method that provides the form view
* @since [v6.1.1]
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function bulkCheckout($licenseId) {
\Log::debug('Checking out '.$licenseId.' via bulk');
$license = License::findOrFail($licenseId);
$this->authorize('checkin', $license);
$avail_count = $license->getAvailSeatsCountAttribute();
$users = User::whereNull('deleted_at')->where('autoassign_licenses', '=', 1)->with('licenses')->get();
\Log::debug($avail_count.' will be assigned');
if ($users->count() > $avail_count) {
\Log::debug('You do not have enough free seats to complete this task, so we will check out as many as we can. ');
}
// If the license is valid, check that there is an available seat
if ($license->availCount()->count() < 1) {
return redirect()->back()->with('error', trans('admin/licenses/general.bulk.checkout_all.error_no_seats'));
}
$assigned_count = 0;
foreach ($users as $user) {
// Check to make sure this user doesn't already have this license checked out to them
if ($user->licenses->where('id', '=', $licenseId)->count()) {
\Log::debug($user->username.' already has this license checked out to them. Skipping... ');
continue;
}
$licenseSeat = $license->freeSeat();
// Update the seat with checkout info
$licenseSeat->assigned_to = $user->id;
if ($licenseSeat->save()) {
$avail_count--;
$assigned_count++;
$licenseSeat->logCheckout(trans('admin/licenses/general.bulk.checkout_all.log_msg'), $user);
\Log::debug('License '.$license->name.' seat '.$licenseSeat->id.' checked out to '.$user->username);
}
if ($avail_count == 0) {
return redirect()->back()->with('warning', trans('admin/licenses/general.bulk.checkout_all.warn_not_enough_seats', ['count' => $assigned_count]));
}
}
if ($assigned_count == 0) {
return redirect()->back()->with('warning', trans('admin/licenses/general.bulk.checkout_all.warn_no_avail_users', ['count' => $assigned_count]));
}
return redirect()->back()->with('success', trans_choice('admin/licenses/general.bulk.checkout_all.success', 2, ['count' => $assigned_count] ));
}
}

View File

@@ -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);
}
}

View File

@@ -6,6 +6,8 @@ use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Company;
use App\Models\License;
use App\Models\LicenseSeat;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
@@ -86,7 +88,7 @@ class LicensesController extends Controller
$license->name = $request->input('name');
$license->notes = $request->input('notes');
$license->order_number = $request->input('order_number');
$license->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
$license->purchase_cost = $request->input('purchase_cost');
$license->purchase_date = $request->input('purchase_date');
$license->purchase_order = $request->input('purchase_order');
$license->purchase_order = $request->input('purchase_order');
@@ -164,7 +166,7 @@ class LicensesController extends Controller
$license->name = $request->input('name');
$license->notes = $request->input('notes');
$license->order_number = $request->input('order_number');
$license->purchase_cost = Helper::ParseCurrency($request->input('purchase_cost'));
$license->purchase_cost = $request->input('purchase_cost');
$license->purchase_date = $request->input('purchase_date');
$license->purchase_order = $request->input('purchase_order');
$license->reassignable = $request->input('reassignable', 0);
@@ -205,7 +207,7 @@ class LicensesController extends Controller
if ($license->assigned_seats_count == 0) {
// Delete the license and the associated license seats
DB::table('license_seats')
->where('id', $license->id)
->where('license_id', $license->id)
->update(['assigned_to' => null, 'asset_id' => null]);
$licenseSeats = $license->licenseseats();
@@ -233,16 +235,40 @@ class LicensesController extends Controller
{
$license = License::with('assignedusers')->find($licenseId);
if ($license) {
$this->authorize('view', $license);
return view('licenses/view', compact('license'));
if (!$license) {
return redirect()->route('licenses.index')
->with('error', trans('admin/licenses/message.does_not_exist'));
}
return redirect()->route('licenses.index')
->with('error', trans('admin/licenses/message.does_not_exist'));
$users_count = User::where('autoassign_licenses', '1')->count();
$total_seats_count = $license->totalSeatsByLicenseID();
$available_seats_count = $license->availCount()->count();
$checkedout_seats_count = ($total_seats_count - $available_seats_count);
\Log::debug('Total: '.$total_seats_count);
\Log::debug('Users: '.$users_count);
\Log::debug('Available: '.$available_seats_count);
\Log::debug('Checkedout: '.$checkedout_seats_count);
$this->authorize('view', $license);
return view('licenses.view', compact('license'))
->with('users_count', $users_count)
->with('total_seats_count', $total_seats_count)
->with('available_seats_count', $available_seats_count)
->with('checkedout_seats_count', $checkedout_seats_count);
}
/**
* Returns a view with prepopulated data for clone
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @param int $licenseId
* @return \Illuminate\Http\RedirectResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function getClone($licenseId = null)
{
if (is_null($license_to_clone = License::find($licenseId))) {

View File

@@ -79,6 +79,8 @@ class LocationsController extends Controller
$location->ldap_ou = $request->input('ldap_ou');
$location->manager_id = $request->input('manager_id');
$location->user_id = Auth::id();
$location->phone = request('phone');
$location->fax = request('fax');
$location = $request->handleImages($location);
@@ -139,6 +141,8 @@ class LocationsController extends Controller
$location->state = $request->input('state');
$location->country = $request->input('country');
$location->zip = $request->input('zip');
$location->phone = request('phone');
$location->fax = request('fax');
$location->ldap_ou = $request->input('ldap_ou');
$location->manager_id = $request->input('manager_id');

View File

@@ -68,6 +68,7 @@ class ManufacturersController extends Controller
$manufacturer->user_id = Auth::id();
$manufacturer->url = $request->input('url');
$manufacturer->support_url = $request->input('support_url');
$manufacturer->warranty_lookup_url = $request->input('warranty_lookup_url');
$manufacturer->support_phone = $request->input('support_phone');
$manufacturer->support_email = $request->input('support_email');
$manufacturer = $request->handleImages($manufacturer);
@@ -123,10 +124,11 @@ class ManufacturersController extends Controller
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
}
// Save the data
// Save the data
$manufacturer->name = $request->input('name');
$manufacturer->url = $request->input('url');
$manufacturer->support_url = $request->input('support_url');
$manufacturer->warranty_lookup_url = $request->input('warranty_lookup_url');
$manufacturer->support_phone = $request->input('support_phone');
$manufacturer->support_email = $request->input('support_email');

View File

@@ -501,7 +501,6 @@ class ReportsController extends Controller
$header[] = trans('general.zip');
}
if ($request->filled('assigned_to')) {
$header[] = trans('admin/hardware/table.checkoutto');
$header[] = trans('general.type');
@@ -532,19 +531,24 @@ class ReportsController extends Controller
}
if ($request->filled('warranty')) {
$header[] = 'Warranty';
$header[] = 'Warranty Expires';
$header[] = trans('admin/hardware/form.warranty');
$header[] = trans('admin/hardware/form.warranty_expires');
}
if ($request->filled('depreciation')) {
$header[] = 'Value';
$header[] = 'Diff';
$header[] = 'Fully Depreciated';
$header[] = trans('admin/hardware/table.book_value');
$header[] = trans('admin/hardware/table.diff');
$header[] = trans('admin/hardware/form.fully_depreciated');
}
if ($request->filled('checkout_date')) {
$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');
}
@@ -590,28 +594,28 @@ class ReportsController extends Controller
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
\Log::debug('Added headers: '.$executionTime);
$assets = \App\Models\Company::scopeCompanyables(Asset::select('assets.*'))->with(
$assets = Asset::select('assets.*')->with(
'location', 'assetstatus', 'company', 'defaultLoc', 'assignedTo',
'model.category', 'model.manufacturer', 'supplier');
if ($request->filled('by_location_id')) {
$assets->where('assets.location_id', $request->input('by_location_id'));
$assets->whereIn('assets.location_id', $request->input('by_location_id'));
}
if ($request->filled('by_rtd_location_id')) {
$assets->where('assets.rtd_location_id', $request->input('by_rtd_location_id'));
$assets->whereIn('assets.rtd_location_id', $request->input('by_rtd_location_id'));
}
if ($request->filled('by_supplier_id')) {
$assets->where('assets.supplier_id', $request->input('by_supplier_id'));
$assets->whereIn('assets.supplier_id', $request->input('by_supplier_id'));
}
if ($request->filled('by_company_id')) {
$assets->where('assets.company_id', $request->input('by_company_id'));
$assets->whereIn('assets.company_id', $request->input('by_company_id'));
}
if ($request->filled('by_model_id')) {
$assets->where('assets.model_id', $request->input('by_model_id'));
$assets->whereIn('assets.model_id', $request->input('by_model_id'));
}
if ($request->filled('by_category_id')) {
@@ -631,7 +635,7 @@ class ReportsController extends Controller
}
if ($request->filled('by_status_id')) {
$assets->where('assets.status_id', $request->input('by_status_id'));
$assets->whereIn('assets.status_id', $request->input('by_status_id'));
}
if (($request->filled('purchase_start')) && ($request->filled('purchase_end'))) {
@@ -639,7 +643,24 @@ class ReportsController extends Controller
}
if (($request->filled('created_start')) && ($request->filled('created_end'))) {
$assets->whereBetween('assets.created_at', [$request->input('created_start'), $request->input('created_end')]);
$created_start = \Carbon::parse($request->input('created_start'))->startOfDay();
$created_end = \Carbon::parse($request->input('created_end'))->endOfDay();
$assets->whereBetween('assets.created_at', [$created_start, $created_end]);
}
if (($request->filled('checkout_date_start')) && ($request->filled('checkout_date_end'))) {
$checkout_start = \Carbon::parse($request->input('checkout_date_start'))->startOfDay();
$checkout_end = \Carbon::parse($request->input('checkout_date_end'))->endOfDay();
$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'))) {
@@ -647,7 +668,10 @@ class ReportsController extends Controller
}
if (($request->filled('last_audit_start')) && ($request->filled('last_audit_end'))) {
$assets->whereBetween('assets.last_audit_date', [$request->input('last_audit_start'), $request->input('last_audit_end')]);
$last_audit_start = \Carbon::parse($request->input('last_audit_start'))->startOfDay();
$last_audit_end = \Carbon::parse($request->input('last_audit_end'))->endOfDay();
$assets->whereBetween('assets.last_audit_date', [$last_audit_start, $last_audit_end]);
}
if (($request->filled('next_audit_start')) && ($request->filled('next_audit_end'))) {
@@ -663,6 +687,7 @@ class ReportsController extends Controller
$assets->onlyTrashed();
}
\Log::debug($assets->toSql());
$assets->orderBy('assets.id', 'ASC')->chunk(20, function ($assets) use ($handle, $customfields, $request) {
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
@@ -822,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 : '';
}
@@ -898,12 +929,8 @@ class ReportsController extends Controller
public function getAssetMaintenancesReport()
{
$this->authorize('reports.view');
// Grab all the improvements
$assetMaintenances = AssetMaintenance::with('asset', 'supplier', 'asset.company')
->orderBy('created_at', 'DESC')
->get();
return view('reports/asset_maintenances', compact('assetMaintenances'));
return view('reports.asset_maintenances');
}
/**
@@ -994,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];

View File

@@ -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')
@@ -827,6 +828,14 @@ class SettingsController extends Controller
if (is_null($setting = Setting::getSettings())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->label2_enable = $request->input('label2_enable');
$setting->label2_template = $request->input('label2_template');
$setting->label2_title = $request->input('label2_title');
$setting->label2_asset_logo = $request->input('label2_asset_logo');
$setting->label2_1d_type = $request->input('label2_1d_type');
$setting->label2_2d_type = $request->input('label2_2d_type');
$setting->label2_2d_target = $request->input('label2_2d_target');
$setting->label2_fields = $request->input('label2_fields');
$setting->labels_per_page = $request->input('labels_per_page');
$setting->labels_width = $request->input('labels_width');
$setting->labels_height = $request->input('labels_height');
@@ -875,7 +884,7 @@ class SettingsController extends Controller
}
if ($setting->save()) {
return redirect()->route('settings.index')
return redirect()->route('settings.labels.index')
->with('success', trans('admin/settings/message.update.success'));
}
@@ -961,6 +970,7 @@ class SettingsController extends Controller
$setting->ldap_phone_field = $request->input('ldap_phone');
$setting->ldap_jobtitle = $request->input('ldap_jobtitle');
$setting->ldap_country = $request->input('ldap_country');
$setting->ldap_location = $request->input('ldap_location');
$setting->ldap_dept = $request->input('ldap_dept');
$setting->ldap_client_tls_cert = $request->input('ldap_client_tls_cert');
$setting->ldap_client_tls_key = $request->input('ldap_client_tls_key');
@@ -1038,6 +1048,48 @@ class SettingsController extends Controller
return $pdf_branding;
}
/**
* Show Google login settings form
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.1.1]
* @return View
*/
public function getGoogleLoginSettings()
{
$setting = Setting::getSettings();
return view('settings.google', compact('setting'));
}
/**
* ShSaveow Google login settings form
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v6.1.1]
* @return View
*/
public function postGoogleLoginSettings(Request $request)
{
if (!config('app.lock_passwords')) {
$setting = Setting::getSettings();
$setting->google_login = $request->input('google_login', 0);
$setting->google_client_id = $request->input('google_client_id');
$setting->google_client_secret = $request->input('google_client_secret');
if ($setting->save()) {
return redirect()->route('settings.index')
->with('success', trans('admin/settings/message.update.success'));
}
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}
return redirect()->back()->with('error', trans('general.feature_disabled'));
}
/**
* Show the listing of backups.
*
@@ -1093,7 +1145,7 @@ class SettingsController extends Controller
public function postBackups()
{
if (! config('app.lock_passwords')) {
Artisan::call('backup:run');
Artisan::call('snipeit:backup', ['--filename' => 'manual-backup-'.date('Y-m-d-H-i-s')]);
$output = Artisan::output();
// Backup completed

View File

@@ -113,7 +113,8 @@ class BulkUsersController extends Controller
->conditionallyAddItem('locale')
->conditionallyAddItem('remote')
->conditionallyAddItem('ldap_import')
->conditionallyAddItem('activated');
->conditionallyAddItem('activated')
->conditionallyAddItem('autoassign_licenses');
// If the manager_id is one of the users being updated, generate a warning.

View File

@@ -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]));
}
}

View File

@@ -74,7 +74,6 @@ class UsersController extends Controller
$permissions = $this->filterDisplayable($permissions);
$user = new User;
$user->activated = 1;
return view('users/edit', compact('groups', 'userGroups', 'permissions', 'userPermissions'))
->with('user', $user);
@@ -121,7 +120,7 @@ class UsersController extends Controller
$user->created_by = Auth::user()->id;
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
$user->autoassign_licenses= $request->input('autoassign_licenses', 1);
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
// Strip out the superuser permission if the user isn't a superadmin
$permissions_array = $request->input('permission');
@@ -134,6 +133,9 @@ class UsersController extends Controller
// we have to invoke the
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
\Log::info("About to call customFill, in the 'store' controller!!!");
$user->customFill($request, Auth::user());
if ($user->save()) {
if ($request->filled('groups')) {
$user->groups()->sync($request->input('groups'));
@@ -211,7 +213,6 @@ class UsersController extends Controller
*/
public function update(SaveUserRequest $request, $id = null)
{
// We need to reverse the UI specific logic for our
// permissions here before we update the user.
$permissions = $request->input('permissions', []);
@@ -269,14 +270,15 @@ class UsersController extends Controller
$user->city = $request->input('city', null);
$user->state = $request->input('state', null);
$user->country = $request->input('country', null);
$user->activated = $request->input('activated', 0);
// if a user is editing themselves we should always keep activated true
$user->activated = $request->input('activated', $request->user()->is($user) ? 1 : 0);
$user->zip = $request->input('zip', null);
$user->remote = $request->input('remote', 0);
$user->vip = $request->input('vip', 0);
$user->website = $request->input('website', null);
$user->start_date = $request->input('start_date', null);
$user->end_date = $request->input('end_date', null);
$user->autoassign_licenses = $request->input('autoassign_licenses', 1);
$user->autoassign_licenses = $request->input('autoassign_licenses', 0);
// Update the location of any assets checked out to this user
Asset::where('assigned_type', User::class)
@@ -301,6 +303,8 @@ class UsersController extends Controller
// Handle uploaded avatar
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
\Log::debug("calling custom fill from the UPDATE method!");
$user->customFill($request, Auth::user());
//\Log::debug(print_r($user, true));
// Was the user updated?
@@ -671,4 +675,4 @@ class UsersController extends Controller
return redirect()->back()->with('error', 'User is not activated, is LDAP synced, or does not have an email address ');
}
}
}

View File

@@ -82,7 +82,7 @@ class ViewAssetsController extends Controller
return view('account/requestable-assets', compact('assets', 'models'));
}
public function getRequestItem(Request $request, $itemType, $itemId = null)
public function getRequestItem(Request $request, $itemType, $itemId = null, $cancel_by_admin = false, $requestingUser = null)
{
$item = null;
$fullItemType = 'App\\Models\\'.studly_case($itemType);
@@ -119,16 +119,16 @@ class ViewAssetsController extends Controller
$settings = Setting::getSettings();
if ($item_request = $item->isRequestedBy($user)) {
$item->cancelRequest();
$data['item_quantity'] = $item_request->qty;
if (($item_request = $item->isRequestedBy($user)) || $cancel_by_admin) {
$item->cancelRequest($requestingUser);
$data['item_quantity'] = ($item_request) ? $item_request->qty : 1;
$logaction->logaction('request_canceled');
if (($settings->alert_email != '') && ($settings->alerts_enabled == '1') && (! config('app.lock_passwords'))) {
$settings->notify(new RequestAssetCancelation($data));
}
return redirect()->route('requestable-assets')->with('success')->with('success', trans('admin/hardware/message.requests.canceled'));
return redirect()->back()->with('success')->with('success', trans('admin/hardware/message.requests.canceled'));
} else {
$item->request();
if (($settings->alert_email != '') && ($settings->alerts_enabled == '1') && (! config('app.lock_passwords'))) {

View File

@@ -18,13 +18,12 @@ class Kernel extends HttpKernel
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Fideloper\Proxy\TrustProxies::class,
\App\Http\Middleware\CheckForSetup::class,
\App\Http\Middleware\CheckForDebug::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\SecurityHeaders::class,
\App\Http\Middleware\PreventBackHistory::class,
\Fruitcake\Cors\HandleCors::class,
\Illuminate\Http\Middleware\HandleCors::class,
];

View File

@@ -0,0 +1,67 @@
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class CategoryEditForm extends Component
{
public $defaultEulaText;
public $eulaText;
public $originalSendCheckInEmailValue;
public $requireAcceptance;
public $sendCheckInEmail;
public $useDefaultEula;
public function mount()
{
$this->originalSendCheckInEmailValue = $this->sendCheckInEmail;
if ($this->eulaText || $this->useDefaultEula) {
$this->sendCheckInEmail = 1;
}
}
public function render()
{
return view('livewire.category-edit-form');
}
public function updated($property, $value)
{
if (! in_array($property, ['eulaText', 'useDefaultEula'])) {
return;
}
$this->sendCheckInEmail = $this->eulaText || $this->useDefaultEula ? 1 : $this->originalSendCheckInEmailValue;
}
public function getShouldDisplayEmailMessageProperty(): bool
{
return $this->eulaText || $this->useDefaultEula;
}
public function getEmailMessageProperty(): string
{
if ($this->useDefaultEula) {
return trans('admin/categories/general.email_will_be_sent_due_to_global_eula');
}
return trans('admin/categories/general.email_will_be_sent_due_to_category_eula');
}
public function getEulaTextDisabledProperty()
{
return (bool)$this->useDefaultEula;
}
public function getSendCheckInEmailDisabledProperty()
{
return $this->eulaText || $this->useDefaultEula;
}
}

View File

@@ -2,6 +2,8 @@
namespace App\Http\Livewire;
use App\Models\Asset;
use App\Models\DefaultValuesForCustomFields;
use Livewire\Component;
use App\Models\CustomFieldset;
@@ -30,7 +32,7 @@ class CustomFieldSetDefaultValuesForModel extends Component
$this->fields = CustomFieldset::find($this->fieldset_id)->fields;
}
$this->add_default_values = ($this->model->defaultValues->count() > 0);
$this->add_default_values = (DefaultValuesForCustomFields::forPivot($this->model, Asset::class)->count() > 0);
}
public function updatedFieldsetId()

View File

@@ -38,6 +38,16 @@ class Importer extends Component
public $field_map; // we need a separate variable for the field-mapping, because the keys in the normal array are too complicated for Livewire to understand
public $file_id; // TODO: I can't figure out *why* we need this, but it really seems like we do. I can't seem to pull the id from the activeFile for some reason?
// Make these variables public - we set the properties in the constructor so we can localize them (versus the old static arrays)
public $accessories_fields;
public $assets_fields;
public $users_fields;
public $licenses_fields;
public $locations_fields;
public $consumables_fields;
public $components_fields;
public $aliases_fields;
protected $rules = [
'files.*.file_path' => 'required|string',
'files.*.created_at' => 'required|string',
@@ -57,138 +67,40 @@ class Importer extends Component
return json_encode(array_filter($tmp));
}
// all of these 'statics', alas, may have to change to something else to handle translations?
// I'm not sure. Maybe I use them to 'populate' the translations? TBH, I don't know yet.
static $general = [
'category' => 'Category',
'company' => 'Company',
'email' => 'Email',
'item_name' => 'Item Name',
'location' => 'Location',
'maintained' => 'Maintained',
'manufacturer' => 'Manufacturer',
'notes' => 'Notes',
'order_number' => 'Order Number',
'purchase_cost' => 'Purchase Cost',
'purchase_date' => 'Purchase Date',
'quantity' => 'Quantity',
'requestable' => 'Requestable',
'serial' => 'Serial Number',
'supplier' => 'Supplier',
'username' => 'Username',
'department' => 'Department',
];
static $accessories = [
'model_number' => 'Model Number',
];
static $assets = [
'asset_tag' => 'Asset Tag',
'asset_model' => 'Model Name',
'byod' => 'BYOD',
'checkout_class' => 'Checkout Type',
'checkout_location' => 'Checkout Location',
'image' => 'Image Filename',
'model_number' => 'Model Number',
'full_name' => 'Full Name',
'status' => 'Status',
'warranty_months' => 'Warranty Months',
];
static $consumables = [
'item_no' => "Item Number",
'model_number' => "Model Number",
'min_amt' => "Minimum Quantity",
];
static $licenses = [
'asset_tag' => 'Assigned To Asset',
'expiration_date' => 'Expiration Date',
'full_name' => 'Full Name',
'license_email' => 'Licensed To Email',
'license_name' => 'Licensed To Name',
'purchase_order' => 'Purchase Order',
'reassignable' => 'Reassignable',
'seats' => 'Seats',
];
static $users = [
'employee_num' => 'Employee Number',
'first_name' => 'First Name',
'jobtitle' => 'Job Title',
'last_name' => 'Last Name',
'phone_number' => 'Phone Number',
'manager_first_name' => 'Manager First Name',
'manager_last_name' => 'Manager Last Name',
'activated' => 'Activated',
'address' => 'Address',
'city' => 'City',
'state' => 'State',
'country' => 'Country',
'vip' => 'VIP'
];
//array of "real fieldnames" to a list of aliases for that field
static $aliases = [
'model_number' =>
[
'model',
'model no',
'model no.',
'model number',
'model num',
'model num.'
],
'warranty_months' =>
[
'Warranty',
'Warranty Months'
],
'qty' =>
[
'QTY',
'Quantity'
],
'min_amt' =>
[
'Min Amount',
'Min QTY'
],
'next_audit_date' =>
[
'Next Audit',
],
];
private function getColumns($type)
{
switch ($type) {
case 'asset':
$results = self::$general + self::$assets;
$results = $this->assets_fields;
break;
case 'accessory':
$results = self::$general + self::$accessories;
$results = $this->accessories_fields;
break;
case 'consumable':
$results = self::$general + self::$consumables;
$results = $this->consumables_fields;
break;
case 'component':
$results = $this->components_fields;
break;
case 'license':
$results = self::$general + self::$licenses;
$results = $this->licenses_fields;
break;
case 'user':
$results = self::$general + self::$users;
$results = $this->users_fields;
break;
case 'location':
$results = $this->locations_fields;
break;
default:
$results = self::$general;
$results = [];
}
asort($results, SORT_FLAG_CASE | SORT_STRING);
if ($type == "asset") {
// add Custom Fields after a horizontal line
$results['-'] = "———" . trans('admin/custom_fields/general.custom_fields') . "———’";
foreach (CustomField::orderBy('name')->get() as $field) {
foreach (CustomField::where('type', \App\Models\Asset::class)->orderBy('name')->get() as $field) { // TODO - generalize?
$results[$field->db_column_name()] = $field->name;
}
}
@@ -211,7 +123,7 @@ class Importer extends Component
continue;
} else {
//no, this key is *INVALID* for this import type. Better set it to null
// and we'll hope that the aliases or something else picks it up.
// and we'll hope that the $aliases_fields or something else picks it up.
$this->field_map[$i] = null; // fingers crossed! But it's not likely, tbh.
} // TODO - strictly speaking, this isn't necessary here I don't think.
}
@@ -222,8 +134,8 @@ class Importer extends Component
continue 2; //don't bother with the alias check, go to the next header
}
}
// if you got here, we didn't find a match. Try the aliases
foreach (self::$aliases as $key => $alias_values) {
// if you got here, we didn't find a match. Try the $aliases_fields
foreach ($this->aliases_fields as $key => $alias_values) {
foreach ($alias_values as $alias_value) {
if (strcasecmp($alias_value, $header) === 0) { // aLsO CaSe-INSENSitiVE!
// Make *absolutely* sure that this key actually _exists_ in this import type -
@@ -252,7 +164,6 @@ class Importer extends Component
$this->authorize('import');
$this->progress = -1; // '-1' means 'don't show the progressbar'
$this->progress_bar_class = 'progress-bar-warning';
\Log::debug("Hey, we are calling MOUNT (in the importer-file) !!!!!!!!"); //fcuk
$this->importTypes = [
'asset' => trans('general.assets'),
'accessory' => trans('general.accessories'),
@@ -260,6 +171,306 @@ class Importer extends Component
'component' => trans('general.components'),
'license' => trans('general.licenses'),
'user' => trans('general.users'),
'location' => trans('general.locations'),
];
/**
* These are the item-type specific columns
*/
$this->accessories_fields = [
'company' => trans('general.company'),
'location' => trans('general.location'),
'quantity' => trans('general.qty'),
'item_name' => trans('general.item_name_var', ['item' => trans('general.accessory')]),
'model_number' => trans('general.model_no'),
'notes' => trans('general.notes'),
'category' => trans('general.category'),
'supplier' => trans('general.supplier'),
'min_amt' => trans('mail.min_QTY'),
'purchase_cost' => trans('general.purchase_cost'),
'purchase_date' => trans('general.purchase_date'),
'manufacturer' => trans('general.manufacturer'),
'order_number' => trans('general.order_number'),
];
$this->assets_fields = [
'company' => trans('general.company'),
'location' => trans('general.location'),
'item_name' => trans('general.item_name_var', ['item' => trans('general.asset')]),
'asset_tag' => trans('general.asset_tag'),
'asset_model' => trans('general.model_name'),
'byod' => trans('general.byod'),
'model_number' => trans('general.model_no'),
'status' => trans('general.status'),
'warranty_months' => trans('admin/hardware/form.warranty'),
'category' => trans('general.category'),
'requestable' => trans('admin/hardware/general.requestable'),
'serial' => trans('general.serial_number'),
'supplier' => trans('general.supplier'),
'purchase_cost' => trans('general.purchase_cost'),
'purchase_date' => trans('general.purchase_date'),
'purchase_order' => trans('admin/licenses/form.purchase_order'),
'asset_notes' => trans('general.item_notes', ['item' => trans('admin/hardware/general.asset')]),
'model_notes' => trans('general.item_notes', ['item' => trans('admin/hardware/form.model')]),
'manufacturer' => trans('general.manufacturer'),
'order_number' => trans('general.order_number'),
'image' => trans('general.importer.image_filename'),
'asset_eol_date' => trans('admin/hardware/form.eol_date'),
/**
* Checkout fields:
* Assets can be checked out to other assets, people, or locations, but we currently
* only support checkout to people and locations in the importer
**/
'checkout_class' => trans('general.importer.checkout_type'),
'first_name' => trans('general.importer.checked_out_to_first_name'),
'last_name' => trans('general.importer.checked_out_to_last_name'),
'full_name' => trans('general.importer.checked_out_to_fullname'),
'email' => trans('general.importer.checked_out_to_email'),
'username' => trans('general.importer.checked_out_to_username'),
'checkout_location' => trans('general.importer.checkout_location'),
];
$this->consumables_fields = [
'company' => trans('general.company'),
'location' => trans('general.location'),
'quantity' => trans('general.qty'),
'item_name' => trans('general.item_name_var', ['item' => trans('general.consumable')]),
'model_number' => trans('general.model_no'),
'notes' => trans('general.notes'),
'min_amt' => trans('mail.min_QTY'),
'category' => trans('general.category'),
'purchase_cost' => trans('general.purchase_cost'),
'purchase_date' => trans('general.purchase_date'),
'checkout_class' => trans('general.importer.checkout_type'),
'supplier' => trans('general.supplier'),
'manufacturer' => trans('general.manufacturer'),
'order_number' => trans('general.order_number'),
'item_no' => trans('admin/consumables/general.item_no'),
];
$this->components_fields = [
'company' => trans('general.company'),
'location' => trans('general.location'),
'quantity' => trans('general.qty'),
'item_name' => trans('general.item_name_var', ['item' => trans('general.component')]),
'model_number' => trans('general.model_no'),
'notes' => trans('general.notes'),
'category' => trans('general.category'),
'supplier' => trans('general.supplier'),
'min_amt' => trans('mail.min_QTY'),
'purchase_cost' => trans('general.purchase_cost'),
'purchase_date' => trans('general.purchase_date'),
'manufacturer' => trans('general.manufacturer'),
'order_number' => trans('general.order_number'),
'serial' => trans('general.serial_number'),
];
$this->licenses_fields = [
'company' => trans('general.company'),
'location' => trans('general.location'),
'item_name' => trans('general.item_name_var', ['item' => trans('general.license')]),
'asset_tag' => trans('general.importer.checked_out_to_tag'),
'expiration_date' => trans('admin/licenses/form.expiration'),
'full_name' => trans('general.importer.checked_out_to_fullname'),
'license_email' => trans('admin/licenses/form.to_email'),
'license_name' => trans('admin/licenses/form.to_name'),
'purchase_order' => trans('admin/licenses/form.purchase_order'),
'reassignable' => trans('admin/licenses/form.reassignable'),
'seats' => trans('admin/licenses/form.seats'),
'notes' => trans('general.notes'),
'category' => trans('general.category'),
'supplier' => trans('general.supplier'),
'purchase_cost' => trans('general.purchase_cost'),
'purchase_date' => trans('general.purchase_date'),
'maintained' => trans('admin/licenses/form.maintained'),
'checkout_class' => trans('general.importer.checkout_type'),
'serial' => trans('general.license_serial'),
'email' => trans('general.importer.checked_out_to_email'),
'username' => trans('general.importer.checked_out_to_username'),
'manufacturer' => trans('general.manufacturer'),
];
$this->users_fields = [
'id' => trans('general.id'),
'company' => trans('general.company'),
'location' => trans('general.location'),
'department' => trans('general.department'),
'first_name' => trans('general.first_name'),
'last_name' => trans('general.last_name'),
'notes' => trans('general.notes'),
'username' => trans('admin/users/table.username'),
'jobtitle' => trans('admin/users/table.title'),
'phone_number' => trans('admin/users/table.phone'),
'manager_first_name' => trans('general.importer.manager_first_name'),
'manager_last_name' => trans('general.importer.manager_last_name'),
'activated' => trans('general.activated'),
'address' => trans('general.address'),
'city' => trans('general.city'),
'state' => trans('general.state'),
'country' => trans('general.country'),
'zip' => trans('general.zip'),
'vip' => trans('general.importer.vip'),
'remote' => trans('admin/users/general.remote'),
'email' => trans('admin/users/table.email'),
'website' => trans('general.website'),
'avatar' => trans('general.image'),
'gravatar' => trans('general.importer.gravatar'),
'start_date' => trans('general.start_date'),
'end_date' => trans('general.end_date'),
'employee_num' => trans('general.employee_number'),
];
$this->locations_fields = [
'name' => trans('general.item_name_var', ['item' => trans('general.location')]),
'address' => trans('general.address'),
'address2' => trans('general.importer.address2'),
'city' => trans('general.city'),
'state' => trans('general.state'),
'country' => trans('general.country'),
'zip' => trans('general.zip'),
'currency' => trans('general.importer.currency'),
'ldap_ou' => trans('admin/locations/table.ldap_ou'),
'manager_username' => trans('general.importer.manager_username'),
'manager' => trans('general.importer.manager_full_name'),
'parent_location' => trans('admin/locations/table.parent'),
];
// "real fieldnames" to a list of aliases for that field
$this->aliases_fields = [
'item_name' =>
[
'item name',
'asset name',
'accessory name',
'user name',
'consumable name',
'component name',
'name',
],
'item_no' => [
'item number',
'item no.',
'item #',
],
'asset_model' =>
[
'model name',
'model',
],
'gravatar' =>
[
'gravatar',
],
'currency' =>
[
'$',
],
'jobtitle' =>
[
'job title for user',
'job title',
],
'username' =>
[
'user name',
'username',
trans('general.importer.checked_out_to_username'),
],
'first_name' =>
[
'first name',
trans('general.importer.checked_out_to_first_name'),
],
'last_name' =>
[
'last name',
'lastname',
trans('general.importer.checked_out_to_last_name'),
],
'email' =>
[
'email',
'e-mail',
trans('general.importer.checked_out_to_email'),
],
'phone_number' =>
[
'phone',
'phone number',
'phone num',
'telephone number',
'telephone',
'tel.',
],
'serial' =>
[
'serial number',
'serial no.',
'serial no',
'product key',
'key',
],
'model_number' =>
[
'model',
'model no',
'model no.',
'model number',
'model num',
'model num.'
],
'warranty_months' =>
[
'Warranty',
'Warranty Months'
],
'qty' =>
[
'QTY',
'Quantity'
],
'zip' =>
[
'Postal Code',
'Post Code',
'Zip Code'
],
'min_amt' =>
[
'Min Amount',
'Minimum Amount',
'Min Quantity',
'Minimum Quantity',
],
'next_audit_date' =>
[
'Next Audit',
],
'address2' =>
[
'Address 2',
'Address2',
],
'ldap_ou' =>
[
'LDAP OU',
'OU',
],
'parent_location' =>
[
'Parent',
'Parent Location',
],
'manager' =>
[
'Managed By',
'Manager Name',
'Manager Full Name',
],
'manager_username' =>
[
'Manager Username',
],
];
$this->columnOptions[''] = $this->getColumns(''); //blank mode? I don't know what this is supposed to mean
@@ -273,8 +484,7 @@ class Importer extends Component
public function selectFile($id)
{
\Log::debug("TOGGLE EVENT FIRED!");
\Log::debug("The ID we are trying to find is AS FOLLOWS: ".$id);
$this->activeFile = Import::find($id);
$this->field_map = null;
foreach($this->activeFile->header_row as $element) {
@@ -284,11 +494,9 @@ class Importer extends Component
$this->field_map[] = null; // re-inject the 'nulls' if a file was imported with some 'Do Not Import' settings
}
}
//$this->field_map = $this->activeFile->field_map ? array_values($this->activeFile->field_map) : []; // this is wrong
$this->file_id = $id;
$this->import_errors = null;
$this->statusText = null;
\Log::debug("The import type we are about to try and load up is gonna be this: ".$this->activeFile->import_type);
}

View File

@@ -2,7 +2,7 @@
namespace App\Http\Middleware;
use Fideloper\Proxy\TrustProxies as Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
@@ -10,7 +10,7 @@ class TrustProxies extends Middleware
/**
* The trusted proxies for this application.
*
* @var array|string|null
* @var array<int, string>|string|null
*/
protected $proxies;
@@ -19,5 +19,10 @@ class TrustProxies extends Middleware
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB;
protected $headers =
Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB;
}

View File

@@ -26,18 +26,22 @@ class CustomFieldRequest extends FormRequest
{
$rules = [];
$rules['associate_fieldsets.*'] = 'nullable|integer|exists:custom_fieldsets,id';
switch ($this->method()) {
// Brand new
case 'POST':
{
$rules['name'] = 'required|unique:custom_fields';
$rules['tab'] = 'required';
break;
}
// Save all fields
case 'PUT':
$rules['name'] = 'required';
$rules['tab'] = 'required';
break;
// Save only what's passed
@@ -54,4 +58,11 @@ class CustomFieldRequest extends FormRequest
return $rules;
}
public function messages()
{
return [
'associate_fieldsets.*.exists' => trans('admin/custom_fields/message/does_not_exist'),
];
}
}

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',
];

View File

@@ -32,7 +32,7 @@ class AccessoriesTransformer
'model_number' => ($accessory->model_number) ? e($accessory->model_number) : null,
'category' => ($accessory->category) ? ['id' => $accessory->category->id, 'name'=> e($accessory->category->name)] : null,
'location' => ($accessory->location) ? ['id' => $accessory->location->id, 'name'=> e($accessory->location->name)] : null,
'notes' => ($accessory->notes) ? e($accessory->notes) : null,
'notes' => ($accessory->notes) ? Helper::parseEscapedMarkedownInline($accessory->notes) : null,
'qty' => ($accessory->qty) ? (int) $accessory->qty : null,
'purchase_date' => ($accessory->purchase_date) ? Helper::getFormattedDateObject($accessory->purchase_date, 'date') : null,
'purchase_cost' => Helper::formatCurrencyOutput($accessory->purchase_cost),

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,6 +43,7 @@ class ActionlogsTransformer
public function transformActionlog (Actionlog $actionlog, $settings = null)
{
$icon = $actionlog->present()->icon();
$custom_field = CustomField::all();
if ($actionlog->filename!='') {
$icon = e(\App\Helpers\Helper::filetype_icon($actionlog->filename));
}
@@ -46,13 +52,24 @@ class ActionlogsTransformer
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);
if( str_starts_with($fieldname, '_snipeit_')){
if( $custom_field->where('db_column', '=', $fieldname)->where('field_encrypted', true)){
$clean_meta[$fieldname]['old'] = "encrypted";
$clean_meta[$fieldname]['new'] = "encrypted";
}
}
else {
$clean_meta[$fieldname]['old'] = $this->clean_field($fieldata->old);
$clean_meta[$fieldname]['new'] = $this->clean_field($fieldata->new);
}
}
}
$clean_meta= $this->changedInfo($clean_meta);
}
$file_url = '';
@@ -110,14 +127,15 @@ class ActionlogsTransformer
'type' => e($actionlog->targetType()),
] : null,
'note' => ($actionlog->note) ? e($actionlog->note): null,
'note' => ($actionlog->note) ? Helper::parseEscapedMarkedownInline($actionlog->note): null,
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
'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 +150,80 @@ 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']."] ". $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']."] ". $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']."] ".$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']."] ".$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->name ?? trans('admin/models/message.deleted');
$newModel = $model->find($clean_meta['model_id']['new']);
$newModelName = $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->name ?? trans('admin/companies/message.deleted');
$newCompany = $company->find($clean_meta['company_id']['new']);
$newCompanyName = $newCompany->name ?? trans('admin/companies/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->name ?? trans('admin/suppliers/message.deleted');
$newSupplier = $supplier->find($clean_meta['supplier_id']['new']);
$newSupplierName = $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;
}

View File

@@ -49,7 +49,7 @@ class AssetMaintenancesTransformer
'id' => (int) $assetmaintenance->asset->defaultLoc->id,
'name'=> e($assetmaintenance->asset->defaultLoc->name),
] : null,
'notes' => ($assetmaintenance->notes) ? e($assetmaintenance->notes) : null,
'notes' => ($assetmaintenance->notes) ? Helper::parseEscapedMarkedownInline($assetmaintenance->notes) : null,
'supplier' => ($assetmaintenance->supplier) ? ['id' => $assetmaintenance->supplier->id, 'name'=> e($assetmaintenance->supplier->name)] : null,
'cost' => Helper::formatCurrencyOutput($assetmaintenance->cost),
'asset_maintenance_type' => e($assetmaintenance->asset_maintenance_type),
@@ -59,6 +59,7 @@ class AssetMaintenancesTransformer
'user_id' => ($assetmaintenance->admin) ? ['id' => $assetmaintenance->admin->id, 'name'=> e($assetmaintenance->admin->getFullNameAttribute())] : null,
'created_at' => Helper::getFormattedDateObject($assetmaintenance->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($assetmaintenance->updated_at, 'datetime'),
'is_warranty'=> $assetmaintenance->is_warranty,
];

View File

@@ -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),
@@ -63,7 +64,7 @@ class AssetModelsTransformer
'default_fieldset_values' => $default_field_values,
'eol' => ($assetmodel->eol > 0) ? $assetmodel->eol.' months' : 'None',
'requestable' => ($assetmodel->requestable == '1') ? true : false,
'notes' => e($assetmodel->notes),
'notes' => Helper::parseEscapedMarkedownInline($assetmodel->notes),
'created_at' => Helper::getFormattedDateObject($assetmodel->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($assetmodel->updated_at, 'datetime'),
'deleted_at' => Helper::getFormattedDateObject($assetmodel->deleted_at, 'datetime'),

View File

@@ -2,6 +2,7 @@
namespace App\Http\Transformers;
use App\Helpers\CustomFieldHelper;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\Setting;
@@ -38,7 +39,7 @@ class AssetsTransformer
'byod' => ($asset->byod ? true : false),
'model_number' => (($asset->model) && ($asset->model->model_number)) ? e($asset->model->model_number) : null,
'eol' => ($asset->model->eol != '') ? $asset->model->eol : null,
'eol' => (($asset->model) && ($asset->model->eol != '')) ? $asset->model->eol : null,
'asset_eol_date' => ($asset->asset_eol_date != '') ? Helper::getFormattedDateObject($asset->asset_eol_date, 'date') : null,
'status_label' => ($asset->assetstatus) ? [
'id' => (int) $asset->assetstatus->id,
@@ -58,7 +59,7 @@ class AssetsTransformer
'id' => (int) $asset->supplier->id,
'name'=> e($asset->supplier->name),
] : null,
'notes' => ($asset->notes) ? e($asset->notes) : null,
'notes' => ($asset->notes) ? Helper::parseEscapedMarkedownInline($asset->notes) : null,
'order_number' => ($asset->order_number) ? e($asset->order_number) : null,
'company' => ($asset->company) ? [
'id' => (int) $asset->company->id,
@@ -92,52 +93,11 @@ class AssetsTransformer
'checkout_counter' => (int) $asset->checkout_counter,
'requests_counter' => (int) $asset->requests_counter,
'user_can_checkout' => (bool) $asset->availableForCheckout(),
'book_value' => Helper::formatCurrencyOutput($asset->getLinearDepreciatedValue()),
];
if (($asset->model) && ($asset->model->fieldset) && ($asset->model->fieldset->fields->count() > 0)) {
$fields_array = [];
foreach ($asset->model->fieldset->fields as $field) {
if ($field->isFieldDecryptable($asset->{$field->db_column})) {
$decrypted = Helper::gracefulDecrypt($field, $asset->{$field->db_column});
$value = (Gate::allows('superadmin')) ? $decrypted : strtoupper(trans('admin/custom_fields/general.encrypted'));
if ($field->format == 'DATE'){
if (Gate::allows('superadmin')){
$value = Helper::getFormattedDateObject($value, 'date', false);
} else {
$value = strtoupper(trans('admin/custom_fields/general.encrypted'));
}
}
$fields_array[$field->name] = [
'field' => e($field->db_column),
'value' => e($value),
'field_format' => $field->format,
'element' => $field->element,
];
} else {
$value = $asset->{$field->db_column};
if (($field->format == 'DATE') && (!is_null($value)) && ($value!='')){
$value = Helper::getFormattedDateObject($value, 'date', false);
}
$fields_array[$field->name] = [
'field' => e($field->db_column),
'value' => e($value),
'field_format' => $field->format,
'element' => $field->element,
];
}
$array['custom_fields'] = $fields_array;
}
} else {
$array['custom_fields'] = new \stdClass; // HACK to force generation of empty object instead of empty list
}
$array['custom_fields'] = CustomFieldHelper::transform($asset->model->fieldset,$asset);
$permissions_array['available_actions'] = [
'checkout' => ($asset->deleted_at=='' && Gate::allows('checkout', Asset::class)) ? true : false,

View File

@@ -38,6 +38,9 @@ class CategoriesTransformer
case 'component':
$category->item_count = $category->components_count;
break;
case 'license':
$category->item_count = $category->licenses_count;
break;
default:
$category->item_count = 0;
}

View File

@@ -26,6 +26,9 @@ class CompaniesTransformer
$array = [
'id' => (int) $company->id,
'name' => e($company->name),
'phone' => ($company->phone!='') ? e($company->phone): null,
'fax' => ($company->fax!='') ? e($company->fax): null,
'email' => ($company->email!='') ? e($company->email): null,
'image' => ($company->image) ? Storage::disk('public')->url('companies/'.e($company->image)) : null,
'created_at' => Helper::getFormattedDateObject($company->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($company->updated_at, 'datetime'),

View File

@@ -37,6 +37,7 @@ class ComponentsTransformer
'id' => (int) $component->category->id,
'name' => e($component->category->name),
] : null,
'supplier' => ($component->supplier) ? ['id' => $component->supplier->id, 'name'=> e($component->supplier->name)] : null,
'order_number' => e($component->order_number),
'purchase_date' => Helper::getFormattedDateObject($component->purchase_date, 'date'),
'purchase_cost' => Helper::formatCurrencyOutput($component->purchase_cost),
@@ -45,7 +46,7 @@ class ComponentsTransformer
'id' => (int) $component->company->id,
'name' => e($component->company->name),
] : null,
'notes' => ($component->notes) ? e($component->notes) : null,
'notes' => ($component->notes) ? Helper::parseEscapedMarkedownInline($component->notes) : null,
'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
'user_can_checkout' => ($component->numRemaining() > 0) ? 1 : 0,

View File

@@ -31,6 +31,7 @@ class ConsumablesTransformer
'item_no' => e($consumable->item_no),
'location' => ($consumable->location) ? ['id' => (int) $consumable->location->id, 'name' => e($consumable->location->name)] : null,
'manufacturer' => ($consumable->manufacturer) ? ['id' => (int) $consumable->manufacturer->id, 'name' => e($consumable->manufacturer->name)] : null,
'supplier' => ($consumable->supplier) ? ['id' => $consumable->supplier->id, 'name'=> e($consumable->supplier->name)] : null,
'min_amt' => (int) $consumable->min_amt,
'model_number' => ($consumable->model_number != '') ? e($consumable->model_number) : null,
'remaining' => $consumable->numRemaining(),
@@ -38,7 +39,7 @@ class ConsumablesTransformer
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
'purchase_date' => Helper::getFormattedDateObject($consumable->purchase_date, 'date'),
'qty' => (int) $consumable->qty,
'notes' => ($consumable->notes) ? e($consumable->notes) : null,
'notes' => ($consumable->notes) ? Helper::parseEscapedMarkedownInline($consumable->notes) : null,
'created_at' => Helper::getFormattedDateObject($consumable->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($consumable->updated_at, 'datetime'),
];

View File

@@ -48,6 +48,8 @@ class CustomFieldsTransformer
'type' => e($field->element),
'required' => (($field->pivot) && ($field->pivot->required=='1')) ? true : false,
'display_in_user_view' => ($field->display_in_user_view =='1') ? true : false,
'auto_add_to_fieldsets' => ($field->auto_add_to_fieldsets == '1') ? true : false,
'show_in_listview' => ($field->show_in_listview == '1') ? true : false,
'created_at' => Helper::getFormattedDateObject($field->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($field->updated_at, 'datetime'),
];

View File

@@ -3,6 +3,8 @@
namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\CustomFieldset;
use Illuminate\Database\Eloquent\Collection;
@@ -21,8 +23,13 @@ class CustomFieldsetsTransformer
public function transformCustomFieldset(CustomFieldset $fieldset)
{
$fields = $fieldset->fields;
$models = $fieldset->models;
$models = [];
$modelsArray = [];
if ($fieldset->type == Asset::class) {
\Log::debug("Item pivot id is: ".$fieldset->item_pivot_id);
$models = AssetModel::where('fieldset_id', $fieldset->id)->get();
\Log::debug("And the models object count is: ".$models->count());
}
foreach ($models as $model) {
$modelsArray[] = [
@@ -30,15 +37,21 @@ class CustomFieldsetsTransformer
'name' => e($model->name),
];
}
\Log::debug("Models array is: ".print_r($modelsArray,true));
$array = [
'id' => (int) $fieldset->id,
'name' => e($fieldset->name),
'fields' => (new CustomFieldsTransformer)->transformCustomFields($fields, $fieldset->fields_count),
'models' => (new DatatablesTransformer)->transformDatatables($modelsArray, $fieldset->models_count),
'customizables' => (new DatatablesTransformer)->transformDatatables($fieldset->customizables(),count($fieldset->customizables())),
'created_at' => Helper::getFormattedDateObject($fieldset->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($fieldset->updated_at, 'datetime'),
'type' => $fieldset->type,
];
if ($fieldset->type == Asset::class) {
// TODO - removeme - legacy column just for Assets?
$array['models'] = (new DatatablesTransformer)->transformDatatables($modelsArray, count($modelsArray));
}
return $array;
}

View File

@@ -26,6 +26,8 @@ class DepartmentsTransformer
$array = [
'id' => (int) $department->id,
'name' => e($department->name),
'phone' => ($department->phone!='') ? e($department->phone): null,
'fax' => ($department->fax!='') ? e($department->fax): null,
'image' => ($department->image) ? Storage::disk('public')->url(app('departments_upload_url').e($department->image)) : null,
'company' => ($department->company) ? [
'id' => (int) $department->company->id,

View File

@@ -0,0 +1,71 @@
<?php
namespace App\Http\Transformers;
use App\Helpers\Helper;
use App\Models\Labels\Label;
use App\Models\Labels\Sheet;
use App\Models\Labels\RectangleSheet;
use Illuminate\Support\Collection;
class LabelsTransformer
{
public function transformLabels(Collection $labels, $total)
{
$array = [];
foreach ($labels as $label) {
$array[] = self::transformLabel($label);
}
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformLabel(Label $label)
{
$array = [
'name' => $label->getName(),
'unit' => $label->getUnit(),
'width' => number_format($label->getWidth(), 2),
'height' => number_format($label->getHeight(), 2),
'margin_top' => $label->getMarginTop(),
'margin_bottom' => $label->getMarginBottom(),
'margin_left' => $label->getMarginLeft(),
'margin_right' => $label->getMarginRight(),
'support_asset_tag' => $label->getSupportAssetTag(),
'support_1d_barcode' => $label->getSupport1DBarcode(),
'support_2d_barcode' => $label->getSupport2DBarcode(),
'support_fields' => $label->getSupportFields(),
'support_logo' => $label->getSupportLogo(),
'support_title' => $label->getSupportTitle(),
];
if ($label instanceof Sheet) {
$array['sheet_info'] = [
'label_width' => $label->getLabelWidth(),
'label_height' => $label->getLabelHeight(),
'label_margin_top' => $label->getLabelMarginTop(),
'label_margin_bottom' => $label->getLabelMarginBottom(),
'label_margin_left' => $label->getLabelMarginLeft(),
'label_margin_right' => $label->getLabelMarginRight(),
'labels_per_page' => $label->getLabelsPerPage(),
'label_border' => $label->getLabelBorder(),
];
}
if ($label instanceof RectangleSheet) {
$array['rectanglesheet_info'] = [
'columns' => $label->getColumns(),
'rows' => $label->getRows(),
'column_spacing' => $label->getLabelColumnSpacing(),
'row_spacing' => $label->getLabelRowSpacing(),
];
}
return $array;
}
}

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