Compare commits
470 Commits
v4.0.2
...
v4.1.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1076ec96be | ||
|
|
3b498efee1 | ||
|
|
9687a78981 | ||
|
|
2244a4b3cf | ||
|
|
f3f84f1a8c | ||
|
|
41994c95e0 | ||
|
|
39c68214e9 | ||
|
|
9c94e70917 | ||
|
|
6a3716a06d | ||
|
|
feccc55c54 | ||
|
|
fe70792cbd | ||
|
|
95b6e0d2d8 | ||
|
|
5d890fb139 | ||
|
|
cd2816b1c7 | ||
|
|
2172e6cc25 | ||
|
|
04130a568c | ||
|
|
108ac79442 | ||
|
|
3d7fd5cf04 | ||
|
|
5737de2e22 | ||
|
|
1e21cef218 | ||
|
|
ad7a2da9bd | ||
|
|
bd48ae96c2 | ||
|
|
0f5e0dcd4f | ||
|
|
c37fa44f72 | ||
|
|
daaf98783f | ||
|
|
1399ebb133 | ||
|
|
03f6211582 | ||
|
|
20bcc73000 | ||
|
|
0058f02e82 | ||
|
|
25b8c4438e | ||
|
|
4f1747023a | ||
|
|
46fb5c9d40 | ||
|
|
52f10232a1 | ||
|
|
5278dac2b0 | ||
|
|
890012f6c4 | ||
|
|
3991f79115 | ||
|
|
0a114c7daf | ||
|
|
3064b3f80e | ||
|
|
df430a2263 | ||
|
|
277e49468b | ||
|
|
f687c8db24 | ||
|
|
c616041876 | ||
|
|
d76f858dcd | ||
|
|
7a543fa6d5 | ||
|
|
49afd325a9 | ||
|
|
ce5ccc31f0 | ||
|
|
c70db75de9 | ||
|
|
7b76bbfd68 | ||
|
|
cfd1925625 | ||
|
|
e8b4bdf6f4 | ||
|
|
7e0c33d535 | ||
|
|
24211cb674 | ||
|
|
2d758be0e1 | ||
|
|
f49ecbdb61 | ||
|
|
3cea12565b | ||
|
|
b1ac024725 | ||
|
|
ec68bd7842 | ||
|
|
a224904ade | ||
|
|
cb3b294baa | ||
|
|
0788347990 | ||
|
|
7496a902bd | ||
|
|
f2d04be8fe | ||
|
|
f2499fc7d2 | ||
|
|
00d910ddbc | ||
|
|
c6d191bcba | ||
|
|
f13836eb55 | ||
|
|
76c4c19b3e | ||
|
|
1d212b59bd | ||
|
|
1174d37c20 | ||
|
|
6bcb55a129 | ||
|
|
a99e09e5e3 | ||
|
|
7d11cb0748 | ||
|
|
9c29ee9c6d | ||
|
|
bdb95e4e3d | ||
|
|
1fa6228fb7 | ||
|
|
8b535c1806 | ||
|
|
b71d0ab484 | ||
|
|
ea07517ad5 | ||
|
|
82690e1fd7 | ||
|
|
75b527ab59 | ||
|
|
b083541723 | ||
|
|
e8d938e188 | ||
|
|
4f80eac467 | ||
|
|
0e5af78cf1 | ||
|
|
0d34cc704a | ||
|
|
d4bb4d2edd | ||
|
|
d008334f2d | ||
|
|
e8847753f4 | ||
|
|
7dad71d2b6 | ||
|
|
db5968f95a | ||
|
|
d97a1edeb4 | ||
|
|
3dd39a46be | ||
|
|
dc9a908de7 | ||
|
|
687cf44d3d | ||
|
|
e054504669 | ||
|
|
e1ad28aa20 | ||
|
|
87992b7f71 | ||
|
|
32478f1a10 | ||
|
|
abc722b9c0 | ||
|
|
49ebf4a314 | ||
|
|
c503729a9a | ||
|
|
0b7864b09c | ||
|
|
ede16eec3c | ||
|
|
21c1ca2336 | ||
|
|
a305b1ea2d | ||
|
|
17d58d9cc5 | ||
|
|
c605984db0 | ||
|
|
d678a0ebff | ||
|
|
e0fe383815 | ||
|
|
7140efc561 | ||
|
|
99be54fd96 | ||
|
|
35da7906cc | ||
|
|
680ad676ca | ||
|
|
4628c15813 | ||
|
|
8a9960f830 | ||
|
|
2b45433255 | ||
|
|
715da63581 | ||
|
|
ad32bae62f | ||
|
|
bbda0dc3b4 | ||
|
|
dc805dd9b1 | ||
|
|
8d68bb7a57 | ||
|
|
7d64ab3158 | ||
|
|
c18220069d | ||
|
|
fbf516284c | ||
|
|
3db25dca7a | ||
|
|
3799ab87ed | ||
|
|
f5ce580593 | ||
|
|
17b271918f | ||
|
|
3a302fe2d7 | ||
|
|
0951a756cc | ||
|
|
fc644925ea | ||
|
|
c0f8b3773c | ||
|
|
fd210c6439 | ||
|
|
f7e23cf7c8 | ||
|
|
b4e1d37b16 | ||
|
|
8ac57d0121 | ||
|
|
b215924b1a | ||
|
|
25d3d66880 | ||
|
|
189574377a | ||
|
|
341ddec9d8 | ||
|
|
abcce78944 | ||
|
|
22e13cd4d2 | ||
|
|
f757da1a98 | ||
|
|
c1f8db37d9 | ||
|
|
4215a3257b | ||
|
|
1f247ff541 | ||
|
|
2fc46746e2 | ||
|
|
e185dc68af | ||
|
|
54000ff69f | ||
|
|
f6a38e848a | ||
|
|
7e8d670f81 | ||
|
|
287b150b7f | ||
|
|
b379656d55 | ||
|
|
2e11a983c8 | ||
|
|
a9753eb646 | ||
|
|
707c4db881 | ||
|
|
d1de34394e | ||
|
|
7153013fb0 | ||
|
|
2b826c3adc | ||
|
|
cd193ce8bb | ||
|
|
cb50142ba3 | ||
|
|
81aaed92ce | ||
|
|
4bc551db82 | ||
|
|
471d665408 | ||
|
|
068308ef56 | ||
|
|
1e65c7bf9a | ||
|
|
ae567c08db | ||
|
|
13586be6b0 | ||
|
|
44c649c3c8 | ||
|
|
2b803a6a6c | ||
|
|
4d3d19ca2b | ||
|
|
9c06912efd | ||
|
|
c5893b4445 | ||
|
|
b90933bb8b | ||
|
|
fe9a90854d | ||
|
|
3b012f2827 | ||
|
|
5519e2d4ae | ||
|
|
a3139c6fc6 | ||
|
|
c0e50be03e | ||
|
|
447833c996 | ||
|
|
809e310565 | ||
|
|
68f6385eba | ||
|
|
bd376a4992 | ||
|
|
9e39abcc32 | ||
|
|
5cd2857d5d | ||
|
|
585fcfb7d4 | ||
|
|
d9135a8aac | ||
|
|
081a64223a | ||
|
|
a4eeff01f0 | ||
|
|
eedbe468ac | ||
|
|
ed4aa7dec2 | ||
|
|
d6bbe15a76 | ||
|
|
34442362ca | ||
|
|
ab3f5f4f4d | ||
|
|
ea63ced2bd | ||
|
|
6bd49bfb72 | ||
|
|
b80d3ce50d | ||
|
|
c069829b33 | ||
|
|
665a113ed8 | ||
|
|
aa7091d962 | ||
|
|
c01850fc73 | ||
|
|
c0103cd878 | ||
|
|
c776fa4f7b | ||
|
|
dc91d10395 | ||
|
|
668a88bc86 | ||
|
|
1d5fb52bfc | ||
|
|
dea42db18b | ||
|
|
a1f5e11517 | ||
|
|
99ad096a8a | ||
|
|
65b4ffeed9 | ||
|
|
0dac88816a | ||
|
|
f7626404b7 | ||
|
|
78f4b08398 | ||
|
|
160fd1c86a | ||
|
|
b46cbac911 | ||
|
|
e9c3d6bfb7 | ||
|
|
9e9a5b7a53 | ||
|
|
e7fe91c9d4 | ||
|
|
02db0f9f9d | ||
|
|
e0668b7507 | ||
|
|
113c55d905 | ||
|
|
9cc25bcfd0 | ||
|
|
81d3f78263 | ||
|
|
66596b0b09 | ||
|
|
7455b1019a | ||
|
|
37df934e97 | ||
|
|
6517a95d45 | ||
|
|
4b84a0c916 | ||
|
|
f64382aa00 | ||
|
|
c61bed52c8 | ||
|
|
176a26e6c3 | ||
|
|
cbe008d52f | ||
|
|
aeb5152789 | ||
|
|
45c2af80a3 | ||
|
|
1fbf3753bc | ||
|
|
bcf435f625 | ||
|
|
b107280b7b | ||
|
|
f1a6926ad9 | ||
|
|
ba7b9d8168 | ||
|
|
59a126c47c | ||
|
|
a98d94ccdc | ||
|
|
56cbc005ae | ||
|
|
22e9246031 | ||
|
|
c0b39701cc | ||
|
|
e2bac62e36 | ||
|
|
fa95f6d836 | ||
|
|
6d4574130f | ||
|
|
485b6397d0 | ||
|
|
93990327de | ||
|
|
4ee7765403 | ||
|
|
13a716310c | ||
|
|
36cbffa183 | ||
|
|
b6a1e0d12f | ||
|
|
f56eb16941 | ||
|
|
64e7ab3a12 | ||
|
|
f64c02ce12 | ||
|
|
bed7b29417 | ||
|
|
40ed86bfe0 | ||
|
|
52a8597813 | ||
|
|
eeb07f73e5 | ||
|
|
57422c9135 | ||
|
|
adca7cb0c5 | ||
|
|
059f8f5bc9 | ||
|
|
c676e9d794 | ||
|
|
e9f10dd74e | ||
|
|
e29d878d4f | ||
|
|
d4e3ea1412 | ||
|
|
c5462c5f1f | ||
|
|
d1328c3ba9 | ||
|
|
8c406e8e55 | ||
|
|
6e33f36595 | ||
|
|
48277606de | ||
|
|
d7c9fcc8df | ||
|
|
9f2fc21649 | ||
|
|
11f99a963a | ||
|
|
f858b2858d | ||
|
|
f468b37f36 | ||
|
|
907b909223 | ||
|
|
9dc79f7165 | ||
|
|
324d44dbac | ||
|
|
a69a939034 | ||
|
|
ed8efbe759 | ||
|
|
834c6ad8f9 | ||
|
|
2ce48fbc7e | ||
|
|
5d18937e94 | ||
|
|
b3186ba5ea | ||
|
|
f51dc9a1c4 | ||
|
|
f3f9920bd3 | ||
|
|
ea6140e786 | ||
|
|
05c4d6dead | ||
|
|
e2c6f36c70 | ||
|
|
21b1ecb6b3 | ||
|
|
a62cf358ee | ||
|
|
20c429b600 | ||
|
|
38e25a388c | ||
|
|
2c6cedd62c | ||
|
|
9b0cca4a37 | ||
|
|
f6d198a39c | ||
|
|
d12fc6b13c | ||
|
|
a12c7c83d4 | ||
|
|
affd4035c3 | ||
|
|
ecfe1a5442 | ||
|
|
e9c77198d7 | ||
|
|
20be670648 | ||
|
|
a03207e5b4 | ||
|
|
6555b3a49d | ||
|
|
61a634bc1a | ||
|
|
00696a3668 | ||
|
|
e20271791b | ||
|
|
86b9fdbffe | ||
|
|
7e728094a1 | ||
|
|
f865c621ef | ||
|
|
e2f4685a55 | ||
|
|
2148ea94bb | ||
|
|
1d2787250b | ||
|
|
7f02ff12cf | ||
|
|
65341a5d8a | ||
|
|
1608edbb28 | ||
|
|
776da1dea4 | ||
|
|
a6b3e4bbb1 | ||
|
|
3b2ecda243 | ||
|
|
57cbb5c5ce | ||
|
|
7b27d32121 | ||
|
|
ccfba324ee | ||
|
|
9f55a76fcf | ||
|
|
8fdddc310f | ||
|
|
064a4ebe33 | ||
|
|
fbea1c0823 | ||
|
|
a84da88114 | ||
|
|
282b3b5b0a | ||
|
|
df4cb7d351 | ||
|
|
1dcff8d463 | ||
|
|
e461c25428 | ||
|
|
554ea8bb95 | ||
|
|
f2be409914 | ||
|
|
af70cdaeac | ||
|
|
f580e20bc3 | ||
|
|
a054cec7c9 | ||
|
|
1ad7bbdd0c | ||
|
|
10c13baf2b | ||
|
|
f6d8642799 | ||
|
|
adddc5324b | ||
|
|
f442b70ae7 | ||
|
|
7b10213b3a | ||
|
|
5e9b04b0f5 | ||
|
|
85da30894b | ||
|
|
f66e222f3d | ||
|
|
eaf55f5e79 | ||
|
|
32b01b8f38 | ||
|
|
6dd4282f1f | ||
|
|
3f44987799 | ||
|
|
b4fec068d0 | ||
|
|
512632ce60 | ||
|
|
58a9b0d3e8 | ||
|
|
fcb1283a14 | ||
|
|
54671af7f0 | ||
|
|
aaf4acef83 | ||
|
|
8e73cacf4e | ||
|
|
b4b2daebbd | ||
|
|
c721fdd793 | ||
|
|
d119372ff0 | ||
|
|
c8bed867da | ||
|
|
3a470ce789 | ||
|
|
d303cbd7cb | ||
|
|
ef19bc7c16 | ||
|
|
655484b1da | ||
|
|
ac8185339d | ||
|
|
a021ce011b | ||
|
|
3687cbfdb3 | ||
|
|
594135fd70 | ||
|
|
8a7abba427 | ||
|
|
9df648b428 | ||
|
|
a65c2f305e | ||
|
|
ff38cdd09b | ||
|
|
9420913d25 | ||
|
|
59225701b5 | ||
|
|
cd2e137fcc | ||
|
|
7a27fda083 | ||
|
|
aab635154a | ||
|
|
169dc779fd | ||
|
|
26423c5c02 | ||
|
|
862543428b | ||
|
|
d28e882f5d | ||
|
|
e26d038589 | ||
|
|
afc8133acf | ||
|
|
abe19a6311 | ||
|
|
07359c76ad | ||
|
|
a2453be573 | ||
|
|
c2616412c0 | ||
|
|
23ca2d9a0b | ||
|
|
0bb186ad3b | ||
|
|
b7abd8328a | ||
|
|
7d5b08446a | ||
|
|
ba793355cb | ||
|
|
655ca78633 | ||
|
|
1e52fb546c | ||
|
|
24cad588bd | ||
|
|
bbffde47f7 | ||
|
|
be7598b279 | ||
|
|
1a7e3fbb4b | ||
|
|
e8a0c44e93 | ||
|
|
fe644c76c5 | ||
|
|
9301c56a77 | ||
|
|
e37503c734 | ||
|
|
878bde67ac | ||
|
|
314d6fa4c5 | ||
|
|
43ff66e4d9 | ||
|
|
2ea91266c0 | ||
|
|
a0bd9bce39 | ||
|
|
5223ec1dbb | ||
|
|
4eda2a2f96 | ||
|
|
fe1975067a | ||
|
|
b9e79c27a8 | ||
|
|
b8ed6a53b6 | ||
|
|
efd71f8bfe | ||
|
|
05a8ba9a8e | ||
|
|
9ce2d1f560 | ||
|
|
c6069b905b | ||
|
|
2e76620cf8 | ||
|
|
a4b30279ee | ||
|
|
faf3802971 | ||
|
|
7fe2a1f802 | ||
|
|
ba8bcce8eb | ||
|
|
aab409dec2 | ||
|
|
d9824a0454 | ||
|
|
42c2a66946 | ||
|
|
4d32f2b337 | ||
|
|
0e29744ec2 | ||
|
|
51236a2ad9 | ||
|
|
46d87849f4 | ||
|
|
507f1f196c | ||
|
|
b60febeea2 | ||
|
|
b3e0d8f675 | ||
|
|
9b84a0d516 | ||
|
|
adac5ac544 | ||
|
|
1775995f26 | ||
|
|
26a7701cda | ||
|
|
a34085f1d9 | ||
|
|
915c19ebda | ||
|
|
7fded367c4 | ||
|
|
0a4743210c | ||
|
|
af19e5d976 | ||
|
|
3d7277398c | ||
|
|
a7ad48a02a | ||
|
|
0fb4ff77f4 | ||
|
|
ac83dba2bb | ||
|
|
979ecf961d | ||
|
|
13dcdf41b8 | ||
|
|
fc96fa756e | ||
|
|
ea9a502152 | ||
|
|
d844734b6c | ||
|
|
ec8a3d2e56 | ||
|
|
5410dc4255 | ||
|
|
d1112bbc99 | ||
|
|
ecf041fa10 | ||
|
|
0ab9bc1db8 | ||
|
|
73e788b94b | ||
|
|
e91a537552 | ||
|
|
ef8c1abf28 | ||
|
|
bd0498aa69 | ||
|
|
5e1df7049c | ||
|
|
e27e1a78c3 | ||
|
|
d585a34a26 | ||
|
|
4edaba648e | ||
|
|
4324242475 | ||
|
|
eca5a05335 | ||
|
|
d442feb687 | ||
|
|
0a88141b18 | ||
|
|
d5e6d82ca1 | ||
|
|
f2a62857cb |
@@ -746,6 +746,69 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "gizzmojr",
|
||||
"name": "gizzmojr",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/3697569?v=4",
|
||||
"profile": "https://github.com/gizzmojr",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "imjennyli",
|
||||
"name": "Jenny Li",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/404729?v=4",
|
||||
"profile": "https://github.com/imjennyli",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "GeoffYoung",
|
||||
"name": "Geoff Young",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/869227?v=4",
|
||||
"profile": "https://github.com/GeoffYoung",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "BlueHatbRit",
|
||||
"name": "Elliot Blackburn",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/1068477?v=4",
|
||||
"profile": "http://www.elliotblackburn.com",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "TonisOrmisson",
|
||||
"name": "Tõnis Ormisson",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/6357451?v=4",
|
||||
"profile": "http://andmemasin.eu",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "thakilla",
|
||||
"name": "Nicolai Essig",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/449411?v=4",
|
||||
"profile": "http://www.nicolai-essig.de",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "techincolor",
|
||||
"name": "Danielle",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/14809698?v=4",
|
||||
"profile": "https://github.com/techincolor",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
22
.env.example
22
.env.example
@@ -8,17 +8,18 @@ APP_URL=null
|
||||
APP_TIMEZONE='UTC'
|
||||
APP_LOCALE=en
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
DB_HOST=127.0.0.1
|
||||
DB_DATABASE=null
|
||||
DB_USERNAME=null
|
||||
DB_PASSWORD=null
|
||||
DB_PREFIX=null
|
||||
DB_DUMP_PATH='/usr/bin'
|
||||
DB_CHARSET=utf8mb4
|
||||
DB_COLLATION=utf8mb4_unicode_ci
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SSL DATABASE SETTINGS
|
||||
@@ -29,7 +30,6 @@ DB_SSL_CERT_PATH=null
|
||||
DB_SSL_CA_PATH=null
|
||||
DB_SSL_CIPHER=null
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: OUTGOING MAIL SERVER SETTINGS
|
||||
# --------------------------------------------
|
||||
@@ -44,14 +44,12 @@ MAIL_FROM_NAME='Snipe-IT'
|
||||
MAIL_REPLYTO_ADDR=you@example.com
|
||||
MAIL_REPLYTO_NAME='Snipe-IT'
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: IMAGE LIBRARY
|
||||
# This should be gd or imagick
|
||||
# --------------------------------------------
|
||||
IMAGE_LIB=gd
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SESSION SETTINGS
|
||||
# --------------------------------------------
|
||||
@@ -62,6 +60,11 @@ COOKIE_NAME=snipeit_session
|
||||
COOKIE_DOMAIN=null
|
||||
SECURE_COOKIES=false
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SECURITY HEADER SETTINGS
|
||||
# --------------------------------------------
|
||||
REFERRER_POLICY=same-origin
|
||||
ENABLE_CSP=false
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: CACHE SETTINGS
|
||||
@@ -70,6 +73,12 @@ CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: REDIS SETTINGS
|
||||
# --------------------------------------------
|
||||
REDIS_HOST=null
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT-null
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: AWS S3 SETTINGS
|
||||
@@ -88,7 +97,8 @@ LOGIN_LOCKOUT_DURATION=60
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: MISC
|
||||
# --------------------------------------------
|
||||
APP_LOG=single
|
||||
APP_LOG=daily
|
||||
APP_LOG_MAX_FILES=10
|
||||
APP_LOCKED=false
|
||||
FILESYSTEM_DISK=local
|
||||
APP_TRUSTED_PROXIES=192.168.1.1,10.0.0.1
|
||||
|
||||
13
.github/ISSUE_TEMPLATE.md
vendored
13
.github/ISSUE_TEMPLATE.md
vendored
@@ -12,20 +12,27 @@
|
||||
|
||||
#### Please confirm you have done the following before posting your bug report:
|
||||
|
||||
- [ ] I have enabled debug mode
|
||||
- [ ] I have enabled debug mode
|
||||
- [ ] I have read [checked the Common Issues page](https://snipe-it.readme.io/docs/common-issues)
|
||||
|
||||
-----
|
||||
#### Please provide answers to these questions before posting your bug report:
|
||||
#### Provide answers to these questions:
|
||||
|
||||
- Is this a fresh install or an upgrade?
|
||||
- Version of Snipe-IT you're running
|
||||
- Version of PHP you're running
|
||||
- Version of MySQL/MariaDB you're running
|
||||
- What OS and web server you're running Snipe-IT on
|
||||
- What method you used to install Snipe-IT (install.sh, manual installation, docker, etc)
|
||||
- WITH DEBUG TURNED ON, if you're getting an error in your browser, include that error
|
||||
- What specific Snipe-IT page you're on, and what specific element you're interacting with to trigger the error
|
||||
- If a stacktrace is provided in the error, include that too.
|
||||
- Any errors that appear in your browser's error console.
|
||||
- Confirm whether the error is [reproduceable on the demo](https://snipeitapp.com/demo).
|
||||
- Confirm whether the error is reproduceable on the demo: https://snipeitapp.com/demo.
|
||||
- Include any additional information you can find in `app/storage/logs` and your webserver's logs.
|
||||
- Include what you've done so far in the installation, and if you got any error messages along the way.
|
||||
- Indicate whether or not you've manually edited any data directly in the database
|
||||
|
||||
Please do not post an issue without answering the related questions above. If you have opened a different issue and already answered these questions, answer them again, once for every ticket. It will be next to impossible for us to help you.
|
||||
|
||||
https://snipe-it.readme.io/docs/getting-help
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -27,8 +27,16 @@ public/uploads/logo.png
|
||||
public/uploads/logo.svg
|
||||
public/uploads/models/*
|
||||
public/uploads/suppliers/*
|
||||
public/uploads/accessories/*
|
||||
public/uploads/locations/*
|
||||
public/uploads/manufacturers/*
|
||||
public/uploads/components/*
|
||||
public/uploads/consumables/*
|
||||
public/uploads/companies/*
|
||||
public/uploads/categories/*
|
||||
public/uploads/users/*
|
||||
storage/app/private_uploads/users/*
|
||||
public/uploads/departments/*
|
||||
storage/debugbar/
|
||||
storage/dumps/*
|
||||
storage/laravel-backups
|
||||
|
||||
@@ -43,7 +43,7 @@ before_script:
|
||||
# use the $DB env variable to determine the phpunit.xml to use
|
||||
# script: ./vendor/bin/codecept run --env testing-ci
|
||||
script:
|
||||
- ./vendor/bin/codecept run unit --env testing-ci
|
||||
- ./vendor/bin/codecept run unit
|
||||
# - ./vendor/bin/codecept run acceptance --env=testing-ci
|
||||
- ./vendor/bin/codecept run functional --env=functional-travis
|
||||
#script: ./vendor/bin/codecept run
|
||||
|
||||
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
|
||||
reported by contacting the project team at abuse@snipeitapp.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
### Contributing
|
||||
|
||||
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing).
|
||||
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing-overview).
|
||||
|
||||
|
||||
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[](https://travis-ci.org/snipe/snipe-it) [](http://waffle.io/snipe/snipe-it) []() [](https://crowdin.com/project/snipe-it) [](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeyhead) [](https://zenhub.io) [](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||
[](#contributors)
|
||||
[](https://travis-ci.org/snipe/snipe-it) [](http://waffle.io/snipe/snipe-it) []() [](https://crowdin.com/project/snipe-it) [](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://hub.docker.com/r/snipe/snipe-it/) [](https://twitter.com/snipeyhead) [](https://zenhub.io) [](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||
[](#contributors)
|
||||
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
@@ -67,7 +67,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/8341172?v=3" width="110px;"/><br /><sub>Jay Richards</sub>](http://www.cordeos.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=technogenus "Code") | [<img src="https://avatars2.githubusercontent.com/u/7295127?v=3" width="110px;"/><br /><sub>Alexander Innes</sub>](https://necurity.co.uk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=leostat "Code") | [<img src="https://avatars2.githubusercontent.com/u/334485?v=3" width="110px;"/><br /><sub>Danny Garcia</sub>](https://buzzedword.codes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=buzzedword "Code") | [<img src="https://avatars2.githubusercontent.com/u/366855?v=3" width="110px;"/><br /><sub>archpoint</sub>](https://github.com/archpoint)<br />[💻](https://github.com/snipe/snipe-it/commits?author=archpoint "Code") | [<img src="https://avatars1.githubusercontent.com/u/67991?v=3" width="110px;"/><br /><sub>Jake McGraw</sub>](http://www.jakemcgraw.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jakemcgraw "Code") | [<img src="https://avatars1.githubusercontent.com/u/1714374?v=3" width="110px;"/><br /><sub>FleischKarussel</sub>](https://github.com/FleischKarussel)<br />[📖](https://github.com/snipe/snipe-it/commits?author=FleischKarussel "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/319644?v=3" width="110px;"/><br /><sub>Dylan Yi</sub>](https://github.com/feeva)<br />[💻](https://github.com/snipe/snipe-it/commits?author=feeva "Code") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/857740?v=3" width="110px;"/><br /><sub>Gil Rutkowski</sub>](http://FlashingCursor.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=flashingcursor "Code") | [<img src="https://avatars3.githubusercontent.com/u/129360?v=3" width="110px;"/><br /><sub>Desmond Morris</sub>](http://www.desmondmorris.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=desmondmorris "Code") | [<img src="https://avatars2.githubusercontent.com/u/52936?v=3" width="110px;"/><br /><sub>Nick Peelman</sub>](http://peelman.us)<br />[💻](https://github.com/snipe/snipe-it/commits?author=peelman "Code") | [<img src="https://avatars0.githubusercontent.com/u/53161?v=3" width="110px;"/><br /><sub>Abraham Vegh</sub>](https://abrahamvegh.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=abrahamvegh "Code") | [<img src="https://avatars0.githubusercontent.com/u/2818680?v=3" width="110px;"/><br /><sub>Mohamed Rashid</sub>](https://github.com/rashivkp)<br />[📖](https://github.com/snipe/snipe-it/commits?author=rashivkp "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/1509456?v=3" width="110px;"/><br /><sub>Kasey</sub>](http://hinchk.github.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=HinchK "Code") | [<img src="https://avatars2.githubusercontent.com/u/10522541?v=3" width="110px;"/><br /><sub>Brett</sub>](https://github.com/BrettFagerlund)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=BrettFagerlund "Tests") |
|
||||
| [<img src="https://avatars2.githubusercontent.com/u/16108587?v=3" width="110px;"/><br /><sub>Jason Spriggs</sub>](http://jasonspriggs.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jasonspriggs "Code") | [<img src="https://avatars2.githubusercontent.com/u/1134568?v=3" width="110px;"/><br /><sub>Nate Felton</sub>](http://n8felton.wordpress.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=n8felton "Code") | [<img src="https://avatars2.githubusercontent.com/u/14036694?v=3" width="110px;"/><br /><sub>Manasses Ferreira</sub>](http://homepages.dcc.ufmg.br/~manassesferreira)<br />[💻](https://github.com/snipe/snipe-it/commits?author=manassesferreira "Code") | [<img src="https://avatars0.githubusercontent.com/u/15913949?v=3" width="110px;"/><br /><sub>Steve</sub>](https://github.com/steveelwood)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=steveelwood "Tests") | [<img src="https://avatars1.githubusercontent.com/u/3361683?v=3" width="110px;"/><br /><sub>matc</sub>](http://twitter.com/matc)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=matc "Tests") | [<img src="https://avatars3.githubusercontent.com/u/7405702?v=3" width="110px;"/><br /><sub>Cole R. Davis</sub>](http://www.davisracingteam.com)<br />[⚠️](https://github.com/snipe/snipe-it/commits?author=VanillaNinjaD "Tests") | [<img src="https://avatars2.githubusercontent.com/u/10167681?v=3" width="110px;"/><br /><sub>gibsonjoshua55</sub>](https://github.com/gibsonjoshua55)<br />[💻](https://github.com/snipe/snipe-it/commits?author=gibsonjoshua55 "Code") |
|
||||
| [<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://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") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
@@ -76,7 +77,7 @@ This project follows the [all-contributors](https://github.com/kentcdodds/all-co
|
||||
|
||||
### Contributing
|
||||
|
||||
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing).
|
||||
Please see the documentation on [contributing and developing for Snipe-IT](https://snipe-it.readme.io/docs/contributing-overview).
|
||||
|
||||
|
||||
Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
|
||||
|
||||
@@ -16,7 +16,7 @@ class LdapSync extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:ldap-sync {--location=} {--location_id=} {--summary}';
|
||||
protected $signature = 'snipeit:ldap-sync {--location=} {--location_id=} {--summary} {--json_summary}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
@@ -55,27 +55,35 @@ class LdapSync extends Command
|
||||
|
||||
try {
|
||||
$ldapconn = Ldap::connectToLdap();
|
||||
} catch (\Exception $e) {
|
||||
LOG::error($e);
|
||||
}
|
||||
|
||||
try {
|
||||
Ldap::bindAdminToLdap($ldapconn);
|
||||
} catch (\Exception $e) {
|
||||
if ($this->option('json_summary')) {
|
||||
$json_summary = [ "error" => true, "error_message" => $e->getMessage(), "summary" => [] ];
|
||||
$this->info(json_encode($json_summary));
|
||||
}
|
||||
LOG::error($e);
|
||||
return [];
|
||||
}
|
||||
|
||||
$summary = array();
|
||||
|
||||
$results = Ldap::findLdapUsers();
|
||||
|
||||
$ldap_ou_locations = Location::whereNotNull('ldap_ou')->get();
|
||||
|
||||
// Retrieve locations with a mapped OU, and sort them from the shallowest to deepest OU (see #3993)
|
||||
$ldap_ou_locations = Location::where('ldap_ou', '!=', '')->get()->toArray();
|
||||
$ldap_ou_lengths = array();
|
||||
|
||||
foreach ($ldap_ou_locations as $location) {
|
||||
$ldap_ou_lengths[] = strlen($location["ldap_ou"]);
|
||||
}
|
||||
|
||||
array_multisort($ldap_ou_lengths, SORT_ASC, $ldap_ou_locations);
|
||||
|
||||
if (sizeof($ldap_ou_locations) > 0) {
|
||||
LOG::debug('Some locations have special OUs set. Locations will be automatically set for users in those OUs.');
|
||||
}
|
||||
|
||||
$results = Ldap::findLdapUsers();
|
||||
// Inject location information fields
|
||||
for ($i = 0; $i < $results["count"]; $i++) {
|
||||
$results[$i]["ldap_location_override"] = false;
|
||||
$results[$i]["location_id"] = 0;
|
||||
@@ -90,8 +98,8 @@ class LdapSync extends Command
|
||||
LOG::debug('Location ID '.$this->option('location_id').' passed');
|
||||
LOG::debug('Importing to '.$location->name.' ('.$location->id.')');
|
||||
} else {
|
||||
$location = NULL;
|
||||
}
|
||||
$location = NULL;
|
||||
}
|
||||
|
||||
if (!isset($location)) {
|
||||
LOG::debug('That location is invalid or a location was not provided, so no location will be assigned by default.');
|
||||
@@ -99,11 +107,11 @@ class LdapSync extends Command
|
||||
|
||||
// Grab subsets based on location-specific DNs, and overwrite location for these users.
|
||||
foreach ($ldap_ou_locations as $ldap_loc) {
|
||||
$location_users = Ldap::findLdapUsers($ldap_loc->ldap_ou);
|
||||
$location_users = Ldap::findLdapUsers($ldap_loc["ldap_ou"]);
|
||||
$usernames = array();
|
||||
for ($i = 0; $i < $location_users["count"]; $i++) {
|
||||
$location_users[$i]["ldap_location_override"] = true;
|
||||
$location_users[$i]["location_id"] = $ldap_loc->id;
|
||||
$location_users[$i]["location_id"] = $ldap_loc["id"];
|
||||
$usernames[] = $location_users[$i][$ldap_result_username][0];
|
||||
}
|
||||
|
||||
@@ -135,6 +143,14 @@ class LdapSync extends Command
|
||||
$item["ldap_location_override"] = isset($results[$i]["ldap_location_override"]) ? $results[$i]["ldap_location_override"]:"";
|
||||
$item["location_id"] = isset($results[$i]["location_id"]) ? $results[$i]["location_id"]:"";
|
||||
|
||||
if ( array_key_exists('useraccountcontrol', $results[$i]) ) {
|
||||
$enabled_accounts = [
|
||||
'512', '544', '66048', '66080', '262656', '262688', '328192', '328224'
|
||||
];
|
||||
$item['activated'] = ( in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts) ) ? 1 : 0;
|
||||
} else {
|
||||
$item['activated'] = 0;
|
||||
}
|
||||
|
||||
// User exists
|
||||
$item["createorupdate"] = 'updated';
|
||||
@@ -145,14 +161,12 @@ class LdapSync extends Command
|
||||
}
|
||||
|
||||
// Create the user if they don't exist.
|
||||
|
||||
|
||||
$user->first_name = e($item["firstname"]);
|
||||
$user->last_name = e($item["lastname"]);
|
||||
$user->username = e($item["username"]);
|
||||
$user->email = e($item["email"]);
|
||||
$user->employee_num = e($item["employee_number"]);
|
||||
$user->activated = 1;
|
||||
$user->activated = $item['activated'];
|
||||
|
||||
if ($item['ldap_location_override'] == true) {
|
||||
$user->location_id = $item['location_id'];
|
||||
@@ -188,13 +202,12 @@ class LdapSync extends Command
|
||||
} else {
|
||||
$this->info('User '.$summary[$x]['firstname'].' '.$summary[$x]['lastname'].' (username: '.$summary[$x]['username'].' was '.strtoupper($summary[$x]['createorupdate']).'.');
|
||||
}
|
||||
|
||||
}
|
||||
} else if ($this->option('json_summary')) {
|
||||
$json_summary = [ "error" => false, "error_message" => "", "summary" => $summary ];
|
||||
$this->info(json_encode($json_summary));
|
||||
} else {
|
||||
return $summary;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,12 +78,7 @@ class ObjectImportCommand extends Command
|
||||
|
||||
$logFile = $this->option('logfile');
|
||||
\Log::useFiles($logFile);
|
||||
if ($this->option('testrun')) {
|
||||
$this->comment('====== TEST ONLY Item Import for '.$filename.' ====');
|
||||
$this->comment('============== NO DATA WILL BE WRITTEN ==============');
|
||||
} else {
|
||||
$this->comment('======= Importing Items from '.$filename.' =========');
|
||||
}
|
||||
$this->comment('======= Importing Items from '.$filename.' =========');
|
||||
$importer->import();
|
||||
|
||||
$this->bar = null;
|
||||
|
||||
@@ -48,6 +48,7 @@ class RecryptFromMcrypt extends Command
|
||||
// If not, we can try to use the current APP_KEY if looks like it's old
|
||||
$legacy_key = env('LEGACY_APP_KEY');
|
||||
$key_parts = explode(':', $legacy_key);
|
||||
$legacy_cipher = env('LEGACY_CIPHER');
|
||||
$errors = array();
|
||||
|
||||
if (!$legacy_key) {
|
||||
@@ -60,6 +61,7 @@ class RecryptFromMcrypt extends Command
|
||||
if (strlen($legacy_key) == 32) {
|
||||
$legacy_length_check = true;
|
||||
} elseif (array_key_exists('1', $key_parts) && (strlen($key_parts[1])==44)) {
|
||||
$legacy_key = base64_decode($key_parts[1],true);
|
||||
$legacy_length_check = true;
|
||||
} else {
|
||||
$legacy_length_check = false;
|
||||
@@ -91,13 +93,21 @@ class RecryptFromMcrypt extends Command
|
||||
}
|
||||
|
||||
|
||||
$mcrypter = new McryptEncrypter($legacy_key);
|
||||
if ($legacy_cipher){
|
||||
$mcrypter = new McryptEncrypter($legacy_key,$legacy_cipher);
|
||||
}else{
|
||||
$mcrypter = new McryptEncrypter($legacy_key);
|
||||
}
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
if ($settings->ldap_password=='') {
|
||||
if ($settings->ldap_pword=='') {
|
||||
$this->comment('INFO: No LDAP password found. Skipping... ');
|
||||
} else {
|
||||
$decrypted_ldap_pword = $mcrypter->decrypt($settings->ldap_pword);
|
||||
$settings->ldap_pword = \Crypt::encrypt($decrypted_ldap_pword);
|
||||
$settings->save();
|
||||
}
|
||||
|
||||
/** @var CustomField[] $custom_fields */
|
||||
$custom_fields = CustomField::where('field_encrypted','=', 1)->get();
|
||||
$this->comment('INFO: Retrieving encrypted custom fields...');
|
||||
|
||||
@@ -110,32 +120,22 @@ class RecryptFromMcrypt extends Command
|
||||
|
||||
|
||||
// Get all assets with a value in any of the fields that were encrypted
|
||||
/** @var Asset[] $assets */
|
||||
$assets = $query->get();
|
||||
|
||||
$bar = $this->output->createProgressBar(count($assets));
|
||||
|
||||
foreach ($custom_fields as $encrypted_field) {
|
||||
|
||||
// Try to decrypt the payload using the legacy app key
|
||||
try {
|
||||
$decrypted_field = $mcrypter->decrypt($encrypted_field);
|
||||
$this->comment($decrypted_field);
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = ' - ERROR: Could not decrypt field ['.$encrypted_field->name.']: '.$e->getMessage();
|
||||
}
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
foreach ($custom_fields as $encrypted_field) {
|
||||
$columnName = $encrypted_field->db_column;
|
||||
|
||||
// Make sure the value isn't null
|
||||
if ($asset->{$encrypted_field}!='') {
|
||||
if ($asset->{$columnName}!='') {
|
||||
// Try to decrypt the payload using the legacy app key
|
||||
try {
|
||||
$decrypted_field = $mcrypter->decrypt($asset->{$encrypted_field});
|
||||
$asset->{$encrypted_field} = \Crypt::encrypt($decrypted_field);
|
||||
$decrypted_field = $mcrypter->decrypt($asset->{$columnName});
|
||||
$asset->{$columnName} = \Crypt::encrypt($decrypted_field);
|
||||
$this->comment($decrypted_field);
|
||||
} catch (\Exception $e) {
|
||||
$errors[] = ' - ERROR: Could not decrypt field ['.$encrypted_field->name.']: '.$e->getMessage();
|
||||
|
||||
75
app/Console/Commands/ResetDemoSettings.php
Normal file
75
app/Console/Commands/ResetDemoSettings.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
|
||||
class ResetDemoSettings extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:demo-settings';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This will reset the Snipe-IT demo settings back to default. ';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$this->info('Resetting the demo settings.');
|
||||
$settings = Setting::first();
|
||||
$settings->per_page = 20;
|
||||
$settings->site_name = 'Snipe-IT Asset Management Demo';
|
||||
$settings->auto_increment_assets = 1;
|
||||
$settings->logo = 'snipe-logo.png';
|
||||
$settings->alert_email = 'service@snipe-it.io';
|
||||
$settings->header_color = null;
|
||||
$settings->barcode_type = 'QRCODE';
|
||||
$settings->default_currency = 'USD';
|
||||
$settings->brand = 3;
|
||||
$settings->ldap_enabled = 0;
|
||||
$settings->full_multiple_companies_support = 1;
|
||||
$settings->alt_barcode = 'C128';
|
||||
$settings->email_domain = 'snipeitapp.com';
|
||||
$settings->email_format = 'filastname';
|
||||
$settings->username_format = 'filastname';
|
||||
$settings->date_display_format = 'D M d, Y';
|
||||
$settings->time_display_format = 'g:iA';
|
||||
$settings->thumbnail_max_h = '30';
|
||||
$settings->locale = 'en';
|
||||
$settings->save();
|
||||
|
||||
if ($user = User::where('username', '=', 'admin')->first()) {
|
||||
$user->locale = 'en';
|
||||
$user->save();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,8 @@ class Kernel extends ConsoleKernel
|
||||
Commands\Purge::class,
|
||||
Commands\LdapSync::class,
|
||||
Commands\FixDoubleEscape::class,
|
||||
Commands\RecryptFromMcrypt::class
|
||||
Commands\RecryptFromMcrypt::class,
|
||||
Commands\ResetDemoSettings::class
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -39,7 +40,7 @@ class Kernel extends ConsoleKernel
|
||||
|
||||
$schedule->command('snipeit:inventory-alerts')->daily();
|
||||
$schedule->command('snipeit:expiring-alerts')->daily();
|
||||
$schedule->command('snipeit:expected-checkins')->daily();
|
||||
$schedule->command('snipeit:expected-checkin')->daily();
|
||||
$schedule->command('snipeit:backup')->weekly();
|
||||
$schedule->command('backup:clean')->daily();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ class CheckoutNotAllowed extends Exception
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
"A checkout is not allowed under these circumstances";
|
||||
return "A checkout is not allowed under these circumstances";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use Illuminate\Auth\AuthenticationException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Log;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
@@ -34,7 +35,10 @@ class Handler extends ExceptionHandler
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
{
|
||||
parent::report($exception);
|
||||
if ($this->shouldReport($exception)) {
|
||||
Log::error($exception);
|
||||
return parent::report($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +67,7 @@ class Handler extends ExceptionHandler
|
||||
}
|
||||
|
||||
if ($e instanceof \Illuminate\Validation\ValidationException) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $e->response['messages'], $e->getMessage(), 400));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $e->response['messages'], 400));
|
||||
}
|
||||
|
||||
if ($this->isHttpException($e)) {
|
||||
|
||||
@@ -18,6 +18,8 @@ use Illuminate\Http\Request;
|
||||
use Slack;
|
||||
use Str;
|
||||
use View;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
/** This controller handles all actions related to Accessories for
|
||||
* the Snipe-IT Asset Management application.
|
||||
@@ -52,13 +54,9 @@ class AccessoriesController extends Controller
|
||||
public function create(Request $request)
|
||||
{
|
||||
$this->authorize('create', Accessory::class);
|
||||
// Show the page
|
||||
return view('accessories/edit')
|
||||
->with('item', new Accessory)
|
||||
->with('category_list', Helper::categoryList('accessory'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
$category_type = 'accessory';
|
||||
return view('accessories/edit')->with('category_type', $category_type)
|
||||
->with('item', new Accessory);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +66,7 @@ class AccessoriesController extends Controller
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize(Accessory::class);
|
||||
// create a new model instance
|
||||
@@ -87,6 +85,28 @@ class AccessoriesController extends Controller
|
||||
$accessory->purchase_cost = Helper::ParseFloat(request('purchase_cost'));
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->user_id = Auth::user()->id;
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
|
||||
if ($request->hasFile('image')) {
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
$image = $request->file('image');
|
||||
$ext = $image->getClientOriginalExtension();
|
||||
$file_name = "accessory-".str_random(18).'.'.$ext;
|
||||
$path = public_path('/uploads/accessories');
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(null, 250, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
$accessory->image = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Was the accessory created?
|
||||
if ($accessory->save()) {
|
||||
@@ -105,18 +125,15 @@ class AccessoriesController extends Controller
|
||||
*/
|
||||
public function edit(Request $request, $accessoryId = null)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($item = Accessory::find($accessoryId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
|
||||
if ($item = Accessory::find($accessoryId)) {
|
||||
$this->authorize($item);
|
||||
$category_type = 'accessory';
|
||||
return view('accessories/edit', compact('item'))->with('category_type', $category_type);
|
||||
}
|
||||
|
||||
$this->authorize($item);
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
|
||||
return view('accessories/edit', compact('item'))
|
||||
->with('category_list', Helper::categoryList('accessory'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +144,7 @@ class AccessoriesController extends Controller
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
*/
|
||||
public function update(Request $request, $accessoryId = null)
|
||||
public function update(ImageUploadRequest $request, $accessoryId = null)
|
||||
{
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
@@ -144,11 +161,38 @@ class AccessoriesController extends Controller
|
||||
$accessory->manufacturer_id = request('manufacturer_id');
|
||||
$accessory->order_number = request('order_number');
|
||||
$accessory->model_number = request('model_number');
|
||||
$accessory->purchase_date = request('purchase_date');
|
||||
$accessory->purchase_cost = request('purchase_cost');
|
||||
$accessory->purchase_date = request('purchase_date');
|
||||
$accessory->purchase_cost = request('purchase_cost');
|
||||
$accessory->qty = request('qty');
|
||||
$accessory->supplier_id = request('supplier_id');
|
||||
|
||||
// Was the accessory updated?
|
||||
if ($request->hasFile('image')) {
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
|
||||
|
||||
$image = $request->file('image');
|
||||
$ext = $image->getClientOriginalExtension();
|
||||
$file_name = "accessory-".str_random(18).'.'.$ext;
|
||||
$path = public_path('/uploads/accessories');
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(null, 250, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
if (($accessory->image) && (file_exists($path.'/'.$accessory->image))) {
|
||||
unlink($path.'/'.$accessory->image);
|
||||
}
|
||||
|
||||
$accessory->image = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Was the accessory updated?
|
||||
if ($accessory->save()) {
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
|
||||
}
|
||||
@@ -197,11 +241,7 @@ class AccessoriesController extends Controller
|
||||
if (isset($accessory->id)) {
|
||||
return view('accessories/view', compact('accessory'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/accessories/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('accessories')->with('error', $error);
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +262,7 @@ class AccessoriesController extends Controller
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return view('accessories/checkout', compact('accessory'))->with('users_list', Helper::usersList());
|
||||
return view('accessories/checkout', compact('accessory'));
|
||||
|
||||
}
|
||||
|
||||
@@ -247,7 +287,7 @@ class AccessoriesController extends Controller
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
if (!$user = User::find(Input::get('assigned_to'))) {
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
return redirect()->route('checkout/accessory', $accessory->id)->with('error', trans('admin/accessories/message.checkout.user_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the accessory data
|
||||
@@ -274,7 +314,8 @@ class AccessoriesController extends Controller
|
||||
$data['note'] = $logaction->note;
|
||||
$data['require_acceptance'] = $accessory->requireAcceptance();
|
||||
// TODO: Port this to new mail notifications
|
||||
if (($accessory->requireAcceptance()=='1') || ($accessory->getEula())) {
|
||||
|
||||
if ((($accessory->requireAcceptance()=='1') || ($accessory->getEula())) && ($user->email!='')) {
|
||||
|
||||
Mail::send('emails.accept-accessory', $data, function ($m) use ($user) {
|
||||
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
|
||||
@@ -351,7 +392,7 @@ class AccessoriesController extends Controller
|
||||
$data['item_tag'] = '';
|
||||
$data['note'] = e($logaction->note);
|
||||
|
||||
if (($accessory->checkin_email()=='1')) {
|
||||
if ((($accessory->checkin_email()=='1')) && ($user->email!='')) {
|
||||
|
||||
Mail::send('emails.checkin-asset', $data, function ($m) use ($user) {
|
||||
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
|
||||
@@ -369,143 +410,5 @@ class AccessoriesController extends Controller
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.checkin.error'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the JSON response for accessories listing view.
|
||||
*
|
||||
* Example:
|
||||
* {
|
||||
* "actions": "(links to available actions)",
|
||||
* "category": "(link to category)",
|
||||
* "company": "My Company",
|
||||
* "location": "My Location",
|
||||
* "min_amt": 2,
|
||||
* "name": "(link to accessory),
|
||||
* "numRemaining": 6,
|
||||
* "order_number": null,
|
||||
* "purchase_cost": "0.00",
|
||||
* "purchase_date": null,
|
||||
* "qty": 7
|
||||
* },
|
||||
*
|
||||
* The names of the fields in the returns JSON correspond directly to the the
|
||||
* names of the fields in the bootstrap-tables in the view.
|
||||
*
|
||||
* For debugging, see at /api/accessories/list
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param Request $request
|
||||
* @return string JSON containing accessories and their associated atrributes.
|
||||
* @internal param int $accessoryId
|
||||
*/
|
||||
public function getDatatable(Request $request)
|
||||
{
|
||||
$this->authorize('index', Accessory::class);
|
||||
$accessories = Company::scopeCompanyables(
|
||||
Accessory::select('accessories.*')
|
||||
->whereNull('accessories.deleted_at')
|
||||
->with('category', 'company', 'manufacturer', 'users', 'location')
|
||||
);
|
||||
if (Input::has('search')) {
|
||||
$accessories = $accessories->TextSearch(e(Input::get('search')));
|
||||
}
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$allowed_columns = ['name','min_amt','order_number','purchase_date','purchase_cost','company','category','model_number', 'manufacturer', 'location'];
|
||||
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
|
||||
|
||||
switch ($sort) {
|
||||
case 'category':
|
||||
$accessories = $accessories->OrderCategory($order);
|
||||
break;
|
||||
case 'company':
|
||||
$accessories = $accessories->OrderCompany($order);
|
||||
break;
|
||||
case 'location':
|
||||
$accessories = $accessories->OrderLocation($order);
|
||||
break;
|
||||
case 'manufacturer':
|
||||
$accessories = $accessories->OrderManufacturer($order);
|
||||
break;
|
||||
default:
|
||||
$accessories = $accessories->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
$accessCount = $accessories->count();
|
||||
$accessories = $accessories->skip($offset)->take($limit)->get();
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($accessories as $accessory) {
|
||||
$rows[] = $accessory->present()->forDataTable();
|
||||
}
|
||||
|
||||
$data = array('total'=>$accessCount, 'rows'=>$rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the JSON response for accessory detail view.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* {
|
||||
* "rows": [
|
||||
* {
|
||||
* "actions": "(link to available actions)",
|
||||
* "name": "(link to user)"
|
||||
* }
|
||||
* ],
|
||||
* "total": 1
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* The names of the fields in the returns JSON correspond directly to the the
|
||||
* names of the fields in the bootstrap-tables in the view.
|
||||
*
|
||||
* For debugging, see at /api/accessories/$accessoryID/view
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $accessoryId
|
||||
* @return string JSON containing accessories and their associated atrributes.
|
||||
**/
|
||||
public function getDataView(Request $request, $accessoryID)
|
||||
{
|
||||
$accessory = Accessory::find($accessoryID);
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($accessory)) {
|
||||
return ['total' => 0, 'rows' => []];
|
||||
}
|
||||
|
||||
$accessory_users = $accessory->users;
|
||||
$count = $accessory_users->count();
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($accessory_users as $user) {
|
||||
$actions = '';
|
||||
if (Gate::allows('checkin', $accessory)) {
|
||||
$actions .= Helper::generateDatatableButton('checkin', route('checkin/accessory', $user->pivot->id));
|
||||
}
|
||||
|
||||
if (Gate::allows('view', $user)) {
|
||||
$name = (string) link_to_route('users.show', e($user->present()->fullName()), [$user->id]);
|
||||
} else {
|
||||
$name = e($user->present()->fullName());
|
||||
}
|
||||
|
||||
$rows[] = array(
|
||||
'name' => $name,
|
||||
'actions' => $actions
|
||||
);
|
||||
}
|
||||
|
||||
$data = array('total'=>$count, 'rows'=>$rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Accessory;
|
||||
use App\Http\Transformers\AccessoriesTransformer;
|
||||
use App\Models\Company;
|
||||
|
||||
|
||||
class AccessoriesController extends Controller
|
||||
@@ -37,6 +38,10 @@ class AccessoriesController extends Controller
|
||||
$accessories->where('manufacturer_id','=',$request->input('manufacturer_id'));
|
||||
}
|
||||
|
||||
if ($request->has('supplier_id')) {
|
||||
$accessories->where('supplier_id','=',$request->input('supplier_id'));
|
||||
}
|
||||
|
||||
$offset = $request->input('offset', 0);
|
||||
$limit = $request->input('limit', 50);
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
@@ -95,8 +100,6 @@ class AccessoriesController extends Controller
|
||||
{
|
||||
$this->authorize('view', Accessory::class);
|
||||
$accessory = Accessory::findOrFail($id);
|
||||
$accessory_users = $accessory->users;
|
||||
|
||||
return (new AccessoriesTransformer)->transformAccessory($accessory);
|
||||
}
|
||||
|
||||
@@ -128,10 +131,15 @@ class AccessoriesController extends Controller
|
||||
public function checkedout($id)
|
||||
{
|
||||
$this->authorize('view', Accessory::class);
|
||||
$accessory = Accessory::findOrFail($id)->with('users')->first();
|
||||
$accessories_users = $accessory->users;
|
||||
$total = $accessories_users->count();
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessories($accessories_users, $total);
|
||||
|
||||
$accessory = Accessory::findOrFail($id);
|
||||
if (!Company::isCurrentUserHasAccess($accessory)) {
|
||||
return ['total' => 0, 'rows' => []];
|
||||
}
|
||||
$accessory_users = $accessory->users;
|
||||
$total = $accessory_users->count();
|
||||
|
||||
return (new AccessoriesTransformer)->transformCheckedoutAccessory($accessory_users, $total);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Helpers\Helper;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Transformers\AssetModelsTransformer;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
|
||||
/**
|
||||
@@ -31,7 +32,7 @@ class AssetModelsController extends Controller
|
||||
$this->authorize('view', AssetModel::class);
|
||||
$allowed_columns = ['id','image','name','model_number','eol','notes','created_at','manufacturer'];
|
||||
|
||||
$assetmodels = AssetModel::select(['models.id','models.image','models.name','model_number','eol','models.notes','models.created_at','category_id','manufacturer_id','depreciation_id','fieldset_id'])
|
||||
$assetmodels = AssetModel::select(['models.id','models.image','models.name','model_number','eol','models.notes','models.created_at','category_id','manufacturer_id','depreciation_id','fieldset_id', 'models.deleted_at'])
|
||||
->with('category','depreciation', 'manufacturer','fieldset')
|
||||
->withCount('assets');
|
||||
|
||||
@@ -39,6 +40,10 @@ class AssetModelsController extends Controller
|
||||
$assetmodels->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
if ($request->has('status')) {
|
||||
$assetmodels->onlyTrashed();
|
||||
}
|
||||
|
||||
|
||||
$offset = $request->input('offset', 0);
|
||||
$limit = $request->input('limit', 50);
|
||||
@@ -154,8 +159,51 @@ class AssetModelsController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/models/message.assoc_users')));
|
||||
}
|
||||
|
||||
if ($assetmodel->image) {
|
||||
try {
|
||||
unlink(public_path().'/uploads/models/'.$assetmodel->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
$assetmodel->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/assetmodels/message.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', AssetModel::class);
|
||||
|
||||
$assetmodels = AssetModel::select([
|
||||
'models.id',
|
||||
'models.name',
|
||||
'models.image',
|
||||
'models.model_number',
|
||||
]);
|
||||
|
||||
|
||||
if ($request->has('search')) {
|
||||
$assetmodels = $assetmodels->where('models.name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('models.model_number', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
$assetmodels = $assetmodels->paginate(50);
|
||||
|
||||
foreach ($assetmodels as $assetmodel) {
|
||||
$assetmodel->use_text = $assetmodel->present()->modelName;
|
||||
$assetmodel->use_image = ($assetmodel->image) ? url('/').'/uploads/models/'.$assetmodel->image : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($assetmodels);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ use Str;
|
||||
use TCPDF;
|
||||
use Validator;
|
||||
use View;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
|
||||
/**
|
||||
@@ -84,21 +85,21 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
$assets = Company::scopeCompanyables(Asset::select('assets.*'))->with(
|
||||
'assetloc', 'assetstatus', 'defaultLoc', 'assetlog', 'company',
|
||||
'location', 'assetstatus', 'assetlog', 'company', 'defaultLoc','assignedTo',
|
||||
'model.category', 'model.manufacturer', 'model.fieldset','supplier');
|
||||
// If we should search on everything
|
||||
if (($request->has('search')) && (count($filter) == 0)) {
|
||||
|
||||
|
||||
if (count($filter) > 0) {
|
||||
$assets->ByFilter($filter);
|
||||
} elseif ($request->has('search')) {
|
||||
$assets->TextSearch($request->input('search'));
|
||||
// otherwise loop through the filters and search strictly on them
|
||||
} else {
|
||||
if (count($filter) > 0) {
|
||||
$assets->ByFilter($filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// These are used by the API to query against specific ID numbers
|
||||
if ($request->has('status_id')) {
|
||||
$assets->where('status_id', '=', $request->input('status_id'));
|
||||
$assets->where('assets.status_id', '=', $request->input('status_id'));
|
||||
}
|
||||
|
||||
if ($request->has('model_id')) {
|
||||
@@ -125,7 +126,11 @@ class AssetsController extends Controller
|
||||
$assets->ByManufacturer($request->input('manufacturer_id'));
|
||||
}
|
||||
|
||||
$request->has('order_number') ? $assets = $assets->where('order_number', '=', e($request->get('order_number'))) : '';
|
||||
if ($request->has('depreciation_id')) {
|
||||
$assets->ByDepreciationId($request->input('depreciation_id'));
|
||||
}
|
||||
|
||||
$request->has('order_number') ? $assets = $assets->where('assets.order_number', '=', e($request->get('order_number'))) : '';
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = $request->input('limit', 50);
|
||||
@@ -133,36 +138,76 @@ class AssetsController extends Controller
|
||||
|
||||
|
||||
// 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->withTrashed()->Deleted();
|
||||
break;
|
||||
case 'Pending':
|
||||
$assets->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->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->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->RequestableAssets();
|
||||
$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':
|
||||
$assets->Deployed();
|
||||
// more sad, horrible workarounds for laravel bugs when doing full text searches
|
||||
$assets->where('assets.assigned_to', '>', '0');
|
||||
break;
|
||||
default:
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 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.
|
||||
$sort_override = str_replace('custom_fields.','', $request->input('sort')) ;
|
||||
|
||||
// This handles all of the pivot sorting (versus the assets.* fields in the allowed_columns array)
|
||||
$column_sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets.created_at';
|
||||
|
||||
switch ($request->input('sort')) {
|
||||
// This handles all of the pivot sorting (versus the assets.* fields
|
||||
// in the allowed_columns array)
|
||||
$column_sort = in_array($sort_override, $allowed_columns) ? $sort_override : 'assets.created_at';
|
||||
|
||||
|
||||
switch ($sort_override) {
|
||||
case 'model':
|
||||
$assets->OrderModels($order);
|
||||
break;
|
||||
@@ -211,12 +256,54 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
if ($asset = Asset::withTrashed()->find($id)) {
|
||||
if ($asset = Asset::with('assetstatus')->with('assignedTo')->withTrashed()->findOrFail($id)) {
|
||||
$this->authorize('view', $asset);
|
||||
return (new AssetsTransformer)->transformAsset($asset);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 200);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Asset::class);
|
||||
|
||||
$assets = Company::scopeCompanyables(Asset::select([
|
||||
'assets.id',
|
||||
'assets.name',
|
||||
'assets.asset_tag',
|
||||
'assets.model_id',
|
||||
]))->with('model')->RTD();
|
||||
|
||||
|
||||
if ($request->has('search')) {
|
||||
$assets = $assets->where('assets.name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('assets.asset_tag', 'LIKE', '%'.$request->get('search').'%')
|
||||
->join('models AS assets_models',function ($join) use ($request) {
|
||||
$join->on('assets_models.id', "=", "assets.model_id");
|
||||
})->orWhere('assets_models.name','LIKE','%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$assets = $assets->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 ($assets as $asset) {
|
||||
$asset->use_text = $asset->present()->fullName;
|
||||
$asset->use_image = ($asset->getImageUrl()) ? $asset->getImageUrl() : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($assets);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -413,23 +500,47 @@ class AssetsController extends Controller
|
||||
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
$error_payload = [];
|
||||
$error_payload['asset'] = [
|
||||
'id' => $asset->id,
|
||||
'asset_tag' => $asset->asset_tag,
|
||||
];
|
||||
if ($request->has('user_id')) {
|
||||
$target = User::find($request->input('user_id'));
|
||||
$error_payload['target_id'] = $request->input('user_id');
|
||||
$error_payload['target_type'] = User::class;
|
||||
// Don't let the user check an asset out to itself
|
||||
} elseif ($request->has('asset_id')) {
|
||||
$target = Asset::find($request->input('asset_id'));
|
||||
$target = Asset::where('id','!=',$asset_id)->find($request->input('asset_id'));
|
||||
$error_payload['target_id'] = $request->input('asset_id');
|
||||
$error_payload['target_type'] = Asset::class;
|
||||
} elseif ($request->has('location_id')) {
|
||||
$target = Location::find($request->input('location_id'));
|
||||
$error_payload['target_id'] = $request->input('location_id');
|
||||
$error_payload['target_type'] = Location::class;
|
||||
}
|
||||
|
||||
if (!isset($target)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', ['asset'=> e($asset->asset_tag)], 'No valid checkout target specified for asset '.e($asset->asset_tag).'.'));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', $error_payload, 'No valid checkout target specified for asset '.e($asset->asset_tag).'.'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
$checkout_at = request('checkout_at', date("Y-m-d H:i:s"));
|
||||
$expected_checkin = request('expected_checkin', null);
|
||||
$note = request('note', null);
|
||||
$asset_name = request('name', null);
|
||||
|
||||
// Set the location ID to the RTD location id if there is one
|
||||
if ($asset->rtd_location_id!='') {
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
}
|
||||
|
||||
// Overwrite that if the target has a location ID though
|
||||
if ($target->location_id!='') {
|
||||
$asset->location_id = $target->location_id;
|
||||
}
|
||||
|
||||
|
||||
if ($asset->checkOut($target, Auth::user(), $checkout_at, $expected_checkin, $note, $asset_name)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkout.success')));
|
||||
@@ -481,6 +592,9 @@ class AssetsController extends Controller
|
||||
$data['item_tag'] = $asset->asset_tag;
|
||||
$data['item_serial'] = $asset->serial;
|
||||
$data['note'] = $logaction->note;
|
||||
$data['manufacturer_name'] = $asset->model->manufacturer->name;
|
||||
$data['model_name'] = $asset->model->name;
|
||||
$data['model_number'] = $asset->model->model_number;
|
||||
|
||||
if ((($asset->checkin_email()=='1')) && (isset($user)) && (!config('app.lock_passwords'))) {
|
||||
Mail::send('emails.checkin-asset', $data, function ($m) use ($user) {
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Category;
|
||||
use App\Http\Transformers\CategoriesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
class CategoriesController extends Controller
|
||||
{
|
||||
@@ -20,9 +21,9 @@ class CategoriesController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$allowed_columns = ['id', 'name','category_type','use_default_eula','require_acceptance','checkin_email'];
|
||||
$allowed_columns = ['id', 'name','category_type','use_default_eula','eula_text', 'require_acceptance','checkin_email', 'assets_count', 'accessories_count', 'consumables_count', 'components_count', 'image'];
|
||||
|
||||
$categories = Category::select(['id', 'created_at', 'updated_at', 'name','category_type','use_default_eula','require_acceptance','checkin_email'])
|
||||
$categories = Category::select(['id', 'created_at', 'updated_at', 'name','category_type','use_default_eula','eula_text', 'require_acceptance','checkin_email','image'])
|
||||
->withCount('assets', 'accessories', 'consumables', 'components');
|
||||
|
||||
if ($request->has('search')) {
|
||||
@@ -32,7 +33,7 @@ class CategoriesController extends Controller
|
||||
$offset = $request->input('offset', 0);
|
||||
$limit = $request->input('limit', 50);
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets_count';
|
||||
$categories->orderBy($sort, $order);
|
||||
|
||||
$total = $categories->count();
|
||||
@@ -128,4 +129,41 @@ class CategoriesController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/categories/message.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request, $category_type = 'asset')
|
||||
{
|
||||
$this->authorize('view', Categories::class);
|
||||
|
||||
$categories = Category::select([
|
||||
'id',
|
||||
'name',
|
||||
'image',
|
||||
]);
|
||||
|
||||
if ($request->has('search')) {
|
||||
$categories = $categories->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$categories = $categories->where('category_type', $category_type)->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 ($categories as $category) {
|
||||
$category->use_image = ($category->image) ? url('/').'/uploads/categories/'.$category->image : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($categories);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Company;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
class CompaniesController extends Controller
|
||||
{
|
||||
@@ -141,4 +142,38 @@ class CompaniesController extends Controller
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Company::class);
|
||||
|
||||
$companies = Company::select([
|
||||
'companies.id',
|
||||
'companies.name',
|
||||
'companies.image',
|
||||
]);
|
||||
|
||||
if ($request->has('search')) {
|
||||
$companies = $companies->where('companies.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$companies = $companies->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 ($companies as $company) {
|
||||
$company->use_image = ($company->image) ? url('/').'/uploads/companies/'.$company->image : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($companies);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class ComponentsController extends Controller
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$allowed_columns = ['id','name','min_amt','order_number','serial','purchase_date','purchase_cost','company','category','qty','location'];
|
||||
$allowed_columns = ['id','name','min_amt','order_number','serial','purchase_date','purchase_cost','company','category','qty','location','image'];
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
|
||||
@@ -158,6 +158,6 @@ class ComponentsController extends Controller
|
||||
$limit = $request->input('limit', 50);
|
||||
$total = $assets->count();
|
||||
$assets = $assets->skip($offset)->take($limit)->get();
|
||||
return (new ComponentsAssetsTransformer)->transformAssets($assets, $total);
|
||||
return (new ComponentsTransformer)->transformCheckedoutComponents($assets, $total);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class ConsumablesController extends Controller
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
$allowed_columns = ['id','name','order_number','min_amt','purchase_date','purchase_cost','company','category','model_number', 'item_no', 'manufacturer','location','qty'];
|
||||
$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';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
|
||||
|
||||
@@ -57,15 +57,15 @@ class CustomFieldsController extends Controller
|
||||
*/
|
||||
public function destroy($field_id)
|
||||
{
|
||||
$field = CustomField::find($field_id);
|
||||
$field = CustomField::findOrFail($field_id);
|
||||
|
||||
if ($field->fieldset->count() >0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Field is in use.'));
|
||||
} else {
|
||||
$field->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/custom_fields/message.field.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
$field->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/custom_fields/message.field.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Models\Department;
|
||||
use App\Http\Transformers\DepartmentsTransformer;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
class DepartmentsController extends Controller
|
||||
{
|
||||
@@ -21,7 +22,7 @@ class DepartmentsController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Department::class);
|
||||
$allowed_columns = ['id','name'];
|
||||
$allowed_columns = ['id','name','image'];
|
||||
|
||||
$departments = Department::select([
|
||||
'id',
|
||||
@@ -30,7 +31,8 @@ class DepartmentsController extends Controller
|
||||
'company_id',
|
||||
'manager_id',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
'updated_at',
|
||||
'image'
|
||||
])->with('users')->with('location')->with('manager')->with('company')->withCount('users');
|
||||
|
||||
if ($request->has('search')) {
|
||||
@@ -110,4 +112,39 @@ class DepartmentsController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Department::class);
|
||||
|
||||
$departments = Department::select([
|
||||
'id',
|
||||
'name',
|
||||
'image',
|
||||
]);
|
||||
|
||||
if ($request->has('search')) {
|
||||
$departments = $departments->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$departments = $departments->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 ($departments as $department) {
|
||||
$department->use_image = ($department->image) ? url('/').'/uploads/departments/'.$department->image : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($departments);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ class GroupsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Group::class);
|
||||
$group = Group::findOrFail($id);
|
||||
return $group;
|
||||
return (new GroupsTransformer)->transformGroup($group);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Location;
|
||||
use App\Http\Transformers\LocationsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
class LocationsController extends Controller
|
||||
{
|
||||
@@ -21,9 +22,9 @@ class LocationsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
$allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at',
|
||||
'updated_at','parent_id', 'manager_id'];
|
||||
'updated_at','parent_id', 'manager_id','image'];
|
||||
|
||||
$locations = Location::select([
|
||||
$locations = Location::with('parent', 'manager', 'childLocations')->select([
|
||||
'locations.id',
|
||||
'locations.name',
|
||||
'locations.address',
|
||||
@@ -36,8 +37,12 @@ class LocationsController extends Controller
|
||||
'locations.manager_id',
|
||||
'locations.created_at',
|
||||
'locations.updated_at',
|
||||
'locations.image',
|
||||
'locations.currency'
|
||||
])->withCount('assets')->withCount('users');
|
||||
])->withCount('locationAssets')
|
||||
->withCount('assignedAssets')
|
||||
->withCount('assets')
|
||||
->withCount('users');
|
||||
|
||||
if ($request->has('search')) {
|
||||
$locations = $locations->TextSearch($request->input('search'));
|
||||
@@ -52,7 +57,6 @@ class LocationsController extends Controller
|
||||
$total = $locations->count();
|
||||
$locations = $locations->skip($offset)->take($limit)->get();
|
||||
return (new LocationsTransformer)->transformLocations($locations, $total);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +78,6 @@ class LocationsController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.create.success')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +112,13 @@ class LocationsController extends Controller
|
||||
$location->fill($request->all());
|
||||
|
||||
if ($location->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new LocationsTransformer)->transformLocation($location), trans('admin/locations/message.update.success')));
|
||||
return response()->json(
|
||||
Helper::formatStandardApiResponse(
|
||||
'success',
|
||||
(new LocationsTransformer)->transformLocation($location),
|
||||
trans('admin/locations/message.update.success')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $location->getErrors()));
|
||||
@@ -129,7 +138,43 @@ class LocationsController extends Controller
|
||||
$location = Location::findOrFail($id);
|
||||
$this->authorize('delete', $location);
|
||||
$location->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/locations/message.delete.success')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
|
||||
$locations = Location::select([
|
||||
'locations.id',
|
||||
'locations.name',
|
||||
'locations.image',
|
||||
]);
|
||||
|
||||
if ($request->has('search')) {
|
||||
$locations = $locations->where('locations.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$locations = $locations->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 ($locations as $location) {
|
||||
$location->use_text = $location->name;
|
||||
$location->use_image = ($location->image) ? url('/').'/uploads/locations/'.$location->image : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($locations);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use App\Helpers\Helper;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Http\Transformers\DatatablesTransformer;
|
||||
use App\Http\Transformers\ManufacturersTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
class ManufacturersController extends Controller
|
||||
{
|
||||
@@ -21,10 +22,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'];
|
||||
$allowed_columns = ['id','name','url','support_url','support_email','support_phone','created_at','updated_at','image'];
|
||||
|
||||
$manufacturers = Manufacturer::select(
|
||||
array('id','name','url','support_url','support_email','support_phone','created_at','updated_at')
|
||||
array('id','name','url','support_url','support_email','support_phone','created_at','updated_at','image')
|
||||
)->withCount('assets')->withCount('licenses')->withCount('consumables')->withCount('accessories');
|
||||
|
||||
|
||||
@@ -120,4 +121,40 @@ class ManufacturersController extends Controller
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/manufacturers/message.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Manufacturers::class);
|
||||
|
||||
$manufacturers = Manufacturer::select([
|
||||
'id',
|
||||
'name',
|
||||
'image',
|
||||
]);
|
||||
|
||||
if ($request->has('search')) {
|
||||
$manufacturers = $manufacturers->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$manufacturers = $manufacturers->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 ($manufacturers as $manufacturer) {
|
||||
$manufacturer->use_text = $manufacturer->name;
|
||||
$manufacturer->use_image = ($manufacturer->image) ? url('/').'/uploads/manufacturers/'.$manufacturer->image : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($manufacturers);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,78 +5,22 @@ namespace App\Http\Controllers\Api;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Ldap;
|
||||
use Validator;
|
||||
use App\Models\Setting;
|
||||
use Mail;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
|
||||
|
||||
public function ldaptest()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
if (Setting::getSettings()->ldap_enabled!='1') {
|
||||
\Log::debug('LDAP is not enabled cannot test.');
|
||||
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function getLdapTest()
|
||||
{
|
||||
\Log::debug('Preparing to test LDAP connection');
|
||||
|
||||
try {
|
||||
@@ -98,4 +42,85 @@ class SettingsController extends Controller
|
||||
|
||||
}
|
||||
|
||||
public function ldaptestlogin(Request $request)
|
||||
{
|
||||
|
||||
if (Setting::getSettings()->ldap_enabled!='1') {
|
||||
\Log::debug('LDAP is not enabled. Cannot test.');
|
||||
return response()->json(['message' => 'LDAP is not enabled, cannot test.'], 400);
|
||||
}
|
||||
|
||||
|
||||
$rules = array(
|
||||
'ldaptest_user' => 'required',
|
||||
'ldaptest_password' => 'required'
|
||||
);
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
\Log::debug('LDAP Validation test failed.');
|
||||
$validation_errors = implode(' ',$validator->errors()->all());
|
||||
return response()->json(['message' => $validator->errors()->all()], 400);
|
||||
}
|
||||
|
||||
|
||||
\Log::debug('Preparing to test LDAP login');
|
||||
try {
|
||||
$connection = Ldap::connectToLdap();
|
||||
try {
|
||||
Ldap::bindAdminToLdap($connection);
|
||||
\Log::debug('Attempting to bind to LDAP for LDAP test');
|
||||
try {
|
||||
$ldap_user = Ldap::findAndBindUserLdap($request->input('ldaptest_user'), $request->input('ldaptest_password'));
|
||||
if ($ldap_user) {
|
||||
\Log::debug('It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.');
|
||||
return response()->json(['message' => 'It worked! '. $request->input('ldaptest_user').' successfully binded to LDAP.'], 200);
|
||||
}
|
||||
return response()->json(['message' => 'Login Failed. '. $request->input('ldaptest_user').' did not successfully bind to LDAP.'], 400);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('LDAP login failed');
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Bind failed');
|
||||
return response()->json(['message' => $e->getMessage()], 400);
|
||||
//return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Log::debug('Connection failed');
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the email configuration
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function ajaxTestEmail()
|
||||
{
|
||||
if (!config('app.lock_passwords')) {
|
||||
try {
|
||||
Mail::send('emails.test', [], function ($m) {
|
||||
$m->to(config('mail.from.address'), config('mail.from.name'));
|
||||
$m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name'));
|
||||
$m->subject(trans('mail.test_email'));
|
||||
});
|
||||
return response()->json(['message' => 'Mail sent to '.config('mail.from.address')], 200);
|
||||
} catch (Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
return response()->json(['message' => 'Mail would have been sent, but this application is in demo mode! '], 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ class StatuslabelsController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$allowed_columns = ['id','name','created_at'];
|
||||
$allowed_columns = ['id','name','created_at', 'assets_count'];
|
||||
|
||||
$statuslabels = Statuslabel::withCount('assets');
|
||||
|
||||
@@ -137,8 +137,14 @@ class StatuslabelsController extends Controller
|
||||
$this->authorize('delete', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
$this->authorize('delete', $statuslabel);
|
||||
$statuslabel->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/statuslabels/message.delete.success')));
|
||||
|
||||
// Check that there are no assets associated
|
||||
if ($statuslabel->assets()->count() == 0) {
|
||||
$statuslabel->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/statuslabels/message.delete.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/statuslabels/message.assoc_assets')));
|
||||
|
||||
}
|
||||
|
||||
@@ -155,7 +161,7 @@ class StatuslabelsController extends Controller
|
||||
public function getAssetCountByStatuslabel()
|
||||
{
|
||||
|
||||
$statusLabels = Statuslabel::with('assets')->get();
|
||||
$statusLabels = Statuslabel::get();
|
||||
$labels=[];
|
||||
$points=[];
|
||||
$colors=[];
|
||||
@@ -168,9 +174,7 @@ class StatuslabelsController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
$labels[]='Deployed';
|
||||
$points[]=Asset::whereNotNull('assigned_to')->count();
|
||||
|
||||
|
||||
$colors_array = array_merge($colors, Helper::chartColors());
|
||||
|
||||
$result= [
|
||||
|
||||
@@ -7,6 +7,8 @@ use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Supplier;
|
||||
use App\Http\Transformers\SuppliersTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
|
||||
class SuppliersController extends Controller
|
||||
{
|
||||
@@ -20,11 +22,11 @@ class SuppliersController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
$allowed_columns = ['id','name','address','phone','contact','fax','email'];
|
||||
$allowed_columns = ['id','name','address','phone','contact','fax','email','image','assets_count','licenses_count', 'accessories_count'];
|
||||
|
||||
$suppliers = Supplier::select(
|
||||
array('id','name','address','address2','city','state','country','fax', 'phone','email','contact','created_at','updated_at','deleted_at')
|
||||
)->withCount('assets')->withCount('licenses')->whereNull('deleted_at');
|
||||
array('id','name','address','address2','city','state','country','fax', 'phone','email','contact','created_at','updated_at','deleted_at','image')
|
||||
)->withCount('assets')->withCount('licenses')->withCount('accessories')->whereNull('deleted_at');
|
||||
|
||||
|
||||
if ($request->has('search')) {
|
||||
@@ -113,10 +115,61 @@ class SuppliersController extends Controller
|
||||
public function destroy($id)
|
||||
{
|
||||
$this->authorize('delete', Supplier::class);
|
||||
$supplier = Supplier::findOrFail($id);
|
||||
$supplier = Supplier::with('asset_maintenances', 'assets', 'licenses')->withCount('asset_maintenances','assets', 'licenses')->findOrFail($id);
|
||||
$this->authorize('delete', $supplier);
|
||||
|
||||
|
||||
if ($supplier->assets_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count])));
|
||||
}
|
||||
|
||||
if ($supplier->asset_maintenances_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_maintenances', ['asset_maintenances_count' => $supplier->asset_maintenances_count])));
|
||||
}
|
||||
|
||||
if ($supplier->licenses_count > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/suppliers/message.delete.assoc_licenses', ['licenses_count' => (int) $supplier->licenses_count])));
|
||||
}
|
||||
|
||||
$supplier->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/suppliers/message.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
|
||||
$suppliers = Supplier::select([
|
||||
'id',
|
||||
'name',
|
||||
'image',
|
||||
]);
|
||||
|
||||
if ($request->has('search')) {
|
||||
$suppliers = $suppliers->where('locations.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$suppliers = $suppliers->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 ($suppliers as $supplier) {
|
||||
$supplier->use_text = $supplier->name;
|
||||
$supplier->use_image = ($supplier->image) ? url('/').'/uploads/suppliers/'.$supplier->image : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($suppliers);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ use App\Models\User;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Models\Asset;
|
||||
use App\Http\Transformers\AssetsTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
@@ -31,6 +33,7 @@ class UsersController extends Controller
|
||||
'users.two_factor_enrolled',
|
||||
'users.jobtitle',
|
||||
'users.email',
|
||||
'users.phone',
|
||||
'users.username',
|
||||
'users.location_id',
|
||||
'users.manager_id',
|
||||
@@ -42,7 +45,9 @@ class UsersController extends Controller
|
||||
'users.last_login',
|
||||
'users.deleted_at',
|
||||
'users.department_id',
|
||||
'users.activated'
|
||||
'users.activated',
|
||||
'users.avatar',
|
||||
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department','throttle','assets','licenses','accessories','consumables')
|
||||
->withCount('assets','licenses','accessories','consumables');
|
||||
$users = Company::scopeCompanyables($users);
|
||||
@@ -57,7 +62,6 @@ class UsersController extends Controller
|
||||
$users = $users->GetDeleted();
|
||||
}
|
||||
|
||||
|
||||
if ($request->has('company_id')) {
|
||||
$users = $users->where('company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
@@ -65,6 +69,10 @@ class UsersController extends Controller
|
||||
if ($request->has('location_id')) {
|
||||
$users = $users->where('location_id', '=', $request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->has('group_id')) {
|
||||
$users = $users->ByGroup($request->get('group_id'));
|
||||
}
|
||||
|
||||
if ($request->has('department_id')) {
|
||||
$users = $users->where('department_id','=',$request->input('department_id'));
|
||||
@@ -89,7 +97,8 @@ class UsersController extends Controller
|
||||
[
|
||||
'last_name','first_name','email','jobtitle','username','employee_num',
|
||||
'assets','accessories', 'consumables','licenses','groups','activated','created_at',
|
||||
'two_factor_enrolled','two_factor_optin','last_login'
|
||||
'two_factor_enrolled','two_factor_optin','last_login', 'assets_count', 'licenses_count',
|
||||
'consumables_count', 'accessories_count', 'phone'
|
||||
];
|
||||
|
||||
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'first_name';
|
||||
@@ -102,6 +111,63 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @see \App\Http\Transformers\SelectlistTransformer
|
||||
*
|
||||
*/
|
||||
public function selectlist(Request $request)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
|
||||
$users = User::select(
|
||||
[
|
||||
'users.id',
|
||||
'users.employee_num',
|
||||
'users.first_name',
|
||||
'users.last_name',
|
||||
'users.gravatar',
|
||||
'users.avatar',
|
||||
'users.email',
|
||||
]
|
||||
);
|
||||
|
||||
$users = Company::scopeCompanyables($users);
|
||||
|
||||
if ($request->has('search')) {
|
||||
$users = $users->where('first_name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('last_name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('username', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->get('search').'%');
|
||||
}
|
||||
|
||||
$users = $users->orderBy('last_name', 'asc')->orderBy('first_name', 'asc');
|
||||
$users = $users->paginate(50);
|
||||
|
||||
foreach ($users as $user) {
|
||||
$name_str = '';
|
||||
if ($user->last_name!='') {
|
||||
$name_str .= e($user->last_name).', ';
|
||||
}
|
||||
$name_str .= e($user->first_name);
|
||||
|
||||
if ($user->employee_num!='') {
|
||||
$name_str .= ' (#'.e($user->employee_num).')';
|
||||
}
|
||||
|
||||
$user->use_text = $name_str;
|
||||
$user->use_image = ($user->present()->gravatar) ? $user->present()->gravatar : null;
|
||||
}
|
||||
|
||||
return (new SelectlistTransformer)->transformSelectlist($users);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
@@ -118,7 +184,7 @@ class UsersController extends Controller
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
|
||||
if ($user->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.create.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.create')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
|
||||
}
|
||||
@@ -202,6 +268,7 @@ class UsersController extends Controller
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$assets = Asset::where('assigned_to', '=', $id)->with('model')->get();
|
||||
return response()->json($assets);
|
||||
return (new AssetsTransformer)->transformAssets($assets, $assets->count());
|
||||
// return response()->json($assets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,8 +115,8 @@ class AssetMaintenancesController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
if (($maintenance->cost) && (isset($maintenance->asset)) && ($maintenance->asset->assetloc) && ($maintenance->asset->assetloc->currency!='')) {
|
||||
$maintenance_cost = $maintenance->asset->assetloc->currency.$maintenance->cost;
|
||||
if (($maintenance->cost) && (isset($maintenance->asset)) && ($maintenance->asset->location) && ($maintenance->asset->location->currency!='')) {
|
||||
$maintenance_cost = $maintenance->asset->location->currency.$maintenance->cost;
|
||||
} else {
|
||||
$maintenance_cost = $settings->default_currency.$maintenance->cost;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ use App\Models\Company;
|
||||
use Config;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
@@ -34,7 +35,6 @@ class AssetModelsController extends Controller
|
||||
* the content for the accessories listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see AssetModelsController::getDatatable() method that generates the JSON response
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
@@ -52,11 +52,9 @@ class AssetModelsController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
// Show the page
|
||||
return view('models/edit')
|
||||
->with('category_list', Helper::categoryList('asset'))
|
||||
$category_type = 'asset';
|
||||
return view('models/edit')->with('category_type',$category_type)
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('manufacturer_list', Helper::manufacturerList())
|
||||
->with('item', new AssetModel);
|
||||
}
|
||||
|
||||
@@ -68,7 +66,7 @@ class AssetModelsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
|
||||
// Create a new asset model
|
||||
@@ -90,14 +88,21 @@ class AssetModelsController extends Controller
|
||||
}
|
||||
|
||||
if (Input::file('image')) {
|
||||
|
||||
$image = Input::file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/models/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$file_name = slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/models/');
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
$model->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
// Was it created?
|
||||
@@ -157,17 +162,15 @@ class AssetModelsController extends Controller
|
||||
*/
|
||||
public function edit($modelId = null)
|
||||
{
|
||||
// Check if the model exists
|
||||
if (is_null($item = AssetModel::find($modelId))) {
|
||||
// Redirect to the model management page
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
|
||||
if ($item = AssetModel::find($modelId)) {
|
||||
$category_type = 'asset';
|
||||
$view = View::make('models/edit', compact('item','category_type'));
|
||||
$view->with('depreciation_list', Helper::depreciationList());
|
||||
return $view;
|
||||
}
|
||||
|
||||
$view = View::make('models/edit', compact('item'));
|
||||
$view->with('category_list', Helper::categoryList('asset'));
|
||||
$view->with('depreciation_list', Helper::depreciationList());
|
||||
$view->with('manufacturer_list', Helper::manufacturerList());
|
||||
return $view;
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +183,7 @@ class AssetModelsController extends Controller
|
||||
* @param int $modelId
|
||||
* @return Redirect
|
||||
*/
|
||||
public function update(Request $request, $modelId = null)
|
||||
public function update(ImageUploadRequest $request, $modelId = null)
|
||||
{
|
||||
// Check if the model exists
|
||||
if (is_null($model = AssetModel::find($modelId))) {
|
||||
@@ -205,14 +208,28 @@ class AssetModelsController extends Controller
|
||||
}
|
||||
|
||||
if (Input::file('image')) {
|
||||
|
||||
$image = Input::file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/models/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(300, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$file_name = str_slug($image->getClientOriginalName()) . "." . $image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/models/');
|
||||
$old_image = $path.$model->image;
|
||||
|
||||
try {
|
||||
unlink($old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(500, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
$model->image = $file_name;
|
||||
|
||||
}
|
||||
|
||||
if ($request->input('image_delete') == 1 && Input::file('image') == "") {
|
||||
@@ -245,6 +262,15 @@ class AssetModelsController extends Controller
|
||||
// Throw an error that this model is associated with assets
|
||||
return redirect()->route('models.index')->with('error', trans('admin/models/message.assoc_users'));
|
||||
}
|
||||
|
||||
if ($model->image) {
|
||||
try {
|
||||
unlink(public_path().'/uploads/models/'.$model->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the model
|
||||
$model->delete();
|
||||
|
||||
@@ -352,49 +378,6 @@ class AssetModelsController extends Controller
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the asset information to present to the model view detail page
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v2.0]
|
||||
* @param Request $request
|
||||
* @param $modelID
|
||||
* @return String JSON
|
||||
* @internal param int $modelId
|
||||
*/
|
||||
public function getDataView(Request $request, $modelID)
|
||||
{
|
||||
$assets = Asset::where('model_id', '=', $modelID)->with('company', 'assetstatus');
|
||||
|
||||
if (Input::has('search')) {
|
||||
$assets = $assets->TextSearch(e($request->input('search')));
|
||||
}
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
|
||||
$allowed_columns = ['name', 'serial','asset_tag'];
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
|
||||
$assets = $assets->orderBy($sort, $order);
|
||||
|
||||
$assetsCount = $assets->count();
|
||||
$assets = $assets->skip($offset)->take($limit)->get();
|
||||
|
||||
$rows = array();
|
||||
|
||||
$all_custom_fields = CustomField::all();
|
||||
foreach ($assets as $asset) {
|
||||
|
||||
$rows[] = $asset->present()->forDataTable($all_custom_fields);
|
||||
}
|
||||
|
||||
$data = array('total' => $assetsCount, 'rows' => $rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that allows the user to bulk edit model attrbutes
|
||||
@@ -405,13 +388,16 @@ class AssetModelsController extends Controller
|
||||
*/
|
||||
public function postBulkEdit(Request $request)
|
||||
{
|
||||
|
||||
$models_raw_array = Input::get('ids');
|
||||
$models = AssetModel::whereIn('id', $models_raw_array)->get();
|
||||
$nochange = ['NC' => 'No Change'];
|
||||
$fieldset_list = $nochange + Helper::customFieldsetList();
|
||||
$depreciation_list = $nochange + Helper::depreciationList();
|
||||
$category_list = $nochange + Helper::categoryList('asset');
|
||||
$manufacturer_list = $nochange + Helper::manufacturerList();
|
||||
|
||||
if (is_array($models_raw_array)) {
|
||||
$models = AssetModel::whereIn('id', $models_raw_array)->get();
|
||||
$nochange = ['NC' => 'No Change'];
|
||||
$fieldset_list = $nochange + Helper::customFieldsetList();
|
||||
$depreciation_list = $nochange + Helper::depreciationList();
|
||||
$category_list = $nochange + Helper::categoryList('asset');
|
||||
$manufacturer_list = $nochange + Helper::manufacturerList();
|
||||
|
||||
|
||||
return view('models/bulk-edit', compact('models'))
|
||||
@@ -419,6 +405,10 @@ class AssetModelsController extends Controller
|
||||
->with('category_list', $category_list)
|
||||
->with('fieldset_list', $fieldset_list)
|
||||
->with('depreciation_list', $depreciation_list);
|
||||
}
|
||||
|
||||
return redirect()->route('models.index')
|
||||
->with('error', 'You must select at least one model to edit.');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class AssetsController extends Controller
|
||||
} else {
|
||||
$company = null;
|
||||
}
|
||||
return view('hardware/index')->with('company',$company);
|
||||
return view('hardware/index')->with('company', $company);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +94,6 @@ class AssetsController extends Controller
|
||||
}
|
||||
$this->authorize('view', $asset);
|
||||
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,24 +110,17 @@ class AssetsController extends Controller
|
||||
$this->authorize('create', Asset::class);
|
||||
$view = View::make('hardware/edit')
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('model_list', Helper::modelList())
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('item', new Asset)
|
||||
->with('manufacturer', Helper::manufacturerList()) //handled in modal now?
|
||||
->with('category', Helper::categoryList('asset')) //handled in modal now?
|
||||
->with('statuslabel_types', Helper::statusTypeList()) //handled in modal now?
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('assets_list', Helper::assetsList())
|
||||
->with('locations_list', Helper::locationsList());
|
||||
->with('statuslabel_types', Helper::statusTypeList());
|
||||
|
||||
if ($request->has('model_id')) {
|
||||
$selected_model = AssetModel::find($request->input('model_id'));
|
||||
$view->with('selected_model', $selected_model);
|
||||
} else {
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
@@ -142,17 +134,18 @@ class AssetsController extends Controller
|
||||
public function store(AssetRequest $request)
|
||||
{
|
||||
$this->authorize(Asset::class);
|
||||
// create a new model instance
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find(e(Input::get('model_id'))));
|
||||
|
||||
$asset->name = Input::get('name');
|
||||
$asset->serial = Input::get('serial');
|
||||
$asset->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
|
||||
$asset->model_id = Input::get('model_id');
|
||||
$asset->order_number = Input::get('order_number');
|
||||
$asset->notes = Input::get('notes');
|
||||
$asset->asset_tag = Input::get('asset_tag');
|
||||
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find($request->input('model_id')));
|
||||
|
||||
$asset->name = $request->input('name');
|
||||
$asset->serial = $request->input('serial');
|
||||
$asset->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$asset->model_id = $request->input('model_id');
|
||||
$asset->order_number = $request->input('order_number');
|
||||
$asset->notes = $request->input('notes');
|
||||
$asset->asset_tag = $request->input('asset_tag');
|
||||
$asset->user_id = Auth::id();
|
||||
$asset->archived = '0';
|
||||
$asset->physical = '1';
|
||||
@@ -167,9 +160,8 @@ class AssetsController extends Controller
|
||||
$asset->rtd_location_id = request('rtd_location_id', null);
|
||||
|
||||
// Create the image (if one was chosen.)
|
||||
if (Input::has('image')) {
|
||||
|
||||
$image = Input::get('image');
|
||||
if ($request->has('image')) {
|
||||
$image = $request->input('image');
|
||||
|
||||
// After modification, the image is prefixed by mime info like the following:
|
||||
// data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
|
||||
@@ -201,7 +193,6 @@ class AssetsController extends Controller
|
||||
->put('default', $messageBag));
|
||||
return response()->json(['image' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -211,31 +202,26 @@ class AssetsController extends Controller
|
||||
// Need to investigate and fix. Using static method for now.
|
||||
$model = AssetModel::find($request->get('model_id'));
|
||||
|
||||
|
||||
|
||||
if ($model->fieldset) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
|
||||
if ($field->field_encrypted=='1') {
|
||||
if (Gate::allows('admin')) {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
|
||||
}
|
||||
|
||||
} else {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Was the asset created?
|
||||
if ($asset->save()) {
|
||||
$asset->logCreate();
|
||||
if(request('assigned_user')) {
|
||||
if (request('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
} elseif(request('assigned_asset')) {
|
||||
} elseif (request('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
} elseif(request('assigned_location')) {
|
||||
} elseif (request('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
}
|
||||
if (isset($target)) {
|
||||
@@ -268,15 +254,9 @@ class AssetsController extends Controller
|
||||
$this->authorize($item);
|
||||
|
||||
return view('hardware/edit', compact('item'))
|
||||
->with('model_list', Helper::modelList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('locations_list', Helper::locationsList())
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('assigned_to', Helper::usersList())
|
||||
->with('manufacturer', Helper::manufacturerList())
|
||||
->with('statuslabel_types', Helper::statusTypeList())
|
||||
->with('category', Helper::categoryList('asset'));
|
||||
->with('model_list', Helper::modelList())
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('statuslabel_types', Helper::statusTypeList());
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +271,6 @@ class AssetsController extends Controller
|
||||
|
||||
public function update(AssetRequest $request, $assetId = null)
|
||||
{
|
||||
|
||||
// Check if the asset exists
|
||||
if (!$asset = Asset::find($assetId)) {
|
||||
// Redirect to the asset management page with error
|
||||
@@ -369,7 +348,6 @@ class AssetsController extends Controller
|
||||
if (Gate::allows('admin')) {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt(e($request->input($field->convertUnicodeDbSlug())));
|
||||
}
|
||||
|
||||
} else {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
|
||||
}
|
||||
@@ -380,12 +358,11 @@ class AssetsController extends Controller
|
||||
if ($asset->save()) {
|
||||
// Redirect to the new asset page
|
||||
\Session::flash('success', trans('admin/hardware/message.update.success'));
|
||||
return response()->json(['redirect_url' => route("view/hardware", $assetId)]);
|
||||
return response()->json(['redirect_url' => route("hardware.show", $assetId)]);
|
||||
}
|
||||
\Input::flash();
|
||||
\Session::flash('errors', $asset->getErrors());
|
||||
return response()->json(['errors' => $asset->getErrors()], 500);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -407,8 +384,8 @@ class AssetsController extends Controller
|
||||
$this->authorize('delete', $asset);
|
||||
|
||||
DB::table('assets')
|
||||
->where('id', $asset->id)
|
||||
->update(array('assigned_to' => null));
|
||||
->where('id', $asset->id)
|
||||
->update(array('assigned_to' => null));
|
||||
|
||||
$asset->delete();
|
||||
|
||||
@@ -417,9 +394,8 @@ class AssetsController extends Controller
|
||||
$logaction->item_id = $asset->id;
|
||||
$logaction->created_at = date("Y-m-d H:i:s");
|
||||
$logaction->user_id = Auth::user()->id;
|
||||
$log = $logaction->logaction('deleted');
|
||||
$logaction->logaction('deleted');
|
||||
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success'));
|
||||
}
|
||||
|
||||
@@ -443,11 +419,7 @@ class AssetsController extends Controller
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return view('hardware/checkout', compact('asset'))
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('assets_list', Helper::assetsList())
|
||||
->with('locations_list', Helper::locationsList());
|
||||
|
||||
return view('hardware/checkout', compact('asset'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -469,11 +441,11 @@ class AssetsController extends Controller
|
||||
}
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
if(request('assigned_user')) {
|
||||
if (request('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
} elseif(request('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
} elseif(request('assigned_location')) {
|
||||
} elseif (request('assigned_asset')) {
|
||||
$target = Asset::where('id','!=',$assetId)->find(request('assigned_asset'));
|
||||
} elseif (request('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
}
|
||||
// $user = User::find(Input::get('assigned_to'));
|
||||
@@ -490,6 +462,17 @@ class AssetsController extends Controller
|
||||
} else {
|
||||
$expected_checkin = '';
|
||||
}
|
||||
|
||||
// Set the location ID to the RTD location id if there is one
|
||||
if ($asset->rtd_location_id!='') {
|
||||
$asset->location_id = $target->rtd_location_id;
|
||||
}
|
||||
|
||||
// Overwrite that if the target has a location ID though
|
||||
if ($target->location_id!='') {
|
||||
$asset->location_id = $target->location_id;
|
||||
}
|
||||
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), Input::get('name'))) {
|
||||
// Redirect to the new asset page
|
||||
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
@@ -519,7 +502,6 @@ class AssetsController extends Controller
|
||||
|
||||
$this->authorize('checkin', $asset);
|
||||
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -544,7 +526,7 @@ class AssetsController extends Controller
|
||||
$this->authorize('checkin', $asset);
|
||||
|
||||
$admin = Auth::user();
|
||||
if($asset->assignedType() == Asset::USER) {
|
||||
if ($asset->assignedType() == Asset::USER) {
|
||||
$user = $asset->assignedTo;
|
||||
}
|
||||
if (is_null($target = $asset->assignedTo)) {
|
||||
@@ -562,6 +544,11 @@ class AssetsController extends Controller
|
||||
if (Input::has('status_id')) {
|
||||
$asset->status_id = e(Input::get('status_id'));
|
||||
}
|
||||
|
||||
if (Input::has('location_id')) {
|
||||
$asset->location_id = e(Input::get('location_id'));
|
||||
}
|
||||
|
||||
// Was the asset updated?
|
||||
if ($asset->save()) {
|
||||
$logaction = $asset->logCheckin($target, e(request('note')));
|
||||
@@ -573,6 +560,9 @@ class AssetsController extends Controller
|
||||
$data['item_tag'] = $asset->asset_tag;
|
||||
$data['item_serial'] = $asset->serial;
|
||||
$data['note'] = $logaction->note;
|
||||
$data['manufacturer_name'] = $asset->model->manufacturer->name;
|
||||
$data['model_name'] = $asset->model->name;
|
||||
$data['model_number'] = $asset->model->model_number;
|
||||
|
||||
if ((($asset->checkin_email()=='1')) && (isset($user)) && (!empty($user->email)) && (!config('app.lock_passwords'))) {
|
||||
Mail::send('emails.checkin-asset', $data, function ($m) use ($user) {
|
||||
@@ -583,7 +573,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($backto=='user') {
|
||||
return redirect()->to("admin/users/".$user->id.'/view')->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
return redirect()->route("users.show", $user->id)->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
}
|
||||
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
}
|
||||
@@ -607,15 +597,16 @@ class AssetsController extends Controller
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$this->authorize('view', $asset);
|
||||
$settings = Setting::getSettings();
|
||||
$audit_log = Actionlog::where('action_type','=','audit')->where('item_id','=',$assetId)->where('item_type','=',Asset::class)->orderBy('created_at','DESC')->first();
|
||||
$audit_log = Actionlog::where('action_type', '=', 'audit')
|
||||
->where('item_id', '=', $assetId)
|
||||
->where('item_type', '=', Asset::class)
|
||||
->orderBy('created_at', 'DESC')->first();
|
||||
|
||||
|
||||
if (isset($asset)) {
|
||||
|
||||
if (!is_null($asset->assetloc)) {
|
||||
$use_currency = $asset->assetloc->currency;
|
||||
if ($asset->location) {
|
||||
$use_currency = $asset->location->currency;
|
||||
} else {
|
||||
|
||||
if ($settings->default_currency!='') {
|
||||
$use_currency = $settings->default_currency;
|
||||
} else {
|
||||
@@ -629,10 +620,10 @@ class AssetsController extends Controller
|
||||
);
|
||||
|
||||
return view('hardware/view', compact('asset', 'qr_code', 'settings'))
|
||||
->with('use_currency', $use_currency)->with('audit_log',$audit_log);
|
||||
->with('use_currency', $use_currency)->with('audit_log', $audit_log);
|
||||
}
|
||||
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist', compact('id')));
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,12 +639,11 @@ class AssetsController extends Controller
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
if ($settings->qr_code == '1') {
|
||||
$asset = Asset::find($assetId);
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$size = Helper::barcodeDimensions($settings->barcode_type);
|
||||
$qr_file = public_path().'/uploads/barcodes/qr-'.str_slug($asset->asset_tag).'-'.str_slug($asset->id).'.png';
|
||||
|
||||
if (isset($asset->id,$asset->asset_tag)) {
|
||||
|
||||
if (isset($asset->id, $asset->asset_tag)) {
|
||||
if (file_exists($qr_file)) {
|
||||
$header = ['Content-type' => 'image/png'];
|
||||
return response()->file($qr_file, $header);
|
||||
@@ -665,7 +655,6 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -683,19 +672,21 @@ class AssetsController extends Controller
|
||||
$asset = Asset::find($assetId);
|
||||
$barcode_file = public_path().'/uploads/barcodes/'.str_slug($settings->alt_barcode).'-'.str_slug($asset->asset_tag).'.png';
|
||||
|
||||
if (isset($asset->id,$asset->asset_tag)) {
|
||||
|
||||
if (isset($asset->id, $asset->asset_tag)) {
|
||||
if (file_exists($barcode_file)) {
|
||||
$header = ['Content-type' => 'image/png'];
|
||||
return response()->file($barcode_file, $header);
|
||||
} else {
|
||||
// Calculate barcode width in pixel based on label width (inch)
|
||||
$barcode_width = ($settings->labels_width - $settings->labels_display_sgutter) * 96.000000000001;
|
||||
|
||||
$barcode = new \Com\Tecnick\Barcode\Barcode();
|
||||
$barcode_obj = $barcode->getBarcodeObj($settings->alt_barcode, $asset->asset_tag, 250, 20);
|
||||
$barcode_obj = $barcode->getBarcodeObj($settings->alt_barcode,$asset->asset_tag,($barcode_width < 300 ? $barcode_width : 300),50);
|
||||
|
||||
file_put_contents($barcode_file, $barcode_obj->getPngData());
|
||||
return response($barcode_obj->getPngData())->header('Content-type', 'image/png');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -723,18 +714,9 @@ class AssetsController extends Controller
|
||||
$asset->assigned_to = '';
|
||||
|
||||
return view('hardware/edit')
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('model_list', Helper::modelList())
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('statuslabel_types', Helper::statusTypeList())
|
||||
->with('assigned_to', Helper::usersList())
|
||||
->with('item', $asset)
|
||||
->with('locations_list', Helper::locationsList())
|
||||
->with('manufacturer', Helper::manufacturerList())
|
||||
->with('category', Helper::categoryList('asset'))
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('assets_list', Helper::assetsList())
|
||||
->with('company_list', Helper::companyList());
|
||||
->with('item', $asset);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -762,7 +744,6 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function postImportHistory(Request $request)
|
||||
{
|
||||
|
||||
if (!ini_get("auto_detect_line_endings")) {
|
||||
ini_set("auto_detect_line_endings", '1');
|
||||
}
|
||||
@@ -780,9 +761,7 @@ class AssetsController extends Controller
|
||||
|
||||
|
||||
foreach ($results as $row) {
|
||||
|
||||
if (is_array($row)) {
|
||||
|
||||
$row = array_change_key_case($row, CASE_LOWER);
|
||||
$asset_tag = Helper::array_smart_fetch($row, "asset tag");
|
||||
if (!array_key_exists($asset_tag, $item)) {
|
||||
@@ -797,7 +776,6 @@ class AssetsController extends Controller
|
||||
$item[$asset_tag][$batch_counter]['email'] = Helper::array_smart_fetch($row, "email");
|
||||
|
||||
if ($asset = Asset::where('asset_tag', '=', $asset_tag)->first()) {
|
||||
|
||||
$item[$asset_tag][$batch_counter]['asset_id'] = $asset->id;
|
||||
|
||||
$base_username = User::generateFormattedNameFromFullName(Setting::getSettings()->username_format, $item[$asset_tag][$batch_counter]['name']);
|
||||
@@ -854,12 +832,10 @@ class AssetsController extends Controller
|
||||
} else {
|
||||
$status['error'][]['asset'][$asset_tag]['msg'] = 'Asset and user was matched but could not be saved.';
|
||||
}
|
||||
|
||||
} else {
|
||||
$item[$asset_tag][$batch_counter]['checkedout_to'] = null;
|
||||
$status['error'][]['user'][Helper::array_smart_fetch($row, "name")]['msg'] = 'User does not exist so no checkin log was created.';
|
||||
}
|
||||
|
||||
} else {
|
||||
$item[$asset_tag][$batch_counter]['asset_id'] = null;
|
||||
$status['error'][]['asset'][$asset_tag]['msg'] = 'Asset does not exist so no match was attempted.';
|
||||
@@ -875,7 +851,6 @@ class AssetsController extends Controller
|
||||
|
||||
// Only do this if a matching user was found
|
||||
if ((array_key_exists('checkedout_to', $asset_batch[$x])) && ($asset_batch[$x]['checkedout_to']!='')) {
|
||||
|
||||
if (($total_in_batch > 1) && ($x < $total_in_batch) && (array_key_exists($next, $asset_batch))) {
|
||||
$checkin_date = Carbon::parse($asset_batch[$next]['checkout_date'])->subDay(1)->format('Y-m-d H:i:s');
|
||||
$asset_batch[$x]['real_checkin'] = $checkin_date;
|
||||
@@ -933,27 +908,23 @@ class AssetsController extends Controller
|
||||
if (!$asset = Asset::find($assetId)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('update', $asset);
|
||||
|
||||
$destinationPath = config('app.private_uploads').'/assets';
|
||||
|
||||
if (Input::hasFile('assetfile')) {
|
||||
foreach (Input::file('assetfile') as $file) {
|
||||
if ($request->hasFile('image')) {
|
||||
foreach ($request->file('image') as $file) {
|
||||
$extension = $file->getClientOriginalExtension();
|
||||
$filename = 'hardware-'.$asset->id.'-'.str_random(8);
|
||||
$filename .= '-'.str_slug($file->getClientOriginalName()).'.'.$extension;
|
||||
$upload_success = $file->move($destinationPath, $filename);
|
||||
//Log the deletion of seats to the log
|
||||
$file->move($destinationPath, $filename);
|
||||
$asset->logUpload($filename, e(Input::get('notes')));
|
||||
}
|
||||
} else {
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles'));
|
||||
}
|
||||
|
||||
if ($upload_success) {
|
||||
return redirect()->back()->with('success', trans('admin/hardware/message.upload.success'));
|
||||
}
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.upload.error'));
|
||||
|
||||
return redirect()->back()->with('error', trans('admin/hardware/message.upload.nofiles'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -982,13 +953,10 @@ class AssetsController extends Controller
|
||||
}
|
||||
$log->delete();
|
||||
return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success'));
|
||||
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/hardware/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the hardware management page
|
||||
return redirect()->route('hardware.index')->with('error', $error);
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1036,8 +1004,6 @@ class AssetsController extends Controller
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
|
||||
|
||||
|
||||
if (!$request->has('ids')) {
|
||||
return redirect()->back()->with('error', 'No assets selected');
|
||||
}
|
||||
@@ -1049,33 +1015,23 @@ class AssetsController extends Controller
|
||||
|
||||
|
||||
if ($request->has('bulk_actions')) {
|
||||
|
||||
if ($request->input('bulk_actions')=='labels') {
|
||||
|
||||
$count = 0;
|
||||
return view('hardware/labels')
|
||||
->with('assets', Asset::find($asset_ids))
|
||||
->with('settings', Setting::getSettings())
|
||||
->with('count', $count)
|
||||
->with('settings',
|
||||
Setting::getSettings()
|
||||
);
|
||||
|
||||
->with('count', $count);
|
||||
} elseif ($request->input('bulk_actions')=='delete') {
|
||||
$assets = Asset::with('assignedTo', 'assetloc')->find($asset_ids);
|
||||
$assets->each(function($asset) {
|
||||
$this->authorize('delete',$asset);
|
||||
$assets = Asset::with('assignedTo', 'location')->find($asset_ids);
|
||||
$assets->each(function ($asset) {
|
||||
$this->authorize('delete', $asset);
|
||||
});
|
||||
return view('hardware/bulk-delete')->with('assets', $assets);
|
||||
|
||||
// Bulk edit
|
||||
} elseif ($request->input('bulk_actions')=='edit') {
|
||||
return view('hardware/bulk')
|
||||
->with('assets', request('ids'))
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('models_list', Helper::modelList())
|
||||
->with(
|
||||
'companies_list',
|
||||
array('' => '') + array('clear' => trans('general.remove_company')) + Helper::companyList()
|
||||
@@ -1148,9 +1104,8 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
DB::table('assets')
|
||||
->where('id', $key)
|
||||
->update($update_array);
|
||||
|
||||
->where('id', $key)
|
||||
->update($update_array);
|
||||
} // endforeach
|
||||
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.update.success'));
|
||||
// no values given, nothing to update
|
||||
@@ -1171,8 +1126,7 @@ class AssetsController extends Controller
|
||||
public function postBulkDelete()
|
||||
{
|
||||
$this->authorize('delete', Asset::class);
|
||||
|
||||
|
||||
|
||||
if (Input::has('ids')) {
|
||||
$assets = Asset::find(Input::get('ids'));
|
||||
foreach ($assets as $asset) {
|
||||
@@ -1180,9 +1134,8 @@ class AssetsController extends Controller
|
||||
$update_array['assigned_to'] = null;
|
||||
|
||||
DB::table('assets')
|
||||
->where('id', $asset->id)
|
||||
->update($update_array);
|
||||
|
||||
->where('id', $asset->id)
|
||||
->update($update_array);
|
||||
} // endforeach
|
||||
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.delete.success'));
|
||||
// no values given, nothing to update
|
||||
@@ -1210,6 +1163,9 @@ class AssetsController extends Controller
|
||||
$user = User::find(e(Input::get('assigned_to')));
|
||||
$admin = Auth::user();
|
||||
|
||||
if (!is_array(Input::get('selected_assets'))) {
|
||||
return redirect()->route('hardware/bulkcheckout')->withInput()->with('error', trans('admin/hardware/message.checkout.no_assets_selected'));
|
||||
}
|
||||
$asset_ids = array_filter(Input::get('selected_assets'));
|
||||
|
||||
if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) {
|
||||
@@ -1230,7 +1186,7 @@ class AssetsController extends Controller
|
||||
foreach ($asset_ids as $asset_id) {
|
||||
$asset = Asset::find($asset_id);
|
||||
$this->authorize('checkout', $asset);
|
||||
$error = $asset->checkOutToUser($user, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), null);
|
||||
$error = $asset->checkOut($user, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), null);
|
||||
|
||||
if ($error) {
|
||||
array_merge_recursive($errors, $asset->getErrors()->toArray());
|
||||
@@ -1247,21 +1203,21 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
|
||||
public function quickScan(Request $request)
|
||||
public function quickScan()
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
$dt = Carbon::now()->addMonths(12)->toDateString();
|
||||
return view('hardware/quickscan')->with('next_audit_date', $dt)->with('locations_list', Helper::locationsList());
|
||||
return view('hardware/quickscan')->with('next_audit_date', $dt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function audit(Request $request, $id)
|
||||
public function audit($id)
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
$dt = Carbon::now()->addMonths(12)->toDateString();
|
||||
$asset = Asset::findOrFail($id);
|
||||
return view('hardware/audit')->with('asset', $asset)->with('next_audit_date', $dt)->with('locations_list', Helper::locationsList());
|
||||
return view('hardware/audit')->with('asset', $asset)->with('next_audit_date', $dt)->with('locations_list');
|
||||
}
|
||||
|
||||
public function auditStore(Request $request, $id)
|
||||
@@ -1282,10 +1238,8 @@ class AssetsController extends Controller
|
||||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
|
||||
if ($asset->save()) {
|
||||
$asset->logAudit(request('note'),request('location_id'));
|
||||
$asset->logAudit(request('note'), request('location_id'));
|
||||
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.audit.success'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ class LoginController extends Controller
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest', ['except' => ['logout','postTwoFactorAuth','getTwoFactorAuth','getTwoFactorEnroll']]);
|
||||
\Session::put('backUrl', \URL::previous());
|
||||
}
|
||||
|
||||
|
||||
@@ -320,4 +321,9 @@ class LoginController extends Controller
|
||||
return redirect()->route('login');
|
||||
}
|
||||
|
||||
public function redirectTo()
|
||||
{
|
||||
return Session::get('backUrl') ? Session::get('backUrl') : $this->redirectTo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
15
app/Http/Controllers/Auth/RegisterController.php
Normal file
15
app/Http/Controllers/Auth/RegisterController.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ class ResetPasswordController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
||||
@@ -15,6 +15,8 @@ use Lang;
|
||||
use Redirect;
|
||||
use Str;
|
||||
use View;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to Categories for
|
||||
@@ -67,7 +69,7 @@ class CategoriesController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
// create a new model instance
|
||||
$category = new Category();
|
||||
@@ -80,6 +82,18 @@ class CategoriesController extends Controller
|
||||
$category->checkin_email = $request->input('checkin_email', '0');
|
||||
$category->user_id = Auth::id();
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/categories/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$category->image = $file_name;
|
||||
}
|
||||
|
||||
|
||||
if ($category->save()) {
|
||||
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.create.success'));
|
||||
}
|
||||
@@ -98,10 +112,8 @@ class CategoriesController extends Controller
|
||||
*/
|
||||
public function edit($categoryId = null)
|
||||
{
|
||||
// Check if the category exists
|
||||
if (is_null($item = Category::find($categoryId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.does_not_exist'));
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.does_not_exist'));
|
||||
}
|
||||
$category_types= Helper::categoryTypeList();
|
||||
|
||||
@@ -120,7 +132,7 @@ class CategoriesController extends Controller
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @since [v1.0]
|
||||
*/
|
||||
public function update(Request $request, $categoryId = null)
|
||||
public function update(ImageUploadRequest $request, $categoryId = null)
|
||||
{
|
||||
// Check if the blog post exists
|
||||
if (is_null($category = Category::find($categoryId))) {
|
||||
@@ -138,6 +150,20 @@ class CategoriesController extends Controller
|
||||
$category->require_acceptance = $request->input('require_acceptance', '0');
|
||||
$category->checkin_email = $request->input('checkin_email', '0');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/categories/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$category->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$category->image = null;
|
||||
}
|
||||
|
||||
|
||||
if ($category->save()) {
|
||||
// Redirect to the new category page
|
||||
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.update.success'));
|
||||
@@ -158,22 +184,22 @@ class CategoriesController extends Controller
|
||||
{
|
||||
// Check if the category exists
|
||||
if (is_null($category = Category::find($categoryId))) {
|
||||
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.not_found'));
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.not_found'));
|
||||
}
|
||||
|
||||
if ($category->has_models() > 0) {
|
||||
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'model']));
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'model']));
|
||||
} elseif ($category->accessories()->count() > 0) {
|
||||
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory']));
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'accessory']));
|
||||
} elseif ($category->consumables()->count() > 0) {
|
||||
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable']));
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'consumable']));
|
||||
} elseif ($category->components()->count() > 0) {
|
||||
return redirect()->to('admin/settings/categories')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'component']));
|
||||
return redirect()->route('categories.index')->with('error', trans('admin/categories/message.assoc_items', ['asset_type'=>'component']));
|
||||
}
|
||||
|
||||
$category->delete();
|
||||
// Redirect to the locations management page
|
||||
return redirect()->to(route('categories.index'))->with('success', trans('admin/categories/message.delete.success'));
|
||||
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.delete.success'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ use Lang;
|
||||
use Redirect;
|
||||
use View;
|
||||
use Illuminate\Http\Request;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Companies for
|
||||
@@ -50,11 +52,22 @@ final class CompaniesController extends Controller
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$company = new Company;
|
||||
$company->name = $request->input('name');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/companies/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$company->image = $file_name;
|
||||
}
|
||||
|
||||
if ($company->save()) {
|
||||
return redirect()->route('companies.index')
|
||||
->with('success', trans('admin/companies/message.create.success'));
|
||||
@@ -89,7 +102,7 @@ final class CompaniesController extends Controller
|
||||
* @param int $companyId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(Request $request, $companyId)
|
||||
public function update(ImageUploadRequest $request, $companyId)
|
||||
{
|
||||
if (is_null($company = Company::find($companyId))) {
|
||||
return redirect()->route('companies.index')->with('error', trans('admin/companies/message.does_not_exist'));
|
||||
@@ -97,6 +110,20 @@ final class CompaniesController extends Controller
|
||||
|
||||
$company->name = $request->input('name');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/companies/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$company->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$company->image = null;
|
||||
}
|
||||
|
||||
|
||||
if ($company->save()) {
|
||||
return redirect()->route('companies.index')
|
||||
->with('success', trans('admin/companies/message.update.success'));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Models\CustomField;
|
||||
@@ -21,6 +22,7 @@ use View;
|
||||
use Validator;
|
||||
use Illuminate\Http\Request;
|
||||
use Gate;
|
||||
use Image;
|
||||
|
||||
/**
|
||||
* This class controls all actions related to Components for
|
||||
@@ -57,12 +59,9 @@ class ComponentsController extends Controller
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
// Show the page
|
||||
return view('components/edit')
|
||||
->with('item', new Component)
|
||||
->with('category_list', Helper::categoryList('component'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList());
|
||||
$category_type = 'component';
|
||||
return view('components/edit')->with('category_type',$category_type)
|
||||
->with('item', new Component);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,22 +73,34 @@ class ComponentsController extends Controller
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store()
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
$component = new Component();
|
||||
$component->name = Input::get('name');
|
||||
$component->category_id = Input::get('category_id');
|
||||
$component->location_id = Input::get('location_id');
|
||||
$component->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
|
||||
$component->order_number = Input::get('order_number');
|
||||
$component->min_amt = Input::get('min_amt');
|
||||
$component->serial = Input::get('serial');
|
||||
$component->purchase_date = Input::get('purchase_date');
|
||||
$component->purchase_cost = request('purchase_cost');
|
||||
$component->qty = Input::get('qty');
|
||||
$component->name = $request->input('name');
|
||||
$component->category_id = $request->input('category_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 = $request->input('purchase_cost', null);
|
||||
$component->qty = $request->input('qty');
|
||||
$component->user_id = Auth::id();
|
||||
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/components/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$component->image = $file_name;
|
||||
}
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.create.success'));
|
||||
}
|
||||
@@ -107,16 +118,18 @@ class ComponentsController extends Controller
|
||||
*/
|
||||
public function edit($componentId = null)
|
||||
{
|
||||
if (is_null($item = Component::find($componentId))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
|
||||
|
||||
if ($item = Component::find($componentId)) {
|
||||
$this->authorize('update', $item);
|
||||
$category_type = 'component';
|
||||
return view('components/edit', compact('item'))->with('category_type', $category_type);
|
||||
}
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
|
||||
|
||||
|
||||
$this->authorize('update', $item);
|
||||
|
||||
return view('components/edit', compact('item'))
|
||||
->with('category_list', Helper::categoryList('component'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList());
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +142,7 @@ class ComponentsController extends Controller
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update($componentId = null)
|
||||
public function update(ImageUploadRequest $request, $componentId = null)
|
||||
{
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
@@ -150,6 +163,19 @@ class ComponentsController extends Controller
|
||||
$component->purchase_cost = request('purchase_cost');
|
||||
$component->qty = Input::get('qty');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/components/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$component->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$component->image = null;
|
||||
}
|
||||
|
||||
if ($component->save()) {
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.update.success'));
|
||||
}
|
||||
@@ -228,7 +254,7 @@ class ComponentsController extends Controller
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkout', $component);
|
||||
return view('components/checkout', compact('component'))->with('assets_list', Helper::detailedAssetList());
|
||||
return view('components/checkout', compact('component'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,35 +314,4 @@ class ComponentsController extends Controller
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return JSON data to populate the components view,
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ComponentsController::getView() method that returns the view.
|
||||
* @since [v3.0]
|
||||
* @param int $componentId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function getDataView($componentId)
|
||||
{
|
||||
if (is_null($component = Component::with('assets')->find($componentId))) {
|
||||
// Redirect to the component management page with error
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($component)) {
|
||||
return ['total' => 0, 'rows' => []];
|
||||
}
|
||||
$this->authorize('view', $component);
|
||||
|
||||
$rows = array();
|
||||
$all_custom_fields = CustomField::all(); // Cached for table;
|
||||
foreach ($component->assets as $component_assignment) {
|
||||
$rows[] = $component_assignment->present()->forDataTable($all_custom_fields);
|
||||
}
|
||||
|
||||
$componentCount = $component->assets->count();
|
||||
$data = array('total' => $componentCount, 'rows' => $rows);
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ use Slack;
|
||||
use Str;
|
||||
use View;
|
||||
use Gate;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Consumables for
|
||||
@@ -54,13 +56,9 @@ class ConsumablesController extends Controller
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
// Show the page
|
||||
return view('consumables/edit')
|
||||
->with('item', new Consumable)
|
||||
->with('category_list', Helper::categoryList('consumable'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
$category_type = 'consumable';
|
||||
return view('consumables/edit')->with('category_type', $category_type)
|
||||
->with('item', new Consumable);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,24 +70,36 @@ class ConsumablesController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store()
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
$consumable = new Consumable();
|
||||
$consumable->name = Input::get('name');
|
||||
$consumable->category_id = Input::get('category_id');
|
||||
$consumable->location_id = Input::get('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
|
||||
$consumable->order_number = Input::get('order_number');
|
||||
$consumable->min_amt = Input::get('min_amt');
|
||||
$consumable->manufacturer_id = Input::get('manufacturer_id');
|
||||
$consumable->model_number = Input::get('model_number');
|
||||
$consumable->item_no = Input::get('item_no');
|
||||
$consumable->purchase_date = Input::get('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseFloat(Input::get('purchase_cost'));
|
||||
$consumable->qty = Input::get('qty');
|
||||
$consumable->name = $request->input('name');
|
||||
$consumable->category_id = $request->input('category_id');
|
||||
$consumable->location_id = $request->input('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$consumable->order_number = $request->input('order_number');
|
||||
$consumable->min_amt = $request->input('min_amt');
|
||||
$consumable->manufacturer_id = $request->input('manufacturer_id');
|
||||
$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::ParseFloat($request->input('purchase_cost'));
|
||||
$consumable->qty = $request->input('qty');
|
||||
$consumable->user_id = Auth::id();
|
||||
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/consumables/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$consumable->image = $file_name;
|
||||
}
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.create.success'));
|
||||
}
|
||||
@@ -109,17 +119,14 @@ class ConsumablesController extends Controller
|
||||
*/
|
||||
public function edit($consumableId = null)
|
||||
{
|
||||
if (is_null($item = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
if ($item = Consumable::find($consumableId)) {
|
||||
$this->authorize($item);
|
||||
$category_type = 'consumable';
|
||||
return view('consumables/edit', compact('item'))->with('category_type', $category_type);
|
||||
}
|
||||
|
||||
$this->authorize($item);
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
|
||||
return view('consumables/edit', compact('item'))
|
||||
->with('category_list', Helper::categoryList('consumable'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +139,7 @@ class ConsumablesController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update($consumableId = null)
|
||||
public function update(ImageUploadRequest $request, $consumableId = null)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
@@ -140,19 +147,32 @@ class ConsumablesController extends Controller
|
||||
|
||||
$this->authorize($consumable);
|
||||
|
||||
$consumable->name = Input::get('name');
|
||||
$consumable->category_id = Input::get('category_id');
|
||||
$consumable->location_id = Input::get('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser(Input::get('company_id'));
|
||||
$consumable->order_number = Input::get('order_number');
|
||||
$consumable->min_amt = Input::get('min_amt');
|
||||
$consumable->manufacturer_id = Input::get('manufacturer_id');
|
||||
$consumable->model_number = Input::get('model_number');
|
||||
$consumable->item_no = Input::get('item_no');
|
||||
$consumable->purchase_date = Input::get('purchase_date');
|
||||
$consumable->purchase_cost = Helper::ParseFloat(Input::get('purchase_cost'));
|
||||
$consumable->name = $request->input('name');
|
||||
$consumable->category_id = $request->input('category_id');
|
||||
$consumable->location_id = $request->input('location_id');
|
||||
$consumable->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$consumable->order_number = $request->input('order_number');
|
||||
$consumable->min_amt = $request->input('min_amt');
|
||||
$consumable->manufacturer_id = $request->input('manufacturer_id');
|
||||
$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::ParseFloat(Input::get('purchase_cost'));
|
||||
$consumable->qty = Helper::ParseFloat(Input::get('qty'));
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/consumables/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$consumable->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$consumable->image = null;
|
||||
}
|
||||
|
||||
if ($consumable->save()) {
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.update.success'));
|
||||
}
|
||||
@@ -194,7 +214,7 @@ class ConsumablesController extends Controller
|
||||
if (isset($consumable->id)) {
|
||||
return view('consumables/view', compact('consumable'));
|
||||
}
|
||||
return redirect()->route('consumables')->with('error', trans('admin/consumables/message.does_not_exist', compact('id')));
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,10 +229,10 @@ class ConsumablesController extends Controller
|
||||
public function getCheckout($consumableId)
|
||||
{
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
}
|
||||
$this->authorize('checkout', $consumable);
|
||||
return view('consumables/checkout', compact('consumable'))->with('users_list', Helper::usersList());
|
||||
return view('consumables/checkout', compact('consumable'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,7 +258,7 @@ class ConsumablesController extends Controller
|
||||
// Check if the user exists
|
||||
if (is_null($user = User::find($assigned_to))) {
|
||||
// Redirect to the consumable management page with error
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.user_does_not_exist'));
|
||||
return redirect()->route('checkout/consumable', $consumable)->with('error', trans('admin/consumables/message.checkout.user_does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
@@ -259,7 +279,7 @@ class ConsumablesController extends Controller
|
||||
$data['note'] = $logaction->note;
|
||||
$data['require_acceptance'] = $consumable->requireAcceptance();
|
||||
|
||||
if (($consumable->requireAcceptance()=='1') || ($consumable->getEula())) {
|
||||
if ((($consumable->requireAcceptance()=='1') || ($consumable->getEula())) && $user->email!='') {
|
||||
|
||||
Mail::send('emails.accept-asset', $data, function ($m) use ($user) {
|
||||
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
|
||||
|
||||
@@ -37,19 +37,25 @@ class CustomFieldsetsController extends Controller
|
||||
public function show($id)
|
||||
{
|
||||
$cfset = CustomFieldset::with('fields')->where('id', '=', $id)->orderBy('id', 'ASC')->first();
|
||||
$custom_fields_list = ["" => "Add New Field to Fieldset"] + CustomField::pluck("name", "id")->toArray();
|
||||
|
||||
$maxid = 0;
|
||||
foreach ($cfset->fields() as $field) {
|
||||
if ($field->pivot->order > $maxid) {
|
||||
$maxid=$field->pivot->order;
|
||||
}
|
||||
if (isset($custom_fields_list[$field->id])) {
|
||||
unset($custom_fields_list[$field->id]);
|
||||
if ($cfset) {
|
||||
$custom_fields_list = ["" => "Add New Field to Fieldset"] + CustomField::pluck("name", "id")->toArray();
|
||||
|
||||
$maxid = 0;
|
||||
foreach ($cfset->fields() as $field) {
|
||||
if ($field->pivot->order > $maxid) {
|
||||
$maxid=$field->pivot->order;
|
||||
}
|
||||
if (isset($custom_fields_list[$field->id])) {
|
||||
unset($custom_fields_list[$field->id]);
|
||||
}
|
||||
}
|
||||
|
||||
return view("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
|
||||
}
|
||||
|
||||
return view("custom_fields.fieldsets.view")->with("custom_fieldset", $cfset)->with("maxid", $maxid+1)->with("custom_fields_list", $custom_fields_list);
|
||||
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -133,16 +139,21 @@ class CustomFieldsetsController extends Controller
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
$fieldset = CustomFieldset::find($id);
|
||||
|
||||
$models = AssetModel::where("fieldset_id", "=", $id);
|
||||
if ($models->count() == 0) {
|
||||
$fieldset->delete();
|
||||
return redirect()->route("fields.show")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
|
||||
} else {
|
||||
return redirect()->route("fields.show")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
|
||||
if ($fieldset) {
|
||||
$models = AssetModel::where("fieldset_id", "=", $id);
|
||||
if ($models->count() == 0) {
|
||||
$fieldset->delete();
|
||||
return redirect()->route("fields.index")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
|
||||
} else {
|
||||
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route("fields.index")->with("error", trans('admin/custom_fields/message.fieldset.does_not_exist'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ class DashboardController extends Controller
|
||||
$counts['grand_total'] = $counts['asset'] + $counts['accessory'] + $counts['license'] + $counts['consumable'];
|
||||
|
||||
if ((!file_exists(storage_path().'/oauth-private.key')) || (!file_exists(storage_path().'/oauth-public.key'))) {
|
||||
\Artisan::call('passport:install');
|
||||
\Artisan::call('migrate', ['--force' => true]);
|
||||
\Artisan::call('passport:install');
|
||||
}
|
||||
|
||||
return view('dashboard')->with('asset_stats', $asset_stats)->with('counts', $counts);
|
||||
|
||||
@@ -6,6 +6,8 @@ use Illuminate\Http\Request;
|
||||
use App\Models\Department;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
class DepartmentsController extends Controller
|
||||
{
|
||||
@@ -27,13 +29,11 @@ class DepartmentsController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('index', Department::class);
|
||||
$company = null;
|
||||
if ($request->has('company_id')) {
|
||||
$company = Company::find($request->input('company_id'));
|
||||
} else {
|
||||
$company = null;
|
||||
}
|
||||
return view('departments/index')->with('company',$company);
|
||||
|
||||
return view('departments/index')->with('company', $company);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class DepartmentsController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$this->authorize('create', Department::class);
|
||||
$department = new Department;
|
||||
@@ -53,12 +53,21 @@ class DepartmentsController extends Controller
|
||||
$department->user_id = Auth::user()->id;
|
||||
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/departments/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$department->image = $file_name;
|
||||
}
|
||||
|
||||
if ($department->save()) {
|
||||
return redirect()->route("departments.index")->with('success', trans('admin/departments/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($department->getErrors());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,10 +100,7 @@ class DepartmentsController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('departments/edit')->with('item', new Department)
|
||||
->with('manager_list', Helper::managerList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('company_list', Helper::companyList());
|
||||
return view('departments/edit')->with('item', new Department);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,30 +141,36 @@ class DepartmentsController extends Controller
|
||||
if (is_null($item = Department::find($id))) {
|
||||
return redirect()->back()->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
return view('departments/edit', compact('item'))
|
||||
->with('manager_list', Helper::managerList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('company_list', Helper::companyList());
|
||||
return view('departments/edit', compact('item'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function update(Request $request, $id) {
|
||||
|
||||
$this->authorize('create', Department::class);
|
||||
if (is_null($department = Department::find($id))) {
|
||||
return redirect()->to('admin/settings/departments')->with('error', trans('admin/departments/message.does_not_exist'));
|
||||
return redirect()->route('departments.index')->with('error', trans('admin/departments/message.does_not_exist'));
|
||||
}
|
||||
|
||||
|
||||
$department->fill($request->all());
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/departments/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$department->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$department->image = null;
|
||||
}
|
||||
|
||||
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
|
||||
|
||||
if ($department->save()) {
|
||||
return redirect()->route("departments.index")->with('success', trans('admin/departments/message.update.success'));
|
||||
}
|
||||
|
||||
return redirect()->back()->withInput()->withErrors($department->getErrors());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -155,5 +155,24 @@ class DepreciationsController extends Controller
|
||||
return redirect()->route('depreciations.index')->with('success', trans('admin/depreciations/message.delete.success'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that displays a form to display depreciation listing
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net]
|
||||
* @see DepreciationsController::postEdit()
|
||||
* @param int $depreciationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
if (is_null($depreciation = Depreciation::find($id))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
return view('depreciations/view', compact('depreciation'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -87,10 +87,15 @@ class GroupsController extends Controller
|
||||
public function edit($id = null)
|
||||
{
|
||||
$group = Group::find($id);
|
||||
$permissions = config('permissions');
|
||||
$groupPermissions = $group->decodePermissions();
|
||||
$selected_array = Helper::selectedPermissionsArray($permissions, $groupPermissions);
|
||||
return view('groups.edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'));
|
||||
|
||||
if ($group) {
|
||||
$permissions = config('permissions');
|
||||
$groupPermissions = $group->decodePermissions();
|
||||
$selected_array = Helper::selectedPermissionsArray($permissions, $groupPermissions);
|
||||
return view('groups.edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'));
|
||||
}
|
||||
|
||||
return redirect()->route('groups.index')->with('error', trans('admin/groups/message.group_not_found', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,4 +147,24 @@ class GroupsController extends Controller
|
||||
return redirect()->route('groups.index')->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the group detail page.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $locationId
|
||||
* @since [v4.0.11]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$group = Group::find($id);
|
||||
|
||||
if ($group) {
|
||||
return view('groups/view', compact('group'));
|
||||
}
|
||||
|
||||
return redirect()->route('groups.index')->with('error', trans('admin/groups/message.group_not_found', compact('id')));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,10 +67,7 @@ class LicensesController extends Controller
|
||||
return view('licenses/edit')
|
||||
//->with('license_options',$license_options)
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('maintained_list', $maintained_list)
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('manufacturer_list', Helper::manufacturerList())
|
||||
->with('item', new License);
|
||||
|
||||
}
|
||||
@@ -144,10 +141,7 @@ class LicensesController extends Controller
|
||||
|
||||
return view('licenses/edit', compact('item'))
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('maintained_list', $maintained_list)
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
->with('maintained_list', $maintained_list);
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +181,7 @@ class LicensesController extends Controller
|
||||
$license->termination_date = $request->input('termination_date');
|
||||
$license->seats = e($request->input('seats'));
|
||||
$license->manufacturer_id = $request->input('manufacturer_id');
|
||||
$license->supplier_id = $request->input('supplier_id');
|
||||
|
||||
if ($license->save()) {
|
||||
return redirect()->route('licenses.show', ['license' => $licenseId])->with('success', trans('admin/licenses/message.update.success'));
|
||||
@@ -253,9 +248,7 @@ class LicensesController extends Controller
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $licenseSeat);
|
||||
return view('licenses/checkout', compact('licenseSeat'))
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('asset_list', Helper::detailedAssetList());
|
||||
return view('licenses/checkout', compact('licenseSeat'));
|
||||
}
|
||||
|
||||
|
||||
@@ -279,7 +272,7 @@ class LicensesController extends Controller
|
||||
|
||||
// Declare the rules for the form validation
|
||||
$rules = [
|
||||
'note' => 'string',
|
||||
'note' => 'string|nullable',
|
||||
'asset_id' => 'required_without:assigned_to',
|
||||
];
|
||||
|
||||
@@ -334,15 +327,14 @@ class LicensesController extends Controller
|
||||
if ($licenseSeat->save()) {
|
||||
$licenseSeat->logCheckout($request->input('note'), $target);
|
||||
|
||||
$data['license_id'] =$licenseSeat->license_id;
|
||||
$data['license_id'] = $licenseSeat->license_id;
|
||||
$data['note'] = $request->input('note');
|
||||
|
||||
// Redirect to the new asset page
|
||||
return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.checkout.success'));
|
||||
}
|
||||
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to("admin/licenses/{$asset_id}/checkout")->with('error', trans('admin/licenses/message.create.error'))->with('license', new License);
|
||||
|
||||
return redirect()->route("licenses.index")->with('error', trans('admin/licenses/message.checkout.error'));
|
||||
}
|
||||
|
||||
|
||||
@@ -358,12 +350,12 @@ class LicensesController extends Controller
|
||||
public function getCheckin($seatId = null, $backTo = null)
|
||||
{
|
||||
// Check if the asset exists
|
||||
if (is_null($licenseseat = LicenseSeat::find($seatId))) {
|
||||
if (is_null($licenseSeat = LicenseSeat::find($seatId))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkin', $licenseseat);
|
||||
return view('licenses/checkin', compact('licenseseat'))->with('backto', $backTo);
|
||||
$this->authorize('checkin', $licenseSeat);
|
||||
return view('licenses/checkin', compact('licenseSeat'))->with('backto', $backTo);
|
||||
}
|
||||
|
||||
|
||||
@@ -441,17 +433,15 @@ class LicensesController extends Controller
|
||||
public function show($licenseId = null)
|
||||
{
|
||||
|
||||
$license = License::find($licenseId);
|
||||
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
|
||||
$license = License::with('assignedusers', 'licenseSeats.user', 'licenseSeats.asset')->find($licenseId);
|
||||
|
||||
if (isset($license->id)) {
|
||||
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
|
||||
if ($license) {
|
||||
$this->authorize('view', $license);
|
||||
return view('licenses/view', compact('license'));
|
||||
}
|
||||
$error = trans('admin/licenses/message.does_not_exist', compact('id'));
|
||||
return redirect()->route('licenses.index')->with('error', $error);
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
|
||||
public function getClone($licenseId = null)
|
||||
{
|
||||
@@ -474,11 +464,8 @@ class LicensesController extends Controller
|
||||
// Show the page
|
||||
return view('licenses/edit')
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('item', $license)
|
||||
->with('maintained_list', $maintained_list)
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
->with('maintained_list', $maintained_list);
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +478,7 @@ class LicensesController extends Controller
|
||||
* @param int $licenseId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postUpload($licenseId = null)
|
||||
public function postUpload(Request $request, $licenseId = null)
|
||||
{
|
||||
$license = License::find($licenseId);
|
||||
// the license is valid
|
||||
@@ -520,13 +507,16 @@ class LicensesController extends Controller
|
||||
//Log the upload to the log
|
||||
$license->logUpload($filename, e($request->input('notes')));
|
||||
}
|
||||
|
||||
// This being called from a modal seems to confuse redirect()->back()
|
||||
// It thinks we should go to the dashboard. As this is only used
|
||||
// from the modal at present, hardcode the redirect. Longterm
|
||||
// maybe we evaluate something else.
|
||||
if ($upload_success) {
|
||||
return redirect()->back()->with('success', trans('admin/licenses/message.upload.success'));
|
||||
return redirect()->route('licenses.show', $license->id)->with('success', trans('admin/licenses/message.upload.success'));
|
||||
}
|
||||
return redirect()->back()->with('error', trans('admin/licenses/message.upload.error'));
|
||||
return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.error'));
|
||||
}
|
||||
return redirect()->back()->with('error', trans('admin/licenses/message.upload.nofiles'));
|
||||
return redirect()->route('licenses.show', $license->id)->with('error', trans('admin/licenses/message.upload.nofiles'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/licenses/message.does_not_exist', compact('id'));
|
||||
@@ -589,61 +579,10 @@ class LicensesController extends Controller
|
||||
$file = $log->get_src('licenses');
|
||||
return Response::download($file);
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/licenses/message.does_not_exist', compact('id'));
|
||||
// Redirect to the licence management page
|
||||
return redirect()->route('licenses.index')->with('error', $error);
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a JSON response to populate the licence index datatables.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LicensesController::getIndex() method that provides the view
|
||||
* @since [v1.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function getDatatable(Request $request)
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
$licenses = Company::scopeCompanyables(License::with('company', 'licenseSeatsRelation', 'manufacturer'));
|
||||
|
||||
if (Input::has('search')) {
|
||||
$licenses = $licenses->TextSearch($request->input('search'));
|
||||
}
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','manufacturer','company'];
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
|
||||
switch ($sort) {
|
||||
case 'manufacturer':
|
||||
$licenses = $licenses->OrderManufacturer($order);
|
||||
break;
|
||||
case 'company':
|
||||
$licenses = $licenses->OrderCompany($order);
|
||||
break;
|
||||
default:
|
||||
$licenses = $licenses->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
$licenseCount = $licenses->count();
|
||||
$licenses = $licenses->skip($offset)->take($limit)->get();
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($licenses as $license) {
|
||||
$rows[] = $license->present()->forDataTable();
|
||||
}
|
||||
|
||||
$data = array('total' => $licenseCount, 'rows' => $rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the next free seat ID for checkout.
|
||||
|
||||
@@ -16,6 +16,8 @@ use Validator;
|
||||
use View;
|
||||
use Auth;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Image;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Locations for
|
||||
@@ -63,8 +65,7 @@ class LocationsController extends Controller
|
||||
|
||||
return view('locations/edit')
|
||||
->with('location_options', $location_options)
|
||||
->with('item', new Location)
|
||||
->with('manager_list', Helper::managerList());
|
||||
->with('item', new Location);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,21 +78,33 @@ class LocationsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store()
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
$location = new Location();
|
||||
$location->name = Input::get('name');
|
||||
$location->parent_id = Input::get('parent_id', null);
|
||||
$location->currency = Input::get('currency', '$');
|
||||
$location->address = Input::get('address');
|
||||
$location->address2 = Input::get('address2');
|
||||
$location->city = Input::get('city');
|
||||
$location->state = Input::get('state');
|
||||
$location->country = Input::get('country');
|
||||
$location->zip = Input::get('zip');
|
||||
$location->manager_id = Input::get('manager_id');
|
||||
$location->name = $request->input('name');
|
||||
$location->parent_id = $request->input('parent_id', null);
|
||||
$location->currency = $request->input('currency', '$');
|
||||
$location->address = $request->input('address');
|
||||
$location->address2 = $request->input('address2');
|
||||
$location->city = $request->input('city');
|
||||
$location->state = $request->input('state');
|
||||
$location->country = $request->input('country');
|
||||
$location->zip = $request->input('zip');
|
||||
$location->ldap_ou = $request->input('ldap_ou');
|
||||
$location->manager_id = $request->input('manager_id');
|
||||
$location->user_id = Auth::id();
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/locations/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$location->image = $file_name;
|
||||
}
|
||||
|
||||
if ($location->save()) {
|
||||
return redirect()->route("locations.index")->with('success', trans('admin/locations/message.create.success'));
|
||||
}
|
||||
@@ -107,7 +120,7 @@ class LocationsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function apiStore()
|
||||
public function apiStore(Request $request)
|
||||
{
|
||||
$new['currency']=Setting::first()->default_currency;
|
||||
|
||||
@@ -115,13 +128,13 @@ class LocationsController extends Controller
|
||||
$location = new Location();
|
||||
|
||||
// Save the location data
|
||||
$location->name = Input::get('name');
|
||||
$location->name = $request->input('name');
|
||||
$location->currency = Setting::first()->default_currency; //e(Input::get('currency'));
|
||||
$location->address = ''; //e(Input::get('address'));
|
||||
// $location->address2 = e(Input::get('address2'));
|
||||
$location->city = Input::get('city');
|
||||
$location->city = $request->input('city');
|
||||
$location->state = '';//e(Input::get('state'));
|
||||
$location->country = Input::get('country');
|
||||
$location->country = $request->input('country');
|
||||
// $location->zip = e(Input::get('zip'));
|
||||
$location->user_id = Auth::id();
|
||||
|
||||
@@ -147,7 +160,7 @@ class LocationsController extends Controller
|
||||
{
|
||||
// Check if the location exists
|
||||
if (is_null($item = Location::find($locationId))) {
|
||||
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
// Show the page
|
||||
@@ -156,7 +169,6 @@ class LocationsController extends Controller
|
||||
$location_options = Location::flattenLocationsArray($location_options_array);
|
||||
$location_options = array('' => 'Top Level') + $location_options;
|
||||
|
||||
|
||||
return view('locations/edit', compact('item'))
|
||||
->with('location_options', $location_options)
|
||||
->with('manager_list', Helper::managerList());
|
||||
@@ -172,32 +184,43 @@ class LocationsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update($locationId = null)
|
||||
public function update(ImageUploadRequest $request, $locationId = null)
|
||||
{
|
||||
// Check if the location exists
|
||||
if (is_null($location = Location::find($locationId))) {
|
||||
return redirect()->to('admin/settings/locations')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
// Update the location data
|
||||
$location->name = Input::get('name');
|
||||
$location->parent_id = Input::get('parent_id', null);
|
||||
$location->currency = Input::get('currency', '$');
|
||||
$location->address = Input::get('address');
|
||||
$location->address2 = Input::get('address2');
|
||||
$location->city = Input::get('city');
|
||||
$location->state = Input::get('state');
|
||||
$location->country = Input::get('country');
|
||||
$location->zip = Input::get('zip');
|
||||
$location->ldap_ou = Input::get('ldap_ou');
|
||||
$location->manager_id = Input::get('manager_id');
|
||||
$location->name = $request->input('name');
|
||||
$location->parent_id = $request->input('parent_id', null);
|
||||
$location->currency = $request->input('currency', '$');
|
||||
$location->address = $request->input('address');
|
||||
$location->address2 = $request->input('address2');
|
||||
$location->city = $request->input('city');
|
||||
$location->state = $request->input('state');
|
||||
$location->country = $request->input('country');
|
||||
$location->zip = $request->input('zip');
|
||||
$location->ldap_ou = $request->input('ldap_ou');
|
||||
$location->manager_id = $request->input('manager_id');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/locations/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$location->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$location->image = null;
|
||||
}
|
||||
|
||||
|
||||
// Was the location updated?
|
||||
if ($location->save()) {
|
||||
// Redirect to the saved location page
|
||||
return redirect()->route("locations.index")->with('success', trans('admin/locations/message.update.success'));
|
||||
}
|
||||
// Redirect to the location management page
|
||||
return redirect()->back()->withInput()->withInput()->withErrors($location->getErrors());
|
||||
}
|
||||
|
||||
@@ -211,21 +234,22 @@ class LocationsController extends Controller
|
||||
*/
|
||||
public function destroy($locationId)
|
||||
{
|
||||
// Check if the location exists
|
||||
if (is_null($location = Location::find($locationId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.not_found'));
|
||||
}
|
||||
|
||||
|
||||
if ($location->users->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_users'));
|
||||
|
||||
} elseif ($location->childLocations->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_child_loc'));
|
||||
|
||||
} elseif ($location->assets->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
|
||||
|
||||
} elseif ($location->assignedassets->count() > 0) {
|
||||
return redirect()->to(route('locations.index'))->with('error', trans('admin/locations/message.assoc_assets'));
|
||||
|
||||
} else {
|
||||
$location->delete();
|
||||
return redirect()->to(route('locations.index'))->with('success', trans('admin/locations/message.delete.success'));
|
||||
@@ -249,11 +273,8 @@ class LocationsController extends Controller
|
||||
if (isset($location->id)) {
|
||||
return view('locations/view', compact('location'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/locations/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('locations.index')->with('error', $error);
|
||||
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Manufacturer;
|
||||
use Auth;
|
||||
@@ -13,6 +14,7 @@ use Redirect;
|
||||
use Str;
|
||||
use View;
|
||||
use Illuminate\Http\Request;
|
||||
use Image;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Manufacturers for
|
||||
@@ -60,7 +62,7 @@ class ManufacturersController extends Controller
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
|
||||
$manufacturer = new Manufacturer;
|
||||
@@ -72,6 +74,18 @@ class ManufacturersController extends Controller
|
||||
$manufacturer->support_email = $request->input('support_email');
|
||||
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_slug($image->getClientOriginalName()).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/manufacturers/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$manufacturer->image = $file_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($manufacturer->save()) {
|
||||
return redirect()->route('manufacturers.index')->with('success', trans('admin/manufacturers/message.create.success'));
|
||||
@@ -124,6 +138,29 @@ class ManufacturersController extends Controller
|
||||
$manufacturer->support_phone = $request->input('support_phone');
|
||||
$manufacturer->support_email = $request->input('support_email');
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_slug($image->getClientOriginalName()).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/manufacturers/'.$file_name);
|
||||
$old_image = $path.$model->image;
|
||||
|
||||
try {
|
||||
unlink($old_image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
|
||||
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$manufacturer->image = $file_name;
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$manufacturer->image = null;
|
||||
}
|
||||
|
||||
|
||||
if ($manufacturer->save()) {
|
||||
return redirect()->route('manufacturers.index')->with('success', trans('admin/manufacturers/message.update.success'));
|
||||
}
|
||||
@@ -150,6 +187,16 @@ class ManufacturersController extends Controller
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.assoc_users'));
|
||||
}
|
||||
|
||||
if ($manufacturer->image) {
|
||||
try {
|
||||
unlink(public_path().'/uploads/manufacturers/'.$manufacturer->image);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Delete the manufacturer
|
||||
$manufacturer->delete();
|
||||
// Redirect to the manufacturers management page
|
||||
@@ -158,11 +205,10 @@ class ManufacturersController extends Controller
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the manufacturers detail listing, which is generated in getDatatable.
|
||||
* the content for the manufacturers detail listing, which is generated via API.
|
||||
* This data contains a listing of all assets that belong to that manufacturer.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ManufacturersController::getDataView()
|
||||
* @param int $manufacturerId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
@@ -174,154 +220,13 @@ class ManufacturersController extends Controller
|
||||
if (isset($manufacturer->id)) {
|
||||
return view('manufacturers/view', compact('manufacturer'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/manufacturers/message.does_not_exist', compact('id'));
|
||||
|
||||
$error = trans('admin/manufacturers/message.does_not_exist');
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('manufacturers')->with('error', $error);
|
||||
return redirect()->route('manufacturers.index')->with('error', $error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the JSON used to display the manufacturer detail.
|
||||
* This JSON returns data on all of the assets with the specified
|
||||
* manufacturer ID number.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ManufacturersController::getView()
|
||||
* @param int $manufacturerId
|
||||
* @param string $itemType
|
||||
* @param Request $request
|
||||
* @return String JSON* @since [v1.0]
|
||||
*/
|
||||
public function getDataView($manufacturerId, $itemType = null, Request $request)
|
||||
{
|
||||
$manufacturer = Manufacturer::find($manufacturerId);
|
||||
|
||||
switch ($itemType) {
|
||||
case "assets":
|
||||
return $this->getDataAssetsView($manufacturer, $request);
|
||||
case "licenses":
|
||||
return $this->getDataLicensesView($manufacturer, $request);
|
||||
case "accessories":
|
||||
return $this->getDataAccessoriesView($manufacturer, $request);
|
||||
case "consumables":
|
||||
return $this->getDataConsumablesView($manufacturer, $request);
|
||||
}
|
||||
|
||||
return "We shouldn't be here";
|
||||
|
||||
}
|
||||
|
||||
protected function getDataAssetsView(Manufacturer $manufacturer, Request $request)
|
||||
{
|
||||
$manufacturer = $manufacturer->load('assets.model', 'assets.assignedTo', 'assets.assetstatus', 'assets.company');
|
||||
$manufacturer_assets = $manufacturer->assets();
|
||||
|
||||
if ($request->has('search')) {
|
||||
$manufacturer_assets = $manufacturer_assets->TextSearch(e($request->input('search')));
|
||||
}
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
$allowed_columns = ['id','name','serial','asset_tag'];
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
$count = $manufacturer_assets->count();
|
||||
$manufacturer_assets = $manufacturer_assets->skip($offset)->take($limit)->get();
|
||||
$rows = array();
|
||||
$all_custom_fields = CustomField::all(); // cached;
|
||||
foreach ($manufacturer_assets as $asset) {
|
||||
$rows[] = $asset->present()->forDataTable($all_custom_fields);
|
||||
}
|
||||
|
||||
$data = array('total' => $count, 'rows' => $rows);
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getDataLicensesView(Manufacturer $manufacturer, Request $request)
|
||||
{
|
||||
$manufacturer = $manufacturer->load('licenses.company', 'licenses.manufacturer', 'licenses.licenseSeatsRelation');
|
||||
$licenses = $manufacturer->licenses;
|
||||
|
||||
if ($request->has('search')) {
|
||||
$licenses = $licenses->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
$licenseCount = $licenses->count();
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($licenses as $license) {
|
||||
$rows[] = $license->present()->forDataTable();
|
||||
}
|
||||
|
||||
$data = array('total' => $licenseCount, 'rows' => $rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getDataAccessoriesView(Manufacturer $manufacturer, Request $request)
|
||||
{
|
||||
$manufacturer = $manufacturer->load(
|
||||
'accessories.location',
|
||||
'accessories.company',
|
||||
'accessories.category',
|
||||
'accessories.manufacturer',
|
||||
'accessories.users'
|
||||
);
|
||||
$accessories = $manufacturer->accessories();
|
||||
|
||||
if ($request->has('search')) {
|
||||
$accessories = $accessories->TextSearch(e($request->input('search')));
|
||||
}
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$accessCount = $accessories->count();
|
||||
$accessories = $accessories->skip($offset)->take($limit)->get();
|
||||
$rows = array();
|
||||
|
||||
foreach ($accessories as $accessory) {
|
||||
$rows[] = $accessory->present()->forDataTable();
|
||||
}
|
||||
|
||||
$data = array('total'=>$accessCount, 'rows'=>$rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getDataConsumablesView($manufacturer, Request $request)
|
||||
{
|
||||
$manufacturer = $manufacturer->load(
|
||||
'consumables.location',
|
||||
'consumables.company',
|
||||
'consumables.category',
|
||||
'consumables.manufacturer',
|
||||
'consumables.users'
|
||||
);
|
||||
$consumables = $manufacturer->consumables();
|
||||
|
||||
if ($request->has('search')) {
|
||||
$consumables = $consumables->TextSearch(e($request->input('search')));
|
||||
}
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
|
||||
$consumCount = $consumables->count();
|
||||
$consumables = $consumables->skip($offset)->take($limit)->get();
|
||||
$rows = array();
|
||||
|
||||
foreach ($consumables as $consumable) {
|
||||
$rows[] = $consumable->present()->forDataTable();
|
||||
}
|
||||
|
||||
$data = array('total' => $consumCount, 'rows' => $rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,7 @@ class ProfileController extends Controller
|
||||
public function getIndex()
|
||||
{
|
||||
$user = Auth::user();
|
||||
$location_list = Helper::locationsList();
|
||||
return view('account/profile', compact('user'))->with('location_list', $location_list);
|
||||
return view('account/profile', compact('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,5 +142,25 @@ class ProfileController extends Controller
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the menu state of open/closed when the user clicks on the hamburger
|
||||
* menu.
|
||||
*
|
||||
* This URL is triggered via jquery in
|
||||
* resources/views/layouts/default.blade.php
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
|
||||
public function getMenuState(Request $request) {
|
||||
if ($request->input('state')=='open') {
|
||||
$request->session()->put('menu_state', 'open');
|
||||
} else {
|
||||
$request->session()->put('menu_state', 'closed');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ use Illuminate\Support\Facades\View;
|
||||
use Input;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Reports for
|
||||
@@ -102,18 +103,45 @@ class ReportsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function exportAssetReport()
|
||||
public function exportAssetReport(Request $request)
|
||||
{
|
||||
|
||||
\Debugbar::disable();
|
||||
|
||||
$customfields = CustomField::get();
|
||||
|
||||
$response = new StreamedResponse(function () use ($customfields) {
|
||||
$response = new StreamedResponse(function () use ($customfields, $request) {
|
||||
// Open output stream
|
||||
$handle = fopen('php://output', 'w');
|
||||
|
||||
Asset::with('assignedTo', 'assetLoc','defaultLoc','assignedTo','model','supplier','assetstatus','model.manufacturer')->orderBy('created_at', 'DESC')->chunk(500, function($assets) use($handle, $customfields) {
|
||||
$assets = Asset::with('assignedTo', 'location','defaultLoc','assignedTo','model','supplier','assetstatus','model.manufacturer');
|
||||
|
||||
// This is used by the sidenav, mostly
|
||||
switch ($request->input('status')) {
|
||||
case 'Deleted':
|
||||
$assets->withTrashed()->Deleted();
|
||||
break;
|
||||
case 'Pending':
|
||||
$assets->Pending();
|
||||
break;
|
||||
case 'RTD':
|
||||
$assets->RTD();
|
||||
break;
|
||||
case 'Undeployable':
|
||||
$assets->Undeployable();
|
||||
break;
|
||||
case 'Archived':
|
||||
$assets->Archived();
|
||||
break;
|
||||
case 'Requestable':
|
||||
$assets->RequestableAssets();
|
||||
break;
|
||||
case 'Deployed':
|
||||
$assets->Deployed();
|
||||
break;
|
||||
}
|
||||
|
||||
$assets->orderBy('created_at', 'DESC')->chunk(500, function($assets) use($handle, $customfields) {
|
||||
$headers=[
|
||||
trans('general.company'),
|
||||
trans('admin/hardware/table.asset_tag'),
|
||||
@@ -126,7 +154,7 @@ class ReportsController extends Controller
|
||||
trans('admin/hardware/table.purchase_date'),
|
||||
trans('admin/hardware/table.purchase_cost'),
|
||||
trans('admin/hardware/form.order'),
|
||||
trans('admin/hardware/form.supplier'),
|
||||
trans('general.supplier'),
|
||||
trans('admin/hardware/table.checkoutto'),
|
||||
trans('admin/hardware/table.checkout_date'),
|
||||
trans('admin/hardware/table.location'),
|
||||
@@ -154,7 +182,7 @@ class ReportsController extends Controller
|
||||
($asset->supplier) ? e($asset->supplier->name) : '',
|
||||
($asset->assignedTo) ? e($asset->assignedTo->present()->name()) : '',
|
||||
($asset->last_checkout!='') ? e($asset->last_checkout) : '',
|
||||
e($asset->assetLoc->present()->name()),
|
||||
($asset->location) ? e($asset->location->present()->name()) : '',
|
||||
($asset->notes) ? e($asset->notes) : '',
|
||||
];
|
||||
foreach ($customfields as $field) {
|
||||
@@ -168,7 +196,8 @@ class ReportsController extends Controller
|
||||
fclose($handle);
|
||||
}, 200, [
|
||||
'Content-Type' => 'text/csv',
|
||||
'Content-Disposition' => 'attachment; filename="assets-'.date('Y-m-d-his').'.csv"',
|
||||
'Content-Disposition'
|
||||
=> 'attachment; filename="'.(($request->has('status')) ? trim($request->input('status')) : 'all').'-assets-'.date('Y-m-d-his').'.csv"',
|
||||
]);
|
||||
|
||||
return $response;
|
||||
@@ -186,7 +215,7 @@ class ReportsController extends Controller
|
||||
{
|
||||
|
||||
// Grab all the assets
|
||||
$assets = Asset::with( 'assignedTo', 'assetstatus', 'defaultLoc', 'assetloc', 'assetlog', 'company', 'model.category', 'model.depreciation')
|
||||
$assets = Asset::with( 'assignedTo', 'assetstatus', 'defaultLoc', 'location', 'assetlog', 'company', 'model.category', 'model.depreciation')
|
||||
->orderBy('created_at', 'DESC')->get();
|
||||
|
||||
return view('reports/depreciation', compact('assets'));
|
||||
@@ -241,7 +270,7 @@ class ReportsController extends Controller
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
|
||||
if (( $asset->assigned_to > 0 ) && ( $location = $asset->assetLoc )) {
|
||||
if (( $asset->assigned_to > 0 ) && ( $location = $asset->location )) {
|
||||
if ($location->city) {
|
||||
$row[] = e($location->city) . ', ' . e($location->state);
|
||||
} elseif ($location->name) {
|
||||
@@ -253,8 +282,8 @@ class ReportsController extends Controller
|
||||
$row[] = ''; // Empty string if location is not set
|
||||
}
|
||||
|
||||
if ($asset->assetloc) {
|
||||
$currency = e($asset->assetloc->currency);
|
||||
if ($asset->location) {
|
||||
$currency = e($asset->location->currency);
|
||||
} else {
|
||||
$currency = e(Setting::first()->default_currency);
|
||||
}
|
||||
@@ -533,8 +562,8 @@ class ReportsController extends Controller
|
||||
}
|
||||
|
||||
if (e(Input::get('location')) == '1') {
|
||||
if($asset->assetLoc) {
|
||||
$show_loc = $asset->assetLoc->present()->name();
|
||||
if($asset->location) {
|
||||
$show_loc = $asset->location->present()->name();
|
||||
} else {
|
||||
$show_loc = 'Default location '.$asset->rtd_location_id.' is invalid';
|
||||
}
|
||||
@@ -543,8 +572,8 @@ class ReportsController extends Controller
|
||||
|
||||
|
||||
if (e(Input::get('assigned_to')) == '1') {
|
||||
if ($asset->assignedTo) {
|
||||
$row[] = '"' .e($asset->assignedTo->present()->name()). '"';
|
||||
if ($asset->assignedto) {
|
||||
$row[] = '"' .e($asset->assignedto->present()->name()). '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
@@ -553,7 +582,7 @@ class ReportsController extends Controller
|
||||
if (e(Input::get('username')) == '1') {
|
||||
// Only works if we're checked out to a user, not anything else.
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = '"' .e($asset->assignedTo->username). '"';
|
||||
$row[] = '"' .e($asset->assignedto->username). '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
@@ -562,7 +591,7 @@ class ReportsController extends Controller
|
||||
if (e(Input::get('employee_num')) == '1') {
|
||||
// Only works if we're checked out to a user, not anything else.
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = '"' .e($asset->assignedTo->employee_num). '"';
|
||||
$row[] = '"' .e($asset->assignedto->employee_num). '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ use App\Models\User;
|
||||
use App\Http\Requests\SetupUserRequest;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Http\Requests\SettingsLdapRequest;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Settings for
|
||||
@@ -136,28 +137,6 @@ class SettingsController extends Controller
|
||||
->with('section', 'Pre-Flight Check');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the email configuration
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function ajaxTestEmail()
|
||||
{
|
||||
|
||||
try {
|
||||
Mail::send('emails.test', [], function ($m) {
|
||||
$m->to(config('mail.from.address'), config('mail.from.name'));
|
||||
$m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name'));
|
||||
$m->subject(trans('mail.test_email'));
|
||||
});
|
||||
return 'success';
|
||||
} catch (Exception $e) {
|
||||
return 'error';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the first admin user from Setup.
|
||||
@@ -263,8 +242,8 @@ class SettingsController extends Controller
|
||||
$output = Artisan::output();
|
||||
|
||||
if ((!file_exists(storage_path().'/oauth-private.key')) || (!file_exists(storage_path().'/oauth-public.key'))) {
|
||||
Artisan::call('passport:install');
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
Artisan::call('passport:install');
|
||||
}
|
||||
|
||||
|
||||
@@ -338,7 +317,7 @@ class SettingsController extends Controller
|
||||
$setting->email_format = $request->input('email_format');
|
||||
$setting->username_format = $request->input('username_format');
|
||||
$setting->require_accept_signature = $request->input('require_accept_signature');
|
||||
if (config('app.lock_passwords')) {
|
||||
if (!config('app.lock_passwords')) {
|
||||
$setting->login_note = $request->input('login_note');
|
||||
}
|
||||
|
||||
@@ -391,6 +370,7 @@ class SettingsController extends Controller
|
||||
|
||||
$setting->brand = $request->input('brand', '1');
|
||||
$setting->header_color = $request->input('header_color');
|
||||
$setting->show_url_in_emails = $request->input('show_url_in_emails', '0');
|
||||
|
||||
|
||||
// Only allow the site name and CSS to be changed if lock_passwords is false
|
||||
@@ -414,7 +394,7 @@ class SettingsController extends Controller
|
||||
$file_name = "logo.".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads');
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(null, 40, function ($constraint) {
|
||||
Image::make($image->getRealPath())->resize(null, 150, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
@@ -846,6 +826,7 @@ class SettingsController extends Controller
|
||||
$setting->is_ad = $request->input('is_ad', '0');
|
||||
$setting->ldap_tls = $request->input('ldap_tls', '0');
|
||||
$setting->ldap_pw_sync = $request->input('ldap_pw_sync', '0');
|
||||
$setting->custom_forgot_pass_url = $request->input('custom_forgot_pass_url');
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
@@ -1023,4 +1004,28 @@ class SettingsController extends Controller
|
||||
public function api() {
|
||||
return view('settings.api');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test the email configuration
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function ajaxTestEmail()
|
||||
{
|
||||
try {
|
||||
Mail::send('emails.test', [], function ($m) {
|
||||
$m->to(config('mail.from.address'), config('mail.from.name'));
|
||||
$m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name'));
|
||||
$m->subject(trans('mail.test_email'));
|
||||
});
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, 'Maiol sent!'));
|
||||
} catch (Exception $e) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, $e->getMessage()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,18 +32,17 @@ class StatuslabelsController extends Controller
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('statuslabels/index', compact('statuslabels'));
|
||||
return view('statuslabels.index', compact('statuslabels'));
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$statuslabel = Statuslabel::find($id);
|
||||
|
||||
if (isset($statuslabel->id)) {
|
||||
return view('statuslabels/view', compact('statuslabel'));
|
||||
if ($statuslabel = Statuslabel::find($id)) {
|
||||
return view('statuslabels.view')->with('statuslabel', $statuslabel);
|
||||
}
|
||||
|
||||
return redirect()->route('statuslabels.index')->with('error', trans('admin/locations/message.does_not_exist', compact('id')));
|
||||
return redirect()->route('statuslabels.index')->with('error', trans('admin/statuslabels/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
|
||||
@@ -200,17 +199,15 @@ class StatuslabelsController extends Controller
|
||||
{
|
||||
// Check if the Statuslabel exists
|
||||
if (is_null($statuslabel = Statuslabel::find($statuslabelId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('statuslabels.index')->with('error', trans('admin/statuslabels/message.not_found'));
|
||||
}
|
||||
|
||||
|
||||
if ($statuslabel->has_assets() == 0) {
|
||||
// Check that there are no assets associated
|
||||
if ($statuslabel->assets()->count() == 0) {
|
||||
$statuslabel->delete();
|
||||
// Redirect to the statuslabels management page
|
||||
return redirect()->route('statuslabels.index')->with('success', trans('admin/statuslabels/message.delete.success'));
|
||||
}
|
||||
// Redirect to the asset management page
|
||||
|
||||
return redirect()->route('statuslabels.index')->with('error', trans('admin/statuslabels/message.assoc_assets'));
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ use Str;
|
||||
use View;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\ImageUploadRequest;
|
||||
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
|
||||
@@ -56,7 +57,7 @@ class SuppliersController extends Controller
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(ImageUploadRequest $request)
|
||||
{
|
||||
// Create a new supplier
|
||||
$supplier = new Supplier;
|
||||
@@ -76,20 +77,18 @@ class SuppliersController extends Controller
|
||||
$supplier->url = $supplier->addhttp(request('url'));
|
||||
$supplier->user_id = Auth::id();
|
||||
|
||||
if (Input::file('image')) {
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/suppliers/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(300, null, function ($constraint) {
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$supplier->image = $file_name;
|
||||
$supplier->image = $file_name;
|
||||
}
|
||||
|
||||
// Was it created?
|
||||
if ($supplier->save()) {
|
||||
// Redirect to the new supplier page
|
||||
return redirect()->route('suppliers.index')->with('success', trans('admin/suppliers/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($supplier->getErrors());
|
||||
@@ -136,7 +135,7 @@ class SuppliersController extends Controller
|
||||
* @param int $supplierId
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update($supplierId = null, Request $request)
|
||||
public function update($supplierId = null, ImageUploadRequest $request)
|
||||
{
|
||||
// Check if the supplier exists
|
||||
if (is_null($supplier = Supplier::find($supplierId))) {
|
||||
@@ -159,18 +158,17 @@ class SuppliersController extends Controller
|
||||
$supplier->url = $supplier->addhttp(request('url'));
|
||||
$supplier->notes = request('notes');
|
||||
|
||||
if (Input::file('image')) {
|
||||
|
||||
if ($request->file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/suppliers/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(300, null, function ($constraint) {
|
||||
Image::make($image->getRealPath())->resize(200, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$supplier->image = $file_name;
|
||||
}
|
||||
|
||||
if (request('image_delete') == 1 && $request->file('image') == "") {
|
||||
} elseif ($request->input('image_delete')=='1') {
|
||||
$supplier->image = null;
|
||||
}
|
||||
|
||||
@@ -190,23 +188,29 @@ class SuppliersController extends Controller
|
||||
*/
|
||||
public function destroy($supplierId)
|
||||
{
|
||||
// Check if the supplier exists
|
||||
if (is_null($supplier = Supplier::find($supplierId))) {
|
||||
// Redirect to the suppliers page
|
||||
if (is_null($supplier = Supplier::with('asset_maintenances', 'assets', 'licenses')->withCount('asset_maintenances','assets','licenses')->find($supplierId))) {
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.not_found'));
|
||||
}
|
||||
|
||||
if ($supplier->num_assets() == 0) {
|
||||
// Delete the supplier
|
||||
$supplier->delete();
|
||||
// Redirect to the suppliers management page
|
||||
return redirect()->route('suppliers.index')->with(
|
||||
'success',
|
||||
trans('admin/suppliers/message.delete.success')
|
||||
);
|
||||
|
||||
if ($supplier->assets_count > 0) {
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_assets', ['asset_count' => (int) $supplier->assets_count]));
|
||||
}
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.assoc_users'));
|
||||
|
||||
if ($supplier->asset_maintenances_count > 0) {
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_maintenances', ['asset_maintenances_count' => $supplier->asset_maintenances_count]));
|
||||
}
|
||||
|
||||
if ($supplier->licenses_count > 0) {
|
||||
return redirect()->route('suppliers.index')->with('error', trans('admin/suppliers/message.delete.assoc_licenses', ['licenses_count' => (int) $supplier->licenses_count]));
|
||||
}
|
||||
|
||||
$supplier->delete();
|
||||
return redirect()->route('suppliers.index')->with('success',
|
||||
trans('admin/suppliers/message.delete.success')
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ use URL;
|
||||
use View;
|
||||
use Illuminate\Http\Request;
|
||||
use Gate;
|
||||
use Artisan;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Users for
|
||||
@@ -84,10 +85,6 @@ class UsersController extends Controller
|
||||
$permissions = $this->filterDisplayable($permissions);
|
||||
|
||||
return view('users/edit', compact('groups', 'userGroups', 'permissions', 'userPermissions'))
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('manager_list', Helper::managerList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('department_list', Helper::departmentList())
|
||||
->with('user', new User);
|
||||
}
|
||||
|
||||
@@ -231,9 +228,9 @@ class UsersController extends Controller
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
try {
|
||||
|
||||
$user = User::find($id);
|
||||
if ($user = User::find($id)) {
|
||||
|
||||
$this->authorize('update', $user);
|
||||
$permissions = config('permissions');
|
||||
|
||||
@@ -243,19 +240,14 @@ class UsersController extends Controller
|
||||
$user->permissions = $user->decodePermissions();
|
||||
$userPermissions = Helper::selectedPermissionsArray($permissions, $user->permissions);
|
||||
$permissions = $this->filterDisplayable($permissions);
|
||||
|
||||
} catch (UserNotFoundException $e) {
|
||||
|
||||
$error = trans('admin/users/message.user_not_found', compact('id'));
|
||||
return redirect()->route('users.index')->with('error', $error);
|
||||
return view('users/edit', compact('user', 'groups', 'userGroups', 'permissions', 'userPermissions'))->with('item', $user);
|
||||
}
|
||||
|
||||
// Show the page
|
||||
return view('users/edit', compact('user', 'groups', 'userGroups', 'permissions', 'userPermissions'))
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('department_list', Helper::departmentList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('manager_list', Helper::managerList());
|
||||
$error = trans('admin/users/message.user_not_found', compact('id'));
|
||||
return redirect()->route('users.index')->with('error', $error);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,6 +368,11 @@ class UsersController extends Controller
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
|
||||
}
|
||||
|
||||
if (count($user->assets) > 0) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . count($user->assets) . ' assets associated with them.');
|
||||
}
|
||||
|
||||
if ($user->licenses()->count() > 0) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
|
||||
@@ -429,11 +426,6 @@ class UsersController extends Controller
|
||||
if ($request->input('bulk_actions')=='edit') {
|
||||
|
||||
return view('users/bulk-edit', compact('users'))
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('manager_list', Helper::managerList())
|
||||
->with('manager_list', Helper::managerList())
|
||||
->with('department_list', Helper::departmentList())
|
||||
->with('groups', Group::pluck('name', 'id'));
|
||||
}
|
||||
|
||||
@@ -719,7 +711,7 @@ class UsersController extends Controller
|
||||
$user->first_name = '';
|
||||
$user->last_name = '';
|
||||
$user->email = substr($user->email, ($pos = strpos($user->email, '@')) !== false ? $pos : 0);
|
||||
;
|
||||
|
||||
$user->id = null;
|
||||
|
||||
// Get this user groups
|
||||
@@ -732,10 +724,6 @@ class UsersController extends Controller
|
||||
|
||||
// Show the page
|
||||
return view('users/edit', compact('permissions', 'userPermissions'))
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('manager_list', Helper::managerList())
|
||||
->with('department_list', Helper::departmentList())
|
||||
->with('user', $user)
|
||||
->with('groups', Group::pluck('name', 'id'))
|
||||
->with('userGroups', $userGroups)
|
||||
@@ -1024,128 +1012,20 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function postLDAP(Request $request)
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', '500M');
|
||||
// Call Artisan LDAP import command.
|
||||
$location_id = $request->input('location_id');
|
||||
Artisan::call('snipeit:ldap-sync', ['--location_id' => $location_id, '--json_summary' => true]);
|
||||
|
||||
$ldap_result_username = Setting::getSettings()->ldap_username_field;
|
||||
$ldap_result_last_name = Setting::getSettings()->ldap_lname_field;
|
||||
$ldap_result_first_name = Setting::getSettings()->ldap_fname_field;
|
||||
// Collect and parse JSON summary.
|
||||
$ldap_results_json = Artisan::output();
|
||||
$ldap_results = json_decode($ldap_results_json, true);
|
||||
|
||||
$ldap_result_active_flag = Setting::getSettings()->ldap_active_flag_field;
|
||||
$ldap_result_emp_num = Setting::getSettings()->ldap_emp_num;
|
||||
$ldap_result_email = Setting::getSettings()->ldap_email;
|
||||
|
||||
try {
|
||||
$ldapconn = Ldap::connectToLdap();
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()->withInput()->with('error', $e->getMessage());
|
||||
// Direct user to appropriate status page.
|
||||
if ($ldap_results['error']) {
|
||||
return redirect()->back()->withInput()->with('error', $ldap_results['error_message']);
|
||||
} else {
|
||||
return redirect()->route('ldap/user')->with('success', "LDAP Import successful.")->with('summary', $ldap_results['summary']);
|
||||
}
|
||||
|
||||
try {
|
||||
Ldap::bindAdminToLdap($ldapconn);
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()->withInput()->with('error', $e->getMessage());
|
||||
}
|
||||
|
||||
$summary = array();
|
||||
|
||||
$ldap_ou_locations = Location::whereNotNull('ldap_ou')->get();
|
||||
|
||||
$results = Ldap::findLdapUsers();
|
||||
|
||||
// Inject location information fields
|
||||
for ($i = 0; $i < $results["count"]; $i++) {
|
||||
$results[$i]["ldap_location_override"] = false;
|
||||
$results[$i]["location_id"] = 0;
|
||||
}
|
||||
|
||||
// Grab subsets based on location-specific DNs, and overwrite location for these users.
|
||||
foreach ($ldap_ou_locations as $ldap_loc) {
|
||||
$location_users = Ldap::findLdapUsers($ldap_loc->ldap_ou);
|
||||
$usernames = array();
|
||||
for ($i = 0; $i < $location_users["count"]; $i++) {
|
||||
$location_users[$i]["ldap_location_override"] = true;
|
||||
$location_users[$i]["location_id"] = $ldap_loc->id;
|
||||
$usernames[] = $location_users[$i][$ldap_result_username][0];
|
||||
}
|
||||
|
||||
// Delete located users from the general group.
|
||||
foreach ($results as $key => $generic_entry) {
|
||||
if (in_array($generic_entry[$ldap_result_username][0], $location_users)) {
|
||||
unset($results[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$global_count = $results['count'];
|
||||
$results = array_merge($location_users, $results);
|
||||
$results['count'] = $global_count;
|
||||
}
|
||||
|
||||
$tmp_pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
|
||||
$pass = bcrypt($tmp_pass);
|
||||
|
||||
for ($i = 0; $i < $results["count"]; $i++) {
|
||||
if (empty($ldap_result_active_flag) || $results[$i][$ldap_result_active_flag][0] == "TRUE") {
|
||||
|
||||
$item = array();
|
||||
$item["username"] = isset($results[$i][$ldap_result_username][0]) ? $results[$i][$ldap_result_username][0] : "";
|
||||
$item["employee_number"] = isset($results[$i][$ldap_result_emp_num][0]) ? $results[$i][$ldap_result_emp_num][0] : "";
|
||||
$item["lastname"] = isset($results[$i][$ldap_result_last_name][0]) ? $results[$i][$ldap_result_last_name][0] : "";
|
||||
$item["firstname"] = isset($results[$i][$ldap_result_first_name][0]) ? $results[$i][$ldap_result_first_name][0] : "";
|
||||
$item["email"] = isset($results[$i][$ldap_result_email][0]) ? $results[$i][$ldap_result_email][0] : "" ;
|
||||
$item["ldap_location_override"] = isset($results[$i]["ldap_location_override"]) ? $results[$i]["ldap_location_override"]:"";
|
||||
$item["location_id"] = isset($results[$i]["location_id"]) ? $results[$i]["location_id"]:"";
|
||||
|
||||
if( array_key_exists('useraccountcontrol', $results[$i]) ) {
|
||||
$enabled_accounts = [
|
||||
'512', '544', '66048', '66080', '262656', '262688', '328192', '328224'
|
||||
];
|
||||
$item['activated'] = ( in_array($results[$i]['useraccountcontrol'][0], $enabled_accounts) ) ? 1 : 0;
|
||||
} else {
|
||||
$item['activated'] = 0;
|
||||
}
|
||||
|
||||
// User exists
|
||||
$item["createorupdate"] = 'updated';
|
||||
if (!$user = User::where('username', $item["username"])->first()) {
|
||||
$user = new User;
|
||||
$user->password = $pass;
|
||||
$item["createorupdate"] = 'created';
|
||||
}
|
||||
|
||||
// Create the user if they don't exist.
|
||||
$user->first_name = $item["firstname"];
|
||||
$user->last_name = $item["lastname"];
|
||||
$user->username = $item["username"];
|
||||
$user->email = $item["email"];
|
||||
$user->employee_num = e($item["employee_number"]);
|
||||
$user->activated = $item['activated'];
|
||||
|
||||
if ($item['ldap_location_override'] == true) {
|
||||
$user->location_id = $item['location_id'];
|
||||
} else if ($request->input('location_id')!='') {
|
||||
$user->location_id = e($request->input('location_id'));
|
||||
}
|
||||
$user->notes = 'Imported from LDAP';
|
||||
$user->ldap_import = 1;
|
||||
|
||||
$errors = '';
|
||||
|
||||
if ($user->save()) {
|
||||
$item["note"] = $item["createorupdate"];
|
||||
$item["status"]='success';
|
||||
} else {
|
||||
foreach ($user->getErrors()->getMessages() as $key => $err) {
|
||||
$errors .='<li>'.$err[0];
|
||||
}
|
||||
$item["note"] = $errors;
|
||||
$item["status"]='error';
|
||||
}
|
||||
array_push($summary, $item);
|
||||
}
|
||||
}
|
||||
return redirect()->route('ldap/user')->with('success', "LDAP Import successful.")->with('summary', $summary);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class ViewAssetsController extends Controller
|
||||
public function getRequestableIndex()
|
||||
{
|
||||
|
||||
$assets = Asset::with('model', 'defaultLoc', 'assetloc', 'assignedTo', 'requests')->Hardware()->RequestableAssets()->get();
|
||||
$assets = Asset::with('model', 'defaultLoc', 'location', 'assignedTo', 'requests')->Hardware()->RequestableAssets()->get();
|
||||
$models = AssetModel::with('category', 'requests', 'assets')->RequestableModels()->get();
|
||||
|
||||
return view('account/requestable-assets', compact('user', 'assets', 'models'));
|
||||
|
||||
@@ -19,10 +19,13 @@ class Kernel extends HttpKernel
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\FrameGuard::class,
|
||||
\App\Http\Middleware\XssProtectHeader::class,
|
||||
\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\CheckForDebug::class,
|
||||
// \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
35
app/Http/Middleware/ContentSecurityPolicyHeader.php
Normal file
35
app/Http/Middleware/ContentSecurityPolicyHeader.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class ContentSecurityPolicyHeader
|
||||
{
|
||||
/**
|
||||
* Handle the given request and get the response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ((config('app.debug')=='true') || (config('app.enable_csp')!='true')) {
|
||||
$response = $next($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
$policy[] = "default-src 'self'";
|
||||
$policy[] = "style-src 'self' 'unsafe-inline' oss.maxcdn.com";
|
||||
$policy[] = "script-src 'self' 'unsafe-inline' oss.mafxcdn.com cdnjs.cloudflare.com 'nonce-".csrf_token()."'";
|
||||
$policy[] = "connect-src 'self'";
|
||||
$policy[] = "object-src 'none'";
|
||||
$policy[] = "font-src 'self' data:";
|
||||
$policy[] = "img-src 'self' data: gravatar.com";
|
||||
$policy = join(';', $policy);
|
||||
|
||||
$response = $next($request);
|
||||
$response->headers->set('Content-Security-Policy', $policy);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
21
app/Http/Middleware/ReferrerPolicyHeader.php
Normal file
21
app/Http/Middleware/ReferrerPolicyHeader.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
||||
class ReferrerPolicyHeader
|
||||
{
|
||||
/**
|
||||
* Handle the given request and get the response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$response = $next($request);
|
||||
$response->headers->set('Referrer-Policy', config('app.referrer_policy'));
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,9 @@ class XssProtectHeader
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$mode = '1;mode=block';
|
||||
$response = $next($request);
|
||||
$response->headers->set('X-XSS-Protection', '1');
|
||||
$response->headers->set('X-XSS-Protection', $mode);
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,13 @@ class AssetCheckoutRequest extends Request
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
$rules = [
|
||||
"assigned_user" => 'required_without_all:assigned_asset,assigned_location',
|
||||
"assigned_asset" => 'required_without_all:assigned_user,assigned_location',
|
||||
"assigned_asset" => 'required_without_all:assigned_user,assigned_location|different:'.$this->id,
|
||||
"assigned_location" => 'required_without_all:assigned_user,assigned_asset',
|
||||
];
|
||||
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,12 +30,13 @@ class SaveUserRequest extends Request
|
||||
switch($this->method())
|
||||
{
|
||||
|
||||
// Brand new asset
|
||||
// Brand new user
|
||||
case 'POST':
|
||||
{
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required_unless:ldap_import,1|string|min:1';
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('store');
|
||||
break;
|
||||
}
|
||||
|
||||
// Save all fields
|
||||
@@ -43,11 +44,13 @@ class SaveUserRequest extends Request
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required_unless:ldap_import,1|string|min:1';
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('update');
|
||||
break;
|
||||
|
||||
// Save only what's passed
|
||||
case 'PATCH':
|
||||
{
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('update');
|
||||
break;
|
||||
}
|
||||
|
||||
default:break;
|
||||
|
||||
@@ -25,6 +25,7 @@ class AccessoriesTransformer
|
||||
'name' => e($accessory->name),
|
||||
'company' => ($accessory->company) ? ['id' => $accessory->company->id,'name'=> e($accessory->company->name)] : null,
|
||||
'manufacturer' => ($accessory->manufacturer) ? ['id' => $accessory->manufacturer->id,'name'=> e($accessory->manufacturer->name)] : null,
|
||||
'supplier' => ($accessory->supplier) ? ['id' => $accessory->supplier->id,'name'=> e($accessory->supplier->name)] : null,
|
||||
'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,
|
||||
@@ -35,6 +36,7 @@ class AccessoriesTransformer
|
||||
'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null,
|
||||
'min_qty' => ($accessory->min_amt) ? (int) $accessory->min_amt : null,
|
||||
'remaining_qty' => $accessory->numRemaining(),
|
||||
'image' => ($accessory->image) ? url('/').'/uploads/accessories/'.e($accessory->image) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($accessory->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($accessory->updated_at, 'datetime'),
|
||||
|
||||
@@ -59,13 +61,26 @@ class AccessoriesTransformer
|
||||
}
|
||||
|
||||
|
||||
public function transformCheckedoutAccessories (Collection $accessories_users, $total)
|
||||
public function transformCheckedoutAccessory ($accessory_users, $total)
|
||||
{
|
||||
|
||||
|
||||
$array = array();
|
||||
foreach ($accessories_users as $user) {
|
||||
$array[] = (new UsersTransformer)->transformUser($user);
|
||||
foreach ($accessory_users as $user) {
|
||||
$array[] = [
|
||||
'assigned_pivot_id' => $user->pivot->id,
|
||||
'id' => (int) $user->id,
|
||||
'username' => e($user->username),
|
||||
'name' => e($user->getFullNameAttribute()),
|
||||
'first_name'=> e($user->first_name),
|
||||
'last_name'=> e($user->last_name),
|
||||
'employee_number' => e($user->employee_num),
|
||||
'type' => 'user',
|
||||
'available_actions' => ['checkin' => true]
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ class ActionlogsTransformer
|
||||
'type' => e($actionlog->targetType()),
|
||||
] : null,
|
||||
|
||||
'note' => e($actionlog->note),
|
||||
'note' => ($actionlog->note) ? e($actionlog->note): null,
|
||||
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
|
||||
|
||||
|
||||
];
|
||||
|
||||
@@ -47,13 +47,15 @@ class AssetModelsTransformer
|
||||
'notes' => e($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'),
|
||||
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', AssetModel::class) ? true : false,
|
||||
'delete' => Gate::allows('delete', AssetModel::class) ? true : false,
|
||||
'clone' => Gate::allows('create', AssetModel::class) ? true : false,
|
||||
'update' => (Gate::allows('update', AssetModel::class) && ($assetmodel->deleted_at=='')) ? true : false,
|
||||
'delete' => (Gate::allows('delete', AssetModel::class) && ($assetmodel->deleted_at=='')) ? true : false,
|
||||
'clone' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at=='')) ,
|
||||
'restore' => (Gate::allows('create', AssetModel::class) && ($assetmodel->deleted_at!='')) ? true : false,
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
@@ -30,10 +30,11 @@ class AssetsTransformer
|
||||
'id' => (int) $asset->model->id,
|
||||
'name'=> e($asset->model->name)
|
||||
] : null,
|
||||
'model_number' => ($asset->model) ? e($asset->model->model_number) : null,
|
||||
'model_number' => (($asset->model) && ($asset->model->model_number)) ? e($asset->model->model_number) : null,
|
||||
'status_label' => ($asset->assetstatus) ? [
|
||||
'id' => (int) $asset->assetstatus->id,
|
||||
'name'=> e($asset->assetstatus->name)
|
||||
'name'=> e($asset->present()->statusText),
|
||||
'status_meta' => e($asset->present()->statusMeta),
|
||||
] : null,
|
||||
'category' => ($asset->model->category) ? [
|
||||
'id' => (int) $asset->model->category->id,
|
||||
@@ -47,15 +48,15 @@ class AssetsTransformer
|
||||
'id' => (int) $asset->supplier->id,
|
||||
'name'=> e($asset->supplier->name)
|
||||
] : null,
|
||||
'notes' => e($asset->notes),
|
||||
'notes' => ($asset->notes) ? e($asset->notes) : null,
|
||||
'order_number' => e($asset->order_number),
|
||||
'company' => ($asset->company) ? [
|
||||
'id' => (int) $asset->company->id,
|
||||
'name'=> e($asset->company->name)
|
||||
] : null,
|
||||
'location' => ($asset->assetLoc) ? [
|
||||
'id' => (int) $asset->assetLoc->id,
|
||||
'name'=> e($asset->assetLoc->name)
|
||||
'location' => ($asset->location) ? [
|
||||
'id' => (int) $asset->location->id,
|
||||
'name'=> e($asset->location->name)
|
||||
] : null,
|
||||
'rtd_location' => ($asset->defaultLoc) ? [
|
||||
'id' => (int) $asset->defaultLoc->id,
|
||||
@@ -67,6 +68,7 @@ class AssetsTransformer
|
||||
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
|
||||
'created_at' => Helper::getFormattedDateObject($asset->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($asset->updated_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($asset->deleted_at, 'datetime'),
|
||||
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
|
||||
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
|
||||
'expected_checkin' => Helper::getFormattedDateObject($asset->expected_checkin, 'date'),
|
||||
@@ -75,8 +77,9 @@ class AssetsTransformer
|
||||
];
|
||||
|
||||
|
||||
if ($asset->model->fieldset) {
|
||||
if (($asset->model->fieldset) && (count($asset->model->fieldset->fields)> 0)) {
|
||||
$fields_array = array();
|
||||
|
||||
foreach ($asset->model->fieldset->fields as $field) {
|
||||
|
||||
if ($field->isFieldDecryptable($asset->{$field->convertUnicodeDbSlug()})) {
|
||||
@@ -127,19 +130,19 @@ class AssetsTransformer
|
||||
public function transformAssignedTo($asset)
|
||||
{
|
||||
if ($asset->checkedOutToUser()) {
|
||||
return $asset->assignedTo ? [
|
||||
'id' => (int) $asset->assignedTo->id,
|
||||
'username' => e($asset->assignedTo->username),
|
||||
'name' => e($asset->assignedTo->getFullNameAttribute()),
|
||||
'first_name'=> e($asset->assignedTo->first_name),
|
||||
'last_name'=> e($asset->assignedTo->last_name),
|
||||
'employee_number' => e($asset->assignedTo->employee_num),
|
||||
return $asset->assigned ? [
|
||||
'id' => (int) $asset->assigned->id,
|
||||
'username' => e($asset->assigned->username),
|
||||
'name' => e($asset->assigned->getFullNameAttribute()),
|
||||
'first_name'=> e($asset->assigned->first_name),
|
||||
'last_name'=> ($asset->assigned->last_name) ? e($asset->assigned->last_name) : null,
|
||||
'employee_number' => ($asset->assigned->employee_num) ? e($asset->assigned->employee_num) : null,
|
||||
'type' => 'user'
|
||||
] : null;
|
||||
}
|
||||
return $asset->assignedTo ? [
|
||||
'id' => $asset->assignedTo->id,
|
||||
'name' => $asset->assignedTo->display_name,
|
||||
return $asset->assigned ? [
|
||||
'id' => $asset->assigned->id,
|
||||
'name' => $asset->assigned->display_name,
|
||||
'type' => $asset->assignedType()
|
||||
] : null;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,9 @@ class CategoriesTransformer
|
||||
$array = [
|
||||
'id' => (int) $category->id,
|
||||
'name' => e($category->name),
|
||||
'image' => ($category->image) ? e(url('/').'/uploads/categories/'.e($category->image)) : null,
|
||||
'type' => e($category->category_type),
|
||||
'use_default_eula' => ($category->use_default_eula =='1') ? true : false,
|
||||
'eula' => ($category->getEula()) ? true : false,
|
||||
'checkin_email' => ($category->checkin_email =='1') ? true : false,
|
||||
'require_acceptance' => ($category->require_acceptance =='1') ? true : false,
|
||||
'assets_count' => $category->assets_count,
|
||||
@@ -39,7 +40,7 @@ class CategoriesTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Category::class) ? true : false,
|
||||
'delete' => Gate::allows('delete', 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,
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
@@ -25,6 +25,7 @@ class CompaniesTransformer
|
||||
$array = [
|
||||
'id' => (int) $company->id,
|
||||
'name' => e($company->name),
|
||||
'image' => ($company->image) ? e(url('/').'/uploads/companies/'.e($company->image)) : null,
|
||||
"created_at" => Helper::getFormattedDateObject($company->created_at, 'datetime'),
|
||||
"updated_at" => Helper::getFormattedDateObject($company->updated_at, 'datetime'),
|
||||
"assets_count" => (int) $company->assets_count,
|
||||
|
||||
@@ -22,7 +22,8 @@ class ComponentsTransformer
|
||||
$array = [
|
||||
'id' => (int) $component->id,
|
||||
'name' => e($component->name),
|
||||
'serial_number' => e($component->serial),
|
||||
'image' => ($component->image) ? e(url('/').'/uploads/components/'.e($component->image)) : null,
|
||||
'serial_number' => ($component->serial) ? e($component->serial) : null,
|
||||
'location' => ($component->location) ? [
|
||||
'id' => (int) $component->location->id,
|
||||
'name' => e($component->location->name)
|
||||
@@ -58,12 +59,22 @@ class ComponentsTransformer
|
||||
}
|
||||
|
||||
|
||||
public function transformCheckedoutComponents(Collection $components_users, $total)
|
||||
public function transformCheckedoutComponents(Collection $components_assets, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($components_users as $user) {
|
||||
$array[] = (new UsersTransformer)->transformUser($user);
|
||||
foreach ($components_assets as $asset) {
|
||||
$array[] = [
|
||||
'assigned_pivot_id' => $asset->pivot->id,
|
||||
'id' => (int) $asset->id,
|
||||
'name' => e($asset->model->present()->name) .' '.e($asset->present()->name),
|
||||
'qty' => $asset->pivot->assigned_qty,
|
||||
'type' => 'asset',
|
||||
'created_at' => Helper::getFormattedDateObject($asset->pivot->created_at, 'datetime'),
|
||||
'available_actions' => ['checkin' => true]
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ class ConsumablesTransformer
|
||||
{
|
||||
$array = [
|
||||
'id' => (int) $consumable->id,
|
||||
'name' => e($consumable->name),
|
||||
'image' => ($consumable->image) ? e(url('/').'/uploads/consumables/'.e($consumable->image)) : null,
|
||||
'category' => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => e($consumable->category->name)] : null,
|
||||
'company' => ($consumable->company) ? ['id' => (int) $consumable->company->id, 'name' => e($consumable->company->name)] : null,
|
||||
'item_no' => e($consumable->item_no),
|
||||
@@ -29,7 +31,6 @@ class ConsumablesTransformer
|
||||
'manufacturer' => ($consumable->manufacturer) ? ['id' => (int) $consumable->manufacturer->id, 'name' => e($consumable->manufacturer->name)] : null,
|
||||
'min_amt' => (int) $consumable->min_amt,
|
||||
'model_number' => e($consumable->model_number),
|
||||
'name' => e($consumable->name),
|
||||
'remaining' => $consumable->numRemaining(),
|
||||
'order_number' => e($consumable->order_number),
|
||||
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
|
||||
|
||||
@@ -25,6 +25,7 @@ class DepartmentsTransformer
|
||||
$array = [
|
||||
'id' => (int) $department->id,
|
||||
'name' => e($department->name),
|
||||
'image' => ($department->image) ? e(url('/').'/uploads/departments/'.e($department->image)) : null,
|
||||
'company' => ($department->company) ? [
|
||||
'id' => (int) $department->company->id,
|
||||
'name'=> e($department->company->name)
|
||||
|
||||
@@ -23,7 +23,7 @@ class GroupsTransformer
|
||||
$array = [
|
||||
'id' => (int) $group->id,
|
||||
'name' => e($group->name),
|
||||
'permissions' => $group->permissions,
|
||||
'permissions' => json_decode($group->permissions),
|
||||
'users_count' => (int) $group->users_count,
|
||||
'created_at' => Helper::getFormattedDateObject($group->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($group->updated_at, 'datetime'),
|
||||
|
||||
@@ -29,7 +29,6 @@ class ImportsTransformer
|
||||
'header_row' => $import->header_row,
|
||||
'first_row' => $import->first_row,
|
||||
'field_map' => $import->field_map,
|
||||
|
||||
];
|
||||
|
||||
return $array;
|
||||
|
||||
@@ -33,13 +33,14 @@ class LocationsTransformer
|
||||
$array = [
|
||||
'id' => (int) $location->id,
|
||||
'name' => e($location->name),
|
||||
'image' => ($location->image) ? e(url('/').'/uploads/locations/'.e($location->image)) : null,
|
||||
'address' => e($location->address),
|
||||
'city' => e($location->city),
|
||||
'state' => e($location->state),
|
||||
'country' => e($location->country),
|
||||
'zip' => e($location->zip),
|
||||
'assets_checkedout' => $location->assets()->count(),
|
||||
'assets_default' => $location->assignedassets()->count(),
|
||||
'assets_checkedout' => $location->location_assets_count,
|
||||
'assets_default' => $location->assigned_assets_count,
|
||||
|
||||
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($location->updated_at, 'datetime'),
|
||||
|
||||
@@ -26,6 +26,7 @@ class ManufacturersTransformer
|
||||
'id' => (int) $manufacturer->id,
|
||||
'name' => e($manufacturer->name),
|
||||
'url' => e($manufacturer->url),
|
||||
'image' => ($manufacturer->image) ? e(url('/').'/uploads/manufacturers/'.e($manufacturer->image)) : null,
|
||||
'support_url' => e($manufacturer->support_url),
|
||||
'support_phone' => e($manufacturer->support_phone),
|
||||
'support_email' => e($manufacturer->support_email),
|
||||
|
||||
51
app/Http/Transformers/SelectlistTransformer.php
Normal file
51
app/Http/Transformers/SelectlistTransformer.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class SelectlistTransformer
|
||||
*
|
||||
* This handles the standardized formatting of the API response we need to provide for
|
||||
* the rich (text and images) Select2 javascript.
|
||||
*
|
||||
* @package App\Http\Transformers
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0.16]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
|
||||
class SelectlistTransformer
|
||||
{
|
||||
|
||||
public function transformSelectlist (LengthAwarePaginator $select_items)
|
||||
{
|
||||
$items_array = [];
|
||||
|
||||
// Loop through the paginated collection to set the array values
|
||||
foreach ($select_items as $select_item) {
|
||||
$items_array[]= [
|
||||
'id' => (int) $select_item->id,
|
||||
'text' => ($select_item->use_text) ? e($select_item->use_text) : e($select_item->name),
|
||||
'image' => ($select_item->use_image) ? e($select_item->use_image) : null,
|
||||
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
$results = [
|
||||
'items' => $items_array,
|
||||
'pagination' =>
|
||||
[
|
||||
'more' => ($select_items->currentPage() >= $select_items->lastPage()) ? false : true,
|
||||
'per_page' => $select_items->perPage()
|
||||
],
|
||||
'total_count' => $select_items->total(),
|
||||
'page' => $select_items->currentPage(),
|
||||
'page_count' => $select_items->lastPage()
|
||||
];
|
||||
|
||||
return $results;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ class StatuslabelsTransformer
|
||||
'type' => $statuslabel->getStatuslabelType(),
|
||||
'color' => ($statuslabel->color) ? e($statuslabel->color) : null,
|
||||
'show_in_nav' => ($statuslabel->show_in_nav=='1') ? true : false,
|
||||
'assets_count' => (int) $statuslabel->assets_count,
|
||||
'notes' => e($statuslabel->notes),
|
||||
'created_at' => Helper::getFormattedDateObject($statuslabel->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($statuslabel->updated_at, 'datetime'),
|
||||
@@ -33,7 +34,7 @@ class StatuslabelsTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Statuslabel::class) ? true : false,
|
||||
'delete' => Gate::allows('delete', Statuslabel::class) ? true : false,
|
||||
'delete' => (Gate::allows('delete', Statuslabel::class) && ($statuslabel->assets_count == 0)) ? true : false,
|
||||
];
|
||||
$array += $permissions_array;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ class SuppliersTransformer
|
||||
$array = [
|
||||
'id' => (int) $supplier->id,
|
||||
'name' => e($supplier->name),
|
||||
'image' => ($supplier->image) ? e(url('/').'/uploads/suppliers/'.e($supplier->image)) : null,
|
||||
'address' => ($supplier->address) ? e($supplier->address) : null,
|
||||
'address2' => ($supplier->address2) ? e($supplier->address2) : null,
|
||||
'city' => ($supplier->city) ? e($supplier->city) : null,
|
||||
@@ -36,8 +37,8 @@ class SuppliersTransformer
|
||||
'email' => ($supplier->email) ? e($supplier->email) : null,
|
||||
'contact' => ($supplier->contact) ? e($supplier->contact) : null,
|
||||
'assets_count' => (int) $supplier->assets_count,
|
||||
'accessories_count' => (int) $supplier->accessories_count,
|
||||
'licenses_count' => (int) $supplier->licenses_count,
|
||||
'image' => ($supplier->image) ? e($supplier->image) : null,
|
||||
'notes' => ($supplier->notes) ? e($supplier->notes) : null,
|
||||
'created_at' => Helper::getFormattedDateObject($supplier->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($supplier->updated_at, 'datetime'),
|
||||
@@ -46,7 +47,7 @@ class SuppliersTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Supplier::class) ? true : false,
|
||||
'delete' => Gate::allows('delete', Supplier::class) ? true : false,
|
||||
'delete' => (Gate::allows('delete', Supplier::class) && ($supplier->assets_count == 0) && ($supplier->licenses_count == 0) && ($supplier->accessories_count == 0)) ? true : false,
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
@@ -23,6 +23,7 @@ class UsersTransformer
|
||||
{
|
||||
$array = [
|
||||
'id' => (int) $user->id,
|
||||
'avatar' => e($user->present()->gravatar),
|
||||
'name' => e($user->first_name).' '.($user->last_name),
|
||||
'firstname' => e($user->first_name),
|
||||
'lastname' => e($user->last_name),
|
||||
@@ -33,6 +34,7 @@ class UsersTransformer
|
||||
'name'=> e($user->manager->username)
|
||||
] : null,
|
||||
'jobtitle' => ($user->jobtitle) ? e($user->jobtitle) : null,
|
||||
'phone' => ($user->phone) ? e($user->phone) : null,
|
||||
'email' => e($user->email),
|
||||
'department' => ($user->department) ? [
|
||||
'id' => (int) $user->department->id,
|
||||
@@ -42,6 +44,7 @@ class UsersTransformer
|
||||
'id' => (int) $user->userloc->id,
|
||||
'name'=> e($user->userloc->name)
|
||||
] : null,
|
||||
'notes'=> e($user->notes),
|
||||
'permissions' => $user->decodePermissions(),
|
||||
'activated' => ($user->activated =='1') ? true : false,
|
||||
'two_factor_activated' => ($user->two_factor_active()) ? true : false,
|
||||
@@ -57,7 +60,7 @@ class UsersTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => (Gate::allows('update', User::class) && ($user->deleted_at=='')) ? true : false,
|
||||
'delete' => (Gate::allows('delete', User::class) && ($user->deleted_at=='')) ? true : false,
|
||||
'delete' => (Gate::allows('delete', User::class) && ($user->deleted_at=='') && ($user->assets_count == 0) && ($user->licenses_count == 0) && ($user->accessories_count == 0) && ($user->consumables_count == 0)) ? true : false,
|
||||
'clone' => (Gate::allows('create', User::class) && ($user->deleted_at=='')) ,
|
||||
'restore' => (Gate::allows('create', User::class) && ($user->deleted_at!='')) ? true : false,
|
||||
];
|
||||
|
||||
@@ -23,14 +23,20 @@ class AssetImporter extends ItemImporter
|
||||
// ItemImporter handles the general fetching.
|
||||
parent::handle($row);
|
||||
|
||||
foreach ($this->customFields as $customField) {
|
||||
$customFieldValue = $this->array_smart_custom_field_fetch($row, $customField);
|
||||
if ($customFieldValue) {
|
||||
$this->item['custom_fields'][$customField->db_column_name()] = $customFieldValue;
|
||||
$this->log('Custom Field '. $customField->name.': '.$customFieldValue);
|
||||
if ($this->customFields) {
|
||||
|
||||
foreach ($this->customFields as $customField) {
|
||||
$customFieldValue = $this->array_smart_custom_field_fetch($row, $customField);
|
||||
if ($customFieldValue) {
|
||||
$this->item['custom_fields'][$customField->db_column_name()] = $customFieldValue;
|
||||
$this->log('Custom Field '. $customField->name.': '.$customFieldValue);
|
||||
} else {
|
||||
$this->item['custom_fields'][$customField->db_column_name()] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->createAssetIfNotExists($row);
|
||||
}
|
||||
|
||||
@@ -61,7 +67,7 @@ class AssetImporter extends ItemImporter
|
||||
}
|
||||
|
||||
$this->item['image'] = $this->findCsvMatch($row, "image");
|
||||
$this->item['warranty_months'] = intval($this->findCsvMatch($row, "warranty"));
|
||||
$this->item['warranty_months'] = intval($this->findCsvMatch($row, "warranty_months"));
|
||||
$this->item['model_id'] = $this->createOrFetchAssetModel($row);
|
||||
|
||||
// If no status ID is found
|
||||
|
||||
@@ -33,10 +33,12 @@ class LicenseImporter extends ItemImporter
|
||||
public function createLicenseIfNotExists(array $row)
|
||||
{
|
||||
$editingLicense = false;
|
||||
$license = License::where('name', $this->item['name'])->first();
|
||||
$license = License::where('name', $this->item['name'])
|
||||
->where('serial', $this->item['serial'])
|
||||
->first();
|
||||
if ($license) {
|
||||
if (!$this->updating) {
|
||||
$this->log('A matching License ' . $this->item['name'] . ' already exists');
|
||||
$this->log('A matching License ' . $this->item['name'] . 'with serial ' . $this->item['serial'] . ' already exists');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class Accessory extends SnipeModel
|
||||
use Loggable, Presentable;
|
||||
use SoftDeletes;
|
||||
|
||||
protected $dates = ['deleted_at', 'purchase_date'];
|
||||
protected $dates = ['deleted_at'];
|
||||
protected $table = 'accessories';
|
||||
protected $casts = [
|
||||
'requestable' => 'boolean'
|
||||
@@ -61,10 +61,19 @@ class Accessory extends SnipeModel
|
||||
'purchase_date',
|
||||
'model_number',
|
||||
'manufacturer_id',
|
||||
'supplier_id',
|
||||
'image',
|
||||
'qty',
|
||||
'requestable'
|
||||
];
|
||||
|
||||
|
||||
public function supplier()
|
||||
{
|
||||
return $this->belongsTo('\App\Models\Supplier', 'supplier_id');
|
||||
}
|
||||
|
||||
|
||||
public function setRequestableAttribute($value)
|
||||
{
|
||||
if ($value == '') {
|
||||
|
||||
@@ -85,6 +85,7 @@ class Asset extends Depreciable
|
||||
'model_id',
|
||||
'name',
|
||||
'notes',
|
||||
'order_number',
|
||||
'purchase_cost',
|
||||
'purchase_date',
|
||||
'rtd_location_id',
|
||||
@@ -126,11 +127,10 @@ class Asset extends Depreciable
|
||||
|
||||
public function availableForCheckout()
|
||||
{
|
||||
return (
|
||||
empty($this->assigned_to) &&
|
||||
$this->assetstatus->deployable == 1 &&
|
||||
empty($this->deleted_at)
|
||||
);
|
||||
if ((empty($this->assigned_to)) && (empty($this->deleted_at)) && ($this->assetstatus->deployable == 1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,13 +179,14 @@ class Asset extends Depreciable
|
||||
|
||||
public function getDetailedNameAttribute()
|
||||
{
|
||||
if ($this->assignedTo) {
|
||||
$user_name = $this->assignedTo->present()->name();
|
||||
if ($this->assignedto) {
|
||||
$user_name = $this->assignedto->present()->name();
|
||||
} else {
|
||||
$user_name = "Unassigned";
|
||||
}
|
||||
return $this->asset_tag . ' - ' . $this->name . ' (' . $user_name . ') ' . $this->model->name;
|
||||
return $this->asset_tag . ' - ' . $this->name . ' (' . $user_name . ') ' . ($this->model) ? $this->model->name: '';
|
||||
}
|
||||
|
||||
public function validationRules($id = '0')
|
||||
{
|
||||
return $this->rules;
|
||||
@@ -253,23 +254,33 @@ class Asset extends Depreciable
|
||||
**/
|
||||
public function assetLoc()
|
||||
{
|
||||
static $iterations=0;
|
||||
static $first_asset;
|
||||
if (!empty($this->assignedType())) {
|
||||
// dd($this->assignedType());
|
||||
if ($this->assignedType() == self::ASSET) {
|
||||
return $this->assignedto->assetloc(); // Recurse until we have a final location
|
||||
$iterations++;
|
||||
if(!$first_asset) {
|
||||
$first_asset=$this;
|
||||
}
|
||||
if($iterations>10) {
|
||||
throw new \Exception("Asset assignment Loop for Asset ID: ".$first_asset->id);
|
||||
}
|
||||
$assigned_to=Asset::find($this->assigned_to); //have to do this this way because otherwise it errors
|
||||
return $assigned_to->assetLoc(); // Recurse until we have a final location
|
||||
}
|
||||
if ($this->assignedType() == self::LOCATION) {
|
||||
return $this->assignedTo();
|
||||
return $this->assignedTo;
|
||||
}
|
||||
if ($this->assignedType() == self::USER) {
|
||||
if (!$this->assignedTo) {
|
||||
return $this->defaultLoc();
|
||||
if (!$this->assignedTo->userLoc) {
|
||||
//this makes no sense
|
||||
return $this->defaultLoc;
|
||||
}
|
||||
return $this->assignedTo->userLoc();
|
||||
return $this->assignedTo->userLoc;
|
||||
}
|
||||
|
||||
}
|
||||
return $this->defaultLoc();
|
||||
return $this->defaultLoc;
|
||||
}
|
||||
|
||||
public function assignedType()
|
||||
@@ -405,6 +416,12 @@ class Asset extends Depreciable
|
||||
}
|
||||
|
||||
|
||||
public function location()
|
||||
{
|
||||
return $this->belongsTo('\App\Models\Location', 'location_id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get auto-increment
|
||||
@@ -486,7 +503,7 @@ class Asset extends Depreciable
|
||||
} elseif ($this->model->category->use_default_eula == '1') {
|
||||
return $Parsedown->text(e(Setting::getSettings()->default_eula_text));
|
||||
} else {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,7 +742,8 @@ class Asset extends Depreciable
|
||||
|
||||
|
||||
/**
|
||||
* Query builder scope to search on text for complex Bootstrap Tables API
|
||||
* Query builder scope to search on text for complex Bootstrap Tables API.
|
||||
* This is really horrible, but I can't think of a less-awful way to do it.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||
* @param text $search Search term
|
||||
@@ -736,7 +754,16 @@ class Asset extends Depreciable
|
||||
{
|
||||
$search = explode(' OR ', $search);
|
||||
|
||||
return $query->where(function ($query) use ($search) {
|
||||
return $query->leftJoin('users',function ($leftJoin) {
|
||||
$leftJoin->on("users.id", "=", "assets.assigned_to")
|
||||
->where("assets.assigned_type", "=", User::class);
|
||||
})->leftJoin('locations',function ($leftJoin) {
|
||||
$leftJoin->on("locations.id","=","assets.assigned_to")
|
||||
->where("assets.assigned_type","=",Location::class);
|
||||
})->leftJoin('assets as assigned_assets',function ($leftJoin) {
|
||||
$leftJoin->on('assigned_assets.id', '=', 'assets.assigned_to')
|
||||
->where('assets.assigned_type', '=', Asset::class);
|
||||
})->where(function ($query) use ($search) {
|
||||
foreach ($search as $search) {
|
||||
$query->whereHas('model', function ($query) use ($search) {
|
||||
$query->whereHas('category', function ($query) use ($search) {
|
||||
@@ -769,26 +796,12 @@ class Asset extends Depreciable
|
||||
$query->whereHas('defaultLoc', function ($query) use ($search) {
|
||||
$query->where('locations.name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
//FIXME: This needs attention to work with checkout to not-users.
|
||||
// })->orWhere(function ($query) use ($search) {
|
||||
// $query->whereHas('assignedTo', function ($query) use ($search) {
|
||||
// $query->where(function ($query) use ($search) {
|
||||
// $query->where('assets.assigned_type', '=', User::class)
|
||||
// ->join('users', 'users.id', '=', 'assets.assigned_to')
|
||||
// ->where(function($query) use ($search) {
|
||||
// $query->where('users.first_name', 'LIKE', '%'.$search.'%')
|
||||
// ->orWhere('users.last_name', 'LIKE', '%'.$search.'%');
|
||||
// });
|
||||
// })->orWhere(function ($query) use ($search) {
|
||||
// $query->where('assets.assigned_type', '=', Location::class)
|
||||
// ->join('locations', 'locations.id', '=', 'assets.assigned_to')
|
||||
// ->where('locations.name', 'LIKE', '%'.$search.'%');
|
||||
// })->orWhere(function ($query) use ($search) {
|
||||
// $query->where('assets.assigned_type', '=', Asset::class)
|
||||
// ->join('assets as assigned_asset', 'assigned_assets.id', '=', 'assets.assigned_to')
|
||||
// ->where('assigned_assets.name', 'LIKE', '%'.$search.'%');
|
||||
// });
|
||||
// });
|
||||
})->orWhere(function ($query) use ($search) {
|
||||
$query->where('users.first_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('users.last_name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('users.username', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('locations.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assigned_assets.name', 'LIKE', '%'.$search.'%');
|
||||
})->orWhere('assets.name', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets.asset_tag', 'LIKE', '%'.$search.'%')
|
||||
->orWhere('assets.serial', 'LIKE', '%'.$search.'%')
|
||||
@@ -796,9 +809,9 @@ class Asset extends Depreciable
|
||||
->orWhere('assets.notes', 'LIKE', '%'.$search.'%');
|
||||
}
|
||||
foreach (CustomField::all() as $field) {
|
||||
$query->orWhere($field->db_column_name(), 'LIKE', "%$search%");
|
||||
$query->orWhere('assets.'.$field->db_column_name(), 'LIKE', "%$search%");
|
||||
}
|
||||
});
|
||||
})->withTrashed()->whereNull("assets.deleted_at"); //workaround for laravel bug
|
||||
}
|
||||
|
||||
|
||||
@@ -815,57 +828,60 @@ class Asset extends Depreciable
|
||||
{
|
||||
return $query->where(function ($query) use ($filter) {
|
||||
foreach ($filter as $key => $search_val) {
|
||||
if ($key =='asset_tag') {
|
||||
|
||||
$fieldname = str_replace('custom_fields.','', $key) ;
|
||||
|
||||
if ($fieldname =='asset_tag') {
|
||||
$query->where('assets.asset_tag', 'LIKE', '%'.$search_val.'%');
|
||||
}
|
||||
|
||||
if ($key =='name') {
|
||||
if ($fieldname =='name') {
|
||||
$query->where('assets.name', 'LIKE', '%'.$search_val.'%');
|
||||
}
|
||||
|
||||
if ($key =='product_key') {
|
||||
if ($fieldname =='product_key') {
|
||||
$query->where('assets.serial', 'LIKE', '%'.$search_val.'%');
|
||||
}
|
||||
|
||||
if ($key =='purchase_date') {
|
||||
if ($fieldname =='purchase_date') {
|
||||
$query->where('assets.purchase_date', 'LIKE', '%'.$search_val.'%');
|
||||
}
|
||||
|
||||
if ($key =='purchase_cost') {
|
||||
if ($fieldname =='purchase_cost') {
|
||||
$query->where('assets.purchase_cost', 'LIKE', '%'.$search_val.'%');
|
||||
}
|
||||
|
||||
if ($key =='notes') {
|
||||
if ($fieldname =='notes') {
|
||||
$query->where('assets.notes', 'LIKE', '%'.$search_val.'%');
|
||||
}
|
||||
|
||||
if ($key =='order_number') {
|
||||
if ($fieldname =='order_number') {
|
||||
$query->where('assets.order_number', 'LIKE', '%'.$search_val.'%');
|
||||
}
|
||||
|
||||
if ($key =='status_label') {
|
||||
if ($fieldname =='status_label') {
|
||||
$query->whereHas('assetstatus', function ($query) use ($search_val) {
|
||||
$query->where('status_labels.name', 'LIKE', '%' . $search_val . '%');
|
||||
});
|
||||
}
|
||||
|
||||
if ($key =='location') {
|
||||
if ($fieldname =='location') {
|
||||
$query->whereHas('defaultLoc', function ($query) use ($search_val) {
|
||||
$query->where('locations.name', 'LIKE', '%' . $search_val . '%');
|
||||
});
|
||||
}
|
||||
|
||||
if ($key =='checkedout_to') {
|
||||
$query->whereHas('assigneduser', function ($query) use ($search) {
|
||||
$query->where(function ($query) use ($search) {
|
||||
$query->where('users.first_name', 'LIKE', '%' . $search . '%')
|
||||
->orWhere('users.last_name', 'LIKE', '%' . $search . '%');
|
||||
if ($fieldname =='checkedout_to') {
|
||||
$query->whereHas('assigneduser', function ($query) use ($search_val) {
|
||||
$query->where(function ($query) use ($search_val) {
|
||||
$query->where('users.first_name', 'LIKE', '%' . $search_val . '%')
|
||||
->orWhere('users.last_name', 'LIKE', '%' . $search_val . '%');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if ($key =='manufacturer') {
|
||||
if ($fieldname =='manufacturer') {
|
||||
$query->whereHas('model', function ($query) use ($search_val) {
|
||||
$query->whereHas('manufacturer', function ($query) use ($search_val) {
|
||||
$query->where(function ($query) use ($search_val) {
|
||||
@@ -875,9 +891,9 @@ class Asset extends Depreciable
|
||||
});
|
||||
}
|
||||
|
||||
if ($key =='category') {
|
||||
$query->whereHas('model', function ($query) use ($search) {
|
||||
$query->whereHas('category', function ($query) use ($search) {
|
||||
if ($fieldname =='category') {
|
||||
$query->whereHas('model', function ($query) use ($search_val) {
|
||||
$query->whereHas('category', function ($query) use ($search_val) {
|
||||
$query->where(function ($query) use ($search_val) {
|
||||
$query->where('categories.name', 'LIKE', '%' . $search_val . '%')
|
||||
->orWhere('models.name', 'LIKE', '%' . $search_val . '%')
|
||||
@@ -887,7 +903,7 @@ class Asset extends Depreciable
|
||||
});
|
||||
}
|
||||
|
||||
if ($key =='model') {
|
||||
if ($fieldname =='model') {
|
||||
$query->where(function ($query) use ($search_val) {
|
||||
$query->whereHas('model', function ($query) use ($search_val) {
|
||||
$query->where('models.name', 'LIKE', '%' . $search_val . '%');
|
||||
@@ -895,7 +911,7 @@ class Asset extends Depreciable
|
||||
});
|
||||
}
|
||||
|
||||
if ($key =='model_number') {
|
||||
if ($fieldname =='model_number') {
|
||||
$query->where(function ($query) use ($search_val) {
|
||||
$query->whereHas('model', function ($query) use ($search_val) {
|
||||
$query->where('models.model_number', 'LIKE', '%' . $search_val . '%');
|
||||
@@ -904,7 +920,7 @@ class Asset extends Depreciable
|
||||
}
|
||||
|
||||
|
||||
if ($key =='company') {
|
||||
if ($fieldname =='company') {
|
||||
$query->where(function ($query) use ($search_val) {
|
||||
$query->whereHas('company', function ($query) use ($search_val) {
|
||||
$query->where('companies.name', 'LIKE', '%' . $search_val . '%');
|
||||
@@ -913,12 +929,12 @@ class Asset extends Depreciable
|
||||
}
|
||||
}
|
||||
|
||||
foreach (CustomField::all() as $field) {
|
||||
if (array_key_exists($field->db_column_name(), $filter)) {
|
||||
$query->orWhere($field->db_column_name(), 'LIKE', "%$search_val%");
|
||||
}
|
||||
}
|
||||
|
||||
$query->orWhere('assets.'.$fieldname, 'LIKE', '%' . $search_val . '%');
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1060,7 +1076,7 @@ class Asset extends Depreciable
|
||||
*/
|
||||
public function scopeOrderLocation($query, $order)
|
||||
{
|
||||
return $query->join('locations', 'locations.id', '=', 'assets.rtd_location_id')->orderBy('locations.name', $order);
|
||||
return $query->leftJoin('locations', 'locations.id', '=', 'assets.rtd_location_id')->orderBy('locations.name', $order);
|
||||
}
|
||||
|
||||
|
||||
@@ -1103,4 +1119,20 @@ class Asset extends Depreciable
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query builder scope to search on location ID
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $query Query builder instance
|
||||
* @param text $search Search term
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeByDepreciationId($query, $search)
|
||||
{
|
||||
return $query->join('models', 'assets.model_id', '=', 'models.id')
|
||||
->join('depreciations', 'models.depreciation_id', '=', 'depreciations.id')->where('models.depreciation_id', '=', $search);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class AssetMaintenance extends Model implements ICompanyableChild
|
||||
'title' => 'required|max:100',
|
||||
'is_warranty' => 'boolean',
|
||||
'start_date' => 'required|date_format:"Y-m-d"',
|
||||
'completion_date' => 'date_format:"Y-m-d"',
|
||||
'completion_date' => 'nullable|date_format:"Y-m-d"',
|
||||
'notes' => 'string|nullable',
|
||||
'cost' => 'numeric|nullable'
|
||||
];
|
||||
|
||||
@@ -153,17 +153,17 @@ class AssetModel extends SnipeModel
|
||||
->orWhere('model_number', 'LIKE', "%$search%")
|
||||
->orWhere(function ($query) use ($search) {
|
||||
$query->whereHas('depreciation', function ($query) use ($search) {
|
||||
$query->where('name', 'LIKE', '%'.$search.'%');
|
||||
$query->where('depreciations.name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
})
|
||||
->orWhere(function ($query) use ($search) {
|
||||
$query->whereHas('category', function ($query) use ($search) {
|
||||
$query->where('name', 'LIKE', '%'.$search.'%');
|
||||
$query->where('categories.name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
})
|
||||
->orWhere(function ($query) use ($search) {
|
||||
$query->whereHas('manufacturer', function ($query) use ($search) {
|
||||
$query->where('name', 'LIKE', '%'.$search.'%');
|
||||
$query->where('manufacturers.name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -37,12 +37,6 @@ class CheckoutRequest extends Model
|
||||
|
||||
public function location()
|
||||
{
|
||||
if ($this->itemType() == "asset") {
|
||||
$asset = $this->itemRequested();
|
||||
if ($asset->assignedTo) {
|
||||
return $asset->assetloc;
|
||||
}
|
||||
}
|
||||
return $this->itemRequested()->location;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,4 +192,20 @@ final class Company extends SnipeModel
|
||||
{
|
||||
return $this->hasMany(Component::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope to search on text
|
||||
*
|
||||
* @param Illuminate\Database\Query\Builder $query Query builder instance
|
||||
* @param text $search Search term
|
||||
*
|
||||
* @return Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeTextSearch($query, $search)
|
||||
{
|
||||
|
||||
return $query->where(function ($query) use ($search) {
|
||||
$query->where('name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ class Component extends SnipeModel
|
||||
'name',
|
||||
'purchase_cost',
|
||||
'purchase_date',
|
||||
'min_amt',
|
||||
'qty',
|
||||
];
|
||||
|
||||
@@ -63,7 +64,7 @@ class Component extends SnipeModel
|
||||
|
||||
public function assets()
|
||||
{
|
||||
return $this->belongsToMany('\App\Models\Asset', 'components_assets')->withPivot('assigned_qty', 'created_at', 'user_id');
|
||||
return $this->belongsToMany('\App\Models\Asset', 'components_assets')->withPivot('id', 'assigned_qty', 'created_at', 'user_id');
|
||||
}
|
||||
|
||||
public function admin()
|
||||
|
||||
@@ -62,9 +62,18 @@ class CustomField extends Model
|
||||
return true;
|
||||
}
|
||||
|
||||
return Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||
$platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform();
|
||||
$platform->registerDoctrineTypeMapping('enum', 'string');
|
||||
|
||||
Schema::table(CustomField::$table_name, function ($table) use ($custom_field) {
|
||||
$table->renameColumn($custom_field->convertUnicodeDbSlug($custom_field->getOriginal("name")), $custom_field->convertUnicodeDbSlug());
|
||||
});
|
||||
|
||||
|
||||
$custom_field->db_column = $custom_field->convertUnicodeDbSlug();
|
||||
$custom_field->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -47,9 +47,7 @@ class CustomFieldset extends Model
|
||||
|
||||
if (($field->field_encrypted!='1') ||
|
||||
(($field->field_encrypted =='1') && (Gate::allows('admin')) )) {
|
||||
if ($field->pivot->required) {
|
||||
$rule[]="required";
|
||||
}
|
||||
$rule[] = ($field->pivot->required=='1') ? "required" : "nullable";
|
||||
}
|
||||
|
||||
array_push($rule, $field->attributes['format']);
|
||||
|
||||
@@ -36,4 +36,21 @@ class Group extends SnipeModel
|
||||
{
|
||||
return json_decode($this->permissions, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query builder scope to search on text
|
||||
*
|
||||
* @param Illuminate\Database\Query\Builder $query Query builder instance
|
||||
* @param text $search Search term
|
||||
*
|
||||
* @return Illuminate\Database\Query\Builder Modified query builder
|
||||
*/
|
||||
public function scopeTextSearch($query, $search)
|
||||
{
|
||||
|
||||
return $query->where(function ($query) use ($search) {
|
||||
|
||||
$query->where('name', 'LIKE', '%'.$search.'%');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,25 +77,22 @@ class Ldap extends Model
|
||||
$connection = Ldap::connectToLdap();
|
||||
$ldap_username_field = $settings->ldap_username_field;
|
||||
$baseDn = $settings->ldap_basedn;
|
||||
$userDn = $ldap_username_field.'='.$username.','.$settings->ldap_basedn;
|
||||
|
||||
if ($settings->is_ad =='1') {
|
||||
// Check if they are using the userprincipalname for the username field.
|
||||
// Check if they are using the userprincipalname for the username field.
|
||||
// If they are, we can skip building the UPN to authenticate against AD
|
||||
if ($ldap_username_field=='userprincipalname') {
|
||||
$userDn = $username;
|
||||
} else {
|
||||
// In case they haven't added an AD domain
|
||||
if ($settings->ad_domain == '') {
|
||||
$userDn = $username.'@'.$settings->email_domain;
|
||||
} else {
|
||||
$userDn = $username.'@'.$settings->ad_domain;
|
||||
}
|
||||
$userDn = ($settings->ad_domain != '') ? $username.'@'.$settings->ad_domain : $username.'@'.$settings->email_domain;
|
||||
}
|
||||
|
||||
} else {
|
||||
$userDn = $ldap_username_field.'='.$username.','.$settings->ldap_basedn;
|
||||
}
|
||||
|
||||
\Log::debug('Attempting to login using distinguished name:'.$userDn);
|
||||
|
||||
|
||||
$filterQuery = $settings->ldap_auth_filter_query . $username;
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ class License extends Depreciable
|
||||
protected $rules = array(
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'seats' => 'required|min:1|max:1000000|integer',
|
||||
'license_email' => 'email|min:0|max:120',
|
||||
'license_name' => 'string|min:0|max:100',
|
||||
'note' => 'string',
|
||||
'notes' => 'string|min:0',
|
||||
'license_email' => 'email|nullable|max:120',
|
||||
'license_name' => 'string|nullable|max:100',
|
||||
'note' => 'string|nullable',
|
||||
'notes' => 'string|nullable',
|
||||
'company_id' => 'integer|nullable',
|
||||
);
|
||||
|
||||
|
||||
@@ -54,12 +54,23 @@ class Location extends SnipeModel
|
||||
|
||||
public function assets()
|
||||
{
|
||||
return $this->hasManyThrough('\App\Models\Asset', '\App\Models\User', 'location_id', 'assigned_to', 'id');
|
||||
return $this->hasManyThrough('\App\Models\Asset', '\App\Models\User', 'location_id', 'assigned_to', 'id')->where("assets.assigned_type",User::class);
|
||||
}
|
||||
|
||||
public function locationAssets()
|
||||
{
|
||||
return $this->hasMany('\App\Models\Asset', 'rtd_location_id')->orHas('assignedAssets');
|
||||
/* This used to have an ...->orHas() clause that referred to
|
||||
assignedAssets, and that was probably incorrect, as well as
|
||||
definitely was setting fire to the query-planner. So don't do that.
|
||||
|
||||
It is arguable that we should have a '...->whereNull('assigned_to')
|
||||
bit in there, but that isn't always correct either (in the case
|
||||
where a user has no location, for example).
|
||||
|
||||
In all likelyhood, we need to denorm an "effective_location" column
|
||||
into Assets to make this slightly less miserable.
|
||||
*/
|
||||
return $this->hasMany('\App\Models\Asset', 'rtd_location_id');
|
||||
}
|
||||
|
||||
public function parent()
|
||||
@@ -83,6 +94,11 @@ class Location extends SnipeModel
|
||||
// return $this->hasMany('\App\Models\Asset', 'assigned_to')->withTrashed();
|
||||
}
|
||||
|
||||
public function setLdapOuAttribute($ldap_ou)
|
||||
{
|
||||
return $this->attributes['ldap_ou'] = empty($ldap_ou) ? null : $ldap_ou;
|
||||
}
|
||||
|
||||
public static function getLocationHierarchy($locations, $parent_id = null)
|
||||
{
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ class Setting extends Model
|
||||
"pwd_secure_min" => "numeric|required|min:5",
|
||||
"audit_warning_days" => "numeric|nullable",
|
||||
"audit_interval" => "numeric|nullable",
|
||||
"custom_forgot_pass_url" => "url|nullable",
|
||||
];
|
||||
|
||||
protected $fillable = ['site_name','email_domain','email_format','username_format'];
|
||||
|
||||
@@ -77,6 +77,25 @@ class SnipeModel extends Model
|
||||
return;
|
||||
}
|
||||
|
||||
public function setMinAmtAttribute($value)
|
||||
{
|
||||
if ($value == '') {
|
||||
$value = null;
|
||||
}
|
||||
$this->attributes['min_amt'] = $value;
|
||||
return;
|
||||
}
|
||||
|
||||
public function setParentIdAttribute($value)
|
||||
{
|
||||
if ($value == '') {
|
||||
$value = null;
|
||||
}
|
||||
$this->attributes['parent_id'] = $value;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
public function getDisplayNameAttribute()
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ class Statuslabel extends SnipeModel
|
||||
|
||||
protected $rules = array(
|
||||
'name' => 'required|string|unique_undeleted',
|
||||
'notes' => 'string',
|
||||
'notes' => 'string|nullable',
|
||||
'deployable' => 'required',
|
||||
'pending' => 'required',
|
||||
'archived' => 'required',
|
||||
@@ -29,16 +29,6 @@ class Statuslabel extends SnipeModel
|
||||
|
||||
protected $fillable = ['name', 'deployable', 'pending', 'archived'];
|
||||
|
||||
/**
|
||||
* Show count of assets with status label
|
||||
*
|
||||
* @todo Remove this. It's dumb.
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function has_assets()
|
||||
{
|
||||
return $this->hasMany('\App\Models\Asset', 'status_id')->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get assets with associated status label
|
||||
@@ -59,14 +49,41 @@ class Statuslabel extends SnipeModel
|
||||
return 'archived';
|
||||
} elseif (($this->pending == '0') && ($this->archived == '0') && ($this->deployable == '0')) {
|
||||
return 'undeployable';
|
||||
} else {
|
||||
return 'deployable';
|
||||
}
|
||||
|
||||
return 'deployable';
|
||||
|
||||
}
|
||||
|
||||
public function scopePending()
|
||||
{
|
||||
return $this->where('pending', '=', 1)
|
||||
->where('archived', '=', 0)
|
||||
->where('deployable', '=', 0);
|
||||
}
|
||||
|
||||
public function scopeArchived()
|
||||
{
|
||||
return $this->where('pending', '=', 0)
|
||||
->where('archived', '=', 1)
|
||||
->where('deployable', '=', 0);
|
||||
}
|
||||
|
||||
public function scopeDeployable()
|
||||
{
|
||||
return $this->where('pending', '=', 0)
|
||||
->where('archived', '=', 0)
|
||||
->where('deployable', '=', 1);
|
||||
}
|
||||
|
||||
|
||||
public static function getStatuslabelTypesForDB($type)
|
||||
{
|
||||
|
||||
$statustype['pending'] = 0;
|
||||
$statustype['deployable'] = 0;
|
||||
$statustype['archived'] = 0;
|
||||
|
||||
if ($type == 'pending') {
|
||||
$statustype['pending'] = 1;
|
||||
$statustype['deployable'] = 0;
|
||||
@@ -81,12 +98,6 @@ class Statuslabel extends SnipeModel
|
||||
$statustype['pending'] = 0;
|
||||
$statustype['deployable'] = 0;
|
||||
$statustype['archived'] = 1;
|
||||
|
||||
} else {
|
||||
$statustype['pending'] = 0;
|
||||
$statustype['deployable'] = 0;
|
||||
$statustype['archived'] = 0;
|
||||
|
||||
}
|
||||
|
||||
return $statustype;
|
||||
|
||||
@@ -15,18 +15,18 @@ class Supplier extends SnipeModel
|
||||
|
||||
protected $rules = array(
|
||||
'name' => 'required|min:3|max:255|unique_undeleted',
|
||||
'address' => 'min:3|max:50',
|
||||
'address2' => 'min:2|max:50',
|
||||
'city' => 'min:3|max:255',
|
||||
'state' => 'min:0|max:32',
|
||||
'country' => 'min:0|max:2',
|
||||
'fax' => 'min:7|max:35',
|
||||
'phone' => 'min:7|max:35',
|
||||
'contact' => 'min:0|max:100',
|
||||
'notes' => 'min:0|max:255',
|
||||
'email' => 'email|min:5|max:150',
|
||||
'zip' => 'min:0|max:10',
|
||||
'url' => 'min:3|max:250',
|
||||
'address' => 'max:50|nullable',
|
||||
'address2' => 'max:50|nullable',
|
||||
'city' => 'max:255|nullable',
|
||||
'state' => 'max:32|nullable',
|
||||
'country' => 'max:3|nullable',
|
||||
'fax' => 'min:7|max:35|nullable',
|
||||
'phone' => 'min:7|max:35|nullable',
|
||||
'contact' => 'max:100|nullable',
|
||||
'notes' => 'max:255|nullable',
|
||||
'email' => 'email|max:150|nullable',
|
||||
'zip' => 'max:10|nullable',
|
||||
'url' => 'sometimes|nullable|string|max:250',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -68,6 +68,11 @@ class Supplier extends SnipeModel
|
||||
return $this->hasMany('\App\Models\Asset', 'supplier_id');
|
||||
}
|
||||
|
||||
public function accessories()
|
||||
{
|
||||
return $this->hasMany('\App\Models\Accessory', 'supplier_id');
|
||||
}
|
||||
|
||||
public function asset_maintenances()
|
||||
{
|
||||
return $this->hasMany('\App\Models\AssetMaintenance', 'supplier_id');
|
||||
|
||||
@@ -4,8 +4,10 @@ namespace App\Models;
|
||||
use App\Presenters\Presentable;
|
||||
use Illuminate\Auth\Authenticatable;
|
||||
use Illuminate\Auth\Passwords\CanResetPassword;
|
||||
use Illuminate\Foundation\Auth\Access\Authorizable;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Http\Traits\UniqueUndeletedTrait;
|
||||
@@ -16,7 +18,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
{
|
||||
protected $presenter = 'App\Presenters\UserPresenter';
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
use Authenticatable, CanResetPassword, HasApiTokens;
|
||||
use Authenticatable, Authorizable, CanResetPassword, HasApiTokens;
|
||||
use UniqueUndeletedTrait;
|
||||
use Notifiable;
|
||||
use Presentable;
|
||||
@@ -53,7 +55,8 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
'username' => 'required|string|min:1|unique_undeleted',
|
||||
'email' => 'email|nullable',
|
||||
'password' => 'required|min:6',
|
||||
'locale' => 'max:10|nullable'
|
||||
'locale' => 'max:10|nullable',
|
||||
'manager_id' => 'nullable|different:id',
|
||||
];
|
||||
|
||||
|
||||
@@ -378,6 +381,14 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
return json_decode($this->permissions, true);
|
||||
}
|
||||
|
||||
|
||||
public function scopeByGroup($query, $id) {
|
||||
return $query->whereHas('groups', function ($query) use ($id) {
|
||||
$query->where('groups.id', '=', $id);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query builder scope to search on text
|
||||
*
|
||||
@@ -395,6 +406,7 @@ class User extends SnipeModel implements AuthenticatableContract, CanResetPasswo
|
||||
->orWhere('users.email', 'LIKE', "%$search%")
|
||||
->orWhere('users.username', 'LIKE', "%$search%")
|
||||
->orWhere('users.notes', 'LIKE', "%$search%")
|
||||
->orWhere('users.phone', 'LIKE', "%$search%")
|
||||
->orWhere('users.jobtitle', 'LIKE', "%$search%")
|
||||
->orWhere('users.employee_num', 'LIKE', "%$search%")
|
||||
->orWhere(function ($query) use ($search) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user