Compare commits

...

69 Commits

Author SHA1 Message Date
snipe e20338ff9e Merge branch 'develop' 2018-07-09 22:38:04 -07:00
snipe 78530ae123 Fix tests 2018-07-09 21:57:45 -07:00
snipe 52d605d13e Merge branch 'develop'
# Conflicts:
#	config/version.php
2018-07-09 19:21:23 -07:00
snipe 0182615e7e Bumped version 2018-07-09 19:18:38 -07:00
snipe fad84d4437 Merge branch 'develop'
# Conflicts:
#	config/version.php
2018-07-09 19:07:49 -07:00
snipe c162e9a4de Bumped hash 2018-07-09 19:06:56 -07:00
snipe bf1e742df6 Merge branch 'develop' 2018-07-09 19:05:19 -07:00
snipe 0e88a6b268 Fixed bug in branding image upload size text 2018-07-09 19:04:18 -07:00
Till Deeke c1e870528e Fixes the label association (#5510) (#5790) 2018-07-09 14:51:17 -07:00
snipe 35fc001c58 Fixed #5742 - create_function() is deprecated 2018-07-05 20:49:01 -07:00
snipe 339263a295 Fixed #5751 - added option for unique constraint on serial 2018-07-05 19:30:36 -07:00
snipe a44bd9abe0 Disallow deleting category if there are licenses 2018-07-05 18:02:25 -07:00
snipe b850d47282 Merge branch 'develop' 2018-07-05 15:40:07 -07:00
snipe 4099c06b27 fix middleware priority: handle trusted proxies prior setup check
From @plexorama
2018-07-05 15:36:59 -07:00
snipe e559879f91 Add @plexorama as a contributor 2018-07-05 15:35:37 -07:00
snipe abb95e7872 Tweaked custom field default value layout
This still needs work. It’s ugly.
2018-07-05 15:31:27 -07:00
snipe 869de3d251 Fixed broken pagination on status labels API 2018-07-05 14:42:39 -07:00
snipe f3526eccb9 Merge branch 'features/textarea-custom-field' into develop
# Conflicts:
#	public/js/build/all.js
#	public/js/build/vue.js
#	public/js/build/vue.js.map
#	public/js/dist/all.js
#	public/mix-manifest.json
2018-07-05 12:37:07 -07:00
Daniel Meltzer 880faa83a6 Importer2 checkout (#5771)
* Importer: checkout to location, backend changes+tests.

* Import location checkout. Frontend changes.

* Allow importing of item number/model number for consumables.
2018-07-05 12:22:24 -07:00
Juan Font 311f9fcefb Implemented method to get info on the current user of the API (#5722)
* Implemented method to get info on the current user of the API

* Move userinfo method to UsersController

* Added missing files
2018-07-02 20:35:10 -07:00
snipe 8732f299e6 Added logo class for logo override in custom CSS 2018-07-02 18:47:30 -07:00
Arunas Skirius b30aac536a fixed the alignment of a couple navbar icons (#5764) 2018-07-02 18:10:25 -07:00
snipe d7dc4ae0c0 Added manager to custom report 2018-06-27 00:45:09 -07:00
snipe 5bb4c85ccb Update twitter handle 2018-06-27 00:44:54 -07:00
snipe 80dda198c5 Parse line breaks in the detail view 2018-06-21 09:44:10 -07:00
snipe 9442736518 Adds textarea as a custom field type 2018-06-21 09:35:04 -07:00
snipe 2fbad52c71 Merge branch 'develop' 2018-06-21 07:54:01 -07:00
snipe 5975c9fac7 Add @ParadoxGuitarist as a contributor 2018-06-21 07:52:24 -07:00
snipe 7b0e392ecd Add @thelamer as a contributor 2018-06-21 07:52:04 -07:00
snipe b51a10b46b Add @RichardRay as a contributor 2018-06-21 07:51:39 -07:00
snipe 6c58f59d72 Add @EarlRamirez as a contributor 2018-06-21 07:51:24 -07:00
snipe cd9caa24ad Add @SjamonDaal as a contributor 2018-06-21 07:51:13 -07:00
snipe cbb4b4d846 Merge branch 'develop'
# Conflicts:
#	config/version.php
2018-06-21 07:46:27 -07:00
snipe ea4cdadc6e Bumped version 2018-06-21 07:44:58 -07:00
snipe 6638d64d68 Merge remote-tracking branch 'origin/master' into develop 2018-06-21 07:43:32 -07:00
snipe eb412c2bcb Missed one 2018-06-21 07:43:12 -07:00
snipe fde4a59510 Bumped version 2018-06-21 07:40:37 -07:00
snipe 1ee394aa69 Added Select2 to class for dropdowns 2018-06-21 07:40:30 -07:00
snipe 707f90573c Merge branch 'thelamer-docker-fixes' into develop 2018-06-21 07:31:55 -07:00
snipe f8429ad357 Merge branch 'docker-fixes' of https://github.com/thelamer/snipe-it into thelamer-docker-fixes 2018-06-21 07:31:15 -07:00
snipe aa5003d297 Merge branch 'develop' 2018-06-21 07:21:24 -07:00
snipe e9901f5e58 Set composer timeout to 3000 2018-06-21 07:17:51 -07:00
Djamon Staal f0d04a4a57 End help text with a period consistently. (#5731) 2018-06-21 07:13:29 -07:00
Djamon Staal 32e3f748d8 Make version footer configurable. (#5730) 2018-06-21 07:12:16 -07:00
Earl Ramirez fa465a84df Added cron to list of packages (#5729) 2018-06-20 23:28:35 -07:00
Earl Ramirez 82cf1a4467 Updated SELinux label (#5728) 2018-06-20 23:28:20 -07:00
tiagom62 3bbd49dbad Don't run composer as root (#5689)
* dont run composer as root

* better naming
2018-06-20 19:59:44 -07:00
Daniel Meltzer ad21857cae Update my email address across files. (#5716) 2018-06-20 01:59:59 -07:00
Daniel Meltzer 2d18b73138 Fix #5408. (#5715)
The temporary password cannot be added to the users data until after do
any update-related logic, otherwise their password will be overwritten.
2018-06-20 01:59:04 -07:00
Richard Ray Thomas e7bc18dad4 Fixed inconsistent or incorrect comment labels (#5691)
Accessories table was labeled 'Checked out License table' likely just a duplicate of the above comment for the actual licenses table. Very minor.
2018-06-11 20:11:58 -07:00
snipe 62e4eabab0 Fixed #5693 - don’t truncate license key 2018-06-11 18:47:02 -07:00
tiagom62 d204eebab9 Ubuntu Bionic Beaver 18.04 support (#5687)
* bionic box

* bionic beaver support
2018-06-09 11:21:28 -07:00
thelamer ed5823151b in order to avoid manual user intervention of running "php artisan migrate" before installation on a clean database pulling in migration scripts on startup if needed, also ownership of keys needs to be the docker user 2018-06-07 22:29:00 -07:00
snipe 968d7d1f11 Fixed #5354 - adds dd/mm/yyyy to localization 2018-06-05 15:30:50 -07:00
snipe 086683319a Fixed #5172 - autosum on assets detail view for components tab 2018-06-02 06:21:51 -07:00
snipe e5c1f4847d Added emoji to exempt list to match current labels 2018-06-01 13:55:39 -07:00
snipe 087e114d34 Merge branch 'develop' 2018-05-31 16:34:25 -07:00
snipe 5a6b8bb856 Make default custom field value null 2018-05-31 14:21:18 -07:00
snipe 102f567cb5 Fixed typo 2018-05-31 10:55:48 -07:00
snipe 1a64879b65 Only allow remote user settings to be saved if the app is not in demo mode 2018-05-31 10:55:48 -07:00
Brady Wetherington 4a0e5e4b88 Possible fix for oauth issue in Docker 2018-05-31 01:36:51 -07:00
snipe 01857fb056 Added created_at to file upload UI, added header/footer to files modal, fixed string for actions 2018-05-29 16:38:23 -07:00
snipe 3afe4938f9 Fixed #5616 - removed duplicate call to ekkoLightbox on asset view
It’s already in the default blade
2018-05-29 16:36:42 -07:00
snipe 9e0544e735 Fixed #5617 - incorrect url to fieldset editing 2018-05-29 10:41:46 -07:00
snipe 3993c6ad6b Use custom header color in emails 2018-05-29 10:23:39 -07:00
Brian Monroe 649563457d Added notes field to acessories and consumable checkout pages. Resolves request #5607. (#5608) 2018-05-28 14:30:18 -07:00
snipe 6ec75714f0 Force default srtorage engine 2018-05-22 14:57:05 -07:00
snipe 15916e6668 Allow checkout to non-user objects even if the object requires checkout 2018-05-21 17:35:04 -07:00
snipe 76d0562716 Added last name to expected checkin notification
For non-US countries like Germany where it’s considered rude not to include last name
2018-05-21 17:34:27 -07:00
67 changed files with 708 additions and 292 deletions
+54
View File
@@ -920,6 +920,60 @@
"contributions": [
"code"
]
},
{
"login": "SjamonDaal",
"name": "Djamon Staal",
"avatar_url": "https://avatars1.githubusercontent.com/u/4325936?v=4",
"profile": "https://www.sdhd.nl/",
"contributions": [
"code"
]
},
{
"login": "EarlRamirez",
"name": "Earl Ramirez",
"avatar_url": "https://avatars3.githubusercontent.com/u/12306859?v=4",
"profile": "https://github.com/EarlRamirez",
"contributions": [
"code"
]
},
{
"login": "RichardRay",
"name": "Richard Ray Thomas",
"avatar_url": "https://avatars2.githubusercontent.com/u/8671456?v=4",
"profile": "https://github.com/RichardRay",
"contributions": [
"code"
]
},
{
"login": "thelamer",
"name": "Ryan Kuba",
"avatar_url": "https://avatars3.githubusercontent.com/u/1852688?v=4",
"profile": "https://www.taisun.io/",
"contributions": [
"code"
]
},
{
"login": "ParadoxGuitarist",
"name": "Brian Monroe",
"avatar_url": "https://avatars1.githubusercontent.com/u/6751928?v=4",
"profile": "https://github.com/ParadoxGuitarist",
"contributions": [
"code"
]
},
{
"login": "plexorama",
"name": "plexorama",
"avatar_url": "https://avatars1.githubusercontent.com/u/605167?v=4",
"profile": "https://github.com/plexorama",
"contributions": [
"code"
]
}
]
}
+4
View File
@@ -9,6 +9,10 @@ exemptLabels:
- :woman_technologist: ready for dev
- :moneybag: bounty
- :hand: bug
- "🔐 security"
- "👩‍💻 ready for dev"
- "💰 bounty"
- "✋ bug"
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
+1
View File
@@ -18,6 +18,7 @@ patch \
curl \
vim \
git \
cron \
mysql-client \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+3 -3
View File
@@ -1,5 +1,5 @@
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=master)](https://travis-ci.org/snipe/snipe-it) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeyhead.svg?style=social)](https://twitter.com/snipeyhead) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-99-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
[![Build Status](https://travis-ci.org/snipe/snipe-it.svg?branch=master)](https://travis-ci.org/snipe/snipe-it) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/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&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
[![All Contributors](https://img.shields.io/badge/all_contributors-105-orange.svg?style=flat-square)](#contributors) [![Open Source Helpers](https://www.codetriage.com/snipe/snipe-it/badges/users.svg)](https://www.codetriage.com/snipe/snipe-it)
## Snipe-IT - Open Source Asset Management System
@@ -83,7 +83,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
| [<img src="https://avatars2.githubusercontent.com/u/2809241?v=4" width="110px;"/><br /><sub>Robin Temme</sub>](https://github.com/zwerch)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zwerch "Code") | [<img src="https://avatars0.githubusercontent.com/u/6961695?v=4" width="110px;"/><br /><sub>Iman</sub>](https://github.com/imanghafoori1)<br />[💻](https://github.com/snipe/snipe-it/commits?author=imanghafoori1 "Code") | [<img src="https://avatars1.githubusercontent.com/u/6551003?v=4" width="110px;"/><br /><sub>Richard Hofman</sub>](https://github.com/richardhofman6)<br />[💻](https://github.com/snipe/snipe-it/commits?author=richardhofman6 "Code") | [<img src="https://avatars0.githubusercontent.com/u/3697569?v=4" width="110px;"/><br /><sub>gizzmojr</sub>](https://github.com/gizzmojr)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gizzmojr "Code") | [<img src="https://avatars3.githubusercontent.com/u/404729?v=4" width="110px;"/><br /><sub>Jenny Li</sub>](https://github.com/imjennyli)<br />[📖](https://github.com/snipe/snipe-it/commits?author=imjennyli "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/869227?v=4" width="110px;"/><br /><sub>Geoff Young</sub>](https://github.com/GeoffYoung)<br />[💻](https://github.com/snipe/snipe-it/commits?author=GeoffYoung "Code") | [<img src="https://avatars3.githubusercontent.com/u/1068477?v=4" width="110px;"/><br /><sub>Elliot Blackburn</sub>](http://www.elliotblackburn.com)<br />[📖](https://github.com/snipe/snipe-it/commits?author=BlueHatbRit "Documentation") |
| [<img src="https://avatars1.githubusercontent.com/u/6357451?v=4" width="110px;"/><br /><sub>Tõnis Ormisson</sub>](http://andmemasin.eu)<br />[💻](https://github.com/snipe/snipe-it/commits?author=TonisOrmisson "Code") | [<img src="https://avatars0.githubusercontent.com/u/449411?v=4" width="110px;"/><br /><sub>Nicolai Essig</sub>](http://www.nicolai-essig.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thakilla "Code") | [<img src="https://avatars1.githubusercontent.com/u/14809698?v=4" width="110px;"/><br /><sub>Danielle</sub>](https://github.com/techincolor)<br />[📖](https://github.com/snipe/snipe-it/commits?author=techincolor "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/18545156?v=4" width="110px;"/><br /><sub>Lawrence</sub>](https://github.com/TheVakman)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=TheVakman "Tests") [🐛](https://github.com/snipe/snipe-it/issues?q=author%3ATheVakman "Bug reports") | [<img src="https://avatars1.githubusercontent.com/u/22473767?v=4" width="110px;"/><br /><sub>uknzaeinozpas</sub>](https://github.com/uknzaeinozpas)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Tests") [💻](https://github.com/snipe/snipe-it/commits?author=uknzaeinozpas "Code") | [<img src="https://avatars3.githubusercontent.com/u/422752?v=4" width="110px;"/><br /><sub>Ryan</sub>](https://github.com/Gelob)<br />[📖](https://github.com/snipe/snipe-it/commits?author=Gelob "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/10672546?v=4" width="110px;"/><br /><sub>vcordes79</sub>](https://github.com/vcordes79)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vcordes79 "Code") |
| [<img src="https://avatars3.githubusercontent.com/u/27958330?v=4" width="110px;"/><br /><sub>fordster78</sub>](https://github.com/fordster78)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fordster78 "Code") | [<img src="https://avatars0.githubusercontent.com/u/34064225?v=4" width="110px;"/><br /><sub>CronKz</sub>](https://github.com/CronKz)<br />[💻](https://github.com/snipe/snipe-it/commits?author=CronKz "Code") | [<img src="https://avatars1.githubusercontent.com/u/585486?v=4" width="110px;"/><br /><sub>Tim Bishop</sub>](https://github.com/tdb)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tdb "Code") | [<img src="https://avatars2.githubusercontent.com/u/5384694?v=4" width="110px;"/><br /><sub>Sean McIlvenna</sub>](https://www.seanmcilvenna.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=seanmcilvenna "Code") | [<img src="https://avatars3.githubusercontent.com/u/36515590?v=4" width="110px;"/><br /><sub>cepacs</sub>](https://github.com/cepacs)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Acepacs "Bug reports") [📖](https://github.com/snipe/snipe-it/commits?author=cepacs "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/37537300?v=4" width="110px;"/><br /><sub>lea-mink</sub>](https://github.com/lea-mink)<br />[💻](https://github.com/snipe/snipe-it/commits?author=lea-mink "Code") | [<img src="https://avatars0.githubusercontent.com/u/7140719?v=4" width="110px;"/><br /><sub>Hannah Tinkler</sub>](https://github.com/hannahtinkler)<br />[💻](https://github.com/snipe/snipe-it/commits?author=hannahtinkler "Code") |
| [<img src="https://avatars1.githubusercontent.com/u/1086388?v=4" width="110px;"/><br /><sub>Doeke Zanstra</sub>](https://github.com/doekman)<br />[💻](https://github.com/snipe/snipe-it/commits?author=doekman "Code") |
| [<img src="https://avatars1.githubusercontent.com/u/1086388?v=4" width="110px;"/><br /><sub>Doeke Zanstra</sub>](https://github.com/doekman)<br />[💻](https://github.com/snipe/snipe-it/commits?author=doekman "Code") | [<img src="https://avatars1.githubusercontent.com/u/4325936?v=4" width="110px;"/><br /><sub>Djamon Staal</sub>](https://www.sdhd.nl/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=SjamonDaal "Code") | [<img src="https://avatars3.githubusercontent.com/u/12306859?v=4" width="110px;"/><br /><sub>Earl Ramirez</sub>](https://github.com/EarlRamirez)<br />[💻](https://github.com/snipe/snipe-it/commits?author=EarlRamirez "Code") | [<img src="https://avatars2.githubusercontent.com/u/8671456?v=4" width="110px;"/><br /><sub>Richard Ray Thomas</sub>](https://github.com/RichardRay)<br />[💻](https://github.com/snipe/snipe-it/commits?author=RichardRay "Code") | [<img src="https://avatars3.githubusercontent.com/u/1852688?v=4" width="110px;"/><br /><sub>Ryan Kuba</sub>](https://www.taisun.io/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thelamer "Code") | [<img src="https://avatars1.githubusercontent.com/u/6751928?v=4" width="110px;"/><br /><sub>Brian Monroe</sub>](https://github.com/ParadoxGuitarist)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ParadoxGuitarist "Code") | [<img src="https://avatars1.githubusercontent.com/u/605167?v=4" width="110px;"/><br /><sub>plexorama</sub>](https://github.com/plexorama)<br />[💻](https://github.com/snipe/snipe-it/commits?author=plexorama "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
Vendored
+8
View File
@@ -5,6 +5,14 @@ SNIPEIT_SH_URL= "https://raw.githubusercontent.com/snipe/snipe-it/master/snipeit
NETWORK_BRIDGE= "en0: Wi-Fi (AirPort)"
Vagrant.configure("2") do |config|
config.vm.define "bionic" do |bionic|
bionic.vm.box = "ubuntu/bionic64"
bionic.vm.hostname = 'bionic'
bionic.vm.network "public_network", bridge: NETWORK_BRIDGE
bionic.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
bionic.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
end
config.vm.define "xenial" do |xenial|
xenial.vm.box = "ubuntu/xenial64"
xenial.vm.hostname = 'xenial'
+1 -1
View File
@@ -413,7 +413,7 @@ class Helper
{
$keys = array_keys(CustomField::$PredefinedFormats);
$stuff = array_combine($keys, $keys);
return $stuff+["" => trans('admin/custom_fields/general.custom_format')];
return $stuff;
}
/**
@@ -320,4 +320,17 @@ class UsersController extends Controller
return response()->json(['message' => 'No ID provided'], 500);
}
/**
* Get info on the current user.
*
* @author [Juan Font] [<juanfontalonso@gmail.com>]
* @since [v4.4.2]
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function getCurrentUserInfo(Request $request)
{
return response()->json($request->user());
}
}
@@ -400,6 +400,10 @@ class ReportsController extends Controller
$header[] = 'Employee No.';
}
if ($request->has('manager')) {
$header[] = trans('admin/users/table.manager');
}
if ($request->has('department')) {
$header[] = trans('general.department');
}
@@ -613,6 +617,14 @@ class ReportsController extends Controller
}
}
if ($request->has('manager')) {
if ($asset->checkedOutToUser()) {
$row[] = (($asset->assignedto) && ($asset->assignedto->manager)) ? $asset->assignedto->manager->present()->fullName : '';
} else {
$row[] = ''; // Empty string if unassigned
}
}
if ($request->has('department')) {
if ($asset->checkedOutToUser()) {
+7 -4
View File
@@ -334,6 +334,7 @@ class SettingsController extends Controller
$setting->full_multiple_companies_support = $request->input('full_multiple_companies_support', '0');
$setting->load_remote = $request->input('load_remote', '0');
$setting->unique_serial = $request->input('unique_serial', '0');
$setting->show_images_in_email = $request->input('show_images_in_email', '0');
$setting->show_archived_in_list = $request->input('show_archived_in_list', '0');
$setting->dashboard_message = $request->input('dashboard_message');
@@ -396,6 +397,7 @@ class SettingsController extends Controller
$setting->brand = $request->input('brand', '1');
$setting->header_color = $request->input('header_color');
$setting->support_footer = $request->input('support_footer');
$setting->version_footer = $request->input('version_footer');
$setting->footer_text = $request->input('footer_text');
$setting->skin = $request->input('skin');
$setting->show_url_in_emails = $request->input('show_url_in_emails', '0');
@@ -478,6 +480,11 @@ class SettingsController extends Controller
$setting->two_factor_enabled = null;
} else {
$setting->two_factor_enabled = $request->input('two_factor_enabled');
# remote user login
$setting->login_remote_user_enabled = (int)$request->input('login_remote_user_enabled');
$setting->login_common_disabled= (int)$request->input('login_common_disabled');
$setting->login_remote_user_custom_logout_url = $request->input('login_remote_user_custom_logout_url');
}
}
@@ -486,10 +493,6 @@ class SettingsController extends Controller
$setting->pwd_secure_min = (int) $request->input('pwd_secure_min');
$setting->pwd_secure_complexity = '';
# remote user login
$setting->login_remote_user_enabled = (int)$request->input('login_remote_user_enabled');
$setting->login_common_disabled= (int)$request->input('login_common_disabled');
$setting->login_remote_user_custom_logout_url = $request->input('login_remote_user_custom_logout_url');
if ($request->has('pwd_secure_complexity')) {
$setting->pwd_secure_complexity = implode('|', $request->input('pwd_secure_complexity'));
+1 -1
View File
@@ -22,8 +22,8 @@ class Kernel extends HttpKernel
\App\Http\Middleware\ReferrerPolicyHeader::class,
\App\Http\Middleware\ContentSecurityPolicyHeader::class,
\App\Http\Middleware\NosniffGuard::class,
\App\Http\Middleware\CheckForSetup::class,
\Fideloper\Proxy\TrustProxies::class,
\App\Http\Middleware\CheckForSetup::class,
\App\Http\Middleware\CheckForDebug::class,
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace App\Http\Traits;
trait UniqueSerialTrait
{
/**
* Prepare a unique_ids rule, adding a model identifier if required.
*
* @param array $parameters
* @param string $field
* @return string
*/
protected function prepareUniqueSerialRule($parameters, $field)
{
if ($settings = \App\Models\Setting::first()) {
if ($settings->unique_serial=='1') {
return 'unique_undeleted:'.$this->table.','. $this->getKey();
}
}
}
}
@@ -41,7 +41,7 @@ class CategoriesTransformer
$permissions_array['available_actions'] = [
'update' => Gate::allows('update', Category::class) ? true : false,
'delete' => (Gate::allows('delete', Category::class) && ($category->assets_count == 0) && ($category->accessories_count == 0) && ($category->consumables_count == 0) && ($category->components_count == 0)) ? true : false,
'delete' => (Gate::allows('delete', Category::class) && ($category->assets_count == 0) && ($category->accessories_count == 0) && ($category->consumables_count == 0) && ($category->components_count == 0) && ($category->licenses_count == 0)) ? true : false,
];
$array += $permissions_array;
@@ -9,13 +9,13 @@ use App\Helpers\Helper;
class StatuslabelsTransformer
{
public function transformStatuslabels (Collection $statuslabels)
public function transformStatuslabels (Collection $statuslabels, $total)
{
$array = array();
foreach ($statuslabels as $statuslabel) {
$array[] = self::transformStatuslabel($statuslabel);
}
return (new DatatablesTransformer)->transformDatatables($array);
return (new DatatablesTransformer)->transformDatatables($array, $total);
}
public function transformStatuslabel (Statuslabel $statuslabel)
+5 -5
View File
@@ -81,8 +81,8 @@ class AssetImporter extends ItemImporter
// We need to save the user if it exists so that we can checkout to user later.
// Sanitizing the item will remove it.
if(array_key_exists('user', $this->item)) {
$user = $this->item['user'];
if(array_key_exists('checkout_target', $this->item)) {
$target = $this->item['checkout_target'];
}
$item = $this->sanitizeItemForStoring($asset, $editingAsset);
// The location id fetched by the csv reader is actually the rtd_location_id.
@@ -112,9 +112,9 @@ class AssetImporter extends ItemImporter
$asset->logCreate('Imported using csv importer');
$this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
// If we have a user to checkout to, lets do so.
if(isset($user)) {
$asset->fresh()->checkOut($user);
// If we have a target to checkout to, lets do so.
if(isset($target)) {
$asset->fresh()->checkOut($target);
}
return;
}
+6 -3
View File
@@ -14,17 +14,18 @@ class ConsumableImporter extends ItemImporter
protected function handle($row)
{
parent::handle($row); // TODO: Change the autogenerated stub
$this->createConsumableIfNotExists();
parent::handle($row);
$this->createConsumableIfNotExists($row);
}
/**
* Create a consumable if a duplicate does not exist
*
* @author Daniel Melzter
* @param array $row CSV Row Being parsed.
* @since 3.0
*/
public function createConsumableIfNotExists()
public function createConsumableIfNotExists($row)
{
$consumable = Consumable::where('name', $this->item['name'])->first();
if ($consumable) {
@@ -39,6 +40,8 @@ class ConsumableImporter extends ItemImporter
}
$this->log("No matching consumable, creating one");
$consumable = new Consumable();
$this->item['model_number'] = $this->findCsvMatch($row, "model_number");;
$this->item['item_no'] = $this->findCsvMatch($row, "item_number");
$consumable->fill($this->sanitizeItemForStoring($consumable));
//FIXME: this disables model validation. Need to find a way to avoid double-logs without breaking everything.
$consumable->unsetEventDispatcher();
+11 -6
View File
@@ -30,8 +30,11 @@ abstract class Importer
private $defaultFieldMap = [
'asset_tag' => 'asset tag',
'category' => 'category',
'checkout_class' => 'checkout type', // Supports Location or User for assets. Using checkout_class instead of checkout_type because type exists on asset already.
'checkout_location' => 'checkout location',
'company' => 'company',
'item_name' => 'item name',
'item_number' => "item number",
'image' => 'image',
'expiration_date' => 'expiration date',
'location' => 'location',
@@ -89,11 +92,12 @@ abstract class Importer
public function __construct($file)
{
$this->fieldMap = $this->defaultFieldMap;
// By default the importer passes a url to the file.
// However, for testing we also support passing a string directly
if (! ini_get("auto_detect_line_endings")) {
ini_set("auto_detect_line_endings", '1');
}
// By default the importer passes a url to the file.
// However, for testing we also support passing a string directly
if (is_file($file)) {
$this->csv = Reader::createFromPath($file);
} else {
@@ -179,9 +183,8 @@ abstract class Importer
*/
public function lookupCustomKey($key)
{
// dd($this->fieldMap);
if (array_key_exists($key, $this->fieldMap)) {
$this->log("Found a match in our custom map: {$key} is " . $this->fieldMap[$key]);
// $this->log("Found a match in our custom map: {$key} is " . $this->fieldMap[$key]);
return $this->fieldMap[$key];
}
// Otherwise no custom key, return original.
@@ -189,6 +192,8 @@ abstract class Importer
}
/**
* Used to lowercase header values to ensure we're comparing values properly.
*
* @param $results
* @return array
*/
@@ -249,11 +254,11 @@ abstract class Importer
$last_name = '';
if(empty($user_name) && empty($user_email) && empty($user_username)) {
$this->log('No user data provided - skipping user creation, just adding asset');
//$user_username = '';
return false;
}
// A username was given.
if( !empty($user_username)) {
// A username was given.
$user = User::where('username', $user_username)->first();
if($user) {
return $user;
+26 -1
View File
@@ -69,11 +69,36 @@ class ItemImporter extends Importer
$this->item['serial'] = $this->findCsvMatch($row, "serial");
// NO need to call this method if we're running the user import.
// TODO: Merge these methods.
$this->item['checkout_class'] = $this->findCsvMatch($row, "checkout_class");
if(get_class($this) !== UserImporter::class) {
$this->item["user"] = $this->createOrFetchUser($row);
// $this->item["user"] = $this->createOrFetchUser($row);
$this->item["checkout_target"] = $this->determineCheckout($row);
}
}
/**
* Parse row to determine what (if anything) we should checkout to.
* @param array $row CSV Row being parsed
* @return SnipeModel Model to be checked out to
*/
protected function determineCheckout($row)
{
// We only supporty checkout-to-location for asset, so short circuit otherw.
if(get_class($this) != AssetImporter::class) {
return $this->createOrFetchUser($row);
}
if ($this->item['checkout_class'] === 'location') {
// dd($this->findCsvMatch($row, 'checkout_location'));
return Location::findOrFail($this->createOrFetchLocation($this->findCsvMatch($row, 'checkout_location')));
// dd('here');
}
return $this->createOrFetchUser($row);
}
/**
* Cleanup the $item array before storing.
* We need to remove any values that are not part of the fillable fields.
+3 -3
View File
@@ -71,11 +71,11 @@ class LicenseImporter extends ItemImporter
// Lets try to checkout seats if the fields exist and we have seats.
if ($license->seats > 0) {
$user = $this->item['user'];
$checkout_target = $this->item['checkout_target'];
$asset = Asset::where('asset_tag', $asset_tag)->first();
$targetLicense = $license->licenseSeats()->first();
if ($user) {
$targetLicense->assigned_to = $user->id;
if ($checkout_target) {
$targetLicense->assigned_to = $checkout_target->id;
if ($asset) {
$targetLicense->asset_id = $asset->id;
}
+4 -2
View File
@@ -37,7 +37,6 @@ class UserImporter extends ItemImporter
$this->item['phone'] = $this->findCsvMatch($row, 'phone_number');
$this->item['jobtitle'] = $this->findCsvMatch($row, 'jobtitle');
$this->item['employee_num'] = $this->findCsvMatch($row, 'employee_num');
$this->item['password'] = $this->tempPassword;
$user = User::where('username', $this->item['username'])->first();
if ($user) {
if (!$this->updating) {
@@ -45,11 +44,14 @@ class UserImporter extends ItemImporter
return;
}
$this->log('Updating User');
// $user = $this->users[$userId];
$user->update($this->sanitizeItemForUpdating($user));
$user->save();
return;
}
// This needs to be applied after the update logic, otherwise we'll overwrite user passwords
// Issue #5408
$this->item['password'] = $this->tempPassword;
$this->log("No matching user, creating one");
$user = new User();
$user->fill($this->sanitizeItemForStoring($user));
+5 -9
View File
@@ -2,6 +2,7 @@
namespace App\Models;
use App\Exceptions\CheckoutNotAllowed;
use App\Http\Traits\UniqueSerialTrait;
use App\Http\Traits\UniqueUndeletedTrait;
use App\Presenters\Presentable;
use AssetPresenter;
@@ -23,7 +24,7 @@ use App\Notifications\CheckoutAssetNotification;
class Asset extends Depreciable
{
protected $presenter = 'App\Presenters\AssetPresenter';
use Loggable, Requestable, Presentable, SoftDeletes, ValidatingTrait, UniqueUndeletedTrait;
use Loggable, Requestable, Presentable, SoftDeletes, ValidatingTrait, UniqueUndeletedTrait, UniqueSerialTrait;
const LOCATION = 'location';
const ASSET = 'asset';
@@ -72,12 +73,13 @@ class Asset extends Depreciable
'status_id' => 'required|integer|exists:status_labels,id',
'company_id' => 'integer|nullable',
'warranty_months' => 'numeric|nullable',
'physical' => 'numeric|max:1|nullable',
'physical' => 'numeric|max:1|nullable',
'checkout_date' => 'date|max:10|min:10|nullable',
'checkin_date' => 'date|max:10|min:10|nullable',
'supplier_id' => 'numeric|nullable',
'asset_tag' => 'required|min:1|max:255|unique_undeleted',
'status' => 'integer',
'serial' => 'unique_serial|nullable',
'purchase_cost' => 'numeric|nullable',
'next_audit_date' => 'date|nullable',
'last_audit_date' => 'date|nullable',
@@ -189,13 +191,7 @@ class Asset extends Depreciable
$this->location_id = $target->location->id;
}
}
if ($this->requireAcceptance()) {
if(get_class($target) != User::class) {
throw new CheckoutNotAllowed;
}
$this->accepted="pending";
}
if ($this->save()) {
$this->logCheckout($note, $target);
+1 -1
View File
@@ -153,7 +153,7 @@ class AssetModel extends SnipeModel
* @param $query
*
* @return $query
* @author Daniel Meltzer <parallelgrapefruit@gmail.com
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
* @version v3.5
*/
public function scopeRequestableModels($query)
+1
View File
@@ -16,6 +16,7 @@ class CustomField extends Model
public $guarded=["id"];
public static $PredefinedFormats=[
"ANY" => "",
"CUSTOM REGEX" => "",
"ALPHA" => "alpha",
"ALPHA-DASH" => "alpha_dash",
"NUMERIC" => "numeric",
+5 -5
View File
@@ -21,7 +21,7 @@ trait Loggable
{
/**
* @author Daniel Meltzer <parallelgrapefruit@gmail.com
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
* @since [v3.4]
* @return \App\Models\Actionlog
*/
@@ -32,7 +32,7 @@ trait Loggable
}
/**
* @author Daniel Meltzer <parallelgrapefruit@gmail.com
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
* @since [v3.4]
* @return \App\Models\Actionlog
*/
@@ -106,7 +106,7 @@ trait Loggable
return $log;
}
/**
* @author Daniel Meltzer <parallelgrapefruit@gmail.com
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
* @since [v3.4]
* @return \App\Models\Actionlog
*/
@@ -204,7 +204,7 @@ trait Loggable
/**
* @author Daniel Meltzer <parallelgrapefruit@gmail.com
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
* @since [v3.5]
* @return \App\Models\Actionlog
*/
@@ -231,7 +231,7 @@ trait Loggable
}
/**
* @author Daniel Meltzer <parallelgrapefruit@gmail.com
* @author Daniel Meltzer <dmeltzer.devel@gmail.com>
* @since [v3.4]
* @return \App\Models\Actionlog
*/
@@ -61,7 +61,7 @@ class ExpectedCheckinNotification extends Notification
return (new MailMessage)
->error()
->subject('Reminder: '.$this->params->present()->name().' checkin deadline approaching')
->line('Hi, '.$this->params->assignedto->first_name)
->line('Hi, '.$this->params->assignedto->first_name.' '.$this->params->assignedto->last_name)
->greeting('An asset checked out to you is due to be checked back in on '.$formatted_due.'.')
->line('Asset: '.$this->params->present()->name())
->line('Serial: '.$this->params->serial)
-7
View File
@@ -1,11 +1,4 @@
<?php
/**
* Created by PhpStorm.
* User: parallelgrapefruit
* Date: 12/23/16
* Time: 11:51 AM
*/
namespace App\Presenters;
use App\Helpers\Helper;
@@ -1,10 +1,4 @@
<?php
/**
* Created by PhpStorm.
* User: parallelgrapefruit
* Date: 12/23/16
* Time: 12:15 PM
*/
namespace App\Presenters;
-6
View File
@@ -1,10 +1,4 @@
<?php
/**
* Created by PhpStorm.
* User: parallelgrapefruit
* Date: 12/23/16
* Time: 12:15 PM
*/
namespace App\Presenters;
+1
View File
@@ -73,6 +73,7 @@
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true,
"process-timeout":3000,
"platform": {
"php": "5.6.4"
}
+1 -1
View File
@@ -78,7 +78,7 @@ return [
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => env('DB_PREFIX', null),
'strict' => false,
'engine' => null,
'engine' => 'InnoDB',
'unix_socket' => env('DB_SOCKET',''),
'dump_command_path' => env('DB_DUMP_PATH', '/usr/local/bin'), // only the path, so without 'mysqldump'
'dump_command_timeout' => 60 * 5, // 5 minute timeout
+5 -5
View File
@@ -1,10 +1,10 @@
<?php
return array (
'app_version' => 'v4.4.1',
'full_app_version' => 'v4.4.1 - build 3636-gece916e12',
'build_version' => '3636',
'app_version' => 'v4.5.0',
'full_app_version' => 'v4.5.0 - build 3701-gbf1e742df',
'build_version' => '3701',
'prerelease_version' => '',
'hash_version' => 'gece916e12',
'full_hash' => 'v4.4.1-54-gece916e12',
'hash_version' => 'gbf1e742df',
'full_hash' => 'v4.4.2-63-gbf1e742df',
'branch' => 'master',
);
@@ -17,7 +17,7 @@ class CreateCustomFieldDefaultValuesTable extends Migration
$table->increments('id');
$table->integer('asset_model_id');
$table->integer('custom_field_id');
$table->text('default_value')->nullable();
$table->text('default_value')->nullable()->default(null);
});
}
@@ -0,0 +1,29 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddVersionFooter extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->char('version_footer', 5)->nullable()->default('on');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('version_footer');
});
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddUniqueSerialOptionToSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->boolean('unique_serial')->default('0');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('unique_serial');
});
}
}
+7 -1
View File
@@ -17,12 +17,18 @@ else
fi
# create data directories
for dir in 'data/private_uploads' 'data/uploads' 'data/uploads/avatars' 'data/uploads/barcodes' 'data/uploads/categories' 'data/uploads/companies' 'data/uploads/departments' 'data/uploads/locations' 'data/uploads/manufacturers' 'data/uploads/models' 'data/uploads/suppliers' 'dumps'; do
for dir in 'data/private_uploads' 'data/uploads' 'data/uploads/avatars' 'data/uploads/barcodes' 'data/uploads/categories' 'data/uploads/companies' 'data/uploads/departments' 'data/uploads/locations' 'data/uploads/manufacturers' 'data/uploads/models' 'data/uploads/suppliers' 'dumps' 'keys'; do
mkdir -p "/var/lib/snipeit/$dir"
done
chown -R docker:root /var/lib/snipeit/data/*
chown -R docker:root /var/lib/snipeit/dumps
chown -R docker:root /var/lib/snipeit/keys
# If the Oauth DB files are not present copy the vendor files over to the db migrations
if [ ! -f "/var/www/html/database/migrations/*create_oauth*" ]; then
cp -ax /var/www/html/vendor/laravel/passport/database/migrations/* /var/www/html/database/migrations/
fi
. /etc/apache2/envvars
exec apache2 -DNO_DETACH < /dev/null
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+16 -16
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+16 -16
View File
File diff suppressed because one or more lines are too long
+7 -7
View File
@@ -1,14 +1,14 @@
{
"/js/build/vue.js": "/js/build/vue.js?id=992bcb968a7f2da998b5",
"/js/build/vue.js": "/js/build/vue.js?id=5eab4676dde73dbab3ca",
"/css/AdminLTE.css": "/css/AdminLTE.css?id=5e72463a66acbcc740d5",
"/css/app.css": "/css/app.css?id=407edb63cc6b6dc62405",
"/css/overrides.css": "/css/overrides.css?id=d85394a0b4f58e81bb78",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=e0eb0edc0b761965973f",
"/css/overrides.css": "/css/overrides.css?id=2d81c3704393bac77011",
"/js/build/vue.js.map": "/js/build/vue.js.map?id=525260f84ea83d4b55cd",
"/css/AdminLTE.css.map": "/css/AdminLTE.css.map?id=99f5a5a03c4155cf69f6",
"/css/app.css.map": "/css/app.css.map?id=bdbe05e6ecd70ccfac72",
"/css/overrides.css.map": "/css/overrides.css.map?id=898c91d4a425b01b589b",
"/css/dist/all.css": "/css/dist/all.css?id=0e3642f1b6a8a436d558",
"/js/dist/all.js": "/js/dist/all.js?id=39b95992f478d68c44a8",
"/css/build/all.css": "/css/build/all.css?id=0e3642f1b6a8a436d558",
"/js/build/all.js": "/js/build/all.js?id=39b95992f478d68c44a8"
"/css/dist/all.css": "/css/dist/all.css?id=98db4e9b7650453c8b00",
"/js/dist/all.js": "/js/dist/all.js?id=85c7dab4c75f53c45b91",
"/css/build/all.css": "/css/build/all.css?id=98db4e9b7650453c8b00",
"/js/build/all.js": "/js/build/all.js?id=85c7dab4c75f53c45b91"
}
@@ -44,8 +44,10 @@
</div>
<div class="col-sm-12 col-lg-6">
<input v-if="field.type == 'text'" class="form-control m-b-xs" type="text" :value="getValue(field)" :id="'default-value' + field.id" :name="'default_values[' + field.id + ']'">
<textarea v-if="field.type == 'textarea'" class="form-control" :value="getValue(field)" :id="'default-value' + field.id" :name="'default_values[' + field.id + ']'"></textarea><br>
<select v-if="field.type == 'listbox'" class="form-control m-b-xs" :name="'default_values[' + field.id + ']'">
<option value="0"></option>
<option value=""></option>
<option v-for="field_value in field.field_values_array" :value="field_value" :selected="getValue(field) == field_value">{{ field_value }}</option>
</select>
</div>
@@ -117,12 +117,18 @@ tr {
assets: [
{id: 'asset_tag', text: 'Asset Tag' },
{id: 'asset_model', text: 'Model Name' },
{id: 'checkout_class', text: 'Checkout Type' },
{id: 'checkout_location', text: 'Checkout Location' },
{id: 'image', text: 'Image Filename' },
{id: 'model_number', text: 'Model Number' },
{id: 'full_name', text: 'Full Name' },
{id: 'status', text: 'Status' },
{id: 'warranty_months', text: 'Warranty Months' },
],
consumables: [
{id: 'item_no', text: "Item Number"},
{id: 'model_number', text: "Model Number"},
],
licenses: [
{id: 'expiration_date', text: 'Expiration Date' },
{id: 'license_email', text: 'Licensed To Email' },
@@ -165,6 +171,11 @@ tr {
.concat(this.columnOptions.assets)
.concat(this.columnOptions.customFields)
.sort(sorter);
case 'consumable':
return this.columnOptions.general
.concat(this.columnOptions.consumables)
.sort(sorter);
case 'license':
return this.columnOptions.general.concat(this.columnOptions.licenses).sort(sorter);
case 'user':
@@ -184,7 +195,6 @@ tr {
},
watch: {
columns() {
console.log("CHANGED");
this.populateSelect2ActiveItems();
}
},
@@ -234,7 +244,6 @@ tr {
for(var j=0; j < this.columns.length; j++) {
let column = this.columns[j];
let lower = this.file.header_row.map((value) => value.toLowerCase());
console.dir(lower);
let index = lower.indexOf(column.text.toLowerCase())
if(index != -1) {
this.$set(this.columnMappings, this.file.header_row[index], column.id)
@@ -248,7 +257,6 @@ tr {
}
},
updateModel(header, value) {
console.log(header, value);
this.columnMappings[header] = value;
}
},
+6
View File
@@ -341,3 +341,9 @@ img.navbar-brand-img, .navbar-brand>img {
font-size: 20px;
color: #889195;
}
#login-logo {
padding-top: 20px;
padding-bottom: 10px;
max-width: 200px
}
+6 -2
View File
@@ -86,7 +86,7 @@ return array(
'login_common_disabled_text' => 'Disable other authentication mechanisms',
'login_common_disabled_help' => 'This option disables other authentication mechanisms. Just enable this option if you are sure that your REMOTE_USER login is already working',
'login_remote_user_custom_logout_url_text' => 'Custom logout URL',
'login_remote_user_custom_logout_url_help' => 'If filled users will get redirected to this URL after the Session of SnipeIT is closed (Logout). This is usefull to close the user sessions of your Authenticationprovider correctly.',
'login_remote_user_custom_logout_url_help' => 'If filled users will get redirected to this URL after the Session of SnipeIT is closed (Logout). This is useful to close the user sessions of your Authentication provider correctly.',
'logo' => 'Logo',
'full_multiple_companies_support_help_text' => 'Restricting users (including admins) assigned to companies to their company\'s assets.',
'full_multiple_companies_support_text' => 'Full Multiple Companies Support',
@@ -121,7 +121,9 @@ return array(
'slack_test_help' => 'Test whether your Slack integration is configured correctly. YOU MUST SAVE YOUR UPDATED SLACK SETTINGS FIRST.',
'snipe_version' => 'Snipe-IT version',
'support_footer' => 'Support Footer Links ',
'support_footer_help' => 'Specify who sees the links to the Snipe-IT Support info and Users Manual',
'support_footer_help' => 'Specify who sees the links to the Snipe-IT Support info and Users Manual.',
'version_footer' => 'Version in Footer ',
'version_footer_help' => 'Specify who sees the Snipe-IT version and build number.',
'system' => 'System Information',
'update' => 'Update Settings',
'value' => 'Value',
@@ -177,5 +179,7 @@ return array(
'bottom' => 'bottom',
'vertical' => 'vertical',
'horizontal' => 'horizontal',
'unique_serial' => 'Unique serial numbers',
'unique_serial_help_text' => 'Checking this box will enforce a uniqeness constraint on asset serials',
'zerofill_count' => 'Length of asset tags, including zerofill',
);
+4 -1
View File
@@ -366,12 +366,14 @@ Form::macro('date_display_format', function ($name = "date_display_format", $sel
'd M, Y',
'm/d/Y',
'n/d/y',
'd/m/Y',
'm/j/Y',
'd.m.Y',
];
foreach ($formats as $format) {
$date_display_formats[$format] = Carbon::now()->format($format);
$date_display_formats[$format] = Carbon::parse(date('Y').'-'.date('m').'-25')->format($format);
}
$select = '<select name="'.$name.'" class="'.$class.'" style="min-width:250px">';
foreach ($date_display_formats as $format => $date_display_format) {
@@ -502,6 +504,7 @@ Form::macro('customfield_elements', function ($name = "customfield_elements", $s
$formats = array(
'text' => 'Text Box',
'listbox' => 'List Box',
'textarea' => 'Textarea (multi-line) ',
// 'checkbox' => 'Checkbox',
// 'radio' => 'Radio Buttons',
);
@@ -79,6 +79,14 @@
</div>
</div>
@endif
<!-- Note -->
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
<label for="note" class="col-md-3 control-label">{{ trans('admin/hardware/form.notes') }}</label>
<div class="col-md-7">
<textarea class="col-md-6 form-control" id="note" name="note">{{ Input::old('note', $accessory->note) }}</textarea>
{!! $errors->first('note', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
</div>
<div class="box-footer">
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
@@ -126,7 +126,7 @@ View Assets for {{ $user->present()->fullName() }}
<td>{{ $license->name }}</td>
<td>
@can('viewKeys', $license)
{{ mb_strimwidth($license->serial, 0, 50, "...") }}
{{ $license->serial }}
@else
------------
@endcan
@@ -205,7 +205,7 @@ View Assets for {{ $user->present()->fullName() }}
@endif
<div class="box-body">
<!-- checked out licenses table -->
<!-- checked out Accessories table -->
<div class="table-responsive">
<table
@@ -66,7 +66,14 @@
</div>
</div>
@endif
<!-- Note -->
<div class="form-group {{ $errors->has('note') ? 'error' : '' }}">
<label for="note" class="col-md-3 control-label">{{ trans('admin/hardware/form.notes') }}</label>
<div class="col-md-7">
<textarea class="col-md-6 form-control" id="note" name="note">{{ Input::old('note', $consumable->note) }}</textarea>
{!! $errors->first('note', '<span class="alert-msg"><i class="fa fa-times"></i> :message</span>') !!}
</div>
</div>
</div> <!-- .box-body -->
<div class="box-footer">
<a class="btn btn-link" href="{{ URL::previous() }}">{{ trans('button.cancel') }}</a>
@@ -105,7 +105,7 @@
<!-- Show in Email -->
<div class="form-group {{ $errors->has('show_in_email') ? ' has-error' : '' }}" id="show_in_email">
<div class="col-md-8 col-md-offset-4">
<label for="field_encrypted">
<label for="show_in_email">
<input type="checkbox" name="show_in_email" value="1" class="minimal"{{ (Input::old('show_in_email') || $field->show_in_email) ? ' checked="checked"' : '' }}>
{{ trans('admin/custom_fields/general.show_in_email') }}
</label>
@@ -167,7 +167,7 @@
// Only display the custom format field if it's a custom format validation type
$(".format").change(function(){
$(this).find("option:selected").each(function(){
if (($(this).attr("value")=="") && $('.format').prop("selectedIndex") != 0) {
if ($('.format').prop("selectedIndex") == 1) {
$("#custom_regex").show();
} else{
$("#custom_regex").hide();
@@ -178,7 +178,7 @@
// Only display the field element if the type is not text
$(".field_element").change(function(){
$(this).find("option:selected").each(function(){
if($(this).attr("value")!="text"){
if (($(this).attr("value")!="text") && ($(this).attr("value")!="textarea")){
$("#field_values_text").show();
} else{
$("#field_values_text").hide();
+1 -11
View File
@@ -47,23 +47,13 @@
@include ('partials.forms.checkout-selector', ['user_select' => 'true','asset_select' => 'true', 'location_select' => 'true'])
@include ('partials.forms.edit.user-select', ['translated_name' => trans('general.user'), 'fieldname' => 'assigned_user', 'required'=>'true'])
@if ($asset->requireAcceptance())
<div class="form-group">
<div class="col-md-8 col-md-offset-3">
<p class="help-block">
Because this asset category requires acceptance,
it cannot be checked out to another asset or to a location.
</p>
</div>
</div>
@else
<!-- We have to pass unselect here so that we don't default to the asset that's being checked out. We want that asset to be pre-selected everywhere else. -->
@include ('partials.forms.edit.asset-select', ['translated_name' => trans('general.asset'), 'fieldname' => 'assigned_asset', 'unselect' => 'true', 'style' => 'display:none;', 'required'=>'true'])
@include ('partials.forms.edit.location-select', ['translated_name' => trans('general.location'), 'fieldname' => 'assigned_location', 'style' => 'display:none;', 'required'=>'true'])
@endif
<!-- Checkout/Checkin Date -->
<div class="form-group {{ $errors->has('checkout_at') ? 'error' : '' }}">
+26 -15
View File
@@ -281,7 +281,7 @@
@if (($field->format=='URL') && ($asset->{$field->db_column_name()}!=''))
<a href="{{ $asset->{$field->db_column_name()} }}" target="_new">{{ $asset->{$field->db_column_name()} }}</a>
@else
{{ $asset->{$field->db_column_name()} }}
{!! nl2br(e($asset->{$field->db_column_name()})) !!}
@endif
@endif
</td>
@@ -605,6 +605,8 @@
<tbody>
<?php $totalCost = 0; ?>
@foreach ($asset->components as $component)
@if (is_null($component->deleted_at))
<tr>
<td>
@@ -612,6 +614,7 @@
</td>
<td>{{ $component->pivot->assigned_qty }}</td>
<td>{{ $component->purchase_cost }}</td>
<?php $totalCost = $totalCost + $component->purchase_cost ;?>
</tr>
@endif
@@ -620,7 +623,9 @@
<tfoot>
<tr>
<td colspan="7" class="text-right">{{ $use_currency.$totalCost }}</td>
<td colspan="2">
</td>
<td>{{ $totalCost }}</td>
</tr>
</tfoot>
</table>
@@ -811,12 +816,13 @@
data-cookie-id-table="assetFileHistory">
<thead>
<tr>
<th data-visible="true"></th>
<th class="col-md-2" data-searchable="true" data-visible="true">{{ trans('general.notes') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true">{{ trans('general.image') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true">{{ trans('general.file_name') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true">{{ trans('general.download') }}</th>
<th class="col-md-1" data-searchable="true" data-visible="true">{{ trans('general.actions') }}</th>
<th data-visible="true" data-field="icon"></th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="notes">{{ trans('general.notes') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="image">{{ trans('general.image') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="filename">{{ trans('general.file_name') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="download">{{ trans('general.download') }}</th>
<th class="col-md-2" data-searchable="true" data-visible="true" data-field="created_at">{{ trans('general.created_at') }}</th>
<th class="col-md-1" data-searchable="true" data-visible="true" data-field="actions">{{ trans('table.actions') }}</th>
</tr>
</thead>
<tbody>
@@ -831,7 +837,9 @@
</td>
<td>
@if ( \App\Helpers\Helper::checkUploadIsImage($file->get_src('assets')))
<a href="{{ route('show/assetfile', ['assetId' => $asset->id, 'fileId' =>$file->id]) }}" data-toggle="lightbox" data-type="image"><img src="{{ route('show/assetfile', ['assetId' => $asset->id, 'fileId' =>$file->id]) }}" class="img-thumbnail" style="max-width: 50px;"></a>
<a href="{{ route('show/assetfile', ['assetId' => $asset->id, 'fileId' =>$file->id]) }}" data-toggle="lightbox" data-type="image" data-title="{{ $file->filename }}" data-footer="{{ \App\Helpers\Helper::getFormattedDateObject($asset->last_checkout, 'datetime', false) }}">
<img src="{{ route('show/assetfile', ['assetId' => $asset->id, 'fileId' =>$file->id]) }}" style="max-width: 50px;">
</a>
@endif
</td>
<td>
@@ -842,6 +850,14 @@
<a href="{{ route('show/assetfile', [$asset->id, $file->id]) }}" class="btn btn-default"><i class="fa fa-download"></i></a>
@endif
</td>
<td>
@if ($file->created_at)
{{ \App\Helpers\Helper::getFormattedDateObject($asset->last_checkout, 'datetime', false) }}
@endif
</td>
<td>
@can('update', \App\Models\Asset::class)
<a class="btn delete-asset btn-sm btn-danger btn-sm" href="{{ route('delete/assetfile', [$asset->id, $file->id]) }}" data-tooltip="true" data-title="Delete" data-content="{{ trans('delete_confirm', ['item' => $file->filename]) }}"><i class="fa fa-trash icon-white"></i></a>
@@ -870,11 +886,6 @@
@section('moar_scripts')
@include ('partials.bootstrap-table')
<script nonce="{{ csrf_token() }}">
$(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) {
event.preventDefault();
$(this).ekkoLightbox();
});
</script>
@stop
+1 -1
View File
@@ -46,7 +46,7 @@
@if (($snipeSettings) && ($snipeSettings->logo!=''))
<center>
<img style="padding-top: 20px; padding-bottom: 10px; max-width: 150px" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
<img id="login-logo" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
</center>
@endif
<!-- Content -->
+7 -3
View File
@@ -224,7 +224,7 @@
@can('create', \App\Models\Component::class)
<li {!! (Request::is('components/create') ? 'class="active"' : '') !!}>
<a href="{{ route('components.create') }}">
<i class="fa fa-hdd-o"></i>
<i class="fa fa-hdd-o fa-fw"></i>
{{ trans('general.component') }}
</a>
</li>
@@ -310,7 +310,7 @@
<li {!! (Request::is('account/requested') ? ' class="active"' : '') !!}>
<a href="{{ route('account.requested') }}">
<i class="fa fa-check fa-disk"></i>
<i class="fa fa-check fa-disk fa-fw"></i>
Requested Assets
</a></li>
@@ -741,7 +741,11 @@
<footer class="main-footer hidden-print">
<div class="pull-right hidden-xs">
<b>Version</b> {{ config('version.app_version') }} - build {{ config('version.build_version') }} ({{ config('version.branch') }})
@if ($snipeSettings->version_footer!='off')
@if (($snipeSettings->version_footer=='on') || (($snipeSettings->version_footer=='admin') && (Auth::user()->isSuperUser()=='1')))
<b>Version</b> {{ config('version.app_version') }} - build {{ config('version.build_version') }} ({{ config('version.branch') }})
@endif
@endif
@if ($snipeSettings->support_footer!='off')
@if (($snipeSettings->support_footer=='on') || (($snipeSettings->support_footer=='admin') && (Auth::user()->isSuperUser()=='1')))
@@ -4,12 +4,17 @@
<label for="{{ $field->db_column_name() }}" class="col-md-3 control-label">{{ $field->name }} </label>
<div class="col-md-7 col-sm-12{{ ($field->pivot->required=='1') ? ' required' : '' }}">
@if ($field->element!='text')
<!-- Listbox -->
@if ($field->element=='listbox')
{{ Form::select($field->db_column_name(), $field->formatFieldValuesAsArray(),
Input::old($field->db_column_name(),(isset($item) ? $item->{$field->db_column_name()} : $field->defaultValue($model->id))), ['class'=>'format select2 form-control']) }}
@elseif ($field->element=='textarea')
<textarea class="col-md-6 form-control" id="{{ $field->db_column_name() }}" name="{{ $field->db_column_name() }}">{{ Input::old($field->db_column_name(),(isset($item) ? $item->{$field->db_column_name()} : $field->defaultValue($model->id))) }}</textarea>
@elseif ($field->element=='checkbox')
<!-- Checkboxes -->
@foreach ($field->formatFieldValuesAsArray() as $key => $value)
+1 -2
View File
@@ -49,8 +49,7 @@
<fieldset-default-values
model-id="{{ $item->id ?: '' }}"
fieldset-id="{{ !empty($item->fieldset) ? $item->fieldset->id : Input::old('custom_fieldset') }}"
previous-input="{{ json_encode(Input::old('default_values')) }}"
>
previous-input="{{ json_encode(Input::old('default_values')) }}">
</fieldset-default-values>
</div>
@@ -155,7 +155,14 @@
return '<nobr><a href="{{ url('/') }}/' + destination + '/' + value.id + '" data-tooltip="true" title="'+ status_meta[value.status_meta] + '"> <i class="fa ' + icon_style + ' text-' + text_color + '"></i> ' + value.name + ' ' + text_help + ' </a> </nobr>';
} else if ((value) && (value.name)) {
return '<nobr><a href="{{ url('/') }}/' + destination + '/' + value.id + '"> ' + value.name + '</a></span>';
// Add some overrides for any funny urls we have
var dest = destination;
if (destination=='fieldsets') {
var dest = 'fields/fieldsets';
}
return '<nobr><a href="{{ url('/') }}/' + dest + '/' + value.id + '"> ' + value.name + '</a></span>';
}
};
}
@@ -166,10 +173,13 @@
var actions = '<nobr>';
// Add some overrides for any funny urls we have
var dest = destination;
if (destination=='groups') {
var dest = 'admin/groups';
}
if (destination=='maintenances') {
var dest = 'hardware/maintenances';
}
+8
View File
@@ -221,6 +221,13 @@
</label>
</div>
<div class="checkbox col-md-12">
<label>
{{ Form::checkbox('manager', '1', '1', ['class' => 'minimal']) }}
{{ trans('admin/users/table.manager') }}
</label>
</div>
<div class="checkbox col-md-12">
<label>
{{ Form::checkbox('department', '1', '1', ['class' => 'minimal']) }}
@@ -231,6 +238,7 @@
@if ($customfields->count() > 0)
<div class="checkbox col-md-12">
<h4>Custom Fields:</h4>
+23 -4
View File
@@ -73,7 +73,8 @@
{{ trans('button.select_file') }}
<input type="file" name="image" accept="image/gif,image/jpeg,image/png,image/svg" hidden>
</label>
<p class="help-block">{{ trans('general.image_filetypes_help') }}</p>
<p class="help-block" id="upload-file-status">{{ trans('general.image_filetypes_help', ['size' => \App\Helpers\Helper::file_upload_max_size_readable()]) }}</p>
{!! $errors->first('image', '<span class="alert-msg">:message</span>') !!}
{{ Form::checkbox('clear_logo', '1', Input::old('clear_logo'),array('class' => 'minimal')) }} Remove
@@ -88,7 +89,7 @@
{{ Form::label('brand', trans('admin/settings/general.brand')) }}
</div>
<div class="col-md-9">
{!! Form::select('brand', array('1'=>'Text','2'=>'Logo','3'=>'Logo + Text'), Input::old('brand', $setting->brand), array('class' => 'form-control', 'style'=>'width: 150px ;')) !!}
{!! Form::select('brand', array('1'=>'Text','2'=>'Logo','3'=>'Logo + Text'), Input::old('brand', $setting->brand), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
{!! $errors->first('brand', '<span class="alert-msg">:message</span>') !!}
</div>
</div>
@@ -158,9 +159,9 @@
</div>
<div class="col-md-9">
@if (config('app.lock_passwords')===true)
{!! Form::select('support_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), Input::old('support_footer', $setting->support_footer), ['class' => 'form-control disabled', 'style'=>'width: 150px ;', 'disabled' => 'disabled']) !!}
{!! Form::select('support_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), Input::old('support_footer', $setting->support_footer), ['class' => 'form-control select2 disabled', 'style'=>'width: 150px ;', 'disabled' => 'disabled']) !!}
@else
{!! Form::select('support_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), Input::old('support_footer', $setting->support_footer), array('class' => 'form-control', 'style'=>'width: 150px ;')) !!}
{!! Form::select('support_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), Input::old('support_footer', $setting->support_footer), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
@endif
<p class="help-block">{{ trans('admin/settings/general.support_footer_help') }}</p>
@@ -168,6 +169,24 @@
</div>
</div>
<!-- Version Footer -->
<div class="form-group {{ $errors->has('version_footer') ? 'error' : '' }}">
<div class="col-md-3">
{{ Form::label('version_footer', trans('admin/settings/general.version_footer')) }}
</div>
<div class="col-md-9">
@if (config('app.lock_passwords')===true)
{!! Form::select('version_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), Input::old('version_footer', $setting->version_footer), ['class' => 'form-control select2 disabled', 'style'=>'width: 150px ;', 'disabled' => 'disabled']) !!}
@else
{!! Form::select('version_footer', array('on'=>'Enabled','off'=>'Disabled','admin'=>'Superadmin Only'), Input::old('version_footer', $setting->version_footer), array('class' => 'form-control select2', 'style'=>'width: 150px ;')) !!}
@endif
<p class="help-block">{{ trans('admin/settings/general.version_footer_help') }}</p>
{!! $errors->first('version_footer', '<span class="alert-msg">:message</span>') !!}
</div>
</div>
<!-- Additional footer -->
<div class="form-group {{ $errors->has('footer_text') ? 'error' : '' }}">
<div class="col-md-3">
+16 -1
View File
@@ -137,8 +137,23 @@
</div>
</div>
<!-- unique serial -->
<div class="form-group">
<div class="col-md-3">
{{ Form::label('unique_serial', trans('admin/settings/general.unique_serial')) }}
</div>
<div class="col-md-9">
{{ Form::checkbox('unique_serial', '1', Input::old('unique_serial', $setting->unique_serial),array('class' => 'minimal')) }}
{{ trans('general.yes') }}
{!! $errors->first('unique_serial', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.unique_serial_help_text') }}
</p>
</div>
</div>
<!-- Per Page -->
<!-- Per Page -->
<div class="form-group {{ $errors->has('per_page') ? 'error' : '' }}">
<div class="col-md-3">
{{ Form::label('per_page', trans('admin/settings/general.per_page')) }}
+4 -5
View File
@@ -31,14 +31,13 @@
# $matches [1]; # Style information
# $matches [2]; # Body information
echo "<div class='phpinfodisplay'><style type='text/css'>\n",
join( "\n",
array_map(
create_function(
'$i',
'return ".phpinfodisplay " . preg_replace( "/,/", ",.phpinfodisplay ", $i );'
),
function ($i) {
return ".phpinfodisplay " . preg_replace( "/,/", ",.phpinfodisplay ", $i );
},
preg_split( '/\n/', $matches[1] )
)
),
+26 -20
View File
@@ -123,27 +123,33 @@
</div>
<div class="col-md-9">
<!-- Enable Remote User Login -->
{{ Form::checkbox('login_remote_user_enabled', '1', Input::old('login_remote_user_enabled', $setting->login_remote_user_enabled),array('class' => 'minimal')) }}
{{ Form::label('login_remote_user_enabled', trans('admin/settings/general.login_remote_user_enabled_text')) }}
{!! $errors->first('login_remote_user_enabled', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_remote_user_enabled_help') }}
</p>
<!-- Custom logout url to redirect to authentication provider -->
{{ Form::label('login_remote_user_custom_logout_url', trans('admin/settings/general.login_remote_user_custom_logout_url_text')) }}
{{ Form::text('login_remote_user_custom_logout_url', Input::old('login_remote_user_custom_logout_url', $setting->login_remote_user_custom_logout_url),array('class' => 'form-control')) }}
{!! $errors->first('login_remote_user_custom_logout_url', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_remote_user_custom_logout_url_help') }}
</p>
<!-- Disable other logins mechanism -->
{{ Form::checkbox('login_common_disabled', '1', Input::old('login_common_disabled', $setting->login_common_disabled),array('class' => 'minimal')) }}
{{ Form::label('login_common_disabled', trans('admin/settings/general.login_common_disabled_text')) }}
{!! $errors->first('login_common_disabled', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_common_disabled_help') }}
</p>
@if (config('app.lock_passwords'))
<p class="help-block">{{ trans('general.feature_disabled') }}</p>
@else
{{ Form::checkbox('login_remote_user_enabled', '1', Input::old('login_remote_user_enabled', $setting->login_remote_user_enabled),array('class' => 'minimal')) }}
{{ Form::label('login_remote_user_enabled', trans('admin/settings/general.login_remote_user_enabled_text')) }}
{!! $errors->first('login_remote_user_enabled', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_remote_user_enabled_help') }}
</p>
<!-- Custom logout url to redirect to authentication provider -->
{{ Form::label('login_remote_user_custom_logout_url', trans('admin/settings/general.login_remote_user_custom_logout_url_text')) }}
{{ Form::text('login_remote_user_custom_logout_url', Input::old('login_remote_user_custom_logout_url', $setting->login_remote_user_custom_logout_url),array('class' => 'form-control')) }}
{!! $errors->first('login_remote_user_custom_logout_url', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_remote_user_custom_logout_url_help') }}
</p>
<!-- Disable other logins mechanism -->
{{ Form::checkbox('login_common_disabled', '1', Input::old('login_common_disabled', $setting->login_common_disabled),array('class' => 'minimal')) }}
{{ Form::label('login_common_disabled', trans('admin/settings/general.login_common_disabled_text')) }}
{!! $errors->first('login_common_disabled', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_common_disabled_help') }}
</p>
@endif
</div>
</div>
+1 -1
View File
@@ -1,5 +1,5 @@
<tr>
<td class="header">
<td class="header"{!! ($snipeSettings->header_color!='') ? ' style="background-color: '.e($snipeSettings->header_color).'"' : '' !!}>
@if (($snipeSettings->show_images_in_email=='1' ) && ($snipeSettings::setupCompleted()))
@if ($snipeSettings->brand == '3')
+9 -2
View File
@@ -674,10 +674,10 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () {
/*--- Users API ---*/
Route::group([ 'prefix' => 'users' ], function () {
Route::post('two_factor_reset',
@@ -687,6 +687,13 @@ Route::group(['prefix' => 'v1','namespace' => 'Api'], function () {
]
);
Route::get('me',
[
'as' => 'api.users.me',
'uses' => 'UsersController@getCurrentUserInfo'
]
);
Route::get('list/{status?}',
[
'as' => 'api.users.list',
+144 -88
View File
@@ -1,5 +1,5 @@
#!/bin/bash
#/ Usage: sniepit [-vh]
#/ Usage: snipeit.sh [-vh]
#/
#/ Install Snipe-IT open source asset management.
#/
@@ -11,10 +11,6 @@
# Snipe-It Install Script #
# Script created by Mike Tucker #
# mtucker6784@gmail.com #
# This script is just to help streamline the #
# install process for Debian and CentOS #
# based distributions. I assume you will be #
# installing as a subdomain on a fresh OS install. #
# #
# Feel free to modify, but please give #
# credit where it's due. Thanks! #
@@ -44,7 +40,7 @@ done
print_usage () {
grep '^#/' <"$0" | cut -c 4-
exit ${1:-1}
exit 1
}
if [ -n "$show_help" ]; then
@@ -67,24 +63,23 @@ if [ "$(id -u)" != "0" ]; then
fi
fi
#First things first, let's set some variables and find our distro.
clear
name="snipeit"
hostname="$(hostname)"
fqdn="$(hostname --fqdn)"
readonly APP_USER="snipeitapp"
readonly APP_NAME="snipeit"
readonly APP_PATH="/var/www/$APP_NAME"
progress () {
spin[0]="-"
spin[1]="\\"
spin[2]="|"
spin[3]="/"
echo -n " "
while kill -0 "$pid" > /dev/null 2>&1; do
for i in "${spin[@]}"; do
echo -ne "\\b$i"
sleep .1
sleep .3
done
done
echo ""
@@ -136,58 +131,103 @@ install_packages () {
create_virtualhost () {
{
echo "<VirtualHost *:80>"
echo " <Directory $webdir/$name/public>"
echo " <Directory $APP_PATH/public>"
echo " Allow From All"
echo " AllowOverride All"
echo " Options +Indexes"
echo " </Directory>"
echo ""
echo " DocumentRoot $webdir/$name/public"
echo " DocumentRoot $APP_PATH/public"
echo " ServerName $fqdn"
echo "</VirtualHost>"
} >> "$apachefile"
}
create_user () {
echo "* Creating Snipe-IT user."
if [ "$distro" == "ubuntu" ] || [ "$distro" == "debian" ] ; then
adduser --quiet --disabled-password --gecos '""' "$APP_USER"
else
adduser "$APP_USER"
fi
usermod -a -G "$apache_group" "$APP_USER"
}
run_as_app_user () {
if ! hash sudo 2>/dev/null; then
su -c "$@" $APP_USER
else
sudo -i -u $APP_USER "$@"
fi
}
install_composer () {
# https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md
EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
run_as_app_user php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(run_as_app_user php -r "echo hash_file('SHA384', 'composer-setup.php');")"
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
>&2 echo 'ERROR: Invalid composer installer signature'
run_as_app_user rm composer-setup.php
exit 1
fi
run_as_app_user php composer-setup.php
run_as_app_user rm composer-setup.php
mv "$(eval echo ~$APP_USER)"/composer.phar /usr/local/bin/composer
}
install_snipeit () {
create_user
echo "* Creating MariaDB Database/User."
echo "* Please Input your MariaDB root password:"
mysql -u root -p --execute="CREATE DATABASE snipeit;GRANT ALL PRIVILEGES ON snipeit.* TO snipeit@localhost IDENTIFIED BY '$mysqluserpw';"
echo "* Cloning Snipe-IT from github to the web directory."
log "git clone https://github.com/snipe/snipe-it $webdir/$name"
log "git clone https://github.com/snipe/snipe-it $APP_PATH"
echo "* Configuring .env file."
cp "$webdir/$name/.env.example" "$webdir/$name/.env"
cp "$APP_PATH/.env.example" "$APP_PATH/.env"
#TODO escape SED delimiter in variables
sed -i '1 i\#Created By Snipe-it Installer' "$webdir/$name/.env"
sed -i "s|^\\(APP_TIMEZONE=\\).*|\\1$tzone|" "$webdir/$name/.env"
sed -i "s|^\\(DB_HOST=\\).*|\\1localhost|" "$webdir/$name/.env"
sed -i "s|^\\(DB_DATABASE=\\).*|\\1snipeit|" "$webdir/$name/.env"
sed -i "s|^\\(DB_USERNAME=\\).*|\\1snipeit|" "$webdir/$name/.env"
sed -i "s|^\\(DB_PASSWORD=\\).*|\\1$mysqluserpw|" "$webdir/$name/.env"
sed -i "s|^\\(APP_URL=\\).*|\\1http://$fqdn|" "$webdir/$name/.env"
sed -i '1 i\#Created By Snipe-it Installer' "$APP_PATH/.env"
sed -i "s|^\\(APP_TIMEZONE=\\).*|\\1$tzone|" "$APP_PATH/.env"
sed -i "s|^\\(DB_HOST=\\).*|\\1localhost|" "$APP_PATH/.env"
sed -i "s|^\\(DB_DATABASE=\\).*|\\1snipeit|" "$APP_PATH/.env"
sed -i "s|^\\(DB_USERNAME=\\).*|\\1snipeit|" "$APP_PATH/.env"
sed -i "s|^\\(DB_PASSWORD=\\).*|\\1$mysqluserpw|" "$APP_PATH/.env"
sed -i "s|^\\(APP_URL=\\).*|\\1http://$fqdn|" "$APP_PATH/.env"
echo "* Installing and running composer."
cd "$webdir/$name/"
curl -sS https://getcomposer.org/installer | php
php composer.phar install --no-dev --prefer-source
echo "* Installing composer."
install_composer
echo "* Setting permissions."
for chmod_dir in "$webdir/$name/storage" "$webdir/$name/storage/private_uploads" "$webdir/$name/public/uploads"; do
chmod -R 755 "$chmod_dir"
for chmod_dir in "$APP_PATH/storage" "$APP_PATH/public/uploads"; do
chmod -R 775 "$chmod_dir"
done
chown -R "$ownergroup" "$webdir/$name"
chown -R "$APP_USER":"$apache_group" "$APP_PATH"
echo "* Running composer."
# We specify the path to composer because CentOS lacks /usr/local/bin in $PATH when using sudo
run_as_app_user /usr/local/bin/composer install --no-dev --prefer-source --working-dir "$APP_PATH"
sudo chgrp -R "$apache_group" "$APP_PATH/vendor"
echo "* Generating the application key."
log "php artisan key:generate --force"
log "php $APP_PATH/artisan key:generate --force"
echo "* Artisan Migrate."
log "php artisan migrate --force"
log "php $APP_PATH/artisan migrate --force"
echo "* Creating scheduler cron."
(crontab -l ; echo "* * * * * /usr/bin/php $webdir/$name/artisan schedule:run >> /dev/null 2>&1") | crontab -
(crontab -l ; echo "* * * * * /usr/bin/php $APP_PATH/artisan schedule:run >> /dev/null 2>&1") | crontab -
}
set_firewall () {
@@ -205,13 +245,14 @@ set_selinux () {
#Required for ldap integration
setsebool -P httpd_can_connect_ldap on
#Sets SELinux context type so that scripts running in the web server process are allowed read/write access
chcon -R -h -t httpd_sys_script_rw_t "$webdir/$name/"
chcon -R -h -t httpd_sys_rw_content_t "$APP_PATH/storage/"
chcon -R -h -t httpd_sys_rw_content_t "$APP_PATH/public/"
fi
}
set_hosts () {
echo "* Setting up hosts file."
echo >> /etc/hosts "127.0.0.1 $hostname $fqdn"
echo >> /etc/hosts "127.0.0.1 $(hostname) $fqdn"
}
if [[ -f /etc/lsb-release || -f /etc/debian_version ]]; then
@@ -219,27 +260,29 @@ if [[ -f /etc/lsb-release || -f /etc/debian_version ]]; then
version="$(lsb_release -rs)"
codename="$(lsb_release -cs)"
elif [ -f /etc/os-release ]; then
distro="$(. /etc/os-release && echo $ID)"
version="$(. /etc/os-release && echo $VERSION_ID)"
# shellcheck disable=SC1091
distro="$(source /etc/os-release && echo "$ID")"
# shellcheck disable=SC1091
version="$(source /etc/os-release && echo "$VERSION_ID")"
#Order is important here. If /etc/os-release and /etc/centos-release exist, we're on centos 7.
#If only /etc/centos-release exist, we're on centos6(or earlier). Centos-release is less parsable,
#so lets assume that it's version 6 (Plus, who would be doing a new install of anything on centos5 at this point..)
#/etc/os-release properly detects fedora
elif [ -f /etc/centos-release ]; then
distro="Centos"
distro="centos"
version="6"
else
distro="unsupported"
fi
echo "
echo '
_____ _ __________
/ ___/____ (_)___ ___ / _/_ __/
\__ \/ __ \/ / __ \/ _ \______ / / / /
___/ / / / / / /_/ / __/_____// / / /
/____/_/ /_/_/ .___/\___/ /___/ /_/
/_/
"
'
echo ""
echo " Welcome to Snipe-IT Inventory Installer for CentOS, Fedora, Debian and Ubuntu!"
@@ -249,30 +292,38 @@ case $distro in
*ubuntu*)
echo " The installer has detected $distro version $version codename $codename."
distro=ubuntu
apache_group=www-data
apachefile=/etc/apache2/sites-available/$APP_NAME.conf
;;
*debian*)
echo " The installer has detected $distro version $version codename $codename."
distro=debian
apache_group=www-data
apachefile=/etc/apache2/sites-available/$APP_NAME.conf
;;
*centos*|*redhat*|*ol*|*rhel*)
echo " The installer has detected $distro version $version."
distro=centos
apache_group=apache
apachefile=/etc/httpd/conf.d/$APP_NAME.conf
;;
*fedora*)
echo " The installer has detected $distro version $version."
distro=fedora
apache_group=apache
apachefile=/etc/httpd/conf.d/$APP_NAME.conf
;;
*)
echo " The installer was unable to determine your OS. Exiting for safety."
exit
exit 1
;;
esac
shopt -u nocasematch
echo -n " Q. What is the FQDN of your server? ($fqdn): "
echo -n " Q. What is the FQDN of your server? ($(hostname --fqdn)): "
read -r fqdn
if [ -z "$fqdn" ]; then
fqdn="$(hostname --fqdn)"
readonly fqdn="$(hostname --fqdn)"
fi
echo " Setting to $fqdn"
echo ""
@@ -299,16 +350,11 @@ case $setpw in
esac
done
#TODO: Lets not install snipeit application under root
case $distro in
debian)
if [[ "$version" =~ ^9 ]]; then
# Install for Debian 9.x
webdir=/var/www
ownergroup=www-data:www-data
tzone=$(cat /etc/timezone)
apachefile=/etc/apache2/sites-available/$name.conf
echo "* Adding PHP repository."
log "apt-get install -y apt-transport-https"
@@ -316,8 +362,7 @@ case $distro in
echo "deb https://packages.sury.org/php/ $codename main" > /etc/apt/sources.list.d/php.list
echo -n "* Updating installed packages."
log "apt-get update"
log "apt-get -y upgrade" & pid=$!
log "apt-get update && apt-get -y upgrade" & pid=$!
progress
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
@@ -327,7 +372,7 @@ case $distro in
echo "* Configuring Apache."
create_virtualhost
log "a2enmod rewrite"
log "a2ensite $name.conf"
log "a2ensite $APP_NAME.conf"
set_hosts
@@ -340,10 +385,7 @@ case $distro in
log "service apache2 restart"
elif [[ "$version" =~ ^8 ]]; then
# Install for Debian 8.x
webdir=/var/www
ownergroup=www-data:www-data
tzone=$(cat /etc/timezone)
apachefile=/etc/apache2/sites-available/$name.conf
echo "* Adding MariaDB and ppa:ondrej/php repositories."
log "apt-get install -y software-properties-common apt-transport-https"
@@ -353,8 +395,7 @@ case $distro in
echo "deb https://packages.sury.org/php/ $codename main" > /etc/apt/sources.list.d/php.list
echo -n "* Updating installed packages."
log "apt-get update"
log "apt-get -y upgrade" & pid=$!
log "apt-get update && apt-get -y upgrade" & pid=$!
progress
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
@@ -364,7 +405,7 @@ case $distro in
echo "* Configuring Apache."
create_virtualhost
log "a2enmod rewrite"
log "a2ensite $name.conf"
log "a2ensite $APP_NAME.conf"
set_hosts
@@ -381,12 +422,40 @@ case $distro in
fi
;;
ubuntu)
if [[ "$version" =~ 16.04 ]]; then
# Install for Ubuntu 16.04
webdir=/var/www
ownergroup=www-data:www-data
if [ "$version" == "18.04" ]; then
# Install for Ubuntu 18.04
tzone=$(cat /etc/timezone)
echo -n "* Updating installed packages."
log "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y upgrade" & pid=$!
progress
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php php php-mcrypt php-curl php-mysql php-gd php-ldap php-zip php-mbstring php-xml php-bcmath curl git unzip"
install_packages
echo "* Configuring Apache."
create_virtualhost
log "phpenmod mcrypt"
log "phpenmod mbstring"
log "a2enmod rewrite"
log "a2ensite $APP_NAME.conf"
set_hosts
echo "* Starting MariaDB."
log "systemctl start mariadb.service"
echo "* Securing MariaDB."
/usr/bin/mysql_secure_installation
install_snipeit
echo "* Restarting Apache httpd."
log "systemctl restart apache2"
elif [ "$version" == "16.04" ]; then
# Install for Ubuntu 16.04
tzone=$(cat /etc/timezone)
apachefile=/etc/apache2/sites-available/$name.conf
echo "* Adding MariaDB and ppa:ondrej/php repositories."
log "apt-get install -y software-properties-common"
@@ -407,7 +476,7 @@ case $distro in
log "phpenmod mcrypt"
log "phpenmod mbstring"
log "a2enmod rewrite"
log "a2ensite $name.conf"
log "a2ensite $APP_NAME.conf"
set_hosts
@@ -421,12 +490,9 @@ case $distro in
echo "* Restarting Apache httpd."
log "service apache2 restart"
elif [[ "$version" =~ 14.04 ]]; then
elif [ "$version" == "14.04" ]; then
# Install for Ubuntu 14.04
webdir=/var/www
ownergroup=www-data:www-data
tzone=$(cat /etc/timezone)
apachefile=/etc/apache2/sites-available/$name.conf
echo "* Adding MariaDB and ppa:ondrej/php repositories."
log "apt-get install -y software-properties-common"
@@ -435,8 +501,7 @@ case $distro in
log "add-apt-repository ppa:ondrej/php -y"
echo -n "* Updating installed packages."
log "apt-get update"
log "DEBIAN_FRONTEND=noninteractive apt-get -y upgrade" & pid=$!
log "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y upgrade" & pid=$!
progress
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
@@ -448,7 +513,7 @@ case $distro in
log "phpenmod mcrypt"
log "phpenmod mbstring"
log "a2enmod rewrite"
log "a2ensite $name.conf"
log "a2ensite $APP_NAME.conf"
set_hosts
@@ -470,10 +535,7 @@ case $distro in
centos)
if [[ "$version" =~ ^6 ]]; then
# Install for CentOS/Redhat 6.x
webdir=/var/www/html
ownergroup=apache:apache
tzone=$(grep ZONE /etc/sysconfig/clock | tr -d '"' | sed 's/ZONE=//g');
apachefile=/etc/httpd/conf.d/$name.conf
echo "* Adding IUS, epel-release and MariaDB repositories."
mariadbRepo=/etc/yum.repos.d/MariaDB.repo
@@ -521,10 +583,7 @@ case $distro in
log "/sbin/service httpd start"
elif [[ "$version" =~ ^7 ]]; then
# Install for CentOS/Redhat 7
webdir=/var/www/html
ownergroup=apache:apache
tzone=$(timedatectl | gawk -F'[: ]' ' $9 ~ /zone/ {print $11}');
apachefile=/etc/httpd/conf.d/$name.conf
echo "* Adding IUS, epel-release and MariaDB repositories."
log "yum -y install wget epel-release"
@@ -564,10 +623,7 @@ case $distro in
fedora)
if [ "$version" -ge 26 ]; then
# Install for Fedora 26+
webdir=/var/www/html
ownergroup=apache:apache
tzone=$(timedatectl | gawk -F'[: ]' ' $9 ~ /zone/ {print $11}');
apachefile=/etc/httpd/conf.d/$name.conf
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
PACKAGES="httpd mariadb-server git unzip php php-mysqlnd php-bcmath php-cli php-common php-embedded php-gd php-mbstring php-mcrypt php-ldap php-json php-simplexml"
@@ -609,40 +665,40 @@ case $setupmail in
[yY] | [yY][Ee][Ss] )
echo -n " Outgoing mailserver address:"
read -r mailhost
sed -i "s|^\\(MAIL_HOST=\\).*|\\1$mailhost|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_HOST=\\).*|\\1$mailhost|" "$APP_PATH/.env"
echo -n " Server port number:"
read -r mailport
sed -i "s|^\\(MAIL_PORT=\\).*|\\1$mailport|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_PORT=\\).*|\\1$mailport|" "$APP_PATH/.env"
echo -n " Username:"
read -r mailusername
sed -i "s|^\\(MAIL_USERNAME=\\).*|\\1$mailusername|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_USERNAME=\\).*|\\1$mailusername|" "$APP_PATH/.env"
echo -n " Password:"
read -rs mailpassword
sed -i "s|^\\(MAIL_PASSWORD=\\).*|\\1$mailpassword|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_PASSWORD=\\).*|\\1$mailpassword|" "$APP_PATH/.env"
echo ""
echo -n " Encryption(null/TLS/SSL):"
read -r mailencryption
sed -i "s|^\\(MAIL_ENCRYPTION=\\).*|\\1$mailencryption|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_ENCRYPTION=\\).*|\\1$mailencryption|" "$APP_PATH/.env"
echo -n " From address:"
read -r mailfromaddr
sed -i "s|^\\(MAIL_FROM_ADDR=\\).*|\\1$mailfromaddr|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_FROM_ADDR=\\).*|\\1$mailfromaddr|" "$APP_PATH/.env"
echo -n " From name:"
read -r mailfromname
sed -i "s|^\\(MAIL_FROM_NAME=\\).*|\\1$mailfromname|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_FROM_NAME=\\).*|\\1$mailfromname|" "$APP_PATH/.env"
echo -n " Reply to address:"
read -r mailreplytoaddr
sed -i "s|^\\(MAIL_REPLYTO_ADDR=\\).*|\\1$mailreplytoaddr|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_REPLYTO_ADDR=\\).*|\\1$mailreplytoaddr|" "$APP_PATH/.env"
echo -n " Reply to name:"
read -r mailreplytoname
sed -i "s|^\\(MAIL_REPLYTO_NAME=\\).*|\\1$mailreplytoname|" "$webdir/$name/.env"
sed -i "s|^\\(MAIL_REPLYTO_NAME=\\).*|\\1$mailreplytoname|" "$APP_PATH/.env"
setupmail="yes"
;;
[nN] | [n|N][O|o] )
+57 -6
View File
@@ -8,6 +8,7 @@ use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\CustomField;
use App\Models\Location;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
@@ -72,12 +73,61 @@ EOT;
'asset_tag' => '970882174-8',
'notes' => "Curabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.",
'purchase_date' => '2016-04-05 00:00:01',
'purchase_cost' => 133289.59,
'warranty_months' => 14,
'purchase_cost' => 133289.59
, 'warranty_months' => 14,
'_snipeit_weight_2' => 35
]);
}
public function testImportCheckoutToLocation()
{
$this->signIn();
// Testing in order:
// * Asset to user, no checkout type defined (default to user).
// * Asset to user, explicit user checkout type (Checkout to user)
// * Asset to location, location does not exist to begin with
// * Asset to preexisting location.
$csv = <<<'EOT'
Full Name,Email,Username,Checkout Location,Checkout Type,item Name,Category,Model name,Manufacturer,Model Number,Serial,Asset Tag,Location,Notes,Purchase Date,Purchase Cost,Company,Status,Warranty,Supplier,Weight
Bonnie Nelson,bnelson0@cdbaby.com,bnelson0,,,eget nunc donec quis,quam,massa id,Linkbridge,6377018600094472,27aa8378-b0f4-4289-84a4-405da95c6147,970882174-8,Daping,"Curabitur in libero ut massa volutpat convallis. Morbi odio odio, elementum eu, interdum eu, tincidunt in, leo. Maecenas pulvinar lobortis est.",2016-04-05,133289.59,Alpha,Undeployable,14,Blogspan,35
Mildred Gibson,mgibson2@wiley.com,mgibson2,,user,morbi quis tortor id,nunc nisl duis,convallis tortor risus,Lajo,374622546776765,2837ab20-8f0d-4935-8a52-226392f2b1b0,710141467-2,Shekou,In congue. Etiam justo. Etiam pretium iaculis justo.,2015-08-09,233.57,Konklab,Lost,,,
,,,Planet Earth,location,dictumst maecenas ut,sem praesent,accumsan felis,Layo,30052522651756,4751495c-cee0-4961-b788-94a545b5643e,998233705-X,Dante Delgado,,2016-04-16,261.79,,Archived,15,Ntag,
,,,Daping,location,viverra diam vitae,semper sapien,dapibus dolor vel,Flashset,3559785746335392,e287bb64-ff4f-434c-88ab-210ad433c77b,927820758-6,Achiaman,,2016-03-05,675.3,,Archived,22,Meevee,
EOT;
$this->import(new AssetImporter($csv));
$user = User::where('username', 'bnelson0')->firstOrFail();
$this->tester->seeRecord('assets', [
'asset_tag' => '970882174-8',
'assigned_type' => User::class,
'assigned_to' => $user->id
]);
$user = User::where('username', 'mgibson2')->firstOrFail();
$this->tester->seeRecord('assets', [
'asset_tag' => '710141467-2',
'assigned_type' => User::class,
'assigned_to' => $user->id
]);
$location = Location::where('name', 'Planet Earth')->firstOrFail();
$this->tester->seeRecord('assets', [
'asset_tag' => '998233705-X',
'assigned_type' => Location::class,
'assigned_to' => $location->id
]);
$location = Location::where('name', 'Daping')->firstOrFail();
$this->tester->seeRecord('assets', [
'asset_tag' => '927820758-6',
'assigned_type' => Location::class,
'assigned_to' => $location->id
]);
}
public function testUpdateAssetIncludingCustomFields()
{
$this->signIn();
@@ -385,18 +435,19 @@ EOT;
public function testDefaultConsumableImport()
{
$csv = <<<'EOT'
Item Name,Purchase Date,Purchase Cost,Location,Company,Order Number,Category,Requestable,Quantity
eget,01/03/2011,$85.91,mauris blandit mattis.,Lycos,T295T06V,Triamterene/Hydrochlorothiazide,No,322
Item Name,Purchase Date,Purchase Cost,Location,Company,Order Number,Category,Requestable,Quantity,Item Number,Model Number
eget,01/03/2011,$85.91,mauris blandit mattis.,Lycos,T295T06V,Triamterene/Hydrochlorothiazide,No,322,3305,30123
EOT;
$this->import(new ConsumableImporter($csv));
$this->tester->seeRecord('consumables', [
'name' => 'eget',
'purchase_date' => '2011-01-03 00:00:01',
'purchase_cost' => 85.91,
'order_number' => 'T295T06V',
'requestable' => 0,
'qty' => 322
'qty' => 322,
'item_no' => 3305,
'model_number' => 30123
]);
$this->tester->seeRecord('locations', [