Compare commits
895 Commits
v4.0-alpha
...
v4.0.14
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47c7061af5 | ||
|
|
3799ab87ed | ||
|
|
6232a1f941 | ||
|
|
f5ce580593 | ||
|
|
3afa5f7cda | ||
|
|
17b271918f | ||
|
|
3922569d7f | ||
|
|
3a302fe2d7 | ||
|
|
249f86bb21 | ||
|
|
0951a756cc | ||
|
|
fc644925ea | ||
|
|
59c0b63ad0 | ||
|
|
c0f8b3773c | ||
|
|
fd210c6439 | ||
|
|
f7e23cf7c8 | ||
|
|
387351d7ed | ||
|
|
6438d30afc | ||
|
|
b4e1d37b16 | ||
|
|
8ac57d0121 | ||
|
|
d3b51715dc | ||
|
|
b215924b1a | ||
|
|
25d3d66880 | ||
|
|
189574377a | ||
|
|
341ddec9d8 | ||
|
|
abcce78944 | ||
|
|
22e13cd4d2 | ||
|
|
5c105b52b6 | ||
|
|
f757da1a98 | ||
|
|
c1f8db37d9 | ||
|
|
cfc215a013 | ||
|
|
4215a3257b | ||
|
|
1f247ff541 | ||
|
|
2fc46746e2 | ||
|
|
e185dc68af | ||
|
|
54000ff69f | ||
|
|
f6a38e848a | ||
|
|
7e8d670f81 | ||
|
|
287b150b7f | ||
|
|
b379656d55 | ||
|
|
2e11a983c8 | ||
|
|
a9753eb646 | ||
|
|
707c4db881 | ||
|
|
d1de34394e | ||
|
|
e5719441bc | ||
|
|
7153013fb0 | ||
|
|
55500f77fb | ||
|
|
2b826c3adc | ||
|
|
cd193ce8bb | ||
|
|
cb50142ba3 | ||
|
|
81aaed92ce | ||
|
|
4bc551db82 | ||
|
|
471d665408 | ||
|
|
068308ef56 | ||
|
|
1e65c7bf9a | ||
|
|
ae567c08db | ||
|
|
0d25a4868a | ||
|
|
13586be6b0 | ||
|
|
44c649c3c8 | ||
|
|
1a7bfb75fa | ||
|
|
2b803a6a6c | ||
|
|
92e4bdc02e | ||
|
|
4d3d19ca2b | ||
|
|
9c06912efd | ||
|
|
c5893b4445 | ||
|
|
b90933bb8b | ||
|
|
fe9a90854d | ||
|
|
3b012f2827 | ||
|
|
e31dadc99a | ||
|
|
5519e2d4ae | ||
|
|
6285a8b5b2 | ||
|
|
a3139c6fc6 | ||
|
|
389ba9059f | ||
|
|
c0e50be03e | ||
|
|
447833c996 | ||
|
|
809e310565 | ||
|
|
38dd03b5ad | ||
|
|
68f6385eba | ||
|
|
bd376a4992 | ||
|
|
97f65ceac0 | ||
|
|
9e39abcc32 | ||
|
|
5cd2857d5d | ||
|
|
585fcfb7d4 | ||
|
|
d9135a8aac | ||
|
|
081a64223a | ||
|
|
a4eeff01f0 | ||
|
|
eedbe468ac | ||
|
|
463d9513e2 | ||
|
|
ed4aa7dec2 | ||
|
|
d6bbe15a76 | ||
|
|
ea0a0a4a69 | ||
|
|
34442362ca | ||
|
|
b846bb20c6 | ||
|
|
ab3f5f4f4d | ||
|
|
ea63ced2bd | ||
|
|
6bd49bfb72 | ||
|
|
b80d3ce50d | ||
|
|
c069829b33 | ||
|
|
665a113ed8 | ||
|
|
aa7091d962 | ||
|
|
ceff6a9617 | ||
|
|
c01850fc73 | ||
|
|
4c04dc7b84 | ||
|
|
c0103cd878 | ||
|
|
1f1d9d5461 | ||
|
|
c776fa4f7b | ||
|
|
dc91d10395 | ||
|
|
4df10ad26c | ||
|
|
668a88bc86 | ||
|
|
d6e0012818 | ||
|
|
1d5fb52bfc | ||
|
|
8efb02a0ee | ||
|
|
dea42db18b | ||
|
|
78d5d3947f | ||
|
|
a1f5e11517 | ||
|
|
99ad096a8a | ||
|
|
65b4ffeed9 | ||
|
|
0dac88816a | ||
|
|
f7626404b7 | ||
|
|
78f4b08398 | ||
|
|
160fd1c86a | ||
|
|
6ce01487c5 | ||
|
|
b46cbac911 | ||
|
|
e9c3d6bfb7 | ||
|
|
9e9a5b7a53 | ||
|
|
e7fe91c9d4 | ||
|
|
6d130326aa | ||
|
|
02db0f9f9d | ||
|
|
e0668b7507 | ||
|
|
1376f246dc | ||
|
|
113c55d905 | ||
|
|
9cc25bcfd0 | ||
|
|
81d3f78263 | ||
|
|
66596b0b09 | ||
|
|
7455b1019a | ||
|
|
37df934e97 | ||
|
|
6517a95d45 | ||
|
|
4b84a0c916 | ||
|
|
0f0a61e477 | ||
|
|
f64382aa00 | ||
|
|
1743417ec9 | ||
|
|
c61bed52c8 | ||
|
|
edf75865dc | ||
|
|
176a26e6c3 | ||
|
|
10a4d7e849 | ||
|
|
cbe008d52f | ||
|
|
aeb5152789 | ||
|
|
938490df16 | ||
|
|
45c2af80a3 | ||
|
|
892c1b04fd | ||
|
|
1fbf3753bc | ||
|
|
5ead5a94e3 | ||
|
|
bcf435f625 | ||
|
|
8638c46b1d | ||
|
|
b107280b7b | ||
|
|
1a60c20117 | ||
|
|
f1a6926ad9 | ||
|
|
c27a7f09bd | ||
|
|
ba7b9d8168 | ||
|
|
5b070ee32f | ||
|
|
59a126c47c | ||
|
|
322e62418e | ||
|
|
a98d94ccdc | ||
|
|
5addcb517f | ||
|
|
56cbc005ae | ||
|
|
22e9246031 | ||
|
|
c0b39701cc | ||
|
|
e2bac62e36 | ||
|
|
c12a23b84a | ||
|
|
fa95f6d836 | ||
|
|
280e8c7ed1 | ||
|
|
7617fda978 | ||
|
|
af69f7636b | ||
|
|
6d4574130f | ||
|
|
485b6397d0 | ||
|
|
93990327de | ||
|
|
4ee7765403 | ||
|
|
bdbad067b4 | ||
|
|
13a716310c | ||
|
|
d0c77c228b | ||
|
|
36cbffa183 | ||
|
|
5edf9e143f | ||
|
|
b6a1e0d12f | ||
|
|
2fda3a2d26 | ||
|
|
f56eb16941 | ||
|
|
c15c082fb4 | ||
|
|
64e7ab3a12 | ||
|
|
afbd6c811b | ||
|
|
f64c02ce12 | ||
|
|
a0d8aa77d3 | ||
|
|
bed7b29417 | ||
|
|
40ed86bfe0 | ||
|
|
33497c9811 | ||
|
|
52a8597813 | ||
|
|
eeb07f73e5 | ||
|
|
57422c9135 | ||
|
|
adca7cb0c5 | ||
|
|
059f8f5bc9 | ||
|
|
c676e9d794 | ||
|
|
e9f10dd74e | ||
|
|
e29d878d4f | ||
|
|
d4e3ea1412 | ||
|
|
c5462c5f1f | ||
|
|
d1328c3ba9 | ||
|
|
8c406e8e55 | ||
|
|
6e33f36595 | ||
|
|
48277606de | ||
|
|
d7c9fcc8df | ||
|
|
508576544b | ||
|
|
9f2fc21649 | ||
|
|
11f99a963a | ||
|
|
27ab0271a1 | ||
|
|
f858b2858d | ||
|
|
e2809f7bd0 | ||
|
|
f468b37f36 | ||
|
|
0b3d3de30f | ||
|
|
907b909223 | ||
|
|
9dc79f7165 | ||
|
|
324d44dbac | ||
|
|
7a0e695ea0 | ||
|
|
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 | ||
|
|
4981077cb1 | ||
|
|
fbea1c0823 | ||
|
|
a84da88114 | ||
|
|
282b3b5b0a | ||
|
|
130a99c46f | ||
|
|
df4cb7d351 | ||
|
|
1dcff8d463 | ||
|
|
ae4ba6176d | ||
|
|
e461c25428 | ||
|
|
ea4bfdc51d | ||
|
|
554ea8bb95 | ||
|
|
f2be409914 | ||
|
|
3fc1bbea73 | ||
|
|
a97f7d2277 | ||
|
|
af70cdaeac | ||
|
|
8919c3b52a | ||
|
|
f580e20bc3 | ||
|
|
a054cec7c9 | ||
|
|
1ad7bbdd0c | ||
|
|
cfe6759825 | ||
|
|
10c13baf2b | ||
|
|
9fe4e11874 | ||
|
|
f6d8642799 | ||
|
|
adddc5324b | ||
|
|
f442b70ae7 | ||
|
|
7b10213b3a | ||
|
|
ddc79b9070 | ||
|
|
5e9b04b0f5 | ||
|
|
2562eb2aeb | ||
|
|
85da30894b | ||
|
|
bf344e9322 | ||
|
|
f66e222f3d | ||
|
|
fb180d74a1 | ||
|
|
eaf55f5e79 | ||
|
|
8edb586576 | ||
|
|
32b01b8f38 | ||
|
|
340386f282 | ||
|
|
6dd4282f1f | ||
|
|
3f44987799 | ||
|
|
b4fec068d0 | ||
|
|
512632ce60 | ||
|
|
58a9b0d3e8 | ||
|
|
fcb1283a14 | ||
|
|
54671af7f0 | ||
|
|
aedabb0920 | ||
|
|
aaf4acef83 | ||
|
|
8e73cacf4e | ||
|
|
b4b2daebbd | ||
|
|
3e2c18cb4d | ||
|
|
c721fdd793 | ||
|
|
d119372ff0 | ||
|
|
c8bed867da | ||
|
|
3a470ce789 | ||
|
|
f9105719a8 | ||
|
|
d303cbd7cb | ||
|
|
96c09e7264 | ||
|
|
ef19bc7c16 | ||
|
|
aa8472971d | ||
|
|
78257d5ca6 | ||
|
|
655484b1da | ||
|
|
ac8185339d | ||
|
|
a021ce011b | ||
|
|
3687cbfdb3 | ||
|
|
594135fd70 | ||
|
|
2542b9cf59 | ||
|
|
8a7abba427 | ||
|
|
3775649c8a | ||
|
|
9df648b428 | ||
|
|
11a1efdbbc | ||
|
|
a65c2f305e | ||
|
|
50777f5c1d | ||
|
|
ff38cdd09b | ||
|
|
9420913d25 | ||
|
|
59225701b5 | ||
|
|
6aa5d4d58c | ||
|
|
cd2e137fcc | ||
|
|
0b968e1d6b | ||
|
|
7a27fda083 | ||
|
|
aab635154a | ||
|
|
e389f67629 | ||
|
|
169dc779fd | ||
|
|
26423c5c02 | ||
|
|
862543428b | ||
|
|
d28e882f5d | ||
|
|
e26d038589 | ||
|
|
afc8133acf | ||
|
|
abe19a6311 | ||
|
|
07359c76ad | ||
|
|
a2453be573 | ||
|
|
c2616412c0 | ||
|
|
23ca2d9a0b | ||
|
|
0bb186ad3b | ||
|
|
b7abd8328a | ||
|
|
ad2821b4ab | ||
|
|
7d5b08446a | ||
|
|
ba793355cb | ||
|
|
655ca78633 | ||
|
|
f00dcb57cf | ||
|
|
1e52fb546c | ||
|
|
24cad588bd | ||
|
|
bbffde47f7 | ||
|
|
be7598b279 | ||
|
|
1a7e3fbb4b | ||
|
|
e8a0c44e93 | ||
|
|
fe644c76c5 | ||
|
|
9301c56a77 | ||
|
|
e37503c734 | ||
|
|
6bc3f194ec | ||
|
|
878bde67ac | ||
|
|
314d6fa4c5 | ||
|
|
43ff66e4d9 | ||
|
|
2ea91266c0 | ||
|
|
a0bd9bce39 | ||
|
|
5223ec1dbb | ||
|
|
4eda2a2f96 | ||
|
|
fe1975067a | ||
|
|
b9e79c27a8 | ||
|
|
b8ed6a53b6 | ||
|
|
efd71f8bfe | ||
|
|
05a8ba9a8e | ||
|
|
9ce2d1f560 | ||
|
|
5a1225a8bf | ||
|
|
c6069b905b | ||
|
|
2e76620cf8 | ||
|
|
a4b30279ee | ||
|
|
db59d4b2c4 | ||
|
|
faf3802971 | ||
|
|
7fe2a1f802 | ||
|
|
3d57d1bd1d | ||
|
|
ba8bcce8eb | ||
|
|
8247a73182 | ||
|
|
aab409dec2 | ||
|
|
70a9b7bf05 | ||
|
|
d9824a0454 | ||
|
|
e759a249bd | ||
|
|
42c2a66946 | ||
|
|
4d32f2b337 | ||
|
|
0e29744ec2 | ||
|
|
51236a2ad9 | ||
|
|
9b6726a630 | ||
|
|
cbdd05144a | ||
|
|
46d87849f4 | ||
|
|
507f1f196c | ||
|
|
b60febeea2 | ||
|
|
b3e0d8f675 | ||
|
|
9b84a0d516 | ||
|
|
adac5ac544 | ||
|
|
1775995f26 | ||
|
|
df4700b411 | ||
|
|
26a7701cda | ||
|
|
a34085f1d9 | ||
|
|
8e682c715e | ||
|
|
915c19ebda | ||
|
|
7fded367c4 | ||
|
|
0a4743210c | ||
|
|
af19e5d976 | ||
|
|
3d7277398c | ||
|
|
a7ad48a02a | ||
|
|
469a3fc608 | ||
|
|
0fb4ff77f4 | ||
|
|
ac83dba2bb | ||
|
|
979ecf961d | ||
|
|
13dcdf41b8 | ||
|
|
fc96fa756e | ||
|
|
ea9a502152 | ||
|
|
d844734b6c | ||
|
|
ec8a3d2e56 | ||
|
|
5410dc4255 | ||
|
|
d1112bbc99 | ||
|
|
ecf041fa10 | ||
|
|
0ab9bc1db8 | ||
|
|
73e788b94b | ||
|
|
e91a537552 | ||
|
|
ef8c1abf28 | ||
|
|
bd0498aa69 | ||
|
|
ea45033588 | ||
|
|
5e1df7049c | ||
|
|
e27e1a78c3 | ||
|
|
d585a34a26 | ||
|
|
4edaba648e | ||
|
|
9dca7396f3 | ||
|
|
4324242475 | ||
|
|
eca5a05335 | ||
|
|
aa4d3c3ffb | ||
|
|
d442feb687 | ||
|
|
0a88141b18 | ||
|
|
d5e6d82ca1 | ||
|
|
f2a62857cb | ||
|
|
b354ca817d | ||
|
|
4b9bfc178d | ||
|
|
abc2f7e789 | ||
|
|
29cc9a0815 | ||
|
|
f2ee7dcabb | ||
|
|
26203801f6 | ||
|
|
fbe9539130 | ||
|
|
43ec959385 | ||
|
|
9b6276f281 | ||
|
|
0715791229 | ||
|
|
0a0661bf41 | ||
|
|
6ee939d29b | ||
|
|
c3afbc0e53 | ||
|
|
38326314ca | ||
|
|
865950e766 | ||
|
|
d49b67d033 | ||
|
|
6b63808e34 | ||
|
|
34dfcb5add | ||
|
|
30019a144a | ||
|
|
3e222b674a | ||
|
|
e316444c63 | ||
|
|
b29d7beb3a | ||
|
|
f0a49fefd7 | ||
|
|
998c4a5fe5 | ||
|
|
626a6408d0 | ||
|
|
126a5671fe | ||
|
|
aff104fa5d | ||
|
|
a5764351f7 | ||
|
|
348becbbec | ||
|
|
922d6937ae | ||
|
|
c53dae4b72 | ||
|
|
17ad7f7800 | ||
|
|
6232a077b5 | ||
|
|
e7d72beb88 | ||
|
|
01e3f4a4db | ||
|
|
1b76880b0e | ||
|
|
ed4ea7f1f4 | ||
|
|
81e358a01d | ||
|
|
6c283de60a | ||
|
|
4e7a6c0ccf | ||
|
|
eba145503b | ||
|
|
ae8c9d6afc | ||
|
|
faeca4139d | ||
|
|
47909b93f7 | ||
|
|
472658b2fe | ||
|
|
42a03a0436 | ||
|
|
ae0573b3da | ||
|
|
34f816097e | ||
|
|
c651c9f1ed | ||
|
|
7c390cee2c | ||
|
|
987536930c | ||
|
|
10f322198f | ||
|
|
761371509d | ||
|
|
3518ea7e7d | ||
|
|
c92eed2b3e | ||
|
|
0054ce3071 | ||
|
|
b0f74466bb | ||
|
|
b4a0484295 | ||
|
|
bb874012d9 | ||
|
|
bb8583eb14 | ||
|
|
8d2c229bc3 | ||
|
|
48e6208214 | ||
|
|
22233e3ba6 | ||
|
|
fd515654ff | ||
|
|
e439f15a64 | ||
|
|
42175782a5 | ||
|
|
c7a21e0e4d | ||
|
|
d98ffd94f9 | ||
|
|
6ad5da44f3 | ||
|
|
479f422e68 | ||
|
|
e10cdd57a5 | ||
|
|
bf157773c8 | ||
|
|
fba3949530 | ||
|
|
abc3dea8ac | ||
|
|
51d74ac06d | ||
|
|
af835d6efc | ||
|
|
a7a10455ae | ||
|
|
bd02b9ed62 | ||
|
|
16f57e16cb | ||
|
|
af6f208c43 | ||
|
|
52270fa4db | ||
|
|
bf3731d65c | ||
|
|
233ebf06ee | ||
|
|
e27f6a483d | ||
|
|
19670f9dd8 | ||
|
|
1448229cd2 | ||
|
|
4721cab928 | ||
|
|
08f3e78d26 | ||
|
|
62227ec27d | ||
|
|
10711245ba | ||
|
|
29a7c8577d | ||
|
|
dfb1ff81e6 | ||
|
|
021e723acf | ||
|
|
14c0c314aa | ||
|
|
d23ea70b08 | ||
|
|
1b047c768b | ||
|
|
e6323e0a1b | ||
|
|
73ce5f98bb | ||
|
|
a37cb616eb | ||
|
|
659d953f3f | ||
|
|
c1dcc22217 | ||
|
|
6a67426140 | ||
|
|
4ba474cf73 | ||
|
|
fb6caa35ff | ||
|
|
a5870c888e | ||
|
|
f35f8477d3 | ||
|
|
d0637d38f3 | ||
|
|
7141968d64 | ||
|
|
0f7b7d8e6a | ||
|
|
ca78b3ed7c | ||
|
|
2d2cae10b9 | ||
|
|
5347b19910 | ||
|
|
5e9331f5ae | ||
|
|
6e30fa6922 | ||
|
|
58b3f0519d | ||
|
|
f119c69698 | ||
|
|
57f4c986af | ||
|
|
2958630923 | ||
|
|
72dacda4f9 | ||
|
|
9c2b986bb0 | ||
|
|
06c5bce3c7 | ||
|
|
a0cbca85bf | ||
|
|
9bda62d295 | ||
|
|
1d7e243d0a | ||
|
|
63bc2ec09f | ||
|
|
d5cadeab1a | ||
|
|
31516abef9 | ||
|
|
d2535582f3 | ||
|
|
eaaea303f4 | ||
|
|
8c5312b931 | ||
|
|
4ef6e292d1 | ||
|
|
6310670835 | ||
|
|
15bb30acd6 | ||
|
|
148d41d8dc | ||
|
|
71c1c74164 | ||
|
|
9c02526a37 | ||
|
|
25dc26aac3 | ||
|
|
afc763ebac | ||
|
|
6a73ec6537 | ||
|
|
481143b891 | ||
|
|
cef67695cd | ||
|
|
4576cb6f56 | ||
|
|
56f88d2c22 | ||
|
|
c1d1cb8122 | ||
|
|
ac8f46c93c | ||
|
|
101a09b421 | ||
|
|
cb1e3b7978 | ||
|
|
de18e2a887 | ||
|
|
241bf0cd4b | ||
|
|
7da4fe4524 | ||
|
|
9bfd345774 | ||
|
|
df87c82ddc | ||
|
|
3e8b7d9c94 | ||
|
|
7adfab9d9f | ||
|
|
7c4ee54f8b | ||
|
|
03f9d01aab | ||
|
|
5b420fb4b9 | ||
|
|
a2d63dd3e4 | ||
|
|
0408509fdc | ||
|
|
5e47c18d68 | ||
|
|
b3293a7a5f | ||
|
|
4e5cf531f7 | ||
|
|
f0bbe38c71 | ||
|
|
ccb7556281 | ||
|
|
ee7348d0d5 | ||
|
|
7d6bf4ac24 | ||
|
|
cb903ab9fd | ||
|
|
66d8308163 | ||
|
|
847262e989 | ||
|
|
59006964d1 | ||
|
|
ac29b142dc | ||
|
|
978a906513 | ||
|
|
dfa0714d44 | ||
|
|
0fbf9236f4 | ||
|
|
c64ca76b3d | ||
|
|
73052d3fc1 | ||
|
|
ae0b639d0c | ||
|
|
5cc84ca137 | ||
|
|
29f1cf2b48 | ||
|
|
7510f9f128 | ||
|
|
7c6143bbb8 | ||
|
|
346156bae1 | ||
|
|
3eea1a23f8 | ||
|
|
1fda4593c1 | ||
|
|
6b5a0983ee | ||
|
|
ad12a5ce11 | ||
|
|
ec09ea53db | ||
|
|
5abe72ce02 | ||
|
|
3e3276334b | ||
|
|
b13e04095e | ||
|
|
3cfcc43efa | ||
|
|
f432f98e12 | ||
|
|
f56862c684 | ||
|
|
9bcfe0748b | ||
|
|
de5e7bd9ba | ||
|
|
635299cd74 | ||
|
|
20376daec4 | ||
|
|
50e1570543 | ||
|
|
eb94c4333d | ||
|
|
a49fd16916 | ||
|
|
0cc9c214aa | ||
|
|
c48bcb7ed1 | ||
|
|
09de201027 | ||
|
|
6ce2127d75 | ||
|
|
e79260a0d4 | ||
|
|
932e25ca9b | ||
|
|
b02148f59e | ||
|
|
6046063666 | ||
|
|
fd57617c8e | ||
|
|
44569558e9 | ||
|
|
d2f6c8af11 | ||
|
|
814bf18a4b | ||
|
|
33557f3792 | ||
|
|
c2927c4a2e | ||
|
|
ab2b2f3043 | ||
|
|
0e598702f8 | ||
|
|
9894edb008 | ||
|
|
c2e8803d1e | ||
|
|
7e1f7297b3 | ||
|
|
3401f3dfb9 | ||
|
|
31cabaa4db | ||
|
|
06c04bf271 | ||
|
|
4c39be1f3c | ||
|
|
c8c279588f | ||
|
|
8aa920ca3a | ||
|
|
0242283a11 | ||
|
|
9e0c5e50b6 | ||
|
|
95d1612234 | ||
|
|
61c6160b98 | ||
|
|
d12159c042 | ||
|
|
e009bb956d | ||
|
|
25e99194ce | ||
|
|
274f3511f5 | ||
|
|
5b9bcd8fa2 | ||
|
|
4bde058192 | ||
|
|
ffba9789b7 | ||
|
|
1052be670d | ||
|
|
770092f23f | ||
|
|
99f65cbf69 | ||
|
|
5d4920c741 | ||
|
|
54279f22a3 | ||
|
|
dfea47a272 | ||
|
|
f0d78091d2 | ||
|
|
966a736602 | ||
|
|
30a9704625 | ||
|
|
30487bfee7 | ||
|
|
3046d7d33c | ||
|
|
0aa76bd946 | ||
|
|
26d7fffae8 | ||
|
|
14f3868b46 | ||
|
|
a5cd4a0a22 | ||
|
|
ad816264e9 | ||
|
|
c2494fe0e5 | ||
|
|
02edb74cdf | ||
|
|
408bb6476f | ||
|
|
ee5b5acffb | ||
|
|
e387673e74 | ||
|
|
17ce4ea08b | ||
|
|
0bc709206f | ||
|
|
e9dd119b9c | ||
|
|
269997a1fb | ||
|
|
041b794e1f | ||
|
|
da2d9b2374 | ||
|
|
a59db7062d | ||
|
|
58b2834c54 | ||
|
|
2aaa635345 | ||
|
|
8269aec71a | ||
|
|
d62896f945 | ||
|
|
a717ca683c | ||
|
|
d7827fedd9 | ||
|
|
fbcc40a145 | ||
|
|
12a7309ecd | ||
|
|
9caf045930 | ||
|
|
1c056d1a59 | ||
|
|
240a07b108 | ||
|
|
c977dda5bb | ||
|
|
03411a3ae8 | ||
|
|
01cc00c832 | ||
|
|
9338b37b74 | ||
|
|
9cd2881ad0 | ||
|
|
64b483b686 | ||
|
|
1f7266274d | ||
|
|
4e5b2d1fe9 | ||
|
|
ada2ac06f2 | ||
|
|
9d948e8d23 | ||
|
|
4062228092 | ||
|
|
3e67cdc501 | ||
|
|
be42a0add1 | ||
|
|
6cadde23d7 | ||
|
|
a6c1f7b30b | ||
|
|
1b5b0e9d19 | ||
|
|
2a226fd3f9 | ||
|
|
043182593d | ||
|
|
08dc07b46b | ||
|
|
9a9b6ae228 | ||
|
|
2d3ea4eec6 | ||
|
|
7c8dc9fe2d | ||
|
|
74aaadcdc5 | ||
|
|
0238dd59a3 | ||
|
|
461ca53289 | ||
|
|
ccc0063556 | ||
|
|
66145a625c | ||
|
|
cc5192c91e | ||
|
|
de5334e525 | ||
|
|
b797604627 | ||
|
|
293981148c | ||
|
|
66eaff739a | ||
|
|
8b5cb6e8c2 | ||
|
|
7b4b2d79cf | ||
|
|
c3af13298e | ||
|
|
312fd27d11 | ||
|
|
1b55d38c63 | ||
|
|
1992906790 | ||
|
|
b0fc2489f6 | ||
|
|
b13726880e | ||
|
|
25dca80644 | ||
|
|
748aba3c48 | ||
|
|
c9484fa30b | ||
|
|
d950ddbda7 | ||
|
|
fd0165b4b8 | ||
|
|
fd0da6ecf0 | ||
|
|
7b1265cb89 | ||
|
|
92052442e3 | ||
|
|
71b668e1a3 | ||
|
|
3c167c9d33 | ||
|
|
9f87f72c96 | ||
|
|
5e0cc93ba2 | ||
|
|
3724442318 | ||
|
|
610a773620 | ||
|
|
a1c7d2922e | ||
|
|
8ab29c628f | ||
|
|
4ada5eaa94 | ||
|
|
5499735f3a | ||
|
|
40e11b6661 | ||
|
|
b1fa25b73e | ||
|
|
452c52a3ab | ||
|
|
76926c97c1 | ||
|
|
6775c39a5e | ||
|
|
ce856bdb0a | ||
|
|
52f24f7587 | ||
|
|
fba7f1ccf6 | ||
|
|
ed46dee646 | ||
|
|
332076bbe5 | ||
|
|
9d45375b8a | ||
|
|
d3b07411da | ||
|
|
d17d3a2ef0 | ||
|
|
dd8511c66a | ||
|
|
f57ebc664e | ||
|
|
f285bd3c29 | ||
|
|
aeca549bab | ||
|
|
e0d2cbef20 | ||
|
|
96e8109d01 | ||
|
|
b223630f72 | ||
|
|
e9c39add4f | ||
|
|
7ec1724308 | ||
|
|
811ddd2f67 | ||
|
|
cefb20d46f | ||
|
|
bb323db685 | ||
|
|
eb3aa99e4f | ||
|
|
a7592de304 | ||
|
|
64f17cecbf | ||
|
|
e2f2f9e154 | ||
|
|
8caf6623f1 | ||
|
|
6c623866c0 | ||
|
|
659e60fd12 | ||
|
|
ae329f4160 | ||
|
|
e314de3594 | ||
|
|
b0479923b1 | ||
|
|
e3a5accace | ||
|
|
b81dd18576 | ||
|
|
dac4b58892 | ||
|
|
71fd430f8e | ||
|
|
5265821bcc | ||
|
|
cb494a74ca | ||
|
|
c526ffbf68 | ||
|
|
6f5fe83a91 | ||
|
|
0c43e64160 | ||
|
|
708385e23a | ||
|
|
0ab37af7ab | ||
|
|
891660d4ea | ||
|
|
dcfc434075 | ||
|
|
0c8308f5a4 | ||
|
|
1bd798c4d2 | ||
|
|
23be188a49 | ||
|
|
fdd88af44a | ||
|
|
5a3816c907 | ||
|
|
c8796cf045 | ||
|
|
f4095c6dd0 | ||
|
|
ee2c67a65f | ||
|
|
5614578710 | ||
|
|
07882110fa | ||
|
|
7a05467dbf | ||
|
|
b7843ea565 | ||
|
|
4f9a253103 | ||
|
|
322817b8b1 | ||
|
|
82dc06ae19 | ||
|
|
38372f2b37 | ||
|
|
e9b056f66c | ||
|
|
f6be7caaeb | ||
|
|
d7f6d8e997 | ||
|
|
841e3efe96 | ||
|
|
8ba19aa855 | ||
|
|
5ad9e8585d | ||
|
|
68e831d555 | ||
|
|
6fbf45554b | ||
|
|
07f8c9dc5e | ||
|
|
e088eea2f7 | ||
|
|
f4cdeaa956 | ||
|
|
59a4e161ff | ||
|
|
6d53a5f58d | ||
|
|
54a2c46101 | ||
|
|
08ef78356d | ||
|
|
47ac59abef | ||
|
|
265a896211 | ||
|
|
f7e4fca70d | ||
|
|
bb4c443cd9 | ||
|
|
7b1d2ee050 | ||
|
|
b3f70a046f | ||
|
|
734e87f85f | ||
|
|
f371c5fd62 | ||
|
|
4b3edbd2f5 | ||
|
|
1f3106b9da | ||
|
|
9fd3a9a82d | ||
|
|
a6e6991a2d | ||
|
|
93ba0717d8 | ||
|
|
a8839e0ef4 | ||
|
|
3e4152c966 | ||
|
|
1bf34d73f5 | ||
|
|
d1e360d64d | ||
|
|
3b5b19848c | ||
|
|
93ba90e837 | ||
|
|
fc70d79a17 | ||
|
|
65016a2383 | ||
|
|
dbcb2ccb46 | ||
|
|
2afcfcc87c | ||
|
|
1afef9416a | ||
|
|
4049143ebf | ||
|
|
4df53bdf8d | ||
|
|
d49a1ea304 | ||
|
|
521f4facd5 | ||
|
|
b4653dfc15 |
@@ -491,7 +491,8 @@
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/2527115?v=3",
|
||||
"profile": "https://github.com/pakkua80",
|
||||
"contributions": [
|
||||
"doc"
|
||||
"doc",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -646,6 +647,159 @@
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "BrettFagerlund",
|
||||
"name": "Brett",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/10522541?v=3",
|
||||
"profile": "https://github.com/BrettFagerlund",
|
||||
"contributions": [
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jasonspriggs",
|
||||
"name": "Jason Spriggs",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/16108587?v=3",
|
||||
"profile": "http://jasonspriggs.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "n8felton",
|
||||
"name": "Nate Felton",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/1134568?v=3",
|
||||
"profile": "http://n8felton.wordpress.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "manassesferreira",
|
||||
"name": "Manasses Ferreira",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/14036694?v=3",
|
||||
"profile": "http://homepages.dcc.ufmg.br/~manassesferreira",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "steveelwood",
|
||||
"name": "Steve",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/15913949?v=3",
|
||||
"profile": "https://github.com/steveelwood",
|
||||
"contributions": [
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "matc",
|
||||
"name": "matc",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/3361683?v=3",
|
||||
"profile": "http://twitter.com/matc",
|
||||
"contributions": [
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "VanillaNinjaD",
|
||||
"name": "Cole R. Davis",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/7405702?v=3",
|
||||
"profile": "http://www.davisracingteam.com",
|
||||
"contributions": [
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "gibsonjoshua55",
|
||||
"name": "gibsonjoshua55",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/10167681?v=3",
|
||||
"profile": "https://github.com/gibsonjoshua55",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zwerch",
|
||||
"name": "Robin Temme",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/2809241?v=4",
|
||||
"profile": "https://github.com/zwerch",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "imanghafoori1",
|
||||
"name": "Iman",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/6961695?v=4",
|
||||
"profile": "https://github.com/imanghafoori1",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "richardhofman6",
|
||||
"name": "Richard Hofman",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/6551003?v=4",
|
||||
"profile": "https://github.com/richardhofman6",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
20
.env.example
20
.env.example
@@ -8,7 +8,6 @@ APP_URL=null
|
||||
APP_TIMEZONE='UTC'
|
||||
APP_LOCALE=en
|
||||
|
||||
|
||||
# --------------------------------------------
|
||||
# REQUIRED: DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
@@ -19,6 +18,8 @@ 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
|
||||
|
||||
@@ -15,7 +15,7 @@ FILESYSTEM_DISK=local
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=snipeit_unit
|
||||
DB_USERNAME=travis
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=null
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
APP_ENV=local
|
||||
APP_ENV=testing
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://snipe-it.localapp
|
||||
DB_CONNECTION=mysql
|
||||
DB_CONNECTION=sqlite_testing
|
||||
DB_DEFAULT=sqlite_testing
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=snipeittests
|
||||
DB_USERNAME=snipeit
|
||||
|
||||
22
.github/CODEOWNERS
vendored
Normal file
22
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Code ownership for pull request reviews, per
|
||||
# the feature detailed here:
|
||||
|
||||
# https://github.com/blog/2392-introducing-code-owners
|
||||
# https://help.github.com/articles/about-codeowners/
|
||||
|
||||
# These owners will be the default owners for everything in the repo.
|
||||
* @snipe
|
||||
|
||||
# Order is important. The last matching pattern has the most precedence.
|
||||
# So if a pull request only touches javascript files, only these owners
|
||||
# will be requested to review.
|
||||
|
||||
# For example:
|
||||
# *.js @octocat @github/js
|
||||
|
||||
|
||||
app/Importer/* @dmeltzer
|
||||
app/Http/Controllers/CustomFields* @uberbrady
|
||||
app/Http/Controllers/Api/CustomFields* @uberbrady
|
||||
resources/views/custom_fields/* @uberbrady
|
||||
docker/* @uberbrady
|
||||
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
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -27,6 +27,7 @@ public/uploads/logo.png
|
||||
public/uploads/logo.svg
|
||||
public/uploads/models/*
|
||||
public/uploads/suppliers/*
|
||||
public/uploads/accessories/*
|
||||
public/uploads/users/*
|
||||
storage/app/private_uploads/users/*
|
||||
storage/debugbar/
|
||||
|
||||
12
.travis.yml
12
.travis.yml
@@ -6,6 +6,9 @@ sudo: false
|
||||
# see http://about.travis-ci.org/docs/user/languages/php/ for more hints
|
||||
language: php
|
||||
|
||||
services:
|
||||
- mysql
|
||||
|
||||
# list any PHP version you want to test against
|
||||
php:
|
||||
- 5.6
|
||||
@@ -15,16 +18,19 @@ php:
|
||||
before_script:
|
||||
- phantomjs --webdriver=4444 &
|
||||
- sleep 4
|
||||
- mysql -e "create database IF NOT EXISTS snipeit_unit;" -utravis
|
||||
- mysql -e 'CREATE DATABASE snipeit_unit;'
|
||||
- mysql -e 'CREATE USER "travis'@'localhost";'
|
||||
- mysql -e 'GRANT ALL PRIVILEGES ON * . * TO "travis'@'localhost";'
|
||||
- mysql -e 'FLUSH PRIVILEGES;'
|
||||
- composer self-update
|
||||
- composer install -n --prefer-source
|
||||
- chmod -R 777 storage
|
||||
- php artisan migrate --env=testing-ci --database=mysql --force
|
||||
- ./vendor/bin/codecept build
|
||||
- php artisan --env=testing-ci key:generate
|
||||
- php artisan --env=testing-ci snipeit:travisci-install
|
||||
- php artisan --env=testing-ci db:seed --database=mysql --force
|
||||
- php artisan --env=testing-ci snipeit:create-admin --first_name=Alison --last_name=Foobar --email=me@example.com --username=snipe --password=password
|
||||
- php artisan --env=testing-ci snipeit:travisci-install
|
||||
- php artisan --env=testing-ci passport:install
|
||||
- php artisan serve --env=testing-ci --port=8000 --host=localhost &
|
||||
- sleep 5
|
||||
@@ -37,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.
|
||||
|
||||
6
CONTRIBUTING.md
Normal file
6
CONTRIBUTING.md
Normal file
@@ -0,0 +1,6 @@
|
||||
### 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.
|
||||
42
Dockerfile
42
Dockerfile
@@ -1,14 +1,19 @@
|
||||
FROM debian:jessie-slim
|
||||
FROM ubuntu:xenial
|
||||
MAINTAINER Brady Wetherington <uberbrady@gmail.com>
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
apache2 \
|
||||
apache2-bin \
|
||||
libapache2-mod-php5 \
|
||||
php5-curl \
|
||||
php5-ldap \
|
||||
php5-mysql \
|
||||
php5-mcrypt \
|
||||
php5-gd \
|
||||
libapache2-mod-php7.0 \
|
||||
php7.0-curl \
|
||||
php7.0-ldap \
|
||||
php7.0-mysql \
|
||||
php7.0-mcrypt \
|
||||
php7.0-gd \
|
||||
php7.0-xml \
|
||||
php7.0-mbstring \
|
||||
php7.0-zip \
|
||||
php7.0-bcmath \
|
||||
patch \
|
||||
curl \
|
||||
vim \
|
||||
@@ -17,13 +22,14 @@ mysql-client \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
RUN php5enmod mcrypt
|
||||
RUN php5enmod gd
|
||||
RUN phpenmod mcrypt
|
||||
RUN phpenmod gd
|
||||
RUN phpenmod bcmath
|
||||
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php5/apache2/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php5/cli/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.0/apache2/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php/7.0/cli/php.ini
|
||||
|
||||
RUN useradd --uid 1000 --gid 50 docker
|
||||
RUN useradd -m --uid 1000 --gid 50 docker
|
||||
|
||||
RUN echo export APACHE_RUN_USER=docker >> /etc/apache2/envvars
|
||||
RUN echo export APACHE_RUN_GROUP=staff >> /etc/apache2/envvars
|
||||
@@ -66,7 +72,9 @@ RUN \
|
||||
RUN cd /tmp;curl -sS https://getcomposer.org/installer | php;mv /tmp/composer.phar /usr/local/bin/composer
|
||||
|
||||
# Get dependencies
|
||||
RUN cd /var/www/html;composer install
|
||||
USER docker
|
||||
RUN cd /var/www/html;composer install && rm -rf /home/docker/.composer/cache
|
||||
USER root
|
||||
|
||||
############### APPLICATION INSTALL/INIT #################
|
||||
|
||||
@@ -86,7 +94,13 @@ VOLUME ["/var/lib/snipeit"]
|
||||
COPY docker/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
# Add Tini
|
||||
ENV TINI_VERSION v0.14.0
|
||||
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
|
||||
RUN chmod +x /tini
|
||||
ENTRYPOINT ["/tini", "--"]
|
||||
|
||||
CMD ["/entrypoint.sh"]
|
||||
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
29
README.md
29
README.md
@@ -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
|
||||
@@ -55,17 +55,20 @@ Please see the [translations documentation](https://snipe-it.readme.io/docs/tran
|
||||
Thanks goes to all of these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)) who have helped Snipe-IT get this far:
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/197404?v=3" width="110px;"/><br /><sub>snipe</sub>](http://www.snipe.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=snipe) 🚇 [📖](https://github.com/snipe/snipe-it/commits?author=snipe) [⚠️](https://github.com/snipe/snipe-it/commits?author=snipe) [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Asnipe) 🎨 👀 | [<img src="https://avatars0.githubusercontent.com/u/36335?v=3" width="110px;"/><br /><sub>Brady Wetherington</sub>](http://www.uberbrady.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=uberbrady) [📖](https://github.com/snipe/snipe-it/commits?author=uberbrady) 🚇 👀 | [<img src="https://avatars0.githubusercontent.com/u/3803132?v=3" width="110px;"/><br /><sub>Daniel Meltzer</sub>](https://github.com/dmeltzer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dmeltzer) [⚠️](https://github.com/snipe/snipe-it/commits?author=dmeltzer) [📖](https://github.com/snipe/snipe-it/commits?author=dmeltzer) | [<img src="https://avatars0.githubusercontent.com/u/1609106?v=3" width="110px;"/><br /><sub>Michael T</sub>](http://www.tuckertechonline.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mtucker6784) | [<img src="https://avatars2.githubusercontent.com/u/3274937?v=3" width="110px;"/><br /><sub>madd15</sub>](https://github.com/madd15)<br />[📖](https://github.com/snipe/snipe-it/commits?author=madd15) 💬 | [<img src="https://avatars2.githubusercontent.com/u/894126?v=3" width="110px;"/><br /><sub>Vincent Sposato</sub>](https://github.com/vsposato)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vsposato) | [<img src="https://avatars0.githubusercontent.com/u/1639757?v=3" width="110px;"/><br /><sub>Andrea Bergamasco</sub>](https://github.com/vjandrea)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vjandrea) |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/197404?v=3" width="110px;"/><br /><sub>snipe</sub>](http://www.snipe.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=snipe "Code") [🚇](#infra-snipe "Infrastructure (Hosting, Build-Tools, etc)") [📖](https://github.com/snipe/snipe-it/commits?author=snipe "Documentation") [⚠️](https://github.com/snipe/snipe-it/commits?author=snipe "Tests") [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Asnipe "Bug reports") [🎨](#design-snipe "Design") [👀](#review-snipe "Reviewed Pull Requests") | [<img src="https://avatars0.githubusercontent.com/u/36335?v=3" width="110px;"/><br /><sub>Brady Wetherington</sub>](http://www.uberbrady.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=uberbrady "Code") [📖](https://github.com/snipe/snipe-it/commits?author=uberbrady "Documentation") [🚇](#infra-uberbrady "Infrastructure (Hosting, Build-Tools, etc)") [👀](#review-uberbrady "Reviewed Pull Requests") | [<img src="https://avatars0.githubusercontent.com/u/3803132?v=3" width="110px;"/><br /><sub>Daniel Meltzer</sub>](https://github.com/dmeltzer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dmeltzer "Code") [⚠️](https://github.com/snipe/snipe-it/commits?author=dmeltzer "Tests") [📖](https://github.com/snipe/snipe-it/commits?author=dmeltzer "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/1609106?v=3" width="110px;"/><br /><sub>Michael T</sub>](http://www.tuckertechonline.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mtucker6784 "Code") | [<img src="https://avatars2.githubusercontent.com/u/3274937?v=3" width="110px;"/><br /><sub>madd15</sub>](https://github.com/madd15)<br />[📖](https://github.com/snipe/snipe-it/commits?author=madd15 "Documentation") [💬](#question-madd15 "Answering Questions") | [<img src="https://avatars2.githubusercontent.com/u/894126?v=3" width="110px;"/><br /><sub>Vincent Sposato</sub>](https://github.com/vsposato)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vsposato "Code") | [<img src="https://avatars0.githubusercontent.com/u/1639757?v=3" width="110px;"/><br /><sub>Andrea Bergamasco</sub>](https://github.com/vjandrea)<br />[💻](https://github.com/snipe/snipe-it/commits?author=vjandrea "Code") |
|
||||
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/10640152?v=3" width="110px;"/><br /><sub>Karol</sub>](https://github.com/kpawelski)<br />🌍 [💻](https://github.com/snipe/snipe-it/commits?author=kpawelski) | [<img src="https://avatars3.githubusercontent.com/u/600106?v=3" width="110px;"/><br /><sub>morph027</sub>](http://blog.morph027.de/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=morph027) | [<img src="https://avatars3.githubusercontent.com/u/22935755?v=3" width="110px;"/><br /><sub>fvleminckx</sub>](https://github.com/fvleminckx)<br />🚇 | [<img src="https://avatars2.githubusercontent.com/u/15633547?v=3" width="110px;"/><br /><sub>itsupportcmsukorg</sub>](https://github.com/itsupportcmsukorg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=itsupportcmsukorg) [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aitsupportcmsukorg) | [<img src="https://avatars3.githubusercontent.com/u/12373799?v=3" width="110px;"/><br /><sub>Frank</sub>](https://override.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=base-zero) | [<img src="https://avatars0.githubusercontent.com/u/10137?v=3" width="110px;"/><br /><sub>Deleted user</sub>](https://github.com/ghost)<br />🌍 | [<img src="https://avatars1.githubusercontent.com/u/10802313?v=3" width="110px;"/><br /><sub>tiagom62</sub>](https://github.com/tiagom62)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tiagom62) 🚇 |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/2389047?v=3" width="110px;"/><br /><sub>Ryan Stafford</sub>](https://github.com/rystaf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rystaf) | [<img src="https://avatars2.githubusercontent.com/u/10345935?v=3" width="110px;"/><br /><sub>Eammon Hanlon</sub>](https://github.com/ehanlon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ehanlon) | [<img src="https://avatars0.githubusercontent.com/u/441924?v=3" width="110px;"/><br /><sub>zjean</sub>](https://github.com/zjean)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zjean) | [<img src="https://avatars0.githubusercontent.com/u/12660103?v=3" width="110px;"/><br /><sub>Matthias Frei</sub>](http://www.frei.media)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FREImedia) | [<img src="https://avatars0.githubusercontent.com/u/3767518?v=3" width="110px;"/><br /><sub>opsydev</sub>](https://github.com/opsydev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=opsydev) | [<img src="https://avatars1.githubusercontent.com/u/82290?v=3" width="110px;"/><br /><sub>Daniel Dreier</sub>](http://www.ddreier.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ddreier) | [<img src="https://avatars0.githubusercontent.com/u/23448?v=3" width="110px;"/><br /><sub>Nikolai Prokoschenko</sub>](http://rassie.org)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rassie) |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/13452757?v=3" width="110px;"/><br /><sub>Drew</sub>](https://github.com/YetAnotherCodeMonkey)<br />[💻](https://github.com/snipe/snipe-it/commits?author=YetAnotherCodeMonkey) | [<img src="https://avatars0.githubusercontent.com/u/1342320?v=3" width="110px;"/><br /><sub>Walter</sub>](https://github.com/merid14)<br />[💻](https://github.com/snipe/snipe-it/commits?author=merid14) | [<img src="https://avatars3.githubusercontent.com/u/11254614?v=3" width="110px;"/><br /><sub>Petr Baloun</sub>](https://github.com/balous)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balous) | [<img src="https://avatars0.githubusercontent.com/u/6117660?v=3" width="110px;"/><br /><sub>reidblomquist</sub>](https://github.com/reidblomquist)<br />[📖](https://github.com/snipe/snipe-it/commits?author=reidblomquist) | [<img src="https://avatars0.githubusercontent.com/u/539914?v=3" width="110px;"/><br /><sub>Mathieu Kooiman</sub>](https://github.com/mathieuk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mathieuk) | [<img src="https://avatars3.githubusercontent.com/u/6606421?v=3" width="110px;"/><br /><sub>csayre</sub>](https://github.com/csayre)<br />[📖](https://github.com/snipe/snipe-it/commits?author=csayre) | [<img src="https://avatars1.githubusercontent.com/u/768488?v=3" width="110px;"/><br /><sub>Adam Dunson</sub>](https://github.com/adamdunson)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adamdunson) |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/5547470?v=3" width="110px;"/><br /><sub>Hereward</sub>](https://github.com/thehereward)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thehereward) | [<img src="https://avatars0.githubusercontent.com/u/5802977?v=3" width="110px;"/><br /><sub>swoopdk</sub>](https://github.com/swoopdk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=swoopdk) | [<img src="https://avatars1.githubusercontent.com/u/3470403?v=3" width="110px;"/><br /><sub>Abdullah Alansari</sub>](https://linkedin.com/in/ahimta)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Ahimta) | [<img src="https://avatars0.githubusercontent.com/u/796443?v=3" width="110px;"/><br /><sub>Micael Rodrigues</sub>](https://github.com/MicaelRodrigues)<br />[💻](https://github.com/snipe/snipe-it/commits?author=MicaelRodrigues) | [<img src="https://avatars0.githubusercontent.com/u/614564?v=3" width="110px;"/><br /><sub>Patrick Gallagher</sub>](http://macadmincorner.com)<br />[📖](https://github.com/snipe/snipe-it/commits?author=patgmac) | [<img src="https://avatars3.githubusercontent.com/u/7165922?v=3" width="110px;"/><br /><sub>Miliamber</sub>](https://github.com/Miliamber)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Miliamber) | [<img src="https://avatars3.githubusercontent.com/u/861766?v=3" width="110px;"/><br /><sub>hawk554</sub>](https://github.com/hawk554)<br />[💻](https://github.com/snipe/snipe-it/commits?author=hawk554) |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/1695622?v=3" width="110px;"/><br /><sub>Justin Kerr</sub>](http://jbirdkerr.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbirdkerr) | [<img src="https://avatars3.githubusercontent.com/u/11426176?v=3" width="110px;"/><br /><sub>Ira W. Snyder</sub>](http://www.irasnyder.com/devel/)<br />[📖](https://github.com/snipe/snipe-it/commits?author=irasnyd) | [<img src="https://avatars2.githubusercontent.com/u/2475759?v=3" width="110px;"/><br /><sub>Aladin Alaily</sub>](https://github.com/aalaily)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aalaily) | [<img src="https://avatars0.githubusercontent.com/u/10247644?v=3" width="110px;"/><br /><sub>Chase Hansen</sub>](https://github.com/kobie-chasehansen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kobie-chasehansen) 💬 [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Akobie-chasehansen) | [<img src="https://avatars2.githubusercontent.com/u/13545400?v=3" width="110px;"/><br /><sub>IDM Helpdesk</sub>](https://github.com/IDM-Helpdesk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=IDM-Helpdesk) | [<img src="https://avatars2.githubusercontent.com/u/614439?v=3" width="110px;"/><br /><sub>Kai</sub>](http://balticer.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balticer) | [<img src="https://avatars1.githubusercontent.com/u/8762511?v=3" width="110px;"/><br /><sub>Michael Daniels</sub>](http://www.michaeldaniels.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mdaniels5757) |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/1532660?v=3" width="110px;"/><br /><sub>Tom Castleman</sub>](http://tomcastleman.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tomcastleman) | [<img src="https://avatars3.githubusercontent.com/u/10723243?v=3" width="110px;"/><br /><sub>Daniel Nemanic</sub>](https://github.com/DanielNemanic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DanielNemanic) | [<img src="https://avatars0.githubusercontent.com/u/150648?v=3" width="110px;"/><br /><sub>SouthWolf</sub>](https://github.com/southwolf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=southwolf) | [<img src="https://avatars2.githubusercontent.com/u/131616?v=3" width="110px;"/><br /><sub>Ivar Nesje</sub>](https://github.com/ivarne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ivarne) | [<img src="https://avatars1.githubusercontent.com/u/62333?v=3" width="110px;"/><br /><sub>Jérémy Benoist</sub>](http://www.j0k3r.net)<br />[📖](https://github.com/snipe/snipe-it/commits?author=j0k3r) | [<img src="https://avatars2.githubusercontent.com/u/724344?v=3" width="110px;"/><br /><sub>Chris Leathley</sub>](https://github.com/cleathley)<br />🚇 | [<img src="https://avatars0.githubusercontent.com/u/972498?v=3" width="110px;"/><br /><sub>splaer</sub>](https://github.com/splaer)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Asplaer) [💻](https://github.com/snipe/snipe-it/commits?author=splaer) |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/967362?v=3" width="110px;"/><br /><sub>Joe Ferguson</sub>](http://www.joeferguson.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=svpernova09) | [<img src="https://avatars3.githubusercontent.com/u/6108682?v=3" width="110px;"/><br /><sub>diwanicki</sub>](https://github.com/diwanicki)<br />[💻](https://github.com/snipe/snipe-it/commits?author=diwanicki) [📖](https://github.com/snipe/snipe-it/commits?author=diwanicki) | [<img src="https://avatars3.githubusercontent.com/u/2527115?v=3" width="110px;"/><br /><sub>Lee Thoong Ching</sub>](https://github.com/pakkua80)<br />[📖](https://github.com/snipe/snipe-it/commits?author=pakkua80) | [<img src="https://avatars1.githubusercontent.com/u/461491?v=3" width="110px;"/><br /><sub>Marek Šuppa</sub>](http://shu.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mrshu) | [<img src="https://avatars1.githubusercontent.com/u/8693762?v=3" width="110px;"/><br /><sub>Juan J. Martinez</sub>](https://github.com/mizar1616)<br />🌍 | [<img src="https://avatars1.githubusercontent.com/u/1458388?v=3" width="110px;"/><br /><sub>R Ryan Dial</sub>](https://github.com/rrdial)<br />🌍 | [<img src="https://avatars2.githubusercontent.com/u/2871745?v=3" width="110px;"/><br /><sub>Andrej Manduch</sub>](https://github.com/burlito)<br />[📖](https://github.com/snipe/snipe-it/commits?author=burlito) |
|
||||
| [<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) | [<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) | [<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) | [<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) | [<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) | [<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) | [<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) |
|
||||
| [<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) | [<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) | [<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) | [<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) | [<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) | [<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) |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/10640152?v=3" width="110px;"/><br /><sub>Karol</sub>](https://github.com/kpawelski)<br />[🌍](#translation-kpawelski "Translation") [💻](https://github.com/snipe/snipe-it/commits?author=kpawelski "Code") | [<img src="https://avatars3.githubusercontent.com/u/600106?v=3" width="110px;"/><br /><sub>morph027</sub>](http://blog.morph027.de/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=morph027 "Code") | [<img src="https://avatars3.githubusercontent.com/u/22935755?v=3" width="110px;"/><br /><sub>fvleminckx</sub>](https://github.com/fvleminckx)<br />[🚇](#infra-fvleminckx "Infrastructure (Hosting, Build-Tools, etc)") | [<img src="https://avatars2.githubusercontent.com/u/15633547?v=3" width="110px;"/><br /><sub>itsupportcmsukorg</sub>](https://github.com/itsupportcmsukorg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=itsupportcmsukorg "Code") [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Aitsupportcmsukorg "Bug reports") | [<img src="https://avatars3.githubusercontent.com/u/12373799?v=3" width="110px;"/><br /><sub>Frank</sub>](https://override.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=base-zero "Code") | [<img src="https://avatars0.githubusercontent.com/u/10137?v=3" width="110px;"/><br /><sub>Deleted user</sub>](https://github.com/ghost)<br />[🌍](#translation-ghost "Translation") | [<img src="https://avatars1.githubusercontent.com/u/10802313?v=3" width="110px;"/><br /><sub>tiagom62</sub>](https://github.com/tiagom62)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tiagom62 "Code") [🚇](#infra-tiagom62 "Infrastructure (Hosting, Build-Tools, etc)") |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/2389047?v=3" width="110px;"/><br /><sub>Ryan Stafford</sub>](https://github.com/rystaf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rystaf "Code") | [<img src="https://avatars2.githubusercontent.com/u/10345935?v=3" width="110px;"/><br /><sub>Eammon Hanlon</sub>](https://github.com/ehanlon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ehanlon "Code") | [<img src="https://avatars0.githubusercontent.com/u/441924?v=3" width="110px;"/><br /><sub>zjean</sub>](https://github.com/zjean)<br />[💻](https://github.com/snipe/snipe-it/commits?author=zjean "Code") | [<img src="https://avatars0.githubusercontent.com/u/12660103?v=3" width="110px;"/><br /><sub>Matthias Frei</sub>](http://www.frei.media)<br />[💻](https://github.com/snipe/snipe-it/commits?author=FREImedia "Code") | [<img src="https://avatars0.githubusercontent.com/u/3767518?v=3" width="110px;"/><br /><sub>opsydev</sub>](https://github.com/opsydev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=opsydev "Code") | [<img src="https://avatars1.githubusercontent.com/u/82290?v=3" width="110px;"/><br /><sub>Daniel Dreier</sub>](http://www.ddreier.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ddreier "Code") | [<img src="https://avatars0.githubusercontent.com/u/23448?v=3" width="110px;"/><br /><sub>Nikolai Prokoschenko</sub>](http://rassie.org)<br />[💻](https://github.com/snipe/snipe-it/commits?author=rassie "Code") |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/13452757?v=3" width="110px;"/><br /><sub>Drew</sub>](https://github.com/YetAnotherCodeMonkey)<br />[💻](https://github.com/snipe/snipe-it/commits?author=YetAnotherCodeMonkey "Code") | [<img src="https://avatars0.githubusercontent.com/u/1342320?v=3" width="110px;"/><br /><sub>Walter</sub>](https://github.com/merid14)<br />[💻](https://github.com/snipe/snipe-it/commits?author=merid14 "Code") | [<img src="https://avatars3.githubusercontent.com/u/11254614?v=3" width="110px;"/><br /><sub>Petr Baloun</sub>](https://github.com/balous)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balous "Code") | [<img src="https://avatars0.githubusercontent.com/u/6117660?v=3" width="110px;"/><br /><sub>reidblomquist</sub>](https://github.com/reidblomquist)<br />[📖](https://github.com/snipe/snipe-it/commits?author=reidblomquist "Documentation") | [<img src="https://avatars0.githubusercontent.com/u/539914?v=3" width="110px;"/><br /><sub>Mathieu Kooiman</sub>](https://github.com/mathieuk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mathieuk "Code") | [<img src="https://avatars3.githubusercontent.com/u/6606421?v=3" width="110px;"/><br /><sub>csayre</sub>](https://github.com/csayre)<br />[📖](https://github.com/snipe/snipe-it/commits?author=csayre "Documentation") | [<img src="https://avatars1.githubusercontent.com/u/768488?v=3" width="110px;"/><br /><sub>Adam Dunson</sub>](https://github.com/adamdunson)<br />[💻](https://github.com/snipe/snipe-it/commits?author=adamdunson "Code") |
|
||||
| [<img src="https://avatars0.githubusercontent.com/u/5547470?v=3" width="110px;"/><br /><sub>Hereward</sub>](https://github.com/thehereward)<br />[💻](https://github.com/snipe/snipe-it/commits?author=thehereward "Code") | [<img src="https://avatars0.githubusercontent.com/u/5802977?v=3" width="110px;"/><br /><sub>swoopdk</sub>](https://github.com/swoopdk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=swoopdk "Code") | [<img src="https://avatars1.githubusercontent.com/u/3470403?v=3" width="110px;"/><br /><sub>Abdullah Alansari</sub>](https://linkedin.com/in/ahimta)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Ahimta "Code") | [<img src="https://avatars0.githubusercontent.com/u/796443?v=3" width="110px;"/><br /><sub>Micael Rodrigues</sub>](https://github.com/MicaelRodrigues)<br />[💻](https://github.com/snipe/snipe-it/commits?author=MicaelRodrigues "Code") | [<img src="https://avatars0.githubusercontent.com/u/614564?v=3" width="110px;"/><br /><sub>Patrick Gallagher</sub>](http://macadmincorner.com)<br />[📖](https://github.com/snipe/snipe-it/commits?author=patgmac "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/7165922?v=3" width="110px;"/><br /><sub>Miliamber</sub>](https://github.com/Miliamber)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Miliamber "Code") | [<img src="https://avatars3.githubusercontent.com/u/861766?v=3" width="110px;"/><br /><sub>hawk554</sub>](https://github.com/hawk554)<br />[💻](https://github.com/snipe/snipe-it/commits?author=hawk554 "Code") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/1695622?v=3" width="110px;"/><br /><sub>Justin Kerr</sub>](http://jbirdkerr.net)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbirdkerr "Code") | [<img src="https://avatars3.githubusercontent.com/u/11426176?v=3" width="110px;"/><br /><sub>Ira W. Snyder</sub>](http://www.irasnyder.com/devel/)<br />[📖](https://github.com/snipe/snipe-it/commits?author=irasnyd "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/2475759?v=3" width="110px;"/><br /><sub>Aladin Alaily</sub>](https://github.com/aalaily)<br />[💻](https://github.com/snipe/snipe-it/commits?author=aalaily "Code") | [<img src="https://avatars0.githubusercontent.com/u/10247644?v=3" width="110px;"/><br /><sub>Chase Hansen</sub>](https://github.com/kobie-chasehansen)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kobie-chasehansen "Code") [💬](#question-kobie-chasehansen "Answering Questions") [🐛](https://github.com/snipe/snipe-it/issues?q=author%3Akobie-chasehansen "Bug reports") | [<img src="https://avatars2.githubusercontent.com/u/13545400?v=3" width="110px;"/><br /><sub>IDM Helpdesk</sub>](https://github.com/IDM-Helpdesk)<br />[💻](https://github.com/snipe/snipe-it/commits?author=IDM-Helpdesk "Code") | [<img src="https://avatars2.githubusercontent.com/u/614439?v=3" width="110px;"/><br /><sub>Kai</sub>](http://balticer.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=balticer "Code") | [<img src="https://avatars1.githubusercontent.com/u/8762511?v=3" width="110px;"/><br /><sub>Michael Daniels</sub>](http://www.michaeldaniels.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mdaniels5757 "Code") |
|
||||
| [<img src="https://avatars3.githubusercontent.com/u/1532660?v=3" width="110px;"/><br /><sub>Tom Castleman</sub>](http://tomcastleman.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=tomcastleman "Code") | [<img src="https://avatars3.githubusercontent.com/u/10723243?v=3" width="110px;"/><br /><sub>Daniel Nemanic</sub>](https://github.com/DanielNemanic)<br />[💻](https://github.com/snipe/snipe-it/commits?author=DanielNemanic "Code") | [<img src="https://avatars0.githubusercontent.com/u/150648?v=3" width="110px;"/><br /><sub>SouthWolf</sub>](https://github.com/southwolf)<br />[💻](https://github.com/snipe/snipe-it/commits?author=southwolf "Code") | [<img src="https://avatars2.githubusercontent.com/u/131616?v=3" width="110px;"/><br /><sub>Ivar Nesje</sub>](https://github.com/ivarne)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ivarne "Code") | [<img src="https://avatars1.githubusercontent.com/u/62333?v=3" width="110px;"/><br /><sub>Jérémy Benoist</sub>](http://www.j0k3r.net)<br />[📖](https://github.com/snipe/snipe-it/commits?author=j0k3r "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/724344?v=3" width="110px;"/><br /><sub>Chris Leathley</sub>](https://github.com/cleathley)<br />[🚇](#infra-cleathley "Infrastructure (Hosting, Build-Tools, etc)") | [<img src="https://avatars0.githubusercontent.com/u/972498?v=3" width="110px;"/><br /><sub>splaer</sub>](https://github.com/splaer)<br />[🐛](https://github.com/snipe/snipe-it/issues?q=author%3Asplaer "Bug reports") [💻](https://github.com/snipe/snipe-it/commits?author=splaer "Code") |
|
||||
| [<img src="https://avatars1.githubusercontent.com/u/967362?v=3" width="110px;"/><br /><sub>Joe Ferguson</sub>](http://www.joeferguson.me)<br />[💻](https://github.com/snipe/snipe-it/commits?author=svpernova09 "Code") | [<img src="https://avatars3.githubusercontent.com/u/6108682?v=3" width="110px;"/><br /><sub>diwanicki</sub>](https://github.com/diwanicki)<br />[💻](https://github.com/snipe/snipe-it/commits?author=diwanicki "Code") [📖](https://github.com/snipe/snipe-it/commits?author=diwanicki "Documentation") | [<img src="https://avatars3.githubusercontent.com/u/2527115?v=3" width="110px;"/><br /><sub>Lee Thoong Ching</sub>](https://github.com/pakkua80)<br />[📖](https://github.com/snipe/snipe-it/commits?author=pakkua80 "Documentation") [💻](https://github.com/snipe/snipe-it/commits?author=pakkua80 "Code") | [<img src="https://avatars1.githubusercontent.com/u/461491?v=3" width="110px;"/><br /><sub>Marek Šuppa</sub>](http://shu.io)<br />[💻](https://github.com/snipe/snipe-it/commits?author=mrshu "Code") | [<img src="https://avatars1.githubusercontent.com/u/8693762?v=3" width="110px;"/><br /><sub>Juan J. Martinez</sub>](https://github.com/mizar1616)<br />[🌍](#translation-mizar1616 "Translation") | [<img src="https://avatars1.githubusercontent.com/u/1458388?v=3" width="110px;"/><br /><sub>R Ryan Dial</sub>](https://github.com/rrdial)<br />[🌍](#translation-rrdial "Translation") | [<img src="https://avatars2.githubusercontent.com/u/2871745?v=3" width="110px;"/><br /><sub>Andrej Manduch</sub>](https://github.com/burlito)<br />[📖](https://github.com/snipe/snipe-it/commits?author=burlito "Documentation") |
|
||||
| [<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://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") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
@@ -74,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.
|
||||
|
||||
85
app/Console/Commands/FixDoubleEscape.php
Normal file
85
app/Console/Commands/FixDoubleEscape.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class FixDoubleEscape extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:unescape';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This should be run to fix some double-escaping issues from earlier versions of Snipe-IT.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$tables = [
|
||||
'\App\Models\Asset' => ['name'],
|
||||
'\App\Models\License' => ['name'],
|
||||
'\App\Models\Consumable' => ['name'],
|
||||
'\App\Models\Accessory' => ['name'],
|
||||
'\App\Models\Component' => ['name'],
|
||||
'\App\Models\Company' => ['name'],
|
||||
'\App\Models\Manufacturer' => ['name'],
|
||||
'\App\Models\Supplier' => ['name'],
|
||||
'\App\Models\Statuslabel' => ['name'],
|
||||
'\App\Models\Depreciation' => ['name'],
|
||||
'\App\Models\AssetModel' => ['name'],
|
||||
'\App\Models\Group' => ['name'],
|
||||
'\App\Models\Department' => ['name'],
|
||||
'\App\Models\Location' => ['name'],
|
||||
'\App\Models\User' => ['first_name', 'last_name'],
|
||||
];
|
||||
|
||||
$count = array();
|
||||
|
||||
|
||||
|
||||
foreach ($tables as $classname => $fields) {
|
||||
$count[$classname] = array();
|
||||
$count[$classname]['classname'] = 0;
|
||||
|
||||
foreach($fields as $field) {
|
||||
|
||||
$count[$classname]['classname']++;
|
||||
$count[$classname][$field] = 0;
|
||||
|
||||
foreach($classname::where("$field",'LIKE','%&%')->get() as $row) {
|
||||
$this->info('Updating '.$field.' for '.$classname);
|
||||
$row->{$field} = html_entity_decode($row->{$field});
|
||||
$row->save();
|
||||
$count[$classname][$field]++;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('Update complete');
|
||||
|
||||
}
|
||||
}
|
||||
57
app/Console/Commands/LdapSync.php
Normal file → Executable file
57
app/Console/Commands/LdapSync.php
Normal file → Executable file
@@ -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,26 +98,26 @@ class LdapSync extends Command
|
||||
LOG::debug('Location ID '.$this->option('location_id').' passed');
|
||||
LOG::debug('Importing to '.$location->name.' ('.$location->id.')');
|
||||
} else {
|
||||
$location = new Location;
|
||||
}
|
||||
$location = NULL;
|
||||
}
|
||||
|
||||
if (!isset($location)) {
|
||||
LOG::debug('That location is invalid, so no location will be assigned by default.');
|
||||
LOG::debug('That location is invalid or a location was not provided, so no location will be assigned by default.');
|
||||
}
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
// Delete located users from the general group.
|
||||
foreach ($results as $key => $generic_entry) {
|
||||
if (in_array($generic_entry[$ldap_result_username][0], $location_users)) {
|
||||
if (in_array($generic_entry[$ldap_result_username][0], $usernames)) {
|
||||
unset($results[$key]);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,398 +0,0 @@
|
||||
<?php
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use League\Csv\Reader;
|
||||
use App\Models\User;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\Asset;
|
||||
|
||||
class LicenseImportCommand extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'snipeit:license-import';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Import Licenses from CSV';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function fire()
|
||||
{
|
||||
$filename = $this->argument('filename');
|
||||
|
||||
|
||||
if (!$this->option('testrun')=='true') {
|
||||
$this->comment('======= Importing Licenses from '.$filename.' =========');
|
||||
} else {
|
||||
$this->comment('====== TEST ONLY License Import for '.$filename.' ====');
|
||||
$this->comment('============== NO DATA WILL BE WRITTEN ==============');
|
||||
}
|
||||
|
||||
if (! ini_get("auto_detect_line_endings")) {
|
||||
ini_set("auto_detect_line_endings", '1');
|
||||
}
|
||||
|
||||
$csv = Reader::createFromPath($this->argument('filename'));
|
||||
$csv->setNewline("\r\n");
|
||||
$csv->setOffset(1);
|
||||
$duplicates = '';
|
||||
|
||||
// Loop through the records
|
||||
$nbInsert = $csv->each(function ($row) use ($duplicates) {
|
||||
$status_id = 1;
|
||||
|
||||
// Let's just map some of these entries to more user friendly words
|
||||
|
||||
if (array_key_exists('0', $row)) {
|
||||
$user_name = trim($row[0]);
|
||||
} else {
|
||||
$user_name = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('1', $row)) {
|
||||
$user_email = trim($row[1]);
|
||||
} else {
|
||||
$user_email = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('2', $row)) {
|
||||
$user_username = trim($row[2]);
|
||||
} else {
|
||||
$user_username = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('3', $row)) {
|
||||
$user_license_name = trim($row[3]);
|
||||
} else {
|
||||
$user_license_name = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('4', $row)) {
|
||||
$user_license_serial = trim($row[4]);
|
||||
} else {
|
||||
$user_license_serial = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('5', $row)) {
|
||||
$user_licensed_to_name = trim($row[5]);
|
||||
} else {
|
||||
$user_licensed_to_name = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('6', $row)) {
|
||||
$user_licensed_to_email = trim($row[6]);
|
||||
} else {
|
||||
$user_licensed_to_email = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('7', $row)) {
|
||||
$user_license_seats = trim($row[7]);
|
||||
} else {
|
||||
$user_license_seats = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('8', $row)) {
|
||||
$user_license_reassignable = trim($row[8]);
|
||||
if ($user_license_reassignable!='') {
|
||||
if ((strtolower($user_license_reassignable)=='yes') || (strtolower($user_license_reassignable)=='true') || ($user_license_reassignable=='1')) {
|
||||
$user_license_reassignable = 1;
|
||||
}
|
||||
} else {
|
||||
$user_license_reassignable = 0;
|
||||
}
|
||||
} else {
|
||||
$user_license_reassignable = 0;
|
||||
}
|
||||
|
||||
if (array_key_exists('9', $row)) {
|
||||
$user_license_supplier = trim($row[9]);
|
||||
} else {
|
||||
$user_license_supplier = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('10', $row)) {
|
||||
$user_license_maintained = trim($row[10]);
|
||||
|
||||
if ($user_license_maintained!='') {
|
||||
if ((strtolower($user_license_maintained)=='yes') || (strtolower($user_license_maintained)=='true') || ($user_license_maintained=='1')) {
|
||||
$user_license_maintained = 1;
|
||||
}
|
||||
} else {
|
||||
$user_license_maintained = 0;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
$user_license_maintained = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('11', $row)) {
|
||||
$user_license_notes = trim($row[11]);
|
||||
} else {
|
||||
$user_license_notes = '';
|
||||
}
|
||||
|
||||
if (array_key_exists('12', $row)) {
|
||||
if ($row[12]!='') {
|
||||
$user_license_purchase_date = date("Y-m-d 00:00:01", strtotime($row[12]));
|
||||
} else {
|
||||
$user_license_purchase_date = '';
|
||||
}
|
||||
} else {
|
||||
$user_license_purchase_date = 0;
|
||||
}
|
||||
|
||||
if (array_key_exists('13', $row)) {
|
||||
$user_licensed_to_asset = trim($row[13]);
|
||||
} else {
|
||||
$user_licensed_to_asset = '';
|
||||
}
|
||||
|
||||
// A number was given instead of a name
|
||||
if (is_numeric($user_name)) {
|
||||
$this->comment('User '.$user_name.' is not a name - assume this user already exists');
|
||||
$user_username = '';
|
||||
// No name was given
|
||||
|
||||
} elseif ($user_name=='') {
|
||||
$this->comment('No user data provided - skipping user creation, just adding license');
|
||||
$first_name = '';
|
||||
$last_name = '';
|
||||
$user_username = '';
|
||||
|
||||
} else {
|
||||
|
||||
$name = explode(" ", $user_name);
|
||||
$first_name = $name[0];
|
||||
$email_last_name = '';
|
||||
$email_prefix = $first_name;
|
||||
|
||||
if (!array_key_exists(1, $name)) {
|
||||
$last_name='';
|
||||
$email_last_name = $last_name;
|
||||
$email_prefix = $first_name;
|
||||
} else {
|
||||
$last_name = str_replace($first_name, '', $user_name);
|
||||
|
||||
if ($this->option('email_format')=='filastname') {
|
||||
$email_last_name.=str_replace(' ', '', $last_name);
|
||||
$email_prefix = $first_name[0].$email_last_name;
|
||||
|
||||
} elseif ($this->option('email_format')=='firstname.lastname') {
|
||||
$email_last_name.=str_replace(' ', '', $last_name);
|
||||
$email_prefix = $first_name.'.'.$email_last_name;
|
||||
|
||||
} elseif ($this->option('email_format')=='firstname') {
|
||||
$email_last_name.=str_replace(' ', '', $last_name);
|
||||
$email_prefix = $first_name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
$user_username = $email_prefix;
|
||||
|
||||
// Generate an email based on their name if no email address is given
|
||||
if ($user_email=='') {
|
||||
if ($first_name=='Unknown') {
|
||||
$status_id = 7;
|
||||
}
|
||||
$email = strtolower($email_prefix).'@'.$this->option('domain');
|
||||
$user_email = str_replace("'", '', $email);
|
||||
}
|
||||
}
|
||||
|
||||
$this->comment('Full Name: '.$user_name);
|
||||
$this->comment('First Name: '.$first_name);
|
||||
$this->comment('Last Name: '.$last_name);
|
||||
$this->comment('Username: '.$user_username);
|
||||
$this->comment('Email: '.$user_email);
|
||||
$this->comment('License Name: '.$user_license_name);
|
||||
$this->comment('Serial No: '.$user_license_serial);
|
||||
$this->comment('Licensed To Name: '.$user_licensed_to_name);
|
||||
$this->comment('Licensed To Email: '.$user_licensed_to_email);
|
||||
$this->comment('Seats: '.$user_license_seats);
|
||||
$this->comment('Reassignable: '.$user_license_reassignable);
|
||||
$this->comment('Supplier: '.$user_license_supplier);
|
||||
$this->comment('Maintained: '.$user_license_maintained);
|
||||
$this->comment('Notes: '.$user_license_notes);
|
||||
$this->comment('Purchase Date: '.$user_license_purchase_date);
|
||||
$this->comment('Asset ID: '.$user_licensed_to_asset);
|
||||
|
||||
$this->comment('------------- Action Summary ----------------');
|
||||
|
||||
if ($user_username!='') {
|
||||
if ($user = User::where('username', $user_username)->whereNotNull('username')->first()) {
|
||||
$this->comment('User '.$user_username.' already exists');
|
||||
} else {
|
||||
|
||||
$user = new \App\Models\User;
|
||||
$password = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
|
||||
|
||||
$user->first_name = $first_name;
|
||||
$user->last_name = $last_name;
|
||||
$user->username = $user_username;
|
||||
$user->email = $user_email;
|
||||
$user->permissions = '{user":1}';
|
||||
$user->password = bcrypt($password);
|
||||
$user->activated = 1;
|
||||
if ($user->save()) {
|
||||
$this->comment('User '.$first_name.' created');
|
||||
} else {
|
||||
$this->error('ERROR CREATING User '.$first_name.' '.$last_name);
|
||||
$this->error($user->getErrors());
|
||||
}
|
||||
|
||||
$this->comment('User '.$first_name.' created');
|
||||
}
|
||||
} else {
|
||||
$user = new User;
|
||||
$user->user_id = null;
|
||||
}
|
||||
|
||||
|
||||
// Check for the supplier match and create it if it doesn't exist
|
||||
if ($supplier = Supplier::where('name', $user_license_supplier)->first()) {
|
||||
$this->comment('Supplier '.$user_license_supplier.' already exists');
|
||||
} else {
|
||||
$supplier = new Supplier();
|
||||
$supplier->name = e($user_license_supplier);
|
||||
$supplier->user_id = 1;
|
||||
|
||||
if ($supplier->save()) {
|
||||
$this->comment('Supplier '.$user_license_supplier.' was created');
|
||||
} else {
|
||||
$this->comment('Something went wrong! Supplier '.$user_license_supplier.' was NOT created');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Add the license
|
||||
$license = new License();
|
||||
$license->name = e($user_license_name);
|
||||
if ($user_license_purchase_date!='') {
|
||||
$license->purchase_date = $user_license_purchase_date;
|
||||
} else {
|
||||
$license->purchase_date = null;
|
||||
}
|
||||
$license->serial = e($user_license_serial);
|
||||
$license->seats = e($user_license_seats);
|
||||
$license->supplier_id = $supplier->id;
|
||||
$license->user_id = 1;
|
||||
if ($user_license_purchase_date!='') {
|
||||
$license->purchase_date = $user_license_purchase_date;
|
||||
} else {
|
||||
$license->purchase_date = null;
|
||||
}
|
||||
$license->license_name = $user_licensed_to_name;
|
||||
$license->license_email = $user_licensed_to_email;
|
||||
$license->notes = e($user_license_notes);
|
||||
|
||||
if ($license->save()) {
|
||||
$this->comment('License '.$user_license_name.' with serial number '.$user_license_serial.' was created');
|
||||
|
||||
|
||||
$license_seat_created = 0;
|
||||
|
||||
for ($x = 0; $x < $user_license_seats; $x++) {
|
||||
// Create the license seat entries
|
||||
$license_seat = new LicenseSeat();
|
||||
$license_seat->license_id = $license->id;
|
||||
|
||||
// Only assign the first seat to the user
|
||||
if ($x==0) {
|
||||
$license_seat->assigned_to = $user->id;
|
||||
} else {
|
||||
$license_seat->assigned_to = null;
|
||||
}
|
||||
|
||||
if($user_licensed_to_asset) {
|
||||
$asset = Asset::where('asset_tag', $user_licensed_to_asset)->first();
|
||||
if($asset) {
|
||||
$license_seat->asset_id = $asset->id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($license_seat->save()) {
|
||||
$license_seat_created++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($license_seat_created > 0) {
|
||||
$this->comment($license_seat_created.' seats were created');
|
||||
} else {
|
||||
$this->comment('Something went wrong! NO seats for '.$user_license_name.' were created');
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
$this->comment('Something went wrong! License '.$user_license_name.' was NOT created');
|
||||
}
|
||||
|
||||
|
||||
$this->comment('=====================================');
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArguments()
|
||||
{
|
||||
return array(
|
||||
array('filename', InputArgument::REQUIRED, 'File for the CSV import.'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return array(
|
||||
array('domain', null, InputOption::VALUE_REQUIRED, 'Email domain for generated email addresses.', null),
|
||||
array('email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null),
|
||||
array('testrun', null, InputOption::VALUE_REQUIRED, 'Test the output without writing to the database or not.', null),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -72,19 +72,13 @@ class ObjectImportCommand extends Command
|
||||
$classString = "App\\Importer\\{$class}Importer";
|
||||
$importer = new $classString($filename);
|
||||
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
|
||||
->setTestRun($this->option('testrun'))
|
||||
->setUserId($this->option('user_id'))
|
||||
->setUpdating($this->option('update'))
|
||||
->setUsernameFormat($this->option('username_format'));
|
||||
|
||||
$logFile = $this->option('logfile');
|
||||
\Log::useFiles($logFile);
|
||||
if ($this->option('testrun')) {
|
||||
$this->comment('====== TEST ONLY Asset Import for '.$filename.' ====');
|
||||
$this->comment('============== NO DATA WILL BE WRITTEN ==============');
|
||||
} else {
|
||||
$this->comment('======= Importing Assets from '.$filename.' =========');
|
||||
}
|
||||
$this->comment('======= Importing Items from '.$filename.' =========');
|
||||
$importer->import();
|
||||
|
||||
$this->bar = null;
|
||||
@@ -173,9 +167,8 @@ class ObjectImportCommand extends Command
|
||||
return array(
|
||||
array('email_format', null, InputOption::VALUE_REQUIRED, 'The format of the email addresses that should be generated. Options are firstname.lastname, firstname, filastname', null),
|
||||
array('username_format', null, InputOption::VALUE_REQUIRED, 'The format of the username that should be generated. Options are firstname.lastname, firstname, filastname, email', null),
|
||||
array('testrun', null, InputOption::VALUE_NONE, 'If set, will parse and output data without adding to database', null),
|
||||
array('logfile', null, InputOption::VALUE_REQUIRED, 'The path to log output to. storage/logs/importer.log by default', storage_path('logs/importer.log') ),
|
||||
array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Or Accessory', 'Asset'),
|
||||
array('item-type', null, InputOption::VALUE_REQUIRED, 'Item Type To import. Valid Options are Asset, Consumable, Accessory, License, or User', 'Asset'),
|
||||
array('web-importer', null, InputOption::VALUE_NONE, 'Internal: packages output for use with the web importer'),
|
||||
array('user_id', null, InputOption::VALUE_REQUIRED, 'ID of user creating items', 1),
|
||||
array('update', null, InputOption::VALUE_NONE, 'If a matching item is found, update item information'),
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use DB;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
@@ -12,14 +9,18 @@ use App\Models\Category;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Department;
|
||||
use App\Models\Depreciation;
|
||||
use App\Models\Group;
|
||||
use App\Models\Import;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\Location;
|
||||
use App\Models\Manufacturer;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Supplier;
|
||||
use DB;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class PaveIt extends Command
|
||||
{
|
||||
@@ -63,6 +64,7 @@ class PaveIt extends Command
|
||||
Company::getQuery()->delete();
|
||||
Component::getQuery()->delete();
|
||||
Consumable::getQuery()->delete();
|
||||
Department::getQuery()->delete();
|
||||
Depreciation::getQuery()->delete();
|
||||
License::getQuery()->delete();
|
||||
LicenseSeat::getQuery()->delete();
|
||||
@@ -72,6 +74,7 @@ class PaveIt extends Command
|
||||
Statuslabel::getQuery()->delete();
|
||||
Supplier::getQuery()->delete();
|
||||
Group::getQuery()->delete();
|
||||
Import::getQuery()->delete();
|
||||
|
||||
DB::statement('delete from accessories_users');
|
||||
DB::statement('delete from asset_logs');
|
||||
@@ -107,6 +110,7 @@ class PaveIt extends Command
|
||||
\DB::statement('drop table IF EXISTS custom_fields');
|
||||
\DB::statement('drop table IF EXISTS custom_fieldsets');
|
||||
\DB::statement('drop table IF EXISTS depreciations');
|
||||
\DB::statement('drop table IF EXISTS departments');
|
||||
\DB::statement('drop table IF EXISTS groups');
|
||||
\DB::statement('drop table IF EXISTS history');
|
||||
\DB::statement('drop table IF EXISTS components');
|
||||
@@ -131,6 +135,7 @@ class PaveIt extends Command
|
||||
\DB::statement('drop table IF EXISTS throttle');
|
||||
\DB::statement('drop table IF EXISTS users_groups');
|
||||
\DB::statement('drop table IF EXISTS users');
|
||||
\DB::statement('drop table IF EXISTS imports');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
167
app/Console/Commands/RecryptFromMcrypt.php
Normal file
167
app/Console/Commands/RecryptFromMcrypt.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Console\Command;
|
||||
use App\LegacyEncrypter\McryptEncrypter;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class RecryptFromMcrypt extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:legacy-recrypt
|
||||
{--force : Force a re-crypt of encrypted data from MCRYPT.}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This command allows upgrading users to de-encrypt their deprecated mcrypt encrypted fields and re-encrypt them using the current OpenSSL encryption.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
|
||||
// Check and see if they have a legacy app key listed in their .env
|
||||
// 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) {
|
||||
$this->error('ERROR: You do not have a LEGACY_APP_KEY set in your .env file. Please locate your old APP_KEY and ADD a line to your .env file like: LEGACY_APP_KEY=YOUR_OLD_APP_KEY');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Do some basic legacy app key length checks
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check that the app key is 32 characters
|
||||
if ($legacy_length_check === true) {
|
||||
$this->comment('INFO: Your LEGACY_APP_KEY looks correct. Okay to continue.');
|
||||
} else {
|
||||
$this->error('ERROR: Your LEGACY_APP_KEY is not the correct length (32 characters or base64 followed by 44 characters for later versions). Please locate your old APP_KEY and use that as your LEGACY_APP_KEY in your .env file to continue.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->error('================================!!!! WARNING !!!!================================');
|
||||
$this->error('================================!!!! WARNING !!!!================================');
|
||||
$this->comment("This tool will attempt to decrypt your old Snipe-IT (mcrypt, now deprecated) encrypted data and re-encrypt it using OpenSSL. \n\nYou should only continue if you have backed up any and all old APP_KEYs and have backed up your data.");
|
||||
|
||||
$force = ($this->option('force')) ? true : false;
|
||||
|
||||
if ($force || ($this->confirm("Are you SURE you wish to continue?"))) {
|
||||
|
||||
$backup_file = 'backups/env-backups/'.'app_key-'.date('Y-m-d-gis');
|
||||
|
||||
try {
|
||||
Storage::disk('local')->put($backup_file, 'APP_KEY: '.config('app.key'));
|
||||
Storage::disk('local')->append($backup_file, 'LEGACY_APP_KEY: '.$legacy_key);
|
||||
} catch (\Exception $e) {
|
||||
$this->info('WARNING: Could not backup app keys');
|
||||
}
|
||||
|
||||
|
||||
if ($legacy_cipher){
|
||||
$mcrypter = new McryptEncrypter($legacy_key,$legacy_cipher);
|
||||
}else{
|
||||
$mcrypter = new McryptEncrypter($legacy_key);
|
||||
}
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
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...');
|
||||
|
||||
$query = Asset::withTrashed();
|
||||
|
||||
foreach ($custom_fields as $custom_field) {
|
||||
$this->comment('FIELD TO RECRYPT: '.$custom_field->name .' ('.$custom_field->db_column.')');
|
||||
$query->orWhereNotNull($custom_field->db_column);
|
||||
}
|
||||
|
||||
|
||||
// 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 ($assets as $asset) {
|
||||
foreach ($custom_fields as $encrypted_field) {
|
||||
$columnName = $encrypted_field->db_column;
|
||||
|
||||
// Make sure the value isn't null
|
||||
if ($asset->{$columnName}!='') {
|
||||
// Try to decrypt the payload using the legacy app key
|
||||
try {
|
||||
$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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$asset->save();
|
||||
$bar->advance();
|
||||
}
|
||||
|
||||
|
||||
|
||||
$bar->finish();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
$this->comment("\n\n");
|
||||
$this->error("The decrypter encountered some errors: \n");
|
||||
foreach ($errors as $error) {
|
||||
$this->error($error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
64
app/Console/Commands/SendExpectedCheckinAlerts.php
Normal file
64
app/Console/Commands/SendExpectedCheckinAlerts.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
|
||||
use App\Models\Asset;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Notifications\ExpectedCheckinNotification;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class SendExpectedCheckinAlerts extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'snipeit:expected-checkin';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Check for overdue or upcoming expected checkins.';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function fire()
|
||||
{
|
||||
|
||||
$whenNotify = Carbon::now()->addDays(7);
|
||||
$assets = Asset::with('assignedTo')->whereNotNull('expected_checkin')->where('expected_checkin', '<=', $whenNotify)->get();
|
||||
|
||||
$this->info($whenNotify.' is deadline');
|
||||
$this->info($assets->count().' assets');
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
if ($asset->assignedTo && $asset->checkoutOutToUser()) {
|
||||
$asset->assignedTo->notify((new ExpectedCheckinNotification($asset)));
|
||||
//$this->info($asset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,16 @@ class Kernel extends ConsoleKernel
|
||||
Commands\CreateAdmin::class,
|
||||
Commands\SendExpirationAlerts::class,
|
||||
Commands\SendInventoryAlerts::class,
|
||||
Commands\LicenseImportCommand::class,
|
||||
Commands\SendExpectedCheckinAlerts::class,
|
||||
Commands\ObjectImportCommand::class,
|
||||
Commands\Versioning::class,
|
||||
Commands\SystemBackup::class,
|
||||
Commands\DisableLDAP::class,
|
||||
Commands\Purge::class,
|
||||
Commands\LdapSync::class,
|
||||
Commands\FixDoubleEscape::class,
|
||||
Commands\RecryptFromMcrypt::class,
|
||||
Commands\ResetDemoSettings::class
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -37,6 +40,7 @@ class Kernel extends ConsoleKernel
|
||||
|
||||
$schedule->command('snipeit:inventory-alerts')->daily();
|
||||
$schedule->command('snipeit:expiring-alerts')->daily();
|
||||
$schedule->command('snipeit:expected-checkin')->daily();
|
||||
$schedule->command('snipeit:backup')->weekly();
|
||||
$schedule->command('backup:clean')->daily();
|
||||
}
|
||||
|
||||
12
app/Exceptions/CheckoutNotAllowed.php
Normal file
12
app/Exceptions/CheckoutNotAllowed.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
class CheckoutNotAllowed extends Exception
|
||||
{
|
||||
public function __toString()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +84,7 @@ class Handler extends ExceptionHandler
|
||||
|
||||
}
|
||||
}
|
||||
// Try to parse 500 Errors ina bit nicer way when debug is enabled.
|
||||
// Try to parse 500 Errors in a bit nicer way when debug is enabled.
|
||||
if (config('app.debug')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, "An Error has occured! " . $e->getMessage()), 500);
|
||||
}
|
||||
@@ -91,7 +95,7 @@ class Handler extends ExceptionHandler
|
||||
if ($this->isHttpException($e) && (isset($statusCode)) && ($statusCode == '404' )) {
|
||||
return response()->view('layouts/basic', [
|
||||
'content' => view('errors/404')
|
||||
]);
|
||||
],$statusCode);
|
||||
}
|
||||
|
||||
return parent::render($request, $e);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Helpers;
|
||||
use DB;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\Location;
|
||||
use App\Models\Department;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
@@ -184,6 +185,25 @@ class Helper
|
||||
return $category_list;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of categories in an array to make a dropdown menu
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v2.5]
|
||||
* @return Array
|
||||
*/
|
||||
public static function departmentList()
|
||||
{
|
||||
$departments = Department::orderBy('name', 'asc')
|
||||
->whereNull('deleted_at')
|
||||
->orderBy('name', 'asc');
|
||||
|
||||
return array('' => trans('general.select_department')) + $departments->pluck('name', 'id')->toArray();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of suppliers in an array to make a dropdown menu
|
||||
*
|
||||
@@ -663,12 +683,11 @@ class Helper
|
||||
public static function formatStandardApiResponse($status, $payload = null, $messages = null) {
|
||||
|
||||
$array['status'] = $status;
|
||||
($payload) ? $array['payload'] = $payload : '';
|
||||
|
||||
$array['messages'] = $messages;
|
||||
if (($messages) && (count($messages) > 0)) {
|
||||
$array['messages'] = $messages;
|
||||
}
|
||||
|
||||
($payload) ? $array['payload'] = $payload : $array['payload'] = null;
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -39,7 +41,7 @@ class AccessoriesController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('index', Accessory::class);
|
||||
return View::make('accessories/index');
|
||||
return view('accessories/index');
|
||||
}
|
||||
|
||||
|
||||
@@ -53,10 +55,11 @@ class AccessoriesController extends Controller
|
||||
{
|
||||
$this->authorize('create', Accessory::class);
|
||||
// Show the page
|
||||
return View::make('accessories/edit')
|
||||
return view('accessories/edit')
|
||||
->with('item', new Accessory)
|
||||
->with('category_list', Helper::categoryList('accessory'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
}
|
||||
@@ -68,7 +71,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,10 +90,31 @@ 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()) {
|
||||
$accessory->logCreate();
|
||||
// Redirect to the new accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.create.success'));
|
||||
}
|
||||
@@ -108,16 +132,16 @@ class AccessoriesController extends Controller
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($item = Accessory::find($accessoryId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize($item);
|
||||
|
||||
return View::make('accessories/edit', compact('item'))
|
||||
return view('accessories/edit', compact('item'))
|
||||
->with('category_list', Helper::categoryList('accessory'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('manufacturer_list', Helper::manufacturerList());
|
||||
}
|
||||
|
||||
@@ -129,11 +153,9 @@ class AccessoriesController extends Controller
|
||||
* @param int $accessoryId
|
||||
* @return Redirect
|
||||
*/
|
||||
public function update(Request $request, $accessoryId = null)
|
||||
public function update(ImageUploadRequest $request, $accessoryId = null)
|
||||
{
|
||||
// Check if the accessory exists
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
// Redirect to the accessory index page
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.does_not_exist'));
|
||||
}
|
||||
|
||||
@@ -148,13 +170,39 @@ 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()) {
|
||||
// Redirect to the updated accessory page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($accessory->getErrors());
|
||||
@@ -169,9 +217,7 @@ class AccessoriesController extends Controller
|
||||
*/
|
||||
public function destroy(Request $request, $accessoryId)
|
||||
{
|
||||
// Check if the blog post exists
|
||||
if (is_null($accessory = Accessory::find($accessoryId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.not_found'));
|
||||
}
|
||||
|
||||
@@ -182,7 +228,6 @@ class AccessoriesController extends Controller
|
||||
return redirect()->route('accessories.index')->with('error', trans('admin/accessories/message.assoc_users', array('count'=> $accessory->hasUsers())));
|
||||
}
|
||||
$accessory->delete();
|
||||
// Redirect to the locations management page
|
||||
return redirect()->route('accessories.index')->with('success', trans('admin/accessories/message.delete.success'));
|
||||
}
|
||||
|
||||
@@ -203,13 +248,9 @@ class AccessoriesController extends Controller
|
||||
$accessory = Accessory::find($accessoryID);
|
||||
$this->authorize('view', $accessory);
|
||||
if (isset($accessory->id)) {
|
||||
return View::make('accessories/view', compact('accessory'));
|
||||
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')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,7 +271,7 @@ class AccessoriesController extends Controller
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return View::make('accessories/checkout', compact('accessory'))->with('users_list', Helper::usersList());
|
||||
return view('accessories/checkout', compact('accessory'))->with('users_list', Helper::usersList());
|
||||
|
||||
}
|
||||
|
||||
@@ -268,7 +309,7 @@ class AccessoriesController extends Controller
|
||||
'assigned_to' => $request->get('assigned_to')
|
||||
]);
|
||||
|
||||
$logaction = $accessory->logCheckout(e(Input::get('note')));
|
||||
$logaction = $accessory->logCheckout(e(Input::get('note')), $user);
|
||||
|
||||
DB::table('accessories_users')->where('assigned_to', '=', $accessory->assigned_to)->where('accessory_id', '=', $accessory->id)->first();
|
||||
|
||||
@@ -282,7 +323,7 @@ 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);
|
||||
@@ -316,7 +357,7 @@ class AccessoriesController extends Controller
|
||||
|
||||
$accessory = Accessory::find($accessory_user->accessory_id);
|
||||
$this->authorize('checkin', $accessory);
|
||||
return View::make('accessories/checkin', compact('accessory'))->with('backto', $backto);
|
||||
return view('accessories/checkin', compact('accessory'))->with('backto', $backto);
|
||||
}
|
||||
|
||||
|
||||
@@ -359,7 +400,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);
|
||||
@@ -377,143 +418,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';
|
||||
@@ -128,10 +133,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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
227
app/Http/Controllers/Api/AssetMaintenancesController.php
Normal file
227
app/Http/Controllers/Api/AssetMaintenancesController.php
Normal file
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\AssetMaintenancesTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\Company;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Asset Maintenance for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @version v2.0
|
||||
*/
|
||||
class AssetMaintenancesController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Generates the JSON response for asset maintenances listing view.
|
||||
*
|
||||
* @see AssetMaintenancesController::getIndex() method that generates view
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$maintenances = AssetMaintenance::with('asset', 'supplier', 'asset.company', 'admin');
|
||||
|
||||
if (Input::has('search')) {
|
||||
$maintenances = $maintenances->TextSearch(e($request->input('search')));
|
||||
}
|
||||
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$allowed_columns = ['id','title','asset_maintenance_time','asset_maintenance_type','cost','start_date','completion_date','notes','user_id'];
|
||||
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array(Input::get('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
|
||||
switch ($sort) {
|
||||
case 'user_id':
|
||||
$maintenances = $maintenances->OrderAdmin($order);
|
||||
break;
|
||||
default:
|
||||
$maintenances = $maintenances->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$maintenances = $maintenances->skip($offset)->take($limit)->get();
|
||||
|
||||
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenances($maintenances, $maintenances->count());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and stores the new asset maintenance
|
||||
*
|
||||
* @see AssetMaintenancesController::getCreate() method for the form
|
||||
* @author Vincent Sposato <vincent.sposato@gmail.com>
|
||||
* @version v1.0
|
||||
* @since [v1.8]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
// create a new model instance
|
||||
$assetMaintenance = new AssetMaintenance();
|
||||
$assetMaintenance->supplier_id = $request->input('supplier_id');
|
||||
$assetMaintenance->is_warranty = $request->input('is_warranty');
|
||||
$assetMaintenance->cost = e($request->input('cost'));
|
||||
$assetMaintenance->notes = e($request->input('notes'));
|
||||
$asset = Asset::find(e($request->input('asset_id')));
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot add a maintenance for that asset'));
|
||||
}
|
||||
|
||||
// Save the asset maintenance data
|
||||
$assetMaintenance->asset_id = $request->input('asset_id');
|
||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$assetMaintenance->title = $request->input('title');
|
||||
$assetMaintenance->start_date = $request->input('start_date');
|
||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
||||
$assetMaintenance->user_id = Auth::id();
|
||||
|
||||
if (( $assetMaintenance->completion_date !== null )
|
||||
&& ( $assetMaintenance->start_date !== "" )
|
||||
&& ( $assetMaintenance->start_date !== "0000-00-00" )
|
||||
) {
|
||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
||||
$assetMaintenance->asset_maintenance_time = $completionDate->diffInDays($startDate);
|
||||
}
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if ($assetMaintenance->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.create.success')));
|
||||
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetMaintenance->getErrors()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and stores an update to an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $assetMaintenanceId
|
||||
* @param int $request
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function update(Request $request, $assetMaintenanceId = null)
|
||||
{
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot edit a maintenance for that asset'));
|
||||
}
|
||||
|
||||
$assetMaintenance->supplier_id = e($request->input('supplier_id'));
|
||||
$assetMaintenance->is_warranty = e($request->input('is_warranty'));
|
||||
$assetMaintenance->cost = Helper::ParseFloat(e($request->input('cost')));
|
||||
$assetMaintenance->notes = e($request->input('notes'));
|
||||
|
||||
$asset = Asset::find(request('asset_id'));
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot edit a maintenance for that asset'));
|
||||
}
|
||||
|
||||
// Save the asset maintenance data
|
||||
$assetMaintenance->asset_id = $request->input('asset_id');
|
||||
$assetMaintenance->asset_maintenance_type = $request->input('asset_maintenance_type');
|
||||
$assetMaintenance->title = $request->input('title');
|
||||
$assetMaintenance->start_date = $request->input('start_date');
|
||||
$assetMaintenance->completion_date = $request->input('completion_date');
|
||||
|
||||
if (( $assetMaintenance->completion_date == null )
|
||||
) {
|
||||
if (( $assetMaintenance->asset_maintenance_time !== 0 )
|
||||
|| ( !is_null($assetMaintenance->asset_maintenance_time) )
|
||||
) {
|
||||
$assetMaintenance->asset_maintenance_time = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (( $assetMaintenance->completion_date !== null )
|
||||
&& ( $assetMaintenance->start_date !== "" )
|
||||
&& ( $assetMaintenance->start_date !== "0000-00-00" )
|
||||
) {
|
||||
$startDate = Carbon::parse($assetMaintenance->start_date);
|
||||
$completionDate = Carbon::parse($assetMaintenance->completion_date);
|
||||
$assetMaintenance->asset_maintenance_time = $completionDate->diffInDays($startDate);
|
||||
}
|
||||
|
||||
// Was the asset maintenance created?
|
||||
if ($assetMaintenance->save()) {
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.edit.success')));
|
||||
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetMaintenance->getErrors()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function destroy($assetMaintenanceId)
|
||||
{
|
||||
// Check if the asset maintenance exists
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot delete a maintenance for that asset'));
|
||||
}
|
||||
|
||||
$assetMaintenance->delete();
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetMaintenance, trans('admin/asset_maintenances/message.delete.success')));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* View an asset maintenance
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @param int $assetMaintenanceId
|
||||
* @version v1.0
|
||||
* @since [v4.0]
|
||||
* @return String JSON
|
||||
*/
|
||||
public function show($assetMaintenanceId)
|
||||
{
|
||||
$assetMaintenance = AssetMaintenance::findOrFail($assetMaintenanceId);
|
||||
if (!Company::isCurrentUserHasAccess($assetMaintenance->asset)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'You cannot view a maintenance for that asset'));
|
||||
}
|
||||
return (new AssetMaintenancesTransformer())->transformAssetMaintenance($assetMaintenance);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,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 +39,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);
|
||||
@@ -76,7 +80,7 @@ class AssetModelsController extends Controller
|
||||
$assetmodel->fill($request->all());
|
||||
|
||||
if ($assetmodel->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/assetmodels/message.create.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/models/message.create.success')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $assetmodel->getErrors()));
|
||||
|
||||
@@ -127,6 +131,7 @@ class AssetModelsController extends Controller
|
||||
$this->authorize('edit', AssetModel::class);
|
||||
$assetmodel = AssetModel::findOrFail($id);
|
||||
$assetmodel->fill($request->all());
|
||||
$assetmodel->fieldset_id = $request->get("custom_fieldset_id");
|
||||
|
||||
if ($assetmodel->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $assetmodel, trans('admin/assetmodels/message.update.success')));
|
||||
|
||||
@@ -31,6 +31,7 @@ use TCPDF;
|
||||
use Validator;
|
||||
use View;
|
||||
|
||||
|
||||
/**
|
||||
* This class controls all actions related to assets for
|
||||
* the Snipe-IT Asset Management application.
|
||||
@@ -83,21 +84,21 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
$assets = Company::scopeCompanyables(Asset::select('assets.*'))->with(
|
||||
'assetLoc', 'assetstatus', 'defaultLoc', 'assetlog', 'company',
|
||||
'model.category', 'model.manufacturer', 'model.fieldset', 'assigneduser');
|
||||
'assetloc', 'assetstatus', 'defaultLoc', 'assetlog', 'company',
|
||||
'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')) {
|
||||
@@ -112,6 +113,10 @@ class AssetsController extends Controller
|
||||
$assets->ByLocationId($request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->has('supplier_id')) {
|
||||
$assets->where('assets.supplier_id', '=', $request->input('supplier_id'));
|
||||
}
|
||||
|
||||
if ($request->has('company_id')) {
|
||||
$assets->where('assets.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
@@ -120,41 +125,88 @@ 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);
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'assets.created_at';
|
||||
$assets->orderBy($sort, $order);
|
||||
|
||||
|
||||
// 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')) ;
|
||||
|
||||
switch ($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;
|
||||
@@ -176,15 +228,17 @@ class AssetsController extends Controller
|
||||
case 'status_label':
|
||||
$assets->OrderStatus($order);
|
||||
break;
|
||||
case 'supplier':
|
||||
$assets->OrderSupplier($order);
|
||||
break;
|
||||
case 'assigned_to':
|
||||
$assets->OrderAssigned($order);
|
||||
break;
|
||||
default:
|
||||
$assets->orderBy($sort, $order);
|
||||
$assets->orderBy($column_sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$total = $assets->count();
|
||||
$assets = $assets->skip($offset)->take($limit)->get();
|
||||
return (new AssetsTransformer)->transformAssets($assets, $total);
|
||||
@@ -220,7 +274,8 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function store(AssetRequest $request)
|
||||
{
|
||||
// $this->authorize('create', Asset::class);
|
||||
|
||||
$this->authorize('create', Asset::class);
|
||||
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find((int) $request->get('model_id')));
|
||||
@@ -266,8 +321,9 @@ class AssetsController extends Controller
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, Auth::user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset->id, trans('admin/hardware/message.create.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.create.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $asset->getErrors()), 200);
|
||||
}
|
||||
|
||||
@@ -331,7 +387,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($asset->save()) {
|
||||
$asset->logCreate();
|
||||
|
||||
if ($request->get('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
} elseif ($request->get('assigned_asset')) {
|
||||
@@ -362,7 +418,10 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$this->authorize('delete', Asset::class);
|
||||
|
||||
if ($asset = Asset::find($id)) {
|
||||
|
||||
$this->authorize('delete', $asset);
|
||||
|
||||
DB::table('assets')
|
||||
@@ -398,16 +457,28 @@ 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"));
|
||||
@@ -466,6 +537,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) {
|
||||
@@ -479,5 +553,52 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', ['asset'=> e($asset->asset_tag)], trans('admin/hardware/message.checkin.error')));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mark an asset as audited
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function audit(Request $request) {
|
||||
|
||||
|
||||
$this->authorize('audit', Asset::class);
|
||||
$rules = array(
|
||||
'asset_tag' => 'required',
|
||||
'location_id' => 'exists:locations,id|nullable|numeric',
|
||||
'next_audit_date' => 'date|nullable'
|
||||
);
|
||||
|
||||
$validator = Validator::make($request->all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()->all()));
|
||||
}
|
||||
|
||||
$asset = Asset::where('asset_tag','=', $request->input('asset_tag'))->first();
|
||||
|
||||
|
||||
if ($asset) {
|
||||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
if ($asset->save()) {
|
||||
$log = $asset->logAudit(request('note'),request('location_id'));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', [
|
||||
'asset_tag'=> e($asset->asset_tag),
|
||||
'note'=> e($request->input('note')),
|
||||
'next_audit_date' => Helper::getFormattedDateObject($log->calcNextAuditDate())
|
||||
], trans('admin/hardware/message.audit.success')));
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', ['asset_tag'=> e($request->input('asset_tag'))], 'Asset with tag '.$request->input('asset_tag').' not found'));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,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'];
|
||||
|
||||
$categories = Category::select(['id', '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'])
|
||||
->withCount('assets', 'accessories', 'consumables', 'components');
|
||||
|
||||
if ($request->has('search')) {
|
||||
@@ -32,7 +32,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();
|
||||
@@ -75,7 +75,8 @@ class CategoriesController extends Controller
|
||||
{
|
||||
$this->authorize('view', Category::class);
|
||||
$category = Category::findOrFail($id);
|
||||
return $category;
|
||||
return (new CategoriesTransformer)->transformCategory($category);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Transformers\DatatablesTransformer;
|
||||
use App\Http\Transformers\CompaniesTransformer;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
@@ -23,7 +23,10 @@ class CompaniesController extends Controller
|
||||
|
||||
$allowed_columns = ['id','name'];
|
||||
|
||||
$companies = Company::withCount('assets','licenses','accessories','consumables','components','users');
|
||||
$companies = Company::withCount('assets','licenses','accessories','consumables','components','users')
|
||||
->withCount('users')->withCount('users')->withCount('assets')
|
||||
->withCount('licenses')->withCount('accessories')
|
||||
->withCount('consumables')->withCount('components');
|
||||
|
||||
if ($request->has('search')) {
|
||||
$companies->TextSearch($request->input('search'));
|
||||
@@ -37,7 +40,7 @@ class CompaniesController extends Controller
|
||||
|
||||
$total = $companies->count();
|
||||
$companies = $companies->skip($offset)->take($limit)->get();
|
||||
return (new DatatablesTransformer)->transformDatatables($companies, $total);
|
||||
return (new CompaniesTransformer)->transformCompanies($companies, $total);
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +60,7 @@ class CompaniesController extends Controller
|
||||
$company->fill($request->all());
|
||||
|
||||
if ($company->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $company, trans('admin/companies/message.create.success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new CompaniesTransformer)->transformCompany($company), trans('admin/companies/message.create.success')));
|
||||
}
|
||||
return response()
|
||||
->json(Helper::formatStandardApiResponse('error', null, $company->getErrors()));
|
||||
@@ -76,7 +79,8 @@ class CompaniesController extends Controller
|
||||
{
|
||||
$this->authorize('view', Company::class);
|
||||
$company = Company::findOrFail($id);
|
||||
return $company;
|
||||
return (new CompaniesTransformer)->transformCompany($company);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +101,7 @@ class CompaniesController extends Controller
|
||||
|
||||
if ($company->save()) {
|
||||
return response()
|
||||
->json(Helper::formatStandardApiResponse('success', $company, trans('admin/companies/message.update.success')));
|
||||
->json(Helper::formatStandardApiResponse('success', (new CompaniesTransformer)->transformCompany($company), trans('admin/companies/message.update.success')));
|
||||
}
|
||||
|
||||
return response()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,4 +148,47 @@ class ConsumablesController extends Controller
|
||||
$consumable->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.delete.success')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a JSON response containing details on the users associated with this consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getView() method that returns the form.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return array
|
||||
*/
|
||||
public function getDataView($consumableId)
|
||||
{
|
||||
//$consumable = Consumable::find($consumableID);
|
||||
$consumable = Consumable::with(array('consumableAssignments'=>
|
||||
function ($query) {
|
||||
$query->orderBy('created_at', 'DESC');
|
||||
},
|
||||
'consumableAssignments.admin'=> function ($query) {
|
||||
},
|
||||
'consumableAssignments.user'=> function ($query) {
|
||||
},
|
||||
))->find($consumableId);
|
||||
|
||||
// $consumable->load('consumableAssignments.admin','consumableAssignments.user');
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($consumable)) {
|
||||
return ['total' => 0, 'rows' => []];
|
||||
}
|
||||
$this->authorize('view', Component::class);
|
||||
$rows = array();
|
||||
|
||||
foreach ($consumable->consumableAssignments as $consumable_assignment) {
|
||||
$rows[] = [
|
||||
'name' => $consumable_assignment->user->present()->nameUrl(),
|
||||
'created_at' => ($consumable_assignment->created_at->format('Y-m-d H:i:s')=='-0001-11-30 00:00:00') ? '' : $consumable_assignment->created_at->format('Y-m-d H:i:s'),
|
||||
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : '',
|
||||
];
|
||||
}
|
||||
|
||||
$consumableCount = $consumable->users->count();
|
||||
$data = array('total' => $consumableCount, 'rows' => $rows);
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\CustomFieldsTransformer;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\CustomFieldset;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class CustomFieldsController extends Controller
|
||||
{
|
||||
@@ -16,6 +18,15 @@ class CustomFieldsController extends Controller
|
||||
* @since [v3.0]
|
||||
* @return Array
|
||||
*/
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', CustomFields::class);
|
||||
$fields = CustomField::get();
|
||||
|
||||
$total = count($fields);
|
||||
return (new CustomFieldsTransformer)->transformCustomFields($fields, $total);
|
||||
}
|
||||
public function postReorder(Request $request, $id)
|
||||
{
|
||||
$fieldset = CustomFieldset::find($id);
|
||||
|
||||
147
app/Http/Controllers/Api/CustomFieldsetsController.php
Normal file
147
app/Http/Controllers/Api/CustomFieldsetsController.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use View;
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use Input;
|
||||
use Validator;
|
||||
use Redirect;
|
||||
use App\Models\AssetModel;
|
||||
use Lang;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Transformers\CustomFieldsTransformer;
|
||||
use App\Http\Transformers\CustomFieldsetsTransformer;
|
||||
use App\Http\Requests\AssetRequest;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Custom Asset Fieldsets for
|
||||
* the Snipe-IT Asset Management application.
|
||||
*
|
||||
* @todo Improve documentation here.
|
||||
* @todo Check for raw DB queries and try to convert them to query builder statements
|
||||
* @version v2.0
|
||||
* @author [Brady Wetherington] [<uberbrady@gmail.com>]
|
||||
* @author [Josh Gibson]
|
||||
*/
|
||||
|
||||
class CustomFieldsetsController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Shows the given fieldset and its fields
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @author [Josh Gibson]
|
||||
* @param int $id
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', CustomFieldset::class);
|
||||
$fieldsets = CustomFieldset::withCount(['fields', 'models'])->get();
|
||||
|
||||
$total = count($fieldsets);
|
||||
return (new CustomFieldsetsTransformer)->transformCustomFieldsets($fieldsets, $total);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the given fieldset and its fields
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @author [Josh Gibson]
|
||||
* @param int $id
|
||||
* @since [v1.8]
|
||||
* @return View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$this->authorize('show', CustomFieldset::class);
|
||||
if ($fieldset = CustomFieldset::find($id)) {
|
||||
return (new CustomFieldsetsTransformer)->transformCustomFieldset($fieldset);
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/custom_fields/message.fieldset.does_not_exist')), 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$this->authorize('edit', CustomFieldset::class);
|
||||
$fieldset = CustomFieldset::findOrFail($id);
|
||||
$fieldset->fill($request->all());
|
||||
|
||||
if ($fieldset->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $fieldset, trans('admin/custom_fields/message.fieldset.update.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $fieldset->getErrors()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$this->authorize('create', CustomFieldset::class);
|
||||
$fieldset = new CustomFieldset;
|
||||
$fieldset->fill($request->all());
|
||||
|
||||
if ($fieldset->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $fieldset, trans('admin/custom_fields/message.fieldset.create.success')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $fieldset->getErrors()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a custom fieldset.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$this->authorize('delete', CustomFieldset::class);
|
||||
$fieldset = CustomFieldset::findOrFail($id);
|
||||
|
||||
$modelsCount = $fieldset->models->count();
|
||||
$fieldsCount = $fieldset->fields->count();
|
||||
|
||||
if (($modelsCount > 0) || ($fieldsCount > 0) ){
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Fieldset is in use.'));
|
||||
}
|
||||
|
||||
if ($fieldset->delete()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/custom_fields/message.fieldset.delete.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Unspecified error'));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
113
app/Http/Controllers/Api/DepartmentsController.php
Normal file
113
app/Http/Controllers/Api/DepartmentsController.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Department;
|
||||
use App\Http\Transformers\DepartmentsTransformer;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
|
||||
class DepartmentsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', Department::class);
|
||||
$allowed_columns = ['id','name'];
|
||||
|
||||
$departments = Department::select([
|
||||
'id',
|
||||
'name',
|
||||
'location_id',
|
||||
'company_id',
|
||||
'manager_id',
|
||||
'created_at',
|
||||
'updated_at'
|
||||
])->with('users')->with('location')->with('manager')->with('company')->withCount('users');
|
||||
|
||||
if ($request->has('search')) {
|
||||
$departments = $departments->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
$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';
|
||||
$departments->orderBy($sort, $order);
|
||||
|
||||
$total = $departments->count();
|
||||
$departments = $departments->skip($offset)->take($limit)->get();
|
||||
return (new DepartmentsTransformer)->transformDepartments($departments, $total);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$this->authorize('create', Department::class);
|
||||
$department = new Department;
|
||||
$department->fill($request->all());
|
||||
$department->user_id = Auth::user()->id;
|
||||
$department->manager_id = ($request->has('manager_id' ) ? $request->input('manager_id') : null);
|
||||
|
||||
if ($department->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $department, trans('admin/departments/message.create.success')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $department->getErrors()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$this->authorize('view', Department::class);
|
||||
$department = Department::findOrFail($id);
|
||||
return (new DepartmentsTransformer)->transformDepartment($department);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Validates and deletes selected location.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $locationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$department = Department::findOrFail($id);
|
||||
|
||||
if ($department->users->count() > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/departments/message.assoc_users')));
|
||||
}
|
||||
|
||||
$department->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/departments/message.delete.success')));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ class GroupsController extends Controller
|
||||
$this->authorize('view', Group::class);
|
||||
$allowed_columns = ['id','name','created_at'];
|
||||
|
||||
$groups = Group::select('id','name','permissions')->withCount('users');
|
||||
$groups = Group::select('id','name','permissions','created_at','updated_at')->withCount('users');
|
||||
|
||||
if ($request->has('search')) {
|
||||
$groups = $groups->TextSearch($request->input('search'));
|
||||
@@ -73,7 +73,7 @@ class GroupsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Group::class);
|
||||
$group = Group::findOrFail($id);
|
||||
return $group;
|
||||
return (new GroupsTransformer)->transformGroup($group);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@ use App\Models\Import;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use League\Csv\Reader;
|
||||
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||
use Artisan;
|
||||
|
||||
class ImportController extends Controller
|
||||
{
|
||||
@@ -29,7 +31,7 @@ class ImportController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
* Process and store a CSV upload file.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
@@ -45,7 +47,6 @@ class ImportController extends Controller
|
||||
$results = [];
|
||||
$import = new Import;
|
||||
foreach ($files as $file) {
|
||||
|
||||
if (!in_array($file->getMimeType(), array(
|
||||
'application/vnd.ms-excel',
|
||||
'text/csv',
|
||||
@@ -53,11 +54,11 @@ class ImportController extends Controller
|
||||
'text/comma-separated-values',
|
||||
'text/tsv'))) {
|
||||
$results['error']='File type must be CSV';
|
||||
return $results;
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 500);
|
||||
}
|
||||
|
||||
$date = date('Y-m-d-his');
|
||||
$fixed_filename = str_replace(' ', '-', $file->getClientOriginalName());
|
||||
$fixed_filename = str_slug($file->getClientOriginalName());
|
||||
try {
|
||||
$file->move($path, $date.'-'.$fixed_filename);
|
||||
} catch (FileException $exception) {
|
||||
@@ -66,17 +67,21 @@ class ImportController extends Controller
|
||||
$results['error'].= ' ' . $exception->getMessage();
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $results['error']), 500);
|
||||
|
||||
}
|
||||
$file_name = date('Y-m-d-his').'-'.$fixed_filename;
|
||||
$import->file_path = $file_name;
|
||||
$import->filesize = filesize($path.'/'.$file_name);
|
||||
//TODO: is there a lighter way to do this?
|
||||
$reader = Reader::createFromPath("{$path}/{$file_name}");
|
||||
$import->header_row = $reader->fetchOne(0);
|
||||
// Grab the first row to display via ajax as the user picks fields
|
||||
$import->first_row = $reader->fetchOne(1);
|
||||
$import->save();
|
||||
$results[] = $import;
|
||||
}
|
||||
$results = (new ImportsTransformer)->transformImports($results);
|
||||
return [
|
||||
'files' => $results
|
||||
'files' => $results,
|
||||
];
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.feature_disabled')), 500);
|
||||
@@ -90,8 +95,10 @@ class ImportController extends Controller
|
||||
public function process(ItemImportRequest $request, $import_id)
|
||||
{
|
||||
$this->authorize('create', Asset::class);
|
||||
// Run a backup immediately before processing
|
||||
Artisan::call('backup:run');
|
||||
$errors = $request->import(Import::find($import_id));
|
||||
$redirectTo = "hardware";
|
||||
$redirectTo = "hardware.index";
|
||||
switch ($request->get('import-type')) {
|
||||
case "asset":
|
||||
$redirectTo = "hardware.index";
|
||||
@@ -108,6 +115,9 @@ class ImportController extends Controller
|
||||
case "license":
|
||||
$redirectTo = "licenses.index";
|
||||
break;
|
||||
case "user":
|
||||
$redirectTo = "users.index";
|
||||
break;
|
||||
}
|
||||
|
||||
if ($errors) { //Failure
|
||||
@@ -132,7 +142,7 @@ class ImportController extends Controller
|
||||
try {
|
||||
unlink(config('app.private_uploads').'/imports/'.$import->file_path);
|
||||
$import->delete();
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('message.import.file_delete_success')));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/hardware/message.import.file_delete_success')));
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.import.file_delete_error')), 500);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class LicensesController extends Controller
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
$licenses = Company::scopeCompanyables(License::with('company', 'licenseSeatsRelation', 'manufacturer'));
|
||||
$licenses = Company::scopeCompanyables(License::with('company', 'licenseSeatsRelation', 'manufacturer', 'supplier'));
|
||||
|
||||
if ($request->has('search')) {
|
||||
$licenses = $licenses->TextSearch($request->input('search'));
|
||||
@@ -59,6 +59,10 @@ class LicensesController extends Controller
|
||||
$licenses->where('manufacturer_id','=',$request->input('manufacturer_id'));
|
||||
}
|
||||
|
||||
if ($request->has('supplier_id')) {
|
||||
$licenses->where('supplier_id','=',$request->input('supplier_id'));
|
||||
}
|
||||
|
||||
if ($request->has('depreciation_id')) {
|
||||
$licenses->where('depreciation_id','=',$request->input('depreciation_id'));
|
||||
}
|
||||
@@ -69,22 +73,26 @@ class LicensesController extends Controller
|
||||
|
||||
$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','license_name','license_email'];
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
|
||||
switch ($sort) {
|
||||
|
||||
switch ($request->input('sort')) {
|
||||
case 'manufacturer':
|
||||
$licenses = $licenses->OrderManufacturer($order);
|
||||
break;
|
||||
case 'supplier':
|
||||
$licenses = $licenses->OrderSupplier($order);
|
||||
break;
|
||||
case 'company':
|
||||
$licenses = $licenses->OrderCompany($order);
|
||||
break;
|
||||
default:
|
||||
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','company','license_name','license_email'];
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
$licenses = $licenses->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$total = $licenses->count();
|
||||
$licenses = $licenses->skip($offset)->take($limit)->get();
|
||||
@@ -117,7 +125,13 @@ class LicensesController extends Controller
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
$license = License::find($id);
|
||||
if (isset($license->id)) {
|
||||
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
|
||||
$this->authorize('view', $license);
|
||||
return (new LicensesTransformer)->transformLicense($license);
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@ class LocationsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Location::class);
|
||||
$allowed_columns = ['id','name','address','address2','city','state','country','zip','created_at',
|
||||
'updated_at'];
|
||||
'updated_at','parent_id', 'manager_id'];
|
||||
|
||||
$locations = Location::select([
|
||||
$locations = Location::with('parent', 'manager', 'childLocations')->select([
|
||||
'locations.id',
|
||||
'locations.name',
|
||||
'locations.address',
|
||||
@@ -33,10 +33,14 @@ class LocationsController extends Controller
|
||||
'locations.zip',
|
||||
'locations.country',
|
||||
'locations.parent_id',
|
||||
'locations.manager_id',
|
||||
'locations.created_at',
|
||||
'locations.updated_at',
|
||||
'locations.currency'
|
||||
])->withCount('assets')->withCount('users');
|
||||
])->withCount('locationAssets')
|
||||
->withCount('assignedAssets')
|
||||
->withCount('assets')
|
||||
->withCount('users');
|
||||
|
||||
if ($request->has('search')) {
|
||||
$locations = $locations->TextSearch($request->input('search'));
|
||||
@@ -51,7 +55,6 @@ class LocationsController extends Controller
|
||||
$total = $locations->count();
|
||||
$locations = $locations->skip($offset)->take($limit)->get();
|
||||
return (new LocationsTransformer)->transformLocations($locations, $total);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -70,10 +73,9 @@ class LocationsController extends Controller
|
||||
$location->fill($request->all());
|
||||
|
||||
if ($location->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $location, trans('admin/locations/message.create.success')));
|
||||
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()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +110,13 @@ class LocationsController extends Controller
|
||||
$location->fill($request->all());
|
||||
|
||||
if ($location->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $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()));
|
||||
@@ -128,7 +136,6 @@ 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')));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class ManufacturersController extends Controller
|
||||
{
|
||||
$this->authorize('view', Manufacturer::class);
|
||||
$manufacturer = Manufacturer::findOrFail($id);
|
||||
return $manufacturer;
|
||||
return (new ManufacturersTransformer)->transformManufacturer($manufacturer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
60
app/Http/Controllers/Api/ReportsController.php
Normal file
60
app/Http/Controllers/Api/ReportsController.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Actionlog;
|
||||
use App\Http\Transformers\ActionlogsTransformer;
|
||||
|
||||
class ReportsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns Activity Report JSON.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
||||
$actionlogs = Actionlog::with('item', 'user', 'target','location');
|
||||
|
||||
if ($request->has('search')) {
|
||||
$actionlogs = $actionlogs->TextSearch(e($request->input('search')));
|
||||
}
|
||||
|
||||
if (($request->has('target_type')) && ($request->has('target_id'))) {
|
||||
$actionlogs = $actionlogs->where('target_id','=',$request->input('target_id'))
|
||||
->where('target_type','=',"App\\Models\\".ucwords($request->input('target_type')));
|
||||
|
||||
}
|
||||
|
||||
if (($request->has('item_type')) && ($request->has('item_id'))) {
|
||||
$actionlogs = $actionlogs->where('item_id','=',$request->input('item_id'))
|
||||
->where('item_type','=',"App\\Models\\".ucwords($request->input('item_type')));
|
||||
}
|
||||
|
||||
if ($request->has('action_type')) {
|
||||
$actionlogs = $actionlogs->where('action_type','=',$request->input('action_type'))->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
$allowed_columns = [
|
||||
'id',
|
||||
'created_at'
|
||||
];
|
||||
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at';
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$offset = request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
$total = $actionlogs->count();
|
||||
$actionlogs = $actionlogs->orderBy($sort, $order);
|
||||
$actionlogs = $actionlogs->skip($offset)->take($limit)->get();
|
||||
return (new ActionlogsTransformer)->transformActionlogs($actionlogs, $total);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,10 @@ 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
|
||||
{
|
||||
@@ -73,4 +77,115 @@ class SettingsController extends Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
\Log::debug('Preparing to test LDAP connection');
|
||||
|
||||
try {
|
||||
$connection = Ldap::connectToLdap();
|
||||
try {
|
||||
\Log::debug('attempting to bind to LDAP for LDAP test');
|
||||
Ldap::bindAdminToLdap($connection);
|
||||
return response()->json(['message' => 'It worked!'], 200);
|
||||
} 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()], 600);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
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');
|
||||
|
||||
@@ -53,9 +53,20 @@ class StatuslabelsController extends Controller
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('create', Statuslabel::class);
|
||||
$request->except('deployable', 'pending','archived');
|
||||
|
||||
if (!$request->has('type')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ["type" => ["Status label type is required."]]));
|
||||
}
|
||||
|
||||
$statuslabel = new Statuslabel;
|
||||
$statuslabel->fill($request->all());
|
||||
|
||||
$statusType = Statuslabel::getStatuslabelTypesForDB($request->input('type'));
|
||||
$statuslabel->deployable = $statusType['deployable'];
|
||||
$statuslabel->pending = $statusType['pending'];
|
||||
$statuslabel->archived = $statusType['archived'];
|
||||
|
||||
if ($statuslabel->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $statuslabel, trans('admin/statuslabels/message.create.success')));
|
||||
}
|
||||
@@ -75,7 +86,7 @@ class StatuslabelsController extends Controller
|
||||
{
|
||||
$this->authorize('view', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
return $statuslabel;
|
||||
return (new StatuslabelsTransformer)->transformStatuslabel($statuslabel);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +103,20 @@ class StatuslabelsController extends Controller
|
||||
{
|
||||
$this->authorize('edit', Statuslabel::class);
|
||||
$statuslabel = Statuslabel::findOrFail($id);
|
||||
|
||||
$request->except('deployable', 'pending','archived');
|
||||
|
||||
if (!$request->has('type')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Status label type is required.'));
|
||||
}
|
||||
|
||||
$statuslabel->fill($request->all());
|
||||
|
||||
$statusType = Statuslabel::getStatuslabelTypesForDB($request->input('type'));
|
||||
$statuslabel->deployable = $statusType['deployable'];
|
||||
$statuslabel->pending = $statusType['pending'];
|
||||
$statuslabel->archived = $statusType['archived'];
|
||||
|
||||
if ($statuslabel->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $statuslabel, trans('admin/statuslabels/message.update.success')));
|
||||
}
|
||||
@@ -114,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')));
|
||||
|
||||
}
|
||||
|
||||
@@ -132,7 +161,7 @@ class StatuslabelsController extends Controller
|
||||
public function getAssetCountByStatuslabel()
|
||||
{
|
||||
|
||||
$statusLabels = Statuslabel::with('assets')->get();
|
||||
$statusLabels = Statuslabel::get();
|
||||
$labels=[];
|
||||
$points=[];
|
||||
$colors=[];
|
||||
@@ -145,9 +174,7 @@ class StatuslabelsController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
$labels[]='Deployed';
|
||||
$points[]=Asset::whereNotNull('assigned_to')->count();
|
||||
|
||||
|
||||
$colors_array = array_merge($colors, Helper::chartColors());
|
||||
|
||||
$result= [
|
||||
|
||||
@@ -6,7 +6,7 @@ use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Supplier;
|
||||
use App\Http\Transformers\DatatablesTransformer;
|
||||
use App\Http\Transformers\SuppliersTransformer;
|
||||
|
||||
class SuppliersController extends Controller
|
||||
{
|
||||
@@ -20,11 +20,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')
|
||||
)->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')
|
||||
)->withCount('assets')->withCount('licenses')->withCount('accessories')->whereNull('deleted_at');
|
||||
|
||||
|
||||
if ($request->has('search')) {
|
||||
@@ -39,8 +39,7 @@ class SuppliersController extends Controller
|
||||
|
||||
$total = $suppliers->count();
|
||||
$suppliers = $suppliers->skip($offset)->take($limit)->get();
|
||||
return (new DatatablesTransformer)->transformDatatables($suppliers, $total);
|
||||
return $suppliers;
|
||||
return (new SuppliersTransformer)->transformSuppliers($suppliers, $total);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +76,7 @@ class SuppliersController extends Controller
|
||||
{
|
||||
$this->authorize('view', Supplier::class);
|
||||
$supplier = Supplier::findOrFail($id);
|
||||
return $supplier;
|
||||
return (new SuppliersTransformer)->transformSupplier($supplier);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,8 +113,22 @@ 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')));
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\UsersTransformer;
|
||||
use App\Models\Company;
|
||||
use App\Models\User;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Models\Asset;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
@@ -28,6 +31,7 @@ class UsersController extends Controller
|
||||
'users.two_factor_enrolled',
|
||||
'users.jobtitle',
|
||||
'users.email',
|
||||
'users.phone',
|
||||
'users.username',
|
||||
'users.location_id',
|
||||
'users.manager_id',
|
||||
@@ -38,8 +42,9 @@ class UsersController extends Controller
|
||||
'users.company_id',
|
||||
'users.last_login',
|
||||
'users.deleted_at',
|
||||
'users.department_id',
|
||||
'users.activated'
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'throttle','assets','licenses','accessories','consumables')
|
||||
])->with('manager', 'groups', 'userloc', 'company', 'department','throttle','assets','licenses','accessories','consumables')
|
||||
->withCount('assets','licenses','accessories','consumables');
|
||||
$users = Company::scopeCompanyables($users);
|
||||
|
||||
@@ -48,8 +53,25 @@ class UsersController extends Controller
|
||||
$users = $users->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
|
||||
if (($request->has('deleted')) && ($request->input('deleted')=='true')) {
|
||||
$users = $users->GetDeleted();
|
||||
}
|
||||
|
||||
if ($request->has('company_id')) {
|
||||
$users = $users->where('company_id','=',$request->input('company_id'));
|
||||
$users = $users->where('company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->has('location_id')) {
|
||||
$users = $users->where('location_id', '=', $request->input('location_id'));
|
||||
}
|
||||
|
||||
if ($request->has('group_id')) {
|
||||
$users = $users->ByGroup($request->has('group_id'));
|
||||
}
|
||||
|
||||
if ($request->has('department_id')) {
|
||||
$users = $users->where('department_id','=',$request->input('department_id'));
|
||||
}
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
@@ -63,21 +85,25 @@ class UsersController extends Controller
|
||||
case 'location':
|
||||
$users = $users->OrderLocation($order);
|
||||
break;
|
||||
case 'department':
|
||||
$users = $users->OrderDepartment($order);
|
||||
break;
|
||||
default:
|
||||
$allowed_columns =
|
||||
[
|
||||
'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';
|
||||
$users = $users->orderBy($sort, $order);
|
||||
break;
|
||||
}
|
||||
$userCount = $users->count();
|
||||
$total = $users->count();
|
||||
$users = $users->skip($offset)->take($limit)->get();
|
||||
return (new UsersTransformer)->transformUsers($users, $userCount);
|
||||
return (new UsersTransformer)->transformUsers($users, $total);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,9 +115,17 @@ class UsersController extends Controller
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
public function store(SaveUserRequest $request)
|
||||
{
|
||||
//
|
||||
$this->authorize('view', User::class);
|
||||
$user = new User;
|
||||
$user->fill($request->all());
|
||||
$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('error', null, $user->getErrors()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,9 +152,22 @@ class UsersController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
public function update(SaveUserRequest $request, $id)
|
||||
{
|
||||
//
|
||||
$this->authorize('edit', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
$user->fill($request->all());
|
||||
|
||||
if ($request->has('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
|
||||
if ($user->save()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.update')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $user->getErrors()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -133,6 +180,33 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
$this->authorize('delete', User::class);
|
||||
$user = User::findOrFail($id);
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
|
||||
if ($user->assets()->count() > 0) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete_has_assets')));
|
||||
}
|
||||
|
||||
if ($user->delete()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.delete')));
|
||||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return JSON containing a list of assets assigned to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function assets($id)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$assets = Asset::where('assigned_to', '=', $id)->with('model')->get();
|
||||
return response()->json($assets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ class AssetMaintenancesController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('asset_maintenances/index');
|
||||
return view('asset_maintenances/index');
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ class AssetMaintenancesController extends Controller
|
||||
] + AssetMaintenance::getImprovementOptions();
|
||||
// Mark the selected asset, if it came in
|
||||
// Render the view
|
||||
return View::make('asset_maintenances/edit')
|
||||
return view('asset_maintenances/edit')
|
||||
->with('asset_list', Helper::detailedAssetList())
|
||||
->with('selectedAsset', request('asset_id'))
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
@@ -259,7 +259,7 @@ class AssetMaintenancesController extends Controller
|
||||
|
||||
// Get Supplier List
|
||||
// Render the view
|
||||
return View::make('asset_maintenances/edit')
|
||||
return view('asset_maintenances/edit')
|
||||
->with('asset_list', Helper::detailedAssetList())
|
||||
->with('selectedAsset', null)
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
@@ -384,6 +384,6 @@ class AssetMaintenancesController extends Controller
|
||||
return static::getInsufficientPermissionsRedirect();
|
||||
}
|
||||
|
||||
return View::make('asset_maintenances/view')->with('assetMaintenance', $assetMaintenance);
|
||||
return view('asset_maintenances/view')->with('assetMaintenance', $assetMaintenance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -40,7 +41,7 @@ class AssetModelsController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('models/index');
|
||||
return view('models/index');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +54,7 @@ class AssetModelsController extends Controller
|
||||
public function create()
|
||||
{
|
||||
// Show the page
|
||||
return View::make('models/edit')
|
||||
return view('models/edit')
|
||||
->with('category_list', Helper::categoryList('asset'))
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('manufacturer_list', Helper::manufacturerList())
|
||||
@@ -68,7 +69,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
|
||||
@@ -82,7 +83,7 @@ class AssetModelsController extends Controller
|
||||
$model->manufacturer_id = $request->input('manufacturer_id');
|
||||
$model->category_id = $request->input('category_id');
|
||||
$model->notes = $request->input('notes');
|
||||
$model->user_id = Auth::guard('api')->user();
|
||||
$model->user_id = Auth::id();
|
||||
$model->requestable = Input::has('requestable');
|
||||
|
||||
if ($request->input('custom_fieldset')!='') {
|
||||
@@ -90,14 +91,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 = str_random(25) . "." . $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?
|
||||
@@ -180,7 +188,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))) {
|
||||
@@ -206,13 +214,19 @@ 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_random(25) . "." . $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;
|
||||
|
||||
}
|
||||
|
||||
if ($request->input('image_delete') == 1 && Input::file('image') == "") {
|
||||
@@ -297,7 +311,7 @@ class AssetModelsController extends Controller
|
||||
$model = AssetModel::withTrashed()->find($modelId);
|
||||
|
||||
if (isset($model->id)) {
|
||||
return View::make('models/view', compact('model'));
|
||||
return view('models/view', compact('model'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/models/message.does_not_exist', compact('id'));
|
||||
@@ -347,51 +361,84 @@ class AssetModelsController extends Controller
|
||||
public function getCustomFields($modelId)
|
||||
{
|
||||
$model = AssetModel::find($modelId);
|
||||
return View::make("models.custom_fields_form")->with("model", $model);
|
||||
return view("models.custom_fields_form")->with("model", $model);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns a view that allows the user to bulk edit model attrbutes
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.7]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function postBulkEdit(Request $request)
|
||||
{
|
||||
|
||||
$models_raw_array = Input::get('ids');
|
||||
|
||||
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'))
|
||||
->with('manufacturer_list', $manufacturer_list)
|
||||
->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.');
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the asset information to present to the model view detail page
|
||||
* Returns a view that allows the user to bulk edit model attrbutes
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v2.0]
|
||||
* @param Request $request
|
||||
* @param $modelID
|
||||
* @return String JSON
|
||||
* @internal param int $modelId
|
||||
* @since [v1.7]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getDataView(Request $request, $modelID)
|
||||
public function postBulkEditSave(Request $request)
|
||||
{
|
||||
$assets = Asset::where('model_id', '=', $modelID)->with('company', 'assetstatus');
|
||||
|
||||
if (Input::has('search')) {
|
||||
$assets = $assets->TextSearch(e($request->input('search')));
|
||||
$models_raw_array = Input::get('ids');
|
||||
$update_array = array();
|
||||
|
||||
if (($request->has('manufacturer_id') && ($request->input('manufacturer_id')!='NC'))) {
|
||||
$update_array['manufacturer_id'] = $request->input('manufacturer_id');
|
||||
}
|
||||
$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);
|
||||
if (($request->has('category_id') && ($request->input('category_id')!='NC'))) {
|
||||
$update_array['category_id'] = $request->input('category_id');
|
||||
}
|
||||
if ($request->input('fieldset_id')!='NC') {
|
||||
$update_array['fieldset_id'] = $request->input('fieldset_id');
|
||||
}
|
||||
if ($request->input('depreciation_id')!='NC') {
|
||||
$update_array['depreciation_id'] = $request->input('depreciation_id');
|
||||
}
|
||||
|
||||
$data = array('total' => $assetsCount, 'rows' => $rows);
|
||||
|
||||
return $data;
|
||||
|
||||
if (count($update_array) > 0) {
|
||||
AssetModel::whereIn('id', $models_raw_array)->update($update_array);
|
||||
return redirect()->route('models.index')
|
||||
->with('success', trans('admin/models/message.bulkedit.success'));
|
||||
}
|
||||
|
||||
return redirect()->route('models.index')
|
||||
->with('warning', trans('admin/models/message.bulkedit.error'));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Company;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\Import;
|
||||
use App\Models\Location;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
@@ -74,7 +75,7 @@ class AssetsController extends Controller
|
||||
} else {
|
||||
$company = null;
|
||||
}
|
||||
return View::make('hardware/index')->with('company',$company);
|
||||
return view('hardware/index')->with('company', $company);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +94,6 @@ class AssetsController extends Controller
|
||||
}
|
||||
$this->authorize('view', $asset);
|
||||
return redirect()->route('hardware.show', $asset->id)->with('topsearch', $topsearch);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,9 +115,9 @@ class AssetsController extends Controller
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('item', new Asset)
|
||||
->with('manufacturer', Helper::manufacturerList())
|
||||
->with('category', Helper::categoryList('asset'))
|
||||
->with('statuslabel_types', Helper::statusTypeList())
|
||||
->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());
|
||||
@@ -125,9 +125,7 @@ class AssetsController extends Controller
|
||||
if ($request->has('model_id')) {
|
||||
$selected_model = AssetModel::find($request->input('model_id'));
|
||||
$view->with('selected_model', $selected_model);
|
||||
} else {
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
@@ -167,7 +165,6 @@ class AssetsController extends Controller
|
||||
|
||||
// Create the image (if one was chosen.)
|
||||
if (Input::has('image')) {
|
||||
|
||||
$image = Input::get('image');
|
||||
|
||||
// After modification, the image is prefixed by mime info like the following:
|
||||
@@ -200,7 +197,6 @@ class AssetsController extends Controller
|
||||
->put('default', $messageBag));
|
||||
return response()->json(['image' => $e->getMessage()], 422);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -209,20 +205,27 @@ class AssetsController extends Controller
|
||||
// FIXME: No idea why this is returning a Builder error on db_column_name.
|
||||
// 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) {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
|
||||
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)) {
|
||||
@@ -254,16 +257,16 @@ class AssetsController extends Controller
|
||||
//Handles company checks and permissions.
|
||||
$this->authorize($item);
|
||||
|
||||
return View::make('hardware/edit', compact('item'))
|
||||
->with('model_list', Helper::modelList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_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'));
|
||||
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'));
|
||||
}
|
||||
|
||||
|
||||
@@ -278,7 +281,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
|
||||
@@ -356,9 +358,8 @@ class AssetsController extends Controller
|
||||
if (Gate::allows('admin')) {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt(e($request->input($field->convertUnicodeDbSlug())));
|
||||
}
|
||||
|
||||
} else {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = e($request->input($field->convertUnicodeDbSlug()));
|
||||
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -372,7 +373,6 @@ class AssetsController extends Controller
|
||||
\Input::flash();
|
||||
\Session::flash('errors', $asset->getErrors());
|
||||
return response()->json(['errors' => $asset->getErrors()], 500);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -394,11 +394,18 @@ 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();
|
||||
|
||||
$logaction = new Actionlog();
|
||||
$logaction->item_type = Asset::class;
|
||||
$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');
|
||||
|
||||
// Redirect to the asset management page
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.delete.success'));
|
||||
}
|
||||
@@ -423,11 +430,10 @@ class AssetsController extends Controller
|
||||
$this->authorize('checkout', $asset);
|
||||
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return View::make('hardware/checkout', compact('asset'))
|
||||
return view('hardware/checkout', compact('asset'))
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('assets_list', Helper::assetsList())
|
||||
->with('assets_list', Helper::detailedAssetList())
|
||||
->with('locations_list', Helper::locationsList());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -449,30 +455,30 @@ 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'));
|
||||
$admin = Auth::user();
|
||||
|
||||
if ((Input::has('checkout_at')) && (Input::get('checkout_at')!= date("Y-m-d"))) {
|
||||
$checkout_at = e(Input::get('checkout_at'));
|
||||
$checkout_at = Input::get('checkout_at');
|
||||
} else {
|
||||
$checkout_at = date("Y-m-d H:i:s");
|
||||
}
|
||||
|
||||
if (Input::has('expected_checkin')) {
|
||||
$expected_checkin = e(Input::get('expected_checkin'));
|
||||
$expected_checkin = Input::get('expected_checkin');
|
||||
} else {
|
||||
$expected_checkin = '';
|
||||
}
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), e(Input::get('name')))) {
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e(Input::get('note')), Input::get('name'))) {
|
||||
// Redirect to the new asset page
|
||||
return redirect()->to("hardware")->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
}
|
||||
|
||||
// Redirect to the asset management page with error
|
||||
@@ -498,8 +504,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
$this->authorize('checkin', $asset);
|
||||
return View::make('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
|
||||
|
||||
return view('hardware/checkin', compact('asset'))->with('statusLabel_list', Helper::statusLabelList())->with('backto', $backto);
|
||||
}
|
||||
|
||||
|
||||
@@ -524,17 +529,18 @@ class AssetsController extends Controller
|
||||
$this->authorize('checkin', $asset);
|
||||
|
||||
$admin = Auth::user();
|
||||
$user = $asset->assignedUser;
|
||||
if ($asset->assignedType() == Asset::USER) {
|
||||
$user = $asset->assignedTo;
|
||||
}
|
||||
if (is_null($target = $asset->assignedTo)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.checkin.already_checked_in'));
|
||||
}
|
||||
|
||||
// This is just used for the redirect
|
||||
$return_to = $asset->assigned_to;
|
||||
$asset->expected_checkin = null;
|
||||
$asset->last_checkout = null;
|
||||
$asset->assigned_to = null;
|
||||
$asset->assignedTo()->disassociate($asset);
|
||||
$asset->assigned_type = null;
|
||||
$asset->accepted = null;
|
||||
$asset->name = e(Input::get('name'));
|
||||
|
||||
@@ -552,8 +558,11 @@ 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'))) {
|
||||
if ((($asset->checkin_email()=='1')) && (isset($user)) && (!empty($user->email)) && (!config('app.lock_passwords'))) {
|
||||
Mail::send('emails.checkin-asset', $data, function ($m) use ($user) {
|
||||
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
|
||||
$m->replyTo(config('mail.reply_to.address'), config('mail.reply_to.name'));
|
||||
@@ -562,13 +571,13 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($backto=='user') {
|
||||
return redirect()->to("admin/users/".$return_to.'/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()->to("hardware")->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
return redirect()->route("hardware.index")->with('success', trans('admin/hardware/message.checkin.success'));
|
||||
}
|
||||
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to("hardware")->with('error', trans('admin/hardware/message.checkin.error'));
|
||||
return redirect()->route("hardware.index")->with('error', trans('admin/hardware/message.checkin.error'));
|
||||
}
|
||||
|
||||
|
||||
@@ -582,18 +591,20 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function show($assetId = null)
|
||||
{
|
||||
|
||||
$asset = Asset::withTrashed()->find($assetId);
|
||||
$settings = Setting::getSettings();
|
||||
$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();
|
||||
|
||||
if (isset($asset->id)) {
|
||||
|
||||
if ($asset->userloc) {
|
||||
$use_currency = $asset->userloc->currency;
|
||||
} elseif ($asset->assetloc) {
|
||||
if (isset($asset)) {
|
||||
if (!is_null($asset->assetloc)) {
|
||||
$use_currency = $asset->assetloc->currency;
|
||||
} else {
|
||||
|
||||
if ($settings->default_currency!='') {
|
||||
$use_currency = $settings->default_currency;
|
||||
} else {
|
||||
@@ -606,10 +617,11 @@ class AssetsController extends Controller
|
||||
'url' => route('qr_code/hardware', $asset->id)
|
||||
);
|
||||
|
||||
return View::make('hardware/view', compact('asset', 'qr_code', 'settings'))->with('use_currency', $use_currency);
|
||||
return view('hardware/view', compact('asset', 'qr_code', 'settings'))
|
||||
->with('use_currency', $use_currency)->with('audit_log', $audit_log);
|
||||
}
|
||||
|
||||
return redirect()->route('hardware')->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', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -625,12 +637,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).'.png';
|
||||
|
||||
if (isset($asset->id,$asset->asset_tag)) {
|
||||
$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 (file_exists($qr_file)) {
|
||||
$header = ['Content-type' => 'image/png'];
|
||||
return response()->file($qr_file, $header);
|
||||
@@ -642,7 +653,6 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -660,69 +670,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');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Asset import upload page.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v2.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getImportUpload()
|
||||
{
|
||||
$this->authorize('create', Asset::class);
|
||||
return View::make('hardware/import');
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the uploaded file
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v2.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function postProcessImportFile(ItemImportRequest $request)
|
||||
{
|
||||
$this->authorize('create', Asset::class);
|
||||
$errors = $request->import();
|
||||
|
||||
// We use hardware instead of asset in the url
|
||||
$redirectTo = "hardware";
|
||||
switch (request('import-type')) {
|
||||
case "asset":
|
||||
$redirectTo = "hardware.index";
|
||||
break;
|
||||
case "accessory":
|
||||
$redirectTo = "accessories.index";
|
||||
break;
|
||||
case "consumable":
|
||||
$redirectTo = "consumables.index";
|
||||
break;
|
||||
case "component":
|
||||
$redirectTo = "components.index";
|
||||
break;
|
||||
}
|
||||
|
||||
if ($errors) { //Failure
|
||||
return redirect()->back()->with('import_errors', json_decode(json_encode($errors)))->with('error', trans('admin/hardware/message.import.error'));
|
||||
}
|
||||
return redirect()->to(route($redirectTo))->with('success', trans('admin/hardware/message.import.success'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -749,16 +711,18 @@ class AssetsController extends Controller
|
||||
$asset->serial = '';
|
||||
$asset->assigned_to = '';
|
||||
|
||||
return View::make('hardware/edit')
|
||||
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('location_list', Helper::locationsList())
|
||||
->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());
|
||||
}
|
||||
|
||||
@@ -772,7 +736,7 @@ class AssetsController extends Controller
|
||||
public function getImportHistory()
|
||||
{
|
||||
$this->authorize('checkout', Asset::class);
|
||||
return View::make('hardware/history');
|
||||
return view('hardware/history');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -787,7 +751,6 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function postImportHistory(Request $request)
|
||||
{
|
||||
|
||||
if (!ini_get("auto_detect_line_endings")) {
|
||||
ini_set("auto_detect_line_endings", '1');
|
||||
}
|
||||
@@ -805,9 +768,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)) {
|
||||
@@ -822,7 +783,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']);
|
||||
@@ -879,12 +839,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.';
|
||||
@@ -900,7 +858,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;
|
||||
@@ -918,7 +875,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
return View::make('hardware/history')->with('status', $status);
|
||||
return view('hardware/history')->with('status', $status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -937,7 +894,7 @@ class AssetsController extends Controller
|
||||
if (isset($asset->id)) {
|
||||
// Restore the asset
|
||||
Asset::withTrashed()->where('id', $assetId)->restore();
|
||||
return redirect()->route('hardware')->with('success', trans('admin/hardware/message.restore.success'));
|
||||
return redirect()->route('hardware.index')->with('success', trans('admin/hardware/message.restore.success'));
|
||||
}
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
@@ -956,7 +913,7 @@ class AssetsController extends Controller
|
||||
{
|
||||
|
||||
if (!$asset = Asset::find($assetId)) {
|
||||
return redirect()->route('hardware')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
$this->authorize('update', $asset);
|
||||
|
||||
@@ -990,7 +947,7 @@ class AssetsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getDeleteFile($assetId = null, $fileId = null)
|
||||
public function deleteFile($assetId = null, $fileId = null)
|
||||
{
|
||||
$asset = Asset::find($assetId);
|
||||
$this->authorize('update', $asset);
|
||||
@@ -1007,13 +964,12 @@ 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')->with('error', $error);
|
||||
return redirect()->route('hardware.index')->with('error', $error);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1046,7 +1002,7 @@ class AssetsController extends Controller
|
||||
$error = trans('admin/hardware/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the hardware management page
|
||||
return redirect()->route('hardware')->with('error', $error);
|
||||
return redirect()->route('hardware.index')->with('error', $error);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1074,28 +1030,22 @@ class AssetsController extends Controller
|
||||
|
||||
|
||||
if ($request->has('bulk_actions')) {
|
||||
|
||||
if ($request->input('bulk_actions')=='labels') {
|
||||
|
||||
$count = 0;
|
||||
return View::make('hardware/labels')
|
||||
return view('hardware/labels')
|
||||
->with('assets', Asset::find($asset_ids))
|
||||
->with('settings', Setting::getSettings())
|
||||
->with('count', $count)
|
||||
->with('settings',
|
||||
Setting::getSettings()
|
||||
);
|
||||
|
||||
->with('settings', Setting::getSettings());
|
||||
} elseif ($request->input('bulk_actions')=='delete') {
|
||||
$assets = Asset::with('assignedTo', 'assetloc')->find($asset_ids);
|
||||
$assets->each(function($asset) {
|
||||
$this->authorize('delete',$asset);
|
||||
$assets->each(function ($asset) {
|
||||
$this->authorize('delete', $asset);
|
||||
});
|
||||
return View::make('hardware/bulk-delete')->with('assets', $assets);
|
||||
|
||||
return view('hardware/bulk-delete')->with('assets', $assets);
|
||||
// Bulk edit
|
||||
} elseif ($request->input('bulk_actions')=='edit') {
|
||||
return View::make('hardware/bulk')
|
||||
return view('hardware/bulk')
|
||||
->with('assets', request('ids'))
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('statuslabel_list', Helper::statusLabelList())
|
||||
@@ -1172,20 +1122,9 @@ class AssetsController extends Controller
|
||||
$update_array['requestable'] = e(Input::get('requestable'));
|
||||
}
|
||||
|
||||
if (DB::table('assets')
|
||||
->where('id', $key)
|
||||
->update($update_array)) {
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Asset::class;
|
||||
$logAction->item_id = $key;
|
||||
$logAction->created_at = date("Y-m-d H:i:s");
|
||||
|
||||
if (Input::has('rtd_location_id')) {
|
||||
$logAction->location_id = e(Input::get('rtd_location_id'));
|
||||
}
|
||||
$logAction->user_id = Auth::user()->id;
|
||||
$logAction->logaction('update');
|
||||
}
|
||||
DB::table('assets')
|
||||
->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
|
||||
@@ -1206,24 +1145,16 @@ class AssetsController extends Controller
|
||||
public function postBulkDelete()
|
||||
{
|
||||
$this->authorize('delete', Asset::class);
|
||||
if (Input::has('bulk_edit')) {
|
||||
$assets = Asset::find(Input::get('bulk_edit'));
|
||||
|
||||
if (Input::has('ids')) {
|
||||
$assets = Asset::find(Input::get('ids'));
|
||||
foreach ($assets as $asset) {
|
||||
$update_array['deleted_at'] = date('Y-m-d H:i:s');
|
||||
$update_array['assigned_to'] = null;
|
||||
|
||||
if (DB::table('assets')
|
||||
->where('id', $asset->id)
|
||||
->update($update_array)) {
|
||||
|
||||
$logAction = new Actionlog();
|
||||
$logAction->item_type = Asset::class;
|
||||
$logAction->item_id = $asset->id;
|
||||
$logAction->created_at = date("Y-m-d H:i:s");
|
||||
$logAction->user_id = Auth::user()->id;
|
||||
$logAction->logaction('deleted');
|
||||
}
|
||||
|
||||
DB::table('assets')
|
||||
->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
|
||||
@@ -1237,7 +1168,7 @@ class AssetsController extends Controller
|
||||
$this->authorize('checkout', Asset::class);
|
||||
// Filter out assets that are not deployable.
|
||||
$assets_list = Company::scopeCompanyables(Asset::RTD()->get(), 'assets.company_id')->pluck('detailed_name', 'id')->toArray();
|
||||
return View::make('hardware/bulk-checkout')
|
||||
return view('hardware/bulk-checkout')
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('assets_list', $assets_list);
|
||||
}
|
||||
@@ -1251,6 +1182,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"))) {
|
||||
@@ -1271,7 +1205,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());
|
||||
@@ -1286,4 +1220,45 @@ class AssetsController extends Controller
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to("hardware/bulk-checkout")->with('error', trans('admin/hardware/message.checkout.error'))->withErrors($errors);
|
||||
}
|
||||
|
||||
|
||||
public function quickScan(Request $request)
|
||||
{
|
||||
$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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function audit(Request $request, $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());
|
||||
}
|
||||
|
||||
public function auditStore(Request $request, $id)
|
||||
{
|
||||
$this->authorize('audit', Asset::class);
|
||||
|
||||
$rules = array(
|
||||
'location_id' => 'exists:locations,id|nullable|numeric',
|
||||
'next_audit_date' => 'date|nullable'
|
||||
);
|
||||
|
||||
$validator = \Validator::make($request->all(), $rules);
|
||||
if ($validator->fails()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()->all()));
|
||||
}
|
||||
|
||||
$asset = Asset::findOrFail($id);
|
||||
$asset->next_audit_date = $request->input('next_audit_date');
|
||||
|
||||
if ($asset->save()) {
|
||||
$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());
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +56,7 @@ class LoginController extends Controller
|
||||
if (Auth::check()) {
|
||||
return redirect()->intended('dashboard');
|
||||
}
|
||||
return View::make('auth.login');
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
|
||||
@@ -198,7 +199,7 @@ class LoginController extends Controller
|
||||
$user->two_factor_secret
|
||||
);
|
||||
|
||||
return View::make('auth.two_factor_enroll')->with('google2fa_url', $google2fa_url);
|
||||
return view('auth.two_factor_enroll')->with('google2fa_url', $google2fa_url);
|
||||
|
||||
}
|
||||
|
||||
@@ -210,7 +211,7 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function getTwoFactorAuth()
|
||||
{
|
||||
return View::make('auth.two_factor');
|
||||
return view('auth.two_factor');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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.
|
||||
|
||||
@@ -38,7 +38,7 @@ class CategoriesController extends Controller
|
||||
public function index()
|
||||
{
|
||||
// Show the page
|
||||
return View::make('categories/index');
|
||||
return view('categories/index');
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class CategoriesController extends Controller
|
||||
{
|
||||
// Show the page
|
||||
$category_types= Helper::categoryTypeList();
|
||||
return View::make('categories/edit')->with('item', new Category)
|
||||
return view('categories/edit')->with('item', new Category)
|
||||
->with('category_types', $category_types);
|
||||
}
|
||||
|
||||
@@ -98,14 +98,12 @@ 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();
|
||||
|
||||
return View::make('categories/edit', compact('item'))
|
||||
return view('categories/edit', compact('item'))
|
||||
->with('category_types', $category_types);
|
||||
}
|
||||
|
||||
@@ -158,22 +156,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'));
|
||||
}
|
||||
|
||||
|
||||
@@ -201,7 +199,7 @@ class CategoriesController extends Controller
|
||||
$category_type = $category->category_type;
|
||||
$category_type_route = $category->category_type.'s';
|
||||
}
|
||||
return View::make('categories/view', compact('category'))
|
||||
return view('categories/view', compact('category'))
|
||||
->with('category_type',$category_type)
|
||||
->with('category_type_route',$category_type_route);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ final class CompaniesController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('companies/index')->with('companies', Company::all());
|
||||
return view('companies/index')->with('companies', Company::all());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,7 +39,7 @@ final class CompaniesController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return View::make('companies/edit')->with('item', new Company);
|
||||
return view('companies/edit')->with('item', new Company);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ final class CompaniesController extends Controller
|
||||
return redirect()->route('companies.index')
|
||||
->with('error', trans('admin/companies/message.does_not_exist'));
|
||||
}
|
||||
return View::make('companies/edit')->with('item', $item);
|
||||
return view('companies/edit')->with('item', $item);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +145,7 @@ final class CompaniesController extends Controller
|
||||
return redirect()->route('companies.index')
|
||||
->with('error', trans('admin/companies/message.not_found'));
|
||||
} else {
|
||||
return View::make('companies/view')->with('company',$company);
|
||||
return view('companies/view')->with('company',$company);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Models\CustomField;
|
||||
@@ -12,7 +11,6 @@ use App\Models\Asset;
|
||||
use Auth;
|
||||
use Config;
|
||||
use DB;
|
||||
use DeepCopyTest\H;
|
||||
use Input;
|
||||
use Lang;
|
||||
use Mail;
|
||||
@@ -44,7 +42,7 @@ class ComponentsController extends Controller
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', Component::class);
|
||||
return View::make('components/index');
|
||||
return view('components/index');
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +58,7 @@ class ComponentsController extends Controller
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
// Show the page
|
||||
return View::make('components/edit')
|
||||
return view('components/edit')
|
||||
->with('item', new Component)
|
||||
->with('category_list', Helper::categoryList('component'))
|
||||
->with('company_list', Helper::companyList())
|
||||
@@ -76,29 +74,23 @@ class ComponentsController extends Controller
|
||||
* @since [v3.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store()
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
// create a new model instance
|
||||
$component = new Component();
|
||||
|
||||
// Update the component data
|
||||
$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();
|
||||
|
||||
// Was the component created?
|
||||
if ($component->save()) {
|
||||
$component->logCreate();
|
||||
// Redirect to the new component page
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($component->getErrors());
|
||||
@@ -115,15 +107,13 @@ class ComponentsController extends Controller
|
||||
*/
|
||||
public function edit($componentId = null)
|
||||
{
|
||||
// Check if the component exists
|
||||
if (is_null($item = Component::find($componentId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('update', $item);
|
||||
|
||||
return View::make('components/edit', compact('item'))
|
||||
return view('components/edit', compact('item'))
|
||||
->with('category_list', Helper::categoryList('component'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList());
|
||||
@@ -141,9 +131,7 @@ class ComponentsController extends Controller
|
||||
*/
|
||||
public function update($componentId = null)
|
||||
{
|
||||
// Check if the blog post exists
|
||||
if (is_null($component = Component::find($componentId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.does_not_exist'));
|
||||
}
|
||||
|
||||
@@ -215,7 +203,7 @@ class ComponentsController extends Controller
|
||||
|
||||
if (isset($component->id)) {
|
||||
$this->authorize('view', $component);
|
||||
return View::make('components/view', compact('component'));
|
||||
return view('components/view', compact('component'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/components/message.does_not_exist', compact('id'));
|
||||
@@ -240,7 +228,7 @@ class ComponentsController extends Controller
|
||||
return redirect()->route('components.index')->with('error', trans('admin/components/message.not_found'));
|
||||
}
|
||||
$this->authorize('checkout', $component);
|
||||
return View::make('components/checkout', compact('component'))->with('assets_list', Helper::detailedAssetList());
|
||||
return view('components/checkout', compact('component'))->with('assets_list', Helper::detailedAssetList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,40 +283,9 @@ class ComponentsController extends Controller
|
||||
'asset_id' => $asset_id
|
||||
]);
|
||||
|
||||
$component->logCheckout(e(Input::get('note')), $asset_id);
|
||||
$component->logCheckout(e(Input::get('note')), $asset);
|
||||
return redirect()->route('components.index')->with('success', trans('admin/components/message.checkout.success'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Company;
|
||||
use App\Models\Consumable;
|
||||
use App\Models\Setting;
|
||||
@@ -40,7 +39,7 @@ class ConsumablesController extends Controller
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', Consumable::class);
|
||||
return View::make('consumables/index');
|
||||
return view('consumables/index');
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +55,7 @@ class ConsumablesController extends Controller
|
||||
{
|
||||
$this->authorize('create', Consumable::class);
|
||||
// Show the page
|
||||
return View::make('consumables/edit')
|
||||
return view('consumables/edit')
|
||||
->with('item', new Consumable)
|
||||
->with('category_list', Helper::categoryList('consumable'))
|
||||
->with('company_list', Helper::companyList())
|
||||
@@ -91,10 +90,7 @@ class ConsumablesController extends Controller
|
||||
$consumable->qty = Input::get('qty');
|
||||
$consumable->user_id = Auth::id();
|
||||
|
||||
// Was the consumable created?
|
||||
if ($consumable->save()) {
|
||||
$consumable->logCreate();
|
||||
// Redirect to the new consumable page
|
||||
return redirect()->route('consumables.index')->with('success', trans('admin/consumables/message.create.success'));
|
||||
}
|
||||
|
||||
@@ -113,15 +109,13 @@ class ConsumablesController extends Controller
|
||||
*/
|
||||
public function edit($consumableId = null)
|
||||
{
|
||||
// Check if the consumable exists
|
||||
if (is_null($item = Consumable::find($consumableId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize($item);
|
||||
|
||||
return View::make('consumables/edit', compact('item'))
|
||||
return view('consumables/edit', compact('item'))
|
||||
->with('category_list', Helper::categoryList('consumable'))
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('location_list', Helper::locationsList())
|
||||
@@ -175,9 +169,7 @@ class ConsumablesController extends Controller
|
||||
*/
|
||||
public function destroy($consumableId)
|
||||
{
|
||||
// Check if the blog post exists
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
|
||||
}
|
||||
$this->authorize($consumable);
|
||||
@@ -200,13 +192,9 @@ class ConsumablesController extends Controller
|
||||
$consumable = Consumable::find($consumableId);
|
||||
$this->authorize($consumable);
|
||||
if (isset($consumable->id)) {
|
||||
return View::make('consumables/view', compact('consumable'));
|
||||
return view('consumables/view', compact('consumable'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/consumables/message.does_not_exist', compact('id'));
|
||||
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('consumables')->with('error', $error);
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,14 +208,11 @@ class ConsumablesController extends Controller
|
||||
*/
|
||||
public function getCheckout($consumableId)
|
||||
{
|
||||
// Check if the consumable exists
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
// Redirect to the consumable management page with error
|
||||
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);
|
||||
// Get the dropdown of users and then pass it to the checkout view
|
||||
return View::make('consumables/checkout', compact('consumable'))->with('users_list', Helper::usersList());
|
||||
return view('consumables/checkout', compact('consumable'))->with('users_list', Helper::usersList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,9 +226,7 @@ class ConsumablesController extends Controller
|
||||
*/
|
||||
public function postCheckout($consumableId)
|
||||
{
|
||||
// Check if the consumable exists
|
||||
if (is_null($consumable = Consumable::find($consumableId))) {
|
||||
// Redirect to the consumable management page with error
|
||||
return redirect()->route('consumables.index')->with('error', trans('admin/consumables/message.not_found'));
|
||||
}
|
||||
|
||||
@@ -252,13 +235,13 @@ class ConsumablesController extends Controller
|
||||
$admin_user = Auth::user();
|
||||
$assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
// Check if the user exists
|
||||
// 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'));
|
||||
}
|
||||
|
||||
// Update the consumable data
|
||||
// Update the consumable data
|
||||
$consumable->assigned_to = e(Input::get('assigned_to'));
|
||||
|
||||
$consumable->users()->attach($consumable->id, [
|
||||
@@ -267,7 +250,7 @@ class ConsumablesController extends Controller
|
||||
'assigned_to' => e(Input::get('assigned_to'))
|
||||
]);
|
||||
|
||||
$logaction = $consumable->logCheckout(e(Input::get('note')));
|
||||
$logaction = $consumable->logCheckout(e(Input::get('note')), $user);
|
||||
$data['log_id'] = $logaction->id;
|
||||
$data['eula'] = $consumable->getEula();
|
||||
$data['first_name'] = $user->first_name;
|
||||
@@ -290,47 +273,4 @@ class ConsumablesController extends Controller
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a JSON response containing details on the users associated with this consumable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see ConsumablesController::getView() method that returns the form.
|
||||
* @since [v1.0]
|
||||
* @param int $consumableId
|
||||
* @return array
|
||||
*/
|
||||
public function getDataView($consumableId)
|
||||
{
|
||||
//$consumable = Consumable::find($consumableID);
|
||||
$consumable = Consumable::with(array('consumableAssigments'=>
|
||||
function ($query) {
|
||||
$query->orderBy('created_at', 'DESC');
|
||||
},
|
||||
'consumableAssigments.admin'=> function ($query) {
|
||||
},
|
||||
'consumableAssigments.user'=> function ($query) {
|
||||
},
|
||||
))->find($consumableId);
|
||||
|
||||
// $consumable->load('consumableAssigments.admin','consumableAssigments.user');
|
||||
|
||||
if (!Company::isCurrentUserHasAccess($consumable)) {
|
||||
return ['total' => 0, 'rows' => []];
|
||||
}
|
||||
$this->authorize('view', Component::class);
|
||||
$rows = array();
|
||||
|
||||
foreach ($consumable->consumableAssigments as $consumable_assignment) {
|
||||
$rows[] = [
|
||||
'name' => $consumable_assignment->user->present()->nameUrl(),
|
||||
'created_at' => ($consumable_assignment->created_at->format('Y-m-d H:i:s')=='-0001-11-30 00:00:00') ? '' : $consumable_assignment->created_at->format('Y-m-d H:i:s'),
|
||||
'admin' => ($consumable_assignment->admin) ? $consumable_assignment->admin->present()->nameUrl() : '',
|
||||
];
|
||||
}
|
||||
|
||||
$consumableCount = $consumable->users->count();
|
||||
$data = array('total' => $consumableCount, 'rows' => $rows);
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class CustomFieldsController extends Controller
|
||||
|
||||
$fieldsets = CustomFieldset::with("fields", "models")->get();
|
||||
$fields = CustomField::with("fieldset")->get();
|
||||
return View::make("custom_fields.index")->with("custom_fieldsets", $fieldsets)->with("custom_fields", $fields);
|
||||
return view("custom_fields.index")->with("custom_fieldsets", $fieldsets)->with("custom_fields", $fields);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class CustomFieldsController extends Controller
|
||||
public function create()
|
||||
{
|
||||
|
||||
return View::make("custom_fields.fields.edit")->with('field', new CustomField());
|
||||
return view("custom_fields.fields.edit")->with('field', new CustomField());
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ class CustomFieldsController extends Controller
|
||||
public function edit($id)
|
||||
{
|
||||
$field = CustomField::find($id);
|
||||
return View::make("custom_fields.fields.edit")->with('field', $field);
|
||||
return view("custom_fields.fields.edit")->with('field', $field);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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::make("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'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +68,7 @@ class CustomFieldsetsController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return View::make("custom_fields.fieldsets.edit");
|
||||
return view("custom_fields.fieldsets.edit");
|
||||
}
|
||||
|
||||
|
||||
@@ -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'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,53 +30,20 @@ class DashboardController extends Controller
|
||||
// Show the page
|
||||
if (Auth::user()->hasAccess('admin')) {
|
||||
|
||||
$asset_stats['total'] = Asset::Hardware()->count();
|
||||
$asset_stats=null;
|
||||
|
||||
$asset_stats['rtd']['total'] = Asset::Hardware()->RTD()->count();
|
||||
$counts['asset'] = \App\Models\Asset::count();
|
||||
$counts['accessory'] = \App\Models\Accessory::count();
|
||||
$counts['license'] = \App\Models\License::assetcount();
|
||||
$counts['consumable'] = \App\Models\Consumable::count();
|
||||
$counts['grand_total'] = $counts['asset'] + $counts['accessory'] + $counts['license'] + $counts['consumable'];
|
||||
|
||||
if ($asset_stats['rtd']['total'] > 0) {
|
||||
$asset_stats['rtd']['percent'] = round(($asset_stats['rtd']['total']/$asset_stats['total']) * 100);
|
||||
} else {
|
||||
$asset_stats['rtd']['percent'] = 0;
|
||||
if ((!file_exists(storage_path().'/oauth-private.key')) || (!file_exists(storage_path().'/oauth-public.key'))) {
|
||||
\Artisan::call('migrate', ['--force' => true]);
|
||||
\Artisan::call('passport:install');
|
||||
}
|
||||
|
||||
|
||||
$asset_stats['pending']['total'] = Asset::Hardware()->Pending()->count();
|
||||
|
||||
if ($asset_stats['pending']['total'] > 0) {
|
||||
$asset_stats['pending']['percent'] = round(($asset_stats['pending']['total']/$asset_stats['total']) * 100);
|
||||
} else {
|
||||
$asset_stats['pending']['percent'] = 0;
|
||||
}
|
||||
|
||||
|
||||
$asset_stats['deployed']['total'] = Asset::Hardware()->Deployed()->count();
|
||||
|
||||
if ($asset_stats['deployed']['total'] > 0) {
|
||||
$asset_stats['deployed']['percent'] = round(($asset_stats['deployed']['total']/$asset_stats['total']) * 100);
|
||||
} else {
|
||||
$asset_stats['deployed']['percent'] = 0;
|
||||
}
|
||||
|
||||
|
||||
$asset_stats['undeployable']['total'] = Asset::Hardware()->Undeployable()->count();
|
||||
|
||||
if ($asset_stats['undeployable']['total'] > 0) {
|
||||
$asset_stats['undeployable']['percent'] = round(($asset_stats['undeployable']['total']/$asset_stats['total']) * 100);
|
||||
} else {
|
||||
$asset_stats['undeployable']['percent'] = 0;
|
||||
}
|
||||
|
||||
$asset_stats['archived']['total'] = Asset::Hardware()->Archived()->count();
|
||||
|
||||
if ($asset_stats['archived']['total'] > 0) {
|
||||
$asset_stats['archived']['percent'] = round(($asset_stats['archived']['total']/$asset_stats['total']) * 100);
|
||||
} else {
|
||||
$asset_stats['archived']['percent'] = 0;
|
||||
}
|
||||
|
||||
|
||||
return View::make('dashboard')->with('asset_stats', $asset_stats);
|
||||
return view('dashboard')->with('asset_stats', $asset_stats)->with('counts', $counts);
|
||||
} else {
|
||||
// Redirect to the profile page
|
||||
return redirect()->intended('account/view-assets');
|
||||
|
||||
155
app/Http/Controllers/DepartmentsController.php
Normal file
155
app/Http/Controllers/DepartmentsController.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Department;
|
||||
use App\Helpers\Helper;
|
||||
use Auth;
|
||||
|
||||
class DepartmentsController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the assets listing, which is generated in getDatatable.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see AssetController::getDatatable() method that generates the JSON response
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$this->authorize('index', Department::class);
|
||||
$company = null;
|
||||
if ($request->has('company_id')) {
|
||||
$company = Company::find($request->input('company_id'));
|
||||
}
|
||||
return view('departments/index')->with('company', $company);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
$this->authorize('create', Department::class);
|
||||
$department = new Department;
|
||||
$department->fill($request->all());
|
||||
$department->user_id = Auth::user()->id;
|
||||
$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.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($department->getErrors());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that invokes the ajax tables which actually contains
|
||||
* the content for the department detail page.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $id
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
$department = Department::find($id);
|
||||
|
||||
if (isset($department->id)) {
|
||||
return view('departments/view', compact('department'));
|
||||
}
|
||||
return redirect()->route('departments.index')->with('error', trans('admin/departments/message.does_not_exist', compact('id')));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a form view used to create a new department.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see DepartmentsController::postCreate() method that validates and stores the data
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validates and deletes selected department.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @param int $locationId
|
||||
* @since [v4.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
if (is_null($department = Department::find($id))) {
|
||||
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.not_found'));
|
||||
}
|
||||
|
||||
if ($department->users->count() > 0) {
|
||||
return redirect()->to(route('departments.index'))->with('error', trans('admin/departments/message.assoc_users'));
|
||||
}
|
||||
|
||||
$department->delete();
|
||||
return redirect()->back()->with('success', trans('admin/departments/message.delete.success'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a form view to edit location information.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::postCreate() method that validates and stores
|
||||
* @param int $locationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit($id = null)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
public function update(Request $request, $id) {
|
||||
|
||||
$this->authorize('create', Department::class);
|
||||
if (is_null($department = Department::find($id))) {
|
||||
return redirect()->route('departments.index')->with('error', trans('admin/departments/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$department->fill($request->all());
|
||||
$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());
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ class DepreciationsController extends Controller
|
||||
public function index()
|
||||
{
|
||||
// Show the page
|
||||
return View::make('depreciations/index', compact('depreciations'));
|
||||
return view('depreciations/index', compact('depreciations'));
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class DepreciationsController extends Controller
|
||||
public function create()
|
||||
{
|
||||
// Show the page
|
||||
return View::make('depreciations/edit')->with('item', new Depreciation);
|
||||
return view('depreciations/edit')->with('item', new Depreciation);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ class DepreciationsController extends Controller
|
||||
return redirect()->route('depreciations.index')->with('error', trans('admin/depreciations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
return View::make('depreciations/edit', compact('item'));
|
||||
return view('depreciations/edit', compact('item'));
|
||||
}
|
||||
|
||||
|
||||
@@ -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'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ class GroupsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getIndex()
|
||||
public function index()
|
||||
{
|
||||
// Show the page
|
||||
return View::make('groups/index', compact('groups'));
|
||||
return view('groups/index', compact('groups'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ class GroupsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getCreate()
|
||||
public function create()
|
||||
{
|
||||
$group = new Group;
|
||||
// Get all the available permissions
|
||||
@@ -51,7 +51,7 @@ class GroupsController extends Controller
|
||||
$selectedPermissions = Input::old('permissions', $groupPermissions);
|
||||
|
||||
// Show the page
|
||||
return View::make('groups/edit', compact('permissions', 'selectedPermissions', 'groupPermissions'))->with('group', $group);
|
||||
return view('groups/edit', compact('permissions', 'selectedPermissions', 'groupPermissions'))->with('group', $group);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ class GroupsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postCreate()
|
||||
public function store()
|
||||
{
|
||||
// create a new group instance
|
||||
$group = new Group();
|
||||
@@ -84,13 +84,18 @@ class GroupsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function getEdit($id = null)
|
||||
public function edit($id = null)
|
||||
{
|
||||
$group = Group::find($id);
|
||||
$permissions = config('permissions');
|
||||
$groupPermissions = $group->decodePermissions();
|
||||
$selected_array = Helper::selectedPermissionsArray($permissions, $groupPermissions);
|
||||
return View::make('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')));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +107,7 @@ class GroupsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postEdit($id = null)
|
||||
public function update($id = null)
|
||||
{
|
||||
$permissions = config('permissions');
|
||||
if (!$group = Group::find($id)) {
|
||||
@@ -113,11 +118,11 @@ class GroupsController extends Controller
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
if ($group->save()) {
|
||||
return redirect()->to("admin/groups")->with('success', trans('admin/groups/message.success.update'));
|
||||
return redirect()->route('groups.index')->with('success', trans('admin/groups/message.success.update'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($group->getErrors());
|
||||
}
|
||||
return redirect()->route('groups')->with('error', trans('general.feature_disabled'));
|
||||
return redirect()->route('groups.index')->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,7 +134,7 @@ class GroupsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function getDelete($id = null)
|
||||
public function destroy($id = null)
|
||||
{
|
||||
if (!config('app.lock_passwords')) {
|
||||
if (!$group = Group::find($id)) {
|
||||
@@ -137,9 +142,29 @@ class GroupsController extends Controller
|
||||
}
|
||||
$group->delete();
|
||||
// Redirect to the group management page
|
||||
return redirect()->route('groups')->with('success', trans('admin/groups/message.success.delete'));
|
||||
return redirect()->route('groups.index')->with('success', trans('admin/groups/message.success.delete'));
|
||||
}
|
||||
return redirect()->route('groups')->with('error', trans('general.feature_disabled'));
|
||||
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')));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
18
app/Http/Controllers/ImportsController.php
Normal file
18
app/Http/Controllers/ImportsController.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Transformers\ImportsTransformer;
|
||||
use App\Models\Import;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ImportsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('create', Asset::class);
|
||||
$imports = Import::latest()->get();
|
||||
$imports = (new ImportsTransformer)->transformImports($imports);
|
||||
return view('importer/import')->with('imports', $imports);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ class LicensesController extends Controller
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
return View::make('licenses/index');
|
||||
return view('licenses/index');
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class LicensesController extends Controller
|
||||
'0' => 'No'
|
||||
];
|
||||
|
||||
return View::make('licenses/edit')
|
||||
return view('licenses/edit')
|
||||
//->with('license_options',$license_options)
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
@@ -113,10 +113,7 @@ class LicensesController extends Controller
|
||||
$license->termination_date = $request->input('termination_date');
|
||||
$license->user_id = Auth::id();
|
||||
|
||||
// Was the license created?
|
||||
if ($license->save()) {
|
||||
$license->logCreate();
|
||||
// Save the license seat data
|
||||
return redirect()->route("licenses.index")->with('success', trans('admin/licenses/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($license->getErrors());
|
||||
@@ -145,7 +142,7 @@ class LicensesController extends Controller
|
||||
'0' => 'No'
|
||||
];
|
||||
|
||||
return View::make('licenses/edit', compact('item'))
|
||||
return view('licenses/edit', compact('item'))
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('company_list', Helper::companyList())
|
||||
@@ -167,15 +164,12 @@ class LicensesController extends Controller
|
||||
*/
|
||||
public function update(Request $request, $licenseId = null)
|
||||
{
|
||||
// Check if the license exists
|
||||
if (is_null($license = License::find($licenseId))) {
|
||||
// Redirect to the blogs management page
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$this->authorize('update', $license);
|
||||
|
||||
// Update the license data
|
||||
$license->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
$license->depreciation_id = $request->input('depreciation_id');
|
||||
$license->expiration_date = $request->input('expiration_date');
|
||||
@@ -193,6 +187,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'));
|
||||
@@ -259,7 +254,7 @@ class LicensesController extends Controller
|
||||
}
|
||||
|
||||
$this->authorize('checkout', $licenseSeat);
|
||||
return View::make('licenses/checkout', compact('licenseSeat'))
|
||||
return view('licenses/checkout', compact('licenseSeat'))
|
||||
->with('users_list', Helper::usersList())
|
||||
->with('asset_list', Helper::detailedAssetList());
|
||||
}
|
||||
@@ -285,7 +280,7 @@ class LicensesController extends Controller
|
||||
|
||||
// Declare the rules for the form validation
|
||||
$rules = [
|
||||
'note' => 'string',
|
||||
'note' => 'string|nullable',
|
||||
'asset_id' => 'required_without:assigned_to',
|
||||
];
|
||||
|
||||
@@ -297,23 +292,23 @@ class LicensesController extends Controller
|
||||
// Ooops.. something went wrong
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
}
|
||||
|
||||
$target = null;
|
||||
if ($assigned_to!='') {
|
||||
// Check if the user exists
|
||||
if (is_null($is_assigned_to = User::find($assigned_to))) {
|
||||
if (is_null($target = User::find($assigned_to))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.user_does_not_exist'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($asset_id!='') {
|
||||
if (is_null($asset = Asset::find($asset_id))) {
|
||||
if (is_null($target = Asset::find($asset_id))) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.asset_does_not_exist'));
|
||||
}
|
||||
|
||||
if (($asset->assigned_to!='') && (($asset->assigned_to!=$assigned_to)) && ($assigned_to!='')) {
|
||||
return redirect()->route('licenses.index')->with('error', trans('admin/licenses/message.owner_doesnt_match_asset'));
|
||||
if (($request->has('assigned_to')) && ($request->has('asset_id'))) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/licenses/message.select_asset_or_person'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,17 +333,16 @@ class LicensesController extends Controller
|
||||
|
||||
// Was the asset updated?
|
||||
if ($licenseSeat->save()) {
|
||||
$licenseSeat->logCheckout($request->input('note'));
|
||||
$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'));
|
||||
}
|
||||
|
||||
|
||||
@@ -364,12 +358,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::make('licenses/checkin', compact('licenseseat'))->with('backto', $backTo);
|
||||
$this->authorize('checkin', $licenseSeat);
|
||||
return view('licenses/checkin', compact('licenseSeat'))->with('backto', $backTo);
|
||||
}
|
||||
|
||||
|
||||
@@ -446,15 +440,16 @@ class LicensesController extends Controller
|
||||
*/
|
||||
public function show($licenseId = null)
|
||||
{
|
||||
$license = License::find($licenseId);
|
||||
if (isset($license->id)) {
|
||||
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
|
||||
|
||||
$license = License::with('assignedusers', 'licenseSeats.user', 'licenseSeats.asset')->find($licenseId);
|
||||
|
||||
if ($license) {
|
||||
$this->authorize('view', $license);
|
||||
return View::make('licenses/view', compact('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)
|
||||
{
|
||||
@@ -475,7 +470,7 @@ class LicensesController extends Controller
|
||||
$license->serial = null;
|
||||
|
||||
// Show the page
|
||||
return View::make('licenses/edit')
|
||||
return view('licenses/edit')
|
||||
->with('depreciation_list', Helper::depreciationList())
|
||||
->with('supplier_list', Helper::suppliersList())
|
||||
->with('item', $license)
|
||||
@@ -494,7 +489,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
|
||||
@@ -523,13 +518,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'));
|
||||
@@ -592,61 +590,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.
|
||||
|
||||
@@ -41,7 +41,7 @@ class LocationsController extends Controller
|
||||
$locations = Location::orderBy('created_at', 'DESC')->with('parent', 'assets', 'assignedassets')->get();
|
||||
|
||||
// Show the page
|
||||
return View::make('locations/index', compact('locations'));
|
||||
return view('locations/index', compact('locations'));
|
||||
}
|
||||
|
||||
|
||||
@@ -61,9 +61,10 @@ class LocationsController extends Controller
|
||||
$location_options = Location::flattenLocationsArray($location_options_array);
|
||||
$location_options = array('' => 'Top Level') + $location_options;
|
||||
|
||||
return View::make('locations/edit')
|
||||
return view('locations/edit')
|
||||
->with('location_options', $location_options)
|
||||
->with('item', new Location);
|
||||
->with('item', new Location)
|
||||
->with('manager_list', Helper::managerList());
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +89,8 @@ class LocationsController extends Controller
|
||||
$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->user_id = Auth::id();
|
||||
|
||||
if ($location->save()) {
|
||||
@@ -145,7 +148,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
|
||||
@@ -154,7 +157,9 @@ class LocationsController extends Controller
|
||||
$location_options = Location::flattenLocationsArray($location_options_array);
|
||||
$location_options = array('' => 'Top Level') + $location_options;
|
||||
|
||||
return View::make('locations/edit', compact('item'))->with('location_options', $location_options);
|
||||
return view('locations/edit', compact('item'))
|
||||
->with('location_options', $location_options)
|
||||
->with('manager_list', Helper::managerList());
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +176,7 @@ class LocationsController extends Controller
|
||||
{
|
||||
// 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
|
||||
@@ -185,6 +190,7 @@ class LocationsController extends Controller
|
||||
$location->country = Input::get('country');
|
||||
$location->zip = Input::get('zip');
|
||||
$location->ldap_ou = Input::get('ldap_ou');
|
||||
$location->manager_id = Input::get('manager_id');
|
||||
|
||||
// Was the location updated?
|
||||
if ($location->save()) {
|
||||
@@ -211,7 +217,6 @@ class LocationsController extends Controller
|
||||
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) {
|
||||
@@ -232,8 +237,6 @@ class LocationsController extends Controller
|
||||
* the content for the locations detail page.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::getDataViewUsers() method that returns JSON for location users
|
||||
* @see LocationsController::getDataViewAssets() method that returns JSON for location assets
|
||||
* @param int $locationId
|
||||
* @since [v1.0]
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
@@ -243,7 +246,7 @@ class LocationsController extends Controller
|
||||
$location = Location::find($locationId);
|
||||
|
||||
if (isset($location->id)) {
|
||||
return View::make('locations/view', compact('location'));
|
||||
return view('locations/view', compact('location'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/locations/message.does_not_exist', compact('id'));
|
||||
@@ -252,78 +255,4 @@ class LocationsController extends Controller
|
||||
return redirect()->route('locations.index')->with('error', $error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a JSON response that contains the users association with the
|
||||
* selected location, to be used by the location detail view.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::getView() method that creates the display view
|
||||
* @param $locationID
|
||||
* @return array
|
||||
* @internal param int $locationId
|
||||
* @since [v1.8]
|
||||
*/
|
||||
public function getDataViewUsers($locationID)
|
||||
{
|
||||
$location = Location::find($locationID);
|
||||
$users = User::where('location_id', '=', $location->id);
|
||||
|
||||
if (Input::has('search')) {
|
||||
$users = $users->TextSearch(e(Input::get('search')));
|
||||
}
|
||||
|
||||
$users = $users->get();
|
||||
$rows = array();
|
||||
|
||||
foreach ($users as $user) {
|
||||
$rows[] = array(
|
||||
'name' => (string)link_to_route('users.show', e($user->present()->fullName()), ['user'=>$user->id])
|
||||
);
|
||||
}
|
||||
|
||||
$data = array('total' => $users->count(), 'rows' => $rows);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a JSON response that contains the assets association with the
|
||||
* selected location, to be used by the location detail view.
|
||||
*
|
||||
* @todo This is broken for accessories and consumables.
|
||||
* @todo This is a very naive implementation. Should clean this up with query scopes.
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @see LocationsController::getView() method that creates the display view
|
||||
* @param int $locationID
|
||||
* @since [v1.8]
|
||||
* @return array
|
||||
*/
|
||||
public function getDataViewAssets($locationID)
|
||||
{
|
||||
$location = Location::find($locationID)->load('assignedassets.model');
|
||||
$assets = Asset::AssetsByLocation($location);
|
||||
|
||||
if (Input::has('search')) {
|
||||
$assets = $assets->TextSearch(e(Input::get('search')));
|
||||
}
|
||||
|
||||
$assets = $assets->get();
|
||||
|
||||
$rows = array();
|
||||
|
||||
foreach ($assets as $asset) {
|
||||
$rows[] = [
|
||||
'name' => (string)link_to_route('hardware.show', e($asset->present()->name()), ['hardware' => $asset->id]),
|
||||
'asset_tag' => e($asset->asset_tag),
|
||||
'serial' => e($asset->serial),
|
||||
'model' => e($asset->model->name),
|
||||
];
|
||||
}
|
||||
|
||||
$data = array('total' => $assets->count(), 'rows' => $rows);
|
||||
return $data;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class ManufacturersController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('manufacturers/index', compact('manufacturers'));
|
||||
return view('manufacturers/index', compact('manufacturers'));
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class ManufacturersController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return View::make('manufacturers/edit')->with('item', new Manufacturer);
|
||||
return view('manufacturers/edit')->with('item', new Manufacturer);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ class ManufacturersController extends Controller
|
||||
return redirect()->route('manufacturers.index')->with('error', trans('admin/manufacturers/message.does_not_exist'));
|
||||
}
|
||||
// Show the page
|
||||
return View::make('manufacturers/edit', compact('item'));
|
||||
return view('manufacturers/edit', compact('item'));
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ class ManufacturersController extends Controller
|
||||
$manufacturer = Manufacturer::find($manufacturerId);
|
||||
|
||||
if (isset($manufacturer->id)) {
|
||||
return View::make('manufacturers/view', compact('manufacturer'));
|
||||
return view('manufacturers/view', compact('manufacturer'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/manufacturers/message.does_not_exist', compact('id'));
|
||||
@@ -212,116 +212,5 @@ class ManufacturersController extends Controller
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
32
app/Http/Controllers/ModalController.php
Normal file
32
app/Http/Controllers/ModalController.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class ModalController extends Controller
|
||||
{
|
||||
function location() {
|
||||
return view('modals.location');
|
||||
}
|
||||
|
||||
function model() {
|
||||
return view('modals.model')
|
||||
->with('manufacturer', Helper::manufacturerList())
|
||||
->with('category', Helper::categoryList('asset'));
|
||||
}
|
||||
|
||||
function statuslabel() {
|
||||
return view('modals.statuslabel')->with('statuslabel_types', Helper::statusTypeList());
|
||||
}
|
||||
|
||||
function supplier() {
|
||||
return view('modals.supplier');
|
||||
}
|
||||
|
||||
function user() {
|
||||
return view('modals.user');
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,13 @@ namespace App\Http\Controllers;
|
||||
use Image;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use App\Models\Location;
|
||||
use View;
|
||||
use Auth;
|
||||
use App\Helpers\Helper;
|
||||
use App\Models\Setting;
|
||||
use Gate;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to User Profiles for
|
||||
@@ -30,7 +31,7 @@ class ProfileController extends Controller
|
||||
{
|
||||
$user = Auth::user();
|
||||
$location_list = Helper::locationsList();
|
||||
return View::make('account/profile', compact('user'))->with('location_list', $location_list);
|
||||
return view('account/profile', compact('user'))->with('location_list', $location_list);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,4 +88,60 @@ class ProfileController extends Controller
|
||||
public function api() {
|
||||
return view('account/api');
|
||||
}
|
||||
|
||||
/**
|
||||
* User change email page.
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function password()
|
||||
{
|
||||
$user = Auth::user();
|
||||
return view('account/change-password', compact('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Users change password form processing page.
|
||||
*
|
||||
* @return Redirect
|
||||
*/
|
||||
public function passwordSave(Request $request)
|
||||
{
|
||||
|
||||
if (config('app.lock_passwords')) {
|
||||
return redirect()->route('account.password.index')->with('error', Lang::get('admin/users/table.lock_passwords'));
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
if ($user->ldap_import=='1') {
|
||||
return redirect()->route('account.password.index')->with('error', Lang::get('admin/users/message.error.password_ldap'));
|
||||
}
|
||||
|
||||
$rules = array(
|
||||
'current_password' => 'required',
|
||||
'password' => Setting::passwordComplexityRulesSaving('store'),
|
||||
'password_confirm' => 'required|same:password',
|
||||
);
|
||||
|
||||
$validator = \Validator::make($request->all(), $rules);
|
||||
$validator->after(function($validator) use ($request, $user) {
|
||||
|
||||
if (!Hash::check($request->input('current_password'), $user->password)) {
|
||||
$validator->errors()->add('current_password', trans('validation.hashed_pass'));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (!$validator->fails()) {
|
||||
$user->password = Hash::make($request->input('password'));
|
||||
$user->save();
|
||||
return redirect()->route('account.password.index')->with('success', 'Password updated!');
|
||||
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($validator);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,22 +6,16 @@ use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetMaintenance;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Company;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Response;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Input;
|
||||
use League\Csv\Reader;
|
||||
use Redirect;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Reports for
|
||||
@@ -42,8 +36,7 @@ class ReportsController extends Controller
|
||||
public function getAccessoryReport()
|
||||
{
|
||||
$accessories = Accessory::orderBy('created_at', 'DESC')->with('company')->get();
|
||||
|
||||
return View::make('reports/accessories', compact('accessories'));
|
||||
return view('reports/accessories', compact('accessories'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +91,7 @@ class ReportsController extends Controller
|
||||
public function getAssetsReport()
|
||||
{
|
||||
$settings = \App\Models\Setting::first();
|
||||
return View::make('reports/asset', compact('assets'))->with('settings', $settings);
|
||||
return view('reports/asset', compact('assets'))->with('settings', $settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,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', 'assetLoc','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'),
|
||||
@@ -134,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'),
|
||||
@@ -162,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->assetLoc) ? e($asset->assetLoc->present()->name()) : '',
|
||||
($asset->notes) ? e($asset->notes) : '',
|
||||
];
|
||||
foreach ($customfields as $field) {
|
||||
@@ -176,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;
|
||||
@@ -194,10 +215,10 @@ class ReportsController extends Controller
|
||||
{
|
||||
|
||||
// Grab all the assets
|
||||
$assets = Asset::with('model', 'assignedTo', 'assetstatus', 'defaultLoc', 'assetlog', 'company')
|
||||
$assets = Asset::with( 'assignedTo', 'assetstatus', 'defaultLoc', 'assetloc', 'assetlog', 'company', 'model.category', 'model.depreciation')
|
||||
->orderBy('created_at', 'DESC')->get();
|
||||
|
||||
return View::make('reports/depreciation', compact('assets'));
|
||||
return view('reports/depreciation', compact('assets'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,6 +300,20 @@ class ReportsController extends Controller
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays audit report.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function audit()
|
||||
{
|
||||
return view('reports/audit');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays activity report.
|
||||
*
|
||||
@@ -289,55 +324,9 @@ class ReportsController extends Controller
|
||||
public function getActivityReport()
|
||||
{
|
||||
|
||||
return View::make('reports/activity');
|
||||
return view('reports/activity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Activity Report JSON.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getActivityReportDataTable()
|
||||
{
|
||||
$activitylogs = Company::scopeCompanyables(Actionlog::with('item', 'user', 'target'))->orderBy('created_at', 'DESC');
|
||||
|
||||
if (Input::has('search')) {
|
||||
$activitylogs = $activitylogs->TextSearch(e(Input::get('search')));
|
||||
}
|
||||
|
||||
if (Input::has('offset')) {
|
||||
$offset = e(Input::get('offset'));
|
||||
} else {
|
||||
$offset = 0;
|
||||
}
|
||||
|
||||
if (Input::has('limit')) {
|
||||
$limit = e(Input::get('limit'));
|
||||
} else {
|
||||
$limit = 50;
|
||||
}
|
||||
|
||||
|
||||
$allowed_columns = ['created_at'];
|
||||
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
|
||||
|
||||
|
||||
$activityCount = $activitylogs->count();
|
||||
$activitylogs = $activitylogs->offset($offset)->limit($limit)->get();
|
||||
|
||||
$rows = array();
|
||||
foreach ($activitylogs as $activity) {
|
||||
$rows[] = $activity->present()->forDataTable();
|
||||
}
|
||||
|
||||
$data = array('total'=>$activityCount, 'rows'=>$rows);
|
||||
|
||||
return $data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays license report
|
||||
@@ -353,7 +342,7 @@ class ReportsController extends Controller
|
||||
->with('company')
|
||||
->get();
|
||||
|
||||
return View::make('reports/licenses', compact('licenses'));
|
||||
return view('reports/licenses', compact('licenses'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,7 +406,7 @@ class ReportsController extends Controller
|
||||
public function getCustomReport()
|
||||
{
|
||||
$customfields = CustomField::get();
|
||||
return View::make('reports/custom')->with('customfields', $customfields);
|
||||
return view('reports/custom')->with('customfields', $customfields);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,7 +419,7 @@ class ReportsController extends Controller
|
||||
*/
|
||||
public function postCustom()
|
||||
{
|
||||
$assets = Asset::orderBy('created_at', 'DESC')->with('company', 'assigneduser', 'assetloc', 'defaultLoc', 'assigneduser.userloc', 'model', 'supplier', 'assetstatus', 'model.manufacturer')->get();
|
||||
$assets = Asset::orderBy('created_at', 'DESC')->with('company', 'assignedTo', 'assetloc', 'defaultLoc', 'model', 'supplier', 'assetstatus', 'model.manufacturer')->get();
|
||||
$customfields = CustomField::get();
|
||||
|
||||
$rows = [ ];
|
||||
@@ -503,7 +492,7 @@ class ReportsController extends Controller
|
||||
}
|
||||
|
||||
if (e(Input::get('notes')) == '1') {
|
||||
$header[] = 'Notes';
|
||||
$header[] = trans('general.notes');
|
||||
}
|
||||
|
||||
|
||||
@@ -583,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
|
||||
}
|
||||
@@ -592,8 +581,8 @@ 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->assigneduser) {
|
||||
$row[] = '"' .e($asset->assigneduser->username). '"';
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = '"' .e($asset->assignedto->username). '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
@@ -601,8 +590,8 @@ 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->assigneduser) {
|
||||
$row[] = '"' .e($asset->assigneduser->employee_num). '"';
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = '"' .e($asset->assignedto->employee_num). '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
@@ -644,9 +633,9 @@ class ReportsController extends Controller
|
||||
|
||||
if (e(Input::get('notes')) == '1') {
|
||||
if ($asset->notes) {
|
||||
$row[] = '"' .$asset->notes. '"';
|
||||
$row[] = '"' .$asset->notes . '"';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
$row[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,7 +679,7 @@ class ReportsController extends Controller
|
||||
->orderBy('created_at', 'DESC')
|
||||
->get();
|
||||
|
||||
return View::make('reports/asset_maintenances', compact('assetMaintenances'));
|
||||
return view('reports/asset_maintenances', compact('assetMaintenances'));
|
||||
|
||||
}
|
||||
|
||||
@@ -765,7 +754,7 @@ class ReportsController extends Controller
|
||||
{
|
||||
$assetsForReport = Asset::notYetAccepted()->with('company')->get();
|
||||
|
||||
return View::make('reports/unaccepted_assets', compact('assetsForReport'));
|
||||
return view('reports/unaccepted_assets', compact('assetsForReport'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,8 @@ use Auth;
|
||||
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
|
||||
@@ -65,15 +67,24 @@ class SettingsController extends Controller
|
||||
|
||||
$start_settings['url_config'] = url('/');
|
||||
$start_settings['real_url'] = $pageURL;
|
||||
|
||||
// Curl the .env file to make sure it's not accessible via a browser
|
||||
$ch = curl_init($protocol . $host.'/.env');
|
||||
curl_setopt($ch, CURLOPT_HEADER, true); // we want headers
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true); // we don't need body
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||||
$output = curl_exec($ch);
|
||||
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
$exposed_env = @file_get_contents($protocol . $host.'/.env');
|
||||
|
||||
if ($exposed_env) {
|
||||
$start_settings['env_exposed'] = true;
|
||||
} else {
|
||||
if ($httpcode == 404 || $httpcode == 403) {
|
||||
$start_settings['env_exposed'] = false;
|
||||
} else {
|
||||
$start_settings['env_exposed'] = true;
|
||||
}
|
||||
|
||||
|
||||
if (\App::Environment('production') && (config('app.debug')==true)) {
|
||||
$start_settings['debug_exposed'] = true;
|
||||
} else {
|
||||
@@ -120,34 +131,12 @@ class SettingsController extends Controller
|
||||
|
||||
|
||||
$start_settings['gd'] = extension_loaded('gd');
|
||||
return View::make('setup/index')
|
||||
return view('setup/index')
|
||||
->with('step', 1)
|
||||
->with('start_settings', $start_settings)
|
||||
->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.
|
||||
@@ -175,12 +164,14 @@ class SettingsController extends Controller
|
||||
$settings->site_name = e(Input::get('site_name'));
|
||||
$settings->alert_email = e(Input::get('email'));
|
||||
$settings->alerts_enabled = 1;
|
||||
$settings->pwd_secure_min = 10;
|
||||
$settings->brand = 1;
|
||||
$settings->locale = 'en';
|
||||
$settings->default_currency = 'USD';
|
||||
$settings->user_id = 1;
|
||||
$settings->email_domain = e(Input::get('email_domain'));
|
||||
$settings->email_format = e(Input::get('email_format'));
|
||||
$settings->next_auto_tag_base = 1;
|
||||
|
||||
|
||||
if ((!$user->isValid()) || (!$settings->isValid())) {
|
||||
@@ -215,7 +206,7 @@ class SettingsController extends Controller
|
||||
*/
|
||||
public function getSetupUser()
|
||||
{
|
||||
return View::make('setup/user')
|
||||
return view('setup/user')
|
||||
->with('step', 3)
|
||||
->with('section', 'Create a User');
|
||||
}
|
||||
@@ -230,7 +221,7 @@ class SettingsController extends Controller
|
||||
public function getSetupDone()
|
||||
{
|
||||
|
||||
return View::make('setup/done')
|
||||
return view('setup/done')
|
||||
->with('step', 4)
|
||||
->with('section', 'Done!');
|
||||
}
|
||||
@@ -249,7 +240,14 @@ class SettingsController extends Controller
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
|
||||
$output = Artisan::output();
|
||||
return View::make('setup/migrate')
|
||||
|
||||
if ((!file_exists(storage_path().'/oauth-private.key')) || (!file_exists(storage_path().'/oauth-public.key'))) {
|
||||
Artisan::call('migrate', ['--force' => true]);
|
||||
Artisan::call('passport:install');
|
||||
}
|
||||
|
||||
|
||||
return view('setup/migrate')
|
||||
->with('output', $output)
|
||||
->with('step', 2)
|
||||
->with('section', 'Create Database Tables');
|
||||
@@ -264,15 +262,15 @@ class SettingsController extends Controller
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getIndex()
|
||||
public function index()
|
||||
{
|
||||
$settings = Setting::all();
|
||||
return View::make('settings/index', compact('settings'));
|
||||
return view('settings/index', compact('settings'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
* Return the admin settings page
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
@@ -281,77 +279,475 @@ class SettingsController extends Controller
|
||||
public function getEdit()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
$is_gd_installed = extension_loaded('gd');
|
||||
|
||||
return View::make('settings/edit', compact('setting'))->with('is_gd_installed', $is_gd_installed);
|
||||
return view('settings/general', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate and process settings edit form.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return Redirect
|
||||
*/
|
||||
public function postEdit(ImageUploadRequest $request)
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getSettings()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings/general', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postSettings(Request $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$setting->full_multiple_companies_support = $request->input('full_multiple_companies_support', '0');
|
||||
$setting->load_remote = $request->input('load_remote', '0');
|
||||
$setting->email_domain = $request->input('email_domain');
|
||||
$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')) {
|
||||
$setting->login_note = $request->input('login_note');
|
||||
}
|
||||
|
||||
$setting->default_eula_text = $request->input('default_eula_text');
|
||||
$setting->thumbnail_max_h = $request->input('thumbnail_max_h');
|
||||
|
||||
if (Input::get('per_page')!='') {
|
||||
$setting->per_page = $request->input('per_page');
|
||||
} else {
|
||||
$setting->per_page = 200;
|
||||
}
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getBranding()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.branding', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postBranding(ImageUploadRequest $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$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
|
||||
// Because public demos make people act like dicks
|
||||
if (!config('app.lock_passwords')) {
|
||||
$setting->site_name = $request->input('site_name');
|
||||
$setting->custom_css = $request->input('custom_css');
|
||||
}
|
||||
|
||||
|
||||
// If the user wants to clear the logo, reset the brand type
|
||||
if ($request->input('clear_logo')=='1') {
|
||||
$setting->logo = null;
|
||||
$setting->brand = 1;
|
||||
|
||||
// If they are uploading an image, validate it and upload it
|
||||
} elseif ($request->hasFile('image')) {
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = "logo.".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads');
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(null, 150, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
$setting->logo = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getSecurity()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.security', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postSecurity(Request $request)
|
||||
{
|
||||
|
||||
// Check if the asset exists
|
||||
if (is_null($setting = Setting::first())) {
|
||||
// Redirect to the asset management page with error
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
$setting->site_name = e(Input::get('site_name'));
|
||||
$setting->custom_css = e(Input::get('custom_css'));
|
||||
|
||||
if (Input::get('two_factor_enabled')=='') {
|
||||
if ($request->input('two_factor_enabled')=='') {
|
||||
$setting->two_factor_enabled = null;
|
||||
} else {
|
||||
$setting->two_factor_enabled = e(Input::get('two_factor_enabled'));
|
||||
$setting->two_factor_enabled = $request->input('two_factor_enabled');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Input::get('per_page')!='') {
|
||||
$setting->per_page = e(Input::get('per_page'));
|
||||
} else {
|
||||
$setting->per_page = 200;
|
||||
$setting->pwd_secure_uncommon = (int) $request->input('pwd_secure_uncommon');
|
||||
$setting->pwd_secure_min = (int) $request->input('pwd_secure_min');
|
||||
$setting->pwd_secure_complexity = '';
|
||||
|
||||
if ($request->has('pwd_secure_complexity')) {
|
||||
$setting->pwd_secure_complexity = implode('|', $request->input('pwd_secure_complexity'));
|
||||
}
|
||||
|
||||
$setting->locale = e(Input::get('locale', 'en'));
|
||||
$setting->qr_code = e(Input::get('qr_code', '0'));
|
||||
$setting->full_multiple_companies_support = e(Input::get('full_multiple_companies_support', '0'));
|
||||
$setting->alt_barcode = e(Input::get('alt_barcode'));
|
||||
$setting->alt_barcode_enabled = e(Input::get('alt_barcode_enabled', '0'));
|
||||
$setting->barcode_type = e(Input::get('barcode_type'));
|
||||
$setting->load_remote = e(Input::get('load_remote', '0'));
|
||||
$setting->default_currency = e(Input::get('default_currency', '$'));
|
||||
$setting->qr_text = e(Input::get('qr_text'));
|
||||
$setting->auto_increment_prefix = e(Input::get('auto_increment_prefix'));
|
||||
$setting->auto_increment_assets = e(Input::get('auto_increment_assets', '0'));
|
||||
$setting->zerofill_count = e(Input::get('zerofill_count'));
|
||||
$setting->alert_interval = e(Input::get('alert_interval'));
|
||||
$setting->alert_threshold = e(Input::get('alert_threshold'));
|
||||
$setting->email_domain = e(Input::get('email_domain'));
|
||||
$setting->email_format = e(Input::get('email_format'));
|
||||
$setting->username_format = e(Input::get('username_format'));
|
||||
$setting->require_accept_signature = e(Input::get('require_accept_signature'));
|
||||
$setting->labels_per_page = e(Input::get('labels_per_page'));
|
||||
$setting->labels_width = e(Input::get('labels_width'));
|
||||
$setting->labels_height = e(Input::get('labels_height'));
|
||||
$setting->labels_pmargin_left = e(Input::get('labels_pmargin_left'));
|
||||
$setting->labels_pmargin_right = e(Input::get('labels_pmargin_right'));
|
||||
$setting->labels_pmargin_top = e(Input::get('labels_pmargin_top'));
|
||||
$setting->labels_pmargin_bottom = e(Input::get('labels_pmargin_bottom'));
|
||||
$setting->labels_display_bgutter = e(Input::get('labels_display_bgutter'));
|
||||
$setting->labels_display_sgutter = e(Input::get('labels_display_sgutter'));
|
||||
$setting->labels_fontsize = e(Input::get('labels_fontsize'));
|
||||
$setting->labels_pagewidth = e(Input::get('labels_pagewidth'));
|
||||
$setting->labels_pageheight = e(Input::get('labels_pageheight'));
|
||||
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getLocalization()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.localization', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postLocalization(Request $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$setting->locale = $request->input('locale', 'en');
|
||||
$setting->default_currency = $request->input('default_currency', '$');
|
||||
$setting->date_display_format = $request->input('date_display_format');
|
||||
$setting->time_display_format = $request->input('time_display_format');
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getAlerts()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.alerts', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postAlerts(Request $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$alert_email = rtrim($request->input('alert_email'), ',');
|
||||
$alert_email = trim($alert_email);
|
||||
|
||||
$setting->alert_email = $alert_email;
|
||||
$setting->alerts_enabled = $request->input('alerts_enabled', '0');
|
||||
$setting->alert_interval = $request->input('alert_interval');
|
||||
$setting->alert_threshold = $request->input('alert_threshold');
|
||||
$setting->audit_interval = $request->input('audit_interval');
|
||||
$setting->audit_warning_days = $request->input('audit_warning_days');
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getSlack()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.slack', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postSlack(Request $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$setting->slack_endpoint = $request->input('slack_endpoint');
|
||||
$setting->slack_channel = $request->input('slack_channel');
|
||||
$setting->slack_botname = $request->input('slack_botname');
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getAssetTags()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.asset_tags', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves settings from form
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postAssetTags(Request $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$setting->auto_increment_prefix = $request->input('auto_increment_prefix');
|
||||
$setting->auto_increment_assets = $request->input('auto_increment_assets', '0');
|
||||
$setting->zerofill_count = $request->input('zerofill_count');
|
||||
$setting->next_auto_tag_base = $request->input('next_auto_tag_base');
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getBarcodes()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
$is_gd_installed = extension_loaded('gd');
|
||||
|
||||
return view('settings.barcodes', compact('setting'))->with('is_gd_installed',$is_gd_installed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves settings from form
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postBarcodes(Request $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$setting->qr_code = $request->input('qr_code', '0');
|
||||
$setting->alt_barcode = $request->input('alt_barcode');
|
||||
$setting->alt_barcode_enabled = $request->input('alt_barcode_enabled', '0');
|
||||
$setting->barcode_type = $request->input('barcode_type');
|
||||
$setting->qr_text = $request->input('qr_text');
|
||||
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getPhpInfo()
|
||||
{
|
||||
if (config('app.debug')=== true) {
|
||||
return view('settings.phpinfo');
|
||||
}
|
||||
return redirect()->route('settings.index')
|
||||
->with('error', 'PHP syetem debugging information is only available when debug is enabled in your .env file.');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getLabels()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.labels', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves settings from form
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postLabels(Request $request)
|
||||
{
|
||||
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
$setting->labels_per_page = $request->input('labels_per_page');
|
||||
$setting->labels_width = $request->input('labels_width');
|
||||
$setting->labels_height = $request->input('labels_height');
|
||||
$setting->labels_pmargin_left = $request->input('labels_pmargin_left');
|
||||
$setting->labels_pmargin_right = $request->input('labels_pmargin_right');
|
||||
$setting->labels_pmargin_top = $request->input('labels_pmargin_top');
|
||||
$setting->labels_pmargin_bottom = $request->input('labels_pmargin_bottom');
|
||||
$setting->labels_display_bgutter = $request->input('labels_display_bgutter');
|
||||
$setting->labels_display_sgutter = $request->input('labels_display_sgutter');
|
||||
$setting->labels_fontsize = $request->input('labels_fontsize');
|
||||
$setting->labels_pagewidth = $request->input('labels_pagewidth');
|
||||
$setting->labels_pageheight = $request->input('labels_pageheight');
|
||||
|
||||
|
||||
|
||||
if (Input::has('labels_display_name')) {
|
||||
@@ -372,96 +768,79 @@ class SettingsController extends Controller
|
||||
$setting->labels_display_tag = 0;
|
||||
}
|
||||
|
||||
$alert_email = rtrim(Input::get('alert_email'), ',');
|
||||
$alert_email = trim($alert_email);
|
||||
|
||||
$setting->alert_email = e($alert_email);
|
||||
$setting->alerts_enabled = e(Input::get('alerts_enabled', '0'));
|
||||
$setting->header_color = e(Input::get('header_color'));
|
||||
$setting->default_eula_text = e(Input::get('default_eula_text'));
|
||||
$setting->slack_endpoint = e(Input::get('slack_endpoint'));
|
||||
$setting->slack_channel = e(Input::get('slack_channel'));
|
||||
$setting->slack_botname = e(Input::get('slack_botname'));
|
||||
$setting->ldap_enabled = e(Input::get('ldap_enabled', '0'));
|
||||
$setting->ldap_server = e(Input::get('ldap_server'));
|
||||
$setting->ldap_server_cert_ignore = e(Input::get('ldap_server_cert_ignore', false));
|
||||
$setting->ldap_uname = e(Input::get('ldap_uname'));
|
||||
if (Input::has('ldap_pword')) {
|
||||
$setting->ldap_pword = Crypt::encrypt(Input::get('ldap_pword'));
|
||||
}
|
||||
$setting->ldap_basedn = e(Input::get('ldap_basedn'));
|
||||
$setting->ldap_filter = Input::get('ldap_filter');
|
||||
$setting->ldap_username_field = Input::get('ldap_username_field');
|
||||
$setting->ldap_lname_field = e(Input::get('ldap_lname_field'));
|
||||
$setting->ldap_fname_field = e(Input::get('ldap_fname_field'));
|
||||
$setting->ldap_auth_filter_query = Input::get('ldap_auth_filter_query');
|
||||
$setting->ldap_version = e(Input::get('ldap_version'));
|
||||
$setting->ldap_active_flag = e(Input::get('ldap_active_flag'));
|
||||
$setting->ldap_emp_num = e(Input::get('ldap_emp_num'));
|
||||
$setting->ldap_email = e(Input::get('ldap_email'));
|
||||
$setting->ad_domain = e(Input::get('ad_domain'));
|
||||
$setting->is_ad = e(Input::get('is_ad', '0'));
|
||||
$setting->ldap_tls = e(Input::get('ldap_tls', '0'));
|
||||
$setting->ldap_pw_sync = e(Input::get('ldap_pw_sync', '0'));
|
||||
|
||||
$setting->date_display_format = e(Input::get('date_display_format'));
|
||||
$setting->time_display_format = e(Input::get('time_display_format'));
|
||||
|
||||
|
||||
if ($request->input('clear_logo')=='1') {
|
||||
$setting->logo = null;
|
||||
$setting->brand = 1;
|
||||
} elseif ($request->hasFile('image')) {
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = "logo.".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads');
|
||||
if ($image->getClientOriginalExtension()!='svg') {
|
||||
Image::make($image->getRealPath())->resize(null, 40, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path.'/'.$file_name);
|
||||
} else {
|
||||
$image->move($path, $file_name);
|
||||
}
|
||||
$setting->logo = $file_name;
|
||||
}
|
||||
}
|
||||
|
||||
if ($setting->save()) {
|
||||
return redirect()->to("admin/settings/app")->with('success', trans('admin/settings/message.update.success'));
|
||||
} else {
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
return redirect()->route('settings.index')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
|
||||
|
||||
// Redirect to the setting management page
|
||||
return redirect()->to("admin/settings/app/edit")->with('error', trans('admin/settings/message.update.error'));
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getLdapTest()
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getLdapSettings()
|
||||
{
|
||||
$setting = Setting::first();
|
||||
return view('settings.ldap', compact('setting'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves settings from form
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function postLdapSettings(Request $request)
|
||||
{
|
||||
|
||||
try {
|
||||
$connection = Ldap::connectToLdap();
|
||||
try {
|
||||
Ldap::bindAdminToLdap($connection);
|
||||
return response()->json(['message' => 'It worked!'], 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
}
|
||||
return response()->json(['message' => 'It worked!'], 200);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['message' => $e->getMessage()], 500);
|
||||
if (is_null($setting = Setting::first())) {
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
$setting->ldap_enabled = $request->input('ldap_enabled', '0');
|
||||
$setting->ldap_server = $request->input('ldap_server');
|
||||
$setting->ldap_server_cert_ignore = $request->input('ldap_server_cert_ignore', false);
|
||||
$setting->ldap_uname = $request->input('ldap_uname');
|
||||
if (Input::has('ldap_pword')) {
|
||||
$setting->ldap_pword = Crypt::encrypt($request->input('ldap_pword'));
|
||||
}
|
||||
$setting->ldap_basedn = $request->input('ldap_basedn');
|
||||
$setting->ldap_filter = $request->input('ldap_filter');
|
||||
$setting->ldap_username_field = $request->input('ldap_username_field');
|
||||
$setting->ldap_lname_field = $request->input('ldap_lname_field');
|
||||
$setting->ldap_fname_field = $request->input('ldap_fname_field');
|
||||
$setting->ldap_auth_filter_query = $request->input('ldap_auth_filter_query');
|
||||
$setting->ldap_version = $request->input('ldap_version');
|
||||
$setting->ldap_active_flag = $request->input('ldap_active_flag');
|
||||
$setting->ldap_emp_num = $request->input('ldap_emp_num');
|
||||
$setting->ldap_email = $request->input('ldap_email');
|
||||
$setting->ad_domain = $request->input('ad_domain');
|
||||
$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')
|
||||
->with('success', trans('admin/settings/message.update.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($setting->getErrors());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Show the listing of backups
|
||||
*
|
||||
@@ -495,7 +874,7 @@ class SettingsController extends Controller
|
||||
}
|
||||
|
||||
|
||||
return View::make('settings/backups', compact('path', 'files'));
|
||||
return view('settings/backups', compact('path', 'files'));
|
||||
}
|
||||
|
||||
|
||||
@@ -511,10 +890,9 @@ class SettingsController extends Controller
|
||||
{
|
||||
if (!config('app.lock_passwords')) {
|
||||
Artisan::call('backup:run');
|
||||
return redirect()->to("admin/settings/backups")->with('success', trans('admin/settings/message.backup.generated'));
|
||||
return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.generated'));
|
||||
} else {
|
||||
|
||||
return redirect()->to("admin/settings/backups")->with('error', trans('general.feature_disabled'));
|
||||
return redirect()->to("settings.backups.index")->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
|
||||
@@ -538,11 +916,11 @@ class SettingsController extends Controller
|
||||
} else {
|
||||
|
||||
// Redirect to the backup page
|
||||
return redirect()->route('settings/backups')->with('error', trans('admin/settings/message.backup.file_not_found'));
|
||||
return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
|
||||
}
|
||||
} else {
|
||||
// Redirect to the backup page
|
||||
return redirect()->route('settings/backups')->with('error', trans('general.feature_disabled'));
|
||||
return redirect()->route('settings.backups.index')->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
|
||||
@@ -564,17 +942,29 @@ class SettingsController extends Controller
|
||||
$file = $path.'/'.$filename;
|
||||
if (file_exists($file)) {
|
||||
unlink($file);
|
||||
return redirect()->route('settings/backups')->with('success', trans('admin/settings/message.backup.file_deleted'));
|
||||
return redirect()->route('settings.backups.index')->with('success', trans('admin/settings/message.backup.file_deleted'));
|
||||
} else {
|
||||
return redirect()->route('settings/backups')->with('error', trans('admin/settings/message.backup.file_not_found'));
|
||||
return redirect()->route('settings.backups.index')->with('error', trans('admin/settings/message.backup.file_not_found'));
|
||||
}
|
||||
} else {
|
||||
return redirect()->route('settings/backups')->with('error', trans('general.feature_disabled'));
|
||||
return redirect()->route('settings.backups.index')->with('error', trans('general.feature_disabled'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a form to allow a super admin to update settings.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v4.0]
|
||||
* @return View
|
||||
*/
|
||||
public function getPurge()
|
||||
{
|
||||
return view('settings.purge-form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges soft-deletes
|
||||
*
|
||||
@@ -586,9 +976,11 @@ class SettingsController extends Controller
|
||||
{
|
||||
if (!config('app.lock_passwords')) {
|
||||
if (Input::get('confirm_purge')=='DELETE') {
|
||||
// Run a backup immediately before processing
|
||||
Artisan::call('backup:run');
|
||||
Artisan::call('snipeit:purge', ['--force'=>'true','--no-interaction'=>true]);
|
||||
$output = Artisan::output();
|
||||
return View::make('settings/purge')
|
||||
return view('settings/purge')
|
||||
->with('output', $output)->with('success', trans('admin/settings/message.purge.success'));
|
||||
} else {
|
||||
return redirect()->back()->with('error', trans('admin/settings/message.purge.validation_failed'));
|
||||
@@ -610,6 +1002,30 @@ class SettingsController extends Controller
|
||||
* @return View
|
||||
*/
|
||||
public function api() {
|
||||
return view('settings/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,7 +32,7 @@ class StatuslabelsController extends Controller
|
||||
|
||||
public function index()
|
||||
{
|
||||
return View::make('statuslabels/index', compact('statuslabels'));
|
||||
return view('statuslabels/index', compact('statuslabels'));
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
@@ -40,7 +40,7 @@ class StatuslabelsController extends Controller
|
||||
$statuslabel = Statuslabel::find($id);
|
||||
|
||||
if (isset($statuslabel->id)) {
|
||||
return View::make('statuslabels/view', compact('statuslabel'));
|
||||
return view('statuslabels/view', compact('statuslabel'));
|
||||
}
|
||||
|
||||
return redirect()->route('statuslabels.index')->with('error', trans('admin/locations/message.does_not_exist', compact('id')));
|
||||
@@ -60,7 +60,7 @@ class StatuslabelsController extends Controller
|
||||
$use_statuslabel_type = $item->getStatuslabelType();
|
||||
$statuslabel_types = Helper::statusTypeList();
|
||||
|
||||
return View::make('statuslabels/edit', compact('statuslabel_types', 'item'))->with('use_statuslabel_type', $use_statuslabel_type);
|
||||
return view('statuslabels/edit', compact('statuslabel_types', 'item'))->with('use_statuslabel_type', $use_statuslabel_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ class StatuslabelsController extends Controller
|
||||
|
||||
$statuslabel_types = array('' => trans('admin/hardware/form.select_statustype')) + array('undeployable' => trans('admin/hardware/general.undeployable')) + array('pending' => trans('admin/hardware/general.pending')) + array('archived' => trans('admin/hardware/general.archived')) + array('deployable' => trans('admin/hardware/general.deployable'));
|
||||
|
||||
return View::make('statuslabels/edit', compact('item', 'statuslabel_types'))->with('use_statuslabel_type', $use_statuslabel_type);
|
||||
return view('statuslabels/edit', compact('item', 'statuslabel_types'))->with('use_statuslabel_type', $use_statuslabel_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,17 +200,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;
|
||||
|
||||
@@ -35,7 +36,7 @@ class SuppliersController extends Controller
|
||||
$suppliers = Supplier::orderBy('created_at', 'DESC')->get();
|
||||
|
||||
// Show the page
|
||||
return View::make('suppliers/index', compact('suppliers'));
|
||||
return view('suppliers/index', compact('suppliers'));
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +47,7 @@ class SuppliersController extends Controller
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return View::make('suppliers/edit')->with('item', new Supplier);
|
||||
return view('suppliers/edit')->with('item', new Supplier);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -87,9 +88,8 @@ class SuppliersController extends Controller
|
||||
$supplier->image = $file_name;
|
||||
}
|
||||
|
||||
// Was it created?
|
||||
if ($supplier->save()) {
|
||||
// Redirect to the new supplier page
|
||||
// Redirect to the nw supplier page
|
||||
return redirect()->route('suppliers.index')->with('success', trans('admin/suppliers/message.create.success'));
|
||||
}
|
||||
return redirect()->back()->withInput()->withErrors($supplier->getErrors());
|
||||
@@ -126,7 +126,7 @@ class SuppliersController extends Controller
|
||||
}
|
||||
|
||||
// Show the page
|
||||
return View::make('suppliers/edit', compact('item'));
|
||||
return view('suppliers/edit', compact('item'));
|
||||
}
|
||||
|
||||
|
||||
@@ -136,7 +136,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 +159,17 @@ class SuppliersController extends Controller
|
||||
$supplier->url = $supplier->addhttp(request('url'));
|
||||
$supplier->notes = request('notes');
|
||||
|
||||
|
||||
if (Input::file('image')) {
|
||||
$image = $request->file('image');
|
||||
$file_name = str_random(25).".".$image->getClientOriginalExtension();
|
||||
$file_name = 'suppliers-'.str_random(25).".".$image->getClientOriginalExtension();
|
||||
$path = public_path('uploads/suppliers/'.$file_name);
|
||||
Image::make($image->getRealPath())->resize(300, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
$supplier->image = $file_name;
|
||||
}
|
||||
|
||||
if (request('image_delete') == 1 && $request->file('image') == "") {
|
||||
} elseif (request('image_delete') == 1) {
|
||||
$supplier->image = null;
|
||||
}
|
||||
|
||||
@@ -190,23 +189,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')
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +227,7 @@ class SuppliersController extends Controller
|
||||
$supplier = Supplier::find($supplierId);
|
||||
|
||||
if (isset($supplier->id)) {
|
||||
return View::make('suppliers/view', compact('supplier'));
|
||||
return view('suppliers/view', compact('supplier'));
|
||||
}
|
||||
// Prepare the error message
|
||||
$error = trans('admin/suppliers/message.does_not_exist', compact('id'));
|
||||
|
||||
@@ -12,9 +12,7 @@ use App\Models\Company;
|
||||
use App\Models\Location;
|
||||
use App\Models\License;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Http\Requests\SaveUserRequest;
|
||||
use App\Http\Requests\UpdateUserRequest;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use App\Models\User;
|
||||
use App\Models\Ldap;
|
||||
@@ -23,7 +21,6 @@ use Config;
|
||||
use Crypt;
|
||||
use DB;
|
||||
use HTML;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Input;
|
||||
use Lang;
|
||||
use League\Csv\Reader;
|
||||
@@ -36,6 +33,7 @@ use URL;
|
||||
use View;
|
||||
use Illuminate\Http\Request;
|
||||
use Gate;
|
||||
use Artisan;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Users for
|
||||
@@ -61,7 +59,7 @@ class UsersController extends Controller
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('index', User::class);
|
||||
return View::make('users/index');
|
||||
return view('users/index');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,10 +84,11 @@ class UsersController extends Controller
|
||||
$userPermissions = Helper::selectedPermissionsArray($permissions, Input::old('permissions', array()));
|
||||
$permissions = $this->filterDisplayable($permissions);
|
||||
|
||||
return View::make('users/edit', compact('groups', 'userGroups', 'permissions', 'userPermissions'))
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -120,6 +119,7 @@ class UsersController extends Controller
|
||||
$user->jobtitle = $request->input('jobtitle');
|
||||
$user->phone = $request->input('phone');
|
||||
$user->location_id = $request->input('location_id', null);
|
||||
$user->department_id = $request->input('department_id', null);
|
||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||
$user->manager_id = $request->input('manager_id', null);
|
||||
$user->notes = $request->input('notes');
|
||||
@@ -167,7 +167,7 @@ class UsersController extends Controller
|
||||
* @since [v1.8]
|
||||
* @return string JSON
|
||||
*/
|
||||
public function apiStore()
|
||||
public function apiStore(SaveUserRequest $request)
|
||||
{
|
||||
$this->authorize('create', User::class);
|
||||
|
||||
@@ -175,12 +175,13 @@ class UsersController extends Controller
|
||||
$inputs = Input::except('csrf_token', 'password_confirm', 'groups', 'email_user');
|
||||
$inputs['activated'] = true;
|
||||
|
||||
$user->first_name = Input::get('first_name');
|
||||
$user->last_name = Input::get('last_name');
|
||||
$user->username = Input::get('username');
|
||||
$user->email = Input::get('email');
|
||||
if (Input::has('password')) {
|
||||
$user->password = bcrypt(Input::get('password'));
|
||||
$user->first_name = $request->input('first_name');
|
||||
$user->last_name = $request->input('last_name');
|
||||
$user->username = $request->input('username');
|
||||
$user->email = $request->input('email');
|
||||
$user->department_id = $request->input('department_id', null);
|
||||
if ($request->has('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
$user->activated = true;
|
||||
|
||||
@@ -190,10 +191,10 @@ class UsersController extends Controller
|
||||
if (Input::get('email_user') == 1) {
|
||||
// Send the credentials through email
|
||||
$data = array();
|
||||
$data['email'] = e(Input::get('email'));
|
||||
$data['first_name'] = e(Input::get('first_name'));
|
||||
$data['last_name'] = e(Input::get('last_name'));
|
||||
$data['password'] = e(Input::get('password'));
|
||||
$data['email'] = $request->input('email');
|
||||
$data['first_name'] = $request->input('first_name');
|
||||
$data['last_name'] = $request->input('last_name');
|
||||
$data['password'] = $request->input('password');
|
||||
|
||||
Mail::send('emails.send-login', $data, function ($m) use ($user) {
|
||||
$m->to($user->email, $user->first_name . ' ' . $user->last_name);
|
||||
@@ -229,10 +230,10 @@ class UsersController extends Controller
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function edit($id = null)
|
||||
public function edit($id)
|
||||
{
|
||||
try {
|
||||
// Get the user information
|
||||
|
||||
$user = User::find($id);
|
||||
$this->authorize('update', $user);
|
||||
$permissions = config('permissions');
|
||||
@@ -243,19 +244,19 @@ class UsersController extends Controller
|
||||
$user->permissions = $user->decodePermissions();
|
||||
$userPermissions = Helper::selectedPermissionsArray($permissions, $user->permissions);
|
||||
$permissions = $this->filterDisplayable($permissions);
|
||||
|
||||
} catch (UserNotFoundException $e) {
|
||||
// Prepare the error message
|
||||
$error = trans('admin/users/message.user_not_found', compact('id'));
|
||||
|
||||
// Redirect to the user management page
|
||||
$error = trans('admin/users/message.user_not_found', compact('id'));
|
||||
return redirect()->route('users.index')->with('error', $error);
|
||||
}
|
||||
|
||||
// Show the page
|
||||
return View::make('users/edit', compact('user', 'groups', 'userGroups', 'permissions', 'userPermissions'))
|
||||
->with('location_list', Helper::locationsList())
|
||||
->with('company_list', Helper::companyList())
|
||||
->with('manager_list', Helper::managerList());
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -267,7 +268,7 @@ class UsersController extends Controller
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, $id = null)
|
||||
public function update(SaveUserRequest $request, $id = null)
|
||||
{
|
||||
// We need to reverse the UI specific logic for our
|
||||
// permissions here before we update the user.
|
||||
@@ -306,14 +307,11 @@ class UsersController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
// Do we want to update the user password?
|
||||
if ($request->has('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
if ($request->has('username')) {
|
||||
$user->username = e($request->input('username'));
|
||||
$user->username = $request->input('username');
|
||||
}
|
||||
$user->email = e($request->input('email'));
|
||||
$user->email = $request->input('email');
|
||||
|
||||
|
||||
// Update the user
|
||||
@@ -329,6 +327,13 @@ class UsersController extends Controller
|
||||
$user->company_id = Company::getIdForUser($request->input('company_id', null));
|
||||
$user->manager_id = $request->input('manager_id', null);
|
||||
$user->notes = $request->input('notes');
|
||||
$user->department_id = $request->input('department_id', null);
|
||||
|
||||
|
||||
// Do we want to update the user password?
|
||||
if ($request->has('password')) {
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
}
|
||||
|
||||
// Strip out the superuser permission if the user isn't a superadmin
|
||||
$permissions_array = $request->input('permission');
|
||||
@@ -366,15 +371,20 @@ class UsersController extends Controller
|
||||
// Authorize takes care of many of our logic checks now.
|
||||
$this->authorize('delete', User::class);
|
||||
|
||||
if ($user->assets()->count() > 0) {
|
||||
// Check if we are not trying to delete ourselves
|
||||
if ($user->id === Auth::user()->id) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->assets()->count() . ' assets associated with them.');
|
||||
}
|
||||
|
||||
if ($user->licenses()->count() > 0) {
|
||||
|
||||
if (count($user->assets) > 0) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->licenses()->count() . ' licenses associated with them.');
|
||||
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.');
|
||||
}
|
||||
|
||||
if ($user->accessories()->count() > 0) {
|
||||
@@ -382,6 +392,11 @@ class UsersController extends Controller
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->accessories()->count() . ' accessories associated with them.');
|
||||
}
|
||||
|
||||
if ($user->managedLocations()->count() > 0) {
|
||||
// Redirect to the user management page
|
||||
return redirect()->route('users.index')->with('error', 'This user still has ' . $user->managedLocations()->count() . ' locations that they manage.');
|
||||
}
|
||||
|
||||
// Delete the user
|
||||
$user->delete();
|
||||
|
||||
@@ -419,15 +434,16 @@ class UsersController extends Controller
|
||||
$users = User::whereIn('id', $user_raw_array)->with('groups', 'assets', 'licenses', 'accessories')->get();
|
||||
if ($request->input('bulk_actions')=='edit') {
|
||||
|
||||
return View::make('users/bulk-edit', compact('users'))
|
||||
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'));
|
||||
}
|
||||
|
||||
return View::make('users/confirm-bulk-delete', compact('users', 'statuslabel_list'));
|
||||
return view('users/confirm-bulk-delete', compact('users', 'statuslabel_list'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,12 +464,16 @@ class UsersController extends Controller
|
||||
|
||||
$user_raw_array = Input::get('ids');
|
||||
$update_array = array();
|
||||
$manager_conflict = false;
|
||||
|
||||
$users = User::whereIn('id', $user_raw_array)->where('id','!=',Auth::user()->id)->get();
|
||||
|
||||
if ($request->has('location_id')) {
|
||||
$update_array['location_id'] = $request->input('location_id');
|
||||
}
|
||||
if ($request->has('department_id')) {
|
||||
$update_array['department_id'] = $request->input('department_id');
|
||||
}
|
||||
if ($request->has('company_id')) {
|
||||
$update_array['company_id'] = $request->input('company_id');
|
||||
}
|
||||
@@ -464,7 +484,7 @@ class UsersController extends Controller
|
||||
// edited.
|
||||
if (!array_key_exists($request->input('manager_id'), $user_raw_array)) {
|
||||
$update_array['manager_id'] = $request->input('manager_id');
|
||||
$manager_conflict = false;
|
||||
|
||||
} else {
|
||||
$manager_conflict = true;
|
||||
}
|
||||
@@ -519,10 +539,7 @@ class UsersController extends Controller
|
||||
if (($key = array_search(Auth::user()->id, $user_raw_array)) !== false) {
|
||||
unset($user_raw_array[$key]);
|
||||
}
|
||||
|
||||
if (!Auth::user()->isSuperUser()) {
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.insufficient_permissions'));
|
||||
}
|
||||
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
|
||||
@@ -636,7 +653,7 @@ class UsersController extends Controller
|
||||
|
||||
if (isset($user->id)) {
|
||||
$this->authorize('view', $user);
|
||||
return View::make('users/view', compact('user', 'userlog'));
|
||||
return view('users/view', compact('user', 'userlog'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,7 +729,7 @@ class UsersController extends Controller
|
||||
$user->id = null;
|
||||
|
||||
// Get this user groups
|
||||
$userGroups = $user_to_clone->groups()->lists('name', 'id');
|
||||
$userGroups = $user_to_clone->groups()->pluck('name', 'id');
|
||||
// Get all the available permissions
|
||||
$permissions = config('permissions');
|
||||
$clonedPermissions = $user_to_clone->decodePermissions();
|
||||
@@ -720,10 +737,11 @@ class UsersController extends Controller
|
||||
$userPermissions =Helper::selectedPermissionsArray($permissions, $clonedPermissions);
|
||||
|
||||
// Show the page
|
||||
return View::make('users/edit', compact('permissions', 'userPermissions'))
|
||||
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)
|
||||
@@ -752,7 +770,7 @@ class UsersController extends Controller
|
||||
$permissions = config('permissions');
|
||||
$selectedPermissions = Input::old('permissions', array('superuser' => -1));
|
||||
// Show the page
|
||||
return View::make('users/import', compact('selectedGroups', 'permissions', 'selectedPermissions'));
|
||||
return view('users/import', compact('selectedGroups', 'permissions', 'selectedPermissions'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -822,7 +840,6 @@ class UsersController extends Controller
|
||||
'permissions' => '{"user":1}',
|
||||
'notes' => 'Imported user'
|
||||
);
|
||||
//dd($newuser);
|
||||
|
||||
DB::table('users')->insert($newuser);
|
||||
|
||||
@@ -914,7 +931,6 @@ class UsersController extends Controller
|
||||
$user = User::find($userId);
|
||||
$destinationPath = config('app.private_uploads').'/users';
|
||||
|
||||
// the license is valid
|
||||
if (isset($user->id)) {
|
||||
$this->authorize('update', $user);
|
||||
$log = Actionlog::find($fileId);
|
||||
@@ -982,7 +998,7 @@ class UsersController extends Controller
|
||||
return redirect()->route('users.index')->with('error', $e->getMessage());
|
||||
}
|
||||
|
||||
return View::make('users/ldap')
|
||||
return view('users/ldap')
|
||||
->with('location_list', Helper::locationsList());
|
||||
}
|
||||
|
||||
@@ -1014,134 +1030,22 @@ 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"]:"";
|
||||
|
||||
// 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 = 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;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return JSON containing a list of assets assigned to a user.
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v3.0]
|
||||
* @param $userId
|
||||
* @return string JSON
|
||||
*/
|
||||
public function getAssetList($userId)
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
$assets = Asset::where('assigned_to', '=', $userId)->with('model')->get();
|
||||
return response()->json($assets);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exports users to CSV
|
||||
|
||||
@@ -53,7 +53,7 @@ class ViewAssetsController extends Controller
|
||||
$userlog = $user->userlog->load('item', 'user', 'target');
|
||||
|
||||
if (isset($user->id)) {
|
||||
return View::make('account/view-assets', compact('user', 'userlog'));
|
||||
return view('account/view-assets', compact('user', 'userlog'));
|
||||
} else {
|
||||
// Prepare the error message
|
||||
$error = trans('admin/users/message.user_not_found', compact('id'));
|
||||
@@ -68,16 +68,16 @@ class ViewAssetsController extends Controller
|
||||
public function getRequestableIndex()
|
||||
{
|
||||
|
||||
$assets = Asset::with('model', 'defaultLoc', 'assetloc', 'assignedTo')->Hardware()->RequestableAssets()->get();
|
||||
$models = AssetModel::with('category')->RequestableModels()->get();
|
||||
$assets = Asset::with('model', 'defaultLoc', 'assetloc', 'assignedTo', 'requests')->Hardware()->RequestableAssets()->get();
|
||||
$models = AssetModel::with('category', 'requests', 'assets')->RequestableModels()->get();
|
||||
|
||||
return View::make('account/requestable-assets', compact('user', 'assets', 'models'));
|
||||
return view('account/requestable-assets', compact('user', 'assets', 'models'));
|
||||
}
|
||||
|
||||
public function getRequestedIndex()
|
||||
{
|
||||
$requestedItems = CheckoutRequest::with('user', 'requestedItem')->get();
|
||||
return View::make('admin/requested-assets', compact('requestedItems'));
|
||||
return view('admin/requested-assets', compact('requestedItems'));
|
||||
}
|
||||
|
||||
|
||||
@@ -280,7 +280,7 @@ class ViewAssetsController extends Controller
|
||||
{
|
||||
$checkoutrequests = CheckoutRequest::all();
|
||||
|
||||
return View::make('account/requested-items', compact($checkoutrequests));
|
||||
return view('account/requested-items', compact($checkoutrequests));
|
||||
}
|
||||
|
||||
|
||||
@@ -314,7 +314,7 @@ class ViewAssetsController extends Controller
|
||||
} elseif (!Company::isCurrentUserHasAccess($item)) {
|
||||
return redirect()->route('requestable-assets')->with('error', trans('general.insufficient_permissions'));
|
||||
} else {
|
||||
return View::make('account/accept-asset', compact('item'))->with('findlog', $findlog)->with('item', $item);
|
||||
return view('account/accept-asset', compact('item'))->with('findlog', $findlog)->with('item', $item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,22 +32,35 @@ class ItemImportRequest extends FormRequest
|
||||
|
||||
public function import(Import $import)
|
||||
{
|
||||
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', '500M');
|
||||
$filename = config('app.private_uploads') . '/imports/' . $import->file_path;
|
||||
$class = title_case($this->input('import-type'));
|
||||
$import->import_type = $this->input('import-type');
|
||||
$class = title_case($import->import_type);
|
||||
$classString = "App\\Importer\\{$class}Importer";
|
||||
$importer = new $classString($filename);
|
||||
$import->field_map = request('column-mappings');
|
||||
$import->save();
|
||||
$fieldMappings=[];
|
||||
if ($import->field_map) {
|
||||
// We submit as csv field: column, but the importer is happier if we flip it here.
|
||||
$fieldMappings = array_change_key_case(array_flip($import->field_map), CASE_LOWER);
|
||||
// dd($fieldMappings);
|
||||
}
|
||||
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
|
||||
->setUserId(Auth::id())
|
||||
->setUpdating($this->has('import-update'))
|
||||
->setUsernameFormat('firstname.lastname');
|
||||
|
||||
->setUsernameFormat('firstname.lastname')
|
||||
->setFieldMappings($fieldMappings);
|
||||
// $logFile = storage_path('logs/importer.log');
|
||||
// \Log::useFiles($logFile);
|
||||
$importer->import();
|
||||
return $this->errors;
|
||||
}
|
||||
|
||||
public function log($string)
|
||||
{
|
||||
return; // FUTURE IMPLEMENTATION
|
||||
// \Log::Info($string);
|
||||
}
|
||||
|
||||
public function progress($count)
|
||||
@@ -58,7 +71,6 @@ class ItemImportRequest extends FormRequest
|
||||
public function errorCallback($item, $field, $errorString)
|
||||
{
|
||||
$this->errors[$item->name][$field] = $errorString;
|
||||
// $this->errors[$item->name] = $errorString;
|
||||
}
|
||||
|
||||
private $errors;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Setting;
|
||||
|
||||
class SaveUserRequest extends Request
|
||||
{
|
||||
@@ -23,12 +24,38 @@ class SaveUserRequest extends Request
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:1',
|
||||
'email' => 'email',
|
||||
'password' => 'required|min:6',
|
||||
'password_confirm' => 'sometimes|required_with:password',
|
||||
'username' => 'required|string|min:2|unique:users,username,NULL,deleted_at',
|
||||
];
|
||||
|
||||
$rules = [];
|
||||
|
||||
switch($this->method())
|
||||
{
|
||||
|
||||
// Brand new asset
|
||||
case 'POST':
|
||||
{
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required_unless:ldap_import,1|string|min:1';
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('store');
|
||||
}
|
||||
|
||||
// Save all fields
|
||||
case 'PUT':
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required_unless:ldap_import,1|string|min:1';
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('update');
|
||||
|
||||
// Save only what's passed
|
||||
case 'PATCH':
|
||||
{
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('update');
|
||||
}
|
||||
|
||||
default:break;
|
||||
}
|
||||
|
||||
$rules['password_confirm'] = 'sometimes|required_with:password';
|
||||
|
||||
return $rules;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
50
app/Http/Requests/SettingsLdapRequest.php
Normal file
50
app/Http/Requests/SettingsLdapRequest.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use Session;
|
||||
|
||||
class SettingsLdapRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
"ldap_server" => 'sometimes|required_if:ldap_enabled,1|url|nullable',
|
||||
"ldap_uname" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_basedn" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_filter" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_username_field" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_fname_field" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_lname_field" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_auth_filter_query" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
"ldap_version" => 'sometimes|required_if:ldap_enabled,1|nullable',
|
||||
];
|
||||
|
||||
return $rules;
|
||||
|
||||
}
|
||||
|
||||
public function response(array $errors)
|
||||
{
|
||||
$this->session()->flash('errors', Session::get('errors', new \Illuminate\Support\ViewErrorBag)
|
||||
->put('default', new \Illuminate\Support\MessageBag($errors)));
|
||||
\Input::flash();
|
||||
return parent::response($errors);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class UpdateUserRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:1',
|
||||
'email' => 'email',
|
||||
'password_confirm' => 'sometimes|required_with:password',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -23,18 +23,20 @@ class AccessoriesTransformer
|
||||
$array = [
|
||||
'id' => $accessory->id,
|
||||
'name' => e($accessory->name),
|
||||
'company' => ($accessory->company) ? ['id' => $accessory->company->id,'name'=> e($accessory->company->name)] : '',
|
||||
'manufacturer' => ($accessory->manufacturer) ? ['id' => $accessory->manufacturer->id,'name'=> e($accessory->manufacturer->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)] : '',
|
||||
'location' => ($accessory->location) ? ['id' => $accessory->location->id,'name'=> e($accessory->location->name)] : '',
|
||||
'category' => ($accessory->category) ? ['id' => $accessory->category->id,'name'=> e($accessory->category->name)] : null,
|
||||
'location' => ($accessory->location) ? ['id' => $accessory->location->id,'name'=> e($accessory->location->name)] : null,
|
||||
'notes' => ($accessory->notes) ? e($accessory->notes) : null,
|
||||
'qty' => ($accessory->qty) ? e($accessory->qty) : null,
|
||||
'qty' => ($accessory->qty) ? (int) $accessory->qty : null,
|
||||
'purchase_date' => ($accessory->purchase_date) ? Helper::getFormattedDateObject($accessory->purchase_date, 'date') : null,
|
||||
'purchase_cost' => ($accessory->purchase_cost) ? e($accessory->purchase_cost) : null,
|
||||
'order_number' => ($accessory->order_number) ? e($accessory->order_number) : null,
|
||||
'min_qty' => ($accessory->min_amt) ? e($accessory->min_amt) : 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);
|
||||
}
|
||||
|
||||
|
||||
79
app/Http/Transformers/ActionlogsTransformer.php
Normal file
79
app/Http/Transformers/ActionlogsTransformer.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Setting;
|
||||
use Gate;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class ActionlogsTransformer
|
||||
{
|
||||
|
||||
public function transformActionlogs (Collection $actionlogs, $total)
|
||||
{
|
||||
$array = array();
|
||||
$settings = Setting::getSettings();
|
||||
foreach ($actionlogs as $actionlog) {
|
||||
$array[] = self::transformActionlog($actionlog, $settings);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformActionlog (Actionlog $actionlog, $settings = null)
|
||||
{
|
||||
$array = [
|
||||
'id' => (int) $actionlog->id,
|
||||
'icon' => $actionlog->present()->icon(),
|
||||
'image' => (method_exists($actionlog->item, 'getImageUrl')) ? $actionlog->item->getImageUrl() : null,
|
||||
'item' => ($actionlog->item) ? [
|
||||
'id' => (int) $actionlog->item->id,
|
||||
'name' => e($actionlog->item->getDisplayNameAttribute()),
|
||||
'type' => e($actionlog->itemType()),
|
||||
] : null,
|
||||
'location' => ($actionlog->location) ? [
|
||||
'id' => (int) $actionlog->location->id,
|
||||
'name' => e($actionlog->location->name)
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($actionlog->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($actionlog->updated_at, 'datetime'),
|
||||
'next_audit_date' => ($actionlog->itemType()=='asset') ? Helper::getFormattedDateObject($actionlog->calcNextAuditDate(), 'date'): null,
|
||||
'days_to_next_audit' => $actionlog->daysUntilNextAudit($settings->audit_interval, $actionlog->item),
|
||||
'action_type' => $actionlog->present()->actionType(),
|
||||
'admin' => ($actionlog->user) ? [
|
||||
'id' => (int) $actionlog->user->id,
|
||||
'name' => e($actionlog->user->getFullNameAttribute()),
|
||||
'first_name'=> e($actionlog->user->first_name),
|
||||
'last_name'=> e($actionlog->user->last_name)
|
||||
] : null,
|
||||
'target' => ($actionlog->target) ? [
|
||||
'id' => (int) $actionlog->target->id,
|
||||
'name' => ($actionlog->targetType()=='user') ? e($actionlog->target->getFullNameAttribute()) : e($actionlog->target->getDisplayNameAttribute()),
|
||||
'type' => e($actionlog->targetType()),
|
||||
] : null,
|
||||
|
||||
'note' => ($actionlog->note) ? e($actionlog->note): null,
|
||||
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
public function transformCheckedoutActionlog (Collection $accessories_users, $total)
|
||||
{
|
||||
|
||||
$array = array();
|
||||
foreach ($accessories_users as $user) {
|
||||
$array[] = (new UsersTransformer)->transformUser($user);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
54
app/Http/Transformers/AssetMaintenancesTransformer.php
Normal file
54
app/Http/Transformers/AssetMaintenancesTransformer.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Models\AssetMaintenance;
|
||||
use Gate;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class AssetMaintenancesTransformer
|
||||
{
|
||||
|
||||
public function transformAssetMaintenances (Collection $assetmaintenances, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($assetmaintenances as $assetmaintenance) {
|
||||
$array[] = self::transformAssetMaintenance($assetmaintenance);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformAssetMaintenance (AssetMaintenance $assetmaintenance)
|
||||
{
|
||||
$array = [
|
||||
'id' => (int) $assetmaintenance->id,
|
||||
'asset_name' => ($assetmaintenance->asset) ? ['id' => $assetmaintenance->asset->id,'name'=> e($assetmaintenance->asset->name)] : null,
|
||||
'title' => ($assetmaintenance->title) ? e($assetmaintenance->title) : null,
|
||||
'notes' => ($assetmaintenance->notes) ? e($assetmaintenance->notes) : null,
|
||||
'supplier' => ($assetmaintenance->supplier) ? ['id' => $assetmaintenance->supplier->id,'name'=> e($assetmaintenance->supplier->name)] : null,
|
||||
'cost' => Helper::formatCurrencyOutput($assetmaintenance->cost),
|
||||
'asset_maintenance_type' => e($assetmaintenance->asset_maintenance_type),
|
||||
'start_date' => Helper::getFormattedDateObject($assetmaintenance->start_date, 'datetime'),
|
||||
'asset_maintenance_time' => $assetmaintenance->asset_maintenance_time,
|
||||
'completion_date' => Helper::getFormattedDateObject($assetmaintenance->completion_date, 'datetime'),
|
||||
'user_id' => ($assetmaintenance->admin) ? ['id' => $assetmaintenance->admin->id,'name'=> e($assetmaintenance->admin->getFullNameAttribute())] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($assetmaintenance->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($assetmaintenance->updated_at, 'datetime'),
|
||||
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => (bool) Gate::allows('update', Asset::class),
|
||||
'delete' => (bool) Gate::allows('delete', Asset::class),
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Gate;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class AssetModelsTransformer
|
||||
{
|
||||
@@ -21,23 +22,40 @@ class AssetModelsTransformer
|
||||
{
|
||||
|
||||
$array = [
|
||||
'id' => $assetmodel->id,
|
||||
'id' => (int) $assetmodel->id,
|
||||
'name' => e($assetmodel->name),
|
||||
'manufacturer' => ($assetmodel->manufacturer_id) ? $assetmodel->manufacturer : null,
|
||||
'image' => ($assetmodel->image!='') ? url('/').'/uploads/models/'.e($assetmodel->image) : '',
|
||||
'manufacturer' => ($assetmodel->manufacturer) ? [
|
||||
'id' => (int) $assetmodel->manufacturer->id,
|
||||
'name'=> e($assetmodel->manufacturer->name)
|
||||
] : null,
|
||||
'image' => ($assetmodel->image!='') ? url('/').'/uploads/models/'.e($assetmodel->image) : null,
|
||||
'model_number' => e($assetmodel->model_number),
|
||||
'depreciation' => ($assetmodel->depreciation) ? $assetmodel->depreciation : 'No',
|
||||
'depreciation' => ($assetmodel->depreciation) ? [
|
||||
'id' => (int) $assetmodel->depreciation->id,
|
||||
'name'=> e($assetmodel->depreciation->name)
|
||||
] : null,
|
||||
'assets_count' => $assetmodel->assets_count,
|
||||
'category' => ($assetmodel->category_id) ? $assetmodel->category : null,
|
||||
'fieldset' => ($assetmodel->fieldset) ? $assetmodel->fieldset : null,
|
||||
'category' => ($assetmodel->category) ? [
|
||||
'id' => (int) $assetmodel->category->id,
|
||||
'name'=> e($assetmodel->category->name)
|
||||
] : null,
|
||||
'fieldset' => ($assetmodel->fieldset) ? [
|
||||
'id' => (int) $assetmodel->fieldset->id,
|
||||
'name'=> e($assetmodel->fieldset->name)
|
||||
] : null,
|
||||
'eol' => ($assetmodel->eol > 0) ? $assetmodel->eol .' months': 'None',
|
||||
'notes' => e($assetmodel->notes)
|
||||
'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('admin') ? true : false,
|
||||
'delete' => Gate::allows('admin') ? 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;
|
||||
|
||||
@@ -33,7 +33,8 @@ class AssetsTransformer
|
||||
'model_number' => ($asset->model) ? 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,
|
||||
@@ -43,6 +44,10 @@ class AssetsTransformer
|
||||
'id' => (int) $asset->model->manufacturer->id,
|
||||
'name'=> e($asset->model->manufacturer->name)
|
||||
] : null,
|
||||
'supplier' => ($asset->supplier) ? [
|
||||
'id' => (int) $asset->supplier->id,
|
||||
'name'=> e($asset->supplier->name)
|
||||
] : null,
|
||||
'notes' => e($asset->notes),
|
||||
'order_number' => e($asset->order_number),
|
||||
'company' => ($asset->company) ? [
|
||||
@@ -58,12 +63,7 @@ class AssetsTransformer
|
||||
'name'=> e($asset->defaultLoc->name)
|
||||
] : null,
|
||||
'image' => ($asset->getImageUrl()) ? $asset->getImageUrl() : null,
|
||||
'assigned_to' => ($asset->assigneduser) ? [
|
||||
'id' => (int) $asset->assigneduser->id,
|
||||
'name' => e($asset->assigneduser->getFullNameAttribute()),
|
||||
'first_name'=> e($asset->assigneduser->first_name),
|
||||
'last_name'=> e($asset->assigneduser->last_name)
|
||||
] : null,
|
||||
'assigned_to' => $this->transformAssignedTo($asset),
|
||||
'warranty' => ($asset->warranty_months > 0) ? e($asset->warranty_months . ' ' . trans('admin/hardware/form.months')) : null,
|
||||
'warranty_expires' => ($asset->warranty_months > 0) ? Helper::getFormattedDateObject($asset->warranty_expires, 'date') : null,
|
||||
'created_at' => Helper::getFormattedDateObject($asset->created_at, 'datetime'),
|
||||
@@ -75,22 +75,49 @@ class AssetsTransformer
|
||||
'user_can_checkout' => (bool) $asset->availableForCheckout(),
|
||||
];
|
||||
|
||||
|
||||
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()})) {
|
||||
$decrypted = \App\Helpers\Helper::gracefulDecrypt($field,$asset->{$field->convertUnicodeDbSlug()});
|
||||
$value = (Gate::allows('superadmin')) ? $decrypted : strtoupper(trans('admin/custom_fields/general.encrypted'));
|
||||
|
||||
// $fields_array = [$field->convertUnicodeDbSlug() => $value];
|
||||
|
||||
|
||||
$fields_array[$field->name] = [
|
||||
'field' => $field->convertUnicodeDbSlug(),
|
||||
'value' => $value
|
||||
];
|
||||
|
||||
} else {
|
||||
$fields_array[$field->name] = [
|
||||
'field' => $field->convertUnicodeDbSlug(),
|
||||
'value' => $asset->{$field->convertUnicodeDbSlug()}
|
||||
];
|
||||
//$fields_array = [$field->convertUnicodeDbSlug() => $asset->{$field->convertUnicodeDbSlug()}];
|
||||
|
||||
|
||||
}
|
||||
//array += $fields_array;
|
||||
$array['custom_fields'] = $fields_array;
|
||||
}
|
||||
} else {
|
||||
$array['custom_fields'] = array();
|
||||
}
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'checkout' => (bool) Gate::allows('checkout', Asset::class),
|
||||
'checkin' => (bool) Gate::allows('checkin', Asset::class),
|
||||
'clone' => Gate::allows('create', Asset::class) ? true : false,
|
||||
'update' => (bool) Gate::allows('update', Asset::class),
|
||||
'delete' => (bool) Gate::allows('delete', Asset::class),
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
if ($asset->model->fieldset) {
|
||||
foreach ($asset->model->fieldset->fields as $field) {
|
||||
$fields_array = [$field->name => $asset->{$field->convertUnicodeDbSlug()}];
|
||||
$array += $fields_array;
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
@@ -98,4 +125,24 @@ class AssetsTransformer
|
||||
{
|
||||
return (new DatatablesTransformer)->transformDatatables($assets);
|
||||
}
|
||||
|
||||
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),
|
||||
'type' => 'user'
|
||||
] : null;
|
||||
}
|
||||
return $asset->assignedTo ? [
|
||||
'id' => $asset->assignedTo->id,
|
||||
'name' => $asset->assignedTo->display_name,
|
||||
'type' => $asset->assignedType()
|
||||
] : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Gate;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class CategoriesTransformer
|
||||
{
|
||||
@@ -22,20 +23,23 @@ class CategoriesTransformer
|
||||
if ($category) {
|
||||
|
||||
$array = [
|
||||
'id' => e($category->id),
|
||||
'id' => (int) $category->id,
|
||||
'name' => e($category->name),
|
||||
'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,
|
||||
'accessories_count' => $category->accessories_count,
|
||||
'consumables_count' => $category->consumables_count,
|
||||
'components_count' => $category->components_count,
|
||||
'created_at' => Helper::getFormattedDateObject($category->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($category->updated_at, 'datetime'),
|
||||
];
|
||||
|
||||
$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;
|
||||
|
||||
53
app/Http/Transformers/CompaniesTransformer.php
Normal file
53
app/Http/Transformers/CompaniesTransformer.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Models\Company;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Gate;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class CompaniesTransformer
|
||||
{
|
||||
|
||||
public function transformCompanies (Collection $companies, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($companies as $company) {
|
||||
$array[] = self::transformCompany($company);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformCompany (Company $company = null)
|
||||
{
|
||||
if ($company) {
|
||||
|
||||
$array = [
|
||||
'id' => (int) $company->id,
|
||||
'name' => e($company->name),
|
||||
"created_at" => Helper::getFormattedDateObject($company->created_at, 'datetime'),
|
||||
"updated_at" => Helper::getFormattedDateObject($company->updated_at, 'datetime'),
|
||||
"assets_count" => (int) $company->assets_count,
|
||||
"licenses_count" => (int) $company->licenses_count,
|
||||
"accessories_count" => (int) $company->accessories_count,
|
||||
"consumables_count" => (int) $company->consumables_count,
|
||||
"components_count" => (int) $company->components_count,
|
||||
"users_count" => (int) $company->users_count
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Company::class) ? true : false,
|
||||
'delete' => Gate::allows('delete', Company::class) ? true : false,
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -27,8 +27,8 @@ class ComponentsTransformer
|
||||
'id' => (int) $component->location->id,
|
||||
'name' => e($component->location->name)
|
||||
] : null,
|
||||
'qty' => number_format($component->qty),
|
||||
'min_amt' => e($component->min_amt),
|
||||
'qty' => ($component->qty!='') ? (int) $component->qty : null,
|
||||
'min_amt' => ($component->min_amt!='') ? (int) $component->min_amt : null,
|
||||
'category' => ($component->category) ? [
|
||||
'id' => (int) $component->category->id,
|
||||
'name' => e($component->category->name)
|
||||
@@ -43,6 +43,7 @@ class ComponentsTransformer
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($component->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($component->updated_at, 'datetime'),
|
||||
'user_can_checkout' => ($component->numRemaining() > 0) ? 1 : 0,
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
@@ -57,12 +58,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,20 +21,20 @@ class ConsumablesTransformer
|
||||
public function transformConsumable (Consumable $consumable)
|
||||
{
|
||||
$array = [
|
||||
'category' => ($consumable->category) ? ['id' => $consumable->category->id, 'name' => $consumable->category->name] : null,
|
||||
'company' => ($consumable->company) ? ['id' => $consumable->company->id, 'name' => $consumable->company->name] : null,
|
||||
'id' => $consumable->id,
|
||||
'item_no' => $consumable->item_no,
|
||||
'location' => ($consumable->location) ? ['id' => $consumable->location->id, 'name' => $consumable->location->name] : null,
|
||||
'manufacturer' => ($consumable->manufacturer) ? ['id' => $consumable->manufacturer->id, 'name' => $consumable->manufacturer->name] : null,
|
||||
'min_amt' => $consumable->min_amt,
|
||||
'model_number' => $consumable->model_number,
|
||||
'name' => $consumable->name,
|
||||
'id' => (int) $consumable->id,
|
||||
'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),
|
||||
'location' => ($consumable->location) ? ['id' => (int) $consumable->location->id, 'name' => e($consumable->location->name)] : null,
|
||||
'manufacturer' => ($consumable->manufacturer) ? ['id' => (int) $consumable->manufacturer->id, 'name' => e($consumable->manufacturer->name)] : null,
|
||||
'min_amt' => (int) $consumable->min_amt,
|
||||
'model_number' => e($consumable->model_number),
|
||||
'name' => e($consumable->name),
|
||||
'remaining' => $consumable->numRemaining(),
|
||||
'order_number' => $consumable->order_number,
|
||||
'order_number' => e($consumable->order_number),
|
||||
'purchase_cost' => Helper::formatCurrencyOutput($consumable->purchase_cost),
|
||||
'purchase_date' => Helper::getFormattedDateObject($consumable->purchase_date, 'date'),
|
||||
'qty' => $consumable->qty,
|
||||
'qty' => (int) $consumable->qty,
|
||||
'created_at' => Helper::getFormattedDateObject($consumable->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($consumable->updated_at, 'datetime'),
|
||||
];
|
||||
|
||||
36
app/Http/Transformers/CustomFieldsTransformer.php
Normal file
36
app/Http/Transformers/CustomFieldsTransformer.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Models\CustomField;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use App\Helpers\Helper;
|
||||
use Gate;
|
||||
|
||||
class CustomFieldsTransformer
|
||||
{
|
||||
|
||||
public function transformCustomFields (Collection $fields, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($fields as $field) {
|
||||
$array[] = self::transformCustomField($field);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformCustomField (CustomField $field)
|
||||
{
|
||||
|
||||
$array = [
|
||||
'name' => e($field->name),
|
||||
'db_column_name' => e($field->db_column_name()),
|
||||
'format' => e($field->format),
|
||||
'required' => $field->pivot ? $field->pivot->required : false,
|
||||
'created_at' => Helper::getFormattedDateObject($field->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($field->updated_at, 'datetime'),
|
||||
];
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
47
app/Http/Transformers/CustomFieldsetsTransformer.php
Normal file
47
app/Http/Transformers/CustomFieldsetsTransformer.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Models\CustomFieldset;
|
||||
use App\Models\CustomField;
|
||||
use App\Models\AssetModel;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use App\Helpers\Helper;
|
||||
use Gate;
|
||||
|
||||
class CustomFieldsetsTransformer
|
||||
{
|
||||
|
||||
public function transformCustomFieldsets (Collection $fieldsets, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($fieldsets as $fieldset) {
|
||||
$array[] = self::transformCustomFieldset($fieldset);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformCustomFieldset (CustomFieldset $fieldset)
|
||||
{
|
||||
$fields = $fieldset->fields;
|
||||
$models = $fieldset->models;
|
||||
$modelsArray = array();
|
||||
|
||||
foreach ($models as $model)
|
||||
{
|
||||
$modelsArray[] = [
|
||||
'id' => $model->id,
|
||||
'name' => e($model->name)
|
||||
];
|
||||
}
|
||||
|
||||
$array = [
|
||||
'id' => (int) $fieldset->id,
|
||||
'name' => e($fieldset->name),
|
||||
'fields' => (new CustomFieldsTransformer)->transformCustomFields($fields, $fieldset->fields_count),
|
||||
'models' => (new DatatablesTransformer)->transformDatatables($modelsArray, $fieldset->models_count),
|
||||
'created_at' => Helper::getFormattedDateObject($fieldset->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($fieldset->updated_at, 'datetime'),
|
||||
];
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
62
app/Http/Transformers/DepartmentsTranformer.php
Normal file
62
app/Http/Transformers/DepartmentsTranformer.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Models\Department;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Gate;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class DepartmentsTransformer
|
||||
{
|
||||
|
||||
public function transformDepartments (Collection $departments, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($departments as $department) {
|
||||
$array[] = self::transformDepartment($department);
|
||||
}
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformDepartment (Department $department = null)
|
||||
{
|
||||
if ($department) {
|
||||
|
||||
$array = [
|
||||
'id' => (int) $department->id,
|
||||
'name' => e($department->name),
|
||||
'company' => ($department->company) ? [
|
||||
'id' => (int) $department->company->id,
|
||||
'name'=> e($department->company->name)
|
||||
] : null,
|
||||
'manager' => ($department->manager) ? [
|
||||
'id' => (int) $department->manager->id,
|
||||
'name' => e($department->manager->getFullNameAttribute()),
|
||||
'first_name'=> e($department->manager->first_name),
|
||||
'last_name'=> e($department->manager->last_name)
|
||||
] : null,
|
||||
'location' => ($department->location) ? [
|
||||
'id' => (int) $department->location->id,
|
||||
'name' => e($department->location->name)
|
||||
] : null,
|
||||
'users_count' => e($department->users_count),
|
||||
'created_at' => Helper::getFormattedDateObject($department->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($department->updated_at, 'datetime'),
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Department::class) ? true : false,
|
||||
'delete' => Gate::allows('delete', Department::class) ? true : false,
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class DepreciationsTransformer
|
||||
public function transformDepreciation (Depreciation $depreciation)
|
||||
{
|
||||
$array = [
|
||||
'id' => e($depreciation->id),
|
||||
'id' => (int) $depreciation->id,
|
||||
'name' => e($depreciation->name),
|
||||
'months' => $depreciation->months . ' '. trans('general.months'),
|
||||
'created_at' => Helper::getFormattedDateObject($depreciation->created_at, 'datetime'),
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Http\Transformers;
|
||||
use App\Models\Group;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Gate;
|
||||
use App\Helpers\Helper;
|
||||
|
||||
class GroupsTransformer
|
||||
{
|
||||
@@ -20,10 +21,10 @@ class GroupsTransformer
|
||||
public function transformGroup (Group $group)
|
||||
{
|
||||
$array = [
|
||||
'id' => e($group->id),
|
||||
'id' => (int) $group->id,
|
||||
'name' => e($group->name),
|
||||
'permissions' => $group->permissions,
|
||||
'users_count' => $group->users_count,
|
||||
'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'),
|
||||
];
|
||||
|
||||
@@ -20,13 +20,15 @@ class ImportsTransformer
|
||||
public function transformImport(Import $import)
|
||||
{
|
||||
$array = [
|
||||
'id' => $import->id,
|
||||
'file_path' => $import->file_path,
|
||||
'id' => (int) $import->id,
|
||||
'file_path' => e($import->file_path),
|
||||
'filesize' => Setting::fileSizeConvert($import->filesize),
|
||||
'name' => $import->name,
|
||||
'import_type' => $import->import_type,
|
||||
'name' => e($import->name),
|
||||
'import_type' => e($import->import_type),
|
||||
'created_at' => $import->created_at->diffForHumans(),
|
||||
|
||||
'header_row' => $import->header_row,
|
||||
'first_row' => $import->first_row,
|
||||
'field_map' => $import->field_map,
|
||||
];
|
||||
|
||||
return $array;
|
||||
|
||||
@@ -21,32 +21,35 @@ class LicensesTransformer
|
||||
public function transformLicense (License $license)
|
||||
{
|
||||
$array = [
|
||||
'id' => $license->id,
|
||||
'id' => (int) $license->id,
|
||||
'name' => e($license->name),
|
||||
'company' => ($license->company) ? ['id' => $license->company->id,'name'=> e($license->company->name)] : null,
|
||||
'manufacturer' => ($license->manufacturer) ? ['id' => $license->manufacturer->id,'name'=> e($license->manufacturer->name)] : null,
|
||||
'company' => ($license->company) ? ['id' => (int) $license->company->id,'name'=> e($license->company->name)] : null,
|
||||
'manufacturer' => ($license->manufacturer) ? ['id' => (int) $license->manufacturer->id,'name'=> e($license->manufacturer->name)] : null,
|
||||
'product_key' => e($license->serial),
|
||||
'order_number' => e($license->order_number),
|
||||
'purchase_order' => e($license->purchase_order),
|
||||
'purchase_date' => Helper::getFormattedDateObject($license->purchase_date, 'date'),
|
||||
'purchase_cost' => e($license->purchase_cost),
|
||||
'depreciation' => ($license->depreciation) ? ['id' => $license->depreciation->id,'name'=> e($license->depreciation->name)] : null,
|
||||
'depreciation' => ($license->depreciation) ? ['id' => (int) $license->depreciation->id,'name'=> e($license->depreciation->name)] : null,
|
||||
'notes' => e($license->notes),
|
||||
'expiration_date' => Helper::getFormattedDateObject($license->expiration_date, 'date'),
|
||||
'total_seats' => e($license->seats),
|
||||
'remaining_qty' => $license->remaincount(),
|
||||
'total_seats' => (int) $license->seats,
|
||||
'next_seat' => ($license->freeSeat()) ? (int) $license->freeSeat()->id : null,
|
||||
'remaining_qty' => (int) $license->remaincount(),
|
||||
'min_qty' => $license->remaincount(),
|
||||
'license_name' => e($license->license_name),
|
||||
'license_email' => e($license->license_email),
|
||||
'maintained' => ($license->maintained == 1) ? true : false,
|
||||
'supplier' => ($license->supplier) ? ['id' => $license->supplier->id,'name'=> e($license->supplier->name)] : null,
|
||||
'supplier' => ($license->supplier) ? ['id' => (int) $license->supplier->id,'name'=> e($license->supplier->name)] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($license->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($license->updated_at, 'datetime'),
|
||||
'user_can_checkout' => (bool) ($license->remaincount() > 0),
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'checkout' => Gate::allows('checkout', License::class) ? true : false,
|
||||
'checkin' => Gate::allows('checkin', License::class) ? true : false,
|
||||
'clone' => Gate::allows('create', License::class) ? true : false,
|
||||
'update' => Gate::allows('update', License::class) ? true : false,
|
||||
'delete' => Gate::allows('delete', License::class) ? true : false,
|
||||
];
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Helpers\Helper;
|
||||
class LocationsTransformer
|
||||
{
|
||||
|
||||
public function transformLocations (Collection $locations, $total)
|
||||
public function transformLocations(Collection $locations, $total)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($locations as $location) {
|
||||
@@ -18,27 +18,39 @@ class LocationsTransformer
|
||||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformLocation (Location $location = null)
|
||||
public function transformLocation(Location $location = null)
|
||||
{
|
||||
if ($location) {
|
||||
|
||||
$assets_arr = [];
|
||||
foreach($location->assets() as $asset) {
|
||||
$assets_arr = ['id' => $asset->id];
|
||||
$children_arr = [];
|
||||
foreach($location->childLocations as $child) {
|
||||
$children_arr[] = [
|
||||
'id' => (int) $child->id,
|
||||
'name' => $child->name
|
||||
];
|
||||
}
|
||||
|
||||
$array = [
|
||||
'id' => e($location->id),
|
||||
'id' => (int) $location->id,
|
||||
'name' => e($location->name),
|
||||
'address' => e($location->address),
|
||||
'city' => e($location->city),
|
||||
'state' => e($location->state),
|
||||
'assets_checkedout' => $location->assets()->count(),
|
||||
'assets_default' => $location->assignedassets()->count(),
|
||||
'country' => e($location->country),
|
||||
'assets' => $assets_arr,
|
||||
'zip' => e($location->zip),
|
||||
'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'),
|
||||
'parent' => ($location->parent) ? [
|
||||
'id' => (int) $location->parent->id,
|
||||
'name'=> e($location->parent->name)
|
||||
] : null,
|
||||
'manager' => ($location->manager) ? (new UsersTransformer)->transformUser($location->manager) : null,
|
||||
|
||||
|
||||
'children' => $children_arr,
|
||||
];
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user