mirror of
https://github.com/grokability/snipe-it.git
synced 2026-03-12 17:52:00 +08:00
Compare commits
882 Commits
add-scim-u
...
e4d7e08902
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4d7e08902 | ||
|
|
428095b71b | ||
|
|
411ffb12ca | ||
|
|
3b93193da1 | ||
|
|
224a813f25 | ||
|
|
7d079f74a1 | ||
|
|
4ca53e6f70 | ||
|
|
70d1ffe294 | ||
|
|
335e1a7e18 | ||
|
|
287481a44e | ||
|
|
2dd09f9702 | ||
|
|
9317d6551d | ||
|
|
ed3d30e343 | ||
|
|
ca5a25f703 | ||
|
|
692a9ebebf | ||
|
|
bf314a0f84 | ||
|
|
c8c2bb6709 | ||
|
|
3fc8b976fc | ||
|
|
6b9dc97fa1 | ||
|
|
4f3a30261e | ||
|
|
e7c478318c | ||
|
|
e75860c6ee | ||
|
|
d0dbd1e561 | ||
|
|
e7eb4f0e80 | ||
|
|
676a995889 | ||
|
|
a44fe14de1 | ||
|
|
0015dbcd1d | ||
|
|
fc5e7cccbc | ||
|
|
8987f3f951 | ||
|
|
ba671a8f1f | ||
|
|
fbe871f8d1 | ||
|
|
116b2d1229 | ||
|
|
20fd870b59 | ||
|
|
5c46990195 | ||
|
|
fab57020f2 | ||
|
|
b37074f473 | ||
|
|
24e2e81a28 | ||
|
|
ccabc1fbcc | ||
|
|
f847f83cb8 | ||
|
|
e0771827aa | ||
|
|
fa6adaa155 | ||
|
|
f3504ce6fc | ||
|
|
a075ca904b | ||
|
|
e3fb6fabf8 | ||
|
|
6f89af790e | ||
|
|
28f493d84d | ||
|
|
a87e862148 | ||
|
|
6e264bfee0 | ||
|
|
1ecf862f2d | ||
|
|
338fc88095 | ||
|
|
0a724cc49a | ||
|
|
a2efcf1ca9 | ||
|
|
c9d73e85e1 | ||
|
|
a956676745 | ||
|
|
5800d08202 | ||
|
|
b8958bad72 | ||
|
|
0508d7558e | ||
|
|
98c3192a13 | ||
|
|
b886e11670 | ||
|
|
92bb1df82e | ||
|
|
1c4549dd8e | ||
|
|
83e61ec8cd | ||
|
|
7ea549df4a | ||
|
|
af1c55cd7e | ||
|
|
7822c0bc3e | ||
|
|
2b7ed1f7fa | ||
|
|
45ddaf1b72 | ||
|
|
7595c922fa | ||
|
|
4d4513d936 | ||
|
|
e378c99923 | ||
|
|
078c870970 | ||
|
|
4a91d37423 | ||
|
|
96befb2aef | ||
|
|
925452e106 | ||
|
|
1678330f0c | ||
|
|
58cf3fc2ea | ||
|
|
13ce17ffc6 | ||
|
|
70e020ee0c | ||
|
|
c6a167ef40 | ||
|
|
420ba5f261 | ||
|
|
7aa1f3ae1d | ||
|
|
556d638136 | ||
|
|
c4aa10baf8 | ||
|
|
86f647e714 | ||
|
|
64f5d40fd9 | ||
|
|
1a0869c2ca | ||
|
|
1fb32ee461 | ||
|
|
68a863e63e | ||
|
|
a1e62ccd46 | ||
|
|
dae66c0fa4 | ||
|
|
1d6b21e1c7 | ||
|
|
455be12058 | ||
|
|
2ebb3ecb96 | ||
|
|
b29056dddf | ||
|
|
3ed09f304c | ||
|
|
4875283ed1 | ||
|
|
261231c09e | ||
|
|
180dad6ee6 | ||
|
|
d7121ad82f | ||
|
|
f121c61524 | ||
|
|
93bf91869b | ||
|
|
2ed32612b9 | ||
|
|
314bcbe208 | ||
|
|
6290e34623 | ||
|
|
5e5521a128 | ||
|
|
1e8bed86d3 | ||
|
|
8bc7d50e35 | ||
|
|
aa420e5006 | ||
|
|
4babaa85fc | ||
|
|
378d9e008e | ||
|
|
340fabe4f6 | ||
|
|
29331b8b06 | ||
|
|
6fbcaa0959 | ||
|
|
52e10205c5 | ||
|
|
f419ae3f4a | ||
|
|
84a6b8e012 | ||
|
|
f234aee691 | ||
|
|
623d516595 | ||
|
|
156eaf53d5 | ||
|
|
678a7c1437 | ||
|
|
ce2a760093 | ||
|
|
34b02d8534 | ||
|
|
42e0e691dd | ||
|
|
ccfda99060 | ||
|
|
57f02bdc57 | ||
|
|
7056656eab | ||
|
|
2d899fc772 | ||
|
|
80ee0835aa | ||
|
|
7b7e6c7971 | ||
|
|
025fb30335 | ||
|
|
fcace4a192 | ||
|
|
619e1c70ea | ||
|
|
7a95bdfba6 | ||
|
|
89962de161 | ||
|
|
d9328bd0ce | ||
|
|
81306df06a | ||
|
|
75abe9eb3e | ||
|
|
1f26bf1125 | ||
|
|
14b9c06d77 | ||
|
|
4f3d23d1ef | ||
|
|
cada43f34d | ||
|
|
9188f89a2a | ||
|
|
1cc7ef0543 | ||
|
|
a86ffc29d1 | ||
|
|
9ed5540c49 | ||
|
|
3a7e00ccc3 | ||
|
|
f82cdabccd | ||
|
|
b9c9cc0046 | ||
|
|
27ece84d52 | ||
|
|
1299186fb8 | ||
|
|
d837e4845b | ||
|
|
39be0c5590 | ||
|
|
d2bb10e96d | ||
|
|
f139a616c7 | ||
|
|
d5099d973b | ||
|
|
82b18a3207 | ||
|
|
10aee6bb5f | ||
|
|
c1b11ab9bf | ||
|
|
c226a061f5 | ||
|
|
c0be738aef | ||
|
|
e6987ec148 | ||
|
|
973fa7a58b | ||
|
|
b6195ba3ae | ||
|
|
d3bd213f29 | ||
|
|
9502dd8bd7 | ||
|
|
e81ccf4280 | ||
|
|
9730f2c0f3 | ||
|
|
1de34c0656 | ||
|
|
bdce6b1387 | ||
|
|
ce0c2ecd8f | ||
|
|
40f07e3d72 | ||
|
|
3c3ccae7c9 | ||
|
|
be211f6f86 | ||
|
|
9789ca42f8 | ||
|
|
da26bc5165 | ||
|
|
0b67626961 | ||
|
|
546c8ce7d5 | ||
|
|
c76a888d11 | ||
|
|
38c495a4ac | ||
|
|
d0ce5e0c57 | ||
|
|
7a0e5b57db | ||
|
|
c31f1d2cce | ||
|
|
ea98ee07e5 | ||
|
|
a38bfada57 | ||
|
|
e5ff19aec4 | ||
|
|
504f63066f | ||
|
|
41b327529b | ||
|
|
e84279c402 | ||
|
|
65e6519f97 | ||
|
|
dbbb3beacc | ||
|
|
e8a73a8de6 | ||
|
|
411cbc0962 | ||
|
|
b487c0e3e9 | ||
|
|
fa0e8f6e01 | ||
|
|
e25e405f74 | ||
|
|
302c4a6414 | ||
|
|
d1e7f6e55e | ||
|
|
d12f0974df | ||
|
|
b751fe7903 | ||
|
|
a6e34522eb | ||
|
|
735e6f3471 | ||
|
|
c9f41c950a | ||
|
|
091c710940 | ||
|
|
276f412a3c | ||
|
|
6f6e5c847a | ||
|
|
6ef0274bb3 | ||
|
|
7ef6a72ec4 | ||
|
|
e2b8c69cf6 | ||
|
|
1254d12d83 | ||
|
|
b68642a827 | ||
|
|
c5214b976b | ||
|
|
e611121244 | ||
|
|
3aa7f0b7fe | ||
|
|
3d38eee71d | ||
|
|
90e6e309f9 | ||
|
|
885314b87a | ||
|
|
ef013a7026 | ||
|
|
0353ade90e | ||
|
|
d90c9282ac | ||
|
|
5055aafe1d | ||
|
|
e68b9ea267 | ||
|
|
1d8ba2ec61 | ||
|
|
d56970eaa3 | ||
|
|
8b3f18ec59 | ||
|
|
170d20ddb5 | ||
|
|
70407dac85 | ||
|
|
c2334d87de | ||
|
|
0662e3351e | ||
|
|
6b90b3743e | ||
|
|
dd1d456106 | ||
|
|
dceead8302 | ||
|
|
832f449868 | ||
|
|
33a104f142 | ||
|
|
28f19689ec | ||
|
|
ce6ee32e89 | ||
|
|
fdf42ba321 | ||
|
|
aadd158108 | ||
|
|
d6592819e8 | ||
|
|
8f34c06196 | ||
|
|
9cdc73917b | ||
|
|
2976159499 | ||
|
|
e302ccf985 | ||
|
|
08915e8607 | ||
|
|
32b2131bff | ||
|
|
50cf15fb71 | ||
|
|
f07ef6d7c5 | ||
|
|
666025d7f6 | ||
|
|
671601365c | ||
|
|
263b04cd69 | ||
|
|
57b98ca782 | ||
|
|
46df19d7cd | ||
|
|
fa18524223 | ||
|
|
3ebc0532ca | ||
|
|
4f59752b8b | ||
|
|
668ab221cc | ||
|
|
ad90e005c4 | ||
|
|
952b3d6884 | ||
|
|
19ca1f7578 | ||
|
|
ef02fab94b | ||
|
|
144b5e7558 | ||
|
|
aff0a60138 | ||
|
|
92a641f01a | ||
|
|
929132ba07 | ||
|
|
2a1a4a1c72 | ||
|
|
4d73894cd2 | ||
|
|
e49e805b2b | ||
|
|
05f3bf633e | ||
|
|
4d5b3548d6 | ||
|
|
00408f0103 | ||
|
|
548cceee18 | ||
|
|
7eb536f80e | ||
|
|
d91ce88e9a | ||
|
|
76d1a20e21 | ||
|
|
5b6951b88d | ||
|
|
56313e4436 | ||
|
|
7810ae74d1 | ||
|
|
3ac1012757 | ||
|
|
91aec08ce0 | ||
|
|
30970cc7f2 | ||
|
|
985c027b04 | ||
|
|
d1c4b055a9 | ||
|
|
3f2f508e49 | ||
|
|
07513cb559 | ||
|
|
66022902b7 | ||
|
|
613efe963a | ||
|
|
5a0affcd8e | ||
|
|
79150edb92 | ||
|
|
6cca24be8e | ||
|
|
c2ca51e8ef | ||
|
|
b9908d5665 | ||
|
|
cbca420217 | ||
|
|
017183e3fe | ||
|
|
0236527f05 | ||
|
|
e946c4bf8c | ||
|
|
8a0414cef6 | ||
|
|
ee1ad692a4 | ||
|
|
fdd5f6b0e1 | ||
|
|
dca6df3244 | ||
|
|
0874b853a0 | ||
|
|
3393916b5e | ||
|
|
b2728b4eb1 | ||
|
|
f3cc3ed682 | ||
|
|
f8cfb8833f | ||
|
|
c2c2332e83 | ||
|
|
9f69c36426 | ||
|
|
ea9de35a3b | ||
|
|
a50a16fb01 | ||
|
|
f27c0206de | ||
|
|
6791ddd911 | ||
|
|
ce95060d60 | ||
|
|
6d9bbe1ddf | ||
|
|
5b1507f4b7 | ||
|
|
53e985aaab | ||
|
|
f5c2119122 | ||
|
|
5fd6918948 | ||
|
|
7423d13bdd | ||
|
|
fb8586f186 | ||
|
|
8b9ebf736b | ||
|
|
5abcdb8c5a | ||
|
|
e549f67fcc | ||
|
|
d68576c2fa | ||
|
|
a6042b6a03 | ||
|
|
d1a3afd992 | ||
|
|
34b00f7dba | ||
|
|
14b6c6861f | ||
|
|
fe4bb4209c | ||
|
|
e997eb2012 | ||
|
|
8337473f5a | ||
|
|
7ada7fb327 | ||
|
|
9d632e39bf | ||
|
|
1f50eada6d | ||
|
|
38e1114dad | ||
|
|
11be73a578 | ||
|
|
13a00df73c | ||
|
|
7739690bf5 | ||
|
|
389eb9e05d | ||
|
|
98fe94aa24 | ||
|
|
4ee378bf8e | ||
|
|
a8c268760b | ||
|
|
c684b8ab1e | ||
|
|
333d0e2391 | ||
|
|
c22c5993fc | ||
|
|
1c239cc7cf | ||
|
|
6ee5aa3e12 | ||
|
|
0d5ceb1e90 | ||
|
|
166a241761 | ||
|
|
f6f5e806e4 | ||
|
|
f0f42240f3 | ||
|
|
686afc0974 | ||
|
|
5d085469ec | ||
|
|
7c54429c13 | ||
|
|
8dfd04573e | ||
|
|
7e5fb3c9ae | ||
|
|
65e4c0b8d1 | ||
|
|
b1301237f1 | ||
|
|
cf82c12708 | ||
|
|
52f8697d91 | ||
|
|
1aee8679d2 | ||
|
|
3169c5b503 | ||
|
|
741f0d69ab | ||
|
|
8829ea9b29 | ||
|
|
53b283eac5 | ||
|
|
1234b6297e | ||
|
|
6ba99e8199 | ||
|
|
b4eb603f22 | ||
|
|
62f9ce979d | ||
|
|
f5928fc707 | ||
|
|
f7040e3616 | ||
|
|
a70f1cc1ef | ||
|
|
a86b738231 | ||
|
|
8a9ddba208 | ||
|
|
4c727966e7 | ||
|
|
c2ac53029a | ||
|
|
5d300d85bd | ||
|
|
1dc181797b | ||
|
|
30d932e2e0 | ||
|
|
9fb32d33af | ||
|
|
70baa60521 | ||
|
|
8ea2784d44 | ||
|
|
2b56d82577 | ||
|
|
8ff34baafa | ||
|
|
eeae534a37 | ||
|
|
8b71049a3d | ||
|
|
373361dab0 | ||
|
|
60a1141b9d | ||
|
|
a38c8a0235 | ||
|
|
c39d165a3d | ||
|
|
2238f8e8ad | ||
|
|
e0c53c3ead | ||
|
|
1074bc2d3b | ||
|
|
4b22b1c115 | ||
|
|
141794caf7 | ||
|
|
d5997e2394 | ||
|
|
429ca8dd34 | ||
|
|
c2ad0defe0 | ||
|
|
b4658f2696 | ||
|
|
11b7dfc9b0 | ||
|
|
f7b7ef850d | ||
|
|
bb9b145519 | ||
|
|
d75f5b8fd3 | ||
|
|
34fe64b27c | ||
|
|
2151595b45 | ||
|
|
b2c94386b3 | ||
|
|
b99ae9be88 | ||
|
|
ffbc831071 | ||
|
|
302a60fbe7 | ||
|
|
3ec8ba01d0 | ||
|
|
2048eb7d5a | ||
|
|
4d605927f3 | ||
|
|
b7ee3a2f1d | ||
|
|
44fa9e2d1e | ||
|
|
a5e818f970 | ||
|
|
066cf81233 | ||
|
|
1b4552cf30 | ||
|
|
0ba8ee1c5f | ||
|
|
5c4f3a5aec | ||
|
|
c963c0b25b | ||
|
|
b3a4fb2676 | ||
|
|
0b82902248 | ||
|
|
e7f70ccd1f | ||
|
|
683395599f | ||
|
|
755d7c2351 | ||
|
|
17d91bcd8e | ||
|
|
2633ec10dc | ||
|
|
c4f772c8d9 | ||
|
|
18addf2a87 | ||
|
|
eee826248d | ||
|
|
96a817753c | ||
|
|
600b06e66b | ||
|
|
cd680daa4c | ||
|
|
315b716e87 | ||
|
|
b2f1966a78 | ||
|
|
6305f87037 | ||
|
|
ab02b67d3c | ||
|
|
0f4086eaf0 | ||
|
|
e7c5329e57 | ||
|
|
ad82ea86c8 | ||
|
|
c310e1e3b7 | ||
|
|
aaf9372474 | ||
|
|
2cf169359e | ||
|
|
7f67f8c20d | ||
|
|
5607dfcecb | ||
|
|
ca99f525c9 | ||
|
|
7e92517d13 | ||
|
|
1ebb67b2e7 | ||
|
|
d9ef7b43b0 | ||
|
|
c074fae885 | ||
|
|
c5ada0fc2f | ||
|
|
5268b0f67f | ||
|
|
7e10089c13 | ||
|
|
1dab36da2d | ||
|
|
fab50e53b8 | ||
|
|
10cfe6d37a | ||
|
|
3718ce9749 | ||
|
|
fd39c8bf11 | ||
|
|
2e122fa8d8 | ||
|
|
66d85d17d9 | ||
|
|
61bc570d59 | ||
|
|
62dbd400a4 | ||
|
|
74af52d29d | ||
|
|
59f377b058 | ||
|
|
949f65b210 | ||
|
|
4046fbae89 | ||
|
|
da8776c2f1 | ||
|
|
4043df1d02 | ||
|
|
3bc5ab593a | ||
|
|
6dad0d669f | ||
|
|
39f581a826 | ||
|
|
2034b25b25 | ||
|
|
468a7aa911 | ||
|
|
ec50643d96 | ||
|
|
3b98fb666f | ||
|
|
f17eeed579 | ||
|
|
452d0b6f6e | ||
|
|
41450b6e1b | ||
|
|
30029462b1 | ||
|
|
e109879cac | ||
|
|
90ad4e9abf | ||
|
|
fd0e2b1a96 | ||
|
|
19d637efea | ||
|
|
6c18b35276 | ||
|
|
184eddb5cf | ||
|
|
1d577b0171 | ||
|
|
05c998227a | ||
|
|
53ed810d86 | ||
|
|
7c136b6f57 | ||
|
|
4e510d9d8c | ||
|
|
e1f30f96c9 | ||
|
|
146d0cefc0 | ||
|
|
0103bd58e1 | ||
|
|
dbc1e7d6ab | ||
|
|
ea706863b5 | ||
|
|
04f4f5b57c | ||
|
|
98b9246c10 | ||
|
|
1e158721ee | ||
|
|
ab4eefcac2 | ||
|
|
cf3b36f124 | ||
|
|
8da01b8569 | ||
|
|
c90afaa312 | ||
|
|
9f20bb89c1 | ||
|
|
dfe664b779 | ||
|
|
88bd1fd6ef | ||
|
|
33f8823edb | ||
|
|
06d5c0a86c | ||
|
|
e12a5eda01 | ||
|
|
b3c59b2cc3 | ||
|
|
24d5969ce8 | ||
|
|
6ad42a02ad | ||
|
|
90b1ee4805 | ||
|
|
0c9d5ca9da | ||
|
|
e05ecd0c3e | ||
|
|
441657cbfb | ||
|
|
0fb6b02fc4 | ||
|
|
f83df0d651 | ||
|
|
e667cd20a8 | ||
|
|
d06c56367f | ||
|
|
039b4cf19f | ||
|
|
ca0961bd49 | ||
|
|
79528fa87b | ||
|
|
d96d0b1bcb | ||
|
|
02c237404e | ||
|
|
c56f5282ff | ||
|
|
d62f10cb46 | ||
|
|
4c6f123cda | ||
|
|
b0b1829426 | ||
|
|
68b590c263 | ||
|
|
b45efddd9a | ||
|
|
d8f5d8c6ec | ||
|
|
56baa8ac9f | ||
|
|
15aa64ed28 | ||
|
|
6d0bfeb420 | ||
|
|
ceff334420 | ||
|
|
4ee2db68fc | ||
|
|
1f04d0023b | ||
|
|
4427fdcaec | ||
|
|
4de642c6a4 | ||
|
|
d3eb89a97c | ||
|
|
d7362a3785 | ||
|
|
26347ac41e | ||
|
|
b396da3f33 | ||
|
|
306a0bf6de | ||
|
|
8000e274c6 | ||
|
|
5d91e0fa0a | ||
|
|
eb41247f2d | ||
|
|
d53eafe87a | ||
|
|
e48c40e5af | ||
|
|
df51318fb9 | ||
|
|
065c17002e | ||
|
|
0e46a54013 | ||
|
|
0e35fb941b | ||
|
|
71c9b927c6 | ||
|
|
0327d01287 | ||
|
|
0ab206ca13 | ||
|
|
e42960ea15 | ||
|
|
636d42a52e | ||
|
|
1451843f84 | ||
|
|
f8af21306a | ||
|
|
4e874cdb1b | ||
|
|
dbd9a844dc | ||
|
|
542cdef0bd | ||
|
|
f5955e14ff | ||
|
|
a0df7adbd1 | ||
|
|
82a4398ef6 | ||
|
|
9271930ba8 | ||
|
|
f149f0d994 | ||
|
|
14ff325608 | ||
|
|
8e37fcc71e | ||
|
|
bf910bc708 | ||
|
|
1136ea0779 | ||
|
|
9ad94b6562 | ||
|
|
c5284ed195 | ||
|
|
5cd92dd794 | ||
|
|
5ddb0b4a55 | ||
|
|
990858ba41 | ||
|
|
406951fc84 | ||
|
|
41c7bf4aaa | ||
|
|
1543634cb0 | ||
|
|
b935752ec0 | ||
|
|
2a60b7b7b2 | ||
|
|
cef78687b3 | ||
|
|
2f29edc01f | ||
|
|
134491b59e | ||
|
|
812ff0bfd2 | ||
|
|
201c4fa0d9 | ||
|
|
ced83b9bfc | ||
|
|
bd98ee62e1 | ||
|
|
e67c5273d7 | ||
|
|
b4b9339065 | ||
|
|
f3cd68eb3f | ||
|
|
ad57dea0e5 | ||
|
|
1e0a348b8e | ||
|
|
9c06a2126d | ||
|
|
dab030e95d | ||
|
|
4995bc0d0d | ||
|
|
d2369893c8 | ||
|
|
e48adf6443 | ||
|
|
505bca8386 | ||
|
|
31ca93a259 | ||
|
|
71523b7038 | ||
|
|
9885dc9c8a | ||
|
|
00d9d9f132 | ||
|
|
320dc3fac6 | ||
|
|
6e68e43a25 | ||
|
|
a19c391aa1 | ||
|
|
32f0101c1b | ||
|
|
12b9fdced5 | ||
|
|
0af45a53a9 | ||
|
|
37773d35f2 | ||
|
|
fca3eb4b7b | ||
|
|
5e9e0b70db | ||
|
|
5242ffc04b | ||
|
|
f0c9a5b2dc | ||
|
|
b3902e82fc | ||
|
|
d70eff6fc4 | ||
|
|
5b5695ffe1 | ||
|
|
deb44cad30 | ||
|
|
35fdca3607 | ||
|
|
93080523d0 | ||
|
|
b7b8f5a7e7 | ||
|
|
59ee55a6b2 | ||
|
|
d85b25d683 | ||
|
|
0108006fab | ||
|
|
755bb8f189 | ||
|
|
f53dcbc64f | ||
|
|
0f215bbcf8 | ||
|
|
9770775770 | ||
|
|
0b63bcc056 | ||
|
|
03116f5ece | ||
|
|
5c091d8690 | ||
|
|
da1ca24190 | ||
|
|
33f7a8d356 | ||
|
|
64c3fe9099 | ||
|
|
fa7382851f | ||
|
|
ab363596fd | ||
|
|
b05970acf4 | ||
|
|
aa6b70c296 | ||
|
|
00171e6d16 | ||
|
|
061e0ded72 | ||
|
|
81bdd86fb7 | ||
|
|
a3a79a696f | ||
|
|
6947672046 | ||
|
|
6f77e96998 | ||
|
|
8a595aa269 | ||
|
|
1ccf38221f | ||
|
|
18c639e6c0 | ||
|
|
06224371b3 | ||
|
|
d06105f410 | ||
|
|
3226340b08 | ||
|
|
25ef5d64b4 | ||
|
|
78d1256b74 | ||
|
|
dba8cb83bf | ||
|
|
744124f407 | ||
|
|
b595fe7488 | ||
|
|
eb0a3a27d3 | ||
|
|
09e660a38c | ||
|
|
193fba71f3 | ||
|
|
181cd7f0dc | ||
|
|
8d0793e004 | ||
|
|
ac2a1503e2 | ||
|
|
e617b913cd | ||
|
|
f974427964 | ||
|
|
c0406734bc | ||
|
|
8a14800ef2 | ||
|
|
a46d73f562 | ||
|
|
e908838376 | ||
|
|
4b1339a11c | ||
|
|
af0aa7da4e | ||
|
|
600238dd9b | ||
|
|
c978be5cab | ||
|
|
2fb29dad0a | ||
|
|
242201ca91 | ||
|
|
865392d1f7 | ||
|
|
b880ed2371 | ||
|
|
b4bc785f7c | ||
|
|
def04017e0 | ||
|
|
9eeb916796 | ||
|
|
b06a0c5d83 | ||
|
|
90541ba349 | ||
|
|
0cc346259b | ||
|
|
98c343b438 | ||
|
|
7ee0cdc6c7 | ||
|
|
6a770832ba | ||
|
|
ef0ff65162 | ||
|
|
8c0e7e1bb3 | ||
|
|
babb3ffb9c | ||
|
|
354bdeffbf | ||
|
|
8cb2ef7cac | ||
|
|
046b38e5c2 | ||
|
|
d50d7fd631 | ||
|
|
ed837b7527 | ||
|
|
bcbf27acca | ||
|
|
20bacfeecf | ||
|
|
beacfbb082 | ||
|
|
130aca2943 | ||
|
|
b8ff3ef41a | ||
|
|
7ecb96d45a | ||
|
|
fe3c301ca2 | ||
|
|
3adf8847b0 | ||
|
|
c73c2b003a | ||
|
|
a6d9c1f882 | ||
|
|
a5e1528c0d | ||
|
|
c25266054b | ||
|
|
a34ea0804d | ||
|
|
0fbf4ce443 | ||
|
|
d062cc45df | ||
|
|
da790136ff | ||
|
|
134f374ada | ||
|
|
df304a894f | ||
|
|
2d1d90e38c | ||
|
|
dcbdc6fcb8 | ||
|
|
5a4ef15de5 | ||
|
|
affc4c8bd9 | ||
|
|
bc5d6e89ba | ||
|
|
c17e6811d2 | ||
|
|
7f097c029a | ||
|
|
60f5affe43 | ||
|
|
444083ec5d | ||
|
|
8f232421d2 | ||
|
|
6217a721ac | ||
|
|
ad9e0cc39a | ||
|
|
3b750541c9 | ||
|
|
79765201ac | ||
|
|
0086b9d848 | ||
|
|
486f0c0035 | ||
|
|
dc3a695ab0 | ||
|
|
e769239213 | ||
|
|
45923a74f6 | ||
|
|
7bf7a87f8a | ||
|
|
8396e27a2c | ||
|
|
5153c68b8b | ||
|
|
391495dd86 | ||
|
|
8c89eb6650 | ||
|
|
4167c6ea70 | ||
|
|
ca3151ce29 | ||
|
|
cc20844eff | ||
|
|
d876e710e4 | ||
|
|
5c1290425b | ||
|
|
2043488c67 | ||
|
|
e7e48c8f03 | ||
|
|
dad650b804 | ||
|
|
d0e73714c6 | ||
|
|
d8b95d3a20 | ||
|
|
559d8cc0db | ||
|
|
7a804aa576 | ||
|
|
0bca66b671 | ||
|
|
24e5cf8121 | ||
|
|
ee7c4ce0f3 | ||
|
|
428b511687 | ||
|
|
49497996d5 | ||
|
|
bccd65e2fc | ||
|
|
f2158843ce | ||
|
|
87fc4a4f22 | ||
|
|
27291f9ee9 | ||
|
|
cba963110e | ||
|
|
aa014e3706 | ||
|
|
58d577f67a | ||
|
|
cd3678841b | ||
|
|
425e0c33df | ||
|
|
2018407782 | ||
|
|
a3a49e47b7 | ||
|
|
a4729a7de8 | ||
|
|
9e23117f9c | ||
|
|
a3bfcc962d | ||
|
|
0b694bfd0b | ||
|
|
56a44ad421 | ||
|
|
78cfb19f69 | ||
|
|
58a47cb52b | ||
|
|
523df21d83 | ||
|
|
d04bf2e8f2 | ||
|
|
89656c7e65 | ||
|
|
5ff813f9b7 | ||
|
|
948b7cda15 | ||
|
|
6601e73069 | ||
|
|
b5c7f374f3 | ||
|
|
f2303ae2dc | ||
|
|
54f065f42c | ||
|
|
333ebb88b9 | ||
|
|
53ff367473 | ||
|
|
33a7de9448 | ||
|
|
c797472bcc | ||
|
|
69a57b77c9 | ||
|
|
d819f31bdd | ||
|
|
5ee955a713 | ||
|
|
270d145466 | ||
|
|
b019af1851 | ||
|
|
6f97a40372 | ||
|
|
607781382f | ||
|
|
2c6869501e | ||
|
|
23b54de8bd | ||
|
|
3934b40282 | ||
|
|
d3c9963051 | ||
|
|
bc5da2532c | ||
|
|
ac6ea8bdcc | ||
|
|
dc4cf8496a | ||
|
|
ed79d21e1b | ||
|
|
743d340bca | ||
|
|
3d1398ab97 | ||
|
|
6faf171007 | ||
|
|
7a680ce4ff | ||
|
|
2ac4456f4e | ||
|
|
391aa30da2 | ||
|
|
f92f76b48a | ||
|
|
61b6d4dc47 | ||
|
|
aa041e39eb | ||
|
|
9348204987 | ||
|
|
776c7caaa5 | ||
|
|
2216b83ca7 | ||
|
|
723abca34a | ||
|
|
32b28327e9 | ||
|
|
c30131275f | ||
|
|
56218dfcb2 | ||
|
|
0d2a75db0a | ||
|
|
eb9d066844 | ||
|
|
029f3030a7 | ||
|
|
8c59a8d405 | ||
|
|
777872d41f | ||
|
|
b85d1f184a | ||
|
|
02129eeddb | ||
|
|
2612e0bbc8 | ||
|
|
3670efacb4 | ||
|
|
476611b70f | ||
|
|
60df2a17f8 | ||
|
|
f64f4795c1 | ||
|
|
e036f756d5 | ||
|
|
92fd121cae | ||
|
|
6307337892 | ||
|
|
fc2e35cd32 | ||
|
|
1811e061aa | ||
|
|
59037f0d83 | ||
|
|
67edb7d396 | ||
|
|
0da393f950 | ||
|
|
abd30e551e | ||
|
|
6fb2889a92 | ||
|
|
54125d27e0 | ||
|
|
41efda5f82 | ||
|
|
2aee14a800 | ||
|
|
be69da0a0d | ||
|
|
31a247b55b | ||
|
|
33c156be16 | ||
|
|
fd66a083d6 | ||
|
|
d276f50fdf | ||
|
|
4cb748e124 | ||
|
|
503e6898c3 | ||
|
|
f34056fe2e | ||
|
|
8ff3575442 | ||
|
|
b5e3358bbd | ||
|
|
047a1197be | ||
|
|
0e87843446 | ||
|
|
4f1ff328ad | ||
|
|
ad5bbb9b37 | ||
|
|
c6e2fd2cab | ||
|
|
d3a7e25b86 | ||
|
|
062445a48e | ||
|
|
3c32be6181 | ||
|
|
e2f4a9bf9f | ||
|
|
2db4c1b2e4 | ||
|
|
6ed93f4a4f | ||
|
|
9dcee71baf | ||
|
|
9bdd0d1d1e | ||
|
|
13b51d8608 | ||
|
|
19969fee39 | ||
|
|
28dc4bf52e | ||
|
|
9a380ac3d4 | ||
|
|
17a26b43f0 | ||
|
|
3c42acebf0 | ||
|
|
3327b2ce3c | ||
|
|
8c56aa9575 | ||
|
|
d528126f15 | ||
|
|
64d0e3928c | ||
|
|
7017a0cae1 | ||
|
|
a40e4d7d04 | ||
|
|
9e3b56f4bc | ||
|
|
3492ed54de | ||
|
|
1455281957 | ||
|
|
e1de57384e | ||
|
|
c95462328a | ||
|
|
84fc89250a | ||
|
|
a80f52cbf4 | ||
|
|
7ce324a3a5 | ||
|
|
7624082b29 | ||
|
|
6d3bba696a | ||
|
|
68dad1d3ae |
14
.env.example
14
.env.example
@@ -40,12 +40,26 @@ DB_SANITIZE_BY_DEFAULT=false
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: SSL DATABASE SETTINGS
|
||||
# --------------------------------------------
|
||||
# Enable SSL connection to database (true/false)
|
||||
DB_SSL=false
|
||||
|
||||
# Set to true for cloud databases like AWS RDS, Azure Database, Google Cloud SQL
|
||||
# Set to false for self-hosted databases with client certificates
|
||||
DB_SSL_IS_PAAS=false
|
||||
|
||||
# Required when DB_SSL_IS_PAAS=false (client certificate authentication)
|
||||
DB_SSL_KEY_PATH=null
|
||||
DB_SSL_CERT_PATH=null
|
||||
|
||||
# Path to CA certificate bundle (required for SSL connections)
|
||||
# For AWS RDS, download from: https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
|
||||
DB_SSL_CA_PATH=null
|
||||
|
||||
# SSL cipher (optional, leave null for default)
|
||||
DB_SSL_CIPHER=null
|
||||
|
||||
# Verify server certificate (true/false, defaults to false if not set)
|
||||
# Set to false for development or when using self-signed certificates
|
||||
DB_SSL_VERIFY_SERVER=null
|
||||
|
||||
# --------------------------------------------
|
||||
|
||||
7
.github/autolabeler.yml
vendored
7
.github/autolabeler.yml
vendored
@@ -1,10 +1,11 @@
|
||||
frontend: ["*.js", "*.css", "*.vue", "*.scss", "*.less", "*.blade.*", "resources/views/livewire/*"]
|
||||
frontend: ["*.js", "*.css", "*.scss", "*.less", "*.blade.*", "resources/views/livewire/*","resources/views/layouts/default.blade.php"]
|
||||
skins: ["*.js", "*.css", "*.scss", "*.less"]
|
||||
css: ["*.css","*.scss", "*.less"]
|
||||
javascript: ["*.js", "package.json", "package.lock"]
|
||||
backend: ["/app/*", "composer.json", "composer.lock"]
|
||||
translations: ["/resources/lang"]
|
||||
translations: ["/resources/lang/*"]
|
||||
livewire: ["/app/Http/Livewire/*", "resources/views/livewire/*"]
|
||||
blade-components: ["resources/views/blade/*"]
|
||||
backups: ["*backup*"]
|
||||
restore: ["*restore*"]
|
||||
saml: ["*saml*"]
|
||||
@@ -16,7 +17,7 @@ api: ["/app/Http/Controllers/Api/*"]
|
||||
notifications: ["/app/Notifications/*"]
|
||||
importer: ["/app/Importer/*","/app/Http/Livewire/Importer.php", "resources/views/livewire/importer.php"]
|
||||
cli / artisan: ["/app/Console/*"]
|
||||
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php"]
|
||||
LDAP: ["*Ldap*", "/app/Console/Commands/Ldap*","/app/Models/Ldap.php", "/resources/views/users/ldap.blade.php","/resources/views/settings/ldap.blade.php"]
|
||||
docker: ["*docker/*", "Dockerfile", "Dockerfile.alpine", "Dockerfile.fpm-alpine", ".dockerignore", ".env.docker"]
|
||||
tests: ["/tests/*", "/database/factories/*", "/stubs"]
|
||||
config: .github
|
||||
|
||||
8
.github/workflows/docker-alpine.yml
vendored
8
.github/workflows/docker-alpine.yml
vendored
@@ -46,13 +46,13 @@ jobs:
|
||||
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
# https://github.com/docker/login-action
|
||||
- name: Login to DockerHub
|
||||
# Only login if not a PR, as PRs only trigger a Docker build and not a push
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
# Get Metadata for docker_build step below
|
||||
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
|
||||
id: meta_build
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: snipe/snipe-it
|
||||
tags: ${{ env.IMAGE_TAGS }}
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.alpine
|
||||
|
||||
8
.github/workflows/docker-ubuntu.yml
vendored
8
.github/workflows/docker-ubuntu.yml
vendored
@@ -46,13 +46,13 @@ jobs:
|
||||
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
# https://github.com/docker/login-action
|
||||
- name: Login to DockerHub
|
||||
# Only login if not a PR, as PRs only trigger a Docker build and not a push
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
# Get Metadata for docker_build step below
|
||||
- name: Sync metadata (tags, labels) from GitHub to Docker for 'snipe-it' image
|
||||
id: meta_build
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: snipe/snipe-it
|
||||
tags: ${{ env.IMAGE_TAGS }}
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push 'snipe-it' image
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
|
||||
4
.github/workflows/tests-mysql.yml
vendored
4
.github/workflows/tests-mysql.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Upload Laravel logs as artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
|
||||
path: |
|
||||
|
||||
4
.github/workflows/tests-postgres.yml
vendored
4
.github/workflows/tests-postgres.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
|
||||
- name: Upload Laravel logs as artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
|
||||
path: |
|
||||
|
||||
4
.github/workflows/tests-sqlite.yml
vendored
4
.github/workflows/tests-sqlite.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
|
||||
- name: Upload Laravel logs as artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v5
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: laravel-logs-php-${{ matrix.php-version }}-run-${{ github.run_attempt }}
|
||||
path: |
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
FROM alpine:3.19
|
||||
FROM alpine:3.23
|
||||
# Apache + PHP
|
||||
RUN apk add --no-cache \
|
||||
apache2 \
|
||||
php82 \
|
||||
php82-common \
|
||||
php82-apache2 \
|
||||
php82-curl \
|
||||
php82-ldap \
|
||||
php82-mysqli \
|
||||
php82-gd \
|
||||
php82-xml \
|
||||
php82-mbstring \
|
||||
php82-zip \
|
||||
php82-ctype \
|
||||
php82-tokenizer \
|
||||
php82-pdo_mysql \
|
||||
php82-openssl \
|
||||
php82-bcmath \
|
||||
php82-phar \
|
||||
php82-json \
|
||||
php82-iconv \
|
||||
php82-fileinfo \
|
||||
php82-simplexml \
|
||||
php82-session \
|
||||
php82-dom \
|
||||
php82-xmlwriter \
|
||||
php82-xmlreader \
|
||||
php82-sodium \
|
||||
php82-redis \
|
||||
php82-pecl-memcached \
|
||||
php82-exif \
|
||||
php84 \
|
||||
php84-common \
|
||||
php84-apache2 \
|
||||
php84-curl \
|
||||
php84-ldap \
|
||||
php84-mysqli \
|
||||
php84-gd \
|
||||
php84-xml \
|
||||
php84-mbstring \
|
||||
php84-zip \
|
||||
php84-ctype \
|
||||
php84-tokenizer \
|
||||
php84-pdo_mysql \
|
||||
php84-openssl \
|
||||
php84-bcmath \
|
||||
php84-phar \
|
||||
php84-json \
|
||||
php84-iconv \
|
||||
php84-fileinfo \
|
||||
php84-simplexml \
|
||||
php84-session \
|
||||
php84-dom \
|
||||
php84-xmlwriter \
|
||||
php84-xmlreader \
|
||||
php84-sodium \
|
||||
php84-redis \
|
||||
php84-pecl-memcached \
|
||||
php84-exif \
|
||||
curl \
|
||||
wget \
|
||||
vim \
|
||||
@@ -42,7 +42,7 @@ COPY docker/column-statistics.cnf /etc/mysql/conf.d/column-statistics.cnf
|
||||
# Where apache's PID lives
|
||||
RUN mkdir -p /run/apache2 && chown apache:apache /run/apache2
|
||||
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php82/php.ini
|
||||
RUN sed -i 's/variables_order = .*/variables_order = "EGPCS"/' /etc/php84/php.ini
|
||||
COPY docker/000-default-2.4.conf /etc/apache2/conf.d/default.conf
|
||||
|
||||
# Enable mod_rewrite
|
||||
|
||||
@@ -78,6 +78,8 @@ Since the release of the JSON REST API, several third-party developers have been
|
||||
|
||||
#### Libraries & Modules
|
||||
|
||||
- [SnipeScheduler](https://github.com/JSY-Ben/SnipeScheduler) by [@JSY-Ben](https://github.com/JSY-Ben) - An Asset Reservation/Checkout System for Snipe-IT
|
||||
- [Snipe-IT MCP Server](https://github.com/jameshgordy/snipeit-mcp) by [@jameshgordy](https://github.com/jameshgordy) - A Model Context Protocol (MCP) server for managing Snipe-IT inventory systems
|
||||
- [SnipeSharp - .NET module in C#](https://github.com/barrycarey/SnipeSharp) by [@barrycarey](https://github.com/barrycarey)
|
||||
- [SnipeitPS](https://github.com/snazy2000/SnipeitPS) by [@snazy2000](https://github.com/snazy2000) - Powershell API Wrapper for Snipe-it
|
||||
- [jamf2snipe](https://github.com/grokability/jamf2snipe) - Python script to sync assets between a JAMFPro instance and a Snipe-IT instance
|
||||
|
||||
@@ -245,26 +245,26 @@ class LdapSync extends Command
|
||||
// Assign the mapped LDAP attributes for each user to the Snipe-IT user fields
|
||||
for ($i = 0; $i < $results['count']; $i++) {
|
||||
$item = [];
|
||||
$item['username'] = $results[$i][$ldap_map["username"]][0] ?? '';
|
||||
$item['display_name'] = $results[$i][$ldap_map["display_name"]][0] ?? '';
|
||||
$item['employee_number'] = $results[$i][$ldap_map["emp_num"]][0] ?? '';
|
||||
$item['lastname'] = $results[$i][$ldap_map["last_name"]][0] ?? '';
|
||||
$item['firstname'] = $results[$i][$ldap_map["first_name"]][0] ?? '';
|
||||
$item['email'] = $results[$i][$ldap_map["email"]][0] ?? '';
|
||||
$item['ldap_location_override'] = $results[$i]['ldap_location_override'] ?? '';
|
||||
$item['location_id'] = $results[$i]['location_id'] ?? '';
|
||||
$item['telephone'] = $results[$i][$ldap_map["phone"]][0] ?? '';
|
||||
$item['mobile'] = $results[$i][$ldap_map["mobile"]][0] ?? '';
|
||||
$item['jobtitle'] = $results[$i][$ldap_map["jobtitle"]][0] ?? '';
|
||||
$item['address'] = $results[$i][$ldap_map["address"]][0] ?? '';
|
||||
$item['city'] = $results[$i][$ldap_map["city"]][0] ?? '';
|
||||
$item['state'] = $results[$i][$ldap_map["state"]][0] ?? '';
|
||||
$item['country'] = $results[$i][$ldap_map["country"]][0] ?? '';
|
||||
$item['zip'] = $results[$i][$ldap_map["zip"]][0] ?? '';
|
||||
$item['department'] = $results[$i][$ldap_map["dept"]][0] ?? '';
|
||||
$item['manager'] = $results[$i][$ldap_map["manager"]][0] ?? '';
|
||||
$item['location'] = $results[$i][$ldap_map["location"]][0] ?? '';
|
||||
$location = $default_location; //initially, set '$location' to the default_location (which may just be `null`)
|
||||
$item['username'] = $results[$i][$ldap_map["username"]][0] ?? null;
|
||||
$item['display_name'] = $results[$i][$ldap_map["display_name"]][0] ?? null;
|
||||
$item['employee_number'] = $results[$i][$ldap_map["emp_num"]][0] ?? null;
|
||||
$item['lastname'] = $results[$i][$ldap_map["last_name"]][0] ?? null;
|
||||
$item['firstname'] = $results[$i][$ldap_map["first_name"]][0] ?? null;
|
||||
$item['email'] = $results[$i][$ldap_map["email"]][0] ?? null;
|
||||
$item['ldap_location_override'] = $results[$i]['ldap_location_override'] ?? null;
|
||||
$item['location_id'] = $results[$i]['location_id'] ?? null;
|
||||
$item['telephone'] = $results[$i][$ldap_map["phone"]][0] ?? null;
|
||||
$item['mobile'] = $results[$i][$ldap_map["mobile"]][0] ?? null;
|
||||
$item['jobtitle'] = $results[$i][$ldap_map["jobtitle"]][0] ?? null;
|
||||
$item['address'] = $results[$i][$ldap_map["address"]][0] ?? null;
|
||||
$item['city'] = $results[$i][$ldap_map["city"]][0] ?? null;
|
||||
$item['state'] = $results[$i][$ldap_map["state"]][0] ?? null;
|
||||
$item['country'] = $results[$i][$ldap_map["country"]][0] ?? null;
|
||||
$item['zip'] = $results[$i][$ldap_map["zip"]][0] ?? null;
|
||||
$item['department'] = $results[$i][$ldap_map["dept"]][0] ?? null;
|
||||
$item['manager'] = $results[$i][$ldap_map["manager"]][0] ?? null;
|
||||
$item['location'] = $results[$i][$ldap_map["location"]][0] ?? null;
|
||||
$location = $default_location; //initially, set '$location' to the default_location (which may just be null)
|
||||
|
||||
// ONLY if you are using the "ldap_location" option *AND* you have an actual result
|
||||
if ($ldap_map["location"] && $item['location']) {
|
||||
@@ -464,6 +464,7 @@ class LdapSync extends Command
|
||||
$errors = '';
|
||||
|
||||
if ($user->save()) {
|
||||
$item['id'] = $user->id;
|
||||
$item['note'] = $item['createorupdate'];
|
||||
$item['status'] = 'success';
|
||||
if ($item['createorupdate'] === 'created' && $ldap_default_group) {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\ActionType;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class MigrateLicenseSeatQuantitiesInActionLogs extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:migrate-license-seat-quantities-in-action-logs
|
||||
{--no-interaction: Do not ask any interactive question}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Updates quantity field in action_logs table for license seats that were added or deleted.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$query = DB::table('action_logs')
|
||||
->whereIn('action_type', [
|
||||
ActionType::AddSeats->value,
|
||||
ActionType::DeleteSeats->value,
|
||||
])
|
||||
->where('quantity', '=', 1)
|
||||
->orderBy('id');
|
||||
|
||||
$count = $query->count();
|
||||
|
||||
if ($count === 0) {
|
||||
$this->info('Nothing to update');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->info("{$count} logs to update");
|
||||
|
||||
if ($this->option('no-interaction') || $this->confirm('Update quantities in the action log?')) {
|
||||
$query->chunk(50, function ($logs) {
|
||||
$logs->each(function ($log) {
|
||||
$quantityFromNote = Str::between($log->note, "ed ", " seats");
|
||||
|
||||
if (!is_numeric($quantityFromNote)) {
|
||||
$this->error('Could not parse quantity from ID: {id}', ['id' => $log->id]);
|
||||
}
|
||||
|
||||
if ($log->quantity !== (int) $quantityFromNote) {
|
||||
$this->info(vsprintf('Updating id: %s to quantity %s', [
|
||||
'id' => $log->id,
|
||||
'new_quantity' => $quantityFromNote,
|
||||
]));
|
||||
|
||||
DB::table('action_logs')->where('id', $log->id)->update(['quantity' => (int) $quantityFromNote]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,7 @@ class MoveUploadsToNewDisk extends Command
|
||||
$filename = basename($private_upload[$x]);
|
||||
|
||||
try {
|
||||
Storage::put($private_type . '/' . $filename, file_get_contents($private_upload[$i]));
|
||||
Storage::put($private_type . '/' . $filename, file_get_contents($private_upload[$x]));
|
||||
$new_url = Storage::url($private_type . '/' . $filename, $filename);
|
||||
$this->info($type_count . '. PRIVATE: ' . $filename . ' was copied to ' . $new_url);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@@ -33,6 +33,11 @@ class ObjectImportCommand extends Command
|
||||
*/
|
||||
protected ProgressIndicator $progressIndicator;
|
||||
|
||||
/**
|
||||
* Logger instance with configurable log path
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
@@ -65,9 +70,11 @@ class ObjectImportCommand extends Command
|
||||
->setShouldNotify($this->option('send-welcome'))
|
||||
->setUsernameFormat($this->option('username_format'));
|
||||
|
||||
// This $logFile/useFiles() bit is currently broken, so commenting it out for now
|
||||
// $logFile = $this->option('logfile');
|
||||
// Log::useFiles($logFile);
|
||||
$this->logger = Log::build([
|
||||
'driver' => 'single',
|
||||
'path' => $this->option('logfile'),
|
||||
]);
|
||||
|
||||
$this->progressIndicator->start('======= Importing Items from '.$filename.' =========');
|
||||
|
||||
$importer->import();
|
||||
@@ -99,10 +106,10 @@ class ObjectImportCommand extends Command
|
||||
public function log($string, $level = 'info')
|
||||
{
|
||||
if ($level === 'warning') {
|
||||
Log::warning($string);
|
||||
$this->logger->warning($string);
|
||||
$this->comment($string);
|
||||
} else {
|
||||
Log::Info($string);
|
||||
$this->logger->Info($string);
|
||||
if ($this->option('verbose')) {
|
||||
$this->comment($string);
|
||||
}
|
||||
|
||||
132
app/Console/Commands/PurgeEulaPDFs.php
Normal file
132
app/Console/Commands/PurgeEulaPDFs.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\CheckoutAcceptance;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class PurgeEulaPDFs extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'snipeit:purge-eula-pdfs
|
||||
{--older-than-days= : The number of days we should delete before }
|
||||
{--force : Skip the interactive yes/no prompt for confirmation}
|
||||
{--dryrun : Show the records that would be deleted but don\'t update the database or delete files from disk}
|
||||
{--with-output : Display the results in a table in your console}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'This purges signature files and EULAs from the system if they are older than the date passed with --older-than-days=.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$before = $this->option('older-than-days');
|
||||
|
||||
if (($before=='') || (!is_numeric($before))) {
|
||||
return $this->error('ERROR: You must pass a valid number for --older-than-days (example: snipeit:purge-eula-pdfs --older-than-days=365.)');
|
||||
}
|
||||
|
||||
$interval_date = Carbon::now()->subDays($before);
|
||||
$signature_path = 'private_uploads/signatures/';
|
||||
$eula_path = 'private_uploads/eula-pdfs/';
|
||||
|
||||
if (!Storage::exists($eula_path)) {
|
||||
$this->fail('The storage directory "'.$eula_path.'" does not exist. No EULA files will be deleted.');
|
||||
}
|
||||
|
||||
if (!Storage::exists($signature_path)) {
|
||||
$this->fail('The storage directory "'.$signature_path.'" does not exist. No signature files will be deleted.');
|
||||
}
|
||||
|
||||
|
||||
if ($this->option('dryrun')) {
|
||||
$this->info('This script is being run with the --dryrun option. No files or records will be deleted.');
|
||||
|
||||
}
|
||||
$acceptances = CheckoutAcceptance::HasFiles()->where('updated_at','<', $interval_date)->with('assignedTo')->get();
|
||||
|
||||
if (!$this->option('force')) {
|
||||
if ($this->confirm("\n****************************************************\nTHIS WILL DELETE ALL OF THE SIGNATURES AND EULA PDF FILES SINCE $interval_date. \nThere is NO undo! \n****************************************************\n\nDo you wish to continue? No backsies! [y|N]")) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($acceptances->count() == 0) {
|
||||
return $this->warn('There are no item acceptances with signatures or EULA PDFs from before '.$interval_date);
|
||||
}
|
||||
|
||||
$this->info(number_format($acceptances->count()) . ' EULA PDFs from before '.$interval_date.' will be purged');
|
||||
|
||||
if (!$this->option('with-output')) {
|
||||
$this->info('Run this command with the --with-output option to see the full list in the console.');
|
||||
} else {
|
||||
$this->table(
|
||||
[
|
||||
trans('general.user'),
|
||||
trans('general.type'),
|
||||
trans('general.item'),
|
||||
trans('general.category'),
|
||||
trans('general.accepted_date'),
|
||||
trans('general.declined_date'),
|
||||
trans('general.signature'),
|
||||
trans('general.filename'),
|
||||
|
||||
],
|
||||
$acceptances->map(fn($acceptance) => [
|
||||
trans('general.user') => $acceptance->assignedTo->display_name,
|
||||
trans('general.type') => $acceptance->display_checkoutable_type,
|
||||
trans('general.item') => $acceptance->checkoutable_type::find($acceptance->checkoutable_id)->display_name,
|
||||
trans('general.category') => $acceptance->checkoutable_category_name,
|
||||
trans('general.accepted_date') => $acceptance->accepted_at,
|
||||
trans('general.declined_date') => $acceptance->declined_at,
|
||||
trans('general.signature') => $acceptance->signature_filename,
|
||||
trans('general.filename') => $acceptance->stored_eula_file,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach ($acceptances as $acceptance) {
|
||||
|
||||
$signature_file = $signature_path.$acceptance->signature_filename;
|
||||
$eula_file = $eula_path.$acceptance->stored_eula_file;
|
||||
|
||||
if (Storage::exists($signature_file)) {
|
||||
if (!$this->option('dryrun')) {
|
||||
Storage::delete($signature_file);
|
||||
}
|
||||
} else {
|
||||
$this->error('The file "'. $signature_file.'" does not exist.');
|
||||
}
|
||||
|
||||
|
||||
if (Storage::exists($eula_file)) {
|
||||
if (!$this->option('dryrun')) {
|
||||
Storage::delete($eula_file);
|
||||
}
|
||||
} else {
|
||||
$this->error('The file "'.$eula_file.'" does not exist.');
|
||||
}
|
||||
|
||||
if (!$this->option('dryrun')) {
|
||||
$acceptance->delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -50,8 +50,9 @@ class ResetDemoSettings extends Command
|
||||
$settings->alert_email = 'service@snipe-it.io';
|
||||
$settings->login_note = 'Use `admin` / `password` to login to the demo.';
|
||||
$settings->header_color = '#3c8dbc';
|
||||
$settings->link_dark_color = '#86cbf2';
|
||||
$settings->link_light_color = '#084d73;';
|
||||
$settings->link_dark_color = '#5fa4cc';
|
||||
$settings->link_light_color = '#296282;';
|
||||
$settings->nav_link_color = '#FFFFFF';
|
||||
$settings->label2_2d_type = 'QRCODE';
|
||||
$settings->default_currency = 'USD';
|
||||
$settings->brand = 2;
|
||||
|
||||
@@ -55,6 +55,8 @@ class SendExpirationAlerts extends Command
|
||||
// Expiring Assets
|
||||
$assets = Asset::getExpiringWarrantyOrEol($alert_interval);
|
||||
|
||||
$assets->load(['assignedTo', 'supplier']);
|
||||
|
||||
if ($assets->count() > 0) {
|
||||
|
||||
Mail::to($recipients)->send(new ExpiringAssetsMail($assets, $alert_interval));
|
||||
|
||||
@@ -15,18 +15,20 @@ class CheckoutableCheckedOut
|
||||
public $checkedOutBy;
|
||||
public $note;
|
||||
public $originalValues;
|
||||
public int $quantity;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [])
|
||||
public function __construct($checkoutable, $checkedOutTo, User $checkedOutBy, $note, $originalValues = [], $quantity = 1)
|
||||
{
|
||||
$this->checkoutable = $checkoutable;
|
||||
$this->checkedOutTo = $checkedOutTo;
|
||||
$this->checkedOutBy = $checkedOutBy;
|
||||
$this->note = $note;
|
||||
$this->originalValues = $originalValues;
|
||||
$this->quantity = $quantity;
|
||||
}
|
||||
}
|
||||
|
||||
24
app/Events/CheckoutablesCheckedOutInBulk.php
Normal file
24
app/Events/CheckoutablesCheckedOutInBulk.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class CheckoutablesCheckedOutInBulk
|
||||
{
|
||||
use Dispatchable, SerializesModels;
|
||||
|
||||
public function __construct(
|
||||
public Collection $assets,
|
||||
public Model $target,
|
||||
public User $admin,
|
||||
public string $checkout_at,
|
||||
public string $expected_checkin,
|
||||
public string $note,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,8 @@ class Handler extends ExceptionHandler
|
||||
$route = 'licenses.index';
|
||||
} elseif (($route === 'customfieldsets.index') || ($route === 'customfields.index')) {
|
||||
$route = 'fields.index';
|
||||
} elseif ($route == 'actionlogs.index') {
|
||||
$route = 'home';
|
||||
}
|
||||
|
||||
return redirect()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Helpers;
|
||||
use App\Models\Accessory;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\Component;
|
||||
@@ -13,6 +14,7 @@ use App\Models\Setting;
|
||||
use App\Models\Statuslabel;
|
||||
use App\Models\License;
|
||||
use App\Models\Location;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
@@ -773,11 +775,11 @@ class Helper
|
||||
public static function checkLowInventory()
|
||||
{
|
||||
$alert_threshold = \App\Models\Setting::getSettings()->alert_threshold;
|
||||
$consumables = Consumable::withCount('consumableAssignments as consumable_assignments_count')->whereNotNull('min_amt')->get();
|
||||
$consumables = Consumable::withCount('consumableAssignments as consumables_users_count')->whereNotNull('min_amt')->get();
|
||||
$accessories = Accessory::withCount('checkouts as checkouts_count')->whereNotNull('min_amt')->get();
|
||||
$components = Component::whereNotNull('min_amt')->get();
|
||||
$asset_models = AssetModel::where('min_amt', '>', 0)->get();
|
||||
$licenses = License::where('min_amt', '>', 0)->get();
|
||||
$components = Component::withCount('assets as sum_unconstrained_assets')->whereNotNull('min_amt')->get();
|
||||
$asset_models = AssetModel::where('min_amt', '>', 0)->withCount(['availableAssets', 'assets'])->get();
|
||||
$licenses = License::withCount('availCount as licenses_available')->where('min_amt', '>', 0)->get();
|
||||
|
||||
$items_array = [];
|
||||
$all_count = 0;
|
||||
@@ -842,8 +844,8 @@ class Helper
|
||||
foreach ($asset_models as $asset_model){
|
||||
|
||||
$asset = new Asset();
|
||||
$total_owned = $asset->where('model_id', '=', $asset_model->id)->count();
|
||||
$avail = $asset->where('model_id', '=', $asset_model->id)->whereNull('assigned_to')->count();
|
||||
$total_owned = $asset_model->assets_count; //requires the withCount() clause in the initial query!
|
||||
$avail = $asset_model->available_assets_count; //requires the withCount() clause in the initial query!
|
||||
|
||||
if ($avail <= ($asset_model->min_amt) + $alert_threshold) {
|
||||
if ($avail > 0) {
|
||||
@@ -1384,49 +1386,24 @@ class Helper
|
||||
* @return string[]
|
||||
*/
|
||||
public static function SettingUrls(){
|
||||
$settings=['#','fields.index', 'statuslabels.index', 'models.index', 'categories.index', 'manufacturers.index', 'suppliers.index', 'departments.index', 'locations.index', 'companies.index', 'depreciations.index'];
|
||||
$settings=[
|
||||
'#',
|
||||
'fields*',
|
||||
'statuslabels*',
|
||||
'models*',
|
||||
'categories*',
|
||||
'manufacturers*',
|
||||
'suppliers*',
|
||||
'departments*',
|
||||
'locations*',
|
||||
'companies*',
|
||||
'depreciations*'
|
||||
];
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generic helper (largely used by livewire right now) that returns the font-awesome icon
|
||||
* for the object type.
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since 6.1.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function iconTypeByItem($item) {
|
||||
|
||||
switch ($item) {
|
||||
case 'asset':
|
||||
return 'fas fa-barcode';
|
||||
case 'accessory':
|
||||
return 'fas fa-keyboard';
|
||||
case 'component':
|
||||
return 'fas fa-hdd';
|
||||
case 'consumable':
|
||||
return 'fas fa-tint';
|
||||
case 'license':
|
||||
return 'far fa-save';
|
||||
case 'location':
|
||||
return 'fas fa-map-marker-alt';
|
||||
case 'user':
|
||||
return 'fas fa-user';
|
||||
case 'supplier':
|
||||
return 'fa-solid fa-store';
|
||||
case 'manufacturer':
|
||||
return 'fa-solid fa-building';
|
||||
case 'category':
|
||||
return 'fa-solid fa-table-columns';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is a shorter way to see if the app is in demo mode.
|
||||
*
|
||||
@@ -1570,7 +1547,6 @@ class Helper
|
||||
]) ? 'rtl' : 'ltr';
|
||||
}
|
||||
|
||||
|
||||
static public function getRedirectOption($request, $id, $table, $item_id = null) : RedirectResponse
|
||||
{
|
||||
|
||||
@@ -1735,4 +1711,83 @@ class Helper
|
||||
}
|
||||
return $mismatched;
|
||||
}
|
||||
static public function labelFieldLayoutScaling(
|
||||
$pdf,
|
||||
iterable|\Closure $fields,
|
||||
float $currentX,
|
||||
float $usableWidth,
|
||||
float $usableHeight,
|
||||
float $baseLabelSize,
|
||||
float $baseFieldSize,
|
||||
float $baseFieldMargin,
|
||||
?string $title = null,
|
||||
float $baseTitleSize = 0.0,
|
||||
float $baseTitleMargin = 0.0,
|
||||
float $baseLabelPadding = 1.5,
|
||||
float $baseGap = 1.5,
|
||||
float $maxScale = 1.8,
|
||||
string $labelFont = 'freesans',
|
||||
|
||||
) : array
|
||||
{
|
||||
$fieldCount = count($fields);
|
||||
$perFieldHeight = max($baseLabelSize, $baseFieldSize) + $baseFieldMargin;
|
||||
$baseFieldsHeight = $fieldCount * $perFieldHeight;
|
||||
|
||||
$hasTitle = is_string($title) && trim($title) !== '';
|
||||
$baseTitleHeight = $hasTitle ? ($baseTitleSize + $baseTitleMargin) : 0.0;
|
||||
$baseTotalHeight = $baseTitleHeight + $baseFieldsHeight;
|
||||
$scale = 1.0;
|
||||
if ($baseTotalHeight > 0 && $usableHeight > 0) {
|
||||
$scale = $usableHeight / $baseTotalHeight;
|
||||
}
|
||||
|
||||
$scale = min($scale, $maxScale);
|
||||
|
||||
$labelSize = $baseLabelSize;
|
||||
$fieldSize = $baseFieldSize * $scale;
|
||||
$fieldMargin = $baseFieldMargin * $scale;
|
||||
|
||||
$rowAdvance = max($labelSize, $fieldSize) + $fieldMargin;
|
||||
$titleSize = $hasTitle ? ($baseTitleSize * $scale) : 0.0;
|
||||
$titleMargin = $hasTitle ? ($baseTitleMargin * $scale) : 0.0;
|
||||
$titleAdvance = $hasTitle ? ($titleSize + $titleMargin) : 0.0;
|
||||
|
||||
$pdf->SetFont($labelFont, '', $baseLabelSize);
|
||||
|
||||
$maxLabelWidthPerUnit = 0;
|
||||
foreach ($fields as $field) {
|
||||
$rawLabel = $field['label'] ?? null;
|
||||
|
||||
// If no label, do not include it in label-column sizing
|
||||
if (!is_string($rawLabel) || trim($rawLabel) === '') {
|
||||
continue;
|
||||
}
|
||||
$label = rtrim($field['label'], ':') . ':';
|
||||
$width = $pdf->GetStringWidth($label);
|
||||
$maxLabelWidthPerUnit = max($maxLabelWidthPerUnit, $width / $baseLabelSize);
|
||||
}
|
||||
|
||||
$labelPadding = $baseLabelPadding * $scale;
|
||||
$gap = $baseGap * $scale;
|
||||
|
||||
$labelWidth = ($maxLabelWidthPerUnit * $labelSize) + $labelPadding;
|
||||
$valueX = $currentX + $labelWidth + $gap;
|
||||
$valueWidth = $usableWidth - $labelWidth - $gap;
|
||||
|
||||
return compact(
|
||||
'scale',
|
||||
'hasTitle',
|
||||
'titleSize',
|
||||
'titleMargin',
|
||||
'titleAdvance',
|
||||
'labelSize',
|
||||
'fieldSize',
|
||||
'fieldMargin',
|
||||
'rowAdvance',
|
||||
'labelWidth',
|
||||
'valueX',
|
||||
'valueWidth'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ class IconHelper
|
||||
case 'checkin':
|
||||
return 'fa-solid fa-rotate-right';
|
||||
case 'edit':
|
||||
case 'update':
|
||||
return 'fas fa-pencil-alt';
|
||||
case 'clone':
|
||||
return 'far fa-clone';
|
||||
@@ -36,6 +37,8 @@ class IconHelper
|
||||
return 'fa-solid fa-user';
|
||||
case 'users':
|
||||
return 'fas fa-users';
|
||||
case 'supplier':
|
||||
return 'fa-solid fa-store';
|
||||
case 'restore':
|
||||
return 'fa-solid fa-trash-arrow-up';
|
||||
case 'external-link':
|
||||
@@ -46,6 +49,8 @@ class IconHelper
|
||||
return 'fa-regular fa-envelope';
|
||||
case 'phone':
|
||||
return 'fa-solid fa-phone';
|
||||
case 'fax':
|
||||
return 'fa-solid fa-fax';
|
||||
case 'mobile':
|
||||
return 'fas fa-mobile-screen-button';
|
||||
case 'long-arrow-right':
|
||||
@@ -53,7 +58,7 @@ class IconHelper
|
||||
case 'download':
|
||||
return 'fas fa-download';
|
||||
case 'checkmark':
|
||||
return 'fas fa-check icon-white';
|
||||
return 'fas fa-check';
|
||||
case 'x':
|
||||
return 'fas fa-times';
|
||||
case 'logout':
|
||||
@@ -85,8 +90,11 @@ class IconHelper
|
||||
case 'licenses':
|
||||
case 'license':
|
||||
return 'far fa-save';
|
||||
case 'requests':
|
||||
case 'requestable':
|
||||
return 'fas fa-laptop';
|
||||
case 'request':
|
||||
case 'requested':
|
||||
return 'fa-solid fa-bell-concierge';
|
||||
case 'reports':
|
||||
return 'fas fa-chart-bar';
|
||||
case 'heart':
|
||||
@@ -129,9 +137,12 @@ class IconHelper
|
||||
return 'fa-regular fa-clipboard';
|
||||
case 'paperclip':
|
||||
return 'fas fa-paperclip';
|
||||
case 'contact-card':
|
||||
return 'fa-regular fa-id-card';
|
||||
case 'files':
|
||||
return 'fa-regular fa-file';
|
||||
case 'more-info':
|
||||
case 'support':
|
||||
return 'far fa-life-ring';
|
||||
case 'calendar':
|
||||
return 'fas fa-calendar';
|
||||
@@ -142,7 +153,7 @@ class IconHelper
|
||||
case 'more-files':
|
||||
return 'fa-solid fa-laptop-file';
|
||||
case 'maintenances':
|
||||
return 'fas fa-wrench';
|
||||
return 'fa-solid fa-screwdriver-wrench';
|
||||
case 'seats':
|
||||
return 'far fa-list-alt';
|
||||
case 'globe-us':
|
||||
@@ -201,6 +212,56 @@ class IconHelper
|
||||
return 'fa-solid fa-lightbulb';
|
||||
case 'highlight':
|
||||
return 'fa-solid fa-highlighter';
|
||||
case 'manager':
|
||||
return 'fa-solid fa-building-user';
|
||||
case 'company':
|
||||
return 'fa-regular fa-building';
|
||||
case 'parent':
|
||||
return 'fa-solid fa-building-flag';
|
||||
case 'number':
|
||||
return 'fa-solid fa-hashtag';
|
||||
case 'depreciation':
|
||||
return 'fa-solid fa-arrows-down-to-line';
|
||||
case 'depreciation-calendar':
|
||||
case 'expiration':
|
||||
case 'terminates':
|
||||
return 'fa-regular fa-calendar-xmark';
|
||||
case 'manufacturer':
|
||||
return 'fa-solid fa-industry';
|
||||
case 'fieldset' :
|
||||
return 'fa-regular fa-rectangle-list';
|
||||
case 'deleted-date':
|
||||
return 'fa-solid fa-calendar-xmark';
|
||||
case 'eol':
|
||||
return 'fa-regular fa-calendar-days';
|
||||
case 'category':
|
||||
return 'fa-solid fa-icons';
|
||||
case 'cost':
|
||||
return 'fa-solid fa-money-bills';
|
||||
case 'available':
|
||||
return 'fa-solid fa-box';
|
||||
case 'checkedout':
|
||||
return 'fa-solid fa-box-open';
|
||||
case 'purchase_order':
|
||||
return 'fa-solid fa-file-invoice-dollar';
|
||||
case 'order':
|
||||
return 'fa-solid fa-file-invoice';
|
||||
case 'checkout-all':
|
||||
return 'fa-solid fa-arrows-down-to-people';
|
||||
case 'square-right':
|
||||
return 'fa-regular fa-square-caret-right';
|
||||
case 'square-left':
|
||||
return 'fa-regular fa-square-caret-left';
|
||||
case 'square':
|
||||
return 'fa-solid fa-square';
|
||||
case 'models':
|
||||
case 'model':
|
||||
return 'fa-solid fa-boxes-stacked';
|
||||
case 'min-qty':
|
||||
return 'fa-solid fa-chart-pie';
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +90,10 @@ class AccessoriesController extends Controller
|
||||
$accessory = $request->handleImages($accessory);
|
||||
}
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
// Was the accessory created?
|
||||
@@ -182,10 +182,10 @@ class AccessoriesController extends Controller
|
||||
|
||||
$accessory = $request->handleImages($accessory);
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
if ($accessory->save()) {
|
||||
|
||||
@@ -76,7 +76,7 @@ class AccessoryCheckinController extends Controller
|
||||
if ($accessory_checkout->delete()) {
|
||||
event(new CheckoutableCheckedIn($accessory, $accessory_checkout->assignedTo, auth()->user(), $request->input('note'), $checkin_at));
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
return Helper::getRedirectOption($request, $accessory->id, 'Accessories')
|
||||
->with('success', trans('admin/accessories/message.checkin.success'));
|
||||
|
||||
@@ -67,7 +67,7 @@ class AccessoryCheckoutController extends Controller
|
||||
*/
|
||||
public function store(AccessoryCheckoutRequest $request, Accessory $accessory) : RedirectResponse
|
||||
{
|
||||
|
||||
|
||||
$this->authorize('checkout', $accessory);
|
||||
|
||||
$target = $this->determineCheckoutTarget();
|
||||
@@ -89,12 +89,19 @@ class AccessoryCheckoutController extends Controller
|
||||
$accessory_checkout->save();
|
||||
}
|
||||
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$accessory,
|
||||
$target,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$accessory->checkout_qty,
|
||||
));
|
||||
|
||||
$request->request->add(['checkout_to_type' => request('checkout_to_type')]);
|
||||
$request->request->add(['assigned_to' => $target->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
|
||||
// Redirect to the new accessory page
|
||||
|
||||
@@ -74,16 +74,16 @@ class AcceptanceController extends Controller
|
||||
*/
|
||||
public function store(Request $request, $id) : RedirectResponse
|
||||
{
|
||||
$acceptance = CheckoutAcceptance::find($id);
|
||||
|
||||
if (!$acceptance = CheckoutAcceptance::find($id)) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
$assigned_user = User::find($acceptance->assigned_to_id);
|
||||
$settings = Setting::getSettings();
|
||||
$sig_filename='';
|
||||
|
||||
|
||||
if (is_null($acceptance)) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
|
||||
if (! $acceptance->isPending()) {
|
||||
return redirect()->route('account.accept')->with('error', trans('admin/users/message.error.asset_already_accepted'));
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ class AccessoriesController extends Controller
|
||||
'company_id',
|
||||
'notes',
|
||||
'checkouts_count',
|
||||
'order_number',
|
||||
'qty',
|
||||
// These are *relationships* so we wouldn't normally include them in this array,
|
||||
// since they would normally create a `column not found` error,
|
||||
@@ -91,6 +92,10 @@ class AccessoriesController extends Controller
|
||||
$accessories->where('accessories.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('order_number')) {
|
||||
$accessories->where('accessories.order_number', '=', $request->input('order_number'));
|
||||
}
|
||||
|
||||
if ($request->filled('category_id')) {
|
||||
$accessories->where('category_id', '=', $request->input('category_id'));
|
||||
}
|
||||
@@ -325,7 +330,14 @@ class AccessoriesController extends Controller
|
||||
}
|
||||
|
||||
// Set this value to be able to pass the qty through to the event
|
||||
event(new CheckoutableCheckedOut($accessory, $target, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$accessory,
|
||||
$target,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$accessory->checkout_qty,
|
||||
));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $payload, trans('admin/accessories/message.checkout.success')));
|
||||
|
||||
@@ -389,7 +401,7 @@ class AccessoriesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$accessories = $accessories->where('accessories.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$accessories = $accessories->where('accessories.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$accessories = $accessories->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -249,7 +249,7 @@ class AssetModelsController extends Controller
|
||||
* it, but I'll be damned if I can think of one. - snipe
|
||||
*/
|
||||
if ($request->filled('custom_fieldset_id')) {
|
||||
$assetmodel->fieldset_id = $request->get('custom_fieldset_id');
|
||||
$assetmodel->fieldset_id = $request->input('custom_fieldset_id');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ use App\Http\Transformers\ComponentsTransformer;
|
||||
use App\Http\Transformers\LicensesTransformer;
|
||||
use App\Http\Transformers\SelectlistTransformer;
|
||||
use App\Models\AccessoryCheckout;
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\CheckoutAcceptance;
|
||||
@@ -153,6 +154,15 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
$assets = Asset::select('assets.*')
|
||||
// ->addSelect([
|
||||
// 'first_checkout_at' => Actionlog::query()
|
||||
// ->select('created_at')
|
||||
// ->whereColumn('item_id', 'assets.id')
|
||||
// ->where('item_type', Asset::class)
|
||||
// ->where('action_type', 'checkout')
|
||||
// ->orderBy('created_at')
|
||||
// ->limit(1),
|
||||
// ])
|
||||
->with(
|
||||
'model',
|
||||
'location',
|
||||
@@ -377,7 +387,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('order_number')) {
|
||||
$assets->where('assets.order_number', '=', strval($request->get('order_number')));
|
||||
$assets->where('assets.order_number', '=', strval($request->input('order_number')));
|
||||
}
|
||||
|
||||
// This is kinda gross, but we need to do this because the Bootstrap Tables
|
||||
@@ -654,7 +664,7 @@ class AssetsController extends Controller
|
||||
public function store(StoreAssetRequest $request): JsonResponse
|
||||
{
|
||||
$asset = new Asset();
|
||||
$asset->model()->associate(AssetModel::find((int) $request->get('model_id')));
|
||||
$asset->model()->associate(AssetModel::find((int) $request->input('model_id')));
|
||||
|
||||
$asset->fill($request->validated());
|
||||
$asset->created_by = auth()->id();
|
||||
@@ -683,8 +693,8 @@ class AssetsController extends Controller
|
||||
// If input value is null, use custom field's default value
|
||||
if ($field_val == null) {
|
||||
Log::debug('Field value for ' . $field->db_column . ' is null');
|
||||
$field_val = $field->defaultValue($request->get('model_id'));
|
||||
Log::debug('Use the default fieldset value of ' . $field->defaultValue($request->get('model_id')));
|
||||
$field_val = $field->defaultValue($request->input('model_id'));
|
||||
Log::debug('Use the default fieldset value of ' . $field->defaultValue($request->input('model_id')));
|
||||
}
|
||||
|
||||
// if the field is set to encrypted, make sure we encrypt the value
|
||||
@@ -695,7 +705,7 @@ class AssetsController extends Controller
|
||||
|
||||
// If input value is null, use custom field's default value
|
||||
if (($field_val == null) && ($request->has('model_id') != '')) {
|
||||
$field_val = Crypt::encrypt($field->defaultValue($request->get('model_id')));
|
||||
$field_val = Crypt::encrypt($field->defaultValue($request->input('model_id')));
|
||||
} else {
|
||||
$field_val = Crypt::encrypt($request->input($field->db_column));
|
||||
}
|
||||
@@ -713,15 +723,15 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($asset->save()) {
|
||||
if ($request->get('assigned_user')) {
|
||||
if ($request->input('assigned_user')) {
|
||||
$target = User::find(request('assigned_user'));
|
||||
} elseif ($request->get('assigned_asset')) {
|
||||
} elseif ($request->input('assigned_asset')) {
|
||||
$target = Asset::find(request('assigned_asset'));
|
||||
} elseif ($request->get('assigned_location')) {
|
||||
} elseif ($request->input('assigned_location')) {
|
||||
$target = Location::find(request('assigned_location'));
|
||||
}
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->get('name')));
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset creation', e($request->input('name')));
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
@@ -798,19 +808,22 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
if ($asset->save()) {
|
||||
if (($request->filled('assigned_user')) && ($target = User::find($request->get('assigned_user')))) {
|
||||
if (($request->filled('assigned_user')) && ($target = User::find($request->input('assigned_user')))) {
|
||||
$location = $target->location_id;
|
||||
} elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->get('assigned_asset')))) {
|
||||
} elseif (($request->filled('assigned_asset')) && ($target = Asset::find($request->input('assigned_asset')))) {
|
||||
$location = $target->location_id;
|
||||
|
||||
Asset::where('assigned_type', \App\Models\Asset::class)->where('assigned_to', $asset->id)
|
||||
->update(['location_id' => $target->location_id]);
|
||||
} elseif (($request->filled('assigned_location')) && ($target = Location::find($request->get('assigned_location')))) {
|
||||
} elseif (($request->filled('assigned_location')) && ($target = Location::find($request->input('assigned_location')))) {
|
||||
$location = $target->id;
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', e($request->get('name')), $location);
|
||||
// Using `->has` preserves the asset name if the name parameter was not included in request.
|
||||
$asset_name = request()->has('name') ? request('name') : $asset->name;
|
||||
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), '', 'Checked out on asset update', $asset_name, $location);
|
||||
}
|
||||
|
||||
if ($asset->image) {
|
||||
@@ -954,7 +967,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
if (! isset($target)) {
|
||||
@@ -1034,7 +1047,7 @@ class AssetsController extends Controller
|
||||
$checkin_at = $request->filled('checkin_at') ? $request->input('checkin_at') . ' ' . date('H:i:s') : date('Y-m-d H:i:s');
|
||||
$originalValues = $asset->getRawOriginal();
|
||||
|
||||
if (($request->filled('checkin_at')) && ($request->get('checkin_at') != date('Y-m-d'))) {
|
||||
if (($request->filled('checkin_at')) && ($request->input('checkin_at') != date('Y-m-d'))) {
|
||||
$originalValues['action_date'] = $checkin_at;
|
||||
}
|
||||
|
||||
@@ -1135,7 +1148,9 @@ class AssetsController extends Controller
|
||||
$payload = [
|
||||
'id' => $asset->id,
|
||||
'asset_tag' => $asset->asset_tag,
|
||||
'note' => $request->input('note'),
|
||||
'note' => e($request->input('note')),
|
||||
'status_label' => e($asset->assetstatus?->display_name),
|
||||
'status_type' => $asset->assetstatus->getStatuslabelType(),
|
||||
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date),
|
||||
];
|
||||
|
||||
@@ -1143,7 +1158,7 @@ class AssetsController extends Controller
|
||||
/**
|
||||
* Update custom fields in the database.
|
||||
* Validation for these fields is handled through the AssetRequest form request
|
||||
* $model = AssetModel::find($request->get('model_id'));
|
||||
* $model = AssetModel::find($request->input('model_id'));
|
||||
*/
|
||||
if (($asset->model) && ($asset->model->fieldset)) {
|
||||
$payload['custom_fields'] = [];
|
||||
|
||||
@@ -265,7 +265,7 @@ class CategoriesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$categories = $categories->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$categories = $categories->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$categories = $categories->where('category_type', $category_type)->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -202,7 +202,7 @@ class CompaniesController extends Controller
|
||||
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$companies = $companies->where('companies.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$companies = $companies->where('companies.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$companies = $companies->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -59,7 +59,7 @@ class ComponentsController extends Controller
|
||||
|
||||
$components = Component::select('components.*')
|
||||
->with('company', 'location', 'category', 'supplier', 'adminuser', 'manufacturer')
|
||||
->withSum('uncontrainedAssets as sum_unconstrained_assets', 'components_assets.assigned_qty');
|
||||
->withSum('unconstrainedAssets as sum_unconstrained_assets', 'components_assets.assigned_qty');
|
||||
|
||||
$filter = [];
|
||||
|
||||
@@ -87,6 +87,10 @@ class ComponentsController extends Controller
|
||||
$components->where('components.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('order_number')) {
|
||||
$components->where('components.order_number', '=', $request->input('order_number'));
|
||||
}
|
||||
|
||||
if ($request->filled('category_id')) {
|
||||
$components->where('category_id', '=', $request->input('category_id'));
|
||||
}
|
||||
@@ -303,11 +307,11 @@ class ComponentsController extends Controller
|
||||
}
|
||||
|
||||
// Make sure there is at least one available to checkout
|
||||
if ($component->numRemaining() < $request->get('assigned_qty')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->get('assigned_qty')])));
|
||||
if ($component->numRemaining() < $request->input('assigned_qty')) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->input('assigned_qty')])));
|
||||
}
|
||||
|
||||
if ($component->numRemaining() >= $request->get('assigned_qty')) {
|
||||
if ($component->numRemaining() >= $request->input('assigned_qty')) {
|
||||
|
||||
$asset = Asset::find($request->input('assigned_to'));
|
||||
$component->assigned_to = $request->input('assigned_to');
|
||||
@@ -315,18 +319,18 @@ class ComponentsController extends Controller
|
||||
$component->assets()->attach($component->id, [
|
||||
'component_id' => $component->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'assigned_qty' => $request->get('assigned_qty', 1),
|
||||
'assigned_qty' => $request->input('assigned_qty', 1),
|
||||
'created_by' => auth()->id(),
|
||||
'asset_id' => $request->get('assigned_to'),
|
||||
'note' => $request->get('note'),
|
||||
'asset_id' => $request->input('assigned_to'),
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
$component->logCheckout($request->input('note'), $asset);
|
||||
$component->logCheckout($request->input('note'), $asset, null, [], $request->get('assigned_qty', 1));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/components/message.checkout.success')));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->get('assigned_qty')])));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/components/message.checkout.unavailable', ['remaining' => $component->numRemaining(), 'requested' => $request->input('assigned_qty')])));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,6 +86,10 @@ class ConsumablesController extends Controller
|
||||
$consumables->where('consumables.company_id', '=', $request->input('company_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('order_number')) {
|
||||
$consumables->where('consumables.order_number', '=', $request->input('order_number'));
|
||||
}
|
||||
|
||||
if ($request->filled('category_id')) {
|
||||
$consumables->where('category_id', '=', $request->input('category_id'));
|
||||
}
|
||||
@@ -326,8 +330,14 @@ class ConsumablesController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
event(new CheckoutableCheckedOut($consumable, $user, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$consumable,
|
||||
$user,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$consumable->checkout_qty,
|
||||
));
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/consumables/message.checkout.success')));
|
||||
|
||||
@@ -346,7 +356,7 @@ class ConsumablesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$consumables = $consumables->where('consumables.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$consumables = $consumables->where('consumables.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$consumables = $consumables->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -195,7 +195,7 @@ class DepartmentsController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$departments = $departments->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$departments = $departments->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$departments = $departments->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -196,7 +196,7 @@ class ImportController extends Controller
|
||||
$this->authorize('import');
|
||||
|
||||
// Run a backup immediately before processing
|
||||
if ($request->get('run-backup')) {
|
||||
if ($request->input('run-backup')) {
|
||||
Log::debug('Backup manually requested via importer');
|
||||
Artisan::call('snipeit:backup', ['--filename' => 'pre-import-backup-'.date('Y-m-d-H-i-s')]);
|
||||
} else {
|
||||
@@ -212,7 +212,7 @@ class ImportController extends Controller
|
||||
|
||||
$errors = $request->import($import);
|
||||
$redirectTo = 'hardware.index';
|
||||
switch ($request->get('import-type')) {
|
||||
switch ($request->input('import-type')) {
|
||||
case 'asset':
|
||||
$model_perms = 'App\Models\Asset';
|
||||
$redirectTo = 'hardware.index';
|
||||
|
||||
@@ -24,7 +24,7 @@ class LabelsController extends Controller
|
||||
$labels = Label::find();
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$search = $request->get('search');
|
||||
$search = $request->input('search');
|
||||
$labels = $labels->filter(function ($label, $index) use ($search) {
|
||||
return stripos($label->getName(), $search) !== false;
|
||||
});
|
||||
@@ -32,11 +32,11 @@ class LabelsController extends Controller
|
||||
|
||||
$total = $labels->count();
|
||||
|
||||
$offset = $request->get('offset', 0);
|
||||
$offset = $request->input('offset', 0);
|
||||
$offset = ($offset > $total) ? $total : $offset;
|
||||
|
||||
$maxLimit = config('app.max_results');
|
||||
$limit = $request->get('limit', $maxLimit);
|
||||
$limit = $request->input('limit', $maxLimit);
|
||||
$limit = ($limit > $maxLimit) ? $maxLimit : $limit;
|
||||
|
||||
$labels = $labels->skip($offset)->take($limit);
|
||||
|
||||
@@ -37,6 +37,9 @@ class LicenseSeatsController extends Controller
|
||||
$seats->ByAssigned();
|
||||
}
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$seats->TextSearch($request->input('search'));
|
||||
}
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
@@ -98,24 +101,52 @@ class LicenseSeatsController extends Controller
|
||||
*/
|
||||
public function update(Request $request, $licenseId, $seatId) : JsonResponse | array
|
||||
{
|
||||
$validated = $this->validate($request, [
|
||||
'assigned_to' => [
|
||||
'sometimes',
|
||||
'int',
|
||||
'nullable',
|
||||
'prohibits:asset_id',
|
||||
// must be a valid user or null to unassign
|
||||
function ($attribute, $value, $fail) {
|
||||
if (!is_null($value) && !User::where('id', $value)->whereNull('deleted_at')->exists()) {
|
||||
$fail('The selected assigned_to is invalid.');
|
||||
}
|
||||
},
|
||||
],
|
||||
'asset_id' => [
|
||||
'sometimes',
|
||||
'int',
|
||||
'nullable',
|
||||
'prohibits:assigned_to',
|
||||
// must be a valid asset or null to unassign
|
||||
function ($attribute, $value, $fail) {
|
||||
if (!is_null($value) && !Asset::where('id', $value)->whereNull('deleted_at')->exists()) {
|
||||
$fail('The selected asset_id is invalid.');
|
||||
}
|
||||
},
|
||||
],
|
||||
'notes' => 'sometimes|string|nullable',
|
||||
]);
|
||||
|
||||
$this->authorize('checkout', License::class);
|
||||
|
||||
$licenseSeat = LicenseSeat::with(['license', 'asset', 'user'])->find($seatId);
|
||||
|
||||
if (! $licenseSeat = LicenseSeat::find($seatId)) {
|
||||
if (!$licenseSeat) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
|
||||
}
|
||||
|
||||
$license = $licenseSeat->license()->first();
|
||||
$license = $licenseSeat->license;
|
||||
if (!$license || $license->id != intval($licenseId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
|
||||
}
|
||||
|
||||
$oldUser = $licenseSeat->user()->first();
|
||||
$oldAsset = $licenseSeat->asset()->first();
|
||||
$oldUser = $licenseSeat->user;
|
||||
$oldAsset = $licenseSeat->asset;
|
||||
|
||||
// attempt to update the license seat
|
||||
$licenseSeat->fill($request->all());
|
||||
$licenseSeat->created_by = auth()->id();
|
||||
$licenseSeat->fill($validated);
|
||||
|
||||
// check if this update is a checkin operation
|
||||
// 1. are relevant fields touched at all?
|
||||
@@ -140,12 +171,17 @@ class LicenseSeatsController extends Controller
|
||||
if ($licenseSeat->isDirty('assigned_to')) {
|
||||
$target = $is_checkin ? $oldUser : User::find($licenseSeat->assigned_to);
|
||||
}
|
||||
|
||||
if ($licenseSeat->isDirty('asset_id')) {
|
||||
$target = $is_checkin ? $oldAsset : Asset::find($licenseSeat->asset_id);
|
||||
}
|
||||
|
||||
if ($assignmentTouched && is_null($target)){
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Target not found'));
|
||||
// if both asset_id and assigned_to are null then we are "checking-in"
|
||||
// a related model that does not exist (possible purged or bad data).
|
||||
if (!is_null($request->input('asset_id')) || !is_null($request->input('assigned_to'))) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Target not found'));
|
||||
}
|
||||
}
|
||||
|
||||
if ($licenseSeat->save()) {
|
||||
@@ -155,6 +191,7 @@ class LicenseSeatsController extends Controller
|
||||
$licenseSeat->unreassignable_seat = true;
|
||||
$licenseSeat->save();
|
||||
}
|
||||
// todo: skip if target is null?
|
||||
$licenseSeat->logCheckin($target, $licenseSeat->notes);
|
||||
} else {
|
||||
// in this case, relevant fields are touched but it's not a checkin operation. so it must be a checkout operation.
|
||||
|
||||
@@ -32,7 +32,7 @@ class LicensesController extends Controller
|
||||
$licenses->ExpiredLicenses();
|
||||
} elseif ($request->input('status')=='expiring') {
|
||||
$licenses->ExpiringLicenses($settings->alert_interval);
|
||||
} else {
|
||||
} elseif ($request->input('status')=='active') {
|
||||
$licenses->ActiveLicenses();
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ class LicensesController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$licenses = $licenses->where('licenses.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$licenses = $licenses->where('licenses.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$licenses = $licenses->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -200,7 +200,7 @@ class LocationsController extends Controller
|
||||
|
||||
// Only scope location if the setting is enabled
|
||||
if (Setting::getSettings()->scope_locations_fmcs) {
|
||||
$location->company_id = Company::getIdForCurrentUser($request->get('company_id'));
|
||||
$location->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
// check if parent is set and has a different company
|
||||
if ($location->parent_id && Location::find($location->parent_id)->company_id != $location->company_id) {
|
||||
response()->json(Helper::formatStandardApiResponse('error', null, 'different company than parent'));
|
||||
@@ -278,13 +278,13 @@ class LocationsController extends Controller
|
||||
if ($request->filled('company_id')) {
|
||||
// Only scope location if the setting is enabled
|
||||
if (Setting::getSettings()->scope_locations_fmcs) {
|
||||
$location->company_id = Company::getIdForCurrentUser($request->get('company_id'));
|
||||
$location->company_id = Company::getIdForCurrentUser($request->input('company_id'));
|
||||
// check if there are related objects with different company
|
||||
if (Helper::test_locations_fmcs(false, $id, $location->company_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'error scoped locations'));
|
||||
}
|
||||
} else {
|
||||
$location->company_id = $request->get('company_id');
|
||||
$location->company_id = $request->input('company_id');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ class MaintenancesController extends Controller
|
||||
'location',
|
||||
'is_warranty',
|
||||
'status_label',
|
||||
'model',
|
||||
'model_number',
|
||||
];
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
@@ -100,6 +102,12 @@ class MaintenancesController extends Controller
|
||||
case 'asset_name':
|
||||
$maintenances = $maintenances->OrderByAssetName($order);
|
||||
break;
|
||||
case 'model':
|
||||
$maintenances = $maintenances->OrderByAssetModelName($order);
|
||||
break;
|
||||
case 'model_number':
|
||||
$maintenances = $maintenances->OrderByAssetModelNumber($order);
|
||||
break;
|
||||
case 'serial':
|
||||
$maintenances = $maintenances->OrderByAssetSerial($order);
|
||||
break;
|
||||
|
||||
@@ -274,7 +274,7 @@ class ManufacturersController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$manufacturers = $manufacturers->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$manufacturers = $manufacturers->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$manufacturers = $manufacturers->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -145,7 +145,7 @@ class PredefinedKitsController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$kits = $kits->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$kits = $kits->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$kits = $kits->orderBy('name', 'ASC')->paginate(50);
|
||||
@@ -184,7 +184,7 @@ class PredefinedKitsController extends Controller
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$license_id = $request->get('license');
|
||||
$license_id = $request->input('license');
|
||||
$relation = $kit->licenses();
|
||||
if ($relation->find($license_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['license' => trans('admin/kits/general.license_error')]));
|
||||
@@ -254,7 +254,7 @@ class PredefinedKitsController extends Controller
|
||||
|
||||
$kit = PredefinedKit::findOrFail($kit_id);
|
||||
|
||||
$model_id = $request->get('model');
|
||||
$model_id = $request->input('model');
|
||||
$quantity = $request->input('quantity', 1);
|
||||
if ($quantity < 1) {
|
||||
$quantity = 1;
|
||||
@@ -332,7 +332,7 @@ class PredefinedKitsController extends Controller
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$consumable_id = $request->get('consumable');
|
||||
$consumable_id = $request->input('consumable');
|
||||
$relation = $kit->consumables();
|
||||
if ($relation->find($consumable_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['consumable' => trans('admin/kits/general.consumable_error')]));
|
||||
@@ -406,7 +406,7 @@ class PredefinedKitsController extends Controller
|
||||
$quantity = 1;
|
||||
}
|
||||
|
||||
$accessory_id = $request->get('accessory');
|
||||
$accessory_id = $request->input('accessory');
|
||||
$relation = $kit->accessories();
|
||||
if ($relation->find($accessory_id)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, ['accessory' => trans('admin/kits/general.accessory_error')]));
|
||||
|
||||
@@ -6,6 +6,7 @@ use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\ProfileTransformer;
|
||||
use App\Models\CheckoutRequest;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -182,19 +183,22 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function eulas(ProfileTransformer $transformer, Request $request)
|
||||
{
|
||||
if($request->filled('user_id') && $request->input('user_id') != 0) {
|
||||
// Return selected user's EULAs
|
||||
$eulas = User::find($request->input('user_id'))->eulas;
|
||||
}
|
||||
else {
|
||||
// Only return this user's EULAs
|
||||
|
||||
if (($request->filled('user_id')) && ($request->input( 'user_id') != 0)) {
|
||||
|
||||
$eula_user = User::find($request->input('user_id'));
|
||||
|
||||
if (($eula_user) && (Setting::getSettings()->manager_view_enabled) && (auth()->user()->isManagerOf($eula_user))) {
|
||||
$eulas = $eula_user->eulas;
|
||||
} else {
|
||||
return response()->json(Helper:: formatStandardApiResponse('error', null, trans('admin/users/message.user_not_found')));
|
||||
}
|
||||
} else {
|
||||
$eulas = auth()->user()->eulas;
|
||||
}
|
||||
|
||||
return response()->json(
|
||||
$transformer->transformFiles($eulas, $eulas->count())
|
||||
);
|
||||
return response()->json($transformer->transformFiles($eulas, $eulas->count()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ class SettingsController extends Controller
|
||||
|
||||
$login_attempts = DB::table('login_attempts');
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->get('sort'), $allowed_columns) ? $request->get('sort') : 'created_at';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
|
||||
$total = $login_attempts->count();
|
||||
$login_attempts->orderBy($sort, $order);
|
||||
|
||||
@@ -324,7 +324,7 @@ class StatuslabelsController extends Controller
|
||||
$statuslabels = Statuslabel::orderBy('default_label', 'desc')->orderBy('name', 'asc')->orderBy('deployable', 'desc');
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$statuslabels = $statuslabels->where('name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$statuslabels = $statuslabels->where('name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
if ($request->filled('deployable')) {
|
||||
|
||||
@@ -256,7 +256,7 @@ class SuppliersController extends Controller
|
||||
]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$suppliers = $suppliers->where('suppliers.name', 'LIKE', '%'.$request->get('search').'%');
|
||||
$suppliers = $suppliers->where('suppliers.name', 'LIKE', '%'.$request->input('search').'%');
|
||||
}
|
||||
|
||||
$suppliers = $suppliers->orderBy('name', 'ASC')->paginate(50);
|
||||
|
||||
@@ -93,7 +93,7 @@ class UploadedFilesController extends Controller
|
||||
|
||||
// Check the permissions to make sure the user can view the object
|
||||
$object = self::$map_object_type[$object_type]::withTrashed()->find($id);
|
||||
$this->authorize('view', $object);
|
||||
$this->authorize('update', $object);
|
||||
|
||||
if (!$object) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.file_upload_status.invalid_object')));
|
||||
@@ -110,15 +110,18 @@ class UploadedFilesController extends Controller
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile(self::$map_storage_path[$object_type], self::$map_file_prefix[$object_type].'-'.$object->id, $file);
|
||||
$files[] = $file_name;
|
||||
$object->logUpload($file_name, $request->get('notes'));
|
||||
$object->logUpload($file_name, $request->input('notes'));
|
||||
}
|
||||
|
||||
$files = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded')
|
||||
->where('item_type', '=', self::$map_object_type[$object_type])
|
||||
->where('item_id', '=', $id)->whereIn('filename', $files)
|
||||
->get();
|
||||
if (isset($files)) {
|
||||
$file_results = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded')
|
||||
->where('item_type', '=', self::$map_object_type[$object_type])
|
||||
->where('item_id', '=', $id)->whereIn('filename', $files)
|
||||
->get();
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UploadedFilesTransformer())->transformFiles($file_results, count($file_results)), trans_choice('general.file_upload_status.upload.success', count($files))));
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UploadedFilesTransformer())->transformFiles($files, count($files)), trans_choice('general.file_upload_status.upload.success', count($files))));
|
||||
}
|
||||
|
||||
// No files were submitted
|
||||
@@ -185,7 +188,7 @@ class UploadedFilesController extends Controller
|
||||
|
||||
// Check the permissions to make sure the user can view the object
|
||||
$object = self::$map_object_type[$object_type]::withTrashed()->find($id);
|
||||
$this->authorize('update', self::$map_object_type[$object_type]);
|
||||
$this->authorize('update', $object);
|
||||
|
||||
if (!$object) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('general.file_upload_status.invalid_object')));
|
||||
|
||||
@@ -253,7 +253,7 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('group_id')) {
|
||||
$users = $users->ByGroup($request->get('group_id'));
|
||||
$users = $users->ByGroup($request->input('group_id'));
|
||||
}
|
||||
|
||||
if ($request->filled('department_id')) {
|
||||
@@ -400,11 +400,11 @@ class UsersController extends Controller
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$users = $users->where(function ($query) use ($request) {
|
||||
$query->SimpleNameSearch($request->get('search'))
|
||||
->orWhere('username', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('display_name', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('email', 'LIKE', '%'.$request->get('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->get('search').'%');
|
||||
$query->SimpleNameSearch($request->input('search'))
|
||||
->orWhere('username', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('display_name', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('email', 'LIKE', '%'.$request->input('search').'%')
|
||||
->orWhere('employee_num', 'LIKE', '%'.$request->input('search').'%');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -450,16 +450,24 @@ class UsersController extends Controller
|
||||
if ($request->has('permissions')) {
|
||||
$permissions_array = $request->input('permissions');
|
||||
|
||||
// Strip out the superuser permission if the API user isn't a superadmin
|
||||
if (! auth()->user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
if ((is_array($permissions_array)) && (array_key_exists('superuser', $permissions_array))) {
|
||||
unset($permissions_array['superuser']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!auth()->user()->isAdmin()) {
|
||||
if ((is_array($permissions_array)) && (array_key_exists('admin', $permissions_array))) {
|
||||
unset($permissions_array['admin']);
|
||||
}
|
||||
}
|
||||
|
||||
$user->permissions = $permissions_array;
|
||||
}
|
||||
|
||||
//
|
||||
if ($request->filled('password')) {
|
||||
$user->password = bcrypt($request->get('password'));
|
||||
$user->password = bcrypt($request->input('password'));
|
||||
} else {
|
||||
$user->password = $user->noPassword();
|
||||
}
|
||||
@@ -478,12 +486,22 @@ class UsersController extends Controller
|
||||
|
||||
}
|
||||
|
||||
if ($request->filled('groups')) {
|
||||
|
||||
if (($request->has('groups')) && (auth()->user()->isSuperUser())) {
|
||||
|
||||
$validator = Validator::make($request->only('groups'), [
|
||||
'groups.*' => 'integer|exists:permission_groups,id',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, $validator->errors()));
|
||||
}
|
||||
|
||||
// Sync the groups since the user is a superuser and the groups pass validation
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
} else {
|
||||
$user->groups()->sync([]);
|
||||
}
|
||||
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', (new UsersTransformer)->transformUser($user), trans('admin/users/message.success.create')));
|
||||
}
|
||||
|
||||
@@ -520,8 +538,6 @@ class UsersController extends Controller
|
||||
*/
|
||||
public function update(SaveUserRequest $request, User $user): JsonResponse
|
||||
{
|
||||
$this->authorize('update', User::class);
|
||||
|
||||
$this->authorize('update', $user);
|
||||
|
||||
/**
|
||||
@@ -557,11 +573,43 @@ class UsersController extends Controller
|
||||
$user->activated = $request->input('activated');
|
||||
}
|
||||
|
||||
// We need to use has() instead of filled()
|
||||
// here because we need to overwrite permissions
|
||||
// if someone needs to null them out
|
||||
|
||||
if ($request->has('permissions')) {
|
||||
|
||||
$permissions_array = $request->input('permissions');
|
||||
$orig_permissions_array = $user->decodePermissions();
|
||||
|
||||
|
||||
// Strip out the individual superuser permission if the API user isn't a superadmin
|
||||
if (!auth()->user()->isSuperUser()) {
|
||||
|
||||
if (is_array($orig_permissions_array)) {
|
||||
if (array_key_exists('superuser', $orig_permissions_array)) {
|
||||
$permissions_array['superuser'] = $orig_permissions_array['superuser'];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Strip out the individual admin permission if the API user isn't an admin
|
||||
if ((!auth()->user()->isAdmin()) && (!auth()->user()->isSuperUser())) {
|
||||
|
||||
if (is_array($orig_permissions_array)) {
|
||||
if (array_key_exists('admin', $orig_permissions_array)) {
|
||||
$permissions_array['admin'] = $orig_permissions_array['admin'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is going to update the whole thing, not just what was passed
|
||||
$user->permissions = $permissions_array;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// We need to use has() instead of filled()
|
||||
// here because we need to overwrite permissions
|
||||
// if someone needs to null them out
|
||||
|
||||
if ($request->filled('display_name')) {
|
||||
$user->display_name = $request->input('display_name');
|
||||
@@ -576,17 +624,7 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($request->has('permissions')) {
|
||||
$permissions_array = $request->input('permissions');
|
||||
|
||||
// Strip out the individual superuser permission if the API user isn't a superadmin
|
||||
if (!auth()->user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
}
|
||||
|
||||
$user->permissions = $permissions_array;
|
||||
}
|
||||
|
||||
if ($request->has('location_id')) {
|
||||
// Update the location of any assets checked out to this user
|
||||
@@ -632,21 +670,27 @@ class UsersController extends Controller
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
|
||||
if ($user->delete()) {
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
|
||||
// Remove the user's avatar if they have one
|
||||
if (Storage::disk('public')->exists('avatars/' . $user->avatar)) {
|
||||
try {
|
||||
Storage::disk('public')->delete('avatars/' . $user->avatar);
|
||||
} catch (\Exception $e) {
|
||||
Log::debug($e);
|
||||
}
|
||||
if ($user->delete()) {
|
||||
|
||||
// Remove the user's avatar if they have one
|
||||
// @todo This should be done on purge, not here
|
||||
// if (Storage::disk('public')->exists('avatars/' . $user->avatar)) {
|
||||
// try {
|
||||
// Storage::disk('public')->delete('avatars/' . $user->avatar);
|
||||
// } catch (\Exception $e) {
|
||||
// Log::debug($e);
|
||||
// }
|
||||
// }
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('success', null, trans('admin/users/message.success.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 response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.error.delete')));
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/users/message.cannot_delete')));
|
||||
|
||||
}
|
||||
|
||||
@@ -795,7 +839,7 @@ class UsersController extends Controller
|
||||
|
||||
if ($request->filled('id')) {
|
||||
try {
|
||||
$user = User::find($request->get('id'));
|
||||
$user = User::find($request->input('id'));
|
||||
$this->authorize('update', $user);
|
||||
$user->two_factor_secret = null;
|
||||
$user->two_factor_enrolled = 0;
|
||||
|
||||
@@ -98,10 +98,10 @@ class AssetCheckinController extends Controller
|
||||
$asset->expected_checkin = null;
|
||||
$asset->assignedTo()->disassociate($asset);
|
||||
$asset->accepted = null;
|
||||
$asset->name = $request->get('name');
|
||||
$asset->name = $request->input('name');
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = e($request->get('status_id'));
|
||||
$asset->status_id = e($request->input('status_id'));
|
||||
}
|
||||
|
||||
// Add any custom fields that should be included in the checkout
|
||||
@@ -112,11 +112,11 @@ class AssetCheckinController extends Controller
|
||||
$asset->location_id = $asset->rtd_location_id;
|
||||
|
||||
if ($request->filled('location_id')) {
|
||||
Log::debug('NEW Location ID: '.$request->get('location_id'));
|
||||
$asset->location_id = $request->get('location_id');
|
||||
Log::debug('NEW Location ID: '.$request->input('location_id'));
|
||||
$asset->location_id = $request->input('location_id');
|
||||
|
||||
if ($request->get('update_default_location') == 0){
|
||||
$asset->rtd_location_id = $request->get('location_id');
|
||||
if ($request->input('update_default_location') == 0){
|
||||
$asset->rtd_location_id = $request->input('location_id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,9 +124,9 @@ class AssetCheckinController extends Controller
|
||||
|
||||
// Handle last checkin date
|
||||
$checkin_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkin_at')) && ($request->get('checkin_at') != date('Y-m-d'))) {
|
||||
if (($request->filled('checkin_at')) && ($request->input('checkin_at') != date('Y-m-d'))) {
|
||||
$originalValues['action_date'] = $checkin_at;
|
||||
$checkin_at = $request->get('checkin_at');
|
||||
$checkin_at = $request->input('checkin_at');
|
||||
|
||||
}
|
||||
$asset->last_checkin = $checkin_at;
|
||||
@@ -145,7 +145,7 @@ class AssetCheckinController extends Controller
|
||||
$acceptance->delete();
|
||||
});
|
||||
|
||||
session()->put('redirect_option', $request->get('redirect_option'));
|
||||
session()->put('redirect_option', $request->input('redirect_option'));
|
||||
|
||||
// Add any custom fields that should be included in the checkout
|
||||
$asset->customFieldsForCheckinCheckout('display_checkin');
|
||||
|
||||
@@ -88,17 +88,17 @@ class AssetCheckoutController extends Controller
|
||||
$asset = $this->updateAssetLocation($asset, $target);
|
||||
|
||||
$checkout_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkout_at')) && ($request->get('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->get('checkout_at');
|
||||
if (($request->filled('checkout_at')) && ($request->input('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->input('checkout_at');
|
||||
}
|
||||
|
||||
$expected_checkin = '';
|
||||
if ($request->filled('expected_checkin')) {
|
||||
$expected_checkin = $request->get('expected_checkin');
|
||||
$expected_checkin = $request->input('expected_checkin');
|
||||
}
|
||||
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
|
||||
@@ -123,9 +123,9 @@ class AssetCheckoutController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->get('note'), $request->get('name'))) {
|
||||
if ($asset->checkOut($target, $admin, $checkout_at, $expected_checkin, $request->input('note'), $request->input('name'))) {
|
||||
return Helper::getRedirectOption($request, $asset->id, 'Assets')
|
||||
->with('success', trans('admin/hardware/message.checkout.success'));
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ class AssetsController extends Controller
|
||||
}
|
||||
|
||||
if (isset($target)) {
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', $request->get('name'), $location);
|
||||
$asset->checkOut($target, auth()->user(), date('Y-m-d H:i:s'), $request->input('expected_checkin', null), 'Checked out on asset creation', $request->input('name'), $location);
|
||||
}
|
||||
|
||||
$successes[] = "<a href='" . route('hardware.show', $asset) . "' style='color: white;'>" . e($asset->asset_tag) . "</a>";
|
||||
@@ -266,13 +266,13 @@ class AssetsController extends Controller
|
||||
}
|
||||
DB::commit();
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
session()->put(['checkout_to_type' => $request->get('checkout_to_type'),
|
||||
session()->put(['checkout_to_type' => $request->input('checkout_to_type'),
|
||||
'other_redirect' => 'model' ]);
|
||||
|
||||
|
||||
@@ -454,7 +454,7 @@ class AssetsController extends Controller
|
||||
// Update custom fields in the database.
|
||||
// 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'));
|
||||
$model = AssetModel::find($request->input('model_id'));
|
||||
if (($model) && ($model->fieldset)) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
if ($field->element == 'checkbox' && !$request->has($field->db_column)) {
|
||||
@@ -480,9 +480,9 @@ class AssetsController extends Controller
|
||||
}
|
||||
}
|
||||
session()->put([
|
||||
'redirect_option' => $request->get('redirect_option'),
|
||||
'checkout_to_type' => $request->get('checkout_to_type'),
|
||||
'other_redirect' => $request->get('redirect_option') === 'other_redirect' ? 'model' : null,
|
||||
'redirect_option' => $request->input('redirect_option'),
|
||||
'checkout_to_type' => $request->input('checkout_to_type'),
|
||||
'other_redirect' => $request->input('redirect_option') === 'other_redirect' ? 'model' : null,
|
||||
]);
|
||||
|
||||
|
||||
@@ -552,9 +552,9 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function getAssetBySerial(Request $request) : RedirectResponse
|
||||
{
|
||||
$topsearch = ($request->get('topsearch')=="true");
|
||||
$topsearch = ($request->input('topsearch')=="true");
|
||||
|
||||
if (!$asset = Asset::where('serial', '=', $request->get('serial'))->first()) {
|
||||
if (!$asset = Asset::where('serial', '=', $request->input('serial'))->first()) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
|
||||
}
|
||||
$this->authorize('view', $asset);
|
||||
@@ -570,8 +570,8 @@ class AssetsController extends Controller
|
||||
*/
|
||||
public function getAssetByTag(Request $request, $tag=null) : RedirectResponse
|
||||
{
|
||||
$tag = $tag ? $tag : $request->get('assetTag');
|
||||
$topsearch = ($request->get('topsearch') == 'true');
|
||||
$tag = $tag ? $tag : $request->input('assetTag');
|
||||
$topsearch = ($request->input('topsearch') == 'true');
|
||||
|
||||
// Search for an exact and unique asset tag match
|
||||
$assets = Asset::where('asset_tag', '=', $tag);
|
||||
@@ -682,8 +682,8 @@ class AssetsController extends Controller
|
||||
return (new Label())
|
||||
->with('assets', collect([ $asset ]))
|
||||
->with('settings', Setting::getSettings())
|
||||
->with('template', request()->get('template'))
|
||||
->with('offset', request()->get('offset'))
|
||||
->with('template', request()->input('template'))
|
||||
->with('offset', request()->input('offset'))
|
||||
->with('bulkedit', false)
|
||||
->with('count', 0);
|
||||
}
|
||||
@@ -982,7 +982,7 @@ class AssetsController extends Controller
|
||||
|
||||
$this->authorize('audit', Asset::class);
|
||||
|
||||
session()->put('redirect_option', $request->get('redirect_option'));
|
||||
session()->put('redirect_option', $request->input('redirect_option'));
|
||||
session()->put('other_redirect', 'audit');
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Assets;
|
||||
|
||||
use App\Events\CheckoutablesCheckedOutInBulk;
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\CheckInOutRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
@@ -12,6 +13,7 @@ use App\Models\Setting;
|
||||
use App\View\Label;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Context;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
@@ -588,7 +590,7 @@ class BulkAssetsController extends Controller
|
||||
if ($request->session()->has('bulk_back_url')) {
|
||||
$bulk_back_url = $request->session()->pull('bulk_back_url');
|
||||
}
|
||||
$assetIds = $request->get('ids');
|
||||
$assetIds = $request->input('ids');
|
||||
|
||||
if(empty($assetIds)) {
|
||||
return redirect($bulk_back_url)->with('error', trans('admin/hardware/message.delete.nothing_updated'));
|
||||
@@ -644,6 +646,8 @@ class BulkAssetsController extends Controller
|
||||
*/
|
||||
public function storeCheckout(AssetCheckoutRequest $request) : RedirectResponse | ModelNotFoundException
|
||||
{
|
||||
Context::add('action', 'bulk_asset_checkout');
|
||||
|
||||
$this->authorize('checkout', Asset::class);
|
||||
|
||||
try {
|
||||
@@ -652,11 +656,11 @@ class BulkAssetsController extends Controller
|
||||
$target = $this->determineCheckoutTarget();
|
||||
session()->put(['checkout_to_type' => $target]);
|
||||
|
||||
if (! is_array($request->get('selected_assets'))) {
|
||||
if (! is_array($request->input('selected_assets'))) {
|
||||
return redirect()->route('hardware.bulkcheckout.show')->withInput()->with('error', trans('admin/hardware/message.checkout.no_assets_selected'));
|
||||
}
|
||||
|
||||
$asset_ids = array_filter($request->get('selected_assets'));
|
||||
$asset_ids = array_filter($request->input('selected_assets'));
|
||||
|
||||
$assets = Asset::findOrFail($asset_ids);
|
||||
|
||||
@@ -692,14 +696,14 @@ class BulkAssetsController extends Controller
|
||||
}
|
||||
}
|
||||
$checkout_at = date('Y-m-d H:i:s');
|
||||
if (($request->filled('checkout_at')) && ($request->get('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->get('checkout_at');
|
||||
if (($request->filled('checkout_at')) && ($request->input('checkout_at') != date('Y-m-d'))) {
|
||||
$checkout_at = $request->input('checkout_at');
|
||||
}
|
||||
|
||||
$expected_checkin = '';
|
||||
|
||||
if ($request->filled('expected_checkin')) {
|
||||
$expected_checkin = $request->get('expected_checkin');
|
||||
$expected_checkin = $request->input('expected_checkin');
|
||||
}
|
||||
|
||||
$errors = [];
|
||||
@@ -709,10 +713,10 @@ class BulkAssetsController extends Controller
|
||||
|
||||
// See if there is a status label passed
|
||||
if ($request->filled('status_id')) {
|
||||
$asset->status_id = $request->get('status_id');
|
||||
$asset->status_id = $request->input('status_id');
|
||||
}
|
||||
|
||||
$checkout_success = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->get('note')), $asset->name, null);
|
||||
$checkout_success = $asset->checkOut($target, $admin, $checkout_at, $expected_checkin, e($request->input('note')), $asset->name, null);
|
||||
|
||||
//TODO - I think this logic is duplicated in the checkOut method?
|
||||
if ($target->location_id != '') {
|
||||
@@ -730,6 +734,15 @@ class BulkAssetsController extends Controller
|
||||
});
|
||||
|
||||
if (! $errors) {
|
||||
CheckoutablesCheckedOutInBulk::dispatch(
|
||||
$assets,
|
||||
$target,
|
||||
$admin,
|
||||
$checkout_at,
|
||||
$expected_checkin,
|
||||
e($request->get('note')),
|
||||
);
|
||||
|
||||
// Redirect to the new asset page
|
||||
return redirect()->to('hardware')->with('success', trans_choice('admin/hardware/message.multi-checkout.success', $asset_ids));
|
||||
}
|
||||
@@ -743,7 +756,7 @@ class BulkAssetsController extends Controller
|
||||
public function restore(Request $request) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', Asset::class);
|
||||
$assetIds = $request->get('ids');
|
||||
$assetIds = $request->input('ids');
|
||||
|
||||
if (empty($assetIds)) {
|
||||
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.restore.nothing_updated'));
|
||||
|
||||
@@ -98,7 +98,7 @@ class ComponentCheckinController extends Controller
|
||||
|
||||
event(new CheckoutableCheckedIn($component, $asset, auth()->user(), $request->input('note'), Carbon::now()));
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||
->with('success', trans('admin/components/message.checkin.success'));
|
||||
|
||||
@@ -80,8 +80,8 @@ class ComponentCheckoutController extends Controller
|
||||
$max_to_checkout = $component->numRemaining();
|
||||
|
||||
// Make sure there are at least the requested number of components available to checkout
|
||||
if ($max_to_checkout < $request->get('assigned_qty')) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/components/message.checkout.unavailable', ['remaining' => $max_to_checkout, 'requested' => $request->get('assigned_qty')]));
|
||||
if ($max_to_checkout < $request->input('assigned_qty')) {
|
||||
return redirect()->back()->withInput()->with('error', trans('admin/components/message.checkout.unavailable', ['remaining' => $max_to_checkout, 'requested' => $request->input('assigned_qty')]));
|
||||
}
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
@@ -115,12 +115,19 @@ class ComponentCheckoutController extends Controller
|
||||
'note' => $request->input('note'),
|
||||
]);
|
||||
|
||||
event(new CheckoutableCheckedOut($component, $asset, auth()->user(), $request->input('note')));
|
||||
event(new CheckoutableCheckedOut(
|
||||
$component,
|
||||
$asset,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$component->checkout_qty,
|
||||
));
|
||||
|
||||
$request->request->add(['checkout_to_type' => 'asset']);
|
||||
$request->request->add(['assigned_asset' => $asset->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||
->with('success', trans('admin/components/message.checkout.success'));
|
||||
|
||||
@@ -7,8 +7,8 @@ use App\Http\Requests\ImageUploadRequest;
|
||||
use App\Models\Company;
|
||||
use App\Models\Component;
|
||||
use App\Helpers\Helper;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
@@ -88,10 +88,10 @@ class ComponentsController extends Controller
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ class ComponentsController extends Controller
|
||||
|
||||
$component = $request->handleImages($component);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($component->save()) {
|
||||
return Helper::getRedirectOption($request, $component->id, 'Components')
|
||||
@@ -226,6 +226,20 @@ class ComponentsController extends Controller
|
||||
public function show(Component $component)
|
||||
{
|
||||
$this->authorize('view', $component);
|
||||
return view('components/view', compact('component'));
|
||||
return view('components/view', compact('component'))->with('snipe_component', $component);
|
||||
}
|
||||
|
||||
public function getClone(Component $component) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('create', Component::class);
|
||||
|
||||
$cloned_component = clone $component;
|
||||
$cloned_component->id = null;
|
||||
$cloned_component->deleted_at = null;
|
||||
|
||||
// Show the page
|
||||
return view('components/edit')
|
||||
->with('item', $cloned_component)
|
||||
->with('component', $cloned_component);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,12 +102,20 @@ class ConsumableCheckoutController extends Controller
|
||||
}
|
||||
|
||||
$consumable->checkout_qty = $quantity;
|
||||
event(new CheckoutableCheckedOut($consumable, $user, auth()->user(), $request->input('note')));
|
||||
|
||||
event(new CheckoutableCheckedOut(
|
||||
$consumable,
|
||||
$user,
|
||||
auth()->user(),
|
||||
$request->input('note'),
|
||||
[],
|
||||
$consumable->checkout_qty,
|
||||
));
|
||||
|
||||
$request->request->add(['checkout_to_type' => 'user']);
|
||||
$request->request->add(['assigned_user' => $user->id]);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => $request->get('checkout_to_type')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => $request->input('checkout_to_type')]);
|
||||
|
||||
|
||||
// Redirect to the new consumable page
|
||||
|
||||
@@ -98,10 +98,10 @@ class ConsumablesController extends Controller
|
||||
$consumable = $request->handleImages($consumable);
|
||||
}
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ class ConsumablesController extends Controller
|
||||
|
||||
$consumable = $request->handleImages($consumable);
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($consumable->save()) {
|
||||
return Helper::getRedirectOption($request, $consumable->id, 'Consumables')
|
||||
|
||||
@@ -32,15 +32,16 @@ use App\Models\Location;
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\Supplier;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Traits\DisablesDebugbar;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
abstract class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
use AuthorizesRequests, DisablesDebugbar, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
static $map_object_type = [
|
||||
'accessories' => Accessory::class,
|
||||
|
||||
@@ -112,9 +112,9 @@ class CustomFieldsController extends Controller
|
||||
|
||||
|
||||
if ($request->filled('custom_format')) {
|
||||
$field->format = $request->get('custom_format');
|
||||
$field->format = $request->input('custom_format');
|
||||
} else {
|
||||
$field->format = $request->get('format');
|
||||
$field->format = $request->input('format');
|
||||
}
|
||||
|
||||
if ($field->save()) {
|
||||
@@ -225,34 +225,34 @@ class CustomFieldsController extends Controller
|
||||
public function update(CustomFieldRequest $request, CustomField $field) : RedirectResponse
|
||||
{
|
||||
$this->authorize('update', CustomField::class);
|
||||
$show_in_email = $request->get("show_in_email", 0);
|
||||
$display_in_user_view = $request->get("display_in_user_view", 0);
|
||||
$show_in_email = $request->input("show_in_email", 0);
|
||||
$display_in_user_view = $request->input("display_in_user_view", 0);
|
||||
|
||||
// Override the display settings if the field is encrypted
|
||||
if ($request->get("field_encrypted") == '1') {
|
||||
if ($request->input("field_encrypted") == '1') {
|
||||
$show_in_email = '0';
|
||||
$display_in_user_view = '0';
|
||||
}
|
||||
|
||||
$field->name = trim($request->get("name"));
|
||||
$field->element = $request->get("element");
|
||||
$field->field_values = $request->get("field_values");
|
||||
$field->name = trim($request->input("name"));
|
||||
$field->element = $request->input("element");
|
||||
$field->field_values = $request->input("field_values");
|
||||
$field->created_by = auth()->id();
|
||||
$field->help_text = $request->get("help_text");
|
||||
$field->help_text = $request->input("help_text");
|
||||
$field->show_in_email = $show_in_email;
|
||||
$field->is_unique = $request->get("is_unique", 0);
|
||||
$field->is_unique = $request->input("is_unique", 0);
|
||||
$field->display_in_user_view = $display_in_user_view;
|
||||
$field->auto_add_to_fieldsets = $request->get("auto_add_to_fieldsets", 0);
|
||||
$field->show_in_listview = $request->get("show_in_listview", 0);
|
||||
$field->show_in_requestable_list = $request->get("show_in_requestable_list", 0);
|
||||
$field->display_checkin = $request->get("display_checkin", 0);
|
||||
$field->display_checkout = $request->get("display_checkout", 0);
|
||||
$field->display_audit = $request->get("display_audit", 0);
|
||||
$field->auto_add_to_fieldsets = $request->input("auto_add_to_fieldsets", 0);
|
||||
$field->show_in_listview = $request->input("show_in_listview", 0);
|
||||
$field->show_in_requestable_list = $request->input("show_in_requestable_list", 0);
|
||||
$field->display_checkin = $request->input("display_checkin", 0);
|
||||
$field->display_checkout = $request->input("display_checkout", 0);
|
||||
$field->display_audit = $request->input("display_audit", 0);
|
||||
|
||||
if ($request->get('format') == 'CUSTOM REGEX') {
|
||||
$field->format = $request->get('custom_format');
|
||||
if ($request->input('format') == 'CUSTOM REGEX') {
|
||||
$field->format = $request->input('custom_format');
|
||||
} else {
|
||||
$field->format = $request->get('format');
|
||||
$field->format = $request->input('format');
|
||||
}
|
||||
|
||||
if ($field->element == 'checkbox' || $field->element == 'radio'){
|
||||
|
||||
@@ -74,7 +74,7 @@ class CustomFieldsetsController extends Controller
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
|
||||
return view('custom_fields.fieldsets.edit')->with('item', new CustomFieldset());
|
||||
return view('custom_fields.fieldsets.view')->with('custom_fieldset', new CustomFieldset());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +91,7 @@ class CustomFieldsetsController extends Controller
|
||||
$this->authorize('create', CustomField::class);
|
||||
|
||||
$fieldset = new CustomFieldset([
|
||||
'name' => $request->get('name'),
|
||||
'name' => $request->input('name'),
|
||||
'created_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
@@ -127,7 +127,7 @@ class CustomFieldsetsController extends Controller
|
||||
public function edit(CustomFieldset $fieldset) : View | RedirectResponse
|
||||
{
|
||||
$this->authorize('create', CustomField::class);
|
||||
return view('custom_fields.fieldsets.edit')->with('item', $fieldset);
|
||||
return view('custom_fields.fieldsets.view')->with('custom_fieldset', $fieldset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -44,7 +44,11 @@ class GroupsController extends Controller
|
||||
$permissions = config('permissions');
|
||||
$groupPermissions = Helper::selectedPermissionsArray($permissions, $permissions);
|
||||
$selectedPermissions = $request->old('permissions', $groupPermissions);
|
||||
$users_query = User::where('show_in_list', 1)->whereNull('deleted_at');
|
||||
$users_query = User::query()
|
||||
->select(['users.id', 'users.first_name', 'users.last_name', 'users.username'])
|
||||
->where('show_in_list', 1)
|
||||
->whereNull('deleted_at');
|
||||
|
||||
$users_count = $users_query->count();
|
||||
|
||||
$users = collect();
|
||||
@@ -55,7 +59,7 @@ class GroupsController extends Controller
|
||||
// Show the page
|
||||
return view('groups/edit', compact('permissions', 'selectedPermissions', 'groupPermissions'))
|
||||
->with('group', $group)
|
||||
->with('associated_users', [])
|
||||
->with('associated_users', collect())
|
||||
->with('unselected_users', $users)
|
||||
->with('all_users_count', $users_count);
|
||||
}
|
||||
@@ -114,8 +118,11 @@ class GroupsController extends Controller
|
||||
|
||||
$selected_array = Helper::selectedPermissionsArray($permissions, $groupPermissions);
|
||||
|
||||
$users_query = User::query()
|
||||
->select(['users.id', 'users.first_name', 'users.last_name', 'users.username'])
|
||||
->where('show_in_list', 1)
|
||||
->whereNull('deleted_at');
|
||||
|
||||
$users_query = User::where('show_in_list', 1)->whereNull('deleted_at');
|
||||
$users_count = $users_query->count();
|
||||
|
||||
$associated_users = collect();
|
||||
@@ -124,7 +131,13 @@ class GroupsController extends Controller
|
||||
if ($users_count <= config('app.max_unpaginated_records')) {
|
||||
$associated_users = $group->users()->where('show_in_list', 1)->orderBy('first_name', 'asc')->orderBy('last_name', 'asc')->get();
|
||||
// Get the unselected users
|
||||
$unselected_users = User::where('show_in_list', 1)->whereNotIn('id', $associated_users->pluck('id')->toArray())->orderBy('first_name', 'asc')->orderBy('last_name', 'asc')->get();
|
||||
$unselected_users = User::query()
|
||||
->select(['users.id', 'users.first_name', 'users.last_name', 'users.username'])
|
||||
->where('show_in_list', 1)
|
||||
->whereNotIn('id', $associated_users->pluck('id')->toArray())
|
||||
->orderBy('first_name', 'asc')
|
||||
->orderBy('last_name', 'asc')
|
||||
->get();
|
||||
}
|
||||
|
||||
return view('groups.edit', compact('group', 'permissions', 'selected_array', 'groupPermissions'))
|
||||
|
||||
@@ -28,23 +28,41 @@ class HealthController extends BaseController
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
if (DB::select('select 2 + 2')) {
|
||||
return response()->json([
|
||||
'status' => 'ok',
|
||||
]);
|
||||
$db_status = 'ok';
|
||||
} else {
|
||||
$db_status = 'Could not connect to database';
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('Could not connect to database');
|
||||
return response()->json([
|
||||
'status' => 'database connection failed',
|
||||
], 500);
|
||||
$db_status = 'Could not connect to database';
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (is_writable(storage_path('logs'))) {
|
||||
$filesystem_status = 'ok';
|
||||
} else {
|
||||
$filesystem_status = 'Could not write to storage/logs';
|
||||
}
|
||||
|
||||
if (($filesystem_status!='ok') || ($db_status!='ok')) {
|
||||
return response()->json([
|
||||
'status' =>
|
||||
[
|
||||
'database' => $db_status,
|
||||
'filesystem' => $filesystem_status,
|
||||
]
|
||||
], 500);
|
||||
}
|
||||
|
||||
|
||||
return response()->json([
|
||||
'status' => 'ok',
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class CheckoutKitController extends Controller
|
||||
*/
|
||||
public function store(Request $request, $kit_id)
|
||||
{
|
||||
$user_id = e($request->get('user_id'));
|
||||
$user_id = e($request->input('user_id'));
|
||||
if (is_null($user = User::find($user_id))) {
|
||||
return redirect()->back()->with('error', trans('admin/users/message.user_not_found'));
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class LabelsController extends Controller
|
||||
|
||||
$settings = Setting::getSettings();
|
||||
if (request()->has('settings')) {
|
||||
$overrides = request()->get('settings');
|
||||
$overrides = request()->input('settings');
|
||||
foreach ($overrides as $key => $value) {
|
||||
$settings->$key = $value;
|
||||
}
|
||||
|
||||
@@ -97,8 +97,8 @@ class LicenseCheckinController extends Controller
|
||||
$licenseSeat->unreassignable_seat = true;
|
||||
}
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
if ($request->get('redirect_option') === 'target'){
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
if ($request->input('redirect_option') === 'target'){
|
||||
session()->put(['checkout_to_type' => 'user']);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,13 +96,13 @@ class LicenseCheckoutController extends Controller
|
||||
session()->put(['checkout_to_type' => 'asset']);
|
||||
$checkoutTarget = $this->checkoutToAsset($licenseSeat);
|
||||
$request->request->add(['assigned_asset' => $checkoutTarget->id]);
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => 'asset']);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => 'asset']);
|
||||
|
||||
} elseif ($request->filled('assigned_to')) {
|
||||
session()->put(['checkout_to_type' => 'user']);
|
||||
$checkoutTarget = $this->checkoutToUser($licenseSeat);
|
||||
$request->request->add(['assigned_user' => $checkoutTarget->id]);
|
||||
session()->put(['redirect_option' => $request->get('redirect_option'), 'checkout_to_type' => 'user']);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option'), 'checkout_to_type' => 'user']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -102,10 +102,10 @@ class LicensesController extends Controller
|
||||
$license->created_by = auth()->id();
|
||||
$license->min_amt = $request->input('min_amt');
|
||||
|
||||
if($request->get('redirect_option') === 'back'){
|
||||
if($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
if ($license->save()) {
|
||||
@@ -183,7 +183,7 @@ class LicensesController extends Controller
|
||||
$license->category_id = $request->input('category_id');
|
||||
$license->min_amt = $request->input('min_amt');
|
||||
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($license->save()) {
|
||||
return Helper::getRedirectOption($request, $license->id, 'Licenses')
|
||||
@@ -315,7 +315,8 @@ class LicensesController extends Controller
|
||||
public function getExportLicensesCsv()
|
||||
{
|
||||
$this->authorize('view', License::class);
|
||||
\Debugbar::disable();
|
||||
|
||||
$this->disableDebugbar();
|
||||
|
||||
$response = new StreamedResponse(function () {
|
||||
// Open output stream
|
||||
|
||||
@@ -38,7 +38,7 @@ class ModalController extends Controller
|
||||
|
||||
|
||||
if (in_array($type, $allowed_types)) {
|
||||
$view = view("modals.${type}");
|
||||
$view = view("modals.{$type}");
|
||||
|
||||
if ($type == "statuslabel") {
|
||||
$view->with('statuslabel_types', Helper::statusTypeList());
|
||||
|
||||
@@ -19,7 +19,8 @@ class ReportTemplatesController extends Controller
|
||||
|
||||
$report = $request->user()->reportTemplates()->create([
|
||||
'name' => $validated['name'],
|
||||
'options' => $request->except(['_token', 'name']),
|
||||
'options' => $request->except(['_token', 'name', 'is_shared']),
|
||||
'is_shared' => $request->has('is_shared'),
|
||||
]);
|
||||
|
||||
session()->flash('success', trans('admin/reports/message.create.success'));
|
||||
@@ -45,6 +46,12 @@ class ReportTemplatesController extends Controller
|
||||
{
|
||||
$this->authorize('reports.view');
|
||||
|
||||
if ($reportTemplate->created_by != auth()->id()) {
|
||||
return redirect()
|
||||
->route('report-templates.show', $reportTemplate)
|
||||
->withError(trans('general.report_not_editable'));
|
||||
}
|
||||
|
||||
return view('reports/custom', [
|
||||
'customfields' => CustomField::get(),
|
||||
'template' => $reportTemplate,
|
||||
@@ -55,13 +62,29 @@ class ReportTemplatesController extends Controller
|
||||
{
|
||||
$this->authorize('reports.view');
|
||||
|
||||
// Ignore "options" rules since data does not come in under that key...
|
||||
$validated = $request->validate(Arr::except((new ReportTemplate)->getRules(), 'options'));
|
||||
if ($reportTemplate->created_by != auth()->id()) {
|
||||
return redirect()
|
||||
->route('report-templates.show', $reportTemplate)
|
||||
->withError(trans('general.report_not_editable'));
|
||||
}
|
||||
|
||||
$reportTemplate->update([
|
||||
'name' => $validated['name'],
|
||||
'options' => $request->except(['_token', 'name']),
|
||||
]);
|
||||
$properties = [
|
||||
'name' => $request->input('name'),
|
||||
'options' => Arr::except($request->all(), ['_token', 'id', 'name', 'is_shared']),
|
||||
'is_shared' => $reportTemplate->is_shared,
|
||||
];
|
||||
|
||||
if ($reportTemplate->created_by == $request->user()->id) {
|
||||
$properties['is_shared'] = $request->boolean('is_shared');
|
||||
}
|
||||
|
||||
$reportTemplate->fill($properties);
|
||||
|
||||
if ($reportTemplate->isInvalid()) {
|
||||
return redirect()->back()->withInput()->withErrors($reportTemplate->getErrors());
|
||||
}
|
||||
|
||||
$reportTemplate->save();
|
||||
|
||||
session()->flash('success', trans('admin/reports/message.update.success'));
|
||||
|
||||
@@ -72,6 +95,12 @@ class ReportTemplatesController extends Controller
|
||||
{
|
||||
$this->authorize('reports.view');
|
||||
|
||||
if ($reportTemplate->creator()->isNot(auth()->user())) {
|
||||
return redirect()
|
||||
->route('report-templates.show', $reportTemplate)
|
||||
->withError(trans('general.generic_model_not_found', ['model' => 'report template']));
|
||||
}
|
||||
|
||||
$reportTemplate->delete();
|
||||
|
||||
return redirect()->route('reports/custom')
|
||||
|
||||
@@ -40,6 +40,7 @@ use League\Csv\EscapeFormula;
|
||||
use App\Http\Requests\CustomAssetReportRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use function Livewire\before;
|
||||
|
||||
/**
|
||||
* This controller handles all actions related to Reports for
|
||||
@@ -242,7 +243,8 @@ class ReportsController extends Controller
|
||||
ini_set('max_execution_time', 12000);
|
||||
$this->authorize('reports.view');
|
||||
|
||||
\Debugbar::disable();
|
||||
$this->disableDebugbar();
|
||||
|
||||
$response = new StreamedResponse(function () {
|
||||
Log::debug('Starting streamed response');
|
||||
|
||||
@@ -437,8 +439,8 @@ class ReportsController extends Controller
|
||||
ini_set('max_execution_time', env('REPORT_TIME_LIMIT', 12000)); //12000 seconds = 200 minutes
|
||||
$this->authorize('reports.view');
|
||||
|
||||
$this->disableDebugbar();
|
||||
|
||||
\Debugbar::disable();
|
||||
$customfields = CustomField::get();
|
||||
$response = new StreamedResponse(function () use ($customfields, $request) {
|
||||
Log::debug('Starting streamed response');
|
||||
@@ -452,6 +454,10 @@ class ReportsController extends Controller
|
||||
|
||||
$header = [];
|
||||
|
||||
if($request->filled('is_shared')) {
|
||||
$header[] = trans('admin/reports/general.share_template');
|
||||
}
|
||||
|
||||
if ($request->filled('id')) {
|
||||
$header[] = trans('general.id');
|
||||
}
|
||||
@@ -549,6 +555,14 @@ class ReportsController extends Controller
|
||||
$header[] = 'Username';
|
||||
}
|
||||
|
||||
if ($request->filled('user_company')) {
|
||||
$header[] = trans('admin/reports/general.custom_export.user_company');
|
||||
}
|
||||
|
||||
if ($request->filled('email')) {
|
||||
$header[] = 'Email';
|
||||
}
|
||||
|
||||
if ($request->filled('employee_num')) {
|
||||
$header[] = 'Employee No.';
|
||||
}
|
||||
@@ -589,6 +603,10 @@ class ReportsController extends Controller
|
||||
$header[] = trans('admin/reports/general.custom_export.user_zip');
|
||||
}
|
||||
|
||||
if ($request->filled('target_notes')) {
|
||||
$header[] = trans('admin/reports/general.custom_export.target_notes');
|
||||
}
|
||||
|
||||
if ($request->filled('status')) {
|
||||
$header[] = trans('general.status');
|
||||
}
|
||||
@@ -646,7 +664,14 @@ class ReportsController extends Controller
|
||||
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
|
||||
Log::debug('Added headers: '.$executionTime);
|
||||
|
||||
$assets = Asset::select('assets.*')->with(
|
||||
if($request->filled('is_shared')) {
|
||||
//to fill with logic for the report template and NOT the assets retrieved by the query
|
||||
//do we scope here or??
|
||||
}
|
||||
|
||||
|
||||
|
||||
$assets = Asset::select('assets.*')->with(
|
||||
'location', 'assetstatus', 'company', 'defaultLoc', 'assignedTo',
|
||||
'model.category', 'model.manufacturer', 'supplier');
|
||||
|
||||
@@ -753,9 +778,15 @@ class ReportsController extends Controller
|
||||
$assets->whereBetween('assets.updated_at', [$request->input('last_updated_start'), $request->input('last_updated_end')]);
|
||||
}
|
||||
|
||||
if(($request->filled('last_updated_before'))){
|
||||
$last_updated_window = Carbon::parse(today()->subDays($request->input('last_updated_before')));
|
||||
$assets->where('assets.updated_at', '<' , $last_updated_window);
|
||||
}
|
||||
|
||||
if ($request->filled('exclude_archived')) {
|
||||
$assets->notArchived();
|
||||
}
|
||||
|
||||
if ($request->input('deleted_assets') == 'include_deleted') {
|
||||
$assets->withTrashed();
|
||||
}
|
||||
@@ -763,7 +794,6 @@ class ReportsController extends Controller
|
||||
$assets->onlyTrashed();
|
||||
}
|
||||
|
||||
Log::debug($assets->toSql());
|
||||
$assets->orderBy('assets.id', 'ASC')->chunk(500, function ($assets) use ($handle, $customfields, $request) {
|
||||
|
||||
$executionTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
|
||||
@@ -818,7 +848,7 @@ class ReportsController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('eol')) {
|
||||
$row[] = ($asset->purchase_date != '') ? $asset->asset_eol_date : '';
|
||||
$row[] = ($asset->asset_eol_date != '') ? $asset->asset_eol_date : '';
|
||||
}
|
||||
|
||||
if ($request->filled('warranty')) {
|
||||
@@ -882,6 +912,23 @@ class ReportsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('user_company')) {
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = ($asset->assignedto->company) ? $asset->assignedto->company->display_name : '';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('email')) {
|
||||
// Only works if we're checked out to a user, not anything else.
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = ($asset->assignedto) ? $asset->assignedto->email : '';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('employee_num')) {
|
||||
// Only works if we're checked out to a user, not anything else.
|
||||
if ($asset->checkedOutToUser()) {
|
||||
@@ -963,6 +1010,15 @@ class ReportsController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('target_notes')) {
|
||||
if ($asset->checkedOutToUser()) {
|
||||
$row[] = ($asset->assignedto) ? $asset->assignedto->notes : '';
|
||||
} else {
|
||||
$row[] = ''; // Empty string if unassigned
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($request->filled('status')) {
|
||||
$row[] = ($asset->assetstatus) ? $asset->assetstatus->name.' ('.$asset->present()->statusMeta.')' : '';
|
||||
}
|
||||
@@ -1228,12 +1284,14 @@ class ReportsController extends Controller
|
||||
];
|
||||
$mailable= $lookup[get_class($acceptance->checkoutable)];
|
||||
|
||||
return new $mailable($acceptance->checkoutable,
|
||||
return new $mailable(
|
||||
$acceptance->checkoutable,
|
||||
$acceptance->checkedOutTo ?? $acceptance->assignedTo,
|
||||
$logItem->adminuser,
|
||||
$acceptance,
|
||||
$acceptance->note);
|
||||
|
||||
$acceptance->note,
|
||||
firstTimeSending: false,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* sentAssetAcceptanceReminder
|
||||
|
||||
@@ -114,7 +114,7 @@ class SettingsController extends Controller
|
||||
$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');
|
||||
$setting->require_accept_signature = $request->input('require_accept_signature', '0');
|
||||
$setting->show_assigned_assets = $request->input('show_assigned_assets', '0');
|
||||
if (! config('app.lock_passwords')) {
|
||||
$setting->login_note = $request->input('login_note');
|
||||
@@ -191,9 +191,9 @@ class SettingsController extends Controller
|
||||
$request->validate(['site_name' => 'required']);
|
||||
}
|
||||
|
||||
$setting->header_color = $request->input('header_color');
|
||||
$setting->header_color = $request->input('header_color', '#3c8dbc');
|
||||
$setting->link_light_color = $request->input('link_light_color', '#296282');
|
||||
$setting->link_dark_color = $request->input('link_dark_color', '#296282');
|
||||
$setting->link_dark_color = $request->input('link_dark_color', '#5fa4cc');
|
||||
$setting->nav_link_color = $request->input('nav_link_color', '#FFFFFF');
|
||||
|
||||
$setting->site_name = $request->input('site_name', 'Snipe-IT');
|
||||
@@ -403,24 +403,23 @@ class SettingsController extends Controller
|
||||
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
|
||||
}
|
||||
|
||||
// Check if the audit interval has changed - if it has, we want to update ALL of the assets audit dates
|
||||
if ($request->input('audit_interval') != $setting->audit_interval) {
|
||||
|
||||
// This could be a negative number if the user is trying to set the audit interval to a lower number than it was before
|
||||
$audit_diff_months = ((int)$request->input('audit_interval') - (int)($setting->audit_interval));
|
||||
// Check if the audit interval has changed - if it has, check if we should update all of the assets audit dates
|
||||
if ((($request->input('audit_interval') != $setting->audit_interval)) && ($request->input('update_existing_dates') == 1)) {
|
||||
|
||||
// Batch update the dates. We have to use this method to avoid time limit exceeded errors on very large datasets,
|
||||
// but it DOES mean this change doesn't get logged in the action logs, since it skips the observer.
|
||||
// @see https://stackoverflow.com/questions/54879160/laravel-observer-not-working-on-bulk-insert
|
||||
$affected = Asset::whereNotNull('next_audit_date')
|
||||
->whereNull('deleted_at')
|
||||
->update(
|
||||
['next_audit_date' => DB::raw('DATE_ADD(next_audit_date, INTERVAL '.$audit_diff_months.' MONTH)')]
|
||||
);
|
||||
|
||||
Log::debug($affected .' assets affected by audit interval update');
|
||||
// This could be a negative number if the user is trying to set the audit interval to a lower number than it was before
|
||||
$audit_diff_months = ((int)$request->input('audit_interval') - (int)($setting->audit_interval));
|
||||
|
||||
// Batch update the dates. We have to use this method to avoid time limit exceeded errors on very large datasets,
|
||||
// but it DOES mean this change doesn't get logged in the action logs, since it skips the observer.
|
||||
// @see https://stackoverflow.com/questions/54879160/laravel-observer-not-working-on-bulk-insert
|
||||
$affected = Asset::whereNotNull('next_audit_date')
|
||||
->whereNull('deleted_at')
|
||||
->update(
|
||||
['next_audit_date' => DB::raw('DATE_ADD(next_audit_date, INTERVAL ' . $audit_diff_months . ' MONTH)')]
|
||||
);
|
||||
|
||||
Log::debug($affected . ' assets affected by audit interval update');
|
||||
}
|
||||
|
||||
$alert_email = rtrim($request->input('alert_email'), ',');
|
||||
|
||||
@@ -56,7 +56,7 @@ class UploadedFilesController extends Controller
|
||||
foreach ($request->file('file') as $file) {
|
||||
$file_name = $request->handleFile(self::$map_storage_path[$object_type], self::$map_file_prefix[$object_type].'-'.$object->id, $file);
|
||||
$files[] = $file_name;
|
||||
$object->logUpload($file_name, $request->get('notes'));
|
||||
$object->logUpload($file_name, $request->input('notes'));
|
||||
}
|
||||
|
||||
$files = Actionlog::select('action_logs.*')->where('action_type', '=', 'uploaded')
|
||||
@@ -133,7 +133,7 @@ class UploadedFilesController extends Controller
|
||||
|
||||
// Check the permissions to make sure the user can view the object
|
||||
$object = self::$map_object_type[$object_type]::withTrashed()->find($id);
|
||||
$this->authorize('update', self::$map_object_type[$object_type]);
|
||||
$this->authorize('update', $object);
|
||||
|
||||
if (!$object) {
|
||||
return redirect()->back()->withFragment('files')->with('error',trans('general.file_upload_status.invalid_object'));
|
||||
|
||||
@@ -169,6 +169,7 @@ class BulkUsersController extends Controller
|
||||
->conditionallyAddItem('remote')
|
||||
->conditionallyAddItem('ldap_import')
|
||||
->conditionallyAddItem('activated')
|
||||
->conditionallyAddItem('display_name')
|
||||
->conditionallyAddItem('start_date')
|
||||
->conditionallyAddItem('end_date')
|
||||
->conditionallyAddItem('city')
|
||||
@@ -214,6 +215,10 @@ class BulkUsersController extends Controller
|
||||
$this->update_array['locale'] = null;
|
||||
}
|
||||
|
||||
if ($request->input('null_display_name')=='1') {
|
||||
$this->update_array['display_name'] = null;
|
||||
}
|
||||
|
||||
if (! $manager_conflict) {
|
||||
$this->conditionallyAddItem('manager_id');
|
||||
}
|
||||
@@ -229,8 +234,11 @@ class BulkUsersController extends Controller
|
||||
|
||||
// Only sync groups if groups were selected
|
||||
if ($request->filled('groups')) {
|
||||
|
||||
foreach ($users as $user) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +320,9 @@ class BulkUsersController extends Controller
|
||||
foreach ($users as $user) {
|
||||
$user->accessories()->sync([]);
|
||||
if ($request->input('delete_user')=='1') {
|
||||
$user->delete();
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
$user->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class UsersController extends Controller
|
||||
public function create(Request $request)
|
||||
{
|
||||
$this->authorize('create', User::class);
|
||||
$groups = Group::pluck('name', 'id');
|
||||
$groups = Group::orderBy('name', 'asc')->pluck('name', 'id');
|
||||
|
||||
$userGroups = collect();
|
||||
|
||||
@@ -122,18 +122,31 @@ class UsersController extends Controller
|
||||
// Strip out the superuser permission if the user isn't a superadmin
|
||||
$permissions_array = $request->input('permission');
|
||||
|
||||
if (! auth()->user()->isSuperUser()) {
|
||||
unset($permissions_array['superuser']);
|
||||
// Strip out the individual superuser permission if the API user isn't a superadmin
|
||||
if (!auth()->user()->isSuperUser()) {
|
||||
|
||||
if ((is_array($permissions_array)) && (array_key_exists('superuser', $permissions_array))) {
|
||||
unset($permissions_array['superuser']);
|
||||
}
|
||||
}
|
||||
|
||||
// Strip out the individual admin permission if the API user isn't an admin
|
||||
if (!auth()->user()->isAdmin()) {
|
||||
|
||||
if ((is_array($permissions_array)) && (array_key_exists('admin', $permissions_array))) {
|
||||
unset($permissions_array['admin']);
|
||||
}
|
||||
}
|
||||
|
||||
$user->permissions = json_encode($permissions_array);
|
||||
|
||||
// we have to invoke the form request here to handle image uploads
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
|
||||
if ($request->get('redirect_option') === 'back'){
|
||||
if ($request->input('redirect_option') === 'back'){
|
||||
session()->put(['redirect_option' => 'index']);
|
||||
} else {
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,7 +164,9 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
if ($request->filled('groups')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
$user->groups()->sync($request->input('groups'));
|
||||
}
|
||||
} else {
|
||||
$user->groups()->sync([]);
|
||||
}
|
||||
@@ -199,7 +214,7 @@ class UsersController extends Controller
|
||||
}
|
||||
|
||||
$permissions = config('permissions');
|
||||
$groups = Group::pluck('name', 'id');
|
||||
$groups = Group::orderBy('name', 'asc')->pluck('name', 'id');
|
||||
|
||||
$userGroups = $user->groups()->pluck('name', 'id');
|
||||
$user->permissions = $user->decodePermissions();
|
||||
@@ -325,7 +340,7 @@ class UsersController extends Controller
|
||||
|
||||
// Handle uploaded avatar
|
||||
app(ImageUploadRequest::class)->handleImages($user, 600, 'avatar', 'avatars', 'avatar');
|
||||
session()->put(['redirect_option' => $request->get('redirect_option')]);
|
||||
session()->put(['redirect_option' => $request->input('redirect_option')]);
|
||||
|
||||
if ($user->save()) {
|
||||
// Redirect to the user page
|
||||
@@ -351,10 +366,13 @@ class UsersController extends Controller
|
||||
if ($user = User::find($id)) {
|
||||
|
||||
$this->authorize('delete', $user);
|
||||
if (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo')) {
|
||||
|
||||
if ($user->delete()) {
|
||||
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.delete'));
|
||||
if ($user->delete()) {
|
||||
return redirect()->route('users.index')->with('success', trans('admin/users/message.success.delete'));
|
||||
}
|
||||
}
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.cannot_delete'));
|
||||
}
|
||||
return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found'));
|
||||
|
||||
@@ -505,7 +523,8 @@ class UsersController extends Controller
|
||||
public function getExportUserCsv()
|
||||
{
|
||||
$this->authorize('view', User::class);
|
||||
\Debugbar::disable();
|
||||
|
||||
$this->disableDebugbar();
|
||||
|
||||
$response = new StreamedResponse(function () {
|
||||
// Open output stream
|
||||
|
||||
@@ -206,7 +206,7 @@ class ViewAssetsController extends Controller
|
||||
if ($fullItemType == Asset::class) {
|
||||
$data['item_url'] = route('hardware.show', $item->id);
|
||||
} else {
|
||||
$data['item_url'] = route("view/${itemType}", $item->id);
|
||||
$data['item_url'] = route("view/{$itemType}", $item->id);
|
||||
}
|
||||
|
||||
$settings = Setting::getSettings();
|
||||
|
||||
@@ -62,8 +62,8 @@ class ItemImportRequest extends FormRequest
|
||||
}
|
||||
$importer->setCallbacks([$this, 'log'], [$this, 'progress'], [$this, 'errorCallback'])
|
||||
->setCreatedBy(auth()->id())
|
||||
->setUpdating($this->get('import-update'))
|
||||
->setShouldNotify($this->get('send-welcome'))
|
||||
->setUpdating($this->input('import-update'))
|
||||
->setShouldNotify($this->input('send-welcome'))
|
||||
->setUsernameFormat('firstname.lastname')
|
||||
->setFieldMappings($fieldMappings);
|
||||
$importer->import();
|
||||
|
||||
@@ -34,7 +34,7 @@ class SaveUserRequest extends FormRequest
|
||||
{
|
||||
$rules = [
|
||||
'department_id' => 'nullable|integer|exists:departments,id',
|
||||
'manager_id' => 'nullable|exists:users,id',
|
||||
'manager_id' => 'nullable|integer|exists:users,id',
|
||||
'company_id' => ['nullable', 'integer', 'exists:companies,id']
|
||||
];
|
||||
|
||||
@@ -44,7 +44,7 @@ class SaveUserRequest extends FormRequest
|
||||
case 'POST':
|
||||
$rules['first_name'] = 'required|string|min:1';
|
||||
$rules['username'] = 'required_unless:ldap_import,1|string|min:1';
|
||||
if ($this->request->get('ldap_import') == false) {
|
||||
if ($this->input('ldap_import') == false) {
|
||||
$rules['password'] = Setting::passwordComplexityRulesSaving('store').'|confirmed';
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -19,6 +19,7 @@ class StoreAccessoryRequest extends ImageUploadRequest
|
||||
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
parent::prepareForValidation();
|
||||
|
||||
if ($this->category_id) {
|
||||
if ($category = Category::find($this->category_id)) {
|
||||
|
||||
@@ -19,6 +19,7 @@ class StoreConsumableRequest extends ImageUploadRequest
|
||||
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
parent::prepareForValidation();
|
||||
|
||||
if ($this->category_id) {
|
||||
if ($category = Category::find($this->category_id)) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace App\Http\Transformers;
|
||||
|
||||
use App\Enums\ActionType;
|
||||
use App\Helpers\Helper;
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Models\Actionlog;
|
||||
@@ -80,7 +81,7 @@ class ActionlogsTransformer
|
||||
|
||||
// this is a custom field
|
||||
if (str_starts_with($fieldname, '_snipeit_')) {
|
||||
|
||||
|
||||
foreach ($custom_fields as $custom_field) {
|
||||
|
||||
if ($custom_field->db_column == $fieldname) {
|
||||
@@ -185,9 +186,9 @@ class ActionlogsTransformer
|
||||
'name' => e($actionlog->target->display_name) ?? null,
|
||||
'type' => e($actionlog->targetType()),
|
||||
] : null,
|
||||
|
||||
'quantity' => $this->getQuantity($actionlog),
|
||||
'note' => ($actionlog->note) ? Helper::parseEscapedMarkedownInline($actionlog->note): null,
|
||||
'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
|
||||
'signature_file' => (($actionlog->accept_signature) && Storage::exists('private_uploads/signatures/'.$actionlog->accept_signature)) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null,
|
||||
'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null,
|
||||
'remote_ip' => e($actionlog->remote_ip) ?? null,
|
||||
'user_agent' => e($actionlog->user_agent) ?? null,
|
||||
@@ -336,6 +337,26 @@ class ActionlogsTransformer
|
||||
|
||||
}
|
||||
|
||||
private function getQuantity(Actionlog $actionlog): ?int
|
||||
{
|
||||
if (!$actionlog->quantity) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// only a few action types will have a quantity we are interested in.
|
||||
if (!in_array($actionlog->action_type, [
|
||||
ActionType::Checkout->value,
|
||||
ActionType::Accepted->value,
|
||||
ActionType::Declined->value,
|
||||
ActionType::CheckinFrom->value,
|
||||
ActionType::AddSeats->value,
|
||||
ActionType::DeleteSeats->value,
|
||||
])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (int) $actionlog->quantity;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ class AssetModelsTransformer
|
||||
$array = [
|
||||
'id' => (int) $file->id,
|
||||
'filename' => e($file->filename),
|
||||
'note' => $file->note,
|
||||
'note' => $file->note ? e($file->note) : null,
|
||||
'url' => route('show/modelfile', [$assetmodel->id, $file->id]),
|
||||
'created_by' => ($file->adminuser) ? [
|
||||
'id' => (int) $file->adminuser->id,
|
||||
'name'=> e($file->adminuser->present()->fullName),
|
||||
'name'=> e($file->adminuser->display_name),
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
|
||||
'updated_at' => Helper::getFormattedDateObject($file->updated_at, 'datetime'),
|
||||
|
||||
@@ -104,6 +104,7 @@ class AssetsTransformer
|
||||
'next_audit_date' => Helper::getFormattedDateObject($asset->next_audit_date, 'date'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($asset->deleted_at, 'datetime'),
|
||||
'purchase_date' => Helper::getFormattedDateObject($asset->purchase_date, 'date'),
|
||||
// 'first_checkout' => Helper::getFormattedDateObject($asset->first_checkout_at, 'datetime'),
|
||||
'age' => $asset->purchase_date ? $asset->purchase_date->locale(app()->getLocale())->diffForHumans() : '',
|
||||
'last_checkout' => Helper::getFormattedDateObject($asset->last_checkout, 'datetime'),
|
||||
'last_checkin' => Helper::getFormattedDateObject($asset->last_checkin, 'datetime'),
|
||||
@@ -210,7 +211,7 @@ class AssetsTransformer
|
||||
return $asset->assigned ? [
|
||||
'id' => (int) $asset->assigned->id,
|
||||
'username' => e($asset->assigned->username),
|
||||
'name' => e($asset->assigned->getFullNameAttribute()),
|
||||
'name' => e($asset->assigned->display_name),
|
||||
'first_name'=> e($asset->assigned->first_name),
|
||||
'last_name'=> ($asset->assigned->last_name) ? e($asset->assigned->last_name) : null,
|
||||
'email'=> ($asset->assigned->email) ? e($asset->assigned->email) : null,
|
||||
@@ -321,14 +322,14 @@ class AssetsTransformer
|
||||
'id' => $accessory_checkout->id,
|
||||
'accessory' => [
|
||||
'id' => $accessory_checkout->accessory->id,
|
||||
'name' => $accessory_checkout->accessory->name,
|
||||
'name' => e($accessory_checkout->accessory->display_name),
|
||||
],
|
||||
'assigned_to' => $accessory_checkout->assigned_to,
|
||||
'image' => ($accessory_checkout->accessory->image) ? Storage::disk('public')->url('accessories/' . e($accessory_checkout->accessory->image)) : null,
|
||||
'note' => $accessory_checkout->note ? e($accessory_checkout->note) : null,
|
||||
'created_by' => $accessory_checkout->adminuser ? [
|
||||
'id' => (int)$accessory_checkout->adminuser->id,
|
||||
'name' => e($accessory_checkout->adminuser->present()->fullName),
|
||||
'name' => e($accessory_checkout->display_name),
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($accessory_checkout->created_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($accessory_checkout->deleted_at, 'datetime'),
|
||||
|
||||
@@ -74,6 +74,7 @@ class ComponentsTransformer
|
||||
'checkout' => Gate::allows('checkout', Component::class),
|
||||
'checkin' => Gate::allows('checkin', Component::class),
|
||||
'update' => Gate::allows('update', Component::class),
|
||||
'clone' => Gate::allows('create', Component::class),
|
||||
'delete' => $component->isDeletable(),
|
||||
];
|
||||
$array += $permissions_array;
|
||||
@@ -90,7 +91,7 @@ class ComponentsTransformer
|
||||
'id' => (int) $asset->id,
|
||||
'name' => e($asset->model->display_name).' '.e($asset->display_name),
|
||||
'qty' => $asset->pivot->assigned_qty,
|
||||
'note' => $asset->pivot->note,
|
||||
'note' => e($asset->pivot->note),
|
||||
'type' => 'asset',
|
||||
'created_at' => Helper::getFormattedDateObject($asset->pivot->created_at, 'datetime'),
|
||||
'available_actions' => ['checkin' => true],
|
||||
|
||||
@@ -44,6 +44,7 @@ class CustomFieldsTransformer
|
||||
'db_column_name' => e($field->db_column_name()),
|
||||
'format' => e($field->format),
|
||||
'field_values' => ($field->field_values) ? e($field->field_values) : null,
|
||||
'field_encrypted' => ($field->field_encrypted =='1') ? true : false,
|
||||
'field_values_array' => ($field->field_values) ? explode("\r\n", e($field->field_values)) : null,
|
||||
'type' => e($field->element),
|
||||
'required' => (($field->pivot) && ($field->pivot->required=='1')) ? true : false,
|
||||
|
||||
@@ -63,7 +63,7 @@ class DepreciationReportTransformer
|
||||
*/
|
||||
if (($asset->model) && ($asset->model->depreciation) && ($asset->model->depreciation->months !== 0)) {
|
||||
$depreciated_value = Helper::formatCurrencyOutput($asset->getDepreciatedValue());
|
||||
$monthly_depreciation =Helper::formatCurrencyOutput($asset->purchase_cost / $asset->model->depreciation->months);
|
||||
$monthly_depreciation =Helper::formatCurrencyOutput($asset->getMonthlyDepreciation());
|
||||
$diff = Helper::formatCurrencyOutput(($asset->purchase_cost - $asset->getDepreciatedValue()));
|
||||
}
|
||||
else if($asset->model->eol !== null) {
|
||||
|
||||
@@ -30,7 +30,7 @@ class LocationsTransformer
|
||||
foreach ($location->children as $child) {
|
||||
$children_arr[] = [
|
||||
'id' => (int) $child->id,
|
||||
'name' => $child->name,
|
||||
'name' => e($child->display_name),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,7 @@ class LocationsTransformer
|
||||
'name' => e($location->name),
|
||||
'created_by' => $location->adminuser ? [
|
||||
'id' => (int) $location->adminuser->id,
|
||||
'name'=> e($location->adminuser->present()->fullName),
|
||||
'name'=> e($location->adminuser->display_name),
|
||||
]: null,
|
||||
'created_at' => Helper::getFormattedDateObject($location->created_at, 'datetime'),
|
||||
];
|
||||
@@ -171,7 +171,7 @@ class LocationsTransformer
|
||||
if ($accessory) {
|
||||
return [
|
||||
'id' => $accessory->id,
|
||||
'name' => $accessory->name,
|
||||
'name' => e($accessory->display_name),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ class MaintenancesTransformer
|
||||
'image' => ($assetmaintenance->image != '') ? Storage::disk('public')->url('maintenances/'.e($assetmaintenance->image)) : null,
|
||||
'model' => (($assetmaintenance->asset) && ($assetmaintenance->asset->model)) ? [
|
||||
'id' => (int) $assetmaintenance->asset->model->id,
|
||||
'name'=> ($assetmaintenance->asset->model->name) ? e($assetmaintenance->asset->model->name).' '.e($assetmaintenance->asset->model->model_number) : null,
|
||||
'name'=> ($assetmaintenance->asset->model->name) ? e($assetmaintenance->asset->model->name) : null,
|
||||
'model_number'=> ($assetmaintenance->asset->model->model_number) ? e($assetmaintenance->asset->model->model_number) : null,
|
||||
] : null,
|
||||
'status_label' => (($assetmaintenance->asset) && ($assetmaintenance->asset->assetstatus)) ? [
|
||||
'id' => (int) $assetmaintenance->asset->assetstatus->id,
|
||||
|
||||
@@ -40,7 +40,7 @@ class StatuslabelsTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Statuslabel::class) ? true : false,
|
||||
'delete' => (Gate::allows('delete', Statuslabel::class) && ($statuslabel->assets_count == 0)) ? true : false,
|
||||
'delete' => (Gate::allows('delete', Statuslabel::class) && ($statuslabel->isDeletable())) ? true : false,
|
||||
];
|
||||
$array += $permissions_array;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class SuppliersTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => Gate::allows('update', Supplier::class),
|
||||
'delete' => (Gate::allows('delete', Supplier::class) && ($supplier->assets_count == 0) && ($supplier->licenses_count == 0) && ($supplier->accessories_count == 0)),
|
||||
'delete' => (Gate::allows('delete', Supplier::class) && ($supplier->isDeletable())),
|
||||
];
|
||||
|
||||
$array += $permissions_array;
|
||||
|
||||
@@ -41,7 +41,7 @@ class UploadedFilesTransformer
|
||||
'note' => ($file->note) ? e($file->note) : null,
|
||||
'created_by' => ($file->adminuser) ? [
|
||||
'id' => (int) $file->adminuser->id,
|
||||
'name'=> e($file->adminuser->present()->fullName),
|
||||
'name'=> e($file->adminuser->display_name),
|
||||
] : null,
|
||||
'created_at' => Helper::getFormattedDateObject($file->created_at, 'datetime'),
|
||||
'deleted_at' => Helper::getFormattedDateObject($file->deleted_at, 'datetime'),
|
||||
|
||||
@@ -101,7 +101,7 @@ class UsersTransformer
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'update' => (Gate::allows('update', User::class) && ($user->deleted_at == '')),
|
||||
'delete' => $user->isDeletable(),
|
||||
'delete' => ($user->isDeletable() && (auth()->user()->can('canEditAuthFields', $user) && auth()->user()->can('editableOnDemo'))),
|
||||
'clone' => (Gate::allows('create', User::class) && ($user->deleted_at == '')),
|
||||
'restore' => (Gate::allows('create', User::class) && ($user->deleted_at != '')),
|
||||
];
|
||||
@@ -141,7 +141,7 @@ class UsersTransformer
|
||||
'id' => (int) $user->id,
|
||||
'image' => e($user->present()->gravatar) ?? null,
|
||||
'type' => 'user',
|
||||
'name' => e($user->getFullNameAttribute()),
|
||||
'name' => e($user->display_name),
|
||||
'first_name' => e($user->first_name),
|
||||
'last_name' => e($user->last_name),
|
||||
'username' => e($user->username),
|
||||
|
||||
@@ -85,9 +85,9 @@ class AssetImporter extends ItemImporter
|
||||
if ($this->findCsvMatch($row, 'id')!='') {
|
||||
// Override asset if an ID was given
|
||||
\Log::debug('Finding asset by ID: '.$this->findCsvMatch($row, 'id'));
|
||||
$asset = Asset::find($this->findCsvMatch($row, 'id'));
|
||||
$asset = Asset::with('assignedTo')->find($this->findCsvMatch($row, 'id'));
|
||||
} else {
|
||||
$asset = Asset::where(['asset_tag'=> (string) $asset_tag])->first();
|
||||
$asset = Asset::with('assignedTo')->where(['asset_tag' => (string) $asset_tag])->first();
|
||||
}
|
||||
|
||||
if ($asset) {
|
||||
@@ -203,7 +203,7 @@ class AssetImporter extends ItemImporter
|
||||
if (isset($target) && ($target !== false)) {
|
||||
if (!is_null($asset->assigned_to)){
|
||||
if ($asset->assigned_to != $target->id) {
|
||||
event(new CheckoutableCheckedIn($asset, User::find($asset->assigned_to), auth()->user(), 'Checkin from CSV Importer', $checkin_date));
|
||||
event(new CheckoutableCheckedIn($asset, $asset->assigned, auth()->user(), 'Checkin from CSV Importer', $checkin_date));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ class CategoryImporter extends ItemImporter
|
||||
$this->item['use_default_eula'] = trim(($this->fetchHumanBoolean($this->findCsvMatch($row, 'use_default_eula'))) == 1) ? 1 : 0;
|
||||
$this->item['require_acceptance'] = trim(($this->fetchHumanBoolean($this->findCsvMatch($row, 'require_acceptance'))) == 1) ? 1 : 0;
|
||||
$this->item['checkin_email'] = trim(($this->fetchHumanBoolean($this->findCsvMatch($row, 'checkin_email'))) == 1) ? 1 : 0;
|
||||
$this->item['tag_color'] = trim($this->findCsvMatch($row, 'tag_color'));
|
||||
|
||||
|
||||
Log::debug('Item array is: ');
|
||||
|
||||
@@ -72,6 +72,7 @@ class ManufacturerImporter extends ItemImporter
|
||||
$this->item['support_url'] = trim($this->findCsvMatch($row, 'support_url'));
|
||||
$this->item['warranty_lookup_url'] = trim($this->findCsvMatch($row, 'warranty_lookup_url'));
|
||||
$this->item['notes'] = trim($this->findCsvMatch($row, 'notes'));
|
||||
$this->item['tag_color'] = trim($this->findCsvMatch($row, 'tag_color'));
|
||||
|
||||
|
||||
Log::debug('Item array is: ');
|
||||
|
||||
@@ -76,6 +76,7 @@ class SupplierImporter extends ItemImporter
|
||||
$this->item['contact'] = trim($this->findCsvMatch($row, 'contact'));
|
||||
$this->item['url'] = trim($this->findCsvMatch($row, 'url'));
|
||||
$this->item['notes'] = trim($this->findCsvMatch($row, 'notes'));
|
||||
$this->item['tag_color'] = trim($this->findCsvMatch($row, 'tag_color'));
|
||||
|
||||
|
||||
Log::debug('Item array is: ');
|
||||
|
||||
@@ -10,6 +10,7 @@ use App\Notifications\WelcomeNotification;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
/**
|
||||
* This is ONLY used for the User Import. When we are importing users
|
||||
@@ -102,8 +103,7 @@ class UserImporter extends ItemImporter
|
||||
|
||||
$this->log('Updating User');
|
||||
|
||||
// Todo - check that this works
|
||||
if (!Gate::allows('canEditAuthFields', $user)) {
|
||||
if (Auth::check() && (!Gate::allows('canEditAuthFields', $user))) {
|
||||
unset($user->username);
|
||||
unset($user->email);
|
||||
unset($user->password);
|
||||
|
||||
@@ -33,6 +33,7 @@ use App\Notifications\CheckoutConsumableNotification;
|
||||
use App\Notifications\CheckoutLicenseSeatNotification;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Context;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Exception;
|
||||
@@ -128,11 +129,18 @@ class CheckoutableListener
|
||||
->notify($this->getCheckoutNotification($event, $acceptance));
|
||||
}
|
||||
} catch (ClientException $e) {
|
||||
$status = $e->getResponse()->getStatusCode();
|
||||
|
||||
if (strpos($e->getMessage(), 'channel_not_found') !== false) {
|
||||
Log::warning(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_channel_not_found'));
|
||||
} else {
|
||||
Log::error("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
if ($status >= 500 || $status === null) {
|
||||
Log::error(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
} else {
|
||||
Log::warning("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
}
|
||||
}
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
} catch (Exception $e) {
|
||||
@@ -224,12 +232,18 @@ class CheckoutableListener
|
||||
->notify($this->getCheckinNotification($event));
|
||||
}
|
||||
} catch (ClientException $e) {
|
||||
$status = $e->getResponse()->getStatusCode();
|
||||
|
||||
if (strpos($e->getMessage(), 'channel_not_found') !== false) {
|
||||
Log::warning(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_channel_not_found'));
|
||||
} else {
|
||||
Log::error("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
if ($status >= 500 || $status === null) {
|
||||
Log::error(Setting::getSettings()->webhook_selected . " notification failed: " . $e->getMessage());
|
||||
} else {
|
||||
Log::warning("ClientException caught during checkin notification: " . $e->getMessage());
|
||||
return redirect()->back()->with('warning', ucfirst(Setting::getSettings()->webhook_selected) . trans('admin/settings/message.webhook.webhook_fail'));
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::warning(ucfirst(Setting::getSettings()->webhook_selected) . ' webhook notification failed:', [
|
||||
@@ -428,12 +442,17 @@ class CheckoutableListener
|
||||
private function shouldSendCheckoutEmailToUser(Model $checkoutable): bool
|
||||
{
|
||||
/**
|
||||
* Send an email if any of the following conditions are met:
|
||||
* Send an email if we didn't get here from a bulk checkout
|
||||
* and any of the following conditions are met:
|
||||
* 1. The asset requires acceptance
|
||||
* 2. The item has a EULA
|
||||
* 3. The item should send an email at check-in/check-out
|
||||
*/
|
||||
|
||||
if (Context::get('action') === 'bulk_asset_checkout') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($checkoutable->requireAcceptance()) {
|
||||
return true;
|
||||
}
|
||||
@@ -451,6 +470,10 @@ class CheckoutableListener
|
||||
|
||||
private function shouldSendEmailToAlertAddress($acceptance = null): bool
|
||||
{
|
||||
if (Context::get('action') === 'bulk_asset_checkout') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$setting = Setting::getSettings();
|
||||
|
||||
if (!$setting) {
|
||||
|
||||
154
app/Listeners/CheckoutablesCheckedOutInBulkListener.php
Normal file
154
app/Listeners/CheckoutablesCheckedOutInBulkListener.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace App\Listeners;
|
||||
|
||||
use App\Events\CheckoutablesCheckedOutInBulk;
|
||||
use App\Mail\BulkAssetCheckoutMail;
|
||||
use App\Models\Asset;
|
||||
use App\Models\Location;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class CheckoutablesCheckedOutInBulkListener
|
||||
{
|
||||
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen(
|
||||
CheckoutablesCheckedOutInBulk::class,
|
||||
CheckoutablesCheckedOutInBulkListener::class
|
||||
);
|
||||
}
|
||||
|
||||
public function handle(CheckoutablesCheckedOutInBulk $event): void
|
||||
{
|
||||
$notifiableUser = $this->getNotifiableUser($event);
|
||||
|
||||
$shouldSendEmailToUser = $this->shouldSendCheckoutEmailToUser($notifiableUser, $event->assets);
|
||||
$shouldSendEmailToAlertAddress = $this->shouldSendEmailToAlertAddress($event->assets);
|
||||
|
||||
if ($shouldSendEmailToUser && $notifiableUser) {
|
||||
try {
|
||||
Mail::to($notifiableUser)->send(new BulkAssetCheckoutMail(
|
||||
$event->assets,
|
||||
$event->target,
|
||||
$event->admin,
|
||||
$event->checkout_at,
|
||||
$event->expected_checkin,
|
||||
$event->note,
|
||||
));
|
||||
|
||||
Log::info('BulkAssetCheckoutMail sent to checkout target');
|
||||
} catch (Exception $e) {
|
||||
Log::debug("Exception caught during BulkAssetCheckoutMail to target: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if ($shouldSendEmailToAlertAddress && Setting::getSettings()->admin_cc_email) {
|
||||
try {
|
||||
Mail::to(Setting::getSettings()->admin_cc_email)->send(new BulkAssetCheckoutMail(
|
||||
$event->assets,
|
||||
$event->target,
|
||||
$event->admin,
|
||||
$event->checkout_at,
|
||||
$event->expected_checkin,
|
||||
$event->note,
|
||||
));
|
||||
|
||||
Log::info('BulkAssetCheckoutMail sent to admin_cc_email');
|
||||
} catch (Exception $e) {
|
||||
Log::debug("Exception caught during BulkAssetCheckoutMail to admin_cc_email: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function shouldSendCheckoutEmailToUser(?User $user, Collection $assets): bool
|
||||
{
|
||||
if (!$user?->email) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->hasAssetWithEula($assets)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->hasAssetWithCategorySettingToSendEmail($assets)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->hasAssetThatRequiresAcceptance($assets);
|
||||
}
|
||||
|
||||
private function shouldSendEmailToAlertAddress(Collection $assets): bool
|
||||
{
|
||||
$setting = Setting::getSettings();
|
||||
|
||||
if (!$setting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($setting->admin_cc_always) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->hasAssetThatRequiresAcceptance($assets)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $setting->admin_cc_email;
|
||||
}
|
||||
|
||||
private function hasAssetWithEula(Collection $assets): bool
|
||||
{
|
||||
foreach ($assets as $asset) {
|
||||
if ($asset->getEula()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function hasAssetWithCategorySettingToSendEmail(Collection $assets): bool
|
||||
{
|
||||
foreach ($assets as $asset) {
|
||||
if ($asset->checkin_email()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function hasAssetThatRequiresAcceptance(Collection $assets): bool
|
||||
{
|
||||
foreach ($assets as $asset) {
|
||||
if ($asset->requireAcceptance()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getNotifiableUser(CheckoutablesCheckedOutInBulk $event): ?Model
|
||||
{
|
||||
$target = $event->target;
|
||||
|
||||
if ($target instanceof Asset) {
|
||||
$target->load('assignedTo');
|
||||
return $target->assignedto;
|
||||
}
|
||||
|
||||
if ($target instanceof Location) {
|
||||
return $target->manager;
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,13 @@ class LogListener
|
||||
*/
|
||||
public function onCheckoutableCheckedOut(CheckoutableCheckedOut $event)
|
||||
{
|
||||
$event->checkoutable->logCheckout($event->note, $event->checkedOutTo, $event->checkoutable->last_checkout, $event->originalValues);
|
||||
$event->checkoutable->logCheckout(
|
||||
$event->note,
|
||||
$event->checkedOutTo,
|
||||
$event->checkoutable->last_checkout,
|
||||
$event->originalValues,
|
||||
$event->quantity
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,6 +72,9 @@ class LogListener
|
||||
$logaction->note = $event->acceptance->note;
|
||||
$logaction->action_type = 'accepted';
|
||||
$logaction->action_date = $event->acceptance->accepted_at;
|
||||
$logaction->quantity = $event->acceptance->qty ?? 1;
|
||||
$logaction->created_by = auth()->user()->id;
|
||||
|
||||
|
||||
// TODO: log the actual license seat that was checked out
|
||||
if ($event->acceptance->checkoutable instanceof LicenseSeat) {
|
||||
@@ -84,6 +93,8 @@ class LogListener
|
||||
$logaction->note = $event->acceptance->note;
|
||||
$logaction->action_type = 'declined';
|
||||
$logaction->action_date = $event->acceptance->declined_at;
|
||||
$logaction->quantity = $event->acceptance->qty ?? 1;
|
||||
$logaction->created_by = auth()->user()->id;
|
||||
|
||||
// TODO: log the actual license seat that was checked out
|
||||
if ($event->acceptance->checkoutable instanceof LicenseSeat) {
|
||||
|
||||
@@ -150,10 +150,15 @@ class Importer extends Component
|
||||
// if you got here, we didn't find a match. Try the $aliases_fields
|
||||
foreach ($this->aliases_fields as $key => $alias_values) {
|
||||
foreach ($alias_values as $alias_value) {
|
||||
|
||||
// Trim off any trailing spaces
|
||||
$key = trim($key);
|
||||
$header = trim($header);
|
||||
if (strcasecmp($alias_value, $header) === 0) { // aLsO CaSe-INSENSitiVE!
|
||||
// Make *absolutely* sure that this key actually _exists_ in this import type -
|
||||
// you can trigger this by importing accessories with a 'Warranty' column (which don't exist
|
||||
// in "Accessories"!)
|
||||
|
||||
if (array_key_exists($key, $this->columnOptions[$type])) {
|
||||
$this->field_map[$i] = $key;
|
||||
continue 3; // bust out of both of these loops and the surrounding one - e.g. move on to the next header
|
||||
@@ -262,7 +267,7 @@ class Importer extends Component
|
||||
'order_number' => trans('general.order_number'),
|
||||
'purchase_cost' => trans('general.purchase_cost'),
|
||||
'purchase_date' => trans('general.purchase_date'),
|
||||
'quantity' => trans('general.qty'),
|
||||
'qty' => trans('general.qty'),
|
||||
'supplier' => trans('general.supplier'),
|
||||
];
|
||||
|
||||
@@ -278,7 +283,7 @@ class Importer extends Component
|
||||
'order_number' => trans('general.order_number'),
|
||||
'purchase_cost' => trans('general.purchase_cost'),
|
||||
'purchase_date' => trans('general.purchase_date'),
|
||||
'quantity' => trans('general.qty'),
|
||||
'qty' => trans('general.qty'),
|
||||
'serial' => trans('general.serial_number'),
|
||||
'supplier' => trans('general.supplier'),
|
||||
];
|
||||
@@ -372,12 +377,14 @@ class Importer extends Component
|
||||
'city' => trans('general.city'),
|
||||
'notes' => trans('general.notes'),
|
||||
'state' => trans('general.state'),
|
||||
'country' => trans('general.country'),
|
||||
'zip' => trans('general.zip'),
|
||||
'phone' => trans('general.phone'),
|
||||
'fax' => trans('general.fax'),
|
||||
'url' => trans('general.url'),
|
||||
'contact' => trans('general.contact'),
|
||||
'email' => trans('general.email'),
|
||||
'tag_color' => trans('general.tag_color'),
|
||||
];
|
||||
|
||||
$this->manufacturers_fields = [
|
||||
@@ -389,6 +396,7 @@ class Importer extends Component
|
||||
'support_email' => trans('admin/manufacturers/table.support_email'),
|
||||
'warranty_lookup_url' => trans('admin/manufacturers/table.warranty_lookup_url'),
|
||||
'url' => trans('general.url'),
|
||||
'tag_color' => trans('general.tag_color'),
|
||||
];
|
||||
|
||||
$this->categories_fields = [
|
||||
@@ -400,6 +408,8 @@ class Importer extends Component
|
||||
'use_default_eula' => trans('admin/categories/general.use_default_eula_column'),
|
||||
'require_acceptance' => trans('admin/categories/general.import_require_acceptance'),
|
||||
'checkin_email' => trans('admin/categories/general.import_checkin_email'),
|
||||
'alert_on_response' => trans('admin/categories/general.import_alert_on_response'),
|
||||
'tag_color' => trans('general.tag_color'),
|
||||
];
|
||||
|
||||
|
||||
@@ -409,22 +419,32 @@ class Importer extends Component
|
||||
'category' => trans('general.category'),
|
||||
'eol' => trans('general.eol'),
|
||||
'fieldset' => trans('admin/models/general.fieldset'),
|
||||
'item_name' => trans('general.item_name_var', ['item' => trans('general.asset_model')]),
|
||||
'name' => trans('general.name'),
|
||||
'manufacturer' => trans('general.manufacturer'),
|
||||
'min_amt' => trans('mail.min_QTY'),
|
||||
'model_number' => trans('general.model_no'),
|
||||
'notes' => trans('general.item_notes', ['item' => trans('admin/hardware/form.model')]),
|
||||
'requestable' => trans('admin/models/general.requestable'),
|
||||
'notes' => trans('general.notes'),
|
||||
'requestable' => trans('general.requestable'),
|
||||
'require_serial' => trans('admin/hardware/general.require_serial'),
|
||||
|
||||
'tag_color' => trans('general.tag_color'),
|
||||
'depreciation' => trans('general.depreciation'),
|
||||
];
|
||||
|
||||
// "real fieldnames" to a list of aliases for that field
|
||||
/**
|
||||
* These are the "real fieldnames" with a list of possible aliases,
|
||||
* like misspellings, slight mis-phrasings, user-specific language, etc. that
|
||||
* could be in the imported file header.
|
||||
* This just makes the user's experience a little better when they're using
|
||||
* their own CSV template.
|
||||
*/
|
||||
|
||||
$this->aliases_fields = [
|
||||
'item_name' =>
|
||||
[
|
||||
'item name',
|
||||
'asset name',
|
||||
'model name',
|
||||
'asset model name',
|
||||
'accessory name',
|
||||
'user name',
|
||||
'consumable name',
|
||||
@@ -438,6 +458,20 @@ class Importer extends Component
|
||||
'item no.',
|
||||
'item #',
|
||||
],
|
||||
'order_number' => [
|
||||
'order #',
|
||||
'order no.',
|
||||
'order num',
|
||||
'order number',
|
||||
'order',
|
||||
],
|
||||
'eula_text' => [
|
||||
'eula',
|
||||
],
|
||||
|
||||
'checkin_email' => [
|
||||
'checkin email',
|
||||
],
|
||||
'asset_model' =>
|
||||
[
|
||||
'model name',
|
||||
@@ -455,16 +489,6 @@ class Importer extends Component
|
||||
'EOL',
|
||||
'eol months',
|
||||
],
|
||||
'depreciation' =>
|
||||
[
|
||||
'Depreciation',
|
||||
'depreciation',
|
||||
],
|
||||
'requestable' =>
|
||||
[
|
||||
'requestable',
|
||||
'Requestable',
|
||||
],
|
||||
'gravatar' =>
|
||||
[
|
||||
'gravatar',
|
||||
@@ -541,7 +565,8 @@ class Importer extends Component
|
||||
],
|
||||
'require_serial' =>
|
||||
[
|
||||
'serial required',
|
||||
trans('admin/models/general.importer.require_serial'),
|
||||
trans('admin/models/general.importer.serial_reqiured'),
|
||||
],
|
||||
'model_number' =>
|
||||
[
|
||||
|
||||
@@ -84,7 +84,7 @@ class OauthClients extends Component
|
||||
]);
|
||||
|
||||
$client = app(ClientRepository::class)->find($editClientId->id);
|
||||
if ($client->created_by == auth()->id()) {
|
||||
if ($client->user_id == auth()->id()) {
|
||||
$client->name = $this->editName;
|
||||
$client->redirect = $this->editRedirect;
|
||||
$client->save();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user